From 0b793b6717a631fa2bd7650b670834e5268e8ae6 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Thu, 11 Mar 2021 11:53:13 +0100 Subject: [PATCH 001/462] Create terraform.tf Signed-off-by: Jacob Valdemar Andreasen --- .../techdocs-s3-storage/terraform.tf | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 contrib/terraform/techdocs-s3-storage/terraform.tf diff --git a/contrib/terraform/techdocs-s3-storage/terraform.tf b/contrib/terraform/techdocs-s3-storage/terraform.tf new file mode 100644 index 0000000000..d8d57e9cd6 --- /dev/null +++ b/contrib/terraform/techdocs-s3-storage/terraform.tf @@ -0,0 +1,73 @@ +#========================== +# Variables +#========================== + +variable "backstage" { + default = "backstage" +} + +#========================== +# Bucket +#========================== + +resource "aws_s3_bucket" "backstage" { + bucket = var.backstage + acl = "private" + provider = aws + + lifecycle { + prevent_destroy = true + } + + server_side_encryption_configuration { + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + } + } + + tags = { + Name = var.backstage + "Managed By Terraform" = var.shared-managed-tag-value + } +} + +resource "aws_s3_bucket_public_access_block" "backstage" { + bucket = aws_s3_bucket.backstage.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + + +#========================== +# IAM +#========================== + +resource "aws_iam_user" "backstage" { + name = var.backstage +} + +resource "aws_iam_user_policy" "backstage" { + name = var.backstage + user = aws_iam_user.backstage.name + policy = data.aws_iam_policy_document.backstage-policy.json +} + +data "aws_iam_policy_document" "backstage-policy" { + statement { + actions = [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucket" + ] + effect = "Allow" + resources = [ + "${aws_s3_bucket.backstage.arn}", + "${aws_s3_bucket.backstage.arn}/*", + ] + } +} From 602cb4152285c70324e1fdcea01fed3d3565f0a4 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Thu, 11 Mar 2021 11:59:45 +0100 Subject: [PATCH 002/462] Create readme.md Signed-off-by: Jacob Valdemar Andreasen --- contrib/terraform/techdocs-s3-storage/readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 contrib/terraform/techdocs-s3-storage/readme.md diff --git a/contrib/terraform/techdocs-s3-storage/readme.md b/contrib/terraform/techdocs-s3-storage/readme.md new file mode 100644 index 0000000000..9615cc8d13 --- /dev/null +++ b/contrib/terraform/techdocs-s3-storage/readme.md @@ -0,0 +1 @@ +This terraform file should create a S3 bucket and setup IAM with a user with an inline policy which gives the user access to the bucket. After you have created the bucket, user and policy you should go to the user in the AWS console and create an access key. This access key should be used as the env variables in step 3a [here](https://backstage.io/docs/features/techdocs/using-cloud-storage#configuring-aws-s3-bucket-with-techdocs). From 3eb3f81a4d177ad324ac2684637c31a0af8e9dff Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Thu, 11 Mar 2021 12:22:06 +0100 Subject: [PATCH 003/462] Update documentation Signed-off-by: Jacob Valdemar Andreasen --- docs/features/techdocs/using-cloud-storage.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index fd8f320859..2f5828331d 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -120,6 +120,7 @@ techdocs: Create a dedicated AWS S3 bucket for the storage of TechDocs sites. [Refer to the official documentation](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-bucket.html). +[Terraform example](https://github.com/backstage/backstage/blob/master/contrib/terraform/techdocs-s3-storage/terraform.tf). TechDocs will publish documentation to this bucket and will fetch files from here to serve documentation in Backstage. Note that the bucket names are @@ -142,7 +143,9 @@ variables** You should follow the [AWS security best practices guide for authentication](https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html). -TechDocs needs access to read files and metadata of the S3 bucket. +TechDocs needs access to read files and metadata of the S3 bucket. So if you are +creating a policy for a user you want to make sure it is granted access to +ListBucket, GetObject and PutObject. If the environment variables From 65a4980f3f1afec0e7431189a6367e9581dd35c9 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Thu, 11 Mar 2021 12:30:01 +0100 Subject: [PATCH 004/462] Fix typo Signed-off-by: Jacob Valdemar Andreasen --- docs/features/techdocs/using-cloud-storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index 2f5828331d..f10b379757 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -145,7 +145,7 @@ You should follow the TechDocs needs access to read files and metadata of the S3 bucket. So if you are creating a policy for a user you want to make sure it is granted access to -ListBucket, GetObject and PutObject. +ListObjects, GetObject and PutObject. If the environment variables From f22a8edaafcba019cf4dcc3b53e0e56a81f3590c Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Wed, 17 Mar 2021 10:15:48 +0100 Subject: [PATCH 005/462] Add and change terraform variables Signed-off-by: Jacob Valdemar Andreasen --- contrib/terraform/techdocs-s3-storage/terraform.tf | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/contrib/terraform/techdocs-s3-storage/terraform.tf b/contrib/terraform/techdocs-s3-storage/terraform.tf index d8d57e9cd6..6dea091492 100644 --- a/contrib/terraform/techdocs-s3-storage/terraform.tf +++ b/contrib/terraform/techdocs-s3-storage/terraform.tf @@ -3,9 +3,17 @@ #========================== variable "backstage" { + default = "backstage_bucket_for_my_corp" +} + +variable "backstage-iam" { default = "backstage" } +variable "shared-managed-tag-value" { + default = "terraform_for_my_corp" +} + #========================== # Bucket #========================== @@ -48,11 +56,11 @@ resource "aws_s3_bucket_public_access_block" "backstage" { #========================== resource "aws_iam_user" "backstage" { - name = var.backstage + name = var.backstage-iam } resource "aws_iam_user_policy" "backstage" { - name = var.backstage + name = var.backstage-iam user = aws_iam_user.backstage.name policy = data.aws_iam_policy_document.backstage-policy.json } From 69d9259d260be837beeec5a6483223cb5a4419f8 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Thu, 11 Mar 2021 11:53:13 +0100 Subject: [PATCH 006/462] Create terraform.tf Signed-off-by: Jacob Valdemar Andreasen --- .../techdocs-s3-storage/terraform.tf | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 contrib/terraform/techdocs-s3-storage/terraform.tf diff --git a/contrib/terraform/techdocs-s3-storage/terraform.tf b/contrib/terraform/techdocs-s3-storage/terraform.tf new file mode 100644 index 0000000000..d8d57e9cd6 --- /dev/null +++ b/contrib/terraform/techdocs-s3-storage/terraform.tf @@ -0,0 +1,73 @@ +#========================== +# Variables +#========================== + +variable "backstage" { + default = "backstage" +} + +#========================== +# Bucket +#========================== + +resource "aws_s3_bucket" "backstage" { + bucket = var.backstage + acl = "private" + provider = aws + + lifecycle { + prevent_destroy = true + } + + server_side_encryption_configuration { + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + } + } + + tags = { + Name = var.backstage + "Managed By Terraform" = var.shared-managed-tag-value + } +} + +resource "aws_s3_bucket_public_access_block" "backstage" { + bucket = aws_s3_bucket.backstage.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + + +#========================== +# IAM +#========================== + +resource "aws_iam_user" "backstage" { + name = var.backstage +} + +resource "aws_iam_user_policy" "backstage" { + name = var.backstage + user = aws_iam_user.backstage.name + policy = data.aws_iam_policy_document.backstage-policy.json +} + +data "aws_iam_policy_document" "backstage-policy" { + statement { + actions = [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucket" + ] + effect = "Allow" + resources = [ + "${aws_s3_bucket.backstage.arn}", + "${aws_s3_bucket.backstage.arn}/*", + ] + } +} From 74748a99a0790fb28431282809a5eda14ba4506d Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Thu, 11 Mar 2021 11:59:45 +0100 Subject: [PATCH 007/462] Create readme.md Signed-off-by: Jacob Valdemar Andreasen --- contrib/terraform/techdocs-s3-storage/readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 contrib/terraform/techdocs-s3-storage/readme.md diff --git a/contrib/terraform/techdocs-s3-storage/readme.md b/contrib/terraform/techdocs-s3-storage/readme.md new file mode 100644 index 0000000000..9615cc8d13 --- /dev/null +++ b/contrib/terraform/techdocs-s3-storage/readme.md @@ -0,0 +1 @@ +This terraform file should create a S3 bucket and setup IAM with a user with an inline policy which gives the user access to the bucket. After you have created the bucket, user and policy you should go to the user in the AWS console and create an access key. This access key should be used as the env variables in step 3a [here](https://backstage.io/docs/features/techdocs/using-cloud-storage#configuring-aws-s3-bucket-with-techdocs). From 26e8254ef289ef16cb0a3ac43e7318869f3833d6 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Thu, 11 Mar 2021 12:22:06 +0100 Subject: [PATCH 008/462] Update documentation Signed-off-by: Jacob Valdemar Andreasen --- docs/features/techdocs/using-cloud-storage.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index fd8f320859..2f5828331d 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -120,6 +120,7 @@ techdocs: Create a dedicated AWS S3 bucket for the storage of TechDocs sites. [Refer to the official documentation](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-bucket.html). +[Terraform example](https://github.com/backstage/backstage/blob/master/contrib/terraform/techdocs-s3-storage/terraform.tf). TechDocs will publish documentation to this bucket and will fetch files from here to serve documentation in Backstage. Note that the bucket names are @@ -142,7 +143,9 @@ variables** You should follow the [AWS security best practices guide for authentication](https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html). -TechDocs needs access to read files and metadata of the S3 bucket. +TechDocs needs access to read files and metadata of the S3 bucket. So if you are +creating a policy for a user you want to make sure it is granted access to +ListBucket, GetObject and PutObject. If the environment variables From 5da1459aeae6b196203fba71b0c0473211a083d6 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Thu, 11 Mar 2021 12:30:01 +0100 Subject: [PATCH 009/462] Fix typo Signed-off-by: Jacob Valdemar Andreasen --- docs/features/techdocs/using-cloud-storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index 2f5828331d..f10b379757 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -145,7 +145,7 @@ You should follow the TechDocs needs access to read files and metadata of the S3 bucket. So if you are creating a policy for a user you want to make sure it is granted access to -ListBucket, GetObject and PutObject. +ListObjects, GetObject and PutObject. If the environment variables From ea0723fd5f4bcc656b3d219cad335341f7fec6d8 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Wed, 17 Mar 2021 10:15:48 +0100 Subject: [PATCH 010/462] Add and change terraform variables Signed-off-by: Jacob Valdemar Andreasen --- contrib/terraform/techdocs-s3-storage/terraform.tf | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/contrib/terraform/techdocs-s3-storage/terraform.tf b/contrib/terraform/techdocs-s3-storage/terraform.tf index d8d57e9cd6..6dea091492 100644 --- a/contrib/terraform/techdocs-s3-storage/terraform.tf +++ b/contrib/terraform/techdocs-s3-storage/terraform.tf @@ -3,9 +3,17 @@ #========================== variable "backstage" { + default = "backstage_bucket_for_my_corp" +} + +variable "backstage-iam" { default = "backstage" } +variable "shared-managed-tag-value" { + default = "terraform_for_my_corp" +} + #========================== # Bucket #========================== @@ -48,11 +56,11 @@ resource "aws_s3_bucket_public_access_block" "backstage" { #========================== resource "aws_iam_user" "backstage" { - name = var.backstage + name = var.backstage-iam } resource "aws_iam_user_policy" "backstage" { - name = var.backstage + name = var.backstage-iam user = aws_iam_user.backstage.name policy = data.aws_iam_policy_document.backstage-policy.json } From c65a85afb691700ddb795f2a4b9d9dc0b2648a13 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Andreasen Date: Wed, 7 Apr 2021 12:32:43 +0200 Subject: [PATCH 011/462] Change terraform variable and fix typo in docs Signed-off-by: Jacob Valdemar Andreasen --- contrib/terraform/techdocs-s3-storage/terraform.tf | 6 +++--- docs/features/techdocs/using-cloud-storage.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/terraform/techdocs-s3-storage/terraform.tf b/contrib/terraform/techdocs-s3-storage/terraform.tf index 6dea091492..ca267f0f12 100644 --- a/contrib/terraform/techdocs-s3-storage/terraform.tf +++ b/contrib/terraform/techdocs-s3-storage/terraform.tf @@ -2,7 +2,7 @@ # Variables #========================== -variable "backstage" { +variable "backstage-bucket" { default = "backstage_bucket_for_my_corp" } @@ -19,7 +19,7 @@ variable "shared-managed-tag-value" { #========================== resource "aws_s3_bucket" "backstage" { - bucket = var.backstage + bucket = var.backstage-bucket acl = "private" provider = aws @@ -36,7 +36,7 @@ resource "aws_s3_bucket" "backstage" { } tags = { - Name = var.backstage + Name = var.backstage-bucket "Managed By Terraform" = var.shared-managed-tag-value } } diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index f10b379757..2f5828331d 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -145,7 +145,7 @@ You should follow the TechDocs needs access to read files and metadata of the S3 bucket. So if you are creating a policy for a user you want to make sure it is granted access to -ListObjects, GetObject and PutObject. +ListBucket, GetObject and PutObject. If the environment variables From d0e2116c448e47087566de0be290f62efb821fee Mon Sep 17 00:00:00 2001 From: Efrain Gutierrez Date: Wed, 7 Apr 2021 11:49:02 -0500 Subject: [PATCH 012/462] Adjusting Heading for Scaffolding Template Page Signed-off-by: Efrain Gutierrez --- packages/core/src/layout/Header/Header.tsx | 8 ++++++-- packages/core/src/layout/InfoCard/InfoCard.tsx | 3 +++ .../components/MultistepJsonForm/MultistepJsonForm.tsx | 4 +++- .../src/components/TemplatePage/TemplatePage.tsx | 6 +++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/core/src/layout/Header/Header.tsx b/packages/core/src/layout/Header/Header.tsx index efa7502723..1ad7b91687 100644 --- a/packages/core/src/layout/Header/Header.tsx +++ b/packages/core/src/layout/Header/Header.tsx @@ -140,7 +140,7 @@ const TypeFragment = ({ const TitleFragment = ({ pageTitle, classes, tooltip }: TitleFragmentProps) => { const FinalTitle = ( - + {pageTitle} ); @@ -166,7 +166,11 @@ const SubtitleFragment = ({ classes, subtitle }: SubtitleFragmentProps) => { } return ( - + {subtitle} ); diff --git a/packages/core/src/layout/InfoCard/InfoCard.tsx b/packages/core/src/layout/InfoCard/InfoCard.tsx index cf06a5f0a1..5bb3e19362 100644 --- a/packages/core/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core/src/layout/InfoCard/InfoCard.tsx @@ -125,6 +125,7 @@ type Props = { actionsTopRight?: ReactNode; className?: string; noPadding?: boolean; + titleTypographyProps?: object; }; export const InfoCard = ({ @@ -143,6 +144,7 @@ export const InfoCard = ({ actionsTopRight, className, noPadding, + titleTypographyProps, }: Props): JSX.Element => { const classes = useStyles(); /** @@ -183,6 +185,7 @@ export const InfoCard = ({ title={title} subheader={subheader} style={{ ...headerStyle }} + titleTypographyProps={titleTypographyProps} {...headerProps} /> )} diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx index 876d6dfa66..5354216bd9 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx @@ -75,7 +75,9 @@ export const MultistepJsonForm = ({ return ( - {title} + + {title} +
{ {loading && } {schema && ( - + Date: Wed, 7 Apr 2021 17:52:41 -0500 Subject: [PATCH 013/462] add accessibility for sighted users Signed-off-by: miguelrambalt --- .../components/MultistepJsonForm/MultistepJsonForm.tsx | 8 ++++++-- .../src/components/TemplateCard/TemplateCard.tsx | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx index 5354216bd9..58f5f5cd11 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx @@ -71,10 +71,14 @@ export const MultistepJsonForm = ({ return ( <> - {steps.map(({ title, schema, ...formProps }) => { + {steps.map(({ title, schema, ...formProps }, index) => { return ( - + {title} diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index 25f89f20ab..2ba83fdaae 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -85,7 +85,7 @@ export const TemplateCard = ({ {description} - From ea677c0361a44e6ac76b93ad34c676bc58f9c72e Mon Sep 17 00:00:00 2001 From: miguelrambalt Date: Thu, 8 Apr 2021 11:47:54 -0500 Subject: [PATCH 014/462] add header accessibility in create Signed-off-by: miguelrambalt --- .../core/src/layout/ContentHeader/ContentHeader.tsx | 7 ++++++- packages/core/src/layout/ItemCard/ItemCardHeader.tsx | 12 ++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/core/src/layout/ContentHeader/ContentHeader.tsx b/packages/core/src/layout/ContentHeader/ContentHeader.tsx index e9fba56358..3ccf8f894c 100644 --- a/packages/core/src/layout/ContentHeader/ContentHeader.tsx +++ b/packages/core/src/layout/ContentHeader/ContentHeader.tsx @@ -66,7 +66,12 @@ const DefaultTitle = ({ title = 'Unknown page', className, }: DefaultTitleProps) => ( - + {title} ); diff --git a/packages/core/src/layout/ItemCard/ItemCardHeader.tsx b/packages/core/src/layout/ItemCard/ItemCardHeader.tsx index 17c4a19e58..ebf419cba0 100644 --- a/packages/core/src/layout/ItemCard/ItemCardHeader.tsx +++ b/packages/core/src/layout/ItemCard/ItemCardHeader.tsx @@ -77,8 +77,16 @@ export const ItemCardHeader = (props: ItemCardHeaderProps) => { const classes = useStyles(props); return (
- {subtitle && {subtitle}} - {title && {title}} + {subtitle && ( + + {subtitle} + + )} + {title && ( + + {title} + + )} {children}
); From 875614c9b629508043bb944db1abdd61b0edb20a Mon Sep 17 00:00:00 2001 From: miguelrambalt Date: Thu, 8 Apr 2021 12:04:44 -0500 Subject: [PATCH 015/462] add color for accessibility in Lifecycle for headers Signed-off-by: miguelrambalt --- packages/core/src/components/Lifecycle/Lifecycle.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/Lifecycle/Lifecycle.tsx b/packages/core/src/components/Lifecycle/Lifecycle.tsx index d388452cdc..585f7a5c18 100644 --- a/packages/core/src/components/Lifecycle/Lifecycle.tsx +++ b/packages/core/src/components/Lifecycle/Lifecycle.tsx @@ -25,7 +25,7 @@ type Props = CSS.Properties & { const useStyles = makeStyles({ alpha: { - color: '#d00150', + color: '#ffffff', fontFamily: 'serif', fontWeight: 'normal', fontStyle: 'italic', From 5d8339cfee72a399a748e80b025f40009d409559 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 9 Apr 2021 14:26:37 +0200 Subject: [PATCH 016/462] some more tests Signed-off-by: blam --- cypress/cypress.json | 2 +- cypress/src/integration/integrations.ts | 45 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 cypress/src/integration/integrations.ts diff --git a/cypress/cypress.json b/cypress/cypress.json index ebbbe59901..59f7516c47 100644 --- a/cypress/cypress.json +++ b/cypress/cypress.json @@ -1,5 +1,5 @@ { - "baseUrl": "http://localhost:7000", + "baseUrl": "http://localhost:3000", "integrationFolder": "./src/integration", "supportFile": "./src/support", "fixturesFolder": "./src/fixures", diff --git a/cypress/src/integration/integrations.ts b/cypress/src/integration/integrations.ts new file mode 100644 index 0000000000..76d0b6b28a --- /dev/null +++ b/cypress/src/integration/integrations.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/// +import 'os'; + +describe('Integrations', () => { + describe('ReadTree', () => { + // it('should work for azure', () => { + // cy.loginAsGuest(); + + // cy.visit('/catalog-import'); + + // cy.get('input[name=url]').type( + // 'https://dev.azure.com/backstage-verification/_git/test-repo?path=%2Fnested%2F*', + // ); + + // cy.contains('Analyze').click(); + // }); + + it('should work for github', () => { + cy.loginAsGuest(); + + cy.visit('/catalog-import'); + + cy.get('input[name=url]').type( + 'https://github.com/backstage-verification/test-repo', + ); + + cy.contains('Analyze').click(); + }); + }); +}); From 84c54474dd43e873b3662f1824cdcf08759baf55 Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Thu, 1 Apr 2021 15:24:33 +0200 Subject: [PATCH 017/462] fix: Forward user token to scaffolder taskworker for subsequent api requests Signed-off-by: Erik Larsson --- .changeset/eight-plums-hide.md | 5 +++++ plugins/scaffolder-backend/src/scaffolder/actions/types.ts | 4 ++++ .../scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts | 1 + plugins/scaffolder-backend/src/scaffolder/tasks/types.ts | 1 + plugins/scaffolder-backend/src/service/router.ts | 6 +++++- 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .changeset/eight-plums-hide.md diff --git a/.changeset/eight-plums-hide.md b/.changeset/eight-plums-hide.md new file mode 100644 index 0000000000..bf34b7ee63 --- /dev/null +++ b/.changeset/eight-plums-hide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Forward user token to scaffolder taskworker for subsequent api requests diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts index 955cb72de9..fbe18b848e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts @@ -32,6 +32,10 @@ export type ActionContext = { logger: Logger; logStream: Writable; + /** + * User token forwarded from initial request, for use in subsequent api requests + */ + token?: string | undefined; workspacePath: string; input: Input; output(name: string, value: JsonValue): void; diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index 3a846f79a5..a6c97027d2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -134,6 +134,7 @@ export class TaskWorker { logger: taskLogger, logStream: stream, input, + token: task.spec.token, workspacePath, async createTemporaryDirectory() { const tmpDir = await fs.mkdtemp( diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index 6963817a1e..a5affc418d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -44,6 +44,7 @@ export type DbTaskEventRow = { export type TaskSpec = { baseUrl?: string; + token?: string | undefined; values: JsonObject; steps: Array<{ id: string; diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 1e2891cfb8..c5f42edd76 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -358,8 +358,9 @@ export async function createRouter( .post('/v2/tasks', async (req, res) => { const templateName: string = req.body.templateName; const values: TemplaterValues = req.body.values; + const token = getBearerToken(req.headers.authorization); const template = await entityClient.findTemplate(templateName, { - token: getBearerToken(req.headers.authorization), + token, }); let taskSpec; @@ -386,6 +387,7 @@ export async function createRouter( taskSpec = { baseUrl, + token, values, steps: template.spec.steps.map((step, index) => ({ ...step, @@ -412,6 +414,8 @@ export async function createRouter( if (!task) { throw new NotFoundError(`Task with id ${taskId} does not exist`); } + // Do not disclose token + delete task.spec.token; res.status(200).json(task); }) .get('/v2/tasks/:taskId/eventstream', async (req, res) => { From 008e8a8b1c02f7b78cd8547e9a07c47ea6ce2259 Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Fri, 2 Apr 2021 00:24:22 +0200 Subject: [PATCH 018/462] vale Signed-off-by: Erik Larsson --- .changeset/eight-plums-hide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/eight-plums-hide.md b/.changeset/eight-plums-hide.md index bf34b7ee63..d1f8bcecfe 100644 --- a/.changeset/eight-plums-hide.md +++ b/.changeset/eight-plums-hide.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend': patch --- -Forward user token to scaffolder taskworker for subsequent api requests +Forward user token to scaffolder task for subsequent api requests From a41a912f2df7988ef9fd6674d42164859b5cd218 Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Fri, 9 Apr 2021 23:33:15 +0200 Subject: [PATCH 019/462] Store secrets in separate db column Signed-off-by: Erik Larsson --- .../migrations/20210409225200_secrets.js | 38 +++++++++++++++++++ .../src/scaffolder/tasks/DatabaseTaskStore.ts | 13 ++++++- .../src/scaffolder/tasks/StorageTaskBroker.ts | 8 +++- .../src/scaffolder/tasks/TaskWorker.ts | 2 +- .../src/scaffolder/tasks/types.ts | 14 +++++-- .../scaffolder-backend/src/service/router.ts | 9 +++-- 6 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 plugins/scaffolder-backend/migrations/20210409225200_secrets.js diff --git a/plugins/scaffolder-backend/migrations/20210409225200_secrets.js b/plugins/scaffolder-backend/migrations/20210409225200_secrets.js new file mode 100644 index 0000000000..e1bd6d2a51 --- /dev/null +++ b/plugins/scaffolder-backend/migrations/20210409225200_secrets.js @@ -0,0 +1,38 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('tasks', table => { + table + .string('secrets') + .nullable() + .comment('JSON encoded secrets to authenticate tasks with'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('tasks', table => { + table.dropColumn('secrets'); + }); +}; diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts index 91264bd3e2..fdc403ec65 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts @@ -24,6 +24,7 @@ import { DbTaskRow, Status, TaskEventType, + TaskSecrets, TaskSpec, TaskStore, TaskStoreEmitOptions, @@ -42,6 +43,7 @@ export type RawDbTaskRow = { status: Status; last_heartbeat_at?: string; created_at: string; + secrets?: string; }; export type RawDbTaskEventRow = { @@ -71,23 +73,29 @@ export class DatabaseTaskStore implements TaskStore { } try { const spec = JSON.parse(result.spec); + const secrets = result.secrets ? JSON.parse(result.secrets) : undefined; return { id: result.id, spec, status: result.status, lastHeartbeatAt: result.last_heartbeat_at, createdAt: result.created_at, + secrets, }; } catch (error) { throw new Error(`Failed to parse spec of task '${taskId}', ${error}`); } } - async createTask(spec: TaskSpec): Promise<{ taskId: string }> { + async createTask( + spec: TaskSpec, + secrets?: TaskSecrets, + ): Promise<{ taskId: string }> { const taskId = uuid(); await this.db('tasks').insert({ id: taskId, spec: JSON.stringify(spec), + secrets: secrets ? JSON.stringify(secrets) : undefined, status: 'open', }); return { taskId }; @@ -119,12 +127,14 @@ export class DatabaseTaskStore implements TaskStore { try { const spec = JSON.parse(task.spec); + const secrets = task.secrets ? JSON.parse(task.spec) : undefined; return { id: task.id, spec, status: 'processing', lastHeartbeatAt: task.last_heartbeat_at, createdAt: task.created_at, + secrets, }; } catch (error) { throw new Error(`Failed to parse spec of task '${task.id}', ${error}`); @@ -209,6 +219,7 @@ export class DatabaseTaskStore implements TaskStore { }) .update({ status, + secrets: undefined, }); if (updateCount !== 1) { throw new ConflictError( diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts index fb1f4ab422..8f30afde6f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts @@ -18,6 +18,7 @@ import { Logger } from 'winston'; import { CompletedTaskState, Task, + TaskSecrets, TaskSpec, TaskStore, TaskBroker, @@ -136,8 +137,11 @@ export class StorageTaskBroker implements TaskBroker { } } - async dispatch(spec: TaskSpec): Promise { - const taskRow = await this.storage.createTask(spec); + async dispatch( + spec: TaskSpec, + secrets?: TaskSecrets, + ): Promise { + const taskRow = await this.storage.createTask(spec, secrets); this.signalDispatch(); return { taskId: taskRow.taskId, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index a6c97027d2..acdf32a383 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -134,7 +134,7 @@ export class TaskWorker { logger: taskLogger, logStream: stream, input, - token: task.spec.token, + token: task.secrets?.identityToken, workspacePath, async createTemporaryDirectory() { const tmpDir = await fs.mkdtemp( diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index a5affc418d..56d2f25e02 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -31,6 +31,7 @@ export type DbTaskRow = { status: Status; createdAt: string; lastHeartbeatAt?: string; + secrets?: TaskSecrets; }; export type TaskEventType = 'completion' | 'log'; @@ -44,7 +45,6 @@ export type DbTaskEventRow = { export type TaskSpec = { baseUrl?: string; - token?: string | undefined; values: JsonObject; steps: Array<{ id: string; @@ -55,12 +55,17 @@ export type TaskSpec = { output: { [name: string]: string }; }; +export type TaskSecrets = { + identityToken: string | undefined; +}; + export type DispatchResult = { taskId: string; }; export interface Task { spec: TaskSpec; + secrets?: TaskSecrets; done: boolean; emitLog(message: string, metadata?: JsonValue): Promise; complete(result: CompletedTaskState, metadata?: JsonValue): Promise; @@ -69,7 +74,7 @@ export interface Task { export interface TaskBroker { claim(): Promise; - dispatch(spec: TaskSpec): Promise; + dispatch(spec: TaskSpec, secrets?: TaskSecrets): Promise; vacuumTasks(timeoutS: { timeoutS: number }): Promise; observe( options: { @@ -94,7 +99,10 @@ export type TaskStoreGetEventsOptions = { }; export interface TaskStore { - createTask(task: TaskSpec): Promise<{ taskId: string }>; + createTask( + task: TaskSpec, + secrets?: TaskSecrets, + ): Promise<{ taskId: string }>; getTask(taskId: string): Promise; claimTask(): Promise; completeTask(options: { diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index c5f42edd76..c77007a573 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -387,7 +387,6 @@ export async function createRouter( taskSpec = { baseUrl, - token, values, steps: template.spec.steps.map((step, index) => ({ ...step, @@ -404,7 +403,9 @@ export async function createRouter( ); } - const result = await taskBroker.dispatch(taskSpec); + const result = await taskBroker.dispatch(taskSpec, { + identityToken: token, + }); res.status(201).json({ id: result.taskId }); }) @@ -414,8 +415,8 @@ export async function createRouter( if (!task) { throw new NotFoundError(`Task with id ${taskId} does not exist`); } - // Do not disclose token - delete task.spec.token; + // Do not disclose secrets + delete task.secrets; res.status(200).json(task); }) .get('/v2/tasks/:taskId/eventstream', async (req, res) => { From 46995e92bf660012bef31b6a4aefa1f13096ad3e Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Sun, 11 Apr 2021 10:01:52 +0200 Subject: [PATCH 020/462] Use text column type Signed-off-by: Erik Larsson --- plugins/scaffolder-backend/migrations/20210409225200_secrets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/migrations/20210409225200_secrets.js b/plugins/scaffolder-backend/migrations/20210409225200_secrets.js index e1bd6d2a51..e96f406782 100644 --- a/plugins/scaffolder-backend/migrations/20210409225200_secrets.js +++ b/plugins/scaffolder-backend/migrations/20210409225200_secrets.js @@ -22,7 +22,7 @@ exports.up = async function up(knex) { await knex.schema.alterTable('tasks', table => { table - .string('secrets') + .text('secrets') .nullable() .comment('JSON encoded secrets to authenticate tasks with'); }); From 47c96fb5396419d715298202ab60196a33fb1a3e Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Sun, 11 Apr 2021 15:35:49 +0200 Subject: [PATCH 021/462] Fix bugs, add tests Signed-off-by: Erik Larsson --- .../actions/builtin/catalog/register.ts | 11 ++++--- .../src/scaffolder/tasks/DatabaseTaskStore.ts | 4 +-- .../tasks/StorageTaskBroker.test.ts | 30 ++++++++++++++++++- .../src/scaffolder/tasks/StorageTaskBroker.ts | 6 ++++ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts index 8ee98f5d20..5d169a73fd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -95,10 +95,13 @@ export function createCatalogRegisterAction(options: { ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`); - const result = await catalogClient.addLocation({ - type: 'url', - target: catalogInfoUrl, - }); + const result = await catalogClient.addLocation( + { + type: 'url', + target: catalogInfoUrl, + }, + ...(ctx.token ? [{ token: ctx.token }] : []), + ); if (result.entities.length >= 1) { const { kind, name, namespace } = getEntityName(result.entities[0]); ctx.output('entityRef', `${kind}:${namespace}/${name}`); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts index fdc403ec65..1f1228baf8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts @@ -127,7 +127,7 @@ export class DatabaseTaskStore implements TaskStore { try { const spec = JSON.parse(task.spec); - const secrets = task.secrets ? JSON.parse(task.spec) : undefined; + const secrets = task.secrets ? JSON.parse(task.secrets) : undefined; return { id: task.id, spec, @@ -219,7 +219,7 @@ export class DatabaseTaskStore implements TaskStore { }) .update({ status, - secrets: undefined, + secrets: null as any, }); if (updateCount !== 1) { throw new ConflictError( diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts index fd2de30332..4a025c25e2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts @@ -21,7 +21,7 @@ import { import { ConfigReader } from '@backstage/config'; import { DatabaseTaskStore } from './DatabaseTaskStore'; import { StorageTaskBroker, TaskAgent } from './StorageTaskBroker'; -import { TaskSpec, DbTaskEventRow } from './types'; +import { TaskSecrets, TaskSpec, DbTaskEventRow } from './types'; async function createStore(): Promise { const manager = SingleConnectionDatabaseManager.fromConfig( @@ -39,6 +39,7 @@ async function createStore(): Promise { describe('StorageTaskBroker', () => { let storage: DatabaseTaskStore; + const fakeSecrets = { identityToken: 'secret' } as TaskSecrets; beforeAll(async () => { storage = await createStore(); @@ -78,6 +79,13 @@ describe('StorageTaskBroker', () => { await expect(taskC.spec.steps[0].id).toBe('c'); }); + it('should store secrets', async () => { + const broker = new StorageTaskBroker(storage, logger); + await broker.dispatch({} as TaskSpec, fakeSecrets); + const task = await broker.claim(); + expect(task.secrets).toEqual(fakeSecrets); + }, 10000); + it('should complete a task', async () => { const broker = new StorageTaskBroker(storage, logger); const dispatchResult = await broker.dispatch({} as TaskSpec); @@ -87,6 +95,16 @@ describe('StorageTaskBroker', () => { expect(taskRow.status).toBe('completed'); }, 10000); + it('should remove secrets after completing a task', async () => { + const broker = new StorageTaskBroker(storage, logger); + const dispatchResult = await broker.dispatch({} as TaskSpec, fakeSecrets); + const task = await broker.claim(); + await task.complete('completed'); + const taskRow = await storage.getTask(dispatchResult.taskId); + expect(taskRow.status).toBe('completed'); + expect(taskRow.secrets).toBeUndefined(); + }, 10000); + it('should fail a task', async () => { const broker = new StorageTaskBroker(storage, logger); const dispatchResult = await broker.dispatch({} as TaskSpec); @@ -96,6 +114,16 @@ describe('StorageTaskBroker', () => { expect(taskRow.status).toBe('failed'); }); + it('should remove secrets afteer failing a task', async () => { + const broker = new StorageTaskBroker(storage, logger); + const dispatchResult = await broker.dispatch({} as TaskSpec, fakeSecrets); + const task = await broker.claim(); + await task.complete('failed'); + const taskRow = await storage.getTask(dispatchResult.taskId); + expect(taskRow.status).toBe('failed'); + expect(taskRow.secrets).toBeUndefined(); + }); + it('multiple brokers should be able to observe a single task', async () => { const broker1 = new StorageTaskBroker(storage, logger); const broker2 = new StorageTaskBroker(storage, logger); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts index 8f30afde6f..6a82fa53ca 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts @@ -49,6 +49,10 @@ export class TaskAgent implements Task { return this.state.spec; } + get secrets() { + return this.state.secrets; + } + async getWorkspaceName() { return this.state.taskId; } @@ -102,6 +106,7 @@ export class TaskAgent implements Task { interface TaskState { spec: TaskSpec; taskId: string; + secrets?: TaskSecrets; } function defer() { @@ -127,6 +132,7 @@ export class StorageTaskBroker implements TaskBroker { { taskId: pendingTask.id, spec: pendingTask.spec, + secrets: pendingTask.secrets, }, this.storage, this.logger, From 382531e50195a22cbde71b91e2107a184a40b09c Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 12 Apr 2021 10:21:42 +0200 Subject: [PATCH 022/462] chore: more work towards fixing Signed-off-by: blam --- cypress/src/integration/integrations.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cypress/src/integration/integrations.ts b/cypress/src/integration/integrations.ts index 76d0b6b28a..839159d34e 100644 --- a/cypress/src/integration/integrations.ts +++ b/cypress/src/integration/integrations.ts @@ -38,6 +38,11 @@ describe('Integrations', () => { cy.get('input[name=url]').type( 'https://github.com/backstage-verification/test-repo', ); + cy.request('/api/catalog/locations', { + target: + 'https://github.com/backstage-verification/test-repo/blob/main/**/*', + type: 'url', + }); cy.contains('Analyze').click(); }); From fd3b689217013abc353cf42d81d28ec5f34fddeb Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Tue, 13 Apr 2021 16:24:04 +0200 Subject: [PATCH 023/462] Added test that secrets are not divulged Signed-off-by: Erik Larsson --- .../tasks/StorageTaskBroker.test.ts | 2 +- .../src/service/router.test.ts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts index 4a025c25e2..e2386fae37 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts @@ -114,7 +114,7 @@ describe('StorageTaskBroker', () => { expect(taskRow.status).toBe('failed'); }); - it('should remove secrets afteer failing a task', async () => { + it('should remove secrets after failing a task', async () => { const broker = new StorageTaskBroker(storage, logger); const dispatchResult = await broker.dispatch({} as TaskSpec, fakeSecrets); const task = await broker.claim(); diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index f01b4f8c95..bb52edaaea 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -301,4 +301,27 @@ describe('createRouter', () => { expect(response.status).toEqual(201); }); }); + + describe('GET /v2/tasks/:taskId', () => { + it('does not divulge secrets', async () => { + const postResponse = await request(app) + .post('/v2/tasks') + .set('Authorization', 'Bearer secret') + .send({ + templateName: 'create-react-app-template', + values: { + storePath: 'https://github.com/backstage/backstage', + component_id: '123', + name: 'test', + use_typescript: false, + }, + }); + + const response = await request(app) + .get(`/v2/tasks/${postResponse.body.id}`) + .send(); + expect(response.status).toEqual(200); + expect(response.body.secrets).toBeUndefined(); + }); + }); }); From 4e26ae5820ac89a94b2380d4e120bd15fca5e18c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 31 Mar 2021 16:29:18 +0200 Subject: [PATCH 024/462] Initial catalog proccessing rework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Co-authored-by: Fredrik Adelöw Co-authored-by: Tim Signed-off-by: Johan Haals --- .../20210302150147_refresh_state.js | 75 +++++++++ plugins/catalog-backend/package.json | 4 +- .../src/next/CatalogProcessingEngineImpl.ts | 125 ++++++++++++++ .../next/CatalogProcessingOrchestratorImpl.ts | 153 +++++++++++++++++ .../src/next/DatabaseLocationProvider.ts | 65 ++++++++ .../src/next/LocationServiceImpl.ts | 70 ++++++++ .../src/next/LocationStoreImpl.ts | 114 +++++++++++++ .../src/next/LocationToEntity.ts | 39 +++++ .../src/next/ProcessingStateManagerImpl.ts | 65 ++++++++ .../next/database/ProcessingDatabaseImpl.ts | 156 ++++++++++++++++++ .../src/next/database/types.ts | 68 ++++++++ plugins/catalog-backend/src/next/types.ts | 103 ++++++++++++ 12 files changed, 1036 insertions(+), 1 deletion(-) create mode 100644 plugins/catalog-backend/migrations/20210302150147_refresh_state.js create mode 100644 plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts create mode 100644 plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts create mode 100644 plugins/catalog-backend/src/next/DatabaseLocationProvider.ts create mode 100644 plugins/catalog-backend/src/next/LocationServiceImpl.ts create mode 100644 plugins/catalog-backend/src/next/LocationStoreImpl.ts create mode 100644 plugins/catalog-backend/src/next/LocationToEntity.ts create mode 100644 plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts create mode 100644 plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts create mode 100644 plugins/catalog-backend/src/next/database/types.ts create mode 100644 plugins/catalog-backend/src/next/types.ts diff --git a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js new file mode 100644 index 0000000000..ae8a02c785 --- /dev/null +++ b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js @@ -0,0 +1,75 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.createTable('refresh_state', table => { + table.comment('Location Refresh states'); + table.text('id').primary().notNullable().comment('Primary id'); + table + .text('entity_ref') + .primary() + .notNullable() + .comment('A reference to the entity that the refresh state is tied to'); + table + .text('unprocessed_entity') + .notNullable() + .comment( + 'The unprocessed entity (in its source form, before being run through all of the processors) as JSON', + ); + table + .text('processed_entity') + .nullable() + .comment( + 'The processed entity (after running through all processors, but before being stitched together with state and relations) as JSON', + ); + table + .text('cache') + .nullable() + .comment( + 'Cache information tied to the refreshing of this entity, such as etag information or actual response caching', + ); + table + .text('errors') + .notNullable() + .comment('JSON array containing all errors related to entity'); + table + .dateTime('next_update_at') + .notNullable() + .comment('Timestamp of when entity should be updated'); + table + .dateTime('last_discovery_at') + .notNullable() + .comment('The last timestamp of which this entity was discovered'); + table.index('entity_ref', 'entity_ref_idx'); + table.index('next_update_at', 'next_update_at_idx'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('refresh_state', table => { + table.dropIndex([], 'entity_ref_idx'); + table.dropIndex([], 'next_update_at_idx'); + }); + await knex.schema.dropTable('refresh_state'); +}; diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 531caa9ea5..2661025000 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -33,6 +33,7 @@ "@backstage/backend-common": "^0.6.1", "@backstage/catalog-model": "^0.7.5", "@backstage/config": "^0.1.4", + "@backstage/core": "^0.7.3", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/plugin-search-backend-node": "^0.1.2", @@ -59,7 +60,8 @@ "winston": "^3.2.1", "yaml": "^1.9.2", "yn": "^4.0.0", - "yup": "^0.29.3" + "yup": "^0.29.3", + "zen-observable": "^0.8.15" }, "devDependencies": { "@backstage/cli": "^0.6.6", diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts new file mode 100644 index 0000000000..e94cdf2f31 --- /dev/null +++ b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts @@ -0,0 +1,125 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Subscription } from '@backstage/core'; +import { + CatalogProcessingEngine, + EntityProvider, + EntityMessage, + ProcessingStateManager, + CatalogProcessingOrchestrator, +} from './types'; + +import { JsonObject } from '@backstage/config'; +import { EntitiesCatalog } from '../catalog/types'; +import { Logger } from 'winston'; + +export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { + private subscriptions: Subscription[] = []; + private running: boolean = false; + + constructor( + private readonly logger: Logger, + private readonly entityProviders: EntityProvider[], + private readonly stateManager: ProcessingStateManager, + private readonly orchestrator: CatalogProcessingOrchestrator, + private readonly entitiesCatalog: EntitiesCatalog, + ) {} + + async start() { + for (const provider of this.entityProviders) { + const subscription = provider + .entityChange$() + .subscribe({ next: m => this.onNext(m) }); + this.subscriptions.push(subscription); + } + + this.running = true; + + while (this.running) { + const { entity, state, eager } = await this.stateManager.pop(); + + const { + completeEntities, + deferredEntites, + errors, + } = await this.orchestrator.process({ + entity, + state, + eager, + }); + + for (const error of errors) { + this.logger.warn(error.message); + } + + for (const deferred of deferredEntites) { + this.stateManager.setResult({ + request: { entity: deferred, state: new Map() }, + nextRefresh: 'now()', + }); + } + + if (completeEntities.length) { + await this.entitiesCatalog.batchAddOrUpdateEntities( + completeEntities.map(e => ({ + entity: e, + relations: [], + })), + { + locationId: 'xyz', + dryRun: false, + outputEntities: true, + }, + ); + } + } + } + + async stop() { + this.running = false; + + for (const subscription of this.subscriptions) { + subscription.unsubscribe(); + } + } + private async onNext(message: EntityMessage) { + if ('all' in message) { + // TODO unhandled rejection + await Promise.all( + message.all.map(entity => + this.stateManager.setResult({ + request: { entity, state: new Map() }, + nextRefresh: 'now()', + }), + ), + ); + } + + if ('added' in message) { + await Promise.all( + message.added.map(entity => + this.stateManager.setResult({ + request: { entity, state: new Map() }, + nextRefresh: 'now()', + }), + ), + ); + + // TODO deletions of message.removed + } + } +} diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts new file mode 100644 index 0000000000..f78ebfbef2 --- /dev/null +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -0,0 +1,153 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + LocationSpec, + stringifyLocationReference, +} from '@backstage/catalog-model'; +import { JsonObject } from '@backstage/config'; +import { + CatalogProcessor, + CatalogProcessorEmit, + CatalogProcessorParser, + CatalogProcessorResult, +} from '../ingestion/processors'; +import { CatalogProcessingOrchestrator, EntityProcessingError } from './types'; +import { Logger } from 'winston'; +import * as result from '../ingestion/processors/results'; +import { locationToEntity } from './LocationToEntity'; + +export class CatalogProcessingOrchestratorImpl + implements CatalogProcessingOrchestrator { + constructor( + private readonly options: { + processors: CatalogProcessor[]; + logger: Logger; + parser: CatalogProcessorParser; + }, + ) {} + + async process(request: { + entity: Entity; + eager?: boolean | undefined; + state: Map; + }): Promise<{ + state: Map; + completeEntities: Entity[]; + deferredEntites: Entity[]; + errors: EntityProcessingError[]; + }> { + const { entity, eager, state } = request; + const completedEntities: Entity[] = []; + const deferredEntites: Entity[] = []; + const errors: EntityProcessingError[] = []; + + if (eager) { + const stack = [entity]; + const emit = (i: CatalogProcessorResult) => stack.push(i); + while (stack.length) { + const item = stack.pop(); + stack.push(); + } + } else { + const emit = (i: CatalogProcessorResult) => { + if (i.type === 'entity') { + deferredEntites.push(i.entity); + } + if (i.type === 'location') { + deferredEntites.push( + locationToEntity(i.location.type, i.location.type), + ); + } + }; + if (entity.spec) { + if (entity.spec.kind === 'Location') { + this.handleLocation( + { + type: (entity.spec.type as unknown) as string, + target: (entity.spec.target as unknown) as string, + }, + emit, + ); + } + } + } + + return { + deferredEntites, + completeEntities: completedEntities, + errors, + state, + }; + } + + private async handleLocation( + location: LocationSpec, + emit: CatalogProcessorEmit, + ) { + const { processors, logger } = this.options; + + const validatedEmit: CatalogProcessorEmit = emitResult => { + if (emitResult.type === 'relation') { + throw new Error('readLocation may not emit entity relations'); + } + if ( + emitResult.type === 'location' && + emitResult.location.type === location.type && + emitResult.location.target === location.target + ) { + // Ignore self-referential locations silently (this can happen for + // example if you use a glob target like "**/*.yaml" in a Location + // entity) + return; + } + emit(emitResult); + }; + + for (const processor of processors) { + if (processor.readLocation) { + try { + if ( + await processor.readLocation( + location, + // TODO: figure out how this will work in the new processing system - locations from PRs might be optional + location.presence !== 'required', + validatedEmit, + this.options.parser, + ) + ) { + return; + } + } catch (e) { + const message = `Processor ${ + processor.constructor.name + } threw an error while reading location ${stringifyLocationReference( + location, + )}, ${e}`; + emit(result.generalError(location, message)); + logger.warn(message); + } + } + } + + const message = `No processor was able to read location ${stringifyLocationReference( + location, + )}`; + emit(result.inputError(location, message)); + logger.warn(message); + } +} diff --git a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts b/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts new file mode 100644 index 0000000000..b56dfa1158 --- /dev/null +++ b/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts @@ -0,0 +1,65 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Observable } from '@backstage/core'; +import { EntityProvider, LocationStore, EntityMessage } from './types'; +import ObservableImpl from 'zen-observable'; +import { locationToEntity, locationToEntityName } from './LocationToEntity'; + +export class DatabaseLocationProvider implements EntityProvider { + private subscribers = new Set< + ZenObservable.SubscriptionObserver + >(); + + constructor(private readonly store: LocationStore) { + store.location$().subscribe({ + next: locations => { + if ('all' in locations) { + this.notify({ + all: locations.all.map(l => locationToEntity(l.type, l.target)), + }); + } else { + this.notify({ + added: locations.added.map(l => locationToEntity(l.type, l.target)), + removed: locations.removed.map(l => + locationToEntityName(l.type, l.target), + ), + }); + } + }, + }); + } + + private notify(message: EntityMessage) { + for (const subscriber of this.subscribers) { + subscriber.next(message); + } + } + + entityChange$(): Observable { + return new ObservableImpl(subscriber => { + this.store.listLocations().then(locations => { + subscriber.next({ + all: locations.map(l => locationToEntity(l.type, l.target)), + }); + this.subscribers.add(subscriber); + }); + return () => { + this.subscribers.delete(subscriber); + }; + }); + } +} diff --git a/plugins/catalog-backend/src/next/LocationServiceImpl.ts b/plugins/catalog-backend/src/next/LocationServiceImpl.ts new file mode 100644 index 0000000000..29b41e0a09 --- /dev/null +++ b/plugins/catalog-backend/src/next/LocationServiceImpl.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { LocationSpec, Location, Entity } from '@backstage/catalog-model'; +import { + LocationService, + LocationStore, + CatalogProcessingOrchestrator, +} from './types'; + +export class LocationServiceImpl implements LocationService { + constructor( + private readonly store: LocationStore, + private readonly orchestrator: CatalogProcessingOrchestrator, + ) {} + + async createLocation( + spec: LocationSpec, + dryRun: boolean, + ): Promise<{ location: Location; entities: Entity[] }> { + if (dryRun) { + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + name: `${spec.type}:${spec.target}`, + namespace: 'default', + }, + spec: { + location: { type: spec.type, target: spec.target }, + }, + }; + const processed = await this.orchestrator.process({ + entity, + eager: true, + state: new Map(), + }); + + return { + location: { ...spec, id: `${spec.type}:${spec.target}` }, + entities: processed.completeEntities, + }; + } + + const location = await this.store.createLocation(spec); + return { location, entities: [] }; + } + + listLocations(): Promise { + return this.store.listLocations(); + } + getLocation(id: string): Promise { + return this.store.getLocation(id); + } + deleteLocation(id: string): Promise { + return this.store.deleteLocation(id); + } +} diff --git a/plugins/catalog-backend/src/next/LocationStoreImpl.ts b/plugins/catalog-backend/src/next/LocationStoreImpl.ts new file mode 100644 index 0000000000..89247056d6 --- /dev/null +++ b/plugins/catalog-backend/src/next/LocationStoreImpl.ts @@ -0,0 +1,114 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { LocationSpec, Location } from '@backstage/catalog-model'; +import { CommonDatabase } from '../database'; +import { LocationStore } from './types'; +import { v4 as uuidv4 } from 'uuid'; +import { ConflictError } from '@backstage/errors'; +import { Observable } from '@backstage/core'; +import ObservableImpl from 'zen-observable'; + +export type LocationMessage = + | { all: Location[] } + | { added: Location[]; removed: Location[] }; + +export class LocationStoreImpl implements LocationStore { + private subscribers = new Set< + ZenObservable.SubscriptionObserver + >(); + + constructor(private readonly db: CommonDatabase) {} + + createLocation(spec: LocationSpec): Promise { + return this.db.transaction(async tx => { + // TODO: id should really be type and target combined and not a uuid. + + // Attempt to find a previous location matching the spec + const previousLocations = await this.listLocations(); + const previousLocation = previousLocations.some( + l => spec.type === l.type && spec.target === l.target, + ); + + if (previousLocation) { + throw new ConflictError( + `Location ${spec.type}:${spec.target} already exists`, + ); + } + + const location = await this.db.addLocation(tx, { + id: uuidv4(), + type: spec.type, + target: spec.target, + }); + + this.notifyAddition(location); + + return location; + }); + } + + async listLocations(): Promise { + const dbLocations = await this.db.locations(); + return dbLocations.map(item => ({ + id: item.id, + target: item.target, + type: item.type, + })); + } + + getLocation(id: string): Promise { + return this.db.location(id); + } + + deleteLocation(id: string): Promise { + return this.db.transaction(async tx => { + const location = await this.db.location(id); + if (!location) { + throw new ConflictError(`No location found with with id: ${id}`); + } + await this.db.removeLocation(tx, id); + this.notifyDeletion(location); + }); + } + + private notifyAddition(location: Location) { + for (const subscriber of this.subscribers) { + subscriber.next({ + added: [location], + removed: [], + }); + } + } + + private notifyDeletion(location: Location) { + for (const subscriber of this.subscribers) { + subscriber.next({ + added: [], + removed: [location], + }); + } + } + + location$(): Observable { + return new ObservableImpl(subscriber => { + this.subscribers.add(subscriber); + return () => { + this.subscribers.delete(subscriber); + }; + }); + } +} diff --git a/plugins/catalog-backend/src/next/LocationToEntity.ts b/plugins/catalog-backend/src/next/LocationToEntity.ts new file mode 100644 index 0000000000..28695e14af --- /dev/null +++ b/plugins/catalog-backend/src/next/LocationToEntity.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity, EntityName } from '@backstage/catalog-model'; + +export function locationToEntity(type: string, target: string): Entity { + return { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + name: `${type}:${target}`, + namespace: 'default', + }, + spec: { + location: { type, target }, + }, + }; +} + +export function locationToEntityName(type: string, target: string): EntityName { + return { + kind: 'Location', + namespace: 'default', + name: `${type}:${target}`, + }; +} diff --git a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts new file mode 100644 index 0000000000..d8736cfa77 --- /dev/null +++ b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts @@ -0,0 +1,65 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { JsonObject } from '@backstage/config'; +import { DbRefreshStateRow, ProcessingDatabase } from './database/types'; +import { ProcessingResult, ProcessingStateManager } from './types'; + +export class ProcessingStateManagerImpl implements ProcessingStateManager { + constructor(private readonly db: ProcessingDatabase) {} + + async setResult(result: ProcessingResult) { + await this.db.transaction(async tx => { + this.db.addEntityRefreshState(tx, [ + { + entity: result.request.entity, + nextRefresh: result.nextRefresh, + }, + ]); + }); + } + + async pop(): Promise<{ + entity: Entity; + eager?: boolean | undefined; + state: Map; + }> { + const entities = await new Promise(resolve => + this.popFromQueue(resolve), + ); + const result = entities[0]; + return { + entity: JSON.parse(result.unproccessed_entity) as Entity, + state: new Map(JSON.parse(result.cache)), + }; + } + + async popFromQueue(resolve: (rows: DbRefreshStateRow[]) => void) { + const entities = await this.db.transaction(async tx => { + return this.db.getProcessableEntities(tx, { + processBatchSize: 1, + }); + }); + + if (!entities.length) { + setTimeout(() => this.popFromQueue(resolve), 1000); + return; + } + + resolve(entities); + } +} diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts new file mode 100644 index 0000000000..af0d331199 --- /dev/null +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -0,0 +1,156 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConflictError, NotFoundError } from '@backstage/errors'; +import { Knex } from 'knex'; +import { Transaction } from '../../database'; +import { + ProcessingDatabase, + AddUnprocessedEntitiesOptions, + UpdateProcessedEntityOptions, + GetProcessedEntitiesResult, +} from './types'; +import type { Logger } from 'winston'; +import { Entity } from '@backstage/catalog-model'; +import { v4 as uuid } from 'uuid'; + +export type DbRefreshStateRequest = { + entity: Entity; + nextRefresh: string; // TODO dateTime/ Date? +}; + +export type DbRefreshStateRow = { + id: string; + entity_ref: string; + unprocessed_entity: string; + processed_entity: string; + cache: string; + next_update_at: string; + last_discovery_at: string; // remove? + errors: string; +}; + +class ProcessingDatabaseImpl implements ProcessingDatabase { + constructor( + private readonly database: Knex, + private readonly logger: Logger, + ) {} + + async updateProcessedEntity( + txOpaque: Transaction, + options: UpdateProcessedEntityOptions, + ): Promise { + const tx = txOpaque as Knex.Transaction; + const { id, processedEntity, cache, errors } = options; + const result = await tx('refresh_state') + .update({ + processed_entity: processedEntity, + cache, + errors, + }) + .where('id', id); + if (result === 0) { + throw new NotFoundError(`Processing state not found for ${id}`); + } + + // Update refs table + // Update fragments + } + + async addUnprocessedEntities( + txOpaque: Transaction, + options: AddUnprocessedEntitiesOptions, + ): Promise { + const tx = txOpaque as Knex.Transaction; + + for (const entity of options.unprocessedEntities) { + await tx('refresh_state') + .insert({ + id: uuid(), + entity_ref: stringifyEntityRef(entity), + unprocessed_entity: JSON.stringify(entity), + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + }) + .onConflict('entity_ref') + .merge(['unprocessed_entity', 'last_discovery_at']); + } + } + + async getProcessableEntities( + txOpaque: Transaction, + request: { processBatchSize: number }, + ): Promise { + const tx = txOpaque as Knex.Transaction; + + const items = await tx('refresh_state') + .select() + .where('next_update_at', '<=', tx.fn.now()) + .limit(request.processBatchSize) + .orderBy('next_update_at', 'desc'); + + await tx('refresh_state') + .whereIn( + 'entity_ref', + items.map(i => i.entity_ref), + ) + .update({ + next_update_at: + tx.client.config.client === 'sqlite3' + ? tx.raw(`datetime('now', ?)`, [`10 seconds`]) // TODO: test this in sqlite3 + : tx.raw(`now() + interval '30 seconds'`), + }); + + return items; + } + + async transaction(fn: (tx: Transaction) => Promise): Promise { + try { + let result: T | undefined = undefined; + + await this.database.transaction( + async tx => { + // We can't return here, as knex swallows the return type in case the transaction is rolled back: + // https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/transaction.js#L136 + result = await fn(tx); + }, + { + // If we explicitly trigger a rollback, don't fail. + doNotRejectOnRollback: true, + }, + ); + + return result!; + } catch (e) { + this.logger.debug(`Error during transaction, ${e}`); + + if ( + /SQLITE_CONSTRAINT: UNIQUE/.test(e.message) || + /unique constraint/.test(e.message) + ) { + throw new ConflictError(`Rejected due to a conflicting entity`, e); + } + + throw e; + } + } +} + +function stringifyEntityRef( + entity: Entity, +): Knex.MaybeRawColumn | undefined { + throw new Error('Function not implemented.'); +} diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts new file mode 100644 index 0000000000..310b6b4b7e --- /dev/null +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { JsonObject } from '@backstage/config'; +import { Transaction } from '../../database/types'; + +export type AddUnprocessedEntitiesOptions = { + unprocessedEntities: Entity[]; +}; + +export type AddUnprocessedEntitiesResult = {}; + +export type UpdateProcessedEntityOptions = { + id: string; + processedEntity?: string; + cache?: string; + errors?: string; +}; + +export type RefreshStateItem = { + id: string; + entityRef: string; + unprocessedEntity: string; + processedEntity: string; + nextUpdateAt: string; + lastDiscoveryAt: string; // remove? + cache: JsonObject; + errors: string; +}; + +export type GetProcessedEntitiesResult = { + items: RefreshStateItem; +}; + +export interface ProcessingDatabase { + transaction(fn: (tx: Transaction) => Promise): Promise; + addUnprocessedEntities( + tx: Transaction, + options: AddUnprocessedEntitiesOptions, + ): Promise; + + getProcessableEntities( + txOpaque: Transaction, + request: { processBatchSize: number }, + ): Promise; + + /** + * Updates the + */ + updateProcessedEntity( + txOpaque: Transaction, + options: UpdateProcessedEntityOptions, + ): Promise; +} diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts new file mode 100644 index 0000000000..c7f1e370e0 --- /dev/null +++ b/plugins/catalog-backend/src/next/types.ts @@ -0,0 +1,103 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + Entity, + EntityName, + LocationSpec, + Location, +} from '@backstage/catalog-model'; +import { JsonObject } from '@backstage/config'; +import { Observable } from '@backstage/core'; // << nooo + +export interface LocationEntity { + apiVersion: 'backstage.io/v1alpha1'; + kind: 'Location'; + metadata: { + name: string; // type:target + namespace: 'default'; + }; + spec: { + location: { type: string; target: string }; + }; +} + +export interface LocationService { + createLocation( + spec: LocationSpec, + dryRun: boolean, + ): Promise<{ location: Location; entities: Entity[] }>; + listLocations(): Promise; + getLocation(id: string): Promise; + deleteLocation(id: string): Promise; +} + +export type EntityMessage = + | { all: Entity[] } + | { added: Entity[]; removed: EntityName[] }; + +export interface LocationStore { + // extends EntityProvider + createLocation(spec: LocationSpec): Promise; + listLocations(): Promise; + getLocation(id: string): Promise; + deleteLocation(id: string): Promise; + + location$(): Observable< + { all: Location[] } | { added: Location[]; removed: Location[] } + >; +} + +export interface CatalogProcessingEngine { + start(): Promise; + stop(): Promise; +} + +export interface EntityProvider { + entityChange$(): Observable; +} + +// interface CatalogProcessor {} +type EntityProcessingRequest = { + entity: Entity; + eager?: boolean; + state: Map; // Versions for multiple deployments etc +}; + +export type EntityProcessingError = { + // some error stuff here + message: String; +}; + +type EntityProcessingResult = { + state: Map; + completeEntities: Entity[]; + deferredEntites: Entity[]; + errors: EntityProcessingError[]; +}; + +export interface CatalogProcessingOrchestrator { + process(request: EntityProcessingRequest): Promise; +} + +export type ProcessingResult = { + nextRefresh: string; + request: EntityProcessingRequest; +}; + +export interface ProcessingStateManager { + setResult(result: ProcessingResult): Promise; + pop(): Promise; +} From aaf8233a5ef944c390f45ad8fdefd77f52abf70d Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Thu, 8 Apr 2021 16:48:29 +0200 Subject: [PATCH 025/462] Refactor types and interfaces Signed-off-by: Johan Haals --- .../src/next/CatalogProcessingEngineImpl.ts | 63 +++++++------------ .../next/CatalogProcessingOrchestratorImpl.ts | 24 +++---- .../src/next/ProcessingStateManagerImpl.ts | 57 ++++++++++------- .../next/database/ProcessingDatabaseImpl.ts | 31 +++++---- .../src/next/database/types.ts | 16 ++--- plugins/catalog-backend/src/next/types.ts | 29 ++++++--- 6 files changed, 111 insertions(+), 109 deletions(-) diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts index e94cdf2f31..8a2a0349d6 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts @@ -23,7 +23,6 @@ import { CatalogProcessingOrchestrator, } from './types'; -import { JsonObject } from '@backstage/config'; import { EntitiesCatalog } from '../catalog/types'; import { Logger } from 'winston'; @@ -50,42 +49,33 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { this.running = true; while (this.running) { - const { entity, state, eager } = await this.stateManager.pop(); + const { + id, + entity, + state: intialState, + } = await this.stateManager.getNextProccessingItem(); const { - completeEntities, + completedEntity, deferredEntites, errors, + state, } = await this.orchestrator.process({ entity, - state, - eager, + state: intialState, }); for (const error of errors) { this.logger.warn(error.message); } - for (const deferred of deferredEntites) { - this.stateManager.setResult({ - request: { entity: deferred, state: new Map() }, - nextRefresh: 'now()', - }); - } - - if (completeEntities.length) { - await this.entitiesCatalog.batchAddOrUpdateEntities( - completeEntities.map(e => ({ - entity: e, - relations: [], - })), - { - locationId: 'xyz', - dryRun: false, - outputEntities: true, - }, - ); - } + await this.stateManager.setProcessingItemResult({ + id, + entity: completedEntity, + state, + errors, + }); + await this.stateManager.addProcessingItems({ entities: deferredEntites }); } } @@ -96,28 +86,19 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { subscription.unsubscribe(); } } + private async onNext(message: EntityMessage) { if ('all' in message) { // TODO unhandled rejection - await Promise.all( - message.all.map(entity => - this.stateManager.setResult({ - request: { entity, state: new Map() }, - nextRefresh: 'now()', - }), - ), - ); + await this.stateManager.addProcessingItems({ + entities: message.all, + }); } if ('added' in message) { - await Promise.all( - message.added.map(entity => - this.stateManager.setResult({ - request: { entity, state: new Map() }, - nextRefresh: 'now()', - }), - ), - ); + await this.stateManager.addProcessingItems({ + entities: message.added, + }); // TODO deletions of message.removed } diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index f78ebfbef2..add7db53b3 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -19,14 +19,18 @@ import { LocationSpec, stringifyLocationReference, } from '@backstage/catalog-model'; -import { JsonObject } from '@backstage/config'; import { CatalogProcessor, CatalogProcessorEmit, CatalogProcessorParser, CatalogProcessorResult, } from '../ingestion/processors'; -import { CatalogProcessingOrchestrator, EntityProcessingError } from './types'; +import { + CatalogProcessingOrchestrator, + EntityProcessingError, + EntityProcessingRequest, + EntityProcessingResult, +} from './types'; import { Logger } from 'winston'; import * as result from '../ingestion/processors/results'; import { locationToEntity } from './LocationToEntity'; @@ -41,18 +45,10 @@ export class CatalogProcessingOrchestratorImpl }, ) {} - async process(request: { - entity: Entity; - eager?: boolean | undefined; - state: Map; - }): Promise<{ - state: Map; - completeEntities: Entity[]; - deferredEntites: Entity[]; - errors: EntityProcessingError[]; - }> { + async process( + request: EntityProcessingRequest, + ): Promise { const { entity, eager, state } = request; - const completedEntities: Entity[] = []; const deferredEntites: Entity[] = []; const errors: EntityProcessingError[] = []; @@ -89,7 +85,7 @@ export class CatalogProcessingOrchestratorImpl return { deferredEntites, - completeEntities: completedEntities, + completedEntity, errors, state, }; diff --git a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts index d8736cfa77..872ee78fdb 100644 --- a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts +++ b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts @@ -14,52 +14,61 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; -import { JsonObject } from '@backstage/config'; -import { DbRefreshStateRow, ProcessingDatabase } from './database/types'; -import { ProcessingResult, ProcessingStateManager } from './types'; +import { ProcessingDatabase, RefreshStateItem } from './database/types'; +import { + AddProcessingItemRequest, + ProccessingItem, + ProcessingItemResult, + ProcessingStateManager, +} from './types'; export class ProcessingStateManagerImpl implements ProcessingStateManager { constructor(private readonly db: ProcessingDatabase) {} - async setResult(result: ProcessingResult) { - await this.db.transaction(async tx => { - this.db.addEntityRefreshState(tx, [ - { - entity: result.request.entity, - nextRefresh: result.nextRefresh, - }, - ]); + async setProcessingItemResult(result: ProcessingItemResult) { + return this.db.transaction(async tx => { + await this.db.updateProcessedEntity(tx, { + id: result.id, + processedEntity: result.entity, + errors: JSON.stringify(result.errors), + state: result.state, + }); }); } - async pop(): Promise<{ - entity: Entity; - eager?: boolean | undefined; - state: Map; - }> { - const entities = await new Promise(resolve => + async addProcessingItems(request: AddProcessingItemRequest) { + return this.db.transaction(async tx => { + await this.db.addUnprocessedEntities(tx, { + unprocessedEntities: request.entities, + }); + }); + } + + async getNextProccessingItem(): Promise { + const entities = await new Promise(resolve => this.popFromQueue(resolve), ); - const result = entities[0]; + const { id, state, unprocessedEntity } = entities[0]; return { - entity: JSON.parse(result.unproccessed_entity) as Entity, - state: new Map(JSON.parse(result.cache)), + id, + entity: unprocessedEntity, + state, }; } - async popFromQueue(resolve: (rows: DbRefreshStateRow[]) => void) { + async popFromQueue(resolve: (rows: RefreshStateItem[]) => void) { const entities = await this.db.transaction(async tx => { return this.db.getProcessableEntities(tx, { processBatchSize: 1, }); }); - if (!entities.length) { + // No entities require refresh, wait and try again. + if (!entities.items.length) { setTimeout(() => this.popFromQueue(resolve), 1000); return; } - resolve(entities); + resolve(entities.items); } } diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts index af0d331199..3fe25c1eae 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -21,10 +21,10 @@ import { ProcessingDatabase, AddUnprocessedEntitiesOptions, UpdateProcessedEntityOptions, - GetProcessedEntitiesResult, + GetProcessableEntitiesResult, } from './types'; import type { Logger } from 'winston'; -import { Entity } from '@backstage/catalog-model'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { v4 as uuid } from 'uuid'; export type DbRefreshStateRequest = { @@ -54,11 +54,11 @@ class ProcessingDatabaseImpl implements ProcessingDatabase { options: UpdateProcessedEntityOptions, ): Promise { const tx = txOpaque as Knex.Transaction; - const { id, processedEntity, cache, errors } = options; + const { id, processedEntity, state, errors } = options; const result = await tx('refresh_state') .update({ - processed_entity: processedEntity, - cache, + processed_entity: JSON.stringify(processedEntity), + cache: JSON.stringify(state), errors, }) .where('id', id); @@ -93,7 +93,7 @@ class ProcessingDatabaseImpl implements ProcessingDatabase { async getProcessableEntities( txOpaque: Transaction, request: { processBatchSize: number }, - ): Promise { + ): Promise { const tx = txOpaque as Knex.Transaction; const items = await tx('refresh_state') @@ -114,7 +114,18 @@ class ProcessingDatabaseImpl implements ProcessingDatabase { : tx.raw(`now() + interval '30 seconds'`), }); - return items; + return { + items: items.map(i => ({ + id: i.id, + entityRef: i.entity_ref, + unprocessedEntity: JSON.parse(i.unprocessed_entity) as Entity, + processedEntity: JSON.parse(i.processed_entity) as Entity, + nextUpdateAt: i.next_update_at, + lastDiscoveryAt: i.last_discovery_at, + state: JSON.parse(i.cache), + errors: i.errors, + })), + }; } async transaction(fn: (tx: Transaction) => Promise): Promise { @@ -148,9 +159,3 @@ class ProcessingDatabaseImpl implements ProcessingDatabase { } } } - -function stringifyEntityRef( - entity: Entity, -): Knex.MaybeRawColumn | undefined { - throw new Error('Function not implemented.'); -} diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index 310b6b4b7e..6cd42e690f 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -26,24 +26,24 @@ export type AddUnprocessedEntitiesResult = {}; export type UpdateProcessedEntityOptions = { id: string; - processedEntity?: string; - cache?: string; + processedEntity?: Entity; + state?: Map; errors?: string; }; export type RefreshStateItem = { id: string; entityRef: string; - unprocessedEntity: string; - processedEntity: string; + unprocessedEntity: Entity; + processedEntity: Entity; nextUpdateAt: string; lastDiscoveryAt: string; // remove? - cache: JsonObject; + state: Map; errors: string; }; -export type GetProcessedEntitiesResult = { - items: RefreshStateItem; +export type GetProcessableEntitiesResult = { + items: RefreshStateItem[]; }; export interface ProcessingDatabase { @@ -56,7 +56,7 @@ export interface ProcessingDatabase { getProcessableEntities( txOpaque: Transaction, request: { processBatchSize: number }, - ): Promise; + ): Promise; /** * Updates the diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index c7f1e370e0..58d88636f8 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -69,8 +69,7 @@ export interface EntityProvider { entityChange$(): Observable; } -// interface CatalogProcessor {} -type EntityProcessingRequest = { +export type EntityProcessingRequest = { entity: Entity; eager?: boolean; state: Map; // Versions for multiple deployments etc @@ -81,9 +80,9 @@ export type EntityProcessingError = { message: String; }; -type EntityProcessingResult = { +export type EntityProcessingResult = { state: Map; - completeEntities: Entity[]; + completedEntity: Entity; deferredEntites: Entity[]; errors: EntityProcessingError[]; }; @@ -92,12 +91,24 @@ export interface CatalogProcessingOrchestrator { process(request: EntityProcessingRequest): Promise; } -export type ProcessingResult = { - nextRefresh: string; - request: EntityProcessingRequest; +export type ProcessingItemResult = { + id: string; + entity: Entity; + state: Map; + errors: EntityProcessingError[]; }; +export type AddProcessingItemRequest = { + entities: Entity[]; +}; + +export type ProccessingItem = { + id: string; + entity: Entity; + state: Map; +}; export interface ProcessingStateManager { - setResult(result: ProcessingResult): Promise; - pop(): Promise; + setProcessingItemResult(result: ProcessingItemResult): Promise; + getNextProccessingItem(): Promise; + addProcessingItems(request: AddProcessingItemRequest): Promise; } From abfbacba46aae31105164ff5a570f81cc78b013b Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 9 Apr 2021 16:22:18 +0200 Subject: [PATCH 026/462] Make entity ref unique Signed-off-by: Johan Haals --- .../catalog-backend/migrations/20210302150147_refresh_state.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js index ae8a02c785..6ee10531eb 100644 --- a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js @@ -25,7 +25,7 @@ exports.up = async function up(knex) { table.text('id').primary().notNullable().comment('Primary id'); table .text('entity_ref') - .primary() + .unique() .notNullable() .comment('A reference to the entity that the refresh state is tied to'); table From 7f2a9b0d079885d6728c520575677b8f8a8db9a7 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 9 Apr 2021 16:23:46 +0200 Subject: [PATCH 027/462] Use Database instead of CommonDatabase Signed-off-by: Johan Haals --- plugins/catalog-backend/src/next/LocationStoreImpl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/src/next/LocationStoreImpl.ts b/plugins/catalog-backend/src/next/LocationStoreImpl.ts index 89247056d6..1b9e9bd92c 100644 --- a/plugins/catalog-backend/src/next/LocationStoreImpl.ts +++ b/plugins/catalog-backend/src/next/LocationStoreImpl.ts @@ -15,7 +15,7 @@ */ import { LocationSpec, Location } from '@backstage/catalog-model'; -import { CommonDatabase } from '../database'; +import { Database } from '../database'; import { LocationStore } from './types'; import { v4 as uuidv4 } from 'uuid'; import { ConflictError } from '@backstage/errors'; @@ -31,7 +31,7 @@ export class LocationStoreImpl implements LocationStore { ZenObservable.SubscriptionObserver >(); - constructor(private readonly db: CommonDatabase) {} + constructor(private readonly db: Database) {} createLocation(spec: LocationSpec): Promise { return this.db.transaction(async tx => { From bfa51b286f052a77b20682c4f5d72db4abf0441a Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 9 Apr 2021 16:25:20 +0200 Subject: [PATCH 028/462] Add entity processing logic Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- .../src/next/CatalogProcessingEngineImpl.ts | 23 +- .../next/CatalogProcessingOrchestratorImpl.ts | 227 +++++++++++------- .../src/next/LocationServiceImpl.ts | 2 +- .../next/database/ProcessingDatabaseImpl.ts | 3 +- plugins/catalog-backend/src/next/types.ts | 25 +- 5 files changed, 163 insertions(+), 117 deletions(-) diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts index 8a2a0349d6..93616b6399 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts @@ -55,27 +55,28 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { state: intialState, } = await this.stateManager.getNextProccessingItem(); - const { - completedEntity, - deferredEntites, - errors, - state, - } = await this.orchestrator.process({ + const result = await this.orchestrator.process({ entity, state: intialState, }); - for (const error of errors) { + for (const error of result.errors) { this.logger.warn(error.message); } + if (!result.ok) { + return; + } + await this.stateManager.setProcessingItemResult({ id, - entity: completedEntity, - state, - errors, + entity: result.completedEntity, + state: result.state, + errors: result.errors, + }); + await this.stateManager.addProcessingItems({ + entities: result.deferredEntites, }); - await this.stateManager.addProcessingItems({ entities: deferredEntites }); } } diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index add7db53b3..1288561b07 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -16,24 +16,23 @@ import { Entity, - LocationSpec, - stringifyLocationReference, + EntityRelationSpec, + stringifyEntityRef, + LOCATION_ANNOTATION, + EntityPolicy, } from '@backstage/catalog-model'; import { CatalogProcessor, - CatalogProcessorEmit, CatalogProcessorParser, CatalogProcessorResult, } from '../ingestion/processors'; import { CatalogProcessingOrchestrator, - EntityProcessingError, EntityProcessingRequest, EntityProcessingResult, } from './types'; import { Logger } from 'winston'; -import * as result from '../ingestion/processors/results'; -import { locationToEntity } from './LocationToEntity'; +import { InputError } from '@backstage/errors'; export class CatalogProcessingOrchestratorImpl implements CatalogProcessingOrchestrator { @@ -42,6 +41,7 @@ export class CatalogProcessingOrchestratorImpl processors: CatalogProcessor[]; logger: Logger; parser: CatalogProcessorParser; + policy: EntityPolicy; }, ) {} @@ -49,101 +49,144 @@ export class CatalogProcessingOrchestratorImpl request: EntityProcessingRequest, ): Promise { const { entity, eager, state } = request; - const deferredEntites: Entity[] = []; - const errors: EntityProcessingError[] = []; - if (eager) { - const stack = [entity]; - const emit = (i: CatalogProcessorResult) => stack.push(i); - while (stack.length) { - const item = stack.pop(); - stack.push(); - } - } else { - const emit = (i: CatalogProcessorResult) => { - if (i.type === 'entity') { - deferredEntites.push(i.entity); - } - if (i.type === 'location') { - deferredEntites.push( - locationToEntity(i.location.type, i.location.type), - ); - } - }; - if (entity.spec) { - if (entity.spec.kind === 'Location') { - this.handleLocation( - { - type: (entity.spec.type as unknown) as string, - target: (entity.spec.target as unknown) as string, - }, - emit, - ); - } - } - } + const result = await this.processSingleEntity(entity); - return { - deferredEntites, - completedEntity, - errors, - state, - }; + console.log('result', JSON.stringify(result)); + return result; } - private async handleLocation( - location: LocationSpec, - emit: CatalogProcessorEmit, - ) { - const { processors, logger } = this.options; + private async processSingleEntity( + unprocessedEntity: Entity, + ): Promise { + // TODO: validate that this doesn't change during processing + const entityRef = stringifyEntityRef(unprocessedEntity); + // TODO: which one do we actually use here? source-location? - maybe probably doesn't exist yet? + const locationRef = + unprocessedEntity.metadata?.annotations?.[LOCATION_ANNOTATION]; - const validatedEmit: CatalogProcessorEmit = emitResult => { - if (emitResult.type === 'relation') { - throw new Error('readLocation may not emit entity relations'); - } - if ( - emitResult.type === 'location' && - emitResult.location.type === location.type && - emitResult.location.target === location.target - ) { - // Ignore self-referential locations silently (this can happen for - // example if you use a glob target like "**/*.yaml" in a Location - // entity) - return; - } - emit(emitResult); - }; + const emitter = createEmitter(this.options.logger); - for (const processor of processors) { - if (processor.readLocation) { - try { - if ( - await processor.readLocation( - location, - // TODO: figure out how this will work in the new processing system - locations from PRs might be optional - location.presence !== 'required', - validatedEmit, - this.options.parser, - ) - ) { - return; + try { + // Pre-process phase, used to populate entities with data that is required during main processing step + let entity = unprocessedEntity; + for (const processor of this.options.processors) { + if (processor.preProcessEntity) { + try { + entity = await processor.preProcessEntity({ + entity, + emit: emitter.emit, + }); + } catch (e) { + throw new Error( + `Processor ${processor.constructor.name} threw an error while preprocessing entity ${entityRef} at ${locationRef}, ${e}`, + ); } - } catch (e) { - const message = `Processor ${ - processor.constructor.name - } threw an error while reading location ${stringifyLocationReference( - location, - )}, ${e}`; - emit(result.generalError(location, message)); - logger.warn(message); } } - } - const message = `No processor was able to read location ${stringifyLocationReference( - location, - )}`; - emit(result.inputError(location, message)); - logger.warn(message); + // Enforce entity policies making sure that entities conform to a general schema + let policyEnforcedEntity; + try { + policyEnforcedEntity = await this.options.policy.enforce(entity); + } catch (e) { + throw new InputError( + `Policy check failed while analyzing entity ${entityRef} at ${locationRef}, ${e}`, + ); + } + if (!policyEnforcedEntity) { + throw new Error( + `Policy unexpectedly returned no data while analyzing entity ${entityRef} at ${locationRef}`, + ); + } + entity = policyEnforcedEntity; + + // Validate the given entity kind against its schema + let handled = false; + for (const processor of this.options.processors) { + if (processor.validateEntityKind) { + try { + handled = await processor.validateEntityKind(entity); + if (handled) { + break; + } + } catch (e) { + throw new InputError( + `Processor ${processor.constructor.name} threw an error while validating the entity ${entityRef} at ${locationRef}, ${e}`, + ); + } + } + } + if (!handled) { + throw new InputError( + `No processor recognized the entity ${entityRef} at ${locationRef}`, + ); + } + + // Main processing step of the entity + for (const processor of this.options.processors) { + if (processor.processEntity) { + try { + entity = await processor.processEntity({ + entity, + emit: emitter.emit, + }); + } catch (e) { + throw new Error( + `Processor ${processor.constructor.name} threw an error while postprocessing entity ${entityRef} at ${locationRef}, ${e}`, + ); + } + } + } + + return { + ...emitter.results(), + completedEntity: entity, + state: new Map(), + ok: true, + }; + } catch (error) { + this.options.logger.warn(error.message); + return { ok: false, errors: emitter.results().errors.concat(error) }; + } } } + +function createEmitter(logger: Logger) { + let done = false; + + const errors = new Array(); + const relations = new Array(); + const deferredEntites = new Array(); + + const emit = (i: CatalogProcessorResult) => { + console.log('CatalogProcessorResult', i); + if (done) { + logger.warn( + `Item if type ${i.type} was emitted after processing had completed at ${ + new Error().stack + }`, + ); + return; + } + if (i.type === 'entity') { + deferredEntites.push(i.entity); + } else if (i.type === 'relation') { + relations.push(i.relation); + } else if (i.type === 'error') { + errors.push(i.error); + } + }; + + return { + emit, + results() { + done = true; + return { + errors, + relations, + deferredEntites, + }; + }, + }; +} diff --git a/plugins/catalog-backend/src/next/LocationServiceImpl.ts b/plugins/catalog-backend/src/next/LocationServiceImpl.ts index 29b41e0a09..e8e8745f01 100644 --- a/plugins/catalog-backend/src/next/LocationServiceImpl.ts +++ b/plugins/catalog-backend/src/next/LocationServiceImpl.ts @@ -50,7 +50,7 @@ export class LocationServiceImpl implements LocationService { return { location: { ...spec, id: `${spec.type}:${spec.target}` }, - entities: processed.completeEntities, + entities: [processed.completedEntity], }; } diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts index 3fe25c1eae..25181335c4 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -43,7 +43,7 @@ export type DbRefreshStateRow = { errors: string; }; -class ProcessingDatabaseImpl implements ProcessingDatabase { +export class ProcessingDatabaseImpl implements ProcessingDatabase { constructor( private readonly database: Knex, private readonly logger: Logger, @@ -82,6 +82,7 @@ class ProcessingDatabaseImpl implements ProcessingDatabase { id: uuid(), entity_ref: stringifyEntityRef(entity), unprocessed_entity: JSON.stringify(entity), + errors: '', next_update_at: tx.fn.now(), last_discovery_at: tx.fn.now(), }) diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 58d88636f8..091ddc8bcd 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -75,17 +75,18 @@ export type EntityProcessingRequest = { state: Map; // Versions for multiple deployments etc }; -export type EntityProcessingError = { - // some error stuff here - message: String; -}; - -export type EntityProcessingResult = { - state: Map; - completedEntity: Entity; - deferredEntites: Entity[]; - errors: EntityProcessingError[]; -}; +export type EntityProcessingResult = + | { + ok: true; + state: Map; + completedEntity: Entity; + deferredEntites: Entity[]; + errors: Error[]; + } + | { + ok: false; + errors: Error[]; + }; export interface CatalogProcessingOrchestrator { process(request: EntityProcessingRequest): Promise; @@ -95,7 +96,7 @@ export type ProcessingItemResult = { id: string; entity: Entity; state: Map; - errors: EntityProcessingError[]; + errors: Error[]; }; export type AddProcessingItemRequest = { From 07de96af3be4ecd6406193014faa885bb4fa3ee0 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 13 Apr 2021 11:25:48 +0200 Subject: [PATCH 029/462] Backwards compatible processing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Co-authored-by: Fredrik Adelöw Signed-off-by: Johan Haals --- .../next/CatalogProcessingOrchestratorImpl.ts | 152 ++++++++++++++++-- .../src/next/DatabaseLocationProvider.ts | 20 ++- .../src/next/LocationServiceImpl.ts | 12 +- .../src/next/LocationToEntity.ts | 39 ----- plugins/catalog-backend/src/next/util.ts | 90 +++++++++++ 5 files changed, 254 insertions(+), 59 deletions(-) delete mode 100644 plugins/catalog-backend/src/next/LocationToEntity.ts create mode 100644 plugins/catalog-backend/src/next/util.ts diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index 1288561b07..9aaa2ffa74 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -19,7 +19,12 @@ import { EntityRelationSpec, stringifyEntityRef, LOCATION_ANNOTATION, + LocationSpec, + LocationEntity, EntityPolicy, + ORIGIN_LOCATION_ANNOTATION, + stringifyLocationReference, + parseLocationReference, } from '@backstage/catalog-model'; import { CatalogProcessor, @@ -33,12 +38,56 @@ import { } from './types'; import { Logger } from 'winston'; import { InputError } from '@backstage/errors'; +import { locationSpecToLocationEntity } from './util'; +import path from 'path'; +import * as results from '../ingestion/processors/results'; +import { ScmIntegrationRegistry } from '@backstage/integration'; + +function isLocationEntity(entity: Entity): entity is LocationEntity { + return entity.kind === 'Location'; +} + +function getEntityOriginLocationRef(entity: Entity): string { + const ref = entity.metadata.annotations?.[ORIGIN_LOCATION_ANNOTATION]; + if (!ref) { + const entityRef = stringifyEntityRef(entity); + throw new InputError( + `Entity '${entityRef}' does not have an origin location`, + ); + } + return ref; +} + +function toAbsoluteUrl( + integrations: ScmIntegrationRegistry, + base: LocationSpec, + type: string, + target: string, +): string { + if (base.type !== type) { + return target; + } + try { + if (type === 'file') { + if (target.startsWith('.')) { + return path.join(path.dirname(base.target), target); + } + return target; + } else if (type === 'url') { + return integrations.resolveUrl({ url: target, base: base.target }); + } + return target; + } catch (e) { + return target; + } +} export class CatalogProcessingOrchestratorImpl implements CatalogProcessingOrchestrator { constructor( private readonly options: { processors: CatalogProcessor[]; + integrations: ScmIntegrationRegistry; logger: Logger; parser: CatalogProcessorParser; policy: EntityPolicy; @@ -52,7 +101,7 @@ export class CatalogProcessingOrchestratorImpl const result = await this.processSingleEntity(entity); - console.log('result', JSON.stringify(result)); + console.log('result', JSON.stringify(result, undefined, 2)); return result; } @@ -64,19 +113,27 @@ export class CatalogProcessingOrchestratorImpl // TODO: which one do we actually use here? source-location? - maybe probably doesn't exist yet? const locationRef = unprocessedEntity.metadata?.annotations?.[LOCATION_ANNOTATION]; + if (!locationRef) { + throw new InputError(`Entity '${entityRef}' does not have a location`); + } + const location = parseLocationReference(locationRef); + const originLocation = parseLocationReference( + getEntityOriginLocationRef(unprocessedEntity), + ); - const emitter = createEmitter(this.options.logger); - + const emitter = createEmitter(this.options.logger, unprocessedEntity); try { // Pre-process phase, used to populate entities with data that is required during main processing step let entity = unprocessedEntity; for (const processor of this.options.processors) { if (processor.preProcessEntity) { try { - entity = await processor.preProcessEntity({ + entity = await processor.preProcessEntity( entity, - emit: emitter.emit, - }); + location, + emitter.emit, + originLocation, + ); } catch (e) { throw new Error( `Processor ${processor.constructor.name} threw an error while preprocessing entity ${entityRef} at ${locationRef}, ${e}`, @@ -123,14 +180,69 @@ export class CatalogProcessingOrchestratorImpl ); } + // Backwards compatible processing of location entites + if (isLocationEntity(entity)) { + const { type = location.type, optional = false } = entity.spec; + const targets = new Array(); + if (entity.spec.target) { + targets.push(entity.spec.target); + } + if (entity.spec.targets) { + targets.push(...entity.spec.targets); + } + + for (const maybeRelativeTarget of targets) { + if (type === 'file' && maybeRelativeTarget.endsWith(path.sep)) { + emitter.emit( + results.inputError( + location, + `LocationEntityProcessor cannot handle ${type} type location with target ${location.target} that ends with a path separator`, + ), + ); + continue; + } + const target = toAbsoluteUrl( + this.options.integrations, + location, + type, + maybeRelativeTarget, + ); + + for (const processor of this.options.processors) { + if (processor.readLocation) { + try { + handled = await processor.readLocation( + { + type, + target, + presence: optional ? 'optional' : 'required', + }, + Boolean(entity.spec?.optional), + emitter.emit, + this.options.parser, + ); + if (handled) { + break; + } + } catch (e) { + throw new Error( + `Processor ${processor.constructor.name} threw an error while postprocessing entity ${entityRef} at ${locationRef}, ${e}`, + ); + } + } + } + } + } + // Main processing step of the entity for (const processor of this.options.processors) { - if (processor.processEntity) { + if (processor.postProcessEntity) { try { - entity = await processor.processEntity({ + entity = await processor.postProcessEntity( entity, - emit: emitter.emit, - }); + location, + emitter.emit, + ); } catch (e) { throw new Error( `Processor ${processor.constructor.name} threw an error while postprocessing entity ${entityRef} at ${locationRef}, ${e}`, @@ -152,7 +264,7 @@ export class CatalogProcessingOrchestratorImpl } } -function createEmitter(logger: Logger) { +function createEmitter(logger: Logger, parentEntity: Entity) { let done = false; const errors = new Array(); @@ -170,7 +282,23 @@ function createEmitter(logger: Logger) { return; } if (i.type === 'entity') { - deferredEntites.push(i.entity); + const originLocation = getEntityOriginLocationRef(parentEntity); + + deferredEntites.push({ + ...i.entity, + metadata: { + ...i.entity.metadata, + annotations: { + ...i.entity.metadata.annotations, + [ORIGIN_LOCATION_ANNOTATION]: originLocation, + [LOCATION_ANNOTATION]: stringifyLocationReference(i.location), + }, + }, + }); + } else if (i.type === 'location') { + deferredEntites.push( + locationSpecToLocationEntity(i.location, parentEntity), + ); } else if (i.type === 'relation') { relations.push(i.relation); } else if (i.type === 'error') { diff --git a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts b/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts index b56dfa1158..eaf5a78556 100644 --- a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts +++ b/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts @@ -15,9 +15,13 @@ */ import { Observable } from '@backstage/core'; +import { ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; import { EntityProvider, LocationStore, EntityMessage } from './types'; import ObservableImpl from 'zen-observable'; -import { locationToEntity, locationToEntityName } from './LocationToEntity'; +import { + locationSpecToLocationEntity, + locationSpecToMetadataName, +} from './util'; export class DatabaseLocationProvider implements EntityProvider { private subscribers = new Set< @@ -29,14 +33,16 @@ export class DatabaseLocationProvider implements EntityProvider { next: locations => { if ('all' in locations) { this.notify({ - all: locations.all.map(l => locationToEntity(l.type, l.target)), + all: locations.all.map(l => locationSpecToLocationEntity(l)), }); } else { this.notify({ - added: locations.added.map(l => locationToEntity(l.type, l.target)), - removed: locations.removed.map(l => - locationToEntityName(l.type, l.target), - ), + added: locations.added.map(l => locationSpecToLocationEntity(l)), + removed: locations.removed.map(l => ({ + kind: 'Location', + namespace: ENTITY_DEFAULT_NAMESPACE, + name: locationSpecToMetadataName(l), + })), }); } }, @@ -53,7 +59,7 @@ export class DatabaseLocationProvider implements EntityProvider { return new ObservableImpl(subscriber => { this.store.listLocations().then(locations => { subscriber.next({ - all: locations.map(l => locationToEntity(l.type, l.target)), + all: locations.map(l => locationSpecToLocationEntity(l)), }); this.subscribers.add(subscriber); }); diff --git a/plugins/catalog-backend/src/next/LocationServiceImpl.ts b/plugins/catalog-backend/src/next/LocationServiceImpl.ts index e8e8745f01..02a98fb2b9 100644 --- a/plugins/catalog-backend/src/next/LocationServiceImpl.ts +++ b/plugins/catalog-backend/src/next/LocationServiceImpl.ts @@ -13,7 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LocationSpec, Location, Entity } from '@backstage/catalog-model'; +import { + LocationSpec, + Location, + Entity, + LOCATION_ANNOTATION, + ORIGIN_LOCATION_ANNOTATION, +} from '@backstage/catalog-model'; import { LocationService, LocationStore, @@ -37,6 +43,10 @@ export class LocationServiceImpl implements LocationService { metadata: { name: `${spec.type}:${spec.target}`, namespace: 'default', + annotations: { + [LOCATION_ANNOTATION]: `${spec.type}:${spec.target}`, + [ORIGIN_LOCATION_ANNOTATION]: `${spec.type}:${spec.target}`, + }, }, spec: { location: { type: spec.type, target: spec.target }, diff --git a/plugins/catalog-backend/src/next/LocationToEntity.ts b/plugins/catalog-backend/src/next/LocationToEntity.ts deleted file mode 100644 index 28695e14af..0000000000 --- a/plugins/catalog-backend/src/next/LocationToEntity.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2021 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entity, EntityName } from '@backstage/catalog-model'; - -export function locationToEntity(type: string, target: string): Entity { - return { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - name: `${type}:${target}`, - namespace: 'default', - }, - spec: { - location: { type, target }, - }, - }; -} - -export function locationToEntityName(type: string, target: string): EntityName { - return { - kind: 'Location', - namespace: 'default', - name: `${type}:${target}`, - }; -} diff --git a/plugins/catalog-backend/src/next/util.ts b/plugins/catalog-backend/src/next/util.ts new file mode 100644 index 0000000000..6ff1cde2f0 --- /dev/null +++ b/plugins/catalog-backend/src/next/util.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + LocationSpec, + LocationEntityV1alpha1, + LOCATION_ANNOTATION, + ORIGIN_LOCATION_ANNOTATION, + stringifyEntityRef, + stringifyLocationReference, +} from '@backstage/catalog-model'; +import { createHash } from 'crypto'; + +export function locationSpecToMetadataName(location: LocationSpec) { + const hash = createHash('sha1') + .update(`${location.type}:${location.target}`) + .digest('hex'); + + return `generated-${hash}`; +} + +export function locationSpecToLocationEntity( + location: LocationSpec, + parentEntity?: Entity, +): LocationEntityV1alpha1 { + let ownLocation: string; + let originLocation: string; + if (parentEntity) { + const maybeOwnLocation = + parentEntity.metadata.annotations?.[LOCATION_ANNOTATION]; + if (!maybeOwnLocation) { + throw new Error( + `Parent entity '${stringifyEntityRef( + parentEntity, + )}' of location '${stringifyLocationReference( + location, + )}' does not have a location annotation`, + ); + } + ownLocation = maybeOwnLocation; + const maybeOriginLocation = + parentEntity.metadata.annotations?.[ORIGIN_LOCATION_ANNOTATION]; + if (!maybeOriginLocation) { + throw new Error( + `Parent entity '${stringifyEntityRef( + parentEntity, + )}' of location '${stringifyLocationReference( + location, + )}' does not have an origin location annotation`, + ); + } + originLocation = maybeOriginLocation; + } else { + ownLocation = stringifyLocationReference(location); + originLocation = ownLocation; + } + + const result: LocationEntityV1alpha1 = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + name: locationSpecToMetadataName(location), + annotations: { + [LOCATION_ANNOTATION]: ownLocation, + [ORIGIN_LOCATION_ANNOTATION]: originLocation, + }, + }, + spec: { + type: location.type, + target: location.target, + optional: location.presence === 'optional' ? true : undefined, + }, + }; + + return result; +} From 77b9fa5e07647fe3c60c117df9222eea6cc3d0db Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 13 Apr 2021 13:35:28 +0200 Subject: [PATCH 030/462] Add NextCatalogBuilder, fix typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- plugins/catalog-backend/src/index.ts | 1 + .../src/next/CatalogProcessingEngineImpl.ts | 2 +- .../next/CatalogProcessingOrchestratorImpl.ts | 1 - .../src/next/LocationServiceImpl.ts | 11 +- .../src/next/NextCatalogBuilder.ts | 364 ++++++++++++++++++ .../src/next/ProcessingStateManagerImpl.ts | 2 +- plugins/catalog-backend/src/next/index.ts | 17 + plugins/catalog-backend/src/next/types.ts | 2 +- 8 files changed, 392 insertions(+), 8 deletions(-) create mode 100644 plugins/catalog-backend/src/next/NextCatalogBuilder.ts create mode 100644 plugins/catalog-backend/src/next/index.ts diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index 51df909d05..058ca728a1 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -20,3 +20,4 @@ export * from './ingestion'; export * from './search'; export * from './service'; export * from './util'; +export * from './next'; diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts index 93616b6399..46c6fb0c1b 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts @@ -53,7 +53,7 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { id, entity, state: intialState, - } = await this.stateManager.getNextProccessingItem(); + } = await this.stateManager.getNextProcessingItem(); const result = await this.orchestrator.process({ entity, diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index 9aaa2ffa74..8706abc162 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -272,7 +272,6 @@ function createEmitter(logger: Logger, parentEntity: Entity) { const deferredEntites = new Array(); const emit = (i: CatalogProcessorResult) => { - console.log('CatalogProcessorResult', i); if (done) { logger.warn( `Item if type ${i.type} was emitted after processing had completed at ${ diff --git a/plugins/catalog-backend/src/next/LocationServiceImpl.ts b/plugins/catalog-backend/src/next/LocationServiceImpl.ts index 02a98fb2b9..4125f96ed1 100644 --- a/plugins/catalog-backend/src/next/LocationServiceImpl.ts +++ b/plugins/catalog-backend/src/next/LocationServiceImpl.ts @@ -57,11 +57,14 @@ export class LocationServiceImpl implements LocationService { eager: true, state: new Map(), }); + if (processed.ok) { + return { + location: { ...spec, id: `${spec.type}:${spec.target}` }, + entities: [processed.completedEntity], + }; + } - return { - location: { ...spec, id: `${spec.type}:${spec.target}` }, - entities: [processed.completedEntity], - }; + throw Error('error handling not implemented.'); } const location = await this.store.createLocation(spec); diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts new file mode 100644 index 0000000000..5525e35f7f --- /dev/null +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -0,0 +1,364 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common'; +import { + DefaultNamespaceEntityPolicy, + EntityPolicies, + EntityPolicy, + FieldFormatEntityPolicy, + makeValidator, + NoForeignRootFieldsEntityPolicy, + SchemaValidEntityPolicy, + Validators, +} from '@backstage/catalog-model'; +import { Config } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import lodash from 'lodash'; +import { Logger } from 'winston'; +import { + DatabaseEntitiesCatalog, + DatabaseLocationsCatalog, + EntitiesCatalog, + LocationsCatalog, +} from '../catalog'; +import { DatabaseManager } from '../database'; +import { + AnnotateLocationEntityProcessor, + BitbucketDiscoveryProcessor, + BuiltinKindsEntityProcessor, + CatalogProcessor, + CatalogProcessorParser, + CodeOwnersProcessor, + FileReaderProcessor, + GithubDiscoveryProcessor, + GithubOrgReaderProcessor, + HigherOrderOperation, + HigherOrderOperations, + LdapOrgReaderProcessor, + LocationEntityProcessor, + LocationReaders, + MicrosoftGraphOrgReaderProcessor, + PlaceholderProcessor, + PlaceholderResolver, + StaticLocationProcessor, + UrlReaderProcessor, +} from '../ingestion'; +import { CatalogRulesEnforcer } from '../ingestion/CatalogRules'; +import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer'; +import { + jsonPlaceholderResolver, + textPlaceholderResolver, + yamlPlaceholderResolver, +} from '../ingestion/processors/PlaceholderProcessor'; +import { defaultEntityDataParser } from '../ingestion/processors/util/parse'; +import { LocationAnalyzer } from '../ingestion/types'; +import { CatalogProcessingEngineImpl } from '../next/CatalogProcessingEngineImpl'; +import { CatalogProcessingOrchestratorImpl } from '../next/CatalogProcessingOrchestratorImpl'; +import { ProcessingDatabaseImpl } from '../next/database/ProcessingDatabaseImpl'; +import { DatabaseLocationProvider } from '../next/DatabaseLocationProvider'; +import { LocationStoreImpl } from '../next/LocationStoreImpl'; +import { ProcessingStateManagerImpl } from '../next/ProcessingStateManagerImpl'; +import { CatalogProcessingEngine } from '../next/types'; + +export type CatalogEnvironment = { + logger: Logger; + database: PluginDatabaseManager; + config: Config; + reader: UrlReader; +}; + +/** + * A builder that helps wire up all of the component parts of the catalog. + * + * The touch points where you can replace or extend behavior are as follows: + * + * - Entity policies can be added or replaced. These are automatically run + * after the processors' pre-processing steps. All policies are given the + * chance to inspect the entity, and all of them have to pass in order for + * the entity to be considered valid from an overall point of view. + * - Placeholder resolvers can be replaced or added. These run on the raw + * structured data between the parsing and pre-processing steps, to replace + * dollar-prefixed entries with their actual values (like $file). + * - Field format validators can be replaced. These check the format of + * individual core fields such as metadata.name, to ensure that they adhere + * to certain rules. + * - Processors can be added or replaced. These implement the functionality of + * reading, parsing, validating, and processing the entity data before it is + * persisted in the catalog. + */ +export class NextCatalogBuilder { + private readonly env: CatalogEnvironment; + private entityPolicies: EntityPolicy[]; + private entityPoliciesReplace: boolean; + private placeholderResolvers: Record; + private fieldFormatValidators: Partial; + private processors: CatalogProcessor[]; + private processorsReplace: boolean; + private parser: CatalogProcessorParser | undefined; + + constructor(env: CatalogEnvironment) { + this.env = env; + this.entityPolicies = []; + this.entityPoliciesReplace = false; + this.placeholderResolvers = {}; + this.fieldFormatValidators = {}; + this.processors = []; + this.processorsReplace = false; + this.parser = undefined; + } + + /** + * Adds policies that are used to validate entities between the pre- + * processing and post-processing stages. All such policies must pass for the + * entity to be considered valid. + * + * If what you want to do is to replace the rules for what format is allowed + * in various core entity fields (such as metadata.name), you may want to use + * {@link NextCatalogBuilder#setFieldFormatValidators} instead. + * + * @param policies One or more policies + */ + addEntityPolicy(...policies: EntityPolicy[]): NextCatalogBuilder { + this.entityPolicies.push(...policies); + return this; + } + + /** + * Sets what policies to use for validation of entities between the pre- + * processing and post-processing stages. All such policies must pass for the + * entity to be considered valid. + * + * If what you want to do is to replace the rules for what format is allowed + * in various core entity fields (such as metadata.name), you may want to use + * {@link NextCatalogBuilder#setFieldFormatValidators} instead. + * + * This function replaces the default set of policies; use with care. + * + * @param policies One or more policies + */ + replaceEntityPolicies(policies: EntityPolicy[]): NextCatalogBuilder { + this.entityPolicies = [...policies]; + this.entityPoliciesReplace = true; + return this; + } + + /** + * Adds, or overwrites, a handler for placeholders (e.g. $file) in entity + * definition files. + * + * @param key The key that identifies the placeholder, e.g. "file" + * @param resolver The resolver that gets values for this placeholder + */ + setPlaceholderResolver( + key: string, + resolver: PlaceholderResolver, + ): NextCatalogBuilder { + this.placeholderResolvers[key] = resolver; + return this; + } + + /** + * Sets the validator function to use for one or more special fields of an + * entity. This is useful if the default rules for formatting of fields are + * not sufficient. + * + * This function has no effect if used together with + * {@link NextCatalogBuilder#replaceEntityPolicies}. + * + * @param validators The (subset of) validators to set + */ + setFieldFormatValidators( + validators: Partial, + ): NextCatalogBuilder { + lodash.merge(this.fieldFormatValidators, validators); + return this; + } + + /** + * Adds entity processors. These are responsible for reading, parsing, and + * processing entities before they are persisted in the catalog. + * + * @param processors One or more processors + */ + addProcessor(...processors: CatalogProcessor[]): NextCatalogBuilder { + this.processors.push(...processors); + return this; + } + + /** + * Sets what entity processors to use. These are responsible for reading, + * parsing, and processing entities before they are persisted in the catalog. + * + * This function replaces the default set of processors; use with care. + * + * @param processors One or more processors + */ + replaceProcessors(processors: CatalogProcessor[]): NextCatalogBuilder { + this.processors = [...processors]; + this.processorsReplace = true; + return this; + } + + /** + * Sets up the catalog to use a custom parser for entity data. + * + * This is the function that gets called immediately after some raw entity + * specification data has been read from a remote source, and needs to be + * parsed and emitted as structured data. + * + * @param parser The custom parser + */ + setEntityDataParser(parser: CatalogProcessorParser): NextCatalogBuilder { + this.parser = parser; + return this; + } + + /** + * Wires up and returns all of the component parts of the catalog + */ + async build(): Promise<{ + entitiesCatalog: EntitiesCatalog; + locationsCatalog: LocationsCatalog; + locationAnalyzer: LocationAnalyzer; + processingEngine: CatalogProcessingEngine; + }> { + const { config, database, logger } = this.env; + + const policy = this.buildEntityPolicy(); + const processors = this.buildProcessors(); + const parser = this.parser || defaultEntityDataParser; + + const dbClient = await database.getClient(); + const db = await DatabaseManager.createDatabase(dbClient, { logger }); + + const processingDatabase = new ProcessingDatabaseImpl(dbClient, logger); + const stateManager = new ProcessingStateManagerImpl(processingDatabase); + const integrations = ScmIntegrations.fromConfig(config); + const orchestrator = new CatalogProcessingOrchestratorImpl({ + processors, + integrations, + logger, + parser, + policy, + }); + const entitiesCatalog = new DatabaseEntitiesCatalog(db, this.env.logger); + + const locationStore = new LocationStoreImpl(db); + const dbLocationProvider = new DatabaseLocationProvider(locationStore); + const processingEngine = new CatalogProcessingEngineImpl( + logger, + [dbLocationProvider], // entityproviders + stateManager, + orchestrator, + entitiesCatalog, + ); + + const locationsCatalog = new DatabaseLocationsCatalog(db); + const locationAnalyzer = new RepoLocationAnalyzer(logger); + + return { + entitiesCatalog, + locationsCatalog, + locationAnalyzer, + processingEngine, + }; + } + + private buildEntityPolicy(): EntityPolicy { + const entityPolicies: EntityPolicy[] = this.entityPoliciesReplace + ? [new SchemaValidEntityPolicy(), ...this.entityPolicies] + : [ + new SchemaValidEntityPolicy(), + new DefaultNamespaceEntityPolicy(), + new NoForeignRootFieldsEntityPolicy(), + new FieldFormatEntityPolicy( + makeValidator(this.fieldFormatValidators), + ), + ...this.entityPolicies, + ]; + + return EntityPolicies.allOf(entityPolicies); + } + + private buildProcessors(): CatalogProcessor[] { + const { config, logger, reader } = this.env; + const integrations = ScmIntegrations.fromConfig(config); + + this.checkDeprecatedReaderProcessors(); + + const placeholderResolvers: Record = { + json: jsonPlaceholderResolver, + yaml: yamlPlaceholderResolver, + text: textPlaceholderResolver, + ...this.placeholderResolvers, + }; + + // These are always there no matter what + const processors: CatalogProcessor[] = [ + StaticLocationProcessor.fromConfig(config), + new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }), + new BuiltinKindsEntityProcessor(), + ]; + + // These are only added unless the user replaced them all + if (!this.processorsReplace) { + processors.push( + new FileReaderProcessor(), + BitbucketDiscoveryProcessor.fromConfig(config, { logger }), + GithubDiscoveryProcessor.fromConfig(config, { logger }), + GithubOrgReaderProcessor.fromConfig(config, { logger }), + LdapOrgReaderProcessor.fromConfig(config, { logger }), + MicrosoftGraphOrgReaderProcessor.fromConfig(config, { logger }), + new UrlReaderProcessor({ reader, logger }), + CodeOwnersProcessor.fromConfig(config, { logger, reader }), + // new LocationEntityProcessor({ integrations }), + new AnnotateLocationEntityProcessor({ integrations }), + ); + } + + // Add the ones (if any) that the user added + processors.push(...this.processors); + + return processors; + } + + // TODO(Rugvip): These old processors are removed, for a while we'll be throwing + // errors here to make sure people know where to move the config + private checkDeprecatedReaderProcessors() { + const pc = this.env.config.getOptionalConfig('catalog.processors'); + if (pc?.has('github')) { + throw new Error( + `Using deprecated configuration for catalog.processors.github, move to using integrations.github instead`, + ); + } + if (pc?.has('gitlabApi')) { + throw new Error( + `Using deprecated configuration for catalog.processors.gitlabApi, move to using integrations.gitlab instead`, + ); + } + if (pc?.has('bitbucketApi')) { + throw new Error( + `Using deprecated configuration for catalog.processors.bitbucketApi, move to using integrations.bitbucket instead`, + ); + } + if (pc?.has('azureApi')) { + throw new Error( + `Using deprecated configuration for catalog.processors.azureApi, move to using integrations.azure instead`, + ); + } + } +} diff --git a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts index 872ee78fdb..bb35da6c37 100644 --- a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts +++ b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts @@ -44,7 +44,7 @@ export class ProcessingStateManagerImpl implements ProcessingStateManager { }); } - async getNextProccessingItem(): Promise { + async getNextProcessingItem(): Promise { const entities = await new Promise(resolve => this.popFromQueue(resolve), ); diff --git a/plugins/catalog-backend/src/next/index.ts b/plugins/catalog-backend/src/next/index.ts new file mode 100644 index 0000000000..d4eeca4c81 --- /dev/null +++ b/plugins/catalog-backend/src/next/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { NextCatalogBuilder } from './NextCatalogBuilder'; diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 091ddc8bcd..ddd2d6ff7c 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -110,6 +110,6 @@ export type ProccessingItem = { }; export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise; - getNextProccessingItem(): Promise; + getNextProcessingItem(): Promise; addProcessingItems(request: AddProcessingItemRequest): Promise; } From 5dafa268f7b180796cbd1168e9a233351eb5ee41 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 13 Apr 2021 13:35:55 +0200 Subject: [PATCH 031/462] Add optional flag to LocationEntityV1Alpha Signed-off-by: Johan Haals --- packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts b/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts index fb452b6ac7..20f99f15b3 100644 --- a/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts @@ -31,6 +31,7 @@ export interface LocationEntityV1alpha1 extends Entity { type?: string; target?: string; targets?: string[]; + optional?: boolean; }; } From 8f6a17c04c37748d07553003d075fb4d939737e9 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 14 Apr 2021 09:53:16 +0200 Subject: [PATCH 032/462] Add experimental option to start the new catalog Signed-off-by: Johan Haals --- packages/backend/src/plugins/catalog.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 076840944f..99ba769736 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -18,6 +18,7 @@ import { useHotCleanup } from '@backstage/backend-common'; import { CatalogBuilder, createRouter, + NextCatalogBuilder, runPeriodically, } from '@backstage/plugin-catalog-backend'; import { Router } from 'express'; @@ -26,6 +27,28 @@ import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise { + // HIGHLY experimental rework of the software catalog + if (process.env.EXPERIMENTAL_CATALOG === '1') { + const builder = new NextCatalogBuilder(env); + const { + entitiesCatalog, + locationsCatalog, + locationAnalyzer, + processingEngine, + } = await builder.build(); + + // TODO(jhaals): run and manage in background. + processingEngine.start(); + + return await createRouter({ + entitiesCatalog, + locationsCatalog, + locationAnalyzer, + logger: env.logger, + config: env.config, + }); + } + const builder = new CatalogBuilder(env); const { entitiesCatalog, From 4ba6ed45e1a8baf4389ceed54aa685e52817cf42 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 14 Apr 2021 09:56:23 +0200 Subject: [PATCH 033/462] Add relations and stitcher class Signed-off-by: Johan Haals --- plugins/catalog-backend/package.json | 1 + .../src/next/CatalogProcessingEngineImpl.ts | 17 ++++- .../src/next/NextCatalogBuilder.ts | 11 ++-- plugins/catalog-backend/src/next/Stitcher.ts | 65 +++++++++++++++++++ .../next/database/ProcessingDatabaseImpl.ts | 46 ++++++++++++- .../src/next/database/types.ts | 11 ++++ plugins/catalog-backend/src/next/types.ts | 2 + yarn.lock | 2 +- 8 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 plugins/catalog-backend/src/next/Stitcher.ts diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 2661025000..6011562078 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -47,6 +47,7 @@ "cross-fetch": "^3.0.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", + "fast-json-stable-stringify": "^2.1.0", "fs-extra": "^9.0.0", "git-url-parse": "^11.4.4", "glob": "^7.1.6", diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts index 46c6fb0c1b..99b2b19091 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts @@ -23,8 +23,13 @@ import { CatalogProcessingOrchestrator, } from './types'; -import { EntitiesCatalog } from '../catalog/types'; import { Logger } from 'winston'; +import { + Entity, + stringifyEntityRef, + EntityRelationSpec, +} from '@backstage/catalog-model'; +import { Stitcher } from './Stitcher'; export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { private subscriptions: Subscription[] = []; @@ -35,7 +40,7 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { private readonly entityProviders: EntityProvider[], private readonly stateManager: ProcessingStateManager, private readonly orchestrator: CatalogProcessingOrchestrator, - private readonly entitiesCatalog: EntitiesCatalog, + private readonly stitcher: Stitcher, ) {} async start() { @@ -77,6 +82,14 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { await this.stateManager.addProcessingItems({ entities: result.deferredEntites, }); + + const setOfThingsToStitch = new Set([ + stringifyEntityRef(result.completedEntity), + ...result.relations.map(relation => + stringifyEntityRef(relation.source), + ), + ]); + await this.stitcher.stitch(setOfThingsToStitch); } } diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 5525e35f7f..95c767407e 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -46,18 +46,13 @@ import { FileReaderProcessor, GithubDiscoveryProcessor, GithubOrgReaderProcessor, - HigherOrderOperation, - HigherOrderOperations, LdapOrgReaderProcessor, - LocationEntityProcessor, - LocationReaders, MicrosoftGraphOrgReaderProcessor, PlaceholderProcessor, PlaceholderResolver, StaticLocationProcessor, UrlReaderProcessor, } from '../ingestion'; -import { CatalogRulesEnforcer } from '../ingestion/CatalogRules'; import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer'; import { jsonPlaceholderResolver, @@ -73,6 +68,7 @@ import { DatabaseLocationProvider } from '../next/DatabaseLocationProvider'; import { LocationStoreImpl } from '../next/LocationStoreImpl'; import { ProcessingStateManagerImpl } from '../next/ProcessingStateManagerImpl'; import { CatalogProcessingEngine } from '../next/types'; +import { Stitcher } from './Stitcher'; export type CatalogEnvironment = { logger: Logger; @@ -255,16 +251,17 @@ export class NextCatalogBuilder { parser, policy, }); - const entitiesCatalog = new DatabaseEntitiesCatalog(db, this.env.logger); + const entitiesCatalog = new DatabaseEntitiesCatalog(db, logger); const locationStore = new LocationStoreImpl(db); const dbLocationProvider = new DatabaseLocationProvider(locationStore); + const stitcher = new Stitcher(dbClient, logger); const processingEngine = new CatalogProcessingEngineImpl( logger, [dbLocationProvider], // entityproviders stateManager, orchestrator, - entitiesCatalog, + stitcher, ); const locationsCatalog = new DatabaseLocationsCatalog(db); diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts new file mode 100644 index 0000000000..8adc93bfad --- /dev/null +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -0,0 +1,65 @@ +import { Transaction } from '../database'; + +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Knex } from 'knex'; +import { Logger } from 'winston'; +import { ConflictError } from '@backstage/errors'; + +export class Stitcher { + constructor( + private readonly database: Knex, + private readonly logger: Logger, + ) {} + + async stitch(entityRefs: Set) { + console.log(entityRefs); + } + + private async transaction( + fn: (tx: Transaction) => Promise, + ): Promise { + try { + let result: T | undefined = undefined; + + await this.database.transaction( + async tx => { + // We can't return here, as knex swallows the return type in case the transaction is rolled back: + // https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/transaction.js#L136 + result = await fn(tx); + }, + { + // If we explicitly trigger a rollback, don't fail. + doNotRejectOnRollback: true, + }, + ); + + return result!; + } catch (e) { + this.logger.debug(`Error during transaction, ${e}`); + + if ( + /SQLITE_CONSTRAINT: UNIQUE/.test(e.message) || + /unique constraint/.test(e.message) + ) { + throw new ConflictError(`Rejected due to a conflicting entity`, e); + } + + throw e; + } + } +} diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts index 25181335c4..bc2d913a73 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -14,17 +14,21 @@ * limitations under the License. */ -import { ConflictError, NotFoundError } from '@backstage/errors'; +import { ConflictError, NotFoundError, InputError } from '@backstage/errors'; import { Knex } from 'knex'; import { Transaction } from '../../database'; +import { DbEntitiesRow } from '../../database/types'; import { ProcessingDatabase, AddUnprocessedEntitiesOptions, UpdateProcessedEntityOptions, GetProcessableEntitiesResult, + UpdateFinalEntityOptions, } from './types'; import type { Logger } from 'winston'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { createHash } from 'crypto'; +import stringify from 'fast-json-stable-stringify'; import { v4 as uuid } from 'uuid'; export type DbRefreshStateRequest = { @@ -43,12 +47,52 @@ export type DbRefreshStateRow = { errors: string; }; +function generateEntityEtag(entity: Entity) { + return createHash('sha1') + .update(stringify({ ...entity })) + .digest('hex'); +} + export class ProcessingDatabaseImpl implements ProcessingDatabase { constructor( private readonly database: Knex, private readonly logger: Logger, ) {} + async updateFinalEntity( + txOpaque: Transaction, + options: UpdateFinalEntityOptions, + ): Promise { + const tx = txOpaque as Knex.Transaction; + + const { finalEntity } = options; + const { relations } = finalEntity; + const { uid, etag, generation } = finalEntity.metadata; + + if (uid === undefined || etag === undefined || generation === undefined) { + throw new InputError( + 'One of the metadata fields "uid", "etag", or "generation" was missing', + ); + } else if (relations === undefined) { + throw new InputError('The field "relations" was missing'); + } + // TODO(freben): state/errors? + + const fullName = stringifyEntityRef(finalEntity); + + const result = await tx('entities') + .insert({ + id: uid, + location_id: null, + etag, + generation, + full_name: fullName, + data: JSON.stringify(finalEntity), + }) + .onConflict('full_name') + .merge(['etag', 'generation', 'data']); + } + async updateProcessedEntity( txOpaque: Transaction, options: UpdateProcessedEntityOptions, diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index 6cd42e690f..83483693c4 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -46,8 +46,19 @@ export type GetProcessableEntitiesResult = { items: RefreshStateItem[]; }; +export type UpdateFinalEntityOptions = { + finalEntity: Entity; + // TODO(freben): search +}; + export interface ProcessingDatabase { transaction(fn: (tx: Transaction) => Promise): Promise; + + updateFinalEntity( + txOpaque: Transaction, + options: UpdateFinalEntityOptions, + ): Promise; + addUnprocessedEntities( tx: Transaction, options: AddUnprocessedEntitiesOptions, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index ddd2d6ff7c..cd3beb4e4c 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -18,6 +18,7 @@ import { EntityName, LocationSpec, Location, + EntityRelationSpec, } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; import { Observable } from '@backstage/core'; // << nooo @@ -81,6 +82,7 @@ export type EntityProcessingResult = state: Map; completedEntity: Entity; deferredEntites: Entity[]; + relations: EntityRelationSpec[]; errors: Error[]; } | { diff --git a/yarn.lock b/yarn.lock index 6f7e171b2c..46f4e73e2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13043,7 +13043,7 @@ fast-json-patch@^3.0.0-1: resolved "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.0.0-1.tgz#4c68f2e7acfbab6d29d1719c44be51899c93dabb" integrity sha512-6pdFb07cknxvPzCeLsFHStEy+MysPJPgZQ9LbQ/2O67unQF93SNqfdSqnPPl71YMHX+AD8gbl7iuoGFzHEdDuw== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== From 99fbef232287eba6733d8811af53dfa27798e28e Mon Sep 17 00:00:00 2001 From: Efrain Gutierrez Date: Wed, 14 Apr 2021 14:16:14 -0500 Subject: [PATCH 034/462] Updating Changeset for Scaffolder Plugin Header Accessibility Signed-off-by: Efrain Gutierrez --- .changeset/flat-paws-rule.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/flat-paws-rule.md diff --git a/.changeset/flat-paws-rule.md b/.changeset/flat-paws-rule.md new file mode 100644 index 0000000000..af7725793e --- /dev/null +++ b/.changeset/flat-paws-rule.md @@ -0,0 +1,6 @@ +--- +'@backstage/core': patch +'@backstage/plugin-scaffolder': patch +--- + +Adding Headings for Accessibility on the Scaffolder Plugin From e4e6ae88b1862de8ac6a2d2ae66718a7072cd15d Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 16 Apr 2021 09:26:30 +0200 Subject: [PATCH 035/462] Add tables for references and relations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- .../20210302150147_refresh_state.js | 112 +++++++++++++++++- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js index 6ee10531eb..a09d892146 100644 --- a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js @@ -20,9 +20,63 @@ * @param {import('knex').Knex} knex */ exports.up = async function up(knex) { + await knex.schema.createTable('relations', table => { + table.comment('All relations between entities in the catalog'); + table + .text('originating_entity_id') + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .text('source_entity_ref') + .notNullable() + .comment('The entity reference of the source entity of the relation'); + table + .text('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .text('target_entity_ref') + .notNullable() + .comment('The entity reference of the target entity of the relation'); + + table.index( + ['source_entity_ref', 'type', 'target_entity_ref'], + 'relations_full_ref_idx', + ); + }); + + await knex.schema.createTable('final_entities', table => { + table.comment( + 'This table contains the final entity result after processing and stitching', + ); + table + .text('entity_id') + .primary() + .notNullable() + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .comment( + 'Entity ID which correspond to the ID in the refresh_state table', + ); + + table.text('finalized_entity').notNullable().comment('The final entity'); + }); + await knex.schema.createTable('refresh_state', table => { - table.comment('Location Refresh states'); - table.text('id').primary().notNullable().comment('Primary id'); + table.comment( + 'Location refresh states. Every individual location (that was ever directly or indirectly discovered) and entity has an entry in this table. It therefore represents the entire live set of things that the refresh loop considers.', + ); + table + .text('entity_id') + .primary() + .notNullable() + .comment( + 'Primary ID, which will also be used as the uid of the resulting entity', + ); table .text('entity_ref') .unique() @@ -58,8 +112,48 @@ exports.up = async function up(knex) { .dateTime('last_discovery_at') .notNullable() .comment('The last timestamp of which this entity was discovered'); - table.index('entity_ref', 'entity_ref_idx'); - table.index('next_update_at', 'next_update_at_idx'); + table.index('entity_ref', 'refresh_state_entity_ref_idx'); + table.index('next_update_at', 'refresh_state_next_update_at_idx'); + }); + + await knex.schema.createTable('refresh_state_references', table => { + table.comment( + 'Holds edges between refresh state rows. Every time when an entity is processed and emits another entity, an edge will be stored to represent that fact. This is used to detect orphans and ultimately deletions.', + ); + table + .text('source_special_key') + .nullable() + .comment( + 'When the reference source is not an entity, this is an opaque identifier for that source.', + ); + table + .text('source_entity_id') + .nullable() + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .comment( + 'When the reference source is an entity, this is the ID of the source entity.', + ); + table + .text('target_entity_id') + .notNullable() + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .comment('The ID of the target entity.'); + table.index( + 'source_special_key', + 'refresh_state_references_source_special_key_idx', + ); + table.index( + 'source_entity_id', + 'refresh_state_references_source_entity_id_idx', + ); + table.index( + 'target_entity_id', + 'refresh_state_references_target_entity_id_idx', + ); }); }; @@ -67,9 +161,15 @@ exports.up = async function up(knex) { * @param {import('knex').Knex} knex */ exports.down = async function down(knex) { + await knex.schema.alterTable('refresh_state_references', table => { + table.dropIndex([], 'refresh_state_references_source_special_key_idx'); + table.dropIndex([], 'refresh_state_references_source_entity_id_idx'); + table.dropIndex([], 'refresh_state_references_target_entity_id_idx'); + }); await knex.schema.alterTable('refresh_state', table => { - table.dropIndex([], 'entity_ref_idx'); - table.dropIndex([], 'next_update_at_idx'); + table.dropIndex([], 'refresh_state_entity_ref_idx'); + table.dropIndex([], 'refresh_state_next_update_at_idx'); }); await knex.schema.dropTable('refresh_state'); + await knex.schema.dropTable('references'); }; From dbbc5af9681ee5daf80bfaa804466c7d92549539 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 16 Apr 2021 09:29:05 +0200 Subject: [PATCH 036/462] Add processing type Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- .../src/next/CatalogProcessingEngineImpl.ts | 21 +-- .../next/CatalogProcessingOrchestratorImpl.ts | 1 - .../src/next/ProcessingStateManagerImpl.ts | 6 +- .../next/database/ProcessingDatabaseImpl.ts | 157 ++++++++++++------ .../src/next/database/types.ts | 20 +-- plugins/catalog-backend/src/next/types.ts | 5 + 6 files changed, 129 insertions(+), 81 deletions(-) diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts index 99b2b19091..41ad2bef8e 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts @@ -24,11 +24,7 @@ import { } from './types'; import { Logger } from 'winston'; -import { - Entity, - stringifyEntityRef, - EntityRelationSpec, -} from '@backstage/catalog-model'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { Stitcher } from './Stitcher'; export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { @@ -45,9 +41,10 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { + const id = 'databaseProvider'; const subscription = provider .entityChange$() - .subscribe({ next: m => this.onNext(m) }); + .subscribe({ next: m => this.onNext(id, m) }); this.subscriptions.push(subscription); } @@ -73,14 +70,14 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { return; } + result.completedEntity.metadata.uid = id; await this.stateManager.setProcessingItemResult({ id, entity: result.completedEntity, state: result.state, errors: result.errors, - }); - await this.stateManager.addProcessingItems({ - entities: result.deferredEntites, + relations: result.relations, + deferredEntities: result.deferredEntites, }); const setOfThingsToStitch = new Set([ @@ -101,16 +98,20 @@ export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { } } - private async onNext(message: EntityMessage) { + private async onNext(id: string, message: EntityMessage) { if ('all' in message) { // TODO unhandled rejection await this.stateManager.addProcessingItems({ + id, + type: 'provider', entities: message.all, }); } if ('added' in message) { await this.stateManager.addProcessingItems({ + id, + type: 'provider', entities: message.added, }); diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index 8706abc162..fee61cb366 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -101,7 +101,6 @@ export class CatalogProcessingOrchestratorImpl const result = await this.processSingleEntity(entity); - console.log('result', JSON.stringify(result, undefined, 2)); return result; } diff --git a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts index bb35da6c37..6cd846d791 100644 --- a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts +++ b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts @@ -32,15 +32,15 @@ export class ProcessingStateManagerImpl implements ProcessingStateManager { processedEntity: result.entity, errors: JSON.stringify(result.errors), state: result.state, + relations: result.relations, + deferedEntities: result.deferredEntities, }); }); } async addProcessingItems(request: AddProcessingItemRequest) { return this.db.transaction(async tx => { - await this.db.addUnprocessedEntities(tx, { - unprocessedEntities: request.entities, - }); + await this.db.addUnprocessedEntities(tx, request); }); } diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts index bc2d913a73..f479c9a4f8 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -14,30 +14,25 @@ * limitations under the License. */ -import { ConflictError, NotFoundError, InputError } from '@backstage/errors'; +import { ConflictError, NotFoundError } from '@backstage/errors'; import { Knex } from 'knex'; import { Transaction } from '../../database'; -import { DbEntitiesRow } from '../../database/types'; +import lodash from 'lodash'; + import { ProcessingDatabase, AddUnprocessedEntitiesOptions, UpdateProcessedEntityOptions, GetProcessableEntitiesResult, - UpdateFinalEntityOptions, } from './types'; import type { Logger } from 'winston'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { createHash } from 'crypto'; -import stringify from 'fast-json-stable-stringify'; +import stableStringify from 'fast-json-stable-stringify'; import { v4 as uuid } from 'uuid'; -export type DbRefreshStateRequest = { - entity: Entity; - nextRefresh: string; // TODO dateTime/ Date? -}; - export type DbRefreshStateRow = { - id: string; + entity_id: string; entity_ref: string; unprocessed_entity: string; processed_entity: string; @@ -47,71 +42,101 @@ export type DbRefreshStateRow = { errors: string; }; +export type DbRelationsRow = { + originating_entity_id: string; + source_entity_ref: string; + target_entity_ref: string; + type: string; +}; + +export type DbRefreshStateReferences = { + source_special_key?: string; + source_entity_id?: string; + target_entity_id: string; +}; + function generateEntityEtag(entity: Entity) { return createHash('sha1') - .update(stringify({ ...entity })) + .update(stableStringify({ ...entity })) .digest('hex'); } +// The number of items that are sent per batch to the database layer, when +// doing .batchInsert calls to knex. This needs to be low enough to not cause +// errors in the underlying engine due to exceeding query limits, but large +// enough to get the speed benefits. +const BATCH_SIZE = 50; + export class ProcessingDatabaseImpl implements ProcessingDatabase { constructor( private readonly database: Knex, private readonly logger: Logger, ) {} - async updateFinalEntity( - txOpaque: Transaction, - options: UpdateFinalEntityOptions, - ): Promise { - const tx = txOpaque as Knex.Transaction; - - const { finalEntity } = options; - const { relations } = finalEntity; - const { uid, etag, generation } = finalEntity.metadata; - - if (uid === undefined || etag === undefined || generation === undefined) { - throw new InputError( - 'One of the metadata fields "uid", "etag", or "generation" was missing', - ); - } else if (relations === undefined) { - throw new InputError('The field "relations" was missing'); - } - // TODO(freben): state/errors? - - const fullName = stringifyEntityRef(finalEntity); - - const result = await tx('entities') - .insert({ - id: uid, - location_id: null, - etag, - generation, - full_name: fullName, - data: JSON.stringify(finalEntity), - }) - .onConflict('full_name') - .merge(['etag', 'generation', 'data']); - } - async updateProcessedEntity( txOpaque: Transaction, options: UpdateProcessedEntityOptions, ): Promise { const tx = txOpaque as Knex.Transaction; - const { id, processedEntity, state, errors } = options; - const result = await tx('refresh_state') + const { + id, + processedEntity, + state, + errors, + relations, + deferedEntities, + } = options; + + const refreshResult = await tx('refresh_state') .update({ processed_entity: JSON.stringify(processedEntity), cache: JSON.stringify(state), errors, }) - .where('id', id); - if (result === 0) { + .where('entity_id', id); + + if (refreshResult === 0) { throw new NotFoundError(`Processing state not found for ${id}`); } - // Update refs table + // Schedule all deferred entities for future processing. + await this.addUnprocessedEntities(tx, { + entities: deferedEntities, + id, + type: 'entity', + }); + // Update fragments + + // Update relations + const entityRef = stringifyEntityRef(processedEntity); + + // Delete old relations + await tx('relations') + .where({ originating_entity_id: id }) + .delete(); + + // Batch insert new relations + const relationRows: DbRelationsRow[] = relations.map( + ({ source, target, type }) => ({ + originating_entity_id: id, + source_entity_ref: stringifyEntityRef(source), + target_entity_ref: stringifyEntityRef(target), + type, + }), + ); + await tx.batchInsert( + 'relations', + this.deduplicateRelations(relationRows), + BATCH_SIZE, + ); + } + + private deduplicateRelations(rows: DbRelationsRow[]): DbRelationsRow[] { + return lodash.uniqBy( + rows, + r => `${r.source_entity_ref}:${r.target_entity_ref}:${r.type}`, + ); } async addUnprocessedEntities( @@ -119,12 +144,14 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { options: AddUnprocessedEntitiesOptions, ): Promise { const tx = txOpaque as Knex.Transaction; + const entityIds = new Array(); - for (const entity of options.unprocessedEntities) { + for (const entity of options.entities) { + const entityRef = stringifyEntityRef(entity); await tx('refresh_state') .insert({ - id: uuid(), - entity_ref: stringifyEntityRef(entity), + entity_id: uuid(), + entity_ref: entityRef, unprocessed_entity: JSON.stringify(entity), errors: '', next_update_at: tx.fn.now(), @@ -132,7 +159,29 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { }) .onConflict('entity_ref') .merge(['unprocessed_entity', 'last_discovery_at']); + + const [{ entity_id: entityId }] = await tx( + 'refresh_state', + ).where({ entity_ref: entityRef }); + entityIds.push(entityId); } + + const key = + options.type === 'provider' + ? { source_special_key: options.id } + : { source_entity_id: options.id }; + // copied from update refs + await tx('refresh_state_references') + .where(key) + .delete(); + + const referenceRows: DbRefreshStateReferences[] = entityIds.map( + entityId => ({ + ...key, + target_entity_id: entityId, + }), + ); + await tx.batchInsert('refresh_state_references', referenceRows, BATCH_SIZE); } async getProcessableEntities( @@ -161,7 +210,7 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { return { items: items.map(i => ({ - id: i.id, + id: i.entity_id, entityRef: i.entity_ref, unprocessedEntity: JSON.parse(i.unprocessed_entity) as Entity, processedEntity: JSON.parse(i.processed_entity) as Entity, diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index 83483693c4..d89a3b23bf 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -14,21 +14,25 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityRelationSpec } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; import { Transaction } from '../../database/types'; export type AddUnprocessedEntitiesOptions = { - unprocessedEntities: Entity[]; + type: 'entity' | 'provider'; + id: string; + entities: Entity[]; }; export type AddUnprocessedEntitiesResult = {}; export type UpdateProcessedEntityOptions = { id: string; - processedEntity?: Entity; + processedEntity: Entity; state?: Map; errors?: string; + relations: EntityRelationSpec[]; + deferedEntities: Entity[]; }; export type RefreshStateItem = { @@ -46,19 +50,9 @@ export type GetProcessableEntitiesResult = { items: RefreshStateItem[]; }; -export type UpdateFinalEntityOptions = { - finalEntity: Entity; - // TODO(freben): search -}; - export interface ProcessingDatabase { transaction(fn: (tx: Transaction) => Promise): Promise; - updateFinalEntity( - txOpaque: Transaction, - options: UpdateFinalEntityOptions, - ): Promise; - addUnprocessedEntities( tx: Transaction, options: AddUnprocessedEntitiesOptions, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index cd3beb4e4c..0aeb290224 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -99,9 +99,13 @@ export type ProcessingItemResult = { entity: Entity; state: Map; errors: Error[]; + relations: EntityRelationSpec[]; + deferredEntities: Entity[]; }; export type AddProcessingItemRequest = { + type: 'entity' | 'provider'; + id: string; entities: Entity[]; }; @@ -110,6 +114,7 @@ export type ProccessingItem = { entity: Entity; state: Map; }; + export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise; getNextProcessingItem(): Promise; From 305914bd8635abe4f3ffce0a1449d24f02ab043a Mon Sep 17 00:00:00 2001 From: ImgBotApp Date: Fri, 16 Apr 2021 14:09:22 +0000 Subject: [PATCH 037/462] [ImgBot] Optimize images *Total -- 1,076.03kb -> 657.29kb (38.92%) /plugins/api-docs/docs/openapi_definition.png -- 333.86kb -> 179.56kb (46.21%) /plugins/api-docs/docs/api_list.png -- 335.30kb -> 206.61kb (38.38%) /plugins/api-docs/docs/entity_tab_api.png -- 406.88kb -> 271.11kb (33.37%) Signed-off-by: ImgBotApp --- plugins/api-docs/docs/api_list.png | Bin 343347 -> 211567 bytes plugins/api-docs/docs/entity_tab_api.png | Bin 416643 -> 277620 bytes plugins/api-docs/docs/openapi_definition.png | Bin 341868 -> 183874 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/plugins/api-docs/docs/api_list.png b/plugins/api-docs/docs/api_list.png index 97d38e25a678565a8be8745c30af90d865d5d3de..1cc02e9561075e5febc986cc0c36c72614606b1e 100644 GIT binary patch literal 211567 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

q|R>ul@wI8!@DR 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ð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%0Dkba~JZf+S}TO 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⁢$WqwY&&f{9|Rpn#zLr=g7`Uq!xu zj-xI=?3JXj!tl1T`xA*8Ar2xTDoNa$n#(to^fpPl7JCl9p827z-Xp{K)cKFlS0DVp zh!o0>^0zsrOq^A1>a?k}HI5fuTNRfPy8h@9VPm(m-a1=Ml=qZLbvS)@SvE+MG;SZX zULJez-F|bzn_sK5nrKrS$J%p|ij@L5A@<|N;n2Oj9w zPGU2ivE%*tR(|AIYqpobCuz@wO4=Cx1NbNe#(WJPr@$!3_Y4Arj^al9i?T99>u)#4XUC@DmZugaIzl7@Yx5RKg0nj}zX;dz zusu=|s!51YeN4CpQK{JtGD=EHlZ9iPpknUXiQxt+7ikdIlH_vGJE2hR)-v*N0%p}J z={&Qe6p@z53EuCey>#HI_dygepF=!VIfMArl*7fb?fjiyTxnyxp+~p9EVy=i{iC<} zTk0nk=EoPtO#Dr&V{Pqs&MT~wJKAj!@y&u;(MGv**~R;WUq8cloH7$FB@U@6&*RcN z!dlw&)vh^<>zTATszkJ(2xEENp_|x|@QRU}`ovIM^=f``tTyfSZ?BS;h{i=N=>| z1J-w&9^%XBEb}OSuzYmz{oc&)Fpl`={sqZ70_b;ga(dw5)AH$42})h+Q$vsGW-UY4 zd*Ppd)iXcN7MTR%c9boc`NuZ3NeHv)xuiN5#5o`O@~(b;ySGYV&lhLt3C~|l7>+1E zY&+QFo-1g7TD~RiP2R4DBY`cf&iUV~?aOi zTl^lJ4y7AGigfdjb&1LmZ)nyV62$lAg=xBtBbY`Kj6PAkLQdj)2wzil1Ndy33hGNs zOE5(LBG;pJ?%c!c2AsYh(W0rD$X8JieLj?;XlXfwMhYT|CB(@4Y(tQXbX5J!^=JK+ zv@9$yns%0Z85#C`{FsGlzgYKmxlfio%yDzUr1;lz7pf>Q(Xygxgj$LflS!US9Rqgyt(NB&)hmAj~;X;ibqj}=~ty}Av z%F8O&a!s3h&$O_6g(h~|iMyuCa6ea`4KE4_-21*|_M(&a!M>4aI{ggG5#>efPdB2> zpw)YMwY7ql=US&sLEfe9y3xC5wVEs6Rjt#qVjR7Zyd`YHDnc*1{S1w_{FV9#UdeiD z{oY;d6Qz|l#LVotW!en?bDGHO*&EOexbt(YeQ-rI3QOs?$_h>CfOFJ~7ccU=Zw&8d zZC2w13IERzz@Kn`VbMP~cRgRPHvCr`Yb$nDe9wUc2S`z{jF&ci?rQH-VS#3={bx#= z15zcj;yEG9dQRh^p>~jiSytXeS^4bQ3CFDfZ&w)}Budj3Yj`I!am=?{WgLr9zSPI^ z>po?=cKAsLuyuMpt61Qkur@j)Mpa{3$w@j^94OIwHS1*Y^2a;242OaQ?Wy= zxn-$Z=Tlb74)>hTSK_tVow>g48N*0LQS7{1_NyO#QsyUqRUYEeX>~LqmK&u|E~yq7 zCaroal`en3`v}cTyGRV(QHR5CW_ZYU{m;(RWnDYG%5>B1%Lgx*EX@zaFj_iBH47hml-{bak1MM5*^wdh zwl=qbT$SxK7pMkv$yzqx8ZziP4VF0s?Yw>sdd3_^^Y8 z_|iLn{$qQ4Bn<0z?GgdZfw$Naga#;s9hbwVz$YRZ8-t9NmXcCQ0#mX92Tod4BKP6L zW|*=7Z*PM47Gml#51+y7?AjIpjT@z^$`i6ha2CdaYJiJ2>L_7g3|qu|pF5ztYu$*^ zjJ~z?i;feQF?GN{+qPv()RD_?fd7WVnq_&xX=DTSGUlT%IBT&zQC4edqH#g~0Riw^ zi|Y_~fPe(Ji%NtL`=LWuh^yt-zv}Uk;0Dg7WoC}!l5m(pD;+6jhYWOO6BBmtc(v5$ z&uNp65K6xXoe;f*P+!Sh>-R5lz~_KVGBvmvNQHH00ob>_I5hPjK>}D*Ir!1G%{q@r zdw_HjQ4u}hzdl%v8{3#gG5PRKYC`3_>HM# zarz{cCl_{S*)g}t(#CC{JNsKg~ z=HXW0>h!DL9TXg|5z*Z8c8pHK$ zog}2Yld@iW9xOlB=P9T9{Fz2vJkQWbSQc}Jj5+u7TtpD85y-Nm`s$w&qyc>JQ(!SV z(M3|VdVk)0@wb#&beSz3hwZM){(WOKkIGPAJ2tD-zOtdo+Ufp?$e?KKyxy()Ze8u> ziCd;+TK2nh7fxu(eZNQ+EYtdV0H&7IJ55NhubkT+^YG!r{{HP=9asj@@thdAqqqbK zoIVQVkh7gbjuM1Cz-!g8=`_^k)8P7gKPZV9X;=@eXjYHN&3#*66PVbBG#TRbOB_-QkO!M$%abW>3ee);m{ z+dwiYW*AJaophzi>FEq=rtqN~UTA$Vx2fgxz>LZ?&R-{wWU%f064Zf!$+U;u=4J3J zSiyS$Pl8>8`s%^#N})d62=Qm&WrBERb=W=Fn~F-KGGpf*@A$(p67m5Q3cS}dRq#HV z(Wn=W`i9OJ;!OOIKJmgM)G>AEv%mlLVSAopi3JQi{xfQ;$0ZWPxh1nI*!WZ9sbQ@p z5R@gS{L7sJuC`_tf8N|@`~6;|&$>jrRdXfZr*0~=8(ZvQ4W?6qWeB4vH?zCi7W$(fHY!h3zuv0}IOC{M7t?Q^eKVthDJ!)?8h zKbd567m9-y`h`MVTwEL+ra0Mzu9(Z-_Eo!ykdM$^#$c~HT%i(N#a3<1Rx6N?W=tYo zk%KHreHCcvz4?U5?s3iEeq=1{ zJy_@EUKvD07q&o55Ml|+doU9{eXrbi?vrMfzPqU3MIVgFd?m%JZtqN^)Z^RD8O*wYgt> z9*JZ55nCu+v43wU4}8RJjh|f)Sp6=$8q`W~a;YNJ$Y=f(N@u5jrpoo};)0Em^BaiH z5S#FBshoGF+1HN}X*r<#Vf}H+hS;_wmlO~#EMtujjUu6}(3!l)fKLZ}d_8D}vZcw~2f z;vBt7{oK=mWgVgGKFnld)WXnVeu|!1N*=K=S-9z$N<>LEC(Sl#j>MCfd}UgqY>K80xE2u`k*va+gb=re-nU6$LuT`&l+^&t)!gY9Oi!~4VXLrq;JrfJsP z;8nZE(ITA7H?~qob{JV>cFj+Ncf<6|N8V#}!A7sH|{vQ6>4An;A^cBqcXYWbWCxYIGXjj3DtMnpPrZA7O0XRKXYbw&TGN@m@9sn!NrtTZ_L_Xr)~g;92_&>%JG&KLI7;tbgfR;BZ0r1= z`*za}4-G*@{6+Vg57{ZC@s02TkK>64%Hgh=cXyc$`;4d{ij?3ZOmoU1-JHi#Kr(>s}{G%zU0pIQ3 zvE%BOSAVqHFYia&eOlR(j*iAKtT|AN+p!6#VvL>4;I( zH+1>6k7N1@E$|jLu1I!#z3OAHiBrYK!lF?+uxXI~+ctDAoMjK|P3hvEfYmbAAGdM4 z_dtl+PP)n+AsFXD$xv|r0Vba0(Rn68b^o6evt!Q|Df~oQRgk1Z;_2OV24NaUB9uuV z9*!o6xci7tK)7Ibb&=pi@1b$n5sD2{^!#3(XcMxGL$43ha_`KYJK?!D-6gI?jDb?u zdYrz0e;1KZ?1=&^{-Gt$eO%R+^Tqu84;rI?pmVW=57Vhrr&i~_J(%eHjJ0UdgYzO5 zY7_WxlU=y^Xc_Q$lKpO?xT5!xK|WIQaDq)|fx3DyS}>)~)Td8RY`vkPs@h`H*4fEh z_5sDNqhO;`S}*Pcc{q37@FBqq&cx>Hz)ZbUinD_5KB7Y;ux@*(uVxBmwS8~eMYq)9M;!eONlfd+C5CQc&!}t8&~}o}XloME3Cn8dNKO+h z8FEaT*<8j%C%tV$(C`|BT%2K{TV7gbl^Xad7dF{KM8J&5AxKf#`YLojnwm$C9<5x3 zdZA}z1|wCkH{qCH9`D+8!l1J5{ri^K^JY>Uz6ysh>mTO&W8mXce{#`f|2Jr-3}nmR zc>BbCdHj|Fubk?U8B`~z^qcn`Vlyk|6G}9OzQ6BBE-QJ%8JfnG!-Ns%8z$prXCD_#GXZD#>gCd2*hO)X~XFQn4Otc4ow6Ja;*!k;$vaYY4Pu<82QZd~hg`0~;RaTKM3LM;8MM+HLP^;Mb45zCf z*HDgNCK@kW*$AI;ajTXWU$IxBX8iG}DZ0;rAsvFqEF(hZ^G>qN!p7i%dU2o ziFT=q65&hsVPI$JkDk7`0##X201+WO<}&qqBkMbC%TVqVh1ihEF($dX8X6i0+1MzO z{^CQumha*DL%LCaZ=X+)i^E)$=)0~0dtfZ{+JtLj;vgL+fx1Mc{)OSI_ z;!jlP^;cT`>btqEx`zJFA`qE{`L2*-8pac`=au)A%QTGecX10_vBbY74lW8DJ+8Ma zx(7artEHSeH8N%M1}|ErTyslHk;fkIiUTsWzKxnF+ewQ>MH2ZPVId*XXOx2vvIYov zSsdZ0B^Q-QWr-K6ZO^0?%=B7au@&RsSSWhW|B5Y9($V0ig5 z+U0lCl`j2zj~WCsOWyOR>z9-Zuej%i`4v{8IyNOw*R$)8`n_45!+sQMdmPBlOirmB zv<{Hen+_&XL!uMQM@5Sap_hzl=b0lZ2b&2Ff3_ACOz44GMULP&Ve)TN=(XxOey*tR zpuXN6ZT5Kx1L#-vbajWE7h!C!S}AYu8@;rD0p>&RJ#B@V=#VB-688iMK)98W=Nt-_ zo}D{)QV!VTv!1fmM@|MuUeoseoq~;Z&qqlmpW)9#S@qqmAUogtSUUsC$rwKId-v{9 zHOIz!fMR#2Gq%O%NXLYKzK8VGY?$R>yLD}=8g%rXXXy363noWGwRZP|&90G?AhcIL zutu4S5)M1oE8MBd8#1vZDq0MuVmuQ&rq!n|n#%4aaycx#E#KIf+qhyQ$a)Q6mwHq@b%jY;#)Cd&XRAEra% zqhV65o93oSq}I`0?t&baj5;kIrcECA=>_fK+)>1r0V|C>DG*FMyo-=e`}s>o`O0|_ zD;I2M%_B2}BIts0w2Vj5%$;N$pmkfWOYA-dO9ys#;0`=70c6!AjTe3?dUtgf8>Gg+ zUPGykx%CNv$;Xf1jOS!^|M~i$SSVc)A^5D*iiAQwrDGdVrOFM!-MfuRHa2NKE>E96wPi)7?b+f1c@>p_xtHI$q^lch zggEf7`C8?yKLq;<0Q4~V^6u3iOI9DdYNBdLEWz3_l}p7 zN_jyz87Vs7UWTwyd~viqVN^OWJKWkZz2i|iBYGL^g(qGtu-z9PdI$P($@Cz@CD%vc zbDw|R?Qx~Q(Nx>Y4#FJ6FaI76M>_Cca7MAAL)i4CGJqViZEuT&GJr#-$VOS-gGtJ9 zOTJdtm>qApZ%TAAI7&~-DM*TK~(>ReUm|0k;qyMd)=Nkfb zRoZFdv&ITMtsEviM;*>bf!oOAeLTuxMVJH7U&>XIE6cDT%t}jkTy>a|OV? zk-;CIe*CZ=zkQy*4>=_1f+)b?6*4s1=O{r$z^LAWUNTgGb9}A6^x6^UMey5lzRSC$ zd|3jsSMj!={!cB{o5ykc0Rhsh^%vNGqlC+75uPGm4}!+3wtLGh4XjSatrpk{sNVMM z3(=x1eiZ9*PcRslvd<|g0VB|ZkJK`T1cNd@y1Wd6H*xa}Q74-#Dful;@wC^Y0?b|a znsVkgYChnhmT)rC-(4lb0ZEgu^!Vf~5vb;WUq?rWdSm3tK0I_PNX69s7wAo3O@dTy z>JDOj1e6OCw1Vb_2DO%LXi_-O%FEy7-Nf;DkT^eEhXZ%mYx^F2iE@13EjDHIVzs2r zf!dUB&00p&-OK=*n3P0N`w0&ChkwpRP%T$%1KN9{&)+H((j^LzRcaMutGajZg2mY3 zN92auJQXRv`Z|cBF@C#Uu;z*TFmeYN^ia6VE&W*;O0|u$%jyHd1#~Oi@h0WGNq;sqg6?D)J2888c z8NhGS8e?2HbQA;3bl7(IWI5LV`6m(fO3E*v?`O#@9lc|YzM4sZL#AoN#*J1kV<7mp z2Vfrf!r(7Q@F0K9GjO02^__dDV&EPwR-LK6^YdWTQIYCSZ#7oE&KPGlNkZYNQMo7X zuv2M*54p!zS zs{FiI2&kN|ULChzMz9@WzV)D#z$kMc5hGpQklAo^p$N*@`o>xSVaFT?&K1(Mzs?5C z7T3FDq&xgGNUH$f>f$P~M5W#5uFjVO-2WJRSQUWH?eKwA!OZlw6*J3`HwH9j6bAP! znX%NKEpoGw;7`45?<$X`%moM3?CM!j7q-#x{M4A$+p$e^Z^J|rcd|7Y6%L+D6%Atj zYM&p@_Svlmba~3IrBy^SH!7sHt&c6KbuzLt&_+f>#7*hzr|=R*rA4zZzBk-Rx;DK* zS(sEciS~Jqij0(;)39@v0xaQ_Z$JO^<8wh*jEMqO)2oF9yIEe*6+UbepKi@NmrR_H z;E5zBm>fLFS}hij?WnNBcZ@+#!qd~dD_ma?V`DCFfP%Is%Jpt+g^hCtlCr#hbWD~+ z+0T1N#)R!p=FZiAm<51z-{3Nuwd!b@gYJ82=F~?`yy){t!f57ysoaUv2jAs2(%_x zF;wT6Kh%^ti17-Hj(R^wr=K@6io@U`CT7H0WNXRIJ=@=6rU1uG23FR%@Njej3S%4d z{K-@=7G`F!tDUEZH17y(%x-gsDH8BFH=~SoWeW}W+uP9!?t$|jwBE2@KsQqsG;8Kv z5fl>Q1oKR&>;>#pI39B$84Xw?DR2v_=OGBmVq$bM^77#Pm5Rc115Fp><7P`0HMMf5 zVFo(JnLmjqP+T=~a+1ZbU5WHFvQw?)`!tPJgAI6Pb;Ir6d%C%g&=@}IF(U<4OM!*c4?K_Ac+7k$GE1Pk9ZX)!Wp9#44^Kn7gv zQoPLKCzRW>f6bZ(!B$jvZB3Q(YhGm&MMb8SwRl^1e=k!hN9wmE>5+=R==k%t&1Sdh z$?EhtTXx)3h=@|v?B+d^Bx9~yQhtG<3Or4brE5jwrQQtl`$6-}Qf3&Rcwy`44@25+ zN3PTn8XYk0?ijDW^cS>p02T8|UQLjm?cOJ6;>x2r%QY{RJ#1qNGJm8sLsM6sVa}rR zJb)a3m?N<{wz%izihQAH_=D2K$Dz>J}S~j$Wpc0-JYV+)^D% zyc$6dksPLmmUq6T#6;4CYHHf#N#qu%=@#-x;>Tx?8a~LE-KqPIFT0oMeK!+nWq2_W2H3UuT14uJlZcvh~wx&uqR6l@}fw z1{t%+uSDdCa6)Cv<%s?p*#|+dEvpk54h(DPxX2qSJ-v@^qriLXEa&iJ;vmo3EfeIy zF;x~ijZvrYUE<~O%Z(h?)!z(ut@+88oRNX@3O<5X(tJW&zU=n#^V7rk#E_MH%@-Xu z;xU*!vJ)#|oqsh#J%o-nbe}L;@Fsh%=on9&xqt(?q2pe^-72TUVl{Sat1saA8Fm-- zn@0rMfv#xB5S}Y$QNH&dc3^|pFQ!BdYSxEs1^wo2!2|BCw|xC(A}(m!9FcUCV=UG8 zP1OTBu4%q6r@*5$*h`=xHox?G*Z2fo{*YMQ^GB_33;oDg1)oNGBc?XE4o}EEQ!Ep( zQ7$p~hn)Xqy#iMGxW#iZN!9L@Rd?euYa2V>TF~S)HAB`h_2>i{_dYeXwT)vMpFJAl zd}`58qd3&BBV63fDrmHEGq+xETDDhfQkA0LL5aeX`n_47{t+8IA&T-JJHdO#OpltC z@QqrH>N>f3Be?7a)({ny))>U+hxT) zM_gs=+eA1dqSG9riT7nfqIjkSr0!mizS_qB|B-Vm??#)znZ z6c8`q7Q2E3SiypF31T0tix!L6f^x4)xX3-w6oi0+1hIl3;DuJ}zLQBp`(vMH`=k4# zPv-{=!#OkGocYd~Gw=7l-?`E~Wn8W==dNFp`FDd^mi>$VZV5{}-)y(F;f||<>z7|! zJ&Y~yelh;=gl2CO-{Fbz!m5f&wfWo6?&y>-0zx-L{PfQz$w#3Rk;fWd$ARH_@Np&k zjb+OCX}U-Wui0q{_Qs!Aa*nIP`_l6Bf$`f{;48q$-z-K^Y=ss*JW&-XaC?IxiVB$)|fW@Dq#Ol3)aa! z>O(%k&C<`WJP1BJC~S{zOVCc=pI>n`BmzKrTXC6aqn?X4#!>>|`qt6m^ngh4Y{``; zh0;r6^`Fanytas|vKqP$mU4Fy+=;D;&829rNL!wNpi5iA$caQTBkE+Q!!NBrA2+b5 zr&(pv@6h6cwSf(*ZtT&Ko1rm{>@aI3wm%WKDu=9xkT1tCE}Bl`JQ(FM4< z8fAN_&YU1D0GglwK-tvaiN$>JHXdiBb}n@*E+|^sd5iyUqO+R2RVHV8dKx6Y@-S%w zC_|VC;*%F^i1v}sf}&H1eWaK$G9;2sO#lHzVdO}+L2S$mXu~7@YE9TCY^h=2rAjSK zxkEw#a=1l+Cl`@C{);aRAjGo$cmTmAka8SIWe7!`?Epm}J1i^=39vxBM35PiZ|oO+ zv%GsWGI+g#VQyX>TReHE1yLK!)eTcG7Zwt0Y9P%FpmTgjl|+vEWF_X457*4R(9A8*29vDU09FDz{1S)i`Cv-8CzYBph}kzV$SC@%740ImcUc83Sp4!qeWLSo$5 zNG|^tvn@9l#68U35phMfS4{Nd;^ug3Mzs_Yu-4P{QMvZ_N-^<;@M^Wpy+T$KBcY0{*H05Iz zp{Y}h&V;5;F*-wnH&ge|;(xZx|Kc-)r3w6MmO`RQ@pv-L=OY%H$BIu%QuaHKVH^cl z^SKrkoC1#gT}#Pno1{`bqAI}YE-!s z#~Agy(&xS5;M7lssrjCz38AH4E4J48o7~Dqw19 z>FFKojsf+cKK0xz6%}I1qpVegg_DyYV3X$bO>;PEbLWa`ZVe9)L%rK^PK!pX+9zJw zdj_DIvIniX7thC{>s+n=jt3@2Yr^Zv>Ytatbm2tkxpqkr%~#%H1z!KSe8i8LDV8gh z9dg^+1w^7treHRarxV$&TKe|GUgafHb7)kgLGiDcQ!5ny71-h!4Y@j~)LpMMz|et? zi!@mB!z0izG#=Is$J8eBTK&GyR1OO@Z@Gv2B1?a2@(QbVYISwBUGqY+(zwvZGdu?* zVqn7+*}Xx7A5>(I5#iXJPd>F&3=O@FHrxSMvr340mwN2~a(HO{l!2{n*Jv+QQ*+L| zMS~`-vrd|l=POHW6$;aRj~cI7Q6D_d>SxuEF(`irojg=#N|@EKZ%oo~tKyf-O7wb$ zO^j?6&$X>G+St$?NerxKg95kklM^K+wn|SpY}=gKkxjmWC{EEJgW?I=|7*4vcmmZb zaszHIn|9$KWOW;{PLC+$f({=1Aos!r7K=D=Ov>9c-7zpQSQec5VCJHGXIWv$H|k2t}n*VI-&5T+1<*NzhPsZNL}foL>wHWi#Eqj+3Av*Iw-@dTi0{c-hO+6MwQN0 z8gu`ty%GKC#dKdBJ})?ss&r9lY&;(pD#YOw*`R@;BnL!Ko`Ir$4m)BluVrae_RRiR z@-ME0Shhx}vg`c;-}C>!Db2*2zf>RhvswMv@<;g3@(5?I2;R&-~Ct4BRS_hlAOo;I@k4lJx`+9L;Xwag6wC`oVjFZaNpw08Rp(I zXD$q|GXL+L^{V|dXRe_MKR|R}DwrPfl7wz$ z7W7?Oq|H0GY(87&%c^pa<=+l#jo&}m;Jc`M683WH!ZBT`EGwzB-BI4Z-nMP?;E(b8 zP@h~To~Rl8@?x_Anmo5YM!TIQ6Wp3N@6-B>F!bBdTQ>FBzO60FAo5uAk_V8|4aX zia4P-Rp;#|;>=HC>Dz=tERJ;W&pHWNT(A?KwAmxaXA>-rZnu}6!_b#rCB%f!fm`wG zw?@?-k*__ixbe=Qk+A+si%5bm>?QU-E4qc9P zmRS29OMl{>3Npph@L^MXB1Q+Po90I7Ua}M{KB#66xOXSN)>M{ub_3Xd)=|DB=*B3n z<#I3i?zpYUWZZjG815OZLxg?neND45QT`XFb%v93CfR-?RRyOz1yk8F7Xh~!vO{f%nGb)8rJW&v&_2)pQJVv+*HIX^6qBN#bX`%LtWyYfW&GAA#AAZj$MMt@HFNOsD?W zrCfu=1`Fd{qS*0wjMCl0vUFPHPz9aNUJ~)-tLOSgn zs+tExn;}__L}{-YHog>{@qYv(~^U&kj@YN@<%#y0lA#6lo5hJ zPnhre+)cE2uw02eq3U^6+;c*eLk-{MvGtDI+ew4#KhT9>(#vvK>mhuQ zk^K;_i7J2)&p*_HK8&XW$i(d1$yMs8Hd0^fuQ9`d7?OQdl+d^ZrTY*uNtveqQN8s= z-|H2qtB+vcePleAdHgv%3QkkY4^E@Q@#nuvRKf~sY{35i!D3B~bB zYr)1BDo${So1OZ7_S#Fy`YwL2!9`pg4vy|KWMDTS zQ?SnUmeH2b_C`YD5SMy6@A@0Qoz0awSEr9eW-HQ=LR~dOBXi`h&ux8G%}D z<(QvB{of3*{Q)GZKHt!JH`}(es{VD`9|%{SzGdna0~TO{0l$ylnZy$CAuGvjUMlHj z1^^~#Tn%=;#F zNQD8j5g!K2DYYFscCe%M!e^1O__L$(W~qVdnfe*eax=-7Z}%Ep#U>2WzxN|6$!deO zRp{NL%;f)SgBXQi=3=FJpe=zP>cL4lHfUrwN`5 zQR_#{#P>A?(L4@;(gsz(v$5ne537Fg2Z1y5(|Za(S&Lj|{9rwwfGm`I{ZwXKZG@u# z;vDvX-QKwl^<&dy6zw$Xf7Z=#&U6xG8iK#tB(a$OJ<9Gk7=gm2CVw9&`B!VF;|R0{ zm~AupepUy1Z_ZXy|1~{v0K(V!L*l(&d@S&eczpHo{_?*OOgCy3(9(Iego@Afpv8@JfrBBuyt*8wSNUr-c700%?G{|Lo#raf0Kv8gEPfWPjvn{ zQO-;tvus|=Tl5*iQ(3UuM_Hqo+R?`Y$Lg>y_u+(>d~p3x^#QV)Q14iU0z=>E67~Bc zZR*MHgCTkH3k(_~A^rWwp1d8lm2j>(54|4or?4zEFc8N|?_7we>9~gzF%huIke5QY z5CCN1h84mCl3A#}HnWPDF#Vd2*s8+_$q>@fY~{4~Vih$!$8(9~a_;zKXG!F+{ms}r zG;rJQM0f1>j zEGqanD;DYOD0L_d0VSQ|2)0Y-hA2iCHf#>U-I}yuum~rPleT5FMQ8F#BGC-~ zH#fe#^bnezf~uffnnf>nc$&u|c?0=y3+deORQb7#+mcxgd$BUzN3`cS3bgkZ5<0ni z>8e!=ed*oVkw&YN$c^KIlZ&@^a=78msextkGGCR&_!;4!x&5rV?y-rF;KoS45YTPG z2kuH?=SZeQC-KriJ(9d7yAg@!5j(tpJ;Yi+xpAd#qS>^FNl07&Zd$O67yxzK0Rb(g z-=&DveAvRnbRtUex)$mEZ_l(WWFW4Lwe%o4zmQWQXP-JEu>3RNGL*BGy|tuL>0&vt zaFu>~xAK6!Nx0%g6_mtSS1n!m9MVPF&6iP;#Z#V7pv&HWnM8Z_iegkFYsRQnjj)Uj zAh|!cylI~@c2pr%>C>-2bb|a^@Pc7(*fU-M>NXuncq>M5DsqrLX)0344EUfKT9Qs><%#aF_)5&kLgMC8n04w3AE< zP;#|+OiM;a_kLapN76e5Lk-ms*a9mbTp~B!?!(lMcKkElQl)FKBRYToFDq0BxRT*o zauo&`oXih-{7L!D1!=(QL&9@G;QEP;eR5%6c%A{ z!`UX|{qKM3-N$592vvX#+^q$F-b<2>NSO%-njWJ^+ z<jq|@WH`n6rYL_Fg1h)Ah^QSA$!vkWgW5Rx(;wkS@hPXMqi`hBENU-Pdmoqrk$hh@M1Po6eMc$WJL9f#1 z6mf*DRGp}3JC4ii%lUWF$g&^X$9K)6-QBaQnT!T=(zxNU0-5d*9l^e%7N`)gB3(gm z)l(-KP$T4~KTaF#^OI6r(0USV;+A?NH5qjo_fgb|)(wXl>*O06sr8F!T^ zzXilo;?{$wahsz7S%j+gYQD=ly4uDE;2I|UU`N~Dizpv&@PxsWYrvwld3)KZ|0xxfPeHx-QA{vfC(Ft7P2GMNp2ToHRu98`ii@c~HP zHNr>n&1hFMyk{6GJy(n8})t9RrHSL%jj zZuo4YdrL0;{purb>v1RU&~}K)2o5@bzH8vh(Fkr}(p?j?_^X@19Oy#MP04XA9K;H%mVs6%mQ~z(_fTX#Dz<4jI|+X04ci*|e5}Ca zP)Rz#Ma5Vu(fbjGnvo5yxSnef?`>Qs_`o)8*8@sDP@Jiw-@@ju9-Fhp!<9dA;0a$W z1d&kh&YPef2wYJe#tQf0;Mekq{RJBJh?(|V-}v+feB6$%NU__-Y;&3Z6dskGV+ZeB z>J|yPMNef;UB1>>=NiFi`Mz8KbX;6QL_Da>Uh$^MikhO0mFSJ&{oM=)>z&e=Z6W=Puk9U@obH%`Wb$=uM&E8?3&zgtyXkj zQ+h!%w42BL8UxSia~ws|pN4ujGm-Q_FD!sk-DNpYb?1cOZX|TI zNm=Ku=L>tv{bInHs4n)1jvY?bS<_>+`PJ=cOkTtquR`kh^lXVVoU!yLrYg7FC< z5YyApk9nLw4cNOg`$Q9V46b7$=FoWt>V0p@e2QQk2=e_m893+DAJok{IZy&w=2BS= z3++^~j{c?8{f(8mD~5hqI;XIL2@~}%{|ZePd|s*cMg^zON@_BfhpRrqpf0sFKCavcTnkbhYj! zIXe&O>wP((uOE2E*ox>87(NwmU=%PtulI1JUT1U6$9P*z(rqRC_lqDGbClsC`jHlP za&!DyZE0+VDw`ONyV2q)gsq55i>g`6=s)V7M7gP>$3Z7>K*exsX{*~D0;xxs3@QxRO5$?}TN&7VN70-k0@ z9c!WX#7r4;1%(UmPz&avHx#;Wm7Y`V-n-*vuko|0MEbM*LJT)t(GN>g2s`0NAg2p% ziC-OkJ`%v#V{j`C*gB-Cf# zkW?C!rj%^teN4Xuae1-84RBQzdjxQH$?xme9d)cWk4HwON^2g6+?LYzMWi+C=@?`O z0;LuDKn03_-tRtj!7Nkc9~3RYm8ImQGz+(0e9wa}9KQhYB@sk`JwEjLHbBPi9rI&)hv z8QKhuDLvMH#{=;OqczM_(+yMA;dhTU zgs51>cSrH|XXH{i_0&MF9;yQWW<6qTW4OF-r~97ab%Ea7Ll}0>%12+@eFR;qnw`Cf_S`%Q-6USP@SCOf7Nsu%IM?6a zzOkGw(`r`lPLmyxS5Z69EY4b-eXVa*Im+~;x>bbXufG35koSN}qyI&vXyQc9i@w@I z?}*F<6lUGfHGe5bYh#>*@|ZgW(<#yp#VK~5lmh+G<5gZlA(CoM2?|2SZqZ0aR1(3< zTYp_!Ts8aig1)iTzQI!;MV^2fQ@bzwM7jt0^JL( zYpWt{;Aw&2ufJ5ep%(oasqZznxa>BM(_%2aXI+t zaBdezmPov09mLQkD!`MrjBlGgE99zL4GtSh&9=(pQcc_LjB>?A+X=()zS_WlPq?-*<}0%6qp0K_`r<603B&HUdD zYuA)OQ&OgK*u8^@Ki-*Gv!4&!%eodbh}thD5CPe#NmZ3Ew$_%vbTPJ(fnNsI+SJQX z=)CS%G5i1hE>i$7i3{)7)|#enleWJ<#(Clf!%bGLl07R`)(&x7;nsTRJypHD&D^Lv z%f*zw`A)U;$hP)ia0Dwvaqx_gNSp3-88l)n+bLUK0T`GmtI)ZmDTuEsS@|<8pSatX zgz4{?4U*WJL zvDJJJo}A!NdLpUlCcCOYy%e7%Mz-u@GWr?I+A+|BxJl$hJr8W**A|px=ewBk3CU&c z8Xe>T5N5y0!=YU-hkBbAq>FUn6U**p3YUS@t=tGupHJiE{B7A~W2o|&PBD*Ou2ZpU zGj~s`SgHD(D&}D#l1jSaYn}3!L&%E#`uQzB4k5=Z6RGZ&@@O|GP=mlw17F&!lnVC0>47B4W% zKTcoPK-?GU{|4}O)QCTB)j20RqBMD(8sJw}5iv1V(Hnih4QHW~JD4QZg}gWvh7-uG z_BH7Z!)WIa*g73U^!D!1kq-5mkwJpy+}N9eCq!uE`jpr*y>d*cBY5-*p2kn=A5=&> zz=sn0z1^2SBl7duSPOB5BiELBkZKpi0K(R~jcGX#&-&hw(ZB8}vfn%$Vq{#Wet9YU z{bW*QBz8byEbPW-hM<6p3Teo}Dmn<8lgPykfw0h2Wz1y>0uRcpM0u(ou&vD&rw-=K z=07-&IgMvH>%d=!{S6` z;h;}Uc)a;>C>8>;ivRrj#@}ltn6R^Bjrac1W=ot7*yvlQ_>cGe^q}xhSLUhAgdgX3 zOyB+7;xF9=;t23}Gt`;QUlEI@_gX4c7hrPF@fuw~@%9KWE>$s%?p&IL*Gcprjs17W zuEt(vu|`f8MBRnmbSBoC6$u<^Y4LfaE-0>l&*fBa`X@I^T2{k7ojK&^OP+%!4}`gOF{ zur2``OQAsx5V&l*aIyZj!h}!IF@qI9Djxjh~$D5&j zFs{f0PhF&&eU1+5pOW}g-tsc?Jv{8`Fd{1ck_cZBcXf(D4${gJpOlxnX)0{vkPUU= znGI%$ilrUU9vw2w8HRfGJM{LPn1Mr;MMfZ%1M>KdfU6_$3#e35Nj47WPKwF@4dDD0 z6lu!)43IejY^yppKiiuF#O|8AI=$wx^>s&vZ1^v&m=~ z5XMX)J;yBH_|sqEtmZ4Hts$;L6d!C|Q?**aBx=E zb5VW|DdU|31G=HPWXcqz%n}-1*wlntpBO?w*h_j#q?Oihi33oJUqF=;$81+kki+#& zPL|pJ-W_Ip&yTd{2oocz8nUiJjhqXfprS9x{@seW#MLQDFJ9dTw(hiY@^4$zXaGO@ zLE0v|mx+YuQsj{#0x6=33lPF$<6XG0)(FGS`8;DSfH4;?{BuV_6t~BZo62#sO6wyE zX_tp^*l&lPI38=Ww@8)FjQr77=~XL)sMox}v$sxJRR40!3imH!ks!~la-2aAw3ttS z&RqPN9XN--K=q=3lswsAX~U)vpB`x{CXTa*+siTCTX(gw2$L7|BGRi|PEm*<&o{GD+jR|P zG2YK$!@EeV&4V-*Nz<#)pZMF_1$#G{Aqs*7hzq;p_qSjFp9_HCeLO}Jo&9GG0WH8< z%jH+b$?x52hL*?c?7eMo3)cJ(*|p%bwQm%pggfRy1z>+^&#}OO1jow1q{MVNg>ER% zYBK-0U)@;C{N}p90N4w>f;!3E3z5981il%=J7Z`i^15DlmWvU49252q-)2SH&)g39 zsQh*lmb@#DcAgE#vlo?Am$*!2D?az3mJPB?RTodw2ih+0RqjCtmFzd1twJ$VSr&}q z&D&OGOKtA$3rEt-V(fvE8u+(F&FckOOmov1B@|H;jB}}oqOqiX*bZmG-#(|c$Rn`Jb+7yto-$~GYS;VvpMj)+o73-9B zjPQb8u&0h0lc{4zemRR7N|ynhEze~22J8OG++Qnd_^*BeCc+Yr1y#bxDLBOP9oO5~ zAUikJo<*ZoIg&1scK)=finm+SpF83s*x^q$Td|&goPy(NYnFOBB`XMQz%=QM@4vP) zqIQ>IS(v5okh-6At(xXKaB0+4N=%bZ2@B_Y`B7p}XKxO)V&LN-2aeZCPFOINxj;5O zWu!YXQpBF&Z%K?(l@}`Z4I45PuIh^Cn!7Wmmt%^tdVlEe1Un~_Z+3k zmOW#2%zfu!PZ+(BJEh>uB_g`d>tKw=R9mjF{HnZ|Lfu(P$s!pTs&4CdlXRVjbOPwM zY<>LU-7QF@*|V-D1B5ov`6~mi?Xa+TKx_^^9q2F#oR>K~fJEXv?bWz4#sX_|boK?; zc$9xO*a~GPmd@t%i;%^{ZH)e5`A8LKx!3|LMfWO$}%UnBd&rYVAdXpIHl zeV82Y>N6eSvTOs9N!GR+*~Rbo2FJ@IV4|zBe~3Goa_1cT~92T z7Kd-n16x~sS%i&isar(4dV-qxA`gwdq`BDw%i24B9_T)Ow8bPU zKo?T-@*$#=lgny9gw;Ab>j>C5091R+_)pyCPdtYapJX_R4FAR;fMM|=Ep_(pW7<4Q zZZe9tBO*k|dZ;HnkKV6NH5Zs}>+0&GDq2PVO0IQceq7SL*IE{@-2}8S6 zpMiZDaY%Ye3d`cM&a`Let2OK|5cvnApKO&pQ?9( zmC=OsYnBeo)O6-t=QaKMzwRDKbcMuBtRpZ|%&P#AbYJ6}DBN%8*8{d|Q;oYxcdizm z!t6hVFOM`q-F#I$0+X6A55Um(Jtje7fB;rV7tz$|{ngr9g;GRB3*+la`6`nbz*B3P zild{F?Hvt!XWz`}gymRiNc;Gq1wTMq86|%AO9R}FPZ>G7Kas3?`o|COuhMgpT?IEk z&w(4w8$UQff|ZX}`i6$#uL(wo(d*^tHIt$D7J=)fn^SBCdaY z!BQN%5+C7f@7iR$%?T^WB#7i$2(rjH^7?xFtOI2x%LJ4y;khnRJC6S5*e{C9{ys0= z%bosen4e4l0tGEi*a;s)%T5CSi|$Wd?J9Zp_n3Jzy+EWZwD0?K>5na*ggmF-y5O9| zD?Ll=-d0XQ@jcJW3u%Gw`X(osSDR5SjHPWgA@cI}Lgd_BYbrVT^2~KA5LTcFtQfn9 zbQw5<_cpWo%qOES;NmD{_Tg*wIj@jgNAz#3p4YXCxn-4Ru!D6)(TSih(0`HB+O0G; z_!CW-JgC5H@RBzjnSD_OekPI2`jHb9u^e9E8fz|^d-txD1!_XF=N;a2pZ9bo85~Xu z6gP8?H8ck8Q}Znv0$15iV>_&GB3Cw{+{0x-E&? zo@neGE*XSpK^@1(xke@oA6j0vMJD~0LUzcLH{43+7Muh3 zz7OBDil2X@$RUj2b-(`T+%r9{>LEE&Ay%@;xM+`>&S|dOI6m8MxNcX-fk4$ZYookFv~LAnN<1A z^X`{z-d%8C%a)2C96flpO42z0zD%VI@K2LR^!6PYBXYr%=K!y6sprEXNd0hK(ec3B z^P56&Bc1%7@2kfdG6Q3Dop_19S6thvia*qOo@PHB?iw&C9(?#|CGSpcbdXdYk*QBS zrFkd#j!qT;;%LZB@qs2^>o&Q>Yjo36Qbs1o(G(8Cgw_8)gdG&gE&A$KnMmT&S%~~6 zri`%)rt@yU4Fo(~*!9J1?E|>nZLKX%$q;`dPv&GeN>T<4Qd}Ti1!c z|5!_v-J?%ai_NgoEbm`KOn5AV+Y;g$U8p$R!z`n?AeaMWop)FONi za`)9c!WVVAi{NBZ1xF*O`=b^r3s2|4p`RMpnTgaSLF#zFM}xZ6Md9V9AC;4<`&3#| zXh-uOJ40QZ`DwtT-@kz%;Vz3M$2?r1C_#wOUgbL`rt z1}mxdg?>f29{Q4Ph7he+Ny*`VjEsd~UKm86>c+2I`ucW7tYf3|-kOaHeT| zmq{gtMCx?uhQA5Ej5Q9Z14#8XG&H!wa`IBrDjy*Cbq1-*JRERnlXWOno4%GX2 zjSPL#snpFHqb&p|*xTot)fKgrmh_s*d3ZxhNXq%U@`gLan;oUqm6_w>9p&>R>_D+p za@^{&Z&ht#*pek^RTKh?kyb@z!5~)nMnSw5gwG_t6*F`3M0R48LU)S=hrq8%%4r0CLdY`eVEn#r9aN_Rd+B(dv4LiI!a#=F z4L?NL8BUO5g2{JMPXCK-ljpc^3yY1Ccprpcvjw)WzWPz9wMEw{+^B|VSS=V1szovQ z#DqQ5zexW$8N49&IBDFaXHTJysW z>=9{>%(DDZ$B#Hyt_ezi^Yh<=%<#4<8D(i*taT6f!q)FkN8DfmB1Hts*C(cJ#Xfjt z=l;3k$F{2u2xgIPg-M@>s`{rk$DVAPyw?4y0X2F&X>7`Lypi1Rr&Fq`96 zPG-@iVf@<#xdZq1GiPNkEo5+WAYJQz8w}Aq87Sv}Y!9q13y2)o*3 zmgF2;dzcXgnM-F%;1qn0{p0;~Jr&9kqcB^aIN#Lp(5i zWTE;eGBw*J?}px3#jQQ8LQl!c@S-4d-2(v|d)(BpDNdma-8D9)0}d@u2PAOK+P!P` zdJA*3X4Z4dyc=qQtW?2=+l2yaoCOQQkzGd=!ualeszaggEClB_9;3Ht`qCs4f;)>l)7Hsi)-iBP_G8%T2 z#I5f*c{rPO@o>xm`zhwmLRy7({DFX+78;^HKZ;)6L4JnREz=h5+4N2qDHY25;gV}3 zvZ{)it|Hkxuy)rqxKkoCojI`FQ$8=~0EIFQ13Ma8FXfa48uRI~d4Ba?uRK&j!m22d z-xsB>eF}a#z%R|Ar*OpZrB@v|UX#k@SQfh!-a7Twd~}MR*JSfxCen7Xm9jM>H1zdD zvRdX-wcyM544+Qksk*NDNv^{sxna;}yp-)*TVv}5bd75_sc za?Ab8g?_aU|20=EGxUcfE*V`~{+52`o%#VZ8zjeQ zYH1tV{dZ~c3xk=|Ve|SlN8Vdh5~{Ab=I-I-pb4nv*CYZlEMFsiWF?b#RjJ|fvsKMn z?o3~`VB`bC5Xkv!|2-|YW1Cb(%i(N-?c{_by7aU^rn4{T4;@$@V=1Qa=FvTnPR8e3 z{!$|a58YzyHsjRACQ=f2BJZHRa0)`b_CBv}XZW0EAC{;%QB%rajgMh}E*|H!UeV%g zdhuP!F-5?ct_`o0d(0_E9B8RDES7M87i6M!b4N!G72j+%ne1BDKhp35OpIeIm%_Cu zj^v^&u)9>gQsIz5+nj(rwk*uzlhk^G*{AN8Ddiay8b%GcQK+x+2%mVYEu9~R0xM}f z!TF&UbJtK=l?>Am3)4`0^!+Yn@SCaM^RG7lbAQ$RyNz;yonM@9-SS!0nVWAN@p(G) zplGaWEo1wu1H5U!&eF}}Xz}2uS%bM@uIUj~cN}H-thH@^c?oq{vl%QhxBNnIn9R+? zK?qNJR{S@Il7fKpiC+ziu+#(SfNj6raQ67YBx<|Il$@}0Bg~pLIOdpJbht<>4RC)k ziCZ?bTIk_1YRWQlX1sHNT45Hg&BF8P;c?6sQrQu+ep5OGGTc>3V;*5>C=`CJdI|ME zS0y2>nP&K+401EQ_KTVyc;HqM$4$oq=GDgPl0THvj;I0Sq8m!^=B)R(x6n%$?Zdkd zV+Lz^%Mul_12jBsk0$DQ|ERp`B*cY3|#Y;-ulqvNGG;n1@= zPwawxTVaV(nKy;6j%u0-RDaG|?lKF#E8vzpCaw@N%HQlL7YVScrE0NA#2`3bcx!Ef z@8r8GjV%0E=fo@Uky$J|RrvKV<@ELcV1Ll4x{xH=7y@Et5y9Mi2sipa4ErD9G@vG_ z8J>2g(Kj+6uCd5z=n)vQ?S&Q(S8EG)2wCaboBbJ*+XiVp2xGL!P+BzG<|! z?Y}AN_ww=4m9!RE=2#wEnN)Y?iX#)kB^z~G&w~C}&wee^vo^AO5CTh_BY(uj!lfUG zUJWy7q&lsgk#`QK?ME)t19=i6gpMFiy{je#u==&V< zlj)p1D};oAZLWKgUB!oY-^+{-=dzWhZ&Xt6(R2@b#kchLS89fF;q$CD;;Z4=qVft| zzZQTK{F2}Qd;Hbz^PERx(1+E*r<1U}g90xIQHr4YgFq+J&HiD^s!eUGo)B#G;D zS2C$enK1=Y^2e31qxOyh-mzg%{f>Wz0@fb!2TET+|BM}%CsGRj8YW*Xfp|Os7t2Lw z2E|#2NA~0$u&i7%22FDm+2DE4f9j3hW9hj@2A%{1Eh`UC#!fn3QOjt}Wcu@#YE_R5 zih|F;a!TFmmOW#@?l*3YbN7$`22%SDu1lNQ&sti4v`Qi7-o$n2d~%!gqO^Ogxe;jP z#~KP3Hy6N)4h>`XJzjZjUF^qHmu$HEPjtc-7z(nksKuT4Ba>)ZT4C?sUz0|28i_>M zI9*y${$6%lG`EGFb1{!7d#0ENAcaAvo*{?V(_RM&P3BD(lmliM7vYMY19|&(t&cOwNV-e%FO;(P(nQ=wFPD$Nv(o zSi^rg&f5B4quDY!Z}te?*UJvT?bv@g=;%R2pGL(XtECBr{ODa@f!|LLjLV(M5M{j( zd~wl7fn?KsFg!cvZir%+tlv*}%z^TIB)-=lbjrF{!bq)HChp^&; z{SZFvr#&n$@xp{XebUIqK#3|E@j~nmGJ{qC|DAj+M}V61nOmG1xiMym7_ zN1X2y5FEMgcNH-5diC6MyCcfj)5-3Zuk)`@I1WED?VE@@!})XxZg(E;?aJ2+a%0XS zC8L7>;Fms{U({(-)C^lIO7N$y9CuOw^X5~ZD8-y1Mu-TlU#;A5&e&5;*sWy<0um8Vlg7lmG&Xn!>Ga}6BCSp* z{j=*D>OAm8@QS4=B`8D{b5tA4xrcKz=Vm*#yu@rzqvl2(Ud(M5v^6S*-qp)t!f~DD zq2*l-1F)26wUtwqepuu>o#**OHV2hFSU=JC6TO7;X+3p}I8LZ&X8;yV&Bk0|%LRF@ zOPunz10{2`X_boKEKrBKqp#CXfRDP)=(4W~ec~u4Sys}Z?L}LxwW(-NJD|boLs{}e zCn-2it4eo4&Wb%Fm$$#F3z#8wEjrb9i$k2%z`Z_-4Zw8(QZ%gaFOy z;2;+ztX^0$JcNmJfpHy}4DBl5cE3VIrz@%>IN8M|odv-U$kH|466U2BKM#QME+xiwFVszXrh@dc-6L3v`8}gua{JG(!9fG2 zdh$I?4rh!6P;WkG^d1^+!&>cIE*d_+U?vC@gty7i_!2SEXO zXN&RD5r1fIf?$O_5zpvdQ22XOq(OvE-7x1oDG9XrC%h>SXf6hba<;s@OFq9?4yhaR zS^vSR%8E8xWQZws^-x;WSq6>wDy9B^znjH~_CdN^kAMk+RU-+;AV=U*`6|s)d|Ewv z!i-J)7fjKfouW?HFH>h*uSsm}V^ z(hXr?L#*CyY2?_lCi%s3!d`6_kZ%NlGEb=oAC^RFl7W*ot@M>f)H21;+0;|~D>bM! zNd0Q4oHi{g0n)P5jySOJcYa#m6mG{-x+f++XQ1&70c{=yi=0XX zO|JJ2JnP*1@tF0)IlV8dKC6>S?(C6Y?B%q1m@m66U1!;I>29^Z+gj@Ina}^rYcsnf zGi(CSBvwi*Z-9iW%jY2VqcMX#;ye?5<55IZ%IWeGp5vNkDW(7pYqwuwdQU+vtR$jx zlYyu73ytx;#YD_R`D2)M@mW|_p|w6Uc&qfS5G zaa)7cJvVnz*f{?1(x}7iuStioR&GB>dw=l%{TPCCU|4RVXAV{TaWC;hyzL>*Kald((v@s)ADprqzltfsN0 zVSEN1PGAufD0&KeP0W|!DerGCw46RQq}@tE1rn&xC@AC+00zyEyi*X*wKGH4?aAX~uHw&y zbWlfmfIf0n->(k4*ByeWEkIgTRInE~N@eo8R1EudL^%aFjc|tMKXdut#F&b7y#c)6 z?0*%D`+Z$isJZQb^T1JR_$#oDAg7Qoz#)C_UD&5`>XR2jVGZOpHx3`EGOaLFkh`!+ z@t$1&x62}aT8~}ZY;&IGO1R%yc?$g&w2C^>N&g9I3@FVSHA}nUtpi(d0z&6rP-|cZ+>ciRA!*!-0QH|OvDY`PxSI}P1O~VzVHT2 z3kUXoh=1)rw)G#ddy!DVjf*p!Arp6LM|(d|*S9d8PsH*W+UfBpF}oltloiae4oY33 zu*;MM&L6GA)UxmPG*gq~`@*emA^|Q|Qs0ng9ofW7#nvFIhnJDin{Mx7!TZM(qP6$f z;6&MMD=Z~>|69w}R;7>@)@N8J)jbdSgmk_pp-dqArfzkQ!)6iTrh|-#t~+W@+xNI@0K| zla~348*VQbR<08+fcGpOgy`cDdW)1f>vtaYJ6JnSrGjP zXKdo_4q+8cMx;o1?0M2f^@V#~ai>nVsyY!vlSq+Qfh!F%8F8`xq5c?TE#?57-m?FP zc1-3OepfaXSw`Y2@BUNq#mI#J0ZVyMd{>N?&x{vcUy!-x_?f&o^dw|-j~?oj!xlV5 z(A^>XHWj2jds-CfS$KG!eTc5SA{M@1%Anggja{VbnS#rsP4^i%sTYyso6=~Pj5SiBB!aAmiF2rq&SAT3`0XJ}f-rs2XF2nIDi-7Q zqAygDnu)%_2p8csoiOQUZQYsLM+1K)J6&KS|80%9d!X)`dn+qk$L06f@{bfn^UZAa zyP^LdP3Ij?<^TWxcT1F#k&Y3S$c%IBGAh|*Z`mVzmwgIZ9f=$cS!K)K`($$*PT5HNCTQ zHkE|nSwMGkfU|x~a$4DPj0seoZVnj~8qkIfz^&Knq`!%#?S{ASs|0u%-qp%#Q=r{R zOza1RUz-!n?>(rNH(igs;d)m@_xr4~zHjVvr?#Y7$C36E|j`TYvD1WOL(j)<-Mie_G|KWT9x)C;}GypyDh; z4H(s#q(M4fh;@DvxTKNK#b-!6q=L}59Q-y+)f1Q;N_oZ$npCxW3g*p7O+@viScg!5 z6-SVc%nJ?7D+`F%+FSFOd?JX^SBzeL+^c*Y8si;%gZ0oogB&&WwkqEV_^ z7;7_ythCO>hIfPT5hd~>0_~-;Zo$q_b?$i|0xrIO%%ztjC$V+BNITfgzEB#UWh}CZ?pnLdmIjE&? zOcx&tM?7TJx$PI$+iPvCuz`B?f$3w2vAUMb_fc*8mZMbFwd^&5B(J3hd2xl*=%TY+ z7AdsAFHSF?^@GHiVy6?MWC}A3tkDTuS}`jDOA2TI^in4twhN}a%2^l5EqP@Deh6yn zEXFVd`jPl#3t2QaD8Ky%I6r+Rk-8UmUZ{GVyxqSj-@blm$vw^Ww&BgKn+e(QI&V+r z1ji2(D345h_DAnKtX=Vs8m%hlSFWf?iZMNGFRGVrA&TW)y{y4HeIvRmZv+~=YN=0i zEc8W_yadTkLs^`jZSM zxaslTtG&K!V()D>Nw7K7(2^Ko`2ec}8b$fEwTBNjC`7#JXbRZLK;=68eF`}B-kZ1Q zv-njtNw>B!Ht6UeMpA8iXnBoaAXVA1@J;H_c2&=@7HqCSNre;Ce+T*l_F+v=fB^?b z65J23ti=$6D3c?K!PtJQ0w0&~lJuN9HIdfUUmQ~HKDD`RG^@AD!tXnR9%+s9cmDuI zBc0h8GT=5gEb%aYYA9So3}t!PSHonm2{foAHS%|f@A&Igu@*j1WBus%2BtFLBlCBL zLSc-Lb>m{zTvLL)tp>Lk##ni8f{=S88J&ZJ)ctpmE&vO6hzP>~69`k5rG7w40zy~( z&r0I@L#SsQLG=JP=8y?ZMLOMnNMl9?^vOkn=dh-{n zRUOygFjxBTQ^BH=Q7{osVgb+jQJQgapJ3D3RGpl@mqSt&RltCpry( zV%NH795G#JJ6dR^I-!n~K{?B=xUkyUNdC<5{iK!rnG`A$h%pw4CZ4_FVh($;RMTF@ zGlYA{K0KN9>vGPAqfw8FAA1+p7EnTdzkjoIHMu`gyc{Eb)#g;B{nxcjM;o4a`X^$e z?{5?wL;XWtHm2IO$}JKex4YLYVso`-S&ef>97av;50*lv*k1i#qjh{bj?WCO_qhH;B{P$$>fD^cM?{fmZ+BNNANBwJOACN?yaJ*>slfO&M7b5rvf2`h# znd14tGbAAY@;yt3^=X*;Ods6S^-)E-p(CeB1}_`g0}dG%uhk&3Fod)_tIHjRx$s(E z1FD3l4UmOGIWsqW3FJj7Rbc%~-`iTqq-Q5=EX7l~@TI#V(}i<0vLHNYG-mZzSWvM4 z4UK&fp-9hiiA}P6h2aXaNFcpXuH6k^o?TQ~0;}PF;7TH3$fWcnMmSQya>Qe-Dt(EY zVRwi!NcKefA;W?*;P$n?yR8P-Jz1|dnpG~`4vj$di_E*$zUFB3{xUJ^cl!2R-Nz-o zEsx13tCnm0Gf(Jl-So00qvQ#Gvt8pYa3)wKZX-PRk3dC&s1i+L#r;u4nSc8$JzpOc z=D^LB;EKYwp6yzGll#$(f<~{%9$!VuCX;+*oKDfGo*(y_=j<=#J*-4-oqjHmPrWDk zYRiRPHm~Q-ipIH0&hveodQ4xxMGN)j*A+*_AHCAkkE8!`65b~6OrJIYw{NCkJgY5b z(FBce1KUyI>D`IZVlU)|;m^a7e+aEgPKeYIt@>P8-i9~nYuGFLzJn9F;XlE1E^K{7;6D8)uhp?lU) zKiVusxA=KW-@msTBbzO&l&LzSu>%_H__c@jyE%>y)slf#RRI}APgq*(15SbIu2-KC z=6t+2v$;v(w@$gOZjF^|Rh6Aw!)wMdPKHobeU~@_KbqZ@vSThq2+22wsNNqk?L}J*u&VqztiB>9VrrWuy?oiUE?Z-BMDrGU< z-?*?#jqXcdOep`w?3N9JAYPz$B~Z52t2Imd6Pdg_xbyohJAy{sz}=~|SDR@>M^Uvf zQyM0m=D7ubb@g)TU0S0$tH@^_8&Vv))la$j$9_!H^ht;nM&U@_pK~DxSLf$|g22g7 zjKjTH$%R^Z5#4AmvH+(My3*13L@78nlVWp(T9y!5Eq$u`-^rKZpwY*<> zj^Uarpo(Gxf@rn;=QD4$$&ve;0=NYBtexhVpucSPw=qz00F8|jSY=Q>zy5k@z&}3b z^#ZxshrAdcE&h4BUy_+%pkDT5>;tS64MKKO*`~ex)ebT`` z2<7q!%_Z8{$Y;LT^;Y@zIp*H`cbBMaY_=vRTv^;Ke5UM3dj-LyC+ZieuIaj+Czn?J z95f~%^>%^Jw{_~Lbgtb0Q|%TnVhODZ4Gy2^%5RZ05EP^SXz{X-*gsOe-Z&)%bf1Jl z)jtCPX@XLpgN+M0G;+64Jh*To^o78% z29dSl9dAXX^1f5M&d`x(z|!Q>a<);MB{(Njo}T^cIk#YHYeYol)+raKFP-eXYY%!UO)BZbP@W(gKa$$giM} zS^%BaF6~viH`?)FZCM&j3zuMy zN=)E@mT*+i`#qO&aYW3!Fd^b>=>Fs^!y&O!M`w4)78{NX@nt9)dmvz#j~@nkrciLhEFUDS{|dmP%uZd1D`vj_AVo<1@J zSBU2CGj?0~IC3z=D6-HMa7QkTqJFvLnNm3AU!CF=gK%5+9@MBtpnyY zaiOFh+Zt>c1j_?_@dFAMduJIQs(-JSaAD_5gTF@Q zVv9(i4rpgsk|XrKvTv1TPPT#fn$O&6z(M%jsG!KW2GV_6UZq59?8P1);eAZroB@C2( zn6t+0hF%N?f#XFgt|M&srruxZ%inVWdmaLZXA-iLJ%cHvwqAcDcADFf!y9UDzgyT5mt z1JkB@9c^h@(FxR*@Kzs>mN5&(8l%gFP z`cOOlfjqZS^tDYNsaT`Ax9jKgX(+^{vj@q~Zpo~;L&RvJUgY*e*0W3HQt^N@N}cIe zP6?YiWEaj1+t zVwc&F2f2n1SGb@yk|S=}2bbUq=){*fDf!ZY>|w-JUfADhGf zAddVXM@+Ia!v8Jcb{e%n?INXJ+yy) zmFvnYbi6GEv7m2~&GlN@B&aZdSqQODp}oDWiGRSE`wr}$v{D0Bw)DQrw-s{jc_cm& z&AO^lv%hc|Td?0kKV|W2tj#wZ=jfMkkJ%7NZQb1;E)Aw=#F#f656zeryN@Hx?F;_w zJ+kM8my=f-eW9=Bs7`sH!){^AWz?-Kwp97yHIdwTY9FEUv8Dz|GIW*!tB$#q#W1lWKg2D5VQaF|-pT)E5Y!5M*iz1J9cl1T(rNM~ z@=KVk9nIvh=mMU3CdLg`KQ!7rcCJexyFJN0m*qnMZtK_8nw1MK?qa-(wVe?@&zuEa zh)KPGEWt9p;E!`2tI0hdmE=(J7jOwXP7z$t#58zvW*VM9V2%krw^;^Sa4m*R=VBp|C`PQ0%T=1ll)|sChs5 zXmD%wH-*VX_XjWL8B=YR;A&t;YJ(ugiWE}W8zm&LD-7;6a-wnWaB&$0?vyfaLE7pM zQV7{xucCO-(q8^Gg>hJWhS~&(tVDsu5blBr{W!PS%$s)PEt|vk_oNW@LS{mK==Tk# zJe3`s;^$+1>X{l#pVC*XhBE_r*bg*yso-qE7T3W=*c}2czT|N1ahhhl?8nulLe4Mv zr$OI^`qxj>x3IEv{bcqO7fml=((i;eOGlTH#axxpp=eNyU@{IT@Ywq?_ z6?5gHYoN#&u}l!w z5(LfzD6y*?Wdng9cB;p-@AH`s2kVt88m3reTiZoUlu0K6@$h>{m-`e0a1^dnhm}KC z>CEfMvo_(1}GAk;ic{EPPI(rb|79R}tAb7%puX1JIrCnLA%sA=VRUtRvy}K$ z2haL!|HN#V`8y_$)!nyo4Q8z&HYMfK3O#uy#X&r?Dh@S)qRUB44>--26|;4ws80j* z8j)YopQ_rb#piaVmV^GDaimU*nQJHgk;Yy2OU*k{e=_GWJe{xVxE52ox5Mz78o;)!k%ET7+k+C10XLORQU8X3oS;Lyy;Bh%~g!IQLH*5q)HexyT{dxrs_lv4Lv|mnrHN zX59*Em&veBA$%aG3z5p!1jeqwsz0Sp78PIoVi)~B$jWpnW6oJrNkXP%1u4J>!rd}bwW!zaSJ{H&3@81_#DOUfecgewa5hsyMDzIbgsGJLe(-f-D;WW}Q|W6v|fl1Tj*ct>!Jmt~(4I%Ris!1C|(lfS1u98Rt*>t?Ssj@aVVl z@6*Dex z+OZFM@jOb*l5mvsD>aW z{h2;g#gP}LxHU1FWy2Z2%3SD!9E96RXv1NFS^4e`C^g;0tQR(%t@Mb!aH!Syi;={M z7|pYA_`f91b1m3+b6_V)DBZh#PhPO|EchA=^m$wncvd6nzvATUTMQ)o1SWO;=m~yO zF%vzTZNL;@zid{~i*5bNV-R)Q ziy|Ckw^=<@kNA6xOtX7~ob7&N*>oc3b?6QW;_oHpxm^40N)Ay@i8`M*9DZ!xQYjtS z;5H-v_h|Ij3+tA@yZ^aXtG;Q={JfgWE0sb#Ji6O%<6_QbyM{!~;`BN07$_9neta%#v@ba&ynNK&ljj{BZL?yq0toZu>C?s?4U_>hK2q{YR`4VwA!i6|Y?yJm>hYO3pCLy{rMT|{2 zI%Vs^tVic6`?rT0D6v;ClYY`dJl9~}q^+6TiAA}f52z|M&8jfJo4Nhd85E(WJ$T4K z2-iqqYAj0OB*we8X)pSH?l&}we2;ewSlgYL-hwZrafN=-kG z0}f+L3aUp7L9RTn^E^Te@CHMEKgf?w?Q%ShdgmCkmdq#V!Y!%${oEv{TNW>emrh@} z{mvmDL1AD`dlm*r(~8+WsS&JNB=&k>ORn>6llZSiT!c2IHPE^}`_NQj{g#QqviF#5 zK`b5vJgd#M{D0-4?3-)rcZ^ZZti2XO7j}7B%nj+J3*5W+c+NtM`^>MX#-UsPmi!pf zS%^uo*6%1lEd2?7ntoG`w=UGkg^&LOUjj{h^|?034mr7|qE(+i>BfFxAF!))RQd18 zC27P%N{a5w)>+)h=EAyiQup2W2N?J|o-sS(IGECqqG5`ZfNy$2){twXt?<4x*AFOsvk`{Px3)-pTX@#>0PXAN)i(f z1Dm}hN~J{6l*I-_vmu*eqaIZCmhvfKh)L-h+&`JA|C?}V1%;kGC&hJM4G7?Ys)jssEU%g*K#L=AfVBlZGrzI46``TtFnM>6Wgkakfzp$Tp(*ss_a( z?+{Ql_`NEcF}d`#_6MkYzc>|4ql$PdE%P?xA`DDZ_!)iiss@WD@*$)Es0ex1d)u_B zVUuno$w*&SO}A~=Ds2S(Ih2bdLO?MfKl3Rc2vTxi1%RcZahS*APa+>%ThhiL6hFXZ z3x!h_RbN7X94Ws(F45C(SLOwj1{y#P2PuOCL?|@UuCj;rGr~y{kYb9tCmOOj=_T{> zf{rhLtBX3QeY*Wv(y)Ep9?oJX>r}dZ&hLBZ;oH@0NY&R!sGN$gHq4LTiyUr>b|@N2 z#R@^vRu~RQ04~+`hv3y2^(B6TI!~;Mjo#y#5f^@Vx*wLW{buiZmR&{t`q-8Q;>F#3 zx@K;}<7KiS!J1=?+Puk~V)uhJq+&_O-XQ=@g5bY*PykMYN-0NZ8)y~JL9$}KyqTF@ zA0|rb_Lr61UNTZ~%J8~3Rx6$*Kd|!Ef(QS#1G<4`YbpYgI+E{nv#3r8p%riI^dd|Z zE%2(Q9=x?rnkKCuGz}{A+NfcUm|fpCCI-+?(W;au{xWU&7+;$&_W>==pQv?TMk1p7 zoY$)hMfnnEY3XJ`FQ-RX@G1`-e)fprgO2HJvGo!Vc3nE-#|i{UbMREm%&XKXT*V=zQ3H@&_`1zcun^s-h!`R}sR~Mh?cqFl@ zoL8N#QTfj=7#+E;~ka%_Zs z0Y{0o=x(3_F;80JwL>qBy@IWblo!h&J-0h0ZX*wzp1hwAR}TnybusTsg@4!uX5p&2 zJl}$3b>(#ZG#b8}j^>?YCG*T2mO>6eXI*gg@~X;FWnJYOapf&=f@T<9Y`RI+?x4P+ z*VHN>0Z@{%otQ?^VkB1~YlluIcj2rkW(r{}sU>Fm;M=F~$ETg3YdGrZie2;QKeN6jxu-)t)w%30`fB?(-TQ2P z2}`A#i~WdU#Cnc^lR`^Xl@1qkYDmU?$5{RFO@by-Ou)N2iq;27bxTBD=a?~Y-|Fw|_xG>I5#%_9vLaONC|u4m?ZM$XXCKWr9O7g0 z1#%XXeM70V`ff#T_|i4c{zMM~TqTWG%kpLDv-a74Dv9NDXe zEzP{T3DPwrzTXN<0JBb#(nUIlEGlxQ;%uR6@LQk`O9TD=wO_gdDpC$NmlFyC$_pKm zvnvUd0&>#&#t8K~IR=8#K;M;X1HAfSC>EtjP`Ga)$lCgjlGa?m&l<~8(K7|37k5Z7 z=r`YFXcs|OJqj3LANExjKTn=i&Pav{#>ptba8MV8Ys~N*@!6G>s?cezNW8=DlmJZ8 zfG_p*)=ruw9g0*xj?`SM54)exc6UM1nQON1vMtoOT9gU?4i)%=C*~sWMquc~L!Bk- z>uwo04bIM#ALo37V#&4Rih)o9`Ke9(U3=K-T^W1&gN>l8f(Zsu>C;@z`b;0MG8BD& zoQc`>m486-|Vd+j&O`&bnG`HhYds z$05ZP)qOI8agpEy;jI5jX)~8`mpgQTi7LGkkEv9+BVT6zjqiF935%j=uV-X8oYJPX zKG~-)WAdR-_{2Kz5K-JQ!ZFoIckzI5_aC`9+LXF4*IF0~{HhAbBw`1FnY^vRx5o+B_q!%xi44r z;O`dgm?duw=8SfV{M$;cF7lkt&%`(rf-c`3$^NDX3p(Xx z=;O5Vu1mk#k&9+7q>>q+wiNPL=l!|TrD~@5L<>tgUaaP-F*ozOMl5#2+Foa=QJP{C zC`=Ul<`r5JM(N)F)4}y-cW!KvyuQaGMY$?7KZP)}RPRPgV=+h4jXBNKfz^I)k48^G zHnFGet#vhIfkQ6-taYoVUfo~^S@N5N~qq20q*J|?o83jP@*ei->_DFDfCkJ0#C zM(g$kSw_#%iqTm(6H`DxSZ24EsaUo>5aYi7Rp5e0d=lT9NhUEd#mSzPF=ADc@0S=9 z&H7zP(Ni^G%Q~1Uzf}bM*b1Gm%qxO!QEYS>uDO?Pe>a&5ZwB|p2;Al;o$NYHLxZT% z2l88$K#%ct*dW{{fD{uN_&rNCw>CdBC*j*W@Z@Mtvk$Tm%8+8Za>L4VX{NZa`WUrl zG4twY;!}|ZMeg>Of*|c@psvmbCK3F^M+R3C#Mtd$A(n>yUE8Q-QFcc_+ZR>GUe)RS z<2f&g>Oi#l01V`&5)$pDOvA_w3CRI#s<4LWQ;V`6P11&ZA7^}p-U z*8(=JKKqZ2`CytyePaC*i6wII^)%S>^}-YJ#f5e`=9nOZU7W{B;dShevdcz;Cxm+jZ3A!ASN-+_BKz^Pk-;+k4e%X zC3@KHPnF=R{ZCimw3&dBEdDE&WJrn#jT4C8lB~#29vzrZ2HCUri9&im2`IDKv#zOM zj{%)d_=)vtz+|}Lg6xB5Bv!aux{KsQb^+yhk>s}-;{*M`_&D%>V$TiyNknZwh(0AE zn(PyVB#ZyWRFezvQnOrnxp_SxO|mSPn@=H^H?r1_K63~ky52qByB8ziZWbpnG4PLo zgLW7W($wH(OVa^*$Tm(Rlti2CIo07)}F8#+eHE~)&Om- z*m^LVhd$XwL##vr5Q}IDqJWtIAc^g!NEk-HSNo4wg$+`FaD)#6o9LS@7WL3}(-r?u zMb;UrjOSG`y_S~%>1<*`ADj))Mjo*P03ixR}}{FSqTja(Jw|qK#TF z3iV<9tFJrf*ko!YSXZ~?^@mWz_MWv}@=MnLZtT_Q$~v{~P>v9Lf8$ir z>Ajf+Zp%+J9YjH)@p>sK4}zX{rSLoQx#=ex!7$y#f<$6Q*X|v^Jm0Y7^-jYMPl`rg z<;ht+8kW!5*>1q=7g@pG&6V%jF0vC7t&x8~Qiq9!QmhI`6F@F<`cFI;YtF}IbH}2d zt)8Md)Wbk0KR+H)zGKr6Z&N9pU2m5kRa8LN0sx9nC5&s$*)yaM@=9O&~`H?%@Xg5cRho;+D5!%q{kGw z4vi5z-4KH5`T{kdtXppsrc_fl&i)GhhrMMVQ< z+o#58FHe}sjmgnV?Z$f^ky+O`7O5%v<$dDgE6uv6@*kKIAiwVy%)1FLosjdKuLb{2 z8Pye)piwN00h7Da)JWabr&tLW>AN9fy+=h`>vlW)oZYbK0Ck7^xKJb*q1`MsG$yh!o+`B%uI5#-&nB^@Ar< zF0auvh#F?6q}bT-zYkKp$EQ&u1yzJHL4H!8ho z(H$HoRxYfOZ^b(SSO5#u9KgP68)0f1RcP}s#*^wARqT$x<6tpcYhAVg4ln_XHJO01 z=1C>BP9Ou61#5Di2r0FRTZY43Y^zJfCuHn*j>eeoT#}D#d;IzO+n+xKSC%gLRZxRO z2qbp*M%!&CkwQhumTNQD^{Ih4^1Yz*ypERFZ$-wOTl_nG(ENa}5UC*FEZSP+jp&>K zU8_FZDT~KFam_n2A1*Mz=S} z`9LSOD7%XVGftP*ACtL*OA}}88upvuwtid0iZqYOm)V>(Q@cFBNlXJ=4BuT9!kW}q zN)om_|0fTfsnvauk{V#_^g$bk%nvRkeN4rIQoN=Ub)#Pl;R%aSDD;Jti0r+$vcW*I zX})ViW8h5b-xcyl5Nj}VL5EG$##)*3i4{{#SfQ;USNfeqNsfrisMt!*YbTF-9#;)>*I1MMK)5_-j#4pXn;Peo{i%YJ)twb;Q3U z6ZuwfIT-Gm;d?#7Kpt5MUT#YE0ALRcU?ugI^LM{V`+Y!Qs*DthKmq{sDvIutm{Cp}>n6?EsN%4@jzz73T+k#WQKVj~% zqVg2KYW`7-hr;l3L^mPsXu!KAvrFjiYC}GKWZ2Ae1xW8-=L9C&DXdMXMmFwO^AKc7 zeNA?(FhxO`m057;&b1__Ix6+%4b3F0Zz~^mD>qKF#Crn&{D)!z$XfP3 zL_UAbc8;b7n`X#Ep{qr3EndfUO~FnLQrtl}J=}(^QqL~dXALBH?k?;b3M9mT0Z{%J z(RQdn3xWCbOC9ie=I+1${EWICKbku?=uuNY4h~Sy-UFk+-Y4p*r_z}^w6JP{LeLJk z_W|8NPfZ5fjoooplFEVhzcHvtJ#kvsaxB<~{7Bl1!PToC!mDK;jGiq@7w z%)+YAuKXj`_ylHLcd6z4omKLHe|k0tkjxVtbAtDa1O$7M55GTjI^}=foYN!lSy)hW z1@~ZWP`pT01Ku;Al*6#0Xt4Rp=d&ut-h3`$_ZDKBQ!r+8`9`xVo?~+q2=Je zC+ChB`M#pdLMpXnK0s0kX(h+kmZ%#WzvOpcYlD}qzo;LXYZXbzK`(0+5k~TZM@S~{ z^w5q!sA1GusFZAWPKaH^R9{bJ9NYE86MZCdj(fh_1*d?^p7**Q^W(Soot8dry6gJ^ z;5qDpANi=~EN2cg)R+TE0La}Wl2})^C^&O`;(a#~(MNas{-E}9Qz%)V0`QXrA>GgA z@_FbO>-lGDeF1iyyp!q@l&GrXk)ulJZ(Vs+R<*6>x*r1K(zQuiPV8m}q>82far6sz z2%uOC*F>kV@GXwa@8Lw>D|tCS`U=iZ5O@!(E~5=8CpqJO1yX(ujib=WyW;dyVF=7v zP@rr`;hpuIPBjh0FTp%v%7379zpG@aR$^U0$;#>Jtk>H=k1pa=Y4LLE8g<9-R3yOrW(y`WW}?$cu@boa>>Rjm?yFGufjkpbxO!*@@m^zYoo zSG}W)Mh~;{!BLhHkb)D+g>{CdY?zjq0<^PjrWShM9#p>Mu-$dsyP1RKSrrjV=|eY- z;);kRd6YA}bgB-H86I~{O9;dexv%D|?}D!Kw~Ey$MQugy3xPV#u_it6C{m>(D`8P_ zgnN(jVhA1BO|*3l?LIOwE~V*1w1?8((u7y&6V2|Xmiki?C)rO{k*A8Qw(?xFSkqqf zK$^oQFgDLk&0nwNVPb{IoiR8j(oyK& za&&SqzdB`c7Up`Gw3~=!NPpMuT`({HB@yE#X^n4lyKODOuw{{8joToI4{$QzAY;9v z6?sLif6U^ux5f>)S<07QTqbxl`cd&!Z;HkQf;NHhDR^%go5^j5#s{ZwU4F7??>Igm z{;a(Xe(cj|*<$U5n|EsG>l2fR4|C2LX-=FgZ?&#iATMOiov(Ed!7|KyY>AE>cd1=@ zb#e6y*x{6(`T}Sn4XUu&&B$sz)VXQT{zZ#IZWDd6<;4rLav?v1k4WO3AF;52>{E}< z8R_nm&4wxZ@pWBWdZkGBLw50=V7N^?!MYY&qy_HqnoLm}rCdt4dj&ht=zv(FH!^W$eTj=n4 z*4YK>GQ$l&=1x75bll!Q0{q>M@d>lHfW1g$0i*bY%$`+Jk%n`Hng)4JsPDSxo93qP z&agqCQ_Y$v*qgt_lZS#RjQS)AxrnUsUh=Us6o_}UM2@{y?(Q$Yb@k0Xv|2cKrrsr@ z&0+9EUc@ow@6tv{aS7Ew+}Nhf?Ely>FaOZze4vjp4O>_|uIKNE+r9b<9PI}(01m8B z;p1p3gH+C&>MdUw&9Z!fKTKl zWJlHhuUK-^rIkoGkJ`*iftizUkxPjwigu4KS^u2AGrNo9MKQp=m1r!bf?c-7sw%CN_v}YkJP)v-wl8!uAYgWj?Fj2{#NUF$jKTNhi#-D+QE-~N_*6E}; zZg_4jSG~DmwNJ3Q|CsY;AEQZ)_v^__MMI6@BXNfd=$%!OxhaXY%W2! z%fR+1yqkhV6z*M7$ik^Z*~L|o%p9ert^*)RYYuqZ8q0(`!_R5NmPw2rT!ub4`b2o+ zOFjrS{Qbwgcy8(R;F^1NS$?S-vW<)<#dsfrCRAp>0{@6m)o$qJDC=%)rI4a&v2>>B z&oIZP#Fi}r0o#V5C0Bcd(Ql!%4-RF^wjDM?1~~JzUW)$FO<&fN3Fv4dA8lXnSMsi_ za1i7@cXu+!*lJJ*fd0^WyiC-rxFrDMlDR-XmxiKo3!%zK3%1*9Fsb z$R#xt=Fe9X?y%c?exm?VG!#J} zY(SzL`_%;n8dx^(L(yrXJv50dwbKObJXHhM^bhK_MP9Xiu=?$+d9HPhP_D%{V$%|k z5zM|6L3};5^gRyj>7uBJT~gA~7mECCyrdd^?#Q9nrzqOzAal)2QemMbOg{7D?zw6E zn0A1&s1&qtqM6bakeceZp3J@Xo^zJ>px=e zyCC+gJXbL?fU~7}D(ZwriVDYjvb>4(T$*ngIQNQp_On{0mp*!-GmYDlxOIaSE zY6|Q=5_Ycw9^68|#?JI@GBl2?yI+0YWWY#^U>Me_+x>VEj^T331@3mcjB8~(r+@1b zl3;x(G3`N?aK#u!&ca#!pP5qbhqZZEYqW)a6LcvYS>Yb|D;sXN2CoDfJMVQkQUOzyr=IJdoA$bu;(;yw58 z4T0$Ka(vNl%zDh;jdM0%zCb?-iB>!nD6Ge9e@(SNi&k$Jr3o%k*dvG#VhGesE$QN% z)TKtT39dIGfI#HWL#&^vyIdS^ycNHoovpJ;fN}oro zvU5K`a4Gg53>~4uEP=qnX?53F=nanOz;QXIHSY&APr+qprWu5tnJgoN$4|uP>ppvX zj!n?0Zl@+u!#Z9S^UzKMbe%&~oV!VYqMc26D&hgq1aa_G-@44rDnt2_f$Y~PZ6U)B z+vK$#aC=s-0NuNz-Tq{zG9N1AETg0AM3$oNTI7qUsfogfKCfq$&nrYNYS4?oAkOpotYFhOt+9~nq19$aET>r{300K6<|kuK{>RyTwD3>vEOm z3caQy@;(;@SG;_rj5J$J_FsQE5YdpRNcm!z+WrJ`CVUBhJJG3eO@}8rAAr`QF068 zxfWH$T^u)m7l&~u$jKKzi1}tI%bI@oo=_AxSOa?_b%2L=?Thk^sWB@}pGS$jrUno} z^s(80D%1iS((v_7+ieiM3YPM;#OI-3Bf7ukqcGf=n){($+}WaUMY7853+qhI2N&4L zxR1Oj>5MNc(2R$CfavIV`8eg4$bZ7qS6Eh;5n4&LRoT7vvZxzMYiWwGk4dI?tT!2o zZE64>uDx4l_v2-N#>z5De*WHb3!hgrpuhOdK~SLk?YU^&wR9VtI$$f*tQ-%x3Y@!A zPrJ!>0yRbnOlkl?hW09^kCbPDbZu5xe+Ssak{ZbN4u7Zqp8^`*iBF8Ill=v!K=LMu zdQy7U@}5bn1u7;uLR0O^{L}L7D3gdo}AQ#s4j$q2GZA}Q7trux*Oq3j2tgqRqfa2=5UOoehzDMpQ=-DIu^rL z>7^{pIaKqJc=qvK0)DqMEF@TenvVUmEu|Hm5%}c@;xz8VxA18}!bxs}h%4c;%D8so z*UlAueigqI(Q9*bDFT6I(CL&pCM}GF$>%t@-|v?g*=WwL$SjvC;&qDZi+@EVaW5{l zCfXD;&S-o2DTGz7p02lmsstXme0S$pF(@aAr0Mz+*zxFSvuy~7j~E4IZw_QFP+IdIoi+3 zX%hNhuCm)lejOb;Wy|DVdo9M%^N0`KT@q`fYA|Y#LFc;uW;3=hK^R!Ytyz#;XEL<(xq@yr#pH{2sMD zE$|44L#!uN=nXHU2T)f7f^sup`u8nP<;pUNdtQ;3&(9&yaoybJZJxd$IC8avajdv! z#RWPI;_-Q#e07dPu(fbB*G4Vr=_59K1ME`?WLgrRV838l$v23u?F|job0Q^@5nm5{ z1!0Q@^f--ly8%$`bI6b5tK$d=PDIhg1=nT0x=~Mr@8vhQ87pe zPyqsSyb@i3>m<>Wj(kqh>Q1pU+bfUhjxO3p4LYl*$Dl;{as3S30{pQY!0H-tq}q{L z?P3t%jb`VC=U;3M4n_6WLpo*fRsYa08vy9zUG~53h_P-sJ(yAR4MU5CGs8yuP zidZqLTEtdrwnmXwjUp%#VkK3pc8waXJ%SjqYL{A3RaH_nBJt$+Jm>i<=j4x^lblc9 z@B6;)>waAXpigQQL`mL^agxwqLOwdQr?BE@dbrjq8$|OM96)OZ2Qd0><&BbHySzbA z&WgL0lwIp2L!sjP=b4vS+t~A7?&Uq;Yv7CLmt0JjbG#0&c1TYnVBJ7aL&ivzVhP0r z;|)+b;)8y&mlBE+6?*w8VqYl{!t;b8q_psKq<8-UYZ*9B4|S7a*L)BcQ+zA&M&ien z)@DUBj^BHs(4&V!^>!ZEK~R@t;ueb6Oqtu;UF#Er1N!@LoJw^l>s=@IUD1mejB5e(0oL=`2X0N2HRIe#2*4Ttcg%oz&uU~Br=hZF0iPeta{0%V=QHM_=ZNNC+D$iaYw&(Qv3YBsfbMN2LlhJ-s8`r z8SpBj)0(FKDLRkj)$q{o(jNFr`%FaDsM#T%nWyPy$mqN>5>=@E!X3tbjogZ@WU(NJ zqxfSSaG_mWC;Xq>v;%(Wxjb-nXIy!wXn6Z}mn%cM! zwg%`Vw7@RvkW`5+nxbl!pOrnUaV=2|hkG4M-@beq!K?6%$2-{(OKm<>IOk& zP}k>N#;>Rsn`)hnu{uWNLC>)Yl&t-=ifSrA(m z{rU?G*>*G;?B#`pKK{=*!v91IOI#Yawp2D^NJ>zLtt2vXx?K#X++BiFJUMn?jjJ3> z=VIq|Qec=E=!}5b>ElU^`2?A!k=66vAh*6;12aGv z8{_}I=_Vq)-dfiZYpNl zhP25q{!s}Q`Nr3a_C7KHwLy;0<*UBFHuCZX*Py!T1r%1txc+zJ%j8_-E#bvAhJovU!03MNq~cNZjXZ^$jL*BY zc`Sfm#VuU$6+QK@e+FLs=61+(86cSCI?8cwQ>YTR5xy10xM&Z5k4D=2{cj{tBBaz4 zw|!I_`2H!PKvoe+2Ik|s`PzIV@n{LHhoz%KxhH-7Dq7vK@2q@e)l}tJ zrtAqw=x*#Nrfy)Lxjp50rJ&Zxw6gL(Z#P+~-ARLgg&L}DHMLLtcq*M1`ERmxpRi@4 z+c0GpwsB;PbFA(!JLD|zVf?NU^mLAz7mOSiUJY|tf`QKlJ)aR#a_+;^2!LLUQi^d) zWI(3H#xdXQW46tgpu=FT&$O*8m-lWqa$6FRvrcHT;?)rL2ZqlM7?kU;I;RZan=Lj) zG)lA^eZN&C_V^y&-k35@vwaK(9*c7)GH`O+)0hdPHWdI{bcq8K9ksS+km( z+NWi2-FLamf!1DDSz|@tBaRf^-MC^a`%OzBEIiPS^w1~^{)0;Ym24iSOKT}QVpMNl z9YKy97mg?&MS=b9r0LlvbY=RY*Y^sFUP zxko059rdbWgW#-d@;Z>6=wWVzpA4lr&{w~=;^W=UyA=j5!Qj6nC9?~_2~bdjh+t*f zMr4@zQ@i8(zuIk#H80yDnnxLUjdI&dd+e~Z3h7j*9rdNCt3@WzZ%En_D!SsYo{sUalac6y3yQ$JH*EVFyMthqhB$Yk!y zdlM1+l9TJUSoOQQ4=)8B?5;;MUxCu!%Ut2Ut;Q|JDg%0dW(E*@-iT*xfQyftUB(;r zQr<$Gkp6P<#pdYn1CJ=;!>@kU2MgBUtiNpz=c!DRwU0ELOrPafS6Bb6E^Z#vMj&K{=@vUj=r(VRe)3i8wSfWYyozYF3u7K3|V>)JoeXKXC)t!sgIX zS|Q9?eM)m^qPMmaZcl%KDwh8}<~PcGw~z?m@c0MTwh$=JGy*^qUJ z5^lfoILM8$z{$Sp#)wnL*BFlLdub!Qt~?aEHIb-UVfCg3Zlkh+xhP9O!}s>*EsZia zu?CG15q6WJy1{xm+6A6me8TVG+Vv4PXS(83LcK^89nXb{HxzmO)AmO!I>s>H!!S?v z;H&YsEx^NHr<`q?*jMO@Bg-YvUH2|*@^`Xtxh+xQJ(uj zd2sHfZ|Tf!;j!eKv0H0S=^rQ-*l5 z_Mh|~(m9-;%WSaF+Ao4h{ZkMnV~cR7SkHa7kEQu!0eevu5&(=v!tKS}m3lt9_g+bw z*TnM_o`?@;oO#rt+Fo>x5DIptUMLsT#K4;e4Ywz?p`aEcqXQ0?97(j3^TwxO)8V)v zrKR-kt+zDJ1v-qy^7$A!L^-|eQXLD&?QMgFfBj0&-P;Fa2tD$bTcYSE5~VlG5!1)- zmUqqw_Ps4mB1m%2Tv2$t3UQtJ_hzZ1=-t-j@pXU1ZIy2E66?!S0KpzlZTClDVk!N4 z=o4m3V_s*4nczMV~4XUmk>}rIqHTdN`E%*fRovYPh`fP|$VICd{UaZzDZ*b8QU$sM#wH z`=RJ+P%(9W5~*$7viY;Q_)8M(W)i-(biN9v$p?Bdq0M0|X{{^CD`;t(!?pJy!&1q* zf+_5MYCVk5KN_b^An+ru@BQu-ho_i{Z{Oki}jS>8D99eRCri&L@}VS?EthB|H+?YI>YyIy4cAE@3AR8c5Hc zcae7jUrSaX)#F@*QpMJ8?S@KiBtO&EBS1tY&E~`BJRcg$}Q z?ZupjHA^@~vDa>Zu2-Sz+t1&VO6hVG%zeXj_W79@{nZyj4@a`B??Kh7@-mQWSkt-% zjUk0>o8R~4J0t8P!y+SUTr^XRcfc-Vr|1yt20P^%5A&U^zdk{|l{1Mg>+1@Uty(;~ zbK}Y_J4$K#egnxt^>-COAD#md9vVl+nulfd4Y)c5A?l&E2RL#IxBg^?;N+`_lNKw! z@Mnv&&Eq;2ywfK#Jlf=JS;}PgX#uH;cWKDl(y*-XN&Px4@}Qaq&LlPICGryg zr1LE0DW5Y%#lw~6Kc?KX!5eX(F$C)*fFamYA}eYb|1u-zZ@~=`rk%NR0eNmDIH?&3Giy+ z6uYjFENefeH&c2feO*XF;Zc#WYXt2C!K&x@Jv{gt^hRpHHvGSGLj{N?r&{#|g7*E5 zH%UyS<0VX1F74gIc8@~`TfV8SY|0}fq?m>6%hM&Sk(%8sRc(-&O%CVuI=0azSbNkg zu~m9cD-o5oau#$}uRW{*{(7S|YJ_>{2&#nJ4XeIa+jZ=G1Ri7_qC~0W-Pj-I9zI^c zIOd%pL5w|mPH6w3ooIyfo_d%U5n0T&5s_{3yr2G)?cJBDm0|t_f2jxR;}xQ+wV7L)vJ8DZ>emz-|+fkR$ViT@VY|d zCR0$QRZ5k%8-u0lt#ELlD#ttP9w;dL$vfKlJ;0dr%R8vCv<$qrl5~hES9kvWIKE7u z+uXvYW(HlCfD$b#;@pu$fh?vJVYf9W%3GZql(Ip2n)e~ER5w`SEZN+UE82N-eTi~q zb?EyxC9@YTqA4<|4#;PtfS?`6W(=G}H=K{UFK7wf|sk1jfMh0CPk#UeXLMUVi4I}E*}de5dSqrZs@Mr;E^SR1c5)#R@RZ4 z?tK;Iq>A;KSt~qWXvnRmk0BmRQjA~QdCkjCoqf@9bmRiPc9!F!`IEo>0#4depE5W} zGPtAAM5eqZ?MG&w(4ArpEIf*hd3rTk2_`ju}q$dH#$kr+0+c2c{kq2YHJ#o*bVYLjD*(i2w5u4 zRo=>GX&=5UoiUZsVv(7(k~&3A#V9gr=j4QP^ArloGi~J%3EyTQyBO=i0i9BAK*{@ioP%bC?dt2~0uh`kMEE3sEoo}~T?tL6{ zdoDU)a~9oTu+7ZEx(cEy4E~(h<|fopHIWxs zgLKeb_S5K4?4IH>y}*QVXmB)2{HP68a=tGv$*4mxs?i&fV2fEBm~w0tVyb!Q0m2(R zm--EQgI@(X9l{Vvso5B?CRVX=&riRfiPH2z0XH#9QG^QGzvxX6=xZX$ zg*H}LkqCJ=U`e#XuN+lJ&_1H|)hYrNj-zHNQw#{M3D)CBK{quk4DsPqMxwypp+$#u z;Va@_vpLqPyWS+aVI*KJ!_Tt&QpM>LVv|p!pe^1F^fl9x)gV!0q15K^;MIOw>1%J$ zXlP*A%RS8UNwYFognOwX5@jJhe-)&CX7Jn?A>w@?UfM&ekMIy>K9r9$n9H!`Y_K27 zhRFE%O|GGi*`i?7=KcOX>ib;|s}x^vVo%A_3u+AutWrE-|5~(Zga}os&jJo^RAdxY zyU-?Hp`-+*Jp8wp1Qq{1=twdH=<^EeF7yT3`|j9Qe03_fk1s2+O27H!nZUOZrS$BT zYz@odQiNBbZMqoAaw(6p;WVT!0BvZu{N=<)%2%<84PZszz054g2!29>eAy)m zF(<+qKs}$bw*x$lhGG*ejVvFKmXPd$A%j~jePmx}UQHLIkg;3P^_i?2k{LTRKjm)E zN1}CLXF1V8dc#5O@^K!@Inyk)IdN-yvRQe2Ix1}D$U)QHC1Y=IWbdqd`=^Lr|I)o~ zu!;LMfsSFK{im}!wWg5Yj-JJSt*2#sA3w4b$=B<2$iOb@+1EPrdY-(f>ad(f>^wG; z!P|el^5WFrjYs!%?8hhbsyD<0ZzgjAQsIBbF0aGBiYEV?9mTivGLE;URMO`dmF|DL zv(?KH?SYJwirTekzzFTuu{{~B$^KJ*dSC2C1fg&>3FUa)3S-5$88tKZdG0+ies0^DWGLT}Cg#;G0OCm6!)1#veR_^3z|eSpq|yM%?GqIJ5e zjJpxSG{B+{QOw|Uujz0{RM6g~i)Hqlwc<kt5r_#QD{nZQIz>RF*^e3`k7Hbd4seWGq<$r?X zYFrkB%#Q+H6Gw(e?s9xdQIYzT*P2PG#>_A+NEZYr0?b%9V8QhB+d!Dw1Auv5$0j35 zkh163QN)$#Cp&1QimUM~WfmTdCkELVpI*V&+OVk|%zrHS=3Kix_+t%z7DWjt7WONx zi`1`;l#;WaeHw26-KduYM{vGN6dC%Jp|)ciraO}AuwzLYq9j#B{xpB(UVnM=D>GD0 zQ0YO1F>`i7k$9oeiKSeX4`u$11e&WM!2r9~04$#j%t+t-G6!!c+k}VqlJ)K<&x+b+ zO4^Q*PV$8=-P;VYx8So)X$C+Y5-eNkS`J_0FG<(>r7vz@%3a1!J9nd`1Nf>tT-QZ~ zZ8V4{(u0O<6^MzJB%}+}>jQ}fq`m(5shoMy>qw*Bh5rf3h}Ac$yZdsdrDTDs52kH_3Swzd2I^oDQG7kDL% zGMV37e>?l(O5vd3k;A@8KN>U$7@vs#!os66pE-?`o^MFcK-faPAF_MkFpDLd9AK$rJ>+$7Km@Zy-^u29+zVL$~nr<4WcI`PT5wh zH1qzP*VvKXD7vC@s)TmX-S&uz5Pbb@^Jv&mF@m<;)E>OU@5L0K4{}%PRk{uw33>kq z!(%hvcO?ka;F|^;rej77Cr#~wX=2nTstA>S1dAmB4`2f_&<69wHHeZZvpP_^md;qb zdE{5fc}Jr_N+N#jcrxT$!kd_pe6`^5nm+UBG)7s*>FyGJCN8UYISEzGFv|;ZBX5b8 ze&b-g&WkB>%g2CblKd5Z(ykO2gP@}|6ByIpDe>ae=HfrF;)5fD<0wNXy2`a5V@|O+`PBltPR5kJ$q?nrgxi9?80=gPtdHl z-Rum*MDf`i5)8RNSh$FVyk*w7Z6?G~e8#DD#|<>+Kq=Y3QPf_rso3o!M~DbQiyqN&c&i0%@C6|)g^=O> zJD}WwbA-Ma*=*DC#YP!Rr&huO#`JE>dIZ?L4ZK5P-N=B8{Ojm&!FJhe3GN)OyF??q zsR4{gocOwp|L+CpkL%L*QT%(}&qsp3-B76KGI;eN=0DyWX>swFadwTw4^70(5oVvS zc~_sfTMu3p@*@E{5C;jYo>M}~!{V|7KcC&ImkoR)y}_b`sKYp^Nm)F0zi^{#?1wpW z%gTo?)h)%WWSI_88hM-Mi%Cr*rBrgJx^_wU$VfnY8wfqEd{p_gC#{bW^P3*pID-_{ zN2j^l9>JJP`ODcHD%$?6y?&#YqMrEN(yl(1&tCm>36y0|1@!?-Vi zQ_6Gv$QV>&J%0RUp4fNZxE1$)?7INyMsVX1RH>S$kUo~QWLB^(q#9Si z$v(7E(XqH}=+F_{Vk_7??HGx>Tz6QA| z^m@2IA*u3GQyrQM7ooV>Xs2n-_}8v1eM zIjUDY<9uA3pj{V!uX^s>e9gze>#)RR6eD*wocYCYA7Bj%g0sbc?3=JN%}a1ME-bwT zG}Uxba6Rqhd(hiRU)#QAfBHaRRq0H7n&X6c>Azuv$!QPW4GW4M=bfU!VZ#f(#SOCO zF1bZcN1;sSvOXbPN&NZXbY&i@q{m%~Om3Q(O_|MqbMRiCLRDZ-Gi(@Idf~J+2_79Q)8(m~ zvi)fEd|^Xs`h{f26FPZcch?pcxAISlQAbh8a*R-6Ae435;0a9ioxU|g6N>CHzZ+1D z9Xu}~iJ3Pen;$APaUrYwt-51nB&=Vc#JI_rR|Ms$vjyz6FEtIW z=sIQ7oY0~j8qsc>q0DCf$usiXujaqo@~}~Sv{31|uS*!~f1SPW;TO%r$8h#WSHQSj z&Jy*c;c%BW4a*UMfd%2tWhN;A;mFR>VQRR63UKcGE9t z>57gmo)+04_|q($$A|{KXvsEINWx4_fz;I%pF~q3uu=-O%gmA zy==T;HFtSv?(!|wQs=q{X3lY+?Q%AbCdlnR@pqc;HT0XkpiL7AtLLGnYEC9qtQpB# zs^!mWjuLV&k<|MxKjJSERt&a-hW5<(YA;9lZDud`s`Whr{6y_)X2|VoS*n!nk2q%d zRDWCsh6`)$55E)ea-J!;9-!%Wf1HlQ%RITx+fTpbXu#_hl)WZK)V2oYbIFSnH(zl+ z1`$J%Upoe<=d-aX2eN|UZ$WA^+ZxNZ1L5-fSJnGn3YLL(sogVT-Ap80mK4Umfc*M= zkg|_c?wTg?nG@~IIg11G$dlnsICjrdmt!BL{=bUDkd;IQ=I`wvopXJ?Q3m$CBsJ@F zhW5egO&Btp27aEY@iQeg>Z+ECiio5QQS3$grYG-$Wmq%YpVqvpKr_T;t&xiJ1F(z! zB>-%^w&VR!Ag@Y}O8>;<11xwb%j_@7j~JK1E9}IW!NV? z94NgwghUxq7H!%sv$NUaZTob?S~*tvUGsiImZ+PX)tgf4HMFTNHlr{~cfX++bK2Uj z4fe}UuO&ovDhW-7_DX7#^wqKk$3}cnbW-lzd9-&`#`JtJ~Jwfv87g1ST z33Y9^J2nl9!O&?zrC35O>AGr#^=+x_va1Ep>azl`!;uQ|e+z8VwmD!{<0n`itwvR# zfuWIm$wqi=_k|n!3>vjPaPBtA(q40Sxx>(FAg=l2WD+2r;~ldTV$?t=L{rV#G|KbWWxGG|j1q2pWAS+{5x$7L=Dj|PHWQUUG&6_GM-f})UtRVH%`mGs0VS*<-!6_2-QzY~-g}nV zg;SiBS~4>=S6N>9LUntKvg!Yhs;~TDA}sLu|NILbn&G_>^VVBQ1-8b*^9PF}vV@nqpq`U8s?;1$98#leOUUm^gZI+JQ zdO;nJFbwsV@rSW6TL1Mhwgh_$rZ#r;PLX;MsvlWExb({X}D zII&ozXJ8AOkHgmRm00|u2y7%B^E-L779w8lt3DoY_LycA9hT5CPkQ@RgIOw`*xXMF|Zsf}tSc)e$jbiS?YN3D*2S^2{6aMq0ex2s{bLVP#GRNKCfs|3*f z*Xw4qj9aEVJfH+{#3LB0>(R(#7}U2ASZv~!s3Z=+&N#HF|2=dgyse~qOsC3G(g|65 z-?7dPzemyjuSYjGH)+}m%Ow#*-ncuPL6Vs%*77<}8NKWe52CG;+s51nozRFV9O28T z-%yQB`O72)x)HXl@#O7tX?TV~(U8i-FwU=u(HJqY(b_YF)x6jI#%OZH1Fu3;7*G<0 zCvYpnWyCOT%>iaJXZ^JYSk=}1xeezJ)flpeJTqV`MT z@R|n*{-I}6`yMYI)w1qwn_f`r6}P>ZX7GMUrFJ;$Vnto#FG&3uy|(ACptGuftonP3 zN4B5(A!2)v8l{nQ^wn_Nb%b?(Gk-0GAu=uYDsS+qX`v zkadQyR_db)pJ7t+#An#Ryo89WjyX_v`Ge2$oy7Io0<8OoSc z>rfOUdRVgJ`#Y8?{I5`!CzGYE?hal|v#a-+r2G-y0cW8b{GvGb_DBaj13g7IIAUW+ zMbV#8PK}49$GOCt-UcvO%aWoybyoazj67G5@HE!x=sR zubooVG(MCu>V1R|c0P-CVu8`G_sgR<~?p3-q7+YoMz57m-GiOA}b|R)YEuay*{J z@$=dUy@tvr5Sd-)cAv_z1g1<(D{@3=PC8CxC`RS^>7GVH`?Zg>=lk(dYnz)Ke$}o* zHo9@P7%$?zFOzOTpH@;%S5iAxrom;wt1kq!wBJ}k=E&cW($%Py+TTMb&85=>Z_(+l(ZwXOABVv|W|QRUTw51wRAjPt1twZ7X(PyC``TXm)o2 zC)d?I&tOoSJ%yL<)D(kIBav$D?GU9wZ#Jau3}0=eu`+*UHTU`0xj$v9jC_|e zyaJzLSOJAgG4`6o)DAhuH<|Q{$l1-Rq~t3&)_xL~MAx5cR1=X`tz9Ec2)AdBWyrK{ zloKOW{P*(Nm&sz8R?)FlqKsa&gK{Pn8ok#26N(z|_#5e8o5gP&3lN2QvfuhOgp00v z+?));7`5d+iO>4 z<5bY$WZgUNF0k=sqO1~kMF8D4hfWb9n{5ph~%YPm=y z=CD%u`DahW&m*e1_D-BBn_95eL}9b*(*&w8S5JrbQb$`3`l8RRHs+t7a%Nr2t)!j0 zW`kuX-Ck6d(8q3nwQIXv&07T8v`RzuHP0`s&9SNBq`+4;4>y9i_6)}7gf8LU+Cjyn0CuTc|A=P2glXt^si946rG1yveluV;wq0ADF?2J0$fzQ;8>KoaE` z)&?G69AO*22QwG%%!y7+^Q%b#fIShTeqZQs_d2tk+~++a?PPn|*{pLwzpB}8yn1%a zm*b1@i=wY3pX_^N((lU07)h!HU6SN8VMdj5yFh@c)T`8f|0_uCg7?ZmOvH|BzT_QS%?#rOWn!Ke4KFBQU~sAXPu3!c}ty9QPAsufW{Sf-grHEKsi zWJl$JU#C^ojcz&9o6hL#ZMhK2W7Z9<>U5^B*3elj;Kx;dl8p(DQ zaS}af7J|L+Z6GRfk()^JclwiReuJlN+oOLbRLo+1kG>gqbRth_Ke)4cQaeJwma`WA zTaXqh)(#4jcXTx46d^Yo&Tj}v`ZxozmU{bP!#~BnU@5LZHwQwqe6eXx`Wuz+5ff#J zO=mCO6qOYAXj(Vouv{UnIj_Iy_(tn04wjo=eneQ z?MiAF?vSc`#No)1OWJg5oV37(%zyZ#j5aNp*{ndymdgti?-x%P;oBT8OJ*4h+=S3x zFL~rW;LABA=S|<(Sc}k(tKfC!T~G+ETj0fmM2Vg9#D3*vN25<%3ojz8E)yN<^_30Z z|M}B<88|s%^wEc7FdazkiSZA8w1DAp=ABW^jpNQ*j>wYh8E!DqjD=jc|L)SB8W=-z zY&;T4Q9L+Y&g#s{?#%P!9+dH3O|<>LllSIiIgr+LFBY zNag29L(6H}^V5uN-=uW;Ygn8KCm=8?SNVo3I0@z4I3TVIk;(w#1>lT7G(;)fG_VAt z;Aoly+cug2j!uE@bMj*%sTQk^ZXD2gRU_U0dJZ4NgH#Y)O$;Zz1ly zwTX|&A)=C8y73>hZR04vnpXdnnOJpNMO(~oo-mw8-)i3O+Y6LDAg?h7B9QWiLz(iJ zp8{ldSTxYBEWXZv5$%*S-pG>2@F3v~1vIdp9cD5vO$$$N*>*Zqba_ZdZ7IhcxU2PC zlFnyNT{?K(>vl?7iD&7t^Zhn|f9Y3^$m`w5{vhp$$sM`c7Whm<|BIC8%A$+4reVLv zTywg=%;|>xTC*@+fP*>8+f9peU{RN(_zvFv{KC_bF}>8<_}t(afnO*} zvwBjUMETH=DtfNgjw6TLIx zkoR(DrYaVH|C4KcK|ja?huW%hEc%;-zkjJj@EN93-MM`35BA7g(zabemf;!NYy-Hw z*}&A~9&CqVG^+#gMZn6FwH`_R^1iwGzOX-WBWh;&e=;F8 zQ@m{114ds8x@|zpf(bRjs}RZ22zy!lq|A|G@yUUcgDbGY_F+3#bT&In8)3J#f%O{+ z(Ndb(?u>iR=6+0rY1+tcwxVAzKuvm%!waqGC_;0ZP4}HoXJ019a?Wu%`b0^{tMdWr?0AZ$uC(bd=jBg=1@$fGB| zAIEakz*4fGJW-UlLiyL;x19w!pNA_^=~E55B~T`Df6&z>rWn*00dNu9Y?3Q$NSA*> z-*itbyK)aWEtAV7pA5vOsy~1?EY0BNhW&*sq3BeUL?cbI9js65a%HsP`M);Xsn6Ox zJDAV_HAw+r|KISeys7nwX8(B7W15u|zsK`AfHOlK68gU`qh6Mwq4Se#MzXsT0B1(=ph-Mds)|5at-U)h;fC7@ zkH9$bc=g~}$SqM?2pNfFfYWEX)~dl9F62+eG0A4Iw@lCQw&Pc35IZ9Dd+F)f>0ix} z!#`pPALU&z51is752Lg4!(@G07DjD8%_d9dXL{QWd5DT8!(d|i-}UO=_Pdn8kPmk# zqR$|o&mW{q5;IOH8X;C07yEZPawzG~Xw?zyU?gIF>o!CL{d`@nkK>W!8L6Dg+jhh5 zk>!bC_U&NP2Y=(y2TQy@=&wOG``mZPvTEmrT)Nk;+vH7ud|wR|*r=%P}t{+@sRyJLQhyRD%_*DO$lF;a~)xbNfQvNL41w&imiC>lPj^ z$1CgMEtq>#2m;w)S30oF>YVxEOzTd)6;yi1IVU12ZCsth(q%)(u?`DfLlZaoPiWj) zrvo{-=6#b?)2_#F=njb)&KphkzL>3ND`loaT4@25EJ2K5DZ8n5H=38F-;oU;%MP9o}PnNY=*Fqq>?hh|h z{j)l4-6O$^F;JEEh>$#J9u+j zqO5a}*wF3o>3M##sttgWDoJb2T7mAj4u`cz*+i?MGEIIQ+%&gW?A)OoUx>zpxS#6l zKKyYq-x}roAN%4msQ>jlO}AgWZW~Gdg|QgOtf&Ij3QKkDHgW{C8M5*WxFWm7N#B+W z4jwhl#J99tArB7zs%Hq4%%}bo9kxn$W;No>jAxZX8Wt5@)IN=I@-~w2R(%(ge4)yd z>~S}NtVfj%+pfVHtbPtsk|?Czi)cR@Khyg)>asgdp)O&EcK4zZKR0rJFFYdKem0`_ z{AA+Ck4HiX-S43v+eLM#>ajJ%FHv24>!0b?Pp;f^nJqvd1g55IR76bvE5Iw&{}JgI zVSSMwcvl<=_nTyQI7-Q|EwcEfCw;X*yLG+jrhr6V{~`%1&QOy;DTCrroEJrnn004H zar;>FUb1!&)GbeddtQ2Z5m`s0EA3~9nDRPT76AqtBXYUoUHhsra}jmD=%?)zS>_ri zcuS8-VDVc4{h^ZJH4!}r;LQ&w+Uz&0Q9(d_CQP6o?SJxlIHJ7fLC5$Nr=VjrH84ej5bVPj>SkEu`;d2q;Uxs@3n*|DdO?^)EZS zm#FXGG%`1xeict8^746=Ep;?&`l_fUwB@6eq$?yvd!D=t@VQrWDR;paWAGKFr>Q3r zbHj|FEPCeGQ~YdmqgkPStnf@_toNsKq_%hcE2L9HOKq=L+u#*V(K>P#Wxc3Hb*E?H z3$%X$T%j|8a&dSdiIVUPb|%PWh`B5G{d=nAfppWW{#ZqXLu(E1kb3wEpMO*?ejh7q zi>J&u3SNqs?(o`vh@%vjouB-5b>ts`u&eO5z`pFPGM)>^%^QHA?B)!E{{Ag}_TMS= zAx`>;zhOT&LZcq$$`=xgIaaF+GIM%>qaL(d>HEYIm-6tFx`3d#a4UJ z26UdzulXex*Pt7cd|`o}6(-zU6!=xtSH*Kpi9E9XonWrZ(L{O(a4BM6!{veECRoxZH~X>e4^-9RL(MgO-F>I^Q~!VStr@DA1!OJyL0pXR(H$j;>hlB zME_0QKXeRIN!Vt*qqT}Iw#{$JI$dKGW8nj=!J(Yp?F@c4FL=Gf%yt$8YM-oQPl7fG8R(vnrauO2+S+-TkDaFg_a zS3SIi)Eexfujn|9>z4K|=8Bzs101?4;#R%y5Vq?6$MC-@YWwzKeSP@qff;@DMjY!4yoP5q3$Ci{o%JFI&72r3;o-kfA8F@SrnsqWRUOZD5A$o9Q!=(YLa(#s2FkZT zM#fkWn0eGrRW~2qWr_QlfN4l>O3`tw@9Q3|;dPc*Hu`gtGirRPi<)m-W_VU(a)8vN zn&mm+-`6j6@hm>2kIiN$Hx-Pv?z4-Sg zzKetO>EDM=K{c1Ep4-Y+49dhIm2*`d;;F9~OD#scIK()4vX9+ZrtIGfEi#RfLbyd- zUYAKbM~t}9n{Dn)-afx3Ur!$=FF3{UhPU%afSqV2YM9Rmw!PgJWvE=&$F@$p{+LgW z>6iHaMKMIQ`_In4<&-)OV#NLUhKC6|AE+NuB8O_UUe78eJ2OTA3Ny6GyTHSImC@JK znwF)5#;ZfSCb0ngf2Ejd9_~f74d|(a1V`~8Sx(hA>CUK2`j-hbgqM%+*u28(j82x1 zm$JTvZb{R(p912h>LRJREo%5l{M^XLvTt09w|;B7B$ZW4OBxk_5O7JnJ6{!zSJ^T)!yszhY$<*;uoU+uTdCTY*QpLp#>`!8t2#_mF zD|x3I{nX2AAG!u=_XQCjL2f$6Gpi9e7=iJ= z;g+|%8?ce%bk+{wxAT;r;aVU2`5bK^V0$;&Uh5wn&He#XH#i;D1J@|qdm_`^0`sz( zY|vOI6e|nchEp2)&)%5kWD(KS;E+r1+=Vd^zQ+At38bg}r{@0=1NeLRH>g^W~B_XpukitP*$N@$nh(?r?syQ7Z59WM_> zhYfYY4jqU08Pmp=Wj9hT6!a@T50n`XEIE|J1R~`I?@xhUXltAit&l;5uD&sT5m~cU=l&10zuE1Sb5b~OlM#Yled&wbzDbAEq0CnxdO`@G(-=kt18*M&p7i?(TUe#Tx-#Hw<} zKTt-}ds2zaj+SND#{qshebuCoUBkdvUa=L^(P)8GTCWYQ@4;eb8;KiXiBuJ{ zl^R$C{^Nb*g-KrTy$1-SA!6l;(4Tu)mGqsQ0wGK0&X3L~c{RGQof`DwOyawh+VG;7 zdy#eh1{#yuD|@Dp{z={P_vMJ4n_nki71u9CKm%{6o^|zqu#IZ6m8P^^jQBZgy_@!a zApqrgw!g;Nu+Blbjzj(}dUueSnavnQvM4wFGgB?mS2CHyk#XDV#2HdlnIg_M)|oP` ze(;bY`3>wZtupM9I(vtFlQ%ITel{{eZsoRb*##xox!ORGD`cV3Jg0{ka z@7^w#eskW_LD+YJcHz%3p)rFh(AZ0n6Kf+1te-I$VW(mp1gK5Tt9D8vhtKxUOkWj_ zYeS)2dB3O&$@F<>J2JhH^*iQodq)X*H`FE!)Rrq`ye&o&WS=fKPrCR zio1k<=~U8=v5GxN4#=Xm$e<6*PN8XeMQ`hjl{#>^^bQ=n=#YLr zv(oP1)}Xla<10JI;no^2UpB34e0HP`Q0GDZv7wTW+@*WaHC2l{^*!#}lK<(_#9~m_ z2y%%D;A!<-3rlsqO>aA2rr+0yh?7}}%6Ek|J-4@70LZIySYb@@ctuy}I%Fv#o?VhX zr>9+azjK6E0}Rk$x^)ke$_>T-b0`exhHyH$)2bt_8F=2@(E-hYDSozuvW!0&SeywGbfS+_$c|pZ5DkMHMnIA z!4{>5q>gURWn+0oxt$g%3Sb^-N$;JMJC>iAf!c({GtN}SwmLx7>SC+#9HAynU0w%wXoLc+I z0dr9QTunFCr=x>;I*ITI_aF0kzuAX@Hv{i%daqq$HZ|UCcHhR`?D~KSqlGvQth%&1 zWk3Y-F2;7?gmlj?Y*sBlvwCqpI*9v#p$zF!<_b`i=fY{>x6KUK!fzNot zI5U?Pp=%X*Z*I>T+E?P+q92AI8ZwIH@mkp6yHgPTeudc5i{RJg$oASb`H9$qqHwi` zM^0y-mTls94aLL#WXU%VAovJLZwuK)yV*f{Z$B?KKdVry?3jB6$(9=sVhUdMkH6<7 zl=h&ap@6teU|5}d{IaFCp!djXzq)X$4jk)J)z#x$Y43&5r4=Z+U=SssFA;|Pd|tBY zIF-G2%7b=&`|@!)RjE~6*T4165@{YsPLx}q3&!DkN$I^U`nZhY+d?wm&swT7Q~szl zjGp4`3TR^-s3yj_-VLSZU+!IgF6?~!nqy>3Bv9phhi+lcqbz^e@WOXOol z{9X`ko|&kOQj2Bug2o^_T@zB!994E7r_}wfWxXN(2_dghV%Pwg_#)ep(rI@*b?EwN z?@9jGo}MDUr~ZY}bs@2LI?*;c1a~2GaexGozF5`e7{Jptm$Z0EN6>IeS+s4OwiNln zA2d-sNX}SSdeiwa=;)z>zs69V|4H?9-2a~@i+M~sefU4u!6iWJMA)e{iofAGJ`)~g zko&w4B_DYX>~MdINh;rmc*)Nl-3nUf5$f3P=DFB}!GFC>prcdvT6Xp5zQVCio98!P zN}+%4GpFjapyBr8dTa3BhK+7K6ZGT>a>vI+7Oh~B`XI|7|ILn8-fD_+rbU*ZGEUyI z(*ULXGz+tJxU&J>$HZZR{!#u|W*=9h*V#qpzpAQkEHf&wF0`s$g>3pv6o%^%Fom528fe1DL(m(jBIHyRyX8 zTO_^jKBbW#OS?v2aI3vlyxL1NPQU2usAECO(F4Ml;!@0|&ftX|e78 zpZm0|SM5juuT4yA@BMr(sY?NfRw)%ln#A8+vajy7ea&506fL#DyBe6T=7lbua)Q|P zAXvUtRGjoc*@gCV#&a?Z9s>xD<8G?jAOkIq-2B{wbf6Bcoweg2fQ@rIyb9Q`Fv*BV z1G~xulJMy$aJH?M!YVI_nVkebi)*$kgSz64vwI*wIZpOLVI$>T_bgv;{*z1E@F*rY z{p9j1j236x3NikqTwni5yo;u(V3JC_-h^GG4Mpc^`f$jXqx3KcFx)T0ylB5qZTq}5 zD7t$S9-O4m@gGXRfW1uA`>?T|vN;TJ^ycTi=zrels@mUV?RkKlg-Qn?XJJTJTguYv ze%NVJ(TRco>_Mn-P6e2W1<<+kjuLf)qohXxzU|Y=EXd~e>SKQ65~mQ8&yW%s8U6ts zyw4PamCr_GCoKr)_m@3x ziFUq0xhNhPZv4G;HC2+;PL`B^wLRsNRNu&)ym+CzFw2I@HJ+>P!KCjYZo|ddEv(z5 zu8v%o5xuuD%EK=5Zt|mn<_1h7`Snf=VLm6xQrY2t`>k^5sie&8W3kS5+h=2>J*oAT ze7#FC#m%LZ9xZd(r&arseJNSDZ4MYea!Oj0N0$2j;+SFSk`BH-q-ZOgg7j}#K|-8yxep73G?(cKHjFKfoVtxyi5T=^TiqKJ|&K)N=;g%I==#^P&aD zoL$hs`c%#hCN8Z%qVRF;sSBd;)NvtbX5hEFynmF`T5khyTy*)gm4}}i6P*!D zqR@XNgW9Vwd9Gh2zdKKKDFUhMood?V7^f~+24`tz5Zxv+Ql~Enf8Qplw-;7)PW}CZ z=KLRe!9?2O6n9D(NFi$XYBXPSu4-^VTHos@CR5}%BgD#gj6)QYy@X5avhAN@{P0Uu zyq@7ujU75zW}MkN+hO(l+pmOkq3|D3;w*L0N2fe%WK^;aA7)Exr)i)j*2Rr# z^N+u{<^2g|qkX#(_@sr`#jWsTn)#3AOd z%ajkUg{Auo-_}2Q-b80vP(4-XBk`a7+E5E>7>Hb~Tp7AveW>|4>sNTuXN^|5aA*Jf zNA%Jv%CA^hc9I!0smx0c=rCGGL~~yxhXff5#iAcLC`hHTPT9VrV@wIVavT!EV9p+5 zQa>4DAVE=3-apRMZj8wCVKr|uJu--Fc_`co)Py(m6Jxqzapp7$^oqD3C9q@rZb1I( zY!Xn@=50UmWzRCpXun0b^*cF0U%O98CH4^lSD3MUu%xZgbNC*wk)#+D zPqs^D?5z(ITg(a!g8b{l&AD9!{=a^7geP}b(3o)O0lz(KFd^ODKq>xFZ-Jp%Sq-Lx628xeZ?mD`X2h#Gumae{-Y=27OjXseWGSaV$Z!g(t906Y#et|0tz#! zBal&y>L3ihWyPpwA4G6Upk#_0E@A7CxiLmsSWruxB?@w;TG~8J8v8fg@lObCeu?gr zT~z$ihwkJR6hsCI@fs4qf(nI1U);!MA@@Bf6MvisvWkdNjM>VIvEA(vtn>JwiZ?JY z{mk|eTSu``M=UMhejOb9A0xL7K7cP8WH1Yk8-{nGofyJP-k#eCw?zu9*+xz8#oxYK zD|!o#Le5Otj#C_Fh#w%~Ha{$Fgd6uF>M;Y8Fhl)!0J3(b2p8=d1^EUoI2eRaw>zBt zw%+DWAHHJy;kS_JyFSs$)*903T0@~v(NT!Cf9ZuhMC7H5hEb%XqH_7-oZ-=Mg^6Y7b+mq$^a(>$z{Nnj!?aME1Lhp8+WuqL#MsKZ2huieDn?HksH8~w* zRPRlcve>X51>tCnX2)547p_A|XURK%Eun^(>VvZT9YlsHMyvfY{?d%9g#m}-nH<8q z!vU9njopKw@PqTxonNuGTQeRlCv`-*yJ$&YrC4wvw9}AA(yPGmvvEVPJ*hvtwJ$@M4n*GBrVAdr|7;ndTop!5eDSDTh z3{mPQ0;jgHacGR_tSB^RZ%q~06jcyh-Kt2Vgd9RwJ zO5&o+K%2`8sunZ_F)n*Qf{Ff$DeHtCobIj+J^9?2+&X<}W9xN5maRyl)`N6tl=WbXVhrRA*dfxV z<9f+X(o4YU+#gXnv9rI6xLJpcz<%Oe4W3$+3vVdBS;y~aHk$+&WRb+0$na_Sm6xAH zSD0kJqv-<5Xpx{b@50#+sg3OW9?~Dpqx=wM`Ac|Z<5mNjwWFXBm+By*L2Z^0f5PkF ze_t_K5#9jyL>WK7ZS9}v>?qo%z=GP2i)Q-|xf^s(1du!Y2#dIMco`zJB`0b)&OQ8JN@C>u)f;DJX!=eoVy%-BW!tple2PV5YOsSI1!;2-+b zF*cJt!OY5}v1^NebS*FA5arOozNV^vzdvpSMEY~u5xba`S!EqYDjxE)R%K#gFx(}* z+h*$Wn2gX}9ju5_*68|8&zsGgVSy{JcH=D1?T;rZXRY-v9;c=b;aP4q`rcMQG$i-m_~Z;k z$f&^_)0v0%Er>SX3c5li&3N$|SFF}7yjYco=#`T5==xQ5ZYcU`3y^Ywnc z1gX*f64$M0COJc}mh=zH)Vv{o9&tKLgj;aIpQ%#vBT!<6Kipe&VZK3bLj!~DLFFt4 zX7TF*y>Gbe3%e^o&$L!qjHP3O0v^DMo?ji;R$4HW@Dv!68j}mZ*5cmd?cF%`ibdRO z$t3no6E39D&Di6%L!gR{A-4nUZ0~4n))zo-W=qT+4@!>UJq`R%lUA!a6*3ep3;W5e z?K`5Q*1+WMWcW{N-sMrL*+p-aji~X2x2k6D=KR0?)JC;tC;!A7xNPL2-T=b5#?G$+ zI}Yz@ENe$3*mjI_QX{(OQ5i5Q33{UdGpe(47TPugvZkF*O#DQ)hoi!h>ZP$IyCPdg zvgSx?MNA8MG_o!U1+g%0;_En;!m^*x*`k=e>BoL+TZlM3{eF%Pd*a!gI@Hg)95rf) z1&Q?LlH;^*>Z3>%U53Z4Jtq#L{s9#iWJ=jxHs5q2Vlrs}_g>#*pA=U_4Y?B1zH_s| zt&<^yl!Qf?hD2!=LE02#N`#jOu;beB4~u7$1Co86eCi<8VW46%qIb1J;i);}6dEv% z5*0C9Ct95A2Ea8s&r5Z{j++G*gUmTLUpV*`B^}vv92XmbQxquPq`eoOI&qOcFEYGx z=0~lSIu-GjL43GH<=f$fi)AWnD}QjDtAHa}1`eVdo~Cw5jUa`tS`G+rEvo&T-a!xU z*|Qs8YP3}#qQ9G$nbH{}{@(m*H0ZZN1`=Q+5VXj%g5k^EH3IOZ-D|vQoYK2}ggN@` zrp1|Cg)>Z&$a^=Dzid)D_82LLzNMjb%<=)ZXUZ(uw+VKtJmw> zg&O{b6NWq=AU~5=_)g)7NmcIIQ-$3dvY=BzvR9XCwxWEvAU&Fj5B^x!3e!Y4KAW7} z2KFDXc~2AyqdJwr_XS5AWHhu34Vc!tgjK9pKQTmCLN}KawFMh#3X-3OXr*VR+Iq&Y z2tqF2c>)n}&8;bWz`AY!cHLJ=1-<2a1?+W||C$=|HiV#KZ)$2)_s;!PN5}BbG=7pw z$<{O#oPQY(V`p<{8A#EttP1WU!{KYFk>mgJX1-ZP^aeZzxd}6e)>wu@iffovhQ{;P zy^U1EMp$g}!@R=e3i77af0D!KGeL6D%2M~zNNKl@j}pJIh72~Mo&})7$7ow8ahbU8 zz5n7m{Ck1?^ibyiGC}H{Fk(L>3`CsD2pd2ATfOw-(9ir+C)1phhX7glyRh8zg#*P* zXif7ED@c;w#OHFd?W<^mD{Kpye6Ds<-6x~eg;*#A+fen~{Z}U+Bo!uBIrBgq#Z+AU zdyCrPZunm;#>K&8muwQcaVPn`dVWHWQ^AZ-2&Z6&3d6gP$?3%c9d~l8T-%4It3@2mtIyvW{DnS2+3a(J)OUY#WL~+?Q(?VyMB?~LeVPprM5h>^%s(-y7L|ky zPu@A?;6W+|^6c7|N3e*4ek1a+XvhF)N;OL_L_t+7oM>)+_)1~pza37OiGZ(nyK8&xoGGg_TqRakm)E#GQ3^N7Ncaj@F|#6)$B zrOc|l8J7NPT@WQz5f)GHr~E^3m(u@%!3$^&neo?T^eG`g!ZV@&g8=z7|Q?4EX^@B}7W zv5WJGeZZskR{r6shcy~j0^HF?i4 z7G$WpG3|EEp~(`x@#ag*FKZv&-qpi#izp&Aa7zhYHkm`q_BT&R_RHSO99YVh-eJTG zC0;4S=}Z6%7nAouEdm(8BT5`gVa1okMGW*-Y@11$Wwy@?N^$Hn$K3R-7=o zRdlpSAzz*v)0O-x$zo+dUD46%Di>1OazJ?kRADB2qws5MT4L|tE~q`yL+sRva%bzL zWgEk!hwYjwJn%5P!^s_@d}ojT5L(8%46CepGlS6i#!MeW3;Ntre)>LIL_I2_CMXdC zm|es8{khEPV{R%SJ6qlzEscm{+&)d8dX&v3yi6Q#0Wi~n=6bS^h`- zOJJ^%Lxn@?F1A?@T!_a3cU-S4jPv)0rt`MhIbIIiXROzLM1h)Dv{+lzG!AA$>%;UY z!_7ys$CSF+Hq&|cITDY8Q+aS$N-CbcakXf&ZDJ(;a6Qo6vgTa= z$vcbdQWht-Tt}rBk*hQ1T(YvSWlTxPi@~ySWh+a|_jLo%!QaldcAYNj3+uUBZrs6Z zMQ|)82D!RaNrhT$e%TAWZ{RdAYhTGI^}g*wE`CR6%u_YHj)V;=qLMjh7@8mDX#Iw^MgSELIx{g&*U3Mf{9i+#;M2+eL7ujraI zZ3NTE#OB~sWa6YJ*Zu$L9(;;YNYr8XQPHY1nNl*<0C`mQj3I~ZLRVWDWD(T-IU@|O zFlvw;g~!UNbyet~Xc zxD_@1KOWmSZ7Gh^{=v&*_yN8x6P=2~b}Wn1Mve>^!M+i9Y$EK%qfi!|G%PdBsDhi~ z?zF&4tpr*EoKW(6(P66hDGzHWnd*a84iDsUo>k93xB|%ZFB1%VRwZ7dVwtdg{XWmv z-*%l$v-{t>b7W*>BEO*q+&53k>a|Hu`w~LBEZMT*q9X$ZPndq>JNs9^FRU%^9V%f*L{>gfV6r0c1-;P$Lk~X~OJ}I#$4U3aBzjugj<;AH?$PbfhNZkSf#J!cl|Xv(kFWHXJB}3KLPMl>*m+!VY9p zZ3{n?%;MWDimvO{n~yA{8X`!-ZTqS@o4Ws-P*Uy~C0ab%7Z=5h0=WTpHOE$Mm{b~W z2EaQfb=Mi~^MRe}r1fyM7AJcZZv|i<={p_3MUVpF?l&Gk9)CKl%vLw=D~T^8wOAjE z22n_#&lx{zv_RcBaU7S&F&Gq!C@@qHNGiA80NYo z&q3MvtZ$#AL^$PSRT2e1vkl^ZJfM5qr_^`gmCV(Hh=rg#H=8G0H`FnhM(Q22-P=0I z54U}WtnGbFOK(JXH{VM&sx@O01e3rvHy`A2 z%=;$CzH*7#aI>&>8hE9Y#dXKXO88IiNd>X#UpG800$T&N^H+5KoalV-j9FV3LoT^L zFv{Z&|8_mv|Ld%V3?m$ZOV)7QI}zwHBHKf7e&nF0E9pviFYHStV*Z>f3&(+j0)b~Z zK}3M#V~34H{IxGe(oYu8oc1+%KRhAUE{Tv%1;<_jIYRzu$&er@1M$pEapFCD_@5YZ zIHv(vw=w|%?p|~+vAh=Z%2F5FLtQB3GAe9TXit{}Y_cM}lp}MbK4w&!T`x>eOcN`( zV_U-*Ka|0Y$6Ufcyva}`MHy- zPL%WzeLpY;c`i!b^rI}nL_;9!y`jv^(q_1ifj8<@tLG_v#PZxz->K}L$WS8K5vkwz zZH4@hNia!DiNjV~k<~Mn-0z;k>zf6%g>1%x;4Ioq?AVeqb;u6}OWqE5IOxfnucOFa zvV-*co>Xa4E@OyHfmE&G3J6;wooY79AtJ=`RHXP(f4@h$sI+mX!q^y;6le;Q>g&eS z*t}w5L9sqZOY9>&l7;MTugbu}?hiD!-WZy`2&>dHvqrT%q<_qk`|qDTBUBB9eTARk zqOvA){I>PA01O5@x;WTM7-IKxIfcjNpxx52QfT|^qDA09Z^aP>sk}*QWwC`u_}6D4 zBmh37K`Oj7@Q`6?DtSMG7P39^Q^lURmRNL+k`MZ=N-CtEGptI@lCUruRI&f1NsKGX zX2ciG-!>|1STsBS=j+ByxAh$wbg`t3rh1uhLYTkEfjs|aqM+`b(3h+@o+WhijY;9d z&F}T|)Y+Jg0I6g*<&q5ik#6u9lSj`}tIsnkx+m$;e=ym8;_THwOplBs4+1O;EEazR z8Kz}=uQb_Yw zY`fHtlcMP9&%ZGwVo?uaHp#si>|HSX zh1j?kBL;z-Tz3p6$` zjp2TFM9WHFk+gMH3LxueAC9Plx7r*&F9Q-PMxoq*;Y? z@+I*Lq8BX)x><33x0SP6<)I(7?hTv`X0i_)2HNIP#lQpfQVsRvH46Hxz3#0-eP3NK zaeanOdZ~<1G>%Fp?JA7fp8^H4Pv@bZmq=A}!}WSl=t;e78elp7{Unstn%+BBxL{YI{_0{wz0+DYZLU#tlfs5o4 z@1?L7BJ<U!ufTPNRGXkJ!&pp-$iNvBBO`GeK=wsPowUoxg3jjN?;bv4w`O5lAyt(5ii$ye7z>P@t%K4MbQCt z-4&XghUG?!=Df6(A;XGnC&63OE?LyKvFqSq<;@mi8P(Rz-xufclGY5+pyQm-Q9;h{ znW&d#pq74sI_uAfj^E!+Htg#%b!{aXt+DtY-l!gW*(Q+Wu87axU*SF@K8fvah_P0T zvX^FTECLhyI)+mcEn1G9-Zp)>8_qJ4FSPU$pJMpP(_qD-;|6`W=FU3F3wM#w?Ox^Mb>Dd0q`Ks( z19(_h8PlWb5PB31`R8#fO`DE|9q2B)8#$7ziwbR`d!5%$ zZtataZ?Uf=F|5RDzU8J8YZ94LoswGe+veNIg*Wsu8biPEk!Y_e?{gM&N6tPPdANA1 zY7C@cB`Wht)J{5uG4?KSIs#fj@61z2WpWX2Z2KTANVjMmuFza_E>Ko8IyBYE-tT*U zqVm{7dXio1gZ`V4!NP>$FD0LQ-#6@8RIM2;QCMc_=P$$R-fj@v40WbhwLKS zv)pOwjHbvpCvbKlBP1ZjDoZj(POwAn|AO^|re3yfl?NH-;iUu)JM&#Oc545*xdEQ0?M7{%W#KPbI=1>v&3%n%_e?V77&6159+?t1=lFL=x! zEu<{?){M(K_N#0jdbCV7Kq+`LQ>ftEXT%;c;!l#8#0&MWDcdJ}$A1ag=$UUE7Njc; zt6AW_L41!vgc#26q%#Efx8O$8QX!soET%iir-1u6mxb@dlj5B}-B}3QSkiZ5k|Rh2 zXog&c-v~Tc1cyE==eWzYL|U6W;D!c0b_P)oc zkYuO^^4t)nr~&yFtg2;HmK-$N5ni+mX_?oqDNv2={sR6sI>^KV?KhCVi|cwvXP@6_ zdr|~htFV$NVET*D~EW{*qoBo3S}^vDx#*1dfz6gJMy#fi1KICIEk9U4eMU0c^@82hRzaB1u(5u@*hSG-ZI!U$B= z6;A>T3q;#?rJ8TQ=}gks76sC5WjYgJkb*mOJFn`t#6kz^b?mMAm=kr86;fRdW4>JQ z0Yjq`sm|lw|G}-^hp8?Y+XZc$%bBNvmX4chkdX&B&iyZmT%MU82NGI9aP~qF1gmzR zJ{6)KRVj-F4MoTe54RP%aR;0uP)zDDDU`yygIY-YDB7s7iY8{DFd+({wN@Xenw*`f zEF&g65#_OGoym4}H2~~SF9t*jvf8MwOZI8XB){yu9Id#)iBjMu0*THB@mXkK51d*z zhpH$cmV-h-uHlsb^V}v&DQ|gh##c;=2$^&U50U>tfa98@qeFgv+n%BQQ-q{nf6hlZ zh7_9^#!OG~nR3*1roQh1-DSLPvwt)k!INm7y7r>YUWuB`_L;i&N=1Tvwz5P;^9CuA zjo<9Ti|Yky6QnUT$FK#4w@hiv;%7=Oo{&&(ePt3sU`UQ(`Sx1%OwUCA-j+DA<=S?L zOzZJRPeT%lQ#{6QrkZ+8=;mK0>D@!_#VGEw>Ij)HGbYO83x|8>i}{ljt5=fkN|aq( zu+pN9dAZ@D^-zmK^)=q0p=)6eqr1^oGSi{o0X0z&e|_D3j?!=ab5%Zwhm7Z76wBih z9rKw+2>A`V6Rt#T6KNswfI5oqd)m6o$T!P-wSBO2>EJqG?iyHjg_Ve}jXy|rQnXc- zls6bm5lQLF=m=sGO>I|H%aq*EV%N$2eM}df3Z)igJWMnyqDr5=`}ZI){`D^pw7Qmn zalUdc-guE{v_?va-pF6z;A3woPGX4G0{0n$)F??*TGzi+kwuOqa}0BJ$X`j}$>qwW zjibeO^f7nf)XDJlQ_HD2%lUyy$9r5AgJ}n=#DbvKK6YxmtI33VFY*l~=)u#-+Sxn^&y?dGyJ1oh4EWpJoE zr@6l@uiL-6&}tVhBF!Yxs4!VR@s%b_9JdZ1xArty0viW3o<#Is?l@nu>V(nTTRE$v zOCIbHRivwE9c`+ceNX!%@3(xVgiYY)aLlhC*sB4l>OF26oDf>JN|-bQzD(YAJbz9 zgD&jh^?)bAYJ3?d+0bbg=XtI#+$ktp+!s<4WYhczOW)e?^3rEM9(^3Y^)8pf?pt@S z1>XG%zuE4gP@t3mqWhJxm81!rs@DI+BNDOv$cZ2 zy+!wbw5X9nj)EW=yA!@j<@n;%7>{x5EV{o3Pt>W)-UN2JHFcP3H1`*K;17RzOld&r zEtv|XXNfvxsjGKB$rL>rWlgk%mGJ3Gf`?mjyYqw+(Mh?G>0CQ*x&rRF)a`h|mk0Wy zf1-qO4US)9Y?hau|KUkdkPS$d0vFZ-CN%VOPwP}P@0Up@=dCKRG#oEDOrX>olD<&hLibjnv=toLpQdMBPpf z5$T!?5qvFf*YZ@G%MAQfAVl_3Dt%>1O?iTN&K+5hT2%4P3S<(yNQYxfa#?=D>D7(p zr`27|FbLxllM!ke2`oU+wqoE<;m4Z#9y$C~sf7o8wQ#32nagW)`fFf&eq9*{VWh66*uzZYJ%e#}e zcbuw0quwWSQ}+!bKvGXhjWea7lk4|crF`Uwgc4W24{}luau39q*K^%*jX{}fg!eSA z$%ZHiX0ev9GohO$RM-E$5l&*g#6*dEC7b?`{<;G&fdVz0$GN_|7n@oSq#90Qx>4V^ z`ppQLxC3?w&5|@sMumaH1@6E2lo(B*82AlU*S)oB=Q%pRJao3lM)PDMIvYc0vA+$4 zwd`ZgQ`~-_5^_S#Mp8 z@NEm5JPQ`&-u{rM`z~eskk9e7`KSsLdI}D{L-Y*-y>US1um~pG_0JN=l+P>3Gs1-( z7aFh^DTv~-0VA+4eXz01p8eUv%i?%Pv@T`OgoW*2_g0o&^nuzfSB^xn^FUjOoj?=qaiJLTf2vXtz{khV!-(u zI6%uX7<*+0^;Z2W`{7eY=&r&|-wlnHWKV+P-eVzpopV8ijBxKN95Kk2lDf#CItdRkWz?7xFLu3bxvI zSqDSUa69CFXnbE#ht8P%7SYRZ{k0Y0Q;KA}J?_URs$Bs5Rj4W(hrhQ}1^dH2B4ffIP9yH#Wu~G5aThr)OQp1nE$El!J?V{)E zaHtZhsc`UR(omV{zvR6VN`wl^who2T%@lw-HQ6Bhc&_Ag3cEf0; zCNr-~WzB(xW`2U~TIFy+_1A=Ne-Vt3EuBJ;Gy$?zZLNm#pCu=~5v`T^a}O@w%bM61 zCmwD>Yv97SCwN$a`0J52`u%Paq>$5d_q?T{N|!6X1f}?IGXG|c6gDWyVk*1$qcH^4 zd14a2+z|v`L&reWPgVRm;kWy=H#It0SxzO@l_DYRBE9SNAMiGA$Th6)6T5Cpo{k+o_KtqLvz4eDQR+L-$%UWn zdL)@Ey4lquWsZ3!(pP~H+hAm~wVP&);f%>jKaP;R;=IqN>lUP7qy~Djs{KM((7P2q z1P%apdQ+<99t&mDK6DFvj!0VKeBD>cbEf6Z;D{DB1i{xjIiN|e_6qB9kiLNk13(S=XoS=WQ^B*VO(R1Fwl^s(tmI@Ne;Y zs3iM3^r@4fSXz1VMQK>UkKjHwecbabpb-M-ZZU;?pS84$uFaXn-%kzivRzsaBy(Li zkrJeM3`4~oSS+FEt-T)YJAn?ZQc5G%0QsX;Xs~b^f)!?J9ri@}BNl1`5S7Fc0u7wm zC}bh!Q%KkG$t`SB0=MXUm?+P~I}Rbc7TFG^$m%_3 zq^4Nk(&@D*rt*pU!yx@mlGI;C1DM-M;s;?=v13!Klpt%E@f}IWgo$15m%8Sh-eG7% zz59L($W}~ziU>R0EA=1_w4me#%ka0C?&_2lkmRhAc=REWmb=uPft?x9(l@){W`4`>j1x(PE2#1I=6S2C*6!?p8zs zOnT+#dgY0Z!l2~|&7pVPZ(8H_2H75~O5VSYWQ?(`F8yq~o_cP^9X!zGd3pKqu(-(u zoBWT;Bu$zEl%ig%POqAa00-RJaL-a(h_@(2>^;C8-%JF!W0W#`AxmY31+2)kpD`0k zYDHSWqN|z>Z{#Fs`ulL(Jk_*WNsPl76hHgYN{S70!NMXF>f*#1-pgf*P!wWkQ5cHipOXfcWqIh%B$ zEuf3rd=M25;g7(AI$c2GHd)>%h+gh$wpHGvN5f@aB2d(L|6S{X#* zj#xBl*uPNo!`G!w9`}%+phVb38ZBUu1&o6CK$x#ocZghoK(d`|*55>#-s6V$pq!vs zwCzVScMH44C6x@fPX2Sv!kd_(8dA#3j2tEu${H&KW^@LU!+@v1_CGMCZgG<6jYXJe z&|qhW4Fjf!bce4^62+}l{lTx;3_m*yn$D00*Dt9s{!gC)D7(IJ(0b(W?{dQnP%XW6 z17yMYy}mFDXtI2V9`k=7v8*cK=g>>Xco!__Pq_czJeV8TIc1}ZJI%kc6Z-#HfD1uK zc`3rnY-{dK1gpyHM-i<)Jjxz}2ihY~Xv?>zJ$2`g-bvf#Ty%|t$Gzid!E5H6%m5%r z6paHsa)hSWNqvz`#+Tgv_Z`PgAx_)9)t@T6{;0n@XU7@0_UJvNb=r|ovi{gA<5_0Q z;y^t(B|zxe=~>aAvWRVOE2vwB_1l@oiowt3ipXmPy_h3MBww=>Y?y8@OUl$mh&PnJ zGURiOuSMV_rcD5Mtg-uOJ?n*Gyjd-+e1LE#gTm?gFAZn;(^+S{>z}7!1)0A;ekmO0 zWvfshsqRUgO-k~HNAOYv-UL_{k4K+G?5T0tQr;YZPwjf=q4vTygOHDS-T@E*P+5043K z-<_I>27(5!n3pvD(v|9KV2-Nyek4-BiizJ#LD`-KYV+r}87l3rtpZvObm0M|VOFONyH<)(Dz_loipAfDNc`k~cx zeL>Eby&>Cuho)tR@%W#@UQw^fhHDz>brKGLo$A30%e@XPh4|~08-44Ok3<|uS+RLR z^5){fLwn^RGb4TfLY{EcG33b);a~Ty^j)L-zxS*Z3iv@y8sb;kVuyT+~p$s_vAYvC=)x;lHAu|ECT6iU0nMs?7FviMe*dlr02coAr1Q4 zYp>;iVpvkLJRzj`@-n^D4~!e|!J}ROS0`t(#h2+yk#?|-)7vMH-+)v1#CBWs*G2;G z;?B&tyVQNjyvE3(SXvvO!c=)%J3@_zPpUrrhyh$GLc?0c#!=>NOe_Z_$ za!YCI?0fg0-cw%Y?lk1_?C||R$&U_z>&_8NxYQYb&?Ount4bqx{?Ahn>u}?7$aHB@ zwwMVV<9~d+0(hB-P?`POrci^=&U{-#;L9bde5#o^)PhY!_A-7&@U(>3mV@U0uPP5-)_Ix(Y{YP-I4N{ z%<%&7Hn3z|xCTANb%!!vS7{M;@BK3Qv_Tg(Or2l#z-x?A3^l4rdN@hN2%)%6#`Wk4_3Cp^x6K%PB z<_%bpS7%|bdDmuK{|w|xmoD*93y$kUG8Cx3*(nJmM}2>P8&E0A?6}^{6ar<_MS5C^ zMWuUZY>W19D8fXl87it|`0>kE(9i1O_OEjoiSuP1S?H~|nSBtj;A1BgrDnN4HSI%b z(S+TQv1R<_&)#IYf5iSO1fA7Dj?EyU|Im7RD-M5678^-6_}>1emSJqL(4^x;8v7{8 z4!A;RaJs@#1&~rpe7QoRwpeZT#P_;gApL#h1Un$9WaWygl)CDl01-TD+S|%zf^#KI zbbhXFE-sBNgHeM+G{ojk)A^>bprby{vh`dIk>*+XZGy+^%{L82Y3hAp!3(V&3gx(PXtW zCQ7<8k|}(v7YG?eL4dT$|MHUcfK7H1u*t5s#LQ$L+GaRAGU$Iu&5bM}RmA}D@qr^G zV;O$&@8|zXj#DYnE4Y?F%r%Qmd8;WDjsaq3mI0IUoIhPAv6$wJxq zJ<|_Py;|9*0R|FCS{b&?Ypl-b1J= z!Ut3T?lPCnTC;wuy`6^TPyd{+H-3&9U$LCd-M00^3vL1QA-nO9e3t*pb1dE2FuNwY zp|b-M9sHR-VBGnEMHKay)WPdFHos6Y;dXYa+>5k7^vc={on>iH7W^@2BI@+tA}4bw z{~T7W{y5{B=7y=|aJVvvJ}R4KY4a~&S@mO6Z{ad%#GCLQl+|IGNRjdTCjwGiiadIb zx2eCktJ{5P{LGvwD_B*C((8}Y$A*;#CJZuWy*mR->u<_ zGC%+LR%eeJ@3G7JTRRuC;bJo27*pYxPcd(FfLIksnEvD823@0(^K zx`%buLc&rGm*%$qHAi|8q6~G%E+*_y4CO}0vh;XTH%NqMBtrwE`kXBlrT)E`< z5&z!r7OicNkB=|7ttd6@zz=o7uenXK zwIAOdte{q@)Ldga;hbwpqlYiQhZWpqv{}#6A0iWQzrOc3z_PWFqVls!@!P5HOlLkD zWKnKnELko#@~V0*NkWQMMrm%{6V!nK#UjkVpYyN-`X?4CaRZt0DwUPn7>CS+G})7T zRm&_*I!8F))&t$MtGvu74lkjwEQ`{*4`mE@>{e6+)97oyj9$xpT&MUq!-0-#z6gG8T*|G%v|A)muh*Te$wP zDcZKK%W*J3_NYO+fT~=tqK$;Ym$B(X#R3uem4f$`A-TK^@BTOJSn-wRa_4zLfet0c zyxcA4=oY<_Ij9X%<6Znjd_Lc5xv!4bnh1sXEwx&b5OM#B3Mj#U*jt*kMrzIv+aYyr zqJr`3Bi4#E{`4D!K2*baPFGe*S1jGmCH4Tx{e}idXnWvCJ%zcV{muhZ3O0W9HzG8b zb4^%Jh(dKS6nvK}Ijky1pENP+Tl@M~O_fDIGM5@V_FT%#T^s&0F0$diWgBSY+!ys$ z3dVC&yT#eD`}-oim{Ip*2`NuPV&9W=nj0$#+WDN>1L~W3I(14@%&xe`9g1ZzGsCe2 zL^MUSJ0|>0EAE+_tQW@ft5EwJnFv zH7+xI!^5`H8FekkhAg@N^~xF$q0syKQ_cL#<2~6BkYM{;@GVlschwc1 z_$$g2Hly{Cea-3rl@39ubI2}O^73MN1|KimKNWR*mzNd}uob$l0``83?b9rtLRkGI zSMC}9`BTl1Ug(-L&%jKuEHUn7$Z1tg{S8J@=aA$8eJ)}_(|-c?wArDyw$|Cq-Dkuo z^>w!#X^0~Kj>i9#YZXr7`Ft`GBD`>7zrf2rUbyz3qxj)_4#Up4;2<@cA8ONliKh62 zqmX@3=lp?TaD2Ctsp$+sP2D{yGClOz<1{bn;TquTx&( zkA7Xzx42%Y_5N#9l-7{g5D@dZb_3%&@zNB-Mh zakYj-_px}#Y5Jpo-s$M;Er>6I-E79X+*Nfi6RFdWyZP&q4E(`&eHOM@_?AqPs@&%2 zwDeE_eJPZm;=TVdp4vO~OgWH`-6-SA#lW!X!sM@qwi22RJq5w!0w=o&XDK%c>0ajTWAprl+g3i4Q!qY`*C(e@4tG7K zu*s^zYCw!m-K+m4sEr>AZT|3iaPiU>kM4ZnUXt&@LEQ5v)y+;Us6LO~?^T)mtnNG-EkDzJlC+436_G78g zU01GxZEjv|Qnv>d%?M=U<2-v^Pr?V=SdG#{F@>Cjht2daMi%saePM`?nCK z=l}DjUyPa)O%CS&Vs@Gzns?AT7X5P`dKEW>(xhDm-2WFS`YtCwKHj*?OJ;a{?0A>| ze*uk)&*qWR=PaJrvL}O*>T%hZ*O)X8KRy?Jex?j&l~a!RvGU_9 z)k;ZrfZDS#E4i3lvwxh*y>eP|cjaQ--b(PTHx3Ba;C!WZ2~d4~eRq9#40>?q__C@- zcx)`Ip`oETV;$Et<#9H37K8b7Vw=&~4z#p;1NC22>VBMayHBx(W*25Ba8R5A3`I7lMqmG4oq!=On8Te&JIm7=Wl$Ut<_+}O~g8T9O9 znTFoANCZ!=bH~&>%Z!7tMzypeW59?qIL)r%6&DKGf2k^J7G)Vx6s!LCei3)K3Bsh%s<@5{zShqN2PFeJ5Fa;w@|tGq z+0(ZHV8=^6H1YH>FBaW=B=DtRSD|z+2y>dESKaq>PICW4 znGLiun~^GQOKPn~zLVDUR_X5(NIIDQEv%W zLR4B*{>7pXc1J*_0~Lz5ulU#iz7=5-Q?nI+SiP=_urt2ebA4^+0r{=4Bm1Ag%w(;%v_ZbHaIOA~n^BuCSSSk~j3-SQC z)50ncY~u>OSiawQcCx^=n@XXGC!k1g1uP*QqIwMCVJJ2>zRZ52ma7IAs|Wt%& zlhwA4ts$Jv!y(g|`@In6*zcf2CCQpTm{2$pJAWK;u7lGN$V4g?S2cOE7`Akh<+y-W z4mSYQX5Xgz`#wegyH_G>L4(_)$m_ZYf?EM`H>G27Jt2UQt3ClTL{GN6o%vzp6H(SZORvULo);a{sW z1kET*#-~4hh7yPduJ*W5tMInvg1NFgFC~%u6)aV%F6Ksy=U-UpgIWH#U*)B;wx(LAxlF2H)MQ#1P$Hog?#6HmXKxIUNbv9&dxi=L!uSeWgV0Dtc8l!NOpE;b9~RN$#;^0O6}) z&lX6kH4OGuOGYMB8EG!m@6G$SA z)}D}A+=%~0v=epK144JH$=_eM;0HgyCd1jz;ci?mV;L2h1R=uUAFp|76yXn1a97JQ zoe(KLh{|2@OvKX_@1<7wKp%&2UHR73D?Dsk^56W!fcr2P7x7z}zE>wgCLa6FQ4kTU zurBV-j5ooP1fP6kK8l1z@DHl*QlSEKO9b@=Ej)M`jcv3=a{FF3XhIjQ zZdt0fnQ?<qcV^Tt^AX`I>*$L zGHzd|nP1KbwwxN-`=7j9Tx5%@!)ZQpSf`~`L=Ei$M??QB)2qSiwA< zm&tn7+WooTs8B3HV3h%9lw097mIjMjuNlPW(V9!mx44p?M=HGHH=2r1kTSQ{m?ZDk z_*^$$S9(1#FPn7=Ik{3hxJsDT(hD5W4}AYpoOmz?fr9ngB&xNzXSmu%@eQRkBf(1g z349I)9^z)*9G?tXSeKJ7)o>F(aXjwt3R15X24qdg=~e{3x)JzRgX61y%2+lJ-fGd- z{6N9iJ(1qpe;zvf2#P{Z2SD=ypCpba&A~bl>)=fQtX(W$D=yi^hQufZ=gAcU%OtxRmfSKe?YHMud*u z4iOZFXO|IRc*hzf$mwvq#=M`XHXol(lkdr%ThXRa%JU8S?|CQwYVZ>gJNak8fp~aZ z>6GfYza#@({GQ$PDqv>!&cfv^h|ObL@95-DmTc3F5Eb_4)JY__&E^>CEq#?TSVAC8 zYgrd$u;;A-M`#YdM$y2YKKj{g;b<}tWAG%sW+&ax!<+@;1`LA5{EzOx_*7@&=8TsZ zgg)BE9k;HUbbVt!MV7xV;7Fv=Z8wts)08DO-2rJj=SPlvNn4wMJ^hhdOg*6l z@0B4&X)64eBB+DCm&?XdOv_7JRu&*{s>@IW8n3zhL1l>;iuD_N19h(b7Agc=q{u zk#Lru2R|^J>vr0-A>|8#b;)}AxB6bcWP5pjm1`Y&7XdY@1L$8Nr++y=6$IsF_ZLV9 zQd+1sNEfYj6AkW#3~h+@cZC&_iMH7c{?h1#E;)no8ItA>c1rrT&O2<&h>ANp$u-Ci zv8W*Kcy1(%O_0JuYmBy@b&&XAV7rsRFPxGBYg?C?aetW~axozx+EF&A{h1<@P;q01 zOj0OUr$9s_;mi_Qx9pL9tw(Na*Ezivsieq_DijEj^}E7uFGl$?TcNAc`NbZ}98D1x z_mfOeG?pdXwglLtC5!E*mN?5RR9P zD_Wm*`xH&QlMQS>{cc`r4|A$H@O6OfDXQv6-(07nP9v9~7MOI~HGIDy0$N(0uDNU~ zyil?RfEt!8TT1Y`Pj&hmQAmv%|K~|0mf04_x8l2*{1hy}g5+3oZavV^vgJ-H_9Eoo z&F1#X07YSWZkWVPV6h*&UcOs#;&9PBNP!JhV#rtNh(96@*uS39r*#~JmM1grK_vDF z73nZUh5c>{l$vp?G6}hIrH=r-BfdCpnD}h+e4j@_Nm5>*v1Ld)BdoqvIfKq8<9%j@ zlkY;2h0vI%??YR7ZFZ2-qlNzrPzcZA9*hcw^tm3oUzOcTm-y(Y<1zOXQY((9(2Cu_ zQT2PCDbhfKSQypr1`#l%&*yG?L-36dO~p!ZAh+O5?$X3(;zDGBP(PMZEF&JO6 z>Axnyg6rT#2`0PYe8q=VtMRS5G|SZL1sC*sUw?y({MIBS9HvV#y#s2$S~l9h5v$FC zU2)*96)ayj1u!;jzGqOiX77BqZyqo*B zIO$~45cNj(Xz`7{+;*2RyE`4OXIk46Jv+xp3%9HK3~DatUa5TdXW!cXbst}@o^+o) z(f<08jl#d$Pj^$V`P`m3nTf>prhd4?(s+;-!?2T?WJXaji#5*QnBF>LdmSPOg*RVp zj2x^m2P%cmmJ-vyvY7{7VvyTZWY%2iT}xa;b06`3I_!+ZK}S|OwOTfj z&b68?Qzp^javXvqZgA0rB9yeWcxn{FI{)W~z@R*;(x)3i7Oyk}E+a46l*N3qMO-Cx zBy?3bX@0R7vqJ^Blk2N`1z+2@2(s%m#R1hfX_7Lbcp(PFlNEclMUNEex%ue_I*pCV z)bXWOe-sSK_`mP}kh6+jWb8KH#_h+sEMWdG3m|*?vTwL0R#4ghA49#JM#_1qM@vI1 zFH`AtsZ8~GOlEie$=?(n0hECxw!PUMS?D|`g%rCju}Y`-JqG7a-0okER2P@WDKfG@ zQNX@hM?I!)WanHH&Bs4hSo#aD62`F!yDCCoJWhSfHKbDP#jc0Y=6z|5*3YOCOTD$9 zm71yV*sM%P-)HTwq5qESqicOe`xAs+TFewof}L2sSZcdP)N9c>;4U}&Iot|Ocre0} zSlA3Q_CVT8CR2)P^0sGRF>e49q}S)YtTAtikY2-(g)+#L4d#A)g7IWap=|bvqCFkE zjuAUl?_I?U#wYhcMmHB${t}QDr2^%uyb=7q$7*LYr~HB;S_pm2(5t$YT2YHJ5}f($ zveOk7B=wYNlT9lwSGW+wiXBD#5bhnlS1>eoja|ZzoWN~ zD|Yrn6>j_U(umkv6+s02CD8Y3N&*`yo+Oa3)z3e+37Se5H8n$$uj$R#WmNCZZo5P2 zJ1gZCg(sCTmtZH4+1M{vhL3W>6iat8QlQ6*Lnr?FMq{@r{H{tW&yEezfV#u1iw=TP zrjxPX==)!LbdT-`DaP0;6iJn;Q6z;D|KYv>&5qH9N-37&`#%qDTsD(1@Fvkf@8boR z`Ii&-HK@iub?T9N{!@~@w;phU?1424pWYVR!|p%CFk;_`yDtPS;;Qadh5kzk-G@cq z{P}jb-3wN1fkE0Zj?mLvY8Vj-6u19M-jQ~)%AeUYe*bVm@;tXk!rS-Cq#mac{U?WC zhJt1=n2qaGyVT@Z}&rP>@`(JDY0OrT6oxyMmDXhr%J zUz;wTS;zyicx)M;ikLEL#w*>F{5JETFtok2@qD^+rf=EnxVSYR4vj3 zVEQmmdK`DM3B6`9R{7;ZSYM%yzKC!;KIuySY-5+}PJEyn}ac8lN6zBMizeA+U zl9KX$0=hsOl^hlG#~nPZL8b8JJIqnj3Wl-oGspDD-_;Ls`UWU!To1)M1`pPWthq$u zIEAb4gS%atKBVvudx<)j! zD#P5Ez(Ek}uTui;CVkrg3qBP-CN^}QU;c_p_nl8=ty;E^bDn%8%c-A<<_{rFegA^C zSL^1S_1*pIZ3G;^VK3b@odI925f3S98B zb;1udw4q^-EK%g3`-e1Y=(lVBe*vf{n-z;i+L~!$4kr_|f$+7YQUK-2v`1)<@sX_O zWduE}K2#ZtW0{yDr7$_mc{}(dqbG^)TBb?H`H>{2#C%cWgQ^mi^XB<@rQ_Tz9uetrIM`Aud%wB2N1qO_aKN93n z`vP3%>`c5c?`0J`q`U5i@|1&03@249O#2tIeVR`8dA`kBIw*m1CPA!7?K->`nOH*a z8iP(#{!EP=6@9Z)vcpGoZ7zPrz92jc!@;C2llsOh^D%Y#$7v;Lq_bF|Vh+GIQsF2w z5!4t(aE>B&)F%E4B-+In#_Vf4C^rUnw0QIvr2)3@y<>1lfuePOPsH8UDo!moH%UjTx zT^%#E3xuF*h=TkBrseLoPBqbxkK2$?-J10(Q(k|98WOjI`}#x#7P|WnMwdqJ=+pxG z5xa9@N?~)adh9sp0Z3P-1ocNZiWL9!5ktG8&@>;nSwW|E0!cBa5;VZmmt;0@C_1aG zcFgM`aeB45-uJtGuP;v%ZsFs7t|+^g%*M0GrN`@UcAht4Q2-Dgxt7M=F**5Ty5j}i z8^t`OVgw(GYDnFg0EZyo^?qxO2dh`OJ>c$lTcmvJt$1w2^|O71_Cb{?zZjEBo_5d3 zy;H&bzYkr~+B(PmZfW`r(Au$IuU77A};#;Mr88SxId3wKIE z&U&?9{aDaP*+;p>x$^CuiS&uqGIfE*i<8aBS5tjt+%1}e84&9!9}Y&T%YW(N7m>SP z&MHDq*g}V((wyG-$~g67-er5;sWsmZcX1sA$wxlE=dmyE#lrK%?&;LxfV7Qay?gYn zV+%Dz_Ql!hSYCi%4h26yPmYUhzTd*zjnJC@RRVS(rXnOkJ3-zsKwt+NcODxh(|~o5 z0VcaGGa7D=Lhu|K8$!#lbYf$@UwZB(qH6g^O>;W1qgXs6=2V|ADGOTkst9@q3N%M5 zP{+R^FLS&W}54Mago`4vE|!a*8?r z%KYyURr((qsIUA5_5G7&3<8=p0;xpsJ68hlyLY>6qSG(QEx1%03>J1)$EDBzKpoKy z3cjD59Lv$gHdk$u{!a&`k2ZQ{4tiRz9?>m$#|x$dR)a+GE!AqIo#Wp*@@Om&9W^18mfv=s)A3QRu%{VJV47JH<;u&LHEw0XJ{ zQ>!iuh?8DKayop|nzAC(38agEtbEhf#zG;}Y%=~WaoZw^g0J|XGGr}!>v!P?!*0Kq zs!?$5{5F^4ZT`vfvE`Dg_1?49Pz-7HSdRhK;Cgr4rukhTl6zUdgnHT!?nK?}@mpMM zK5~lSZB5?pPNYx#c8I8gq(oY4M_xS9eywcLQvZ2^f+eh5-!R7VqufhQzq?I`1x0~a zRuaHP1#f2b0^63etG+1Qaa*8LrdakWDVbH??kOX4NOm_Xn}>5xjrii(`xhvswo~7- zZi=a^pp1iBmTQ|+eH&}rU4FHTj_2pdIuSempWuS|11agr>kztSU};nDB-3D$t$A@Z zSV)pBCo8EfDx}wN(?TT4_~QB97=CE+4Te?-OWH*bzW#pZ8a|<$U#Qi!@w(bmAfxs_ z4fPxOVC#Dv;bKGY`gJUt<|Aoq5<5(ew@=eMM~$@@@Ik0#RAkC{oG$=h31?_G<(* zl-(biV7}#TwHl<-xHW-suy~w9M^oJB(Q=UX3ZQ^rt^N0V-NMeAg4g?4?F4s}UI#-7 zL4%4iWiwAry_PdbO6pt|N+pffACep#_&xc+77;=E{>g29>{C`%N$<~Z@(%O9_JJeX zR5$C9EfeWj@=43Jd$D8J$BcnDF-<2d7PoVf_@~+-eImM>iklzPVgD%T2zQJg2KOvy z1on>|jPmf4YLF6@QC*6K{&wE!PAQw9*fh-N$cQY+>CInB($+@CGo>_^jixRV5A|~r zlSY`z%3Mz5l!(YazdI5}GuqO${H-|J%Y*WTKNqUBr1=cq_ZHntG8&@NIIJ1H$F~q4 zL_ia!fRB7=pe{Zi^+q($TH|dha{mLIClgQG?UmE}`8!@uRl~ikAe|$>m0_7h|I=a9 z3UXhJr|==M-|$A!yPl4}>`{b2uRg|r?yB{b#F|6LA~#3L$T)Sw$L>R3(8}HE_@GVm zokMjZVv(jh%raw&YPl$Ogbz*9^xetVjf!nm%(H=E(~auh!OTK*k` z>QL5u285x*fq542-vVXDU4RiF#wjC^NvA(IcNjB4xX=7EfQ>cK>lEa0m2VvZvJs^y zvFoQ9!Bli$T6Zrq=wl7MrtQ|68{V<<#Ovn84EQ8}@JCx;(*I(nPpW{yhrEr;D&mOj zg%p5#4E^t><96gvG);%cH~UMyWQ&jXWz}e%@}a1%j}z7N%m!jYe^51Etq12tgkhgb z^LpRDKU|8)@1%;muXF=8hlz@(f$Z`3Oi;Ukl$F7zjZSMhy28P^)rh{+&fSzwamZtp zspEx=`<|zsuQgzdj=Qrx%eXH(-)aR(EH{=Bd?{fgInjw-8zt`D6*Pk_A2T+ zyy=*j?J&RI&v?i#a^u;=iwh)*V{KF;TK29?Ro8fI_Z5zZzx{XXZ#{ud^{G>HF`Hk_ zZ2d05llwYdvt3CP`zz8soW0$fJ?~Pa>>s=oKO3Q_fct+Fuws2J)EnQfU+iu1Jdfb% z?$JI!vvY%Fr&7?VX}qE8BA;B-@boVZ(@wZPd)V~L?m13K5B9nd<)+>NkBsacByk@C zoyH4belqKjPCJ{+YI{3PREN^4jx1}z@>7(7wh}E*<5Pnx4%)-d2ckmhjxXrO;)hhJ zy>lNxe$^wV5g3xj;`Q|6Z=WKk_8FFChfW}Ilo&tx90SbX8=rFD;sV}Y1jP2+LJG!G ze_Lr+p6v>n622i+Lath;A)HU!1f&{>i9e7QHENb_f1>mk{L* zSz~d2Cj9L-boLA_`t>7))5t|EDru~*TR|>zQ&K zx>Ov$J7;Ys{`p+DcC5kE30noEf&_)AO}aB#4bOt{({I)ULZzQwjA<5E^n=#t8UNEV5zCP~TK;IHWb_sK9C zOGr7lFGHBRzBYH2dcBW5C+5B~h}~B^rdsX$R0;U6o4s~>QJ)xHURo5EoNnLRI;{-* za&RQ~9e$+<()~%RJhq@a#BuO*vQBI5U+A_JWeg|}P7wRJ`)Zh^fl&5TU>SIkK@Oh}-pU@%<)xmm-NZjx zr?-jUU$bAYiMP^_(ry`>7^(4bdXh3b>2scE*#JN|pEZ>d<&Z1a*s5HpwRY`D@^HB1 z(U^|CbqU1a3_s?q5;vI5`V8FqY`dI z#0KCC61B>?oU>1r27d(1+EL;=SothoI1V<(icG}o(Q^v6cV3`MNK)UvYQQS90(+Mg zlJKua&(r$PU!-c#BmG&yk!YfUV`<%*X}R5qChdt|Q}8RWjx5^ofmA$Y_#E6UE%3&{ zKLm4_@U|MvTSf&(D0y8&ISd53(u>Q|j7(2{O*3>_!Nxd3_ee|~)k5hdKTzz>Ex&o& zbr;k8XVP+C=3EHve}YFp&aXNs^GAQ7MAK0}%s*-E_pjBgj$xC(Q#rhpzRv?g5R`|Y zPV@9K+OOn}N4NY2oVW!42$svt0$dy*tFfy6WMYCk?^gz+eQ7@iXZQu!!LvL6+hd2xS|*r6Pi(1Y z%=k3cLn9;n<%4)j9bN+DZA1)r7nDktj~_3;;!1B4_b`#@^Z;ibQK0?Hrl4&<&t z>D`o(ZZWoptu+BX4>gP;PewC%1c z@l(MWS*u-9-vGnwSuHzjI7rBDGb8fPnd}$Q`dz0JrxWh;e9q3$IK%Sm-ff`r{Oy2m>~1Hn z`${Fm8zC_kRz+kiQ16S%JIi)OC$qAPu;n6l|K`fdRyyv)*qQ-trQI+%Mk zJejKAm!*EY+v0*@c^d~c**6?nYFS=Ar_kh<=gYKZjzcPH+=>8g$I+??M%mu-Hi;|v z>X;&>P}*mV8a-a^9@A-wT@TTP`~$3}7F&JNZSQ(tq0^V8R2#mT51xnEV~;$n+w-(q zo?yjk?{Ow|Pxf>?PT;_>OutJiuU&U%z_`bA`b#4oK>7KI%@=-bn3vQ#12lqCAAEHU z3qD|^%3Nn_lD6h_@rfb5`KOm7-I|_io z`w&f11$XA?E~6p+>e7@!^i@vsppq_M(J`#VDMCl4YgIJ6I{bXdrXe$GyhYjGLc6*I zU#qfQKc|2n(c=2^v-}W!k+>Haw{HaQJn(}s?{jyce==2ft0X)?^t1D$Ee*X4M$ST; z)~nqf8j}rf1^NE7-F@yz5p^Q8w2$YJay_e&UA2bPGj)NWVEb0-G-mJ4*X7YUEaIILb;MFX4?fjUaplc zgvS-Ay7y6w-iz{V8ab5$HVLH%apeB!!uF-tKFI~p!2yRe)T8c4OvX^nQ6K<<9M zsl@q1U?C-{hy!UxyZcZ&7M@`TS|!v1KFo4B{3yR-+{6>3Q)&?TWKzy^+8Qiw7&3W@CRx4h-6Ny8rkTWcrX4gvQVt*`Un4w;NtMh5iHs2a%1g6#2Uub zR%lJN*j>Kgk{$H}z0*gnx46dh#}zGm9`(HMy@0TpwvZGp?>{^yEXwVmXs6A$&JI7D z&|JQtU+7upNdV@9&9=Lq;+{}3*hF;x1tzMZt85CvXsFdu%ahm}cF(d$%@X%PhSldo zGG>MsJ<}wSyxO7bw>!A9ElXoClBWyck=T-=StNApL{R~`dYQ=+etGaZw?$^bpWc(y3Z}b8N)t;IUw4h<6&j(1DgoL~rHb9uJXxFXOY;lOgRe*;DApq!Z=M>I?d7id$`amL9r! z#<9vsDDN-m(hdB(=KCU+6LDU~J+Xw<#kfphu~+UYr0&w2|VHKKZyo+>qDr&;V% zSF|gp9Po#$jMz4%=#a3PkHU^~j{(k1F$N>G8oIy&8Cln>e}5nAz{wFI$XM-yT?9abv_Pt9y1 zMvDWZip?yJ4rxWL6r)DYlycl0eqxJV-!KJ=x(0X}OF}j?{v_x#>wu4#+IEVcJal?- z8VMV-Eb2j6wu%0h; z`UK>X=wYq^MfWS`l!fgzCHr;GNfw<(Vl`*t(-@HI6>$RDIQ!yM<;RC<2?vF=&LmFk zE_AMH(wo+sjvl9u?|*GgO@N_-X*cgpRdzx8>g#dQDYC=v{Wt^R>d1jhsp8AGXco6^ z4d|T6wlTOy13p2Ck=sr>d+KYydp=*u$@&b2WH;tjAziEHDKa_DHji`n1zeQ}>Hp%<{|yR zQ(W-M0RO`WTi9LnUIu4kzWA(p@^_ZAu6_OoCH`0!?<;W06}|@0x+Il=dkEy&V7H49 zH)-{2CLf8U|3H7+=LJAx2qK)qyD>$|!Jgs()l6`Z$O-acex4Iy*%|XowB}_tMs{bj z?49j7*6)DTQ2I8!*5c2lqEz5~hEg4&xSQgF<_?AeN1vk(_Sn35zW_+&(DNF_P3u4X z+R}ED%YxT~S~7xT*{~(UAG&<5m7uxh{{WcR_vD!#^#w-`@?0|SBNYeF=IDjV^7cdE zQ1vp&jA7KaZ0KLVUIpl}bUFUtRk;Fs1X?XU|(!_`PF6d$a*kpswWk0;YQX z_-!-`(HVS2OCMs)+b#fAncUw*xQ(%x9d^v!EAM67E-~^0%}M4jB^QhtL2IXTOc!Ct4u)!r!HxJhQ%yFCt+lZP}MIgxU@5l8LsZ~2ul(6cw|0C?Z(wHibCH+Zn<>1e?JM5G zhFJX<^^PM^A2*?4^SHm%xX8i0Ea!we<3a@T%<{4j&762*37GL4Sqcr4+W`)Zy1mL; z1Cp6o3MqkIw7LF4HArV$&U(?>JJ)hT~2*Sb&EWMG;L?0wTXzSmD67)Un=rVlhxU({82qcGHfKeiUt*( z&x&;!F7UT}rd3MWbQ+p9Klc)ik*WFTNR#5YSJtk&Jgx7D9)7-oHai1Dw~LcOyGtZo zIRwpIjvNH|ohR&0 zJ8;ekpu}%LjtE@Y>$vXb~7ElIIZ(V$z>cm&#UV`MjKim>-pKSSC3KqBc z29pR>e0MT^^7$c)<<<70u;s9vV%nTv{N1|00w|MniaDRJs(2#-lv`{feA^UA4->11 znP9X=A=MY{I%se+Y%JG>+rOK;Sb6u1yV|+7h@C?BbMQ*2`^NqNi;s{h;)UP$6!Anc z7~s9}2ILtBPPooq!v1}%s(e`Z4o8r`^LL==S-bgvARLu$p=jD{~` zss|#qq9Skf_~~FbuY_4~QI_BwPX&XbW#A|H?u;OV0jkr(LglWM8|z60tRWfcP?Y?v zJ&Z_Q>Zwsn%aE5rVQ3bao0)n*joyB0AFQZOgArWqIt?cfF_E`98u5Y)aFu%Q+J!7j zN*@(@P2NOm(3k)234#$-{??F!H>VXt$rfXlB3+>LC9D>yb%z@mEco`hwRzk(giecN zol@l~0&0kVo3A&0-mT0m_;u(aYIvSdqT9khD$>f*C^>Br1%hRj{pB9y-#vTw9`6I{ z>O8yOA@9>9B!W5_wpsng6m*wPR!cb~60*ZMMW<_ComaL{+EkodLO26$UP_SGa5T0~ z5y-iv2`5oC0JqP?AaxQV|HH2AAB3eddE=F40a;D@LSK7rWnABTe`VdTMST_ZZo){* z&h-@t@E48__r5A%Rd3!lBDRK2Gz6cyaRC%u+wiyVM=TAn7Yb3S6o12MxMn}zR{aj~ zVj9u^ZUu|a%nzj7O$IpU-&YMer`&Fwe@VvETVD+sjV>0V-VVPyPk)G04`b-W&w#EI zkB{4$uHFH-o=lxT3Yaty%e~|HZY`nIDd!whuAy5zwXlGG#^F9P)w(DAjHlB?ie=bq zD^D-G)&*ly-gGEEWvy{rctNC0x5c}=Myn+_S$g)ilr}!`by2=`lXr$DAIM*=wBCqo z7E)EyMZj&bMNz4H)!A8ccXyenBUl#0sWlsl;CIP!0}9EBZ%7OF%sQc`)AmpX65B#v zc}%*EX3G%1fqQQFh!{ZjWUw|$(^ejs01_id``LaS0c!Iy#n;dThvvNJ8~ZF)iU~h6 zyvCZ$lGj@>f9w@k915o^kEZMdf{9t^M|4HTlRwM%f2x*R#v<)vP6jTxR6SN!=SS%N=KRX zrq#vz;QiQGXT1);9bEU%S~;G}LyS$Qt*>Cw@OwHK1Wz zqq{wE;$}R2V&#iN92UGSsVn{O?+=D;McQrSEuW+Y^`sREx8uJ$4Bxt>r7P>jXxjdO ztE#FOep9_anvl17ta`vY7;z?Cxkh>MnmE2&NIt+zA^NNnIXDzdQUHu>ZIxlzOA(O7 z)}p;3xrQ_)Ok9z)AhIph09c?^O}x&nRzbi8Xnsmr=-as6A2B3chaRe+@5{r0#8}{I z%<7+Zn1n&mQmH|RpZ1O}(Ix=T|BV;xqvnzeutGcN(iecoau2da;I(4+Qh{a#h#K97 zMJo-x7KOa{&N~HiS-m4ADd=B5N6xRO{%rs`dB&jD##IL2T81D0P(qeM_2|{Nj>jSo zNA31S=kQi4oSu2{#Zc`8wOUKDB6y*VwxV!Dby4zQg*J1D1sTh3@c*OfyyMyW!}i}+ zOKY~ZDcYJr5m9@zS`<-x$BeyaYXof-wW>yl-P(IoGclufQLBpDMa|TRkUZ!6{C>|L z`6sXZm2=ML-1l`~*ZWqlFqDm2%|_5Vk&65%j=Ed1&nQN(qM{ztF+175e;lM3udTIN zy}_@gukZ&2a+6=4f;S#{E1ii5KTM{6cFV?uTOtF5ixB3B;}M@Y{xUiPbS(5T2;+zJ{lK$>!t#Mbl?5(+rP`FoCQb#E{s9n6!Lq6* z3_$GUp)4;v#W_F?*;hxN?@T?P(qYy;R7rm=8_QZ<3qPk0fFT*HC~T6Ww`iYkf7 zAIH4Br}KiHtuVWe-=w(0&thBQzm7bS;_ z73w4Qrv3yxbZB9i?D#5i zlZ-4}#}3KjX0<{Ln$JAa8pF`km-2e%J4z@T)OVz_=6lGsZO;1^nRcehsnbuA+;}5G~Qy_Nz<;Ooy?l`JK8<}2DUwq z-IQ)PFt{?>F!-;&ULfeskXpf|-8h9u6N5gX*mQ%t^qMwCeT|;fz8_S@!p@DoHH>3{ z!P9lkI1lg3uAND6pMVd|(%YSLa@G;2j~jy@R$od&*Ry_~i6>{V7SM|~9(-3vWlIi= zF&9bijrIQP@r~mk)tpr5mYG#)i}6pQj+4J#h_iMj#f!rF`TKlWnNCl;v(T2WB3ONe zWPDv4rmP%p;~a0zh23(w!f0EjVr6JqDqL2AI70A^g=8P89@`lwI5*(|X>b0>sDDOm z>BXUg9-4PVDq{6!f5T>ut88JGhgg+h*N-ljB*a{a7PS=pq>dqWV17$}>_<&{VM+v*9=v9V#T#L!|eAot$#}7l%Jf* z?Vc$JjRAk+7``I3?!45I02E*p26r>DYISucp-L#0gjS-lQR~^|9jkxF$S2zulsK}% z2OB&)Cl}u|s$iP5-#!$=L${7Jd+cvRYhgLZZG2eN2+{d6igi_9(#U{R*%k^;s2320 z^nG~5hvr!Mz12_gl-I<7#2Yo1%<82Jba?#+e8}N;$q~}}u~4HtnE5dD_A@AP8r1(| z*GbVMD0J;uX5o19;+G%0-wsvlG1X*%!M&weiQcAX{DOYlWqEgncUxfqrJd=t;$2@~ zo*e@&{Sy#)!5D6sq>eE<@D*A>rhq0*)B5`0|Gq^Ma}(u-4Ycn(J`o#41_pow6AcVQ z(``2=KUW&zZ3;7asvTmhf1MSI2ML^1i@C5^Gp!Bil;a$+4-ITp?pYZfMT~_rRYR%c zf38!cc#=Dq&(ec_q2J}?HIC7VoCFVwhxaFzz1NF>@Srf|DC9Fo=*Jnv@tgd-8(2oZ$egiPG96N)MG{2y48G})9~v8l8~um?C-yXDr*SXx7FOG zWO#p1OY+AOh+~uvJ5jwrP&Ve+3{8CRM{$u#b*k`-Xl(>R?X8 zbH=|T`aNBRI#Wiy#fmyC#3R#DA~}v<*Y4eg84Mn^=vLS6B%G^B#C#e23=bfH*?Qm{@fYd0Dc@<-9RSX3d&h=1byMD<2{VaB z@~+0P!S&s54e!dvq=bs6PI4c-K2M&Qh*xQ)su-A)l6ddrN%a!*$AgUFD9OT_| zdEE6T=9*q}a95cPOJ$yvE7GaUyBlCLK^*-?5YVdIiT0qDLGu7q%KfMQ$2;6Fi{ESZ zIVH>ILNz2aH?;-yOGz=YUDeF;GNyQ#-$BaWuBgJw|#pNg6WKp7|Z^&;%`J>#pM@%zIVBUlq^q?3ppHSZl3*5== zCImnc2>FLr!Qb8LV{Qxv0p0UwiZem3S|7C%n!lu1X5{fm=vUVss-j&40fx60Zcr zLaeCat&MJ$dcchf^$p_uacnfdscwm}9?Jy^pG~f>IZyE!#|+F(Ccj#fGXT&~mmYQg z>^$5+wsf#Yc!awrj*r|NI7jSh2Pw4`T&%hlzx+Hfm4B*zB@H3vpxufZ^#(19wE5ogso5Q!Ka|W~p z3x3?fO21ARu(&+oGVn1AJ%>iM)nCVahqGQ`H#hA{B`E zQb4;?^dVnL)-ubb56Oat&#VkZTEt0;NnB^)d&_#v%WHu3a}g=hgF!EXHUSmq`M%O5 zaTWDa7ust8CPnFslhqxSqNvb!;u5MO#$znKx?iM!(+h!gNP*;f^+?JVkYBC;efK1I7wlTcHsOxCPXsDS-sF-ab`o`$!y> zM5ax~t{mK_(DttVu`%f|_}7`@kQ(=U4*HuM=5jxOq8>zbSn=@Hj1cd38qyBUn+UFMgF-EDdb5;WZ_%3z=0D8LWT(d6pX|BN>zq|L;U_E-brR zbh}4@Hfgxg$T_Gc>dzy>tgPn`G}srW}@vKBSs2{ zJws*#u*iV95LJ1%EIkF(Te8lY(a>yrmuZ?G@g5gj@_6$nYv$S_=V)~L|koNf?W1x z&QxqFO=crAFKrN{k^Tx$NRF*Hy49AP#%hL@XL^=EYfJp}fNWZiA9XE4Q{?mC7!7XC zicdqpV&Z%WP!H^cKQ}>>hqohXkXJleRc7P%nDz|kL=GkzT%?a(CPYumI9;k&1i#qf zC^}Xa)W-X;^#>O)=%?GtVo^FPU|7u9hgiL$(m^qqO7UL5trC3mWI*GnhS>aZdSQry zSX*^kgzj*Pb-wm32fZeH@>+w9&lNQlfW5zG`>^enSE-?3$sl=ugQlAclJSe2_G6|1 z?xOrz1&588XcZ&O65|IN{oeQ=_`CC3_TRTqeiAo(JkyWuGFGpf${m+mE#M_=2{dn$ z6?E$U-eNvM_`(CGj#|To8!4|(U{UjnuTrdx264C6zR9`pXDl7)A<9OZHQ~(oCj*OO3(Rg6ahivU&Tb1<) z6aK{_-Y(CZ@nL`?nU6QUHRMr>7vH+ZgWS#K$)i9fEU#evOfeii6@E4Cc_4f!puFiw zYmsX@ZO~62>BhIg-e@(b{c|xp#g}$aN-rrIway^aM!Dpj2{%1o(dXR_43T+RG@@ww=@@FUmM`RGx8Zd%Yx zf}ea=LjK*B%I_KHA^AHAFqQ#XEQ^dTpM6~4$o?9Fa2>mSS2gVah$26~_PRYN^QHh=5(lg!-#>j0-qHUk z%Jvq>4R@^_&VP#+bsZ0S_k z!x-{rq1$D$63XJZRWjA*90sMpS<2ve-gT;Ayx{Ox9g}{x^-PqZi}W=^5dY?meBh7S z!-vBkpAM{KR15kTIG7qJveMh}eyottN6HCK3ag{b{J3vqso&xUVDV=LN<}ClAgl~_ zO8`#tB5&@rk5|<&#zIPEA=|c*Gx?Y2s=N2e65}Szl1A1BEHu|M%j;+;1K;Se{_u3E zZoMqjZAJ<*{sC|(L?7KZZ!+UM49anjL0=5klgbb-s`klc0U7`?eb6@|Ir=aPLr~>f z3>(lWEJ0YDaRX@yYW!5FQfW@V`l%8+pPug{$B_K7|GsG;2Cds4MyIy!I1KjvrG$*m zAFZytxSu~<6snA^ql~oay?NhGICd|0<-A&0sT@;sYCf%))R>@r<8w!2yo^K1K6rtk z5?YM{+T?TXz^wa1y8g?ihFBJnumM$iq>O#N;!{;24tU(GH4r}~etdZa56cNDj{|2O z>Gpq>AvMg5RoE|fGgQ*WLePL2X8Qac%R6*Aj{orEpT9G-b>!e>PcqHImT?7r()z-? z|J#%+s}Cr&D(5(28*BV_r7Hdzz=J2Pf0DAn+wEOpCIh8dBkk9rHihYzICdTMR0;9V z1$iv*A0Zm$T9e4n^-s=;G9_!?Az|@<4|_BOE(znq0EZJ){*tq9Ghla-#BCmCqy258 zmDH$6`gC{DihJ3Wdy&Un;0rZ=;-|)Ue3ZP67PLV)_mS*|xsO<->%GrUg{42LpAxBs zzFhQiDAKOw{1Oa@8cJ@(W%&eJZ56z9H(1wC<*Il)RUg`ot&6cv-Ab{aBRH>Zd>xSw zEjuRoO6+5R*=m!r;z6j+W*A!ceadr>%Qk#R9=dpCl1Vb_Hr2S4U^)smjuQn&;)`J= zC?wLsW%o=KOs_9=e&#%8#U9P$mE^HsT%%`cs7k>-^&UC5wSk$k_AO)$`>*j{{pun< zkvFZj_D!Mdg~|Cbl~U68Z|l`;_ui;^d9b|9Xe|9uJPXC2b^`{6!sDP zVIHDlfmOeI&6s;k7SO!8Q5tinUbX7^-ZWNw4Po~zblmKZsLKp9QasBh9?5Ej3y8O- zPdI3o6+mgFirB0g{;|5a{G<~tg;$ggKi2;lc~~U4kT-fB>?Uhh`Ze@sz}1T9W1cyW}Bpjd~L&0mgCVh+%2(dX!vTI!IqCVs|+y- zk~)-0MrMT``-IrlhLE4D_UkQ456iV-OW%GnE6`Qqjcst0kdBMIBoxTXYfy;fAfAZh%|}TRhE!!o=eHF&X=@$08Y`MxWes$Q*{diRxw) zlZB=7Z2e+ONN|z(*I%q~w7w|Ur2fYLc>yp)G59c0UnAitEU}q4O)Z);SgBruiefn4 z5uGR`%b~+0Tk-Wzl@icX=P3rgtb@+-DlAEmUZpPqs&M4)cqE8Vs2}L&>-3;veFX=J z`46~&-4TQ!Qx+9Nd`cny90Xd+_@XEtZsIVhVMvyoFv}k7|5Aqm@b*iLvK}m?+~=}7 zBJQ1OE~T7UxI4w3_jl5XPXeyEjYoTW$APiv2ijqYTy|A`;5jHBo%BetNDQ)V%DJ@G zrQWxb&UG_wGy6^18W`LI1y{Nb_}Oj>#fih58T)x+;W>TCYE{L^ar(<}N1pspiqo+| zvla51e=o$A-L}6bq6C2_l>4hydk+I&QVv(f_1JmsxW{@&Dq=HUE3*)ZD`YHES+=uO z`7EG<0Fru6`p8{+1$Y?`d=RkQQ_|O(;bn{Hn{39FK1~cjl44IY%lrn9(&?Yp|40ZR z-GvN)SHf$^C_uzTFnU!_G;=WfZ6Nvv&`5d9f*lJ-l@GJ zPR+un>kwI66Ai}O5;NX_un(Jg+KCQf7#hYv78QxO<$k*S7a9T{40+nA)q?A6#i8Qi zs3k2s5^u@Xs@ton)|9?R<$h+oY*J<3yy<1a^}2PuifHEfIaPd-;5zE=DDH<=5fnGn z589mA%T1$${C272(Mfj`*%DYc&Jq_ERMG(P_kY0lo%3ik^JskK(U3H~^_;V{z)f$m z^>PR0`JgZ%!Z9nh?wblQ#G8a_NYgTGXef+h3_;mz2z3y1G4*%wa?(BR;(}Ox^wyD~ zy=hWIWfG5j@a8gmK$wwm+LvnBySHzzraEZIF_AYDFD(>4<{I3ZqSh#qwnw@Xd=A$t z3hR6&vVie;Y3d~_=wY`HYN`$-UG$Ct4Vpg61ibs@XK8u^xNt~8G2D{arn_g~H z^vi!^68dcdvjvszb6F_uPAEMGF}kNbk^Qf=hCRd-SmX*iv%sTg>f66*i)>aK>$N;b zkBedNt>~#@sukcb--{1h+}ebT9)tq(bpH;1Ejy+;Y4*ol>g9mBKK7-0>M^FBw9CQv z{)U2(bztqR9}vLT_nF#8K*CL~aqAfMRs&a!n|JnG$fTyqse7x{na=V_x3{v{-;Y1J zkdq<4Dp@U@uu)NWIdjJeJCoNF5~%Nwna-nP#KPumQT1-1iUWC8*ok&5=G;>sicch1 zj0LQ^J!Wq*{lt;-SN6r#O`%=rUm4PCtl!=HhMYzZ#Qq$1OBte;Oe$qS)<%1TZi`56PNFjq?2kkOjd{-msKFUiXKQg9OVFngn2wM?;Yl`ohs zV>_NfBTpePrm(p|M>4S+v?Ax~xN-OrJ#j6$t=0Ny)|*mjxc7I({=TyF7U-(mG`Et(n?RqD1El#mk(n|F6$S3C<2>wA9szFOoK!EqU&2 z{Bt@(Axssy%Qz0fV)a{hTjwOb zzV*L)+sLOiEjeL|Q+%_efRk>&SZq@*gk>dtT+c7QjddH{e4FCtJSn_(Q$NE{o3(f^ z0j1c2ppE3^yImNr@%0?C^zF}|JU{((H$}3KQU3D*Kg|v-O5;UL8?TKvA5uQyHBXt? zEf40r+2(e*{B5+#)9JRNN&A1FD@3_4+Ka8JG*%%^qi!wE85&~*9xA!47O~+^w?v_h zIZrysih-A9x6fQX7(n5^XRlQR)-SKfg^l$53Dht$lwl}FOs-Qoq%&7_8nt-g(l=ud zs!6^CnuCptmgzWY=5^&pl&5owx5#Gsbnc^PBSxloiwk-XZd|X4#(x8S~v( zu=`1^00Z26Fh6KBfqeb@3!(C|IrKp&>V$cQ=uSur61!u#uAeWEy)s-SnV zVQcT7&G&<2y@KzB)qLRV$+C%DnpOJU&U*`|V&7@!Y&DQL#otuDQJ&B=ZS>~}twQXt zPals<;6PIF(k~7SlP}&>x&;^Z=+GQZ&`W9&!-@&#wQ}0i&+%3!Y4kJDS2%fQ-31bb z;(hX16csS}|8)4uzM6-Ahjjv1a6)R8P$AygEsTrsGh@Lt0b6cq%Q2|JkUZ0WyE|j6k2DDj2>pOO&@XkG1FNvwoAiu@gQnK zAjVnKxi#pHN1Qxt0!#hU5`6=onWI)K-Qjb?Lv}Uu`xKbZ3$quz$J%_H-j5*9cpLqy z+k?=#IKR&z{vl*{qa5$4{AGF6V8~GHp1s7g_@jBs8)qwfgw8#4PcCWZ$I6oS=zn`* z%f%QBJ$cNt#5l?MRf0yFjROyECoRr_!66Qo-OFUzQxcZJp1XqbbP1KmQJ-q&nu$fg z(p{|PT*Cn7Y1gYm%;^O=@py4wwU8=@R2s~6z0Hl&{kFbbi?LDwa~0yi1Ara()DJSE zByDIMZm;H2!cGq^57xpg*Fd)#Vq$N|j#cQNDzGTF;3Y>dL2SJut(U4c|B@NWh?j>* zx<&`|!mH7U6;r~A`%F*84crCGQFqTMI;`F%sTA5QyY2-`RV1-Iq(epoGEd$YCh|Xvt7I_ zZ1{7(JVjf02JjqQlP&r5+Am+MbOmK-ithJ2W(v97Vzj#c(oCu0rWM$6aVr#Txw{u6n9aGfI3;FJ-H}02S zvGr=lvB9!uH2n1DaLJyPmY?iE5Z&vE4KBg4;0Mu(4l)?VxX0Bca*zcot*8Bx%4Ppf z)3DEu2uOC0-EFIEr6`jmKD+EMA+r?;2M5H93%~s_iA%bVYLh8e*@Wtxw^x}|y}fG% zKz(dc=@IVo@C-b(9{PZ<<7-{mg6n@i14{)u8G&F`uz2bK0K=8t_~cay={;*4IE{ZL zUy+FjZEg-+1#R8}yq+GymM!;QqEEz&Zs)7$T%;nsngxRv2CSlhf!X`4dqbG7PFE3^ zspS!eTC_NB`EmKed!U~{4q9IkBzDji4CRLfoYmIstvTn(>a;*yM+pbmU#DLRC$2&G zwBK?lHh?~>A*Br7Ixd~jU0e{`X76Kr-{|)=m1?v!BVr8QV@!9GvhH38 ze57s)*cPBt!)hn&#)EhCzZtjQ80ue-LV8Q~_p85A$4@Vg)6QfC(E2sKzP`dCPuM8; znhPQIGuYiv@nQUgbS~cW|5SYYSwO&z)C$;xpUeXX^YcGV2&+_X7ieL#+Iyp|TN(mL zjkv}J2V*Ii_r%;o($A>92!6}pMAo6R!%I&?)+jtNu=!Zm>2}+}C_9;|(!I9&4-%0F z$u4L%@@Iw_Eo)1!nrv?;18tV}lcw1RagptpXE}C=x`H8oIPc{@j#TAk28zsHsPs#XUj(Upp`dRY%6&BQzi$m(yC-LX1?29i!S~I5m z4Q80_L)Y|b!O7;$cIG{^e3&`M(Ykb4>pANd;+Xhtu=O)NvoYr&URvv@M?5HYEoYqi zbSRZnNDMAG=cgxA3&A*S&LCEYf*M4#`hWlW^4RKwy^Shp0LXAp;`(#-_g0-KslG)$ zL*Er;2-VVkxHbJ1Ag~UdN0(hF_c<@Zf5mzx+$q{)o@}n_CNS?6Jc_f@Gc(jvsT>$lg8=Wu<`&l7SWPo`*+Q z7VjvndrMYQG^bSe;}(YZDU{-DWeQT*Je(8b^lW$yQ>`%P1Jt%2JLPlJ8Z;H&vzA2B zYn=2|eACh88sfGAr8&&luJ_xZd|KH&oK}B--+HF@DIgNYugkqAQW6yiA>TArYbj;d zz=f=x(~z0)SXw2;e|sTehu6-2Y8eY*iseW(#c^Smj(=a@H2xm&@rgG2;u?(bolGo? zJr(7^i2A9(IXX)cn+>S+@6&4CEsa`U+$0t0)|CoNJbaSL;=G4{T4bhki`hekuQGEW zS##mp`4PiQ@Hai~)fh|l4WV8)oVxmESa6k5%w`7ud<{qV;b7hc?Ee~!)5QS@mn~PQ z?Tx5GUg`A=O&h~7jN`q$RXjFN|CBeJF{yq70 zo!p{IV@M!y6I_)oRZ~=R}EQz2#-VhV~x!G#985L(*K1r=AZ>@xKX8E zpQEGrIQ}CEx9>a5$*q4c{$1J+o|FoHF=#S*0V-`)gXWc8j^V$Y`4Oh96-=TS9D58BZ8%S&X= zNll2WVrDPT6qw~nV&=n@q!M!dVW5_P`?ic$+rhKd)tN%ut|RSJ5-x98^*>!rsVJy3 z&&9c$sc+_%c|&8gg?jS(-ab4cn^63EDx}ZE*BlDAV#XcVRY)tfw@2S%y1Y171^=SW z=BXoAXIydtrO2-tGT)$J8aJ?2X@R4wJ^q)plWlcjb?$!?i)LVA@xDiq=FyuR?w%)u zqBDMIUb=M+R?0_#0)~U1i~I>ai)=l&@+PQopm?g^KQimR!c(1XZj)UxF!FC|tPcwO z*N5qOoS^vaq*`!ZEdI-%li3aK;kPwmPPehvElh7tbswDUlt?vtg)N4pT;b!5x3i)S6^Sz@YXX9Y22=#>pHvoygUqval^dVi9 zS{jhN9*JZ}-cjQeFR-gsPu`>lhxvhPR$1KnRI}7&n7?955JIY%Kt+x8Y}z8pti;yL z$wEwn(aYlmo3E8kQFN6u;qk2=fh%+eov|b_@%fi?n^$J-V|QnrLJkKRy|(?+0^_6r z)aTo21ZQZ_uYsD4=XNuOS4{nx7hjRhTNdB$`4p`P5ouR4D^Om~tT0&JJoMEbaL~gh zPQ)LD4@x0hjAA7k&A)UGe(iL3v|NjzD(n2}*>-giB^3o)GuU7+wC6Q{(NZL^kOWj2 zk2C%5;VLsOGykUd^I0Y7Y4!d+O>r%f08a@lrPijtA29H^%EH3({_S#-wdz#zRU|mO z*%owbwbU$*Pd0Soa(T_bQ1-EzEd0j}h2!KOY6G|mKCDgSq&r?7$^r10=jF<}P1J{+ zN*(Y)V$A`w#phs5#%@5P?MHwE*W55D;JV?b$Cpl%uWD4qGslU1^vem`GpHM&N=d~h zG@A4;ikRnNQkt_XdP#8bFI@sgK0nRpUAh_a@vwVjw{iYZuw>X_id_>FjC_jCVta%# zDp|TM0gufVF4p;9DC{6b5|L~X$?%I&+`F}j(5S!|b*myx$yEMfSt7O(hLp_Mfkn>5V)L!8tG8rLN_-3bi~)H99%%POB!~N*Nb2 zol_Fgx!g|i>}&>S4=3+wlLBwOS~%+YyC5jkd-BUgjzy^{8JSaW2fo-HnPJerYZ-Rd zEo&E*oxWT-q4#!k5y9agYT;I8H7V`ccQ;_8k<=NaU)-%YzjqT-Ts2@_={cHCBZ`Jl5%Htu zE9Z)>U8*&Gtvfw@IYI8ky269rp|PH!eauj|QOt=>RcDpC+YS9z{+e9k`Oh%xuEF)1 zoegvF`aHSosP!g(w7unE`hxCvi)pnlo!V0202SQ;(jz-U@~qdvynA}b^SW!??z`Gu z_-Dt@bWBwyv|+)Q_5sVgrf*_@`QZKev?4hqf5u(D-^8bxR(G>y!%bfdR!%QmDbmik z7HcFNZtCmU6F#Oy^^EtuEp9Bzv5Jnpszs6zRwHqpPM%Z&cEF2dy3^>l_Se#f1b4yC zX4*(d*ue96mLcuj8gkgHZdSM9NSi3_j?5KBLHM63JX787H=58mrpduP8U z!&qJ}oZc4ogX@%%e<;IsD+E25d<<=-gl5-}BWx!tXCHVS9%e`2en-3}vg=@N7A1Eo z=-4Y;Qa_|$9%z!@*ctKdwz>2S9rKpq6F_H?b8ly@Q1X`@&T8VL>Ob#F ziZ~#4-#8c~?01^uHk}#oQWKqwGp^(iq#eSD-{Sw@*{?iflm6O@+9WKP zu7c7ZzfGo$MID{BAE!oI*O>f((1`OHJQM!{M6C4Eb@MFBHHvkyc2uBBqxzkEv1fiH zt>KRi_+$kmmKCTui^(EYwH$0(y!e8+Xe>K0SZcNzOPn)r*Gn+ozbJrKO=S-_3^C-N zS286-1vscRK$y!vNIg@<>Z^v)8yOBZ`Mz1skvQ88hLy^bq?I^;u)SZFn2uU^JWkFF zS^IJWFnhdNvJH(63BO6Ffu4lPaBt*lpodddLgH>+E6h#U$>DOBR%vXG2KA*pA4oTn zUi7j7D3x_CV%Ui+B`GvNCRAzoVdYlKqPF@i5jCSjtNV$Y{86UV4P^5K&n_5XnL6~& zwjfA}f2lvpIeFMh5}R5|LJHZuS`uUtOiR~|Q)HdgGz^+bXaS5M&mqG^bv-iZ1Bd0( zJblTQ0Hd0x5#e{W0yY8$AAh0NNwF_*YuoyV`&=H*Ug?4OcXig0kUe`%G&I!jwDREB zyyyFmn4WX?9w|DxNO#;I!Lz5Lg{$*{+-~>8zGx1eEtipVOwvp+64`NCPU(Dfe7|7fO{Wp`9bf%3Hy z0a_vM0aK$u*!5_!2C?oOub(bOswkA3m}rWBNdcR@aw~L%t zn_0R!D*fBb$ch~>wg#Z6R$9H z9jl-|)C9fj3fh;J&~q7dXC8gEr#GiI3^-~`Q{^OSw(XMzdw%7f7iGKlvF(E3 zcA(Ih$zt1XR2}l?^q^Nrv^Jwjw>7(N|830>(|lcBfkA%ci}mP6AdVvz&lo`5{P?!A zcH{|_zHiR!p~f0({M{z$56L;s^n6_jA1^751C?)Z25$kL#c>J~Qqx?V|L>K2bZ;nW z|Dwff6;9Xvl~#_tRrb>mQ(V2Qj&R)$VW?t;r|6y(+hR01*x{mF?D$tjpzpQeCe{Vl zPG>?0ljJ`J#5UR6gJjJt}P7CBGm zUQu|5j*SG-h;*F3{u^Lk)xnvCUb6YV5FKKP>N`E48tWbj3%Wj7xZH`qTtiihzkHB0 z^VOq;>DByEPtEBoxoGv3dQT!nRlskLrkl#Df>X&Ol3F%nFrbJdyw>e53=Cr&7c;u| z{wYjAqXcGa6DMC}e0Lq-KA7|BLj=;?kOsOrDdn;Jk3q@XAsu|Y3@4rusrP*UJWy4s zFLpg_S5+9xu5=eGtfy*~>n}R_R9%!8yI7yUJfAAVSN{|W9djTosIoqQysFy`hl-}1 z>ma?$jsQoz?qI6)daOHom|BpAJL*cj6C&}aRN0}|;##Tpe!1`nlBVeNtC`X^p<^0< z%&GmHqdLElrba6R_2Oth5elLz^hyz*Qo*MisjDRVc)>(b4<5&*D&{m_qy5xj3u5CBmPEEyx4nY^tN&m%`E$E8?vpK)BL!c9T~ zn@R^Mpi4fH)wkP-iG=jLor8q^t`pp*vDLd=r2y?G;J1T$kW&SQR}0ss#I6`C_|ZYR zly1@DXRC6ax?RokUlmQi=G+mj|9e6-TV(q$f%F>Eey}(H1xMHhQ1v-Z4Ak-lCd1Dj&&bQ?>je<5B3NCH`8{&P6TG>CI^mEE1zkuyMA zj#x%iJR3Ar3cs6DnJY!j8Z>1*>Yyrnaj^oh)WN;~zU=qodjmm;v`KprQK1>U#y45ZpuqZI{VO!``7+pLzkX4Q@6BIBG~S zu8|K(KSB=WbxKvqYje%h`e?>k9)HPCW{uZTiC`pQvrd1{W7^U|4PM{z9r@_%Tp6Rt z;F5#(-_z{YUd_F6FEgtZ=tUHd0#c(+zcw}^8}$tmY%)3K!Q>7vO(*rk4)xpchf3Yy zqL&JtvTdubiqEJ|m0XwaC1S>ZG|q-N(_>9X5#|j(GUfUPA`=w3g;bsdM(WLGUFvu> zbS>rYu1(T4f;;K(35UY}YIWfxiZ;&^8)@f#GL?DDRu|r3%eqer#je^Jf>q0fuNU8O zEd}$ZXefs7^7kh{rT*O&Mntlo7moSXTSg4+5il9x`RyTuCezSD@24Fu!8&5GfwBsZ zAXkXdl7_Og{r`CZUKG?W=r_NVN4sY<)#Ev%ci6UqMm|=1&PeR#or4SgS0Nnbx{EKl ze3uwpL;n#K?-<%xtWr}m(wjd7rhCITr(>O}a~vB$*#(znyYtRo$?jQGPu{V48HO6> zTNK;yC9XgnvTAD;YDblaGb^m>w`PW+1LOK(5z3rDeQ%JltA}M5NNXK9)jpgGux!u} zCxe@1zYfsVYJ7>6Bp}C>)H%NGT$k*h%vO?l#s}Jm)M^cjMJ>@AJo!xQRxF-Ajp!cF zm|Gji8Ql5AyTg^8Lkc>H6{0w|SsX;xG{`e_ePipurK+Z509WvJ4hvwy`Svh(Av`Mi zh~et5dZGRlv6AOE3x^n)h%eXF3L+ez(6Y+uK@U+4yTmzsU_S=m;ORp~c?CxL6Y?gu z%Q(l6R`ZlO>i2sqq9}E$hTEs`>FlOd`CkD)0|5lWRlq@#bvDG+^*}E48tt63l;_hB z#jMMn^4=3AVz;_&?d2A!{bm|zdGAdfZBN01*S3^3!jW0%zdGRR*l3W2*o1*9J9v_I zHdIae)#+G`xD!lvWn#bPCIhg2Vh}c2`1+SMz4U&)T5RS8VUtMxm9*~tYRroOvRGZt z%)Pu;q2w+bT)O)1+!=E&WBx~l{1?CE;&X6KlJr`x zy(8eNP(t{Z%dhiqr)XIB_we({Uh`Ht3>p>HTyIn{kLHNFeg5OSQl0I{q38G!hYFe{ z#iLl|xf5i0*tOVT<66YrpQ!cVbHZ{AA&i0)bm~5>$QQTuer&&vg05qWCUTTG#dy#) z!7EIfwNRv?_lE z$N&EIEWu%&A~N#I7$yv`s>c5E9dchT=%BNOSD=A0f0PE3M;u&4ZCK1_P?5rSo#Tzp zhXK6b#V@ZLwDZo!(tqjOVx7nnFlThl8;KMqA=(@>G?=r&Ior4x$})bd!00}c{tM|M zHsi7oRJLcS!8@r9^nTyPba>C9Oy4JerDnqP8^?J`$V`+c=PTiIdV|!3^B-KxXl5d< z+TVZbXMacAAiVe3+{ZBMYz`(O@PJYTXA=r72}At2C7c_TS<-nKMxy$4{*PN{VAB+Z z9azQov_x^L{trF`JpU7=)ELpKa#Z zfWp_FU`?hvFD?^I$%*W%(~#ybjDlW6^kMHQtO7>itu#H_AC*)DdV%5Co18?^i&OuA zb0yKPclMfd9Tq?9DMN|t5L6w_gvM$x)S=sk(7oAXcq?k2+q}Zl>r>-ZJ%>VFOM4CeQEJT<^%6m(!Pqw! zNOp!PtD$G%q?0r!n(HvcSue5-uRgg-Sqa52OfBw3JX?#=Q$kp^Hf+mi+gN9qK1~IG zGqWy8w`UC>4)bgg=+8?LKzk#jc>Q#X;v#pWy(7n@K>9BNvEkAW^=|HD%lSF17O$-q zJLn}b9Nj2N?LG``T(pwqz5P0`@``8J`DW&kzXsH-+In|V|86NYm_r|G$Of!b&3ib) zV;_^4G`w-|+h;NZ7bWRA`({>FkGaRbpTDj6+jIQpM!8Yvyh8bv9zF*sScJBOAN~mP!G5~Z z;PLm6*_`istdSa;qo)C<6Af?}R3##EUuG8)<&_z<@%4AxD1ht0+nh@|=7_S`&M5ha zUK}os^^ih|Lp6tS{&Nm#N(XWQ=TpYb$|ZVlv!#AgqeBliO&6CI18#)+koJG0687&H ze7HPMySR;{{M$A{>$PG@QDe9C{R(2MjH^edl;v# zTr!*260KtE!#-z&jcH&w3!UQLu3}^t-#(YzvXHhkM^Pm>nlbcZiS*t|5#jk^d3s8c zJk)!IwfoKMQ>)x}^ErX{npTOk3C7&BbO;)q@wnh^|7xfES)T9X z&p;{ZzpJ?`$BNROXD;QD=jpmT+sUKvYT>eTm-yq=u=o6yfr(L@Z)`jm$lh=vmaoq` zoy-0`XM7XuiMeW-je9GwG`>hHmE$AQ&~)U51PZiA!x>U^(A_lf^n2xG(e9Al zH$67}@luX6hiNmGkwaX~^ZLz(*06q-=DifpoBqEX1dCVWZxA_$;YPSkDM&z=dHs48rtbV*)%c&vJ!W1H~jqF^(S6=?w zx$hv|SANnXbF{FGxB2jtI$Ax~(TYU(A4lJEBH`)c)Z*2&+<+oxjXS?{FbX#?mqYsR z4qrvt-ER9my|Y}2_ce{!ZR(TsIzmSs_zI>iS6E$MW2%JR`AO=M`%A61TgOl60Q~o( z%|xGRtIy+qi~G;9f^IM96iHIe_${?-mpiwD|563J#|j#RC<+EOna@Djf>ggxdN$wF zunbTItYtQ=hvEIr>jP1hgx8}8T)K-Je~g}b4YH(;MuX2AQkIgiqIrCwV?WS6w6=cA zY~1<1zu;!faJ9kbYKiLr+z0MdqmmA|+#doO?p6U7QO$&lmRHrfMl*+9S;SLfcQ;PnnTvxOtzz`$n@bAk~Njr|8 zD%r^j=T6cL26$Y`HK4VhR>JwD`T8P*+OA#Wx~@4wz# ztTOspPt3k60Q>LS@p|=Y)i$?o;KSBNf1mWks=0UX6|2UhMDJ&v-9b;Py!< zaqqcTpmA?OD3MPTuw()6cqreE7A)_Ajmx%dG(UOr@S%ag6d8T0Aj=Dt*sz30oxb-r z437hu&kT!%B#Bq$@h+5!8-{|Mr{QRt3}R#_X$K72cxy!Z=d-4z*$ zmP+AW4hck@AI+H6P|nf`^snNt9?M*3Y8W0>RTOho%O5-|^E+X(((b}$p76Ava@V4^ z@|e3Q@*w1*op{k=(nl)yjJvE$rp3W47FAJ1b$tLiZ2{m_z@zsCok0T8%r9Fc*fW-Z z+@i92f~X@^@8vVC&EECt9dY*T}oM}G9~*N#k3iZ3w*-n~=Hgjj6Bn+PCl8#&4Pza^YknBj|vC2bfG zfxpln+@eMj6%BvdAJL5%D&kk=hz9S^>rUV34^=-&akgDr>QA0)YeC+@2Vg$+yhGe1 zb9B?eni8pQ(1GhvvFsssm&0N>b-9K20%a{6#MtloF7~vGHP2A9wc$d}oD88u7z6TKMC{h_j?@4Np{$Oxmc-_-RMyNXI4>_yh98jKyrkD zSyJHr@i4fOxnS>ZAeti2#F1njV!tKlJ~%cX$>uZ^Jfe?GJpR@;fZ!l7CAl#^ZmaxT~*Ft+#0o9 z54RcQrSRoew#gCR^(x#{l=EIPm3Zfq4O@T`UHY zbG&&E_*Yc^>fJjPF(wUn92bOqBXRf#;(P5@kzxO3Tsk0}vHF&aX07?Sm;ngrJU=e} z?2H>`cl$PCLn^s-^9(nAf(s5kU^F-3+{4j-g7m0=h?`32N<=;7O}gZn2g=b}lPE5Pa)%zSn{2*_FQ$4EOqPk5#@k-dRN-AVu_=3rBebYvcH1XMu$ zN+u6~7S&&S_}hG*@*7vm8UT-76h0`cewMX7OCt2ihZ48@#^~dKwP*YpatLaBd%2Kd zXCC@uFM(VNT16vh3_9M-R{AObA@brF1`ixU~{Euk|XZ$Zz$G3Wvu-CY%_Bp z5g>83{AB`hwaN>9e{yZYuiamIo6A@B7JerL=RC^8aXMF(2zn2({ArGv#5^6(X>4j9 zzGO)pGdlp%n#C7onES^g_lAaQ=qzc!0sp9ctEKS*)m^>DCvW0E*)!kNL8fl+SSXeM zjTmBS5br$-q+vjr6JPk+Mbg{G-@vHK1?;nf03}wLxZF{wZ6lb&Hhw~X`1lDMXOcZx z;daaIH2^G2F7Qvn=tkbgfF(^9qPquD7H766+H2Mywi$%<7Az<{S8p5wmn<0qx}fi2@RA}=oaX+87g61Y_=A?nIbvH_gFb)53jEK#WMR{9@B+>TpiCOGHyBnZW^@I;m^VwJ_)81I+-5`xcYP4Nj?6h*L_l-A@s@s z{t!;U@~a@;tL5i=ecD}}u!U8%IM!ZqW6Spzkm)j~ZYYLJG|l4q9|{V~Gmc}O`jr5V z9sxFC<%r=aOZuY6_BoaMM74X4&0(*6d#wuX;&Oae&b~3Y;sN{rA(sLu>P8#fI>{YZ zJPP%?a`MUgb#i?AlJWlupnhiI0+6q)!e{3gwhZZ3?p}`i@p<31Rfo+!)%sG#$k+E# z=eE!`D4ny*{M`$TexU1y^pv@s^6HN(+9An&elR%19R^dxww_;> zk<6roB5(HRYVqm5^cah!d5S2D5YY{4{~FGs_@@2Zo)Y(4ZlvzZPR0`Oe>|c+Yo$DK zvbk(F;vcPS7k~S1kB3(9bg?>!Wb-VHr+A>&{yx?++B6e|9n$(;6|;xPvRbt5o=-6F zeGI@FJ3_7fNAR7;Ad$ieBNA?_)%w+Mp0pUGAZn=3jZVgtG;N3O+M^V^>$$_xU7xh{ zNuPAV?p$(x8^igiroo2(qJ7P{-aMD0H8t;q*XmSqJ~A)l@J^j@?)+m>g?WSurR(kb zgyHaO@I&&WEG%96=<^NwRWCXDn}5{#iXa4j(f2Y+yQ=A{%-eazAf8)vTWP;Xb~sht zuzvq#V#gV$c>ppe6vY@jz!>ru8_BSIJ<90J^GxhcPzW}`dX`d;H(;#qGNwM(PZ?Vu zuh-;%jrIM2Sc7`sK7Ea`KZ>Vld*4y=AS0oZ*#q+5irbY>QVoFF{-wRi{Ya)Xtz91O zFI^pWbL@*|Ohs>Y=>+l@d|LAyQ}&=mCBvF4Zsn9($u~vb>v`jVaGl3Z!L3s<_^;m> zKo-)g=dVDPIE6)W$lCL=qZ^%ELXv=>SqB_u|&LWNvUA1aT<@@3XfD4`Z&tP6=KMT8kW8DK{YW zdXytLj%Q!PO;hSsIt5Z*yB97(Cf+D^IrCAVt3)2!XC!bj8HMq-ccCu4mOi#^3VrZ> zXr)|EN|`@{QB=`))-3;#$7KJ{k6G)%*+0RqH4qR?KbYb&w_(}SS+%_s7=+rG zt8d=+_($(tco2!7E}**-7Kv>yZ>e-5AvY78FY>>=mn*N-AsR8cmdw}v@BR2|7=~5#9Ew`wlNGqBtCTwAeHsH4PJb z`o|HFNjGG9jae9N6q&cwu8P~^0ixwI8j9w@JR`jKGhEqbv${q5}1@HBlxGyzLr`F$XXc60SUt{&1Bev0ds4Ce4IqoD;(Yb>! zS@ES<#!tZ_PC&C8ssl`RWM2Cl7O+C%?~uR?^{c+Z%Q)n8(r^!V-U?M$$Mv>VQ)-7N z#1saW`U42d6_L$8Czsi7-iuJyB*#j9Ar!bmPt$}W3rliJFVv{sEaM4>mSGNBU;d7V zr0TNcs!~`9D)7>Gk1Zo)pRmL4s4}Z2!f`c_I$%j|z1$Y^B+TRLkN0Tfsfv}FaTopL zuPN@!U29ew>Tl^W12G>BbM-O7GG)r~QXM8p+>EXJ3L_m^%KM>%u>ES0eh$PGPO;mw zAmExL=(mdKVrAlXPuS)N6DmPy(>sDq(c9uHRb4u`R=CwxclC;Hh&5G4R8KS*S7mov#qR%Qwe6>NmbA@ zn+_F(wLLW3;4IbQWfmVR8ZKGwjq;I7k0|g}>c!~!n@P-n8IIr`%^N*Hn1`=W@crK4?vaxb*ZY*ck*~w)|gf^jCG0GT@-h z>BJ!CbgHcsZ)(i7y-oaNpoQt+yCkd{u)lXyL~m5Rm{WZ4jjY;B5qz+YDn+3)K3FWK zpfX4)3Etz0);+jv-)p--xiyGM24Zfk4o-?|-QU+%YgPpSJMMQXvEGYgzw(HKn*G=& zSgGPeObhO7im{s)N*GG~F2?ci7^-Z+o1Xqq))Z_kQr z9!+!9giXVm=zy+$h6r)EAM9C++8EV-ZUo& zL&(JnN#`uc{gxRPzSv1^J@i)b?hsX)F8L}{jzX*R!1J-!-KWR%rXTEEyHQrwF;&6i z7+$6ycM#R>53^%w#P3|S`igUUT>JmM+`-zmh_o0{i3nFyl}(eekWWAVEK3%c8lvtaaUSJVUDiPrRi~I_;dc--I%D?-wul`F7!er z&al1*&VEkg6k@)UL4J6Y|It+CrS;Nxr7x5UwgbQ3-9O#McRf7lMO5+7-jtDaM+qgq z^f?Gs>s?B=e?ik`atXW2`^<3AZ*dvMB|p1XSR+pdgKbMKe3%|v+p*{pne*Sp;(GzE zU3}eNQ1LRZH88lr)fi6g8cn|qVZUSWi%Swq%%4I9QZEte-@3f$oty^zC$#=->;3^q zeBq4%g-Z8HGAoaNy?heG=jwaYP?zR&?PYrab4Mn!o$YIGNWR_=l`6M#fv(;APCfV# zyp`_w>l%~b@ha(Vpc{<7yzT2qvT~)H)g9W79pSe`td)yh7yYU0`>(#HLi36l_5*Q% z{LkT(cW$pY@-%QS$k)#HO8U%Bx1z1)iq*1dk~=)svkC0ABQjX1()n~8Rn{KNst60+ zpJ>7E(YGGQK%(ovZFBiGQboUQKa?U&N36t}t&&eQ!@TGewJM`RQEFfsiNiCT1`XNm z!GJF^vb6547=O^c1CkMmzp@=%xMK;y#qtp`b-iTnAxc3C^&#!%n#QD;A~&Zaa^$Iw z){y6XpUV`I&@j?h#l&ZK@4kXq`}K<_w@y_oLf@%pye&vfv3|~bEM)&skX4dT{mq9B zfjk5J28e%~#~RJrvuvMATYK~;CD%i&titRG&(+In@6qI+=WT>FFTej2gl^bCvbj3Xw_y+BVKxD+Hj|w;7?kzddk? zqlW#uHoZboDjEL!W-BU3u_a-RX+`KpTnv3lIt6@7Al>z(&mM5Gf_v> zH`OKHz@^vr%v=lKy`TV}n9;vRyoZ+`Ws!(w=n;RBeD>UkOGBL8 z>X3_ZijlT89dAh0T98(@h7!8`{UsI;fb;S!oaCfFh)0$8P&7ZVzCZ3fPSXrx#vNW{ zrJSJS4|$51Y<^C)?}x$!?CAtW-V8_fG*HvZk}KAo7)RVl zn9~C8-i{f~6N`kCxc?r2MerOp0fGY1+Offwo|oYD@5W#WL8LeDeZlqLiVoWfR;Ahy zt;)o5QDOD6JFA(V6qpZzW*p8NsmcADkl<5EF;u7T7fUW?wSp)P=trm8iDAcN8zMaSpAtx;teR8xIxGiwCy%TDg?hya`u5e= zP)R;5dIapMI%_>f+LFki`Ojt8q|XHU=yE=nPHcT?$#m@(qgFaXgox97(#`6+`?KNh zV5(c|>LLX_Dh7fCb6Och%Umi#C!FTe8!C#O z;|fz6#OJ+>7ylgHJKH`baCAl}f60{RQoJ*7^h9;>(G^9Wpr_XzIte(&s_fW`pcD4^ z{_NsCzoNw=CU~lZPWLa3)k-Jci!Wbk-?asDHa2ZMNFIAh`82&_d$_+jW99^yV@&EZ zAA1rwBET4J|2mab74y{bOh)ea*?mfMzF=_5lVsuQgn1&z_ynmeV8KW0xQmMgz5e(l zVS((4KkQmB9WpuH!sAO#Il-Io{M!1TomI@9eiMTmZ5htS*rAsH=LHb2j-NY}R!`}B z?v+?Q@dQ2!LXb>ILm(9!!63(YXo}sLV)UW9o-FIW+b{zI(my=BApTM3#3Gx`IAA;d zZ(|~Lba4!E+b09+HxU^LyLyO2^_P78tZnfuq{(mzs@Tcn>sX*(?seXL&YAuW_w>Us zlb;(sQ$DTo5`tPcH@Qc}V?|+mSbv@#(_~|M{E(i_yux+u4OaPKGnzHRZEMJDy}v?~ zw$AFCh4|4ujxC%lVW~<=)E(%wpM%cIFO3nU{5obX4}7<&HTb~9!yj-o=X}w+&&IlcZ0itDb9Lh8gPP}CYO&zUnXH=Vsgy=6qwflkE&3!Z>v`X!arajE z!m&H0K>zC(`%->K#oMS#!8BPy+@3R!1wYiyNp6C=C1VGltgp|kz^Kh!T4VlG46Z%0 zy*dY1hd0p5Fbw+m#Q0{guKIJ}4%7BJAEYt8aQQWud34%Ir~8TA&F}1GD;oMV;S+^6 zX6tg@YtQY;+^YyA6w;<8a=EP!5v>t1h_;a9TFsVI6ZZXM+(q7Q^Z7Z6SRgJ)W-~Fp zTdb>SEvM zQ^EuOZ1UcgS!yj%U#UCl$^GrWXT<@cg^3L^qO?p=)>c;k-Q-)@Yc4M6Hy^6!zYfWZ zP}OYQ$Wy&A3D2dwe{TNwVo%}Hgb<`2!LA1g!NIzE^5;oc0I1*_I`I zJruCb0}d7Jw+d&~(_}GkDtp5ktVQk_e^8@%mk@&1?viHJ;PVMSZT<9TuaPs=jR|xY zjeEQQtZeNMQ$kU}F|F-*zX%y~6bxb5JW&>`a)e11-3>kSKb-4P^nfy`FtOO8u=Ig@D*4cV>fiFGc zOG*b5cKF?^JY{XQD7NXER=jAds*n0R3r=HIS#^fc|VxJ3HjzsJRT7EROc- zuU7506qv!4COXIad_cK+B-InPe5teGJ=QdE@l9lAy=+3XecQA{7|LP(*u5bvKpfIM}&;*m5z(+N?@61h+f@zY>0w~Sv?q~ZaOpYBB&gK2mG z=v4bCDwP+_Q(v=O1a7@pMLy%Pr?a00`A<;C!Tx>PJ(OXEks9`Ecnc*iODHx}r`ZLz zUg8dKxnMySD(@fdvi_%zYwd6>l$a!0Al)$|QzDR5Ee;YAk0RS(nz zrixtn^{;9(7k^8QJ30z3uzPHu=G)lZrw!}OGd8Uw1#VA-GveL9AMu<;x2ju%?LSUngy z!lGf1mg?Qy?>z6cnk%ds{Y;JbsW7}AOm%+``4B#~cC`X46#bJ-kRC?OJGy_`6`&Nh zDgwK;vNTjox^zAhlr4$?OnTf8^f4Qa13?+tY8p=giZAcnjmWikHF&|JFV;>rWb0_)bB*)XE^*_JT{0^Z2T(es|0LOf)bC8B3R|M8Ix- zfve^VA6L%TXF4wod-9#Qe{me-9t&@1ko~sztR4PX(FeFt(7e`F_ZdupeD-A>Wem}6 zu1g7>sKTi0il%^GXG4Y(jyAG>=Olw<*zYB87Hh#=?{_HrHv1t=Ki&GZu6;w1Nz>w8 z130hEwFL+7yYi&EC|!@!S#=s3vkrw4o#o*-6JxJ^)IW| ze5!?k*bxNp%`41xpXMwvM;cGVc|7X|8dyHrbf0NFB|E)`>1(6-@UjKt8XhI~bNB9Y z(abu$-cw2(sRRAeBVf}p+m{BdSs(rF36eI=O>tWmP2bIUUFKjgXYchlq^?p-xO)1A zKiEzdb|Vn?uM^e^;tMd*ZomDlt8Dmc@e7G2FZ}0ZeF%5zoJ~hMn%@4gqr2zjJ6&#F z$IOMW=xj=s0h)@YJRUlGc?6s7>p%3O9Jy`l-m5Rqy7ZI;l#%J;8RS|R5;eBSM` zOOO#4C0sOlDqO1;}od2jd07QbO5sAzib z6h4ULwok5HlL0+8hcy*5o4T8=desn+hhMeOrw?*B*r&r+%Baxl>}M9*9vL=88!^+0 z_Cmp*IcrA52b1{wG!HeJFKcQ&zh_vR`!hMjK2+>Ggcw@I^G5SQZ}b@kO_{<+uSbAO zssR`pTDm^9k+kmp&5>+9n$%(OR4Xa_9O~${9U~QyKb`Z&1}@g{_-6ZGN24E>>O=~E zrG?Nl6~dG$ao#7p1l#~IUWQOCV|!t#9Hqc&`5U!Z-UwRZSH1+t%E;$$tY?3z>KLoL zWY$WNZPTh*Jsy@~F+O1=h#uA)vf%57kCUr7_3x&->klSI;jssywKqk>g8Y#^)zaIe zU*;VADEw}T+82)j zA1zg0S~(lDIv>ZJuQ{2yRy7}ARRGtPVJna3hJ03BSMIK>1)`re1Bh+Xb2t_hwZ86O zup309Mbmn0Uq@#Aqp);n8@Hq8?+5Y9cpbh5-b+@yIx}lEG^Rwo zR~1(LWK-kd@Zg5}7ImK9zj4rmP!c$(>yHFzFyZ{FMYRWwXVnTha<; znsCE{+ee`;3T9YE{@xhmRkL0+FMDkymHz_f7TA9Xc3CEs!4SY>VbfdZzZa!EQBFJ% z9rEy6`Jxi#zVna(^fNzSoIJfI!uedg8*m}}tafjcfRcvv6Z5Ki+`M2THikXFa^pIMtvDJi2Q7;od*AK1I9irrR zto#l#D`~w=fK%qkt0=&oQVTDEQFAe{IAVM{%aQp_6nD8no%f3i+HK?P)(XKT&70;3HHTJ zC*^H$ggk-fc*%{awgn9jQw!;*0JCHogxIGkN7!ujNU`71hseLBr$u@NSo&&)!PkXQ zc~|@ty$--Dam?I zzpomjoyqbdf^DK`a-<9jXS2%LBBtfDRHehuVC8@Fg%NYp8387W;8A|KRz&G}wbHux z&cQdLx{3oB^+CpQieA@x_+*b<5OY`CIqMf5K-2$1Lmbd=rHrPgb#pw>K?oA$U!lh3V*{8|X(2ec?ZKN=| zppNg-(Dl7dR3L3p!r1-feB?mmQn$6_e(Q=1KVDhMcYQg_^5?j>-K~$zcSRV^l60aj z*56^pD3L;&<&*p0za4nXiZouH^JaD>Re2v$-6mfYKMi%B=(rZVz4^*9+qVsXMbU_t z-NS5i0D4%Q-0pC>{PqVbajoK)^~KPKmoJ7Z?yjZ{_W&;C4C>}J_tsxyhcp6IVq^o} zs~RmG8=I3NDqBMTyIH?H4GfGZr(*ZWzV^Wpsr5eBH)0%;MC01mx>$251=ig?&qoir z?qpRpNVCdC=oR7 z%p$7v*Y2JFvY$t_<9MlO9=ps3R`A1;cOO?0w_Sk1C)0nu@ zbv}PZ2ISv)@HI+&O)SGRti(V=LMy+17ejazf;5iYhsab4jgzH;vMEZ!( z5u9(VoZd8=_xGCm!rG3M<}GPoT|aXEwe-(@uq!I=lSfV|GT?4A@;z`bU)Z#nbo|$5 zfFA}$M{+KuOeC)TF!E)~c$$yQU#IpST8@#aZ_P@=#r^{Xb*-?bQ#kC?3=hEsB4apy zG}Z1F3hB6EV3Lo>!nIA#%&vb~fl=t!YC1waX&{hYCHG;hFF)CRi3Ptu=$>>((p$D$ z)ToqA%Oabb`mKSN*~Gq{H0j}BH;_x{Jh^wQ#9QO<)6J}L&BrWh2~dYql#?y~=)u|M z>7y4P^*x6VUEq8-iq%S$-UY`)gFzotknbjDewhCq@vu)mrPvdKE)CJ$kf!R$lcWh1 zYqHnN7$qltd~#JLr4T%I)dy?2HvYFCrk=B+%x?LCJOEfdQNvRmL}(&CpN+ma4u7sk zSu9k1bn6bQCZ$T7pcO2OKZGdn>TY4(zFhm)MhHm;v3zqLs?~$LfwybkVy-}(rx$H` zDbm@yeW|j1TXc?T9uD9JjO?j~K(xHnZS3EPrp6aed_sa`y7$xtC&S>11a@}6Yjnew5d24=rgdtzplciP;PPIPFJQ8(=qUQ9CJyjcyy(#?%&+&GcbA<3VqC1cdI(Ibj0~!PIJb8xqtid-fOETd>JSsvMDF=fD|F zQ-`)2?!Od&;Ipan(1%3?ax01q<5I$!%;q|-dP~Y*9zd!_hU^=x+?}@*q@y~U@e-O` z0K*42Jk9Izgp|lG-71+EE5HFmnAL6--W8y0YYwRL%-kLmGKF`Y9Ve%X-A7>D5ikY3 z_Z#*mYyijbiP!JIe-<=RV4vI;9tfu0<=S7ydwWIYD3Zy>fG=rj+BllXYPcVa^aB4BK@WFize|b05FxW{5jk5#j^fG-hqB`3->=-?cF{cAs~5g z-9Oaxkb@lQwM4oVA<(#m-*3u4OH+?-y;wv(qe}2v{QZ6=Z@>a;6yai@YsXUz2Oj>9 z{wGWt?74qO4yCUGVU5G3YyB&=q{XAot>`kfwIwwk+FYJ$Qfud29%l^i)wquwT+vjp z=X-iC3D2d-DYL^f0avRV&a2{_bu+W!&j1|uYH4IWfo}VbME_5_N94N%Dma9F(4rQ< zGk;7FoBHh4usSaIq(HX_f}bW=94T*~I5_%!!*)zK_K zmA1U+Xe(Cc+mL&{eoq1ASQN=~O=)t-W5dPLGzBHrIBDnQE z(K2qPkYJFrWWv6|+JoGCUJk*3WVIwlS?1CoB{Pisef`M~LzCK=sCTCe!qPgdf{sUJ zo$di##(YbhHEOXBfMN@f;DHRg?ub;IvtWCiGNFev!up-!Gyd^fEY8UYbj@BJqBCkB zs!CV>UCB?dO)oO<{WhJTx~eheOR7%LRFy{A%aj}!w(5s-AhmSs67Wk)thHDO)@$sm!_IQ!|B&}x2Ub7u>ZLd{f@)mJrdFSnz^XihA(ePS zWK~avYTIFLn5^nXZC|{Zl-L~}5is%T4Q4TL>UV$=6>#h$;S@h`$jbIY4t)$AcMDcu z?mu?Wg6ilt=c+$;g;UO_)7?GEXAIZhbj~+8{`gX8P(Px%JZ3z_)tms$U5O_*1yEYI z1oAU=?E5s?XU(EMQ3YdpXmr$5z;BkQGF8Om&1}~iIe)53MGt#6~UnQXpqc3$t*9~cfre`+KUZCs}B&R4$QInyN;kXy_0_HMiud8O`N6%OD$*7 z?kV9?CM8_T)&J>P;D2L}=1aL*sR*TbgT24>jY&4xJF%0T84d5Pqt^$auE_y|y{5@V zk##vMN0S9)VqTL$?^cz5Nc0U7N+ky?svd^fxQ$-lQ8Zl=;;Z8K5~e*(0Iu(>XLRA= z1mH#49&Aju`4#q;IHSog|Kc9{()QHu6N8eaQdj-&5_xL=$&UNz-_eX9nexT2iCZ$m zMlNP@ih8Y+S2m66CaNHrEOhETP+(G1Q_7~u<@u+(GG0n$_xe6BC~o8R&L9S_TsoFa z3uc(hdoA-6ILI~p%Q|d9(kpz$$>UaxDE3smQ0kA;PLerGe~I|RgHV&x?Vd^%YErp! zQ^~>Og*YffW!Kb`Nj!DLqfyf<@t{_}I)k*AM)AxGbTZRp4ycRhHwmMSMa>@|{qGs$ zpKBizya!ot(HbH39vG?O`^L@1O))Pc7mNGf^wErXN?ovWHoW(*|6ay&8Du-BkhYBG z;WipAAkL*bteO|kDPY&qjW2Bt$zI+Bl{&Pv)ekS~wOQ-?K$q0aYfPXX{25Ql<>r&Z z%W_sePjFp54L3N!jj@}Lmpq7b<{9U7N^!C2el2d3IhOauWcq#NTx>mLVCFo-KB4|C zNYbErck~hCbmd&g5dUfToyXsMi~xKlOe6`w5%{7EKD3-)&*)DuSR!$=Bc1BT?^IWY zNA-|sbE`#1J<|D8rV?=REa(T@$JJA1S&l>P{fI=4Bg4{lJE`0Qo6ZI=fxrzHS?D2M5DoLhWx8)@v&NnMIOi;~dHHa$CJ(&YRUTx|F6 zb@gG6TE27PD0|hd*~Sf%dG+nB>#sr6qmf`<$Gappf#55l$H1?bHT+vyI<(?^W`wq^ zv=FU0`+msBmg8^??rg@r_Rsfcu&IeE>dFDIe@5@U%SxNO#9ApDK z4|Q!jie*mrvj_y>~7+ly%r8+|j zR+yr;8k88KF#JGIzJv`1K?ND}?&-IwNIpzDx&~X$N5VP9k=n1>-@Gj=aSrGb*dFTt z@l8+058o(==s?@z>FpU5it8*1vA>WmhPR}ovWyn`vGn?)>2aln{Oso3me8t3!%F2oYQIf2OD|w$ zD)IBne-7NUzZA~V>H5E7MtdaSGK?sZuTvsr5(lHfw4vJmM0I;SZFB^m65}`3vJ#F{#VgAAB zZI;mX6hG1#Bm+qT#3bDX3nmHYDHHAi&m!+>w)cLPQWheW_w>;N86QD0|HNnFr37oD z*SE-u6Pimp?q2B=maC^YZQgzif;$+Nh>=grGQMmP_fr8?v=U-=cjBCq3v`W}cQFK~ z_@=h=(vZ;PZvC>6xaq%RyEH?`vYQty*SC1G+lx(5fMLwKT$uTQx zhov5azB%-44mZ|Ge%El$D~#7-wqMQ1;Vn|&*LRK{DK31x79D%imGXrbRN~_@r=yFX z&&7=UFH9SQ1V&A|m{{m&1&b^6V~0W9za+-V`t?Xdmjy$p|BJ{_p*KJudeloj4r9{0 zwytjwG2!2e`vDP*NG@?MSfdOcwD&HyI5^_+4Xp`w5Yi2~M`C$a?~a*H>@|cyUXXd& z-5UgCW%xj5Ehl~loibS8_vnBv&(lTcEAQ7#D007-4hi`rcW|r+qZHVLpA~vy2GEoK zi~k6z4E%mm-haZ4O^rXP|5eF0tPRau5|L>Fj9<2G?b4MXSz8o18nS6V>K%bX$Wv`S zzEZQ>_(Z&0I%PDH_d5u04ifgF5@3!~C$;`nU zxIDkRu8G$)BMW=yOjr_f6Wb>y_Us8`N>jQ&?afywjgsVq&5bTF{SpP$oo}a@(6N%k z({J2qn0f@6^_VN&9QJ2;1iK4A$#YP+kmB)Pv| zNnB;wgM83BSf8U2YxrJ-bEiBzz*sf8;N~fqyG8%N|3NIfVOc%A>X5RS27X^2@BtB} z1oN=B=)~$`8U*m=vbn8-PO~-jbD1tg!Y$hkJ)@dp(+R|m`&+|9p#=C*l zYq3LC6DnMZ2dquN%6-@ISTCQv#TUKFv&VRhcbmtab95)d+96hFSMMj4 z|0k|ST(VBEzT~JD*0Axi&w5K4#U5kM&Y~vZxTGiukG@s~?dbRE{C_V%R#k=o_v7kJ zP)jRZ3U2<2@BWX1nGt8;Vpf$PA@aM%!O0yNEGna)<{`{P)-DQ7sv`6(aZD!&Aiqd7 zW+#b+!Z?8mLK94{#`IZ+tjj$HO&Ji4ke(;gOnx3IuCd?O1(2<8X&Q^*jUNGSHXZBK zVEms4!fLcXbmC_%)l&@o4bYn?v7CYoZI4^?-F|kxv7cW+h2B%Z{FR%e>nLcC49+(2 zn?iNfT|R;d_~7Egy~LXw`Z%QIV|M)emZ18JznW63Asd(B!aZojt&{`1W31sXMI`q` zG!JD+j_zQpg?g&BtG~^@j(`8Zg>##f$?Fz$B1SDK0sfWWA@y|RLrx>Str4xJDPRgS zl^W-5qKf!dxe<;6jsbQrYD*sUZhkToi0io2N={(@A{KL>*?4E(#o*EPsNygUVK&O1 zNY(ccbc;SoAkGVAWH1Q@Jd~py=~(vC;M}Z#tIlaGFba+2lN&p)5R$FPmv1z>Im!i~ zZen^$G8Ub&rq^-z8$@IDsu>)zV_rt_iUA)8i3}VMEkZ;lYQVV$bO-QjH*r`#+&2@e zyO(u45=FjV$Q!qg>LJSa{sa;S3v3bF2>HFJn94)O@-iA8fsXnIR3ei}&Ptv2XrB=Q zDZ*_8857_NNhk4qA3Dj(dtM`~379eKt`e_Ag!s|%{~}L+DgeLt^^y=~8IF%K`1#QG z>`LPXeG=byj6o&;ZJ9D9k8RCg9s+a3`UFNB8R)djNq$EOAdXeAA<2-qrn%5#ixnHX z!=ST=9W8IjzrP-A@s)4H$RJqhqRP)2+W3@=8OqS5RwY%PCw2>7dt5)-3mMZcM527R zL;j=dJmVzjYDb8en>=ewHsS81mOT}Tg|ZkGkU`Ciia90k=+{Ftyx#HY3CIcjS2CCW zk{3K2L$`vvqW^R|d!#0gtgQ(Ss5*cBoF^^R?`+K2@bc?4tbgPc85YE(BYfXBMaFck$}VC z-|QURa9X4#b4+VPZdKhFsh}dHByY< zh;--Q`zQe}3$gJ)DSA|#U}?%%fxmO5o(2gYU=G%4*X&ru2F+Cx&cc3i&=e5l4B|Zx z(zWL`cD84F>$=25i6i-Dn+9d#s1DxP*?B7%#l&xkDY8$qCgvsYDL9z;sHh^)yMYyc zretmXRYkn1U=V`udI`S|*j4RPw|pAxL!R5r+tlMawY&bp(I zi6ZX;v!`xcG^K77zasm8qOgFm&xWYg}5rxCE$ zv=7mwk+C$21+FLE5FV9oExau)u;K?5C?9YUQc9iSG4^mU)#{WN z{Y;&&PdJqKN(MNd>>;*kB%R%gzx+vYSr82m*AtIaXSS5mh(3Oel&(@L7OkLM!K9Kt|(23 zE(k}%sKB&X96$y!3Pj|9-DzB6h6P0!lDa`ceq4kfIH+F z9m8ZHwadnjm(=L~?SO;{{4TOztniYT1NFY>dRiWgc^UUZkK|O!%+wV7#Qv>#36r5S z_rNoye57N{%i?!xlm|+Dn+ESgh}iq=;kSRUN`T|762e7Hr%ZOglH%EHm^AyI=&_$A zovPpZhYQtQdr_peZGx;3SCz)NAJ>Ubu<0pZe%>*F!)WSJMGV@;EZ-l&OX5GK5I*}h zS*SD{EC_F{kI!o{%>~;{K1?2;gSCPk7wAX60?}8OeE2)%1B7*Jbm=07haw+V>CP`> zp6yM`cLAy?$K|{T<>K6MamK0wy(qA?Xbh6TzYcv~zHdsfk-Zc1nzlq_I0lr<%81XG zgjuqX-!;zkk6B1rt4jH>ei#myT;Zu)=TuZYA+$NK9#8r(0i#mfq$0Jru&ONd`n?eg z>hjasLdhR@=2P8_O7!nuCcfliW;zY=jaE>Dw=1is0{e$Os)eVWbSc7ABo%QwC1e7t z87CsNz=}C%X2it^5H8~t*UBoi!HTjBohOO<#g}jNg(anHr zH{;`?FTotGQh9HMb?&{ z{^Yc(>PykeU$xa$RuLa49}e;q{`Ie6$0+5rk3I0#_jFr{VDO)aI1|XDOHFzl3YHku zc(J)H7Rl%!k)WldRn+o;!aS9^v92d+1>c92y2dsoVMywFl;MPSY=NICC(QP{TNEm7 z(iXo{-EY%2x6VS?YVeEiYzpK{7JfjjnTgAa|mj3D@;Uj~uQBVgDm((&Uc5$L=ME0(#l)zBy z+r6ju)!(PS9wO}!DQ?eCDZ^j0WgEm3$5|BB7nn@* zIr71erL6SvkL>|z3H_t$&lSTNv@DR!5=efNM@8Nvc0T}0q`}u6Y;I1UV2uJU<#kFN z(=oXeA2)~6nX7|78nvgPVFhA?gLVyKO-{mboJ<)#|2QH?W_j?DVVZ?CDt%G41Bv@1;89tCy2m*@42!V~1n5axrU~~u)qr0T1s31rP zY_JicFpx&NnY4^Cq(mB-11XWN#qWH+&-47Q{eP}q+d1d`x?gt{PJdlGVPEc_$@T2F zf=tIk%Lbew#(wer)p(hSoS~k>Gb`S>ow%w%SW5!86Fe^Yn#4b9>ipqD{2Y$Ef*|v8 zceN82{s;r&}v3Y$ZqKYRQGB#HKFXcj|G`NN*f2OVm~DI}(dJA7z2@p3aE|nMw-B z#sc`=B|$}vWS#mzNhzcPEF(do~+kC>a$egyCfw|x57y7 zszGrrdB2RI==Ntlb@C6^%OZKD5u4o7 zF&no&z~dJ`mlA_E=z>w&g(_S0g+xYM3M;uaS}O^0IEG?TP_!;XFo+(cN#`T}{(6^sajE zsc)v}Xys=>TZum{3Dh)*L@D>`#$QGRdvfC}I3<#XJRz`5I-{n~g3duOPbk~lE&NaaAmJgTR z>(`REv=quPXi83r7w`87>YxE4fOdmhthB?H^GC9&*9f5OJL1JR2u(P`T_R2hA^$hW zqs3MXmjC$?|FS$?jV0j8G9NSB{}z2?-%KeIb=N2AWcoZ_f=#_)@&2GqY^dgV}`Fdv8mot3duPw4ue`nqNPx-x;_pZ+tGC z77*r=Dg5)gmwS%zl#vzdROQPj5WDqG%G)?9L_7HCsVh{RLEEh07ZeoDYqAg-tJe&UKMws>5-oPNz%NK2v%u(TRDf%ZI*<;1ZBKy6HQ4 zE=m99=X9kmPi3CYp6SAw{gfi%>ppRxoE(;9|An#X=z-pS(Z&AY*Su<$pnnA}{-PlV zw#cL0rbsKaS(BnQk;k1OH$`e=Y;>m0IHC$=Y)Z&NXR|z!1(pM+JoSG|e|M)pj@UK%(YS*;c&&X4F%&OjqKvH$pm_!~Ls>6V4=MUYrCX0%orIv5X z&ZSt4w=c>KsCCr)Ps6(K9IgFAR}N0_MOg4Edpd=yV!g)WJ#$HNKPV%>R(&(2y2afaWQ{Qf}5m6?KKMF z1XK6L5Uy)+G7_wRoIB(@7PW;URpf=(X821e{1*s?u&f-|eva= zRZ~d{+a8qYBat35BdZH$W|Q=UHCVB7OSRd5Oj{okg>lo`lDqEYEvZf|X_`4D^pKZ` zGUYf|_Ed>DZVrP&k~ud@18`ixnKNBtWTUhVfvMCQn~{m9@NxSo62dvlH`uSj4+DsaF8Y z{k7%O$<5hZ@mjYc-jZ5yf;TX{TN{+*a(r8_e3g7CXf9hUT*VSJfq^DCF3#Utpi_Pe zg8HL~yri0(PI@;ntnfo&MDu^^kMOZ%tZ-ucSC38sY*X89jGLiuIZjvJQtdC@H-sf_ zXxC&X%JJa+-AF!VIt=^{c5z#B;=s-HLD8n*Nj5z*`R=FugAjB~*IvFBI50xSDf>o@ z>q&3x%b+({C=NG571l_Lq{8wm5sY0vhTi^TUp%~5WWy}-*f{;r=?0XE`7GDBrB4;_ z#|gcLJuVSg3peV&zpOttiyq)B0#Yca4i7{KQTGZ^*-B12uf{o@6aO7Mm(g~eyyUhHzucge%=YH& zP{-q3IbuM9y~e!~{zS0e%C#Z>T+BmPbm$7*%kGZIZVUwnyA3)N-(p2Ea-+cwZ{eSiQd4cZ|dIW~_ zUhKXWUK4P&Wu)00rH{i8b+P-OltEhd(WEq(KR$?e&hm#{-S?+p3MZ^22*iYxGb0W& zaC_)-jv0~_Um9|z8Q1nc%`Qzr8&cl^hmvk^1Ozg#W!PPa07DQ9}@Z0fzH zXCBV!4zEqL3@vZ|$aSQkjp`;*Vb-yTevgWD`x5TGPOM}L9kqRq+iBpt8XZ?ZcxNc- z-Em;P@t?y>bM=yxGR+Cu3~D$y8`6{oHIFRko&xqoKEpSX^vw#E2l)*n1s@W^W((GR z5WL7Xt%Y7!a@MoBH{AAI#$b?3V+tXNX8+JYT8Dw#?^8qzh_&*gjZS0|Xjn|#-kkH@ zcP=YAp%z~Epmm2ANao~zxsHu5pGzAGlg(CZ$fFF)tAQz4^QvFYgti6#VT3%3iQ<b}=?{MpwJ;@O#Y zhTR-|(VJv*eRUbqw4od_R%YH4YRrt`+wvVYE?JK6kJTEvn3z=IU3zOEQHr?uOE+Cq zSeHVdcl0#S`p(kJnMH*C$Q%r3hK#zvyG)y#TA-!IsUD4Az)!s97$4G73CgrEdt~3b zCcd>U2+_+=k|nQSnQbG5GJ|Fm$?@VtH|9B0$-r%?M%%nE1}P<$h}q1+dQ$CYa$Ox%7!*Vp$5bnnMvIiPU>N-`L8G9qITJt<Stp~P%Ndp&OE%QUszw8=C&5+^uBc9xGLhH~Sfg%-jNa!h@(l zZ9V66@8nz%wvBW5B>z5d_CPN4>H1RTP)#ezgUJ*IGk?q(@9Lgp zET92GHEb15tZ75qGkqh<9sPm~CPv@x2_UYTof@5z2W2lvdnmpVOUTCMYEJJJOs5km^D=>mIja97mDlzfzJ8eS6`PEK@vsERgW$?Y_4Lf^%(?jJaPQotw-Jhn#J8 znB?Ns$pz*XZnji-+Cvm!tZ)-=jr@T|S}#AAFW29g*in<4^vFzkCyvib7*91O`SxU1 z3qeYMtU~}L9lyl-n+cut!b3(f5jZX?<2uy6D8#?EUm$`Q@H*;pbCfbu+$5!yaeDtTGFve*-efsZwLOl;`)B^OMEXQ>k?A zsiYt2CU<`auRO=k9~4ivTYW8fYt(D|a4}Pnbl%CzdU0ufUV4XfTiW0oGexhEW(3Y} zNYO$tg((-N^P}|(eX0`h))QSw{PsAW)?{h*O#3mX?iwGnWMi7SZi46{434)CKsf}t z5W#{Yc^4y_5^3aQZjvwdmZ9#|rSw6CT6;g>k|ZSuhTYSoR+C4A^qu}4~(2dBYs;prP#A}}j7D<$P%?19F(D*9ct@iNvtGNe0z zXa!Y*fxqTqoT#B+5|-$zc81{3tx<@$Q!O&BL?3cigpw zvC7D?4F>a3dgr;;cXmVn-m8Oz(RMrIM4}8J!2jGw6VYRK44Qd@@G$7Pfbe*$rLPa_ zfONmP_Hetm*4NK?uC33jk0P)k6Y(Y9;##J-f}5RDfgEVH_>+Wd5G7Ml?W*IJ`x6g|HXSkNSf6dA{>#Bc(xl@*&anV3Me{XsEmL9)tF3O2Q z#k~dyg6T*l3Pz8+x84~}03gIK#Ud%&cbk3kdS>^SVXT||tz zz=bD1#JH8=bebZJi^*p$-;|obga8b|#U62lQ{tKC&$ZWucXz&aC3=1PrMUQ#EOP*q zMttL-ScKP|Pg~U?w8Yuln@r7l5b9w!llVuI5d!4NfJi;;UT}`~>Jly58$V0;qcvS6 z)aIH(iR*YjAv@Hyu0?O0Uxgv?;!^ReBdX(`O>4Ta+NS~Po_iyuSyh)lzp<)n)Xc|_ z-Y#xPX-^2HT$IaCcQQK)H~PLf_%B4O-t(e4?MS=$44L-HI?S&py_ymxIH2FK=d(Wa zmi}U#8l%I}eyo%JmLM%?_#ZRrntR{tCUh!nU#c*EOSI?0V0b+u*NR)&X0ZufnRlpk zTEjX2-?{=@UNpw|2teBW-ezn%WfqC);Mf0x|4|*3q$Sv3w3s#RBdaoVjRN|l#CkFR zn=L741k4z~~HdT;iMac=;I&p%Qu4;jzYz9v@5Ts&>&+Zn16y#)dRzsolcdEN zW~Othb>_Qst8Tk|%fQUT6j~oQcdGko{qFtWLid9UpEU)`Jx%?IyYq3^Ge{1ypZDM0 zjZzvwdul-{$zo(5WUvY@ToCd0#`d1*|I-2tn657&j{Z@UstYr;+1wNeyh#qJelNM) zn#v$)#Ub>=ev@lVSqYn_I)FTZi3j}VaPg59h85kUor zHba=pjr>e8ev5O$Pp3E8s(a7H!~h`boa2kDf`hm-WB^PfYeCqCsv>yU9Z(+3-ia@5 z=;O9+0@*gNnprq#_v_C+nPQ|N)GAp`t7t@2$OLuD>&|iZaG_tmVLm~!{L#XcPKje& ze^;f<%Y&mlb#A$9C>24y5aZ>|9+SHopiHsdye(TZ*yg$~L-R}Ha6yJH#6HeM=K@Sy z1|A(-^)`3mweiQtGXUiKrMO?OsQukf`@R+9<^@__2CbboJAd$N(!sI*9BCxHriOFY zrpD(HsN4EJQKMeW?PZ78R8giRf}Vl7!F4Au{%V%>1FNy~1zReCj-eVdfn9fSwq1%} zTZ-gUORp^^VjgWp+28^MtZu5E?Y<~9K7lVjwBx}<-a|L z;ma)zxT-z&FHG`&yfj0pd#bJ5+ac`@#=*qKRwdmnHJH90OVEZ}Shyz1GBgp9hpEMa zsj)p+MAovYQ~@@Wu}ipjT#;TicTAfg@&*EWMPIaYd8;F{@w*A!{vRTcfHA%p*MS~=>aiq zSyFhg<({2WG|W^lWxdyZILkax-qE?%c9 zV*0XKn_<`_Ky=S_{fmVcckhmb%xfn!toCcIN|O`PoegLs4jm>d`nlnNn<#U5Acwj= z5g6OA`(@7ADCO7wx5$S~yk>Pn`_mQTGcL`Px}+(+6_GSv29Z)_Aj;kjFg2t7$>c=Pl4m={W?Ord9Z!m;hGB2ngWYEt%lmRA z{BvWQAvoUc82snAzC@jj%~V(1ZCzxNsIyrpUSWpQBfjlB^b4`1LH z{rBJ%i~94(ZiiTOk>ZWXrOsK6e@+|rO86K14hb?GOSDn_72W+vp63yqS9JJJ`?+)ef)@@>qB{d-Us+9Ign+S&9IMB=BF!vW&wkHeDTSz}Z9<^4m7U?<-8 z%Sg*dE<}_wb4t-75^nGgsb9BI5p+x-zn@y_?M1T%0k@N-&kyZgs_+jh&Dfp^H)GUX zk9EmQXx{;QAZ^@_N~m*0r3>I{S zgj?*ph9lYa6fC_3`5Jv9a_dbwaU1R7 zgwH;Ftzh%i;;Sv%^+)gC#dT^qZFrx*-1x$-T7`$KS)x)j*5RLQO8YBa8N*GXg~K<; zorAYFKiIl#sZz62)(+LrY@R~)^>}liVPQI*wLaM?GXz@-o`x!(uTGbUp6E}v`e~nl zL_R+$!#P`Ac=qDlPbO`f1bgno?vJQa3lICKI|vVK+G7C_)3~371l|Pxb;z%7kebpz zzI7l9>FqKAER$v(zEeG;vG%3FBTf%kw)&#nVUp23TqAzWhY&wT9^4PIrTbgcV~ zJ*RMvK>ngrWxveN;?0&ZkExu|p$lxvP0#EHfBxhi@`Ze!@lzX-(&}l1SM@lijfNg- zL*_F>A~H1MJA;c*LzEx;M)l;H=dBooVSM$_SBZy0W(Kj>jX4wxuJlg07+WvrUKoai37^InKX{9-;$R<4gdlWeC4Y5YbBl4C*Yh)fiCe!Ln z@eDFW=L}GKH`xR)&0txs(RJgzQXxi5yhQV#pD8pVufOnA{4 zO>HUH@lGil%i9>Qfv>n!^)Da&5++4TWm5^&p~qytoIq-!piv?3h#qK;I*RBE*69l{ z!s0+b(l5d-_DDSez_Q9de$cgI;}@_`ii!DHVesOXl%QOxV+!HUQ3=2kYxZfq{!aUx zNb6mPo;GT3dUL~L8k4x_5Ya1HkuoH*P?72_0sijLQ z@)fVfjCWHXYF7E1-8!NN2xZ2eNVPCpY+@}GJc}BZN}V0N_YUR_CvGBpPxnf!ptF)U7~s9F)U)jXwD=Kr)=I{;oTt$N0aWUznS7g9gP_`Hi6C zp4lJ{`@$ZB*CwI-V$Y%9u?dERAJ@kQ(Lb$St-bL^(IQ6C&3oG8Hq1a1`+g{A$MCOb zLKqkb_(LQ#u6!$7sK5V;_g7JPxnxE(#?Rk)`U}mQ4?8rm`^y(G-Y=+ zaQbB0HJS02!2*?8iKqf09m)00&0VET$ppP6=A`~QT1~IjyIq(z0~d4&JcBz$BI%M@ zGL9xrf##n=aqJ_-r;YwTTF{3a3mY0wmNeRFPAbST zwGE1Mx~ch-n1o1u$i`IG{#T$LR(_H#MaUuFRJzd7)FXyz0L5S2^bGfr4T<6;9`=Q8;4)c?_D2qfwez?L>< z8HQmdt0P@LWCAd?mQ4V1KB3HnPq6+>D&|&mxXXDa9Stth(i^yZ`EaawUc(lMVC$Wa zaz*Z%GL1VR#h(YY6U6JA5b_4rk3ci3AEF^!pKpgov?EW zSvtUaF}R87I}XhDWrgEr!kKJ7MGd+#S*!+#g^U+6i+@@F(&u};6(U7$;?sBbJHy^B zc2a-YU4^=wF(QJxGNixBrd)PCuOnPgco<7jq^5iWYdTeDeiAN`IHx5w0~Xal0=njd zG9nH~FI=~x-Zqa~$e_YxrWT|Jb0-_BSsdUCpVZ8y4AuR#ki|kP*S-2|*Dkhqke18bK!cUjc8o@d6#ji+6--b!V12 zg;_e?FtZWMfAu`dlc0-KNpF{1$r1ZTk-T5Gg5-11yY$78Q~H}Qw@0m0o87;}4XEew zSjq(v^R%;lK6$!fRm%sB_^Y~dhd!$_A6jCb28P|9>QFI?mm3_!y1O{UCb$2xGlxsu zFEF@5Ibp&uqMSrTmn2{dQBP*K8lF;1L?C50#O^!$>6Q$7qV?s1fc>wyM6W+w5Ex41 zj!*bU+RbXcojI5_9*oi8Uf7D{Yr-oOmza?I^c+p_^R1d??>A5d4<)?UkvTN~BP5wVa@6~I=8h`B|VH2?AyN%CVb*8)Mi zWP)^+#?p>cr>2srs1c(`GWE@;ltI4RZ>~n9ZD*ofS~%3qicMA?%ijo&m!(S7N2G2g ztdbkI%HYt-8ISmS$4IE3cmDwe`#Zc*6kpCh;$-M5f1Mavq4HUw(QVb%I)npxY)9eU zNS7DNYU5?9P;^K@#qMyA^Vicxyll^$yo8;}I_ypoESu|jmbXDZSf;MTf5OoQN1-N% zX2j_cl)Hw0J1hqWq>g0{Bxx(dKL7-qOUdZqv8%fy`SMXXZR9`Z^_>9rBI){@Q$SRvcnoan7g4T_CW>!U0nHqUm~|{irf$Wv zyUFKUs?w6jpSKB^JLoWn4E5@f%|>a?vPYn|F7D93{6D}ug{pt5ztFmw zEnOK_I!_vVpl&RVfETaFZT+%iy1~Q{J&*Ze+j0MkW@z%%IJZ+nL}pIgI8*4Y4vW(QQ(iH1*Owfn^L6jf%(dK0;M@7!| z9qc=DQXFN~?!2YF!B`%srn%RQ@s{Pxbq(jL6J{R=JMq|79nt6Sup3qRM&EF58yk`` zcbj!gTJc_^n&lxcP%?fnPD!A+@HrJpy?VVm3d~lF($90F(7=3b@<}%G{yVy(!-mP1 zw({_j?!7=nwC8bFESLSj^>lo`|bov8%1MsPQY@Albx;-h|6id_hZ_0_|Wp$`T0vBK4gtK^c4p&{eX6-Bg! zn++IW4)q#!4^%ivzsZAkTZirgiC&n|nM>q*%@*aXFUck*9!soW9*Md0+lDOJX~#u| zSYz4m6I!++mC3s0{Qu6GJGHMu!fz@grHyhRR@TQ2d!SyGKw9T6>o{~ljX&}AagvQz zFKc2*lvF6ML5}g_?BDeE>VQErJ0WZ{^elIY7d4Pv!GkPOqLcnUJ>xB5IbYfB21Vi@ zobB414fFm9{Ev#B$MR|1cmBddK`gD{= zX3hcR1fgDgz0TwE+t_Ft$!R3`wfa{WWKNMh;B>r{B+maTNUqnYTo*F&9~H@0;bN;V z^H?7AD`k>`@zsv)`!7|XV5(^=Aw{fVxD>9e-Dm1`Tx;KgcIe1AY?wfK>}mO_E!)iA zt*5bomsNT)6MhwN`QUsAoFCs0e4PhUZ?C_5peh`twi429rs7XAs-8$FEJ`H5lY~h1 zZSMT``%fqg2%4@Tt|lkH9A^e$S3EOO#?}^c_8xkDPd#BAW*tI^Ad@hfF+pV`lz;c) zqkU!fo??Gmxjf7L@$&MgGYuZj9&sr{xzu#WYj&chqbehJ>#pc-xi1#x|*cA_w#45wABgb zG5d6DzgW?tKXgZCmcLaA7?obFr7K2X38NPwZ;A(M&Wi?$=3_4#puKS{PD;zE1&f6r zxIL|G(Uj^nTc&O5UZXdpsl|3y$#Qyc9_0=6Mu13lrL+d>3rN=k1B zwHk849U94mayhtGkf3kOl#)2u<5)bJ^Lp9Q5f(Bo1#No|{}%SGqL;?}_z*ykl30g@ zvsR#on!kiz8L#YtAhin9|o{)!L!HAA%A#o za8THlMkF>oKYozwC#yieZ;q}U;?kyU8}m+^{`~_KRjKBVCaxi^V}DP~vU+d;nj_5~ zm`k_|+$jy(C=JHi{yhjOIQ(W`*SNhzvK7+3J&v?y_|kgKGJt%H&{LqnZzE{OQ;(uI zGAFm+RiWV$fA;&u?V$lg_!PBY6H(l>d42Brt~S$+YDEJZREomm*qm0|v$NhchuL3u zE6frLw~lbeCL3W_H;_Q9M|3*p0H^x#Gogl+fw_t+CoB1Be;)Td<4RKxUx*cX_M_Bd zfuCMh*>huIZg0w))!ZhTVP~+G)Ar zgdrz*aq^ZPC`Xp!u9R;9=nZ|*-lO`vluf&r?8X4GkII3}H{7g^R6?o_DpZaG7YiuJ zY*WcbeyZ65-^rU40hR+KyDRA!FJQ(cg#+u=fC9^W?fSyq>L^3w*NQp9JvW>iO!}YX z2J?`X>^}ZaD&%Y9o*nYz&-#){qg@E{%YKy%*N=fCJT_VB{u(a4_- z{mKu$Gr_ApR;RZclF6O(-vxlQ&?{=@bv0sWod&qa=(#Rk#5I|NKyrct%&%Qqpl(p@ z`0WWSeTg7)R5n!K|KnK+x20HG*YAs!;yx)F^~=Y1a@sRmTcUkKGhdMdr%2Y7m2PhP ztp@BeJsH_pCx@c3jWD*7V#{_1#w|myp)()ls;8+{r;9yaD7cFBvz@6oD49pH)Y8kM`BBs)=GLaZfAh>8YNE`X;Mu zs+O9z54kX~`hQik{-uWN?GvIcjL|7?=h~lKcmIY-i6mB@e%jm+bhQx>B%Hydl&hN7 ztajYl*;*1OK9HVjIenq`pTCCtj~q(eipLY$(@qCg7R_AFwbud4_L6!D@=nb}u+(Vm+qovt$|q68l5J4IrNSLX9Y zINv}xSvy(D^?ud{t`2N30mISw!T}I?N075`14zO7Le;}9Uv3Xql%Hf{mi4#;D7Y62&6xdFQQeq%v|_2?F^1tO`ht+3YL9}{Eu z#hm?O5spx3DQSBtI=##ZQ2e?VGG$IrTmq77wBN8Lj@y7=O0uDkvn5jl3R|ti02-TS zxAT-Wn17gCjT-u#epJWm?d^PSYOeP2cI`Q}iraO!)04F$*&Kkwhydy*$aGI1dbe$F zkj!AMwhi>gg}uQCpH4tH2V$NB3lF!}xx|$hTvBL^EElZ(u8{!|{RCB3y|!xQim(xL z=5VaST$OrdBetz^wq0y4vexbPDp6MAbS&i-$U!yE!dM(%QL~NZ6nsDKxkbFQV@pZsEdXIH;!`G|nJ<1pZCYJqVt&PuLt(UfGHRFN8c^t3W| z-Tb)X^oX9QJ3%^sVP_CWtQQrwzJXU$1GGksbIwOJEv$!Dk3u-M^BLxRMhF31)!lh_ z@6O8eONtCxP^`KI<7hLgYIFu9`r`#TZ||y>(1#AmxaG7Rs#!JdO>TUYkj?Sc)c4~2 zjqrLn9$r;REBW~Gb4w?=omhTA&A5q_01Fv>^;Z(1{M&d}O zMp&;gC84eUP!EygXCKy9^)@|5dsXD@V=H0ihnRNsKr#78(tn0ntE_g|#gj+BS?Y0- zZ4oSg4GjirkTZZoelwIg>oDzyJ^>8$K6N~$5i_P#%~r$co!D! z`zsPt$CyBQ()X*Nbxzgy<7JC{E~Y&euV(<-6!{(={+I^vll@GLEtTruV`d43R>)HX zBlXqQtd8vp8qPOe;P_mjlDDxt=twI$KVf~@fceW?=l`b#*o5T()8g@_S~uE-N>BeW zh{l9B11tPS+VKk)WwPY@VfSt{bBdh&TY`*Kum<@w|8r06yKU2&Hb}oP<O-RzcUc|LbSa&?qCA3##g`)+=)cNY71SCwhZ2%-S>?UkZ!Xop?_Bbi zDk2!G;rZzH*idf^7wV>5Q^YjA)BMWH;O?KCa@y15aet}=2eY*M=7WQc1r2-pql)m9 z-?Xq%CZJoyRivGf3zhKxcG^)((1Pnk=T|P;t(dh>F?`xhSi{;D#+9*2X1wn7fN9_TZ(0iS-wgq;R-rv{cB`4qfr`NAtvz zNuUBxJQ%WnPNMt_`Jn}ky7)}Ys7dHA(i*g+U)4|R-Vqnd=3fJs=Nufgkc$>}IiIzL zsN3@ZPu19gU+oUL(?oOm$C-7`XMw+P@?x2iEOOU(wh}X?ILG-dllII|glFPb;tL15 zWKKqe;Z#MMt#gYn#j0`6tc;e)&Nz$d;r%rR2~sUi=NE8N9#13-3r-z zwXsneQw8WR7!7+vR$rgu!68$7OOu}`rku5aNV4jA2Mkoj@!2~Kd`{Bj3ocfhr-5T8 z{|1rt>fC3ebyHrqlJ@z`0kk5;!@lq;fUHutB=7o5lD7UkteTdAYz|G3GyH=uu+i}3 zA?rC;`2tBF9wg&;&M|0jS8i9z@#l)ysWh3mUrwg--H2k7SB9DZu|F5UQ}Nt5Eg4L5 zVq;673M>EJT^G6Ts39$NVO#Ppxh#W4x?Dxv*3Yg{4|d?!mXzAH9fAIxqQM1c!k;nQqGOPR}F7|uvl4pCS2#9biH1cAY-W;&)F_J zieehGfyUh;Q-!{x*~?Xd^Nl{AH1{{ug}!={+y2e9v+dzP%~;PD=&Cl@h*ADO8m9P3 zMZ?^GaxV4jsn*ECncaWwxrhJu7Bo)gbD1S#*9>{C93KuMFT0mF7F^_}EpXybIKDO6 zs_(hse!?q;?nKJE;GE?P6UyY>T)j)3TvGj*JxI;fjf4l$kb9)lx`|bEGJaLAF<@9r zQ{d$7i=s29hOaN5KQFeze-;$=LO@TwDazRJ4D-#G2B`9nvR5zY3EV>O%%(Q~_S&Ei zDpzk1*P0>C)%Bi1`;fuZC9uMJ_TVvTZ8m)A_&5U#E*KG)_V4wHb~T^ys3?AgeFE;q z7R<#55TJW^t0hKgpYOH#r4@mbwPiPxxoK8Ps+(9J zfYody61CE`uGd(jEB&*)np*Py-tX)qE6(|~O#AxvBz+d_WY5u^G$R78A-#LYNldEP z?Z$8Sb;A9Hw{_)&;u^=Dn{*XAL20+QOP`aa4i0{J-npC7NFE`MUQ|${_N2EmW^;08 z)y58FvprtsKvnBbi}3fOUHIkw!G8|C7Hz-Ml+R(E;CTdBm=r{^{X)U4^?pBZLJl5V zl-7S7_E=w69<*fsyng%8Dh~UM5K>U^DM1g6Yt)#uw9Nlh_XH^jWK@Btj&Dtc%^43+ zx6efW^Jg?TQhika`zRt$ZialAKLeUM&fDLx%5LO+gLiJ6^TSgj`)NOf4YH0`dlD~W z+uX3FF5dMvmSaZ6_`!bDD@KXZ8@~gC5P1(M?)ZtCBFxm}Wf}DKACfX9*4Z?tn&&o3 zZ%}!K#Z9o#CI`6HQ?}6AfUV#DHp;m-iqX}512-T`t=v|TSm{GwuLjB#*tZRf^?2jq zZ6IvLwUiM=XnfNA$QipV+uy^T9=kmd&_i)h$sqR<0lRYBdsyY*S~FSI}XksSQtl|C(9a($}9!{1DGE z`+Hz6vt=^2BXhe&X)tqp$?n3DN|M^6|KR*7HQ#~AD3C{VWB8lMB881y^l$moB zr!YsEN4s5%GQTZ7b;}8_Wjit>Sh-Sc0IfC8&DOJgG_vi6RJV|SLv6K9OABh#SayEE z@jf{jot4jlGE8I4O(lYNVfbT6VTAeB^k0w7 z)lK&YgLP70n!fOLae8=|&~KjrIF0n=NVx&6R*6+FSZYOUM-=iTeh9AYPt^JQJL^t{ zHQ}lu!hkH}_NHnNRW0A9n0t0q?3JZeep%xfp~^n$#2JATFL%xiM{GDW9;-Gf%w_&E zyGPB!_a>~l&TPD~@#0GgIc|JpfPC~O=}@J|!@E5F@p7Yi(~_ZtKCR`l+CQy8RqwTF z3I8;y)We%RaJs5ZT@*&lvrwCN1;h{J;aq@uU+CVk&FlA0kUNg}A=aC&BNFGAG1gUG zP%|Pi(~<*`obz@H%l4iG;j(>}7oRSru4ge5%tyG*mcbQpC3MHVxt1r2>k=bRltx@R zoYagyKNcp{&pNeGI%2=`ELpuDk$f5!mE~iXor4{X#ZTb5;yWRWHYB9^>Y-kW|rIziDb^Lu(4SVO5Kp)eQImb*{|R{%|gw)3Eaj#hxSud&iM?3rKlm( zdTl4gukfcTY{yc6on&1VnmpM37A!ij`HUXnz9-T@qpcQ6Zv7q(j^L{d9&igmQo!O& zxw+sjlJbTMR@yEq?>@+R+`XbT4Sl<|moMyX{mw#->&Wj(_lg0xocy**F|7GpqL|g4 zk;}5pDtRAJ=1%GEHQ8=&ND^Cob3siLx6?oDgc}rCHWB4otyOiarR=TF{HY=|H7sTJ z9hR)`qW&H{S$x6=o-yWuuj8*^y&Jjkdk>A*!>jw1n`jmNs(bROcYVVkY>x+ zg?NwuzK8L|WA~8D;7aha?fyY|^?)BLzi+4i@gk;)4*cXqy3tdpI`%{Nd`X+}YCJfC zD(aMGvA^H&O5z_q(>}b|FD|p$ewgoFx-pBzNK1Xr#%#v&X}48J19yJz(b3zIdU`Lh z!EajdOX4G=kw!K9*g_9hXb;7k|;}d@*g-)QMkHz=R{#IxqZ8`rPUL#ld_1Zc+ zeJ z%uaGo)Xnco+P1*2qZEq!RNdM@~-e+BWgC zWqG&6hW-rSx-q05i6upS>3@~weY9_v<}Q-8ujij#i$i7*o)`4%iM$UI_>)tVcB~ZG z@o$LL^;Mlhy7*ESpU9#oI zx=52QolrFpdXdn(pa=-kTPT7cp@VcoRq06xO79>TkPe{)2!U_$yzk!UJkQy$-#J$< zF7hLpbFRCLd)#BrwW4-WxML6dx_nWvkG6_4AK``aO!mpNn%{A-M(%i`a8JQOX`0}5 zxU3DL%!4CQC3zK|smKKU_w~u?8X70*rXJDtw^&=hzg5<*SnFS_Wuc5rz&5tz8?PmZ4^qA0+1+8|U86uaWy3%fS2o z<;6wuA4&tPo>^9HulEn%dNA(d>^ohu>~u_-qzF6Sfcc*dI-Wh4`PXZ!|Hv<8og;#E z&wpksxR*+XW6!^9eW8_bX&K*&SNkZBYWMXmiK?i)+IEhXHTBn&jh z;9*TXn?%A#ARLhW8j@2CnJ!-;;9bSc7`(ZS@l(&V#cj~ATAkEr;k*p%wq*0NEj-h$ zc5m>O@qmu3he0Akt6;w3#A31?sjo&h0UtQ3xClnWWsevfM0nR_wJ+Ywbe{Ln+1p** z_3Km?UgNMH(koljO16bs9U^czf72H81;!k*K0kz)?KNAq(pm~{pxwO;tN8_m zb6FgywV?7U!SEKh;};pY2;%W$LBrWp#Qt-M&YTwkK2>OS8_1Qh6aq=v-_+B~Lrpmb z{;vJwEjd=OEU`7{$mPex%~$EhutyHX1H%KxqnD9e0;7ZPjXl}IvR z%{QAR@+I@`#?0p5yfrUq!VexUuTVH~&A=`3D#zIgl$%h>NXNSy;J(DP^mIj3t5OX6 zs-rSW;YK?lz$-fPu5`|n>e{x|{>QXo7x?ndt9ieK{RH8D!SsuKnT0Tkp9InJu|Mqk(Zl2TQBzrK9%Gp@mjJR&f)CTc@xHB#Fc=Nh+*cZ=$;sqK z0xWl59fa0nQCdHcL%>9LN)-m`#@P!O3*$|(RN~#+0bhbp0!7P&cTG()eE~Q_4Oak0>TLX zG3ViL7I(KDY-724gg^y(G53bW9=e#OyIcon?ajM3d)szGJv?gMCFy?Dhx&NmW#5*E zl~JuxP0)Sjcp*DO3Sk%}kbJTQOeoD<{$1#OLf1IFzvRZwJs&*q09oQI2~2H=re=t@ z&_HM^LrA4-I_zVIqCY;56z~9Mow5VfIQ$u%u3{zY$ggA_VgJgqpJ)~M5$%uWsZwd` z{yx5{v5+}y+r-77%K}?Vzd3(238DzTioBan;G=cAWo~wS-Tm;@V!d;@wrw zeyN_c&QQ~`3}atVrj@VE`TK~~i%kOv8*S#SqM#jeCsq%Rc1wO@t^WbcNCy3A#EF6v z1kba;YJVfw!q9JAtmALRr5VT3@i}c&%H1*b5GPz^NVgzfo7Bq33 zvqALxwj~P6^l#xHkg+9{3Oww@b;9SMlp1;U$q8VW%xKi5h0I{Z&HYw-;|qlyhL>MX z!)e{)O(C1~@!{6cu6nJ!x^$a1j*g6s#5t;pl@Ei#Svoxe+E2uLt98|S!#t3%%H}|@ zB;!Il>e&BbM97q0ZwD%Y&PFa)_Z!w0VkxJZ;mZKCi9l(!u}^ zR5$NamZ30Dt`gIHTy=awRHo-*rTY9%dhpcsgMClJFJSa?l8s@Bngn#RkA1mPm6O)N zIr(%?Y2VO<;Nal>A&m6%sgGcvG#BW+uMgLOmIcTDb&i$kvY&L*-yU9IafuQu6I&CT za6wHI$lYYWx68qQy*_YG$Arw0w8hwUj@4vf#AAL}_ z@ZRsF7zdy-0uL5hQp^MmztqZOai6KnN^j^TK$`XiX%L2iHR-RwE+Lf<2*-Zo`_?IG zo|!xmTfq<>ITl-=J%He=yik&Rx_WeYEF-E`s@%Axy%a?LG)@BZC6uJL5Umr%??=sz z>T53@w?$R5Yj0`WTR@c%2s@jHW?L`F2iB0hhtU=f%o58u0{;3mu5+(-m@mNK;M}-U zc2>Y|>k1Qj(U)J2aXPo9Nh-`zn z?5Z8fW{I;m=I)`epRG(m!l+|6jv1LR0WV3Xh^N;m0*S%=`h~^Hud`k}5vS#sqt}Je zX-Tf$(~d4T)%2S3$#2{pb3jeNx>p?*Q@r4yw(2LbIG_G;{PRp3Gy<8aFot5fS3b3} z=HwTGGdz}Iw1J3%2JiJcW=Mv1y*{6y0u=SDpj@m6gFz&Y8JsCErRL_2BPR6~6HWG|cdmsgu#cD|5*9A*3p z>>__MT@O202kui67{tRYKtGD_?k8zoEPhl7iqMkUd_Cd6)kBl6SI<{#l%(#iz`cr9 z#WjB7@SP7t9en?RpexfAGH?FTHPF?$Imq=bqlNs_R1P(nF;S*Olx~+gsA|3QF7945xwl{CutbJdAKaBIk;o*gMG zox%ru??jegb+Kg+QRzNCUS8cHd{J-TTksQ38TMYw(#9QDq2)W-V8IA8y92Kmx{=#X z&T+L!9=n2KuXUFvW6J9wuX@UMO>AGqE96!7#1w-cbJ+0l#LB zve&^Xxb?j~C@O#>`aDOz?3sfw{N_C9yexSfiV%w5hb872zdtlIt*jEx2s8qLnHGK>~$#ae>AGp#AErwQ^JndnyC8xk|>EG;Zz zz~8Qt>6CJrS@tx+1O%23>ElFq`p0Af+2^&kdInXE*NF4b$NNK{8GA|dw=k>Aa*;(t zlD0B)A{>|m1=HLhLXByX{-#XZ-QFzxkJ-5Z=3>mveVNw;2`4i9Y~_T<&DPHKWiJ0& zeCOw8e|7@=_=E(1LNmgHW{zfvl?sV1S^62A$o7(83MzE8L}NP`!FGUrMzUhcdSm(h!%pBrC_k=j}x{(hT6 z@N$V_+I7dvSP@;3^i7uKXcfbf@%sD%68t+y{^8VdjKSwG+~4V^*OcThA z-ue2k*MC8;b_1PW2`AI`69Me{<#tomP%M3=j4SHU91A&AXUe3ZhFbyx9E1t zR{eA{q3fuZl5 z6lo@<>YwI2I@;7f?WOMl+&#gkrq$jx(-P3b(b&?Eo?rc9M^?Tr zHS^UQP|5OAZ90yFmgQuil@3Kz=rqKf0N35Wlr_Na`;T>Blbyedt+dI@k;Ln?s)OJDg_XF;;2SZ zq%P=EKEyOp$m*E)Ax%yDC|foSISYdoCGSHggC1L@-MM_9uU~Y0Ip4+Xl|F3+K=`Wf z-A7Gxgs}49PHoG)-c2m-C-z=JKzI3(2|wNs=Ur)lnhkkTf;ghY?gi}eHhyJ>qPWq1 z>_yxU6Kfbhsi&l8t@DJLig=;9JABeeHa=2ddYK`4=MLq=ez_Q`OqQ;_Xa0#BJI|Zi zXMJR552Y9Vd-+%3`O>F5ZBPcoJH+y~qhLD!l{yh-j@@YvQ;sQ;pUgTPHFVALZPalX zA5RV|bl=li(c@U+MjH?oR#PHX{KE?l*6}dVdI}BW&}e)in1}C``qss&M*7wJU^ECJ zq7c-8a4R~5)}?g?##47-hO>ZWa(Mfk3DU(5U+p8~1U zl?lOO9f*KE&x8V0p)kV|ct5pMQze*!tKj4{e#naudT*S!t>>eeFXeEQX?3v0$;gWs zoepKqO4H@%1@vTx!eY0KXHGpr&OE94f>0iu2(PYS`|iP3MSZ<-y)-djZ;RhSeKAp$ zRhQ8vgur9V-9&@-wrRWuZ7dEG8&bP=8hG57h*(UgKlJ!YWY|H*Fq71}_m9;(+wd)K zEblIz)XdK&a~8TNs*YD|@AI=-5^vH`Rz$%*wO!&jyP}4rzkohh+&H}q(pj>3fz;eY z?ZJ}HS{G2lim%KNr%FJbD8}W>JER%)g6xvYL-G_*nn$g=Szzt!F5{PTFJAW)m)!w) zpWyixB8ERwCun^1*=*wIQ#y#L4TAjrj_T^pZo}g3cYPk~t3?Z%3K3y2^woUptJs?T&U{!RNHm90}yL&d%QwYzhS#9`t1 zF$8R_TntwsoG+CtWS$D>-nE_*zlzAdvQ4h>9!v0dn_2Vz!k{GI1Z}2Y1KLungm)6J zcu82^eimgV1VbpiQw-=p%{Iln+(w&qZe&>{7N#)4Qy|Hhs7m3*=oGh=xLNDOtGy7W z_NdC!I~t(uJjH{14^$j<-QpPq@AhNvc>T`W&m%OuhbN&aF`bRKF3nQ9-%m>k65%(rtCH9psge4p5>VAy#-|Y zBFi!BJBlB3-0H|w`1gZ%<-mps%gBfzInCswi*5qI9X=1cq^X||-P!uDvj8HiSTyW- zBnRO}6%lDW+UwVuUyn=j!!mR;fI188EDF+g4Pqqdo_FbS>ISPvJhrwULA*TRiWdg6 zWO;#3`_)Yx9xYg}jgl;V4oTXljvsHif@#R4FuX(+y-eV+$lR;V56vxVEo)H_l}*AeDfV-TyOd*G6jQQDr_n2#J?LYMSMS901wcraU|$9W(b@S=s#d-0sK z7~Q+$N0-K?OlpS$MzfW%7mM2nwY%xrqRLjT>*;a`%Xtqg>(o4xGB!y$T%{gnr|yNJ zm6~U~U1uD?BYM6G)1mqLTj&6B?oQhBk=9^~H4nnew7_+ysrkmz66}$D0(Z!coqhbl zn8dXD-KwY@9Cbg7`H9RbFbJP4S54Jfw&P719)(5I_3tM|;+OVRM|4Lmm)2#b?)}nG zo4SX8XYyYu%Qq14NS2jWf*rFO))_i$Nr*-_3f#O+xEsVVU|#E$`C@8wz$8#^e3PVr z+u#!h@QYPV!(6*$qWx~Du&BJctkgxcDilS2anDcYh|bT+1|qy$UWH@`vYrZxV1ezn ze*aRE^LZY7baaQkYUVgE!K0bx4t6Cl1DgTh;*0s(gn;Ue zVZ)q}_}_wRM@vwNPV9XGFh@;&J41U2sP(OP&@kC0z`28gG`-B~;AES4`chBdP~Xjf z8|kGNftWB@-#@VVK1wbIH^&Dpkzz7W8O-4B0m?+6;ZM zL77GK^4&Nkv+*2gM_vSN^wR!3>LSOHZV{E&VkS7qprI3$muqK%BE%^AtZ0oS_uIn4 zjLhfPZ?Hg7y&LEUjOvmd@Hjx~05%K)wR`#cb2MY!I^E-a7Hayl=~-ZMI8eXceCDtw zh`W+64%l@}0mwuo2r(=r>9OC;3aCjq5C{!V-#|J{~FL9~^*O{`BQ45=$3BA7RVID=GA-UYca`HqUM3%mBu7S>j;Fi zk`m9>l6O&#g&Gs zx|5Gu_l?qm#~~ki`&F0{A^K5R5R6$g^Q0$r0pkx3v?R+z4#aGI3Zt}4+yM%QJtA74 zIe6c~3%)yz5weLJ|MFTL1g$KouP=Xm-7aT!vlf= z>FIfe%`!GDrn}<5Wacy?vVHr=#cWXPpavqx>g@|?1uPkk5od}79`)dcl@9*=P=SXD zVPplp3Sz`GOJ5aE2;S`3v-VFwsmvo6)~VK7{EyWND8G<{Nfbn?UXIU-4YGhi;(e3C z-1KQh!HkhUJF#NE03%s|0Gx*Vz0WWaQ-U@;UM2%t7xI9Y&kc>`!??>Nxv59kJkNmb zJ7&pb0b+w54#bVz7w;j6Pk~+I@3^)%G+WFYBFQYCWXB9x=x-P4DK(h?d>;E9fEf^%hxQMcgQoYZxim!Z%a_0Px@?W9gTO80XSF8s~4CAFnVCe#L!HL zY+{^O`a$Jfb+xL7#yfn0&Vz62StM8#Owdl1&h(H$4QT7>10?Um>ti$?~=+P_fTfmIrd95686ZAIZvo;%3$Cb)ukPPqcJERiyZ34abk|~T70F7h$o4hLCXE-4!OxIvJQsIffm=cI;^_ znTq?^lA_YG__8&2{{fbSlJ%CPGWw zu}DlF8?e=M2u2Oa%S&GcgOzHy&Ue-+f=JI(fdagcdsoI$86kxH9QP;!0h4&u-cucs zVkr2`I*x%Wqbtc9@$D~l%Aj!h3-)#-)EW>?>@N4nRuwTLtdb?U&6{=EEW{(RC&(c9 z!hhEmFq8Guwd54^o*u$j0?_$TIjIoqNij>$<8;J{u20k&mxHBP+yj?NO%;d0;P(dy zRa)NgERIi{l!}i(&=i<}Hz`hbaNG#-@D->Di!Gm779%3er$~{@Ru^zrs@Pzgy{<%x zzRRe@+yPVeUw7SPWyx$fdlUn^aR@VIR^Ja@pGP+6R%I3k70{2{jKyPyi93D>G&miekc^wPZ(NOBMqwjN& zZGygURo%s0Zp$eEB|S}Vq^-z~;wSqhkF$s(b&DtVZIvOhRf2Tv6ynMLEY^)O(ODeNZ*bvl|V+^3>fOa);_0}u! zB4~9wd-HOlwso@Py}#70-^V&ES=KFY7LOlqfJxJW77l-jWfsZQI6km!ko)MPEutL4 zdTkx(Kir4(pT0SnHUaB@UaSD1=>r0nOCSJQ=S~#g#%zO*jfYuGnAX95bQqHDgE zXo|^fN}T?D^Vf34bO5!#2@$Q67MH)er*T{GhBgH4*(8qQDzgPa<^9DC#_>ZZw8lXH zFIw|$r#!GLGgW&?$lkwRQ`u}y^aqM5!!Gf7msf&@F*6t0FSsZnGPARuqLH$48@!$y z+7Jl9B_J<#PupM(FRb1-wqMR`VfcFeMxKRR@xai)o^_zzk1p&Pw}sWYYi=lht%4)w zAv(nYt%%k>1k6`vKc6YHC{bu)K^`;#4+uEBDw~e?6jw2+jx?0loL!Z;zz801L^x0O z-KsFEt8pr6Fd1mvnz!&zrEK;wf?^V;Oz(|Zl;Dxfb_5$AD35%_zR}K#V2uc$KnVW7 zsZjj?Mun1mgB0i^bI^K^oqP`#^A)ALw2uc`FKlJ)#Fy_#yw9JB6}5Prucpg&>NNGE zQ)lR3o}BynKi=|zPVeX-z52G6^7plxx(biD!mpzGRmmH`O(c#X%*aqt4|8Mct@BXi zLxZISEz->8TAga)-2^1yNRfBWjJZZH8Vme?ci)t|s_|e(R`t<=KnJ z|6x7Z|kVUN>!)mYl&R|Bup{vRg!-wf3yd0O|>7W>@- z_Z%^`i($Y@3V@XmFd`Et-1FQqC$k`=?3|c2IdPH!AH-DO=GH_xqoI=||tdE-Ah_2dfZ z&z|{U3Vqm?^Ibo0{EgVOf4_ZWomGy^jsCN51WMdVh-CRc&77n3#XS=7E!8u;&~uJH z(s(_|$PcNGm<@k!%)E89{hl_&D8fUyC-i>|s()KhA@!xje%qJ6h=*-ACla{7R|6YT zo%VT54cM%}{FiqP&akO5{?T}sx#<&cA=8$5!yzro^pUnM$xo`LfU`DFq0BdpBHa0U zUjJ$OMEcsz;?t`^>UDEL1?#lO7@tb{iBb_#O{ zbMCDhXTUZ%_Xo-sF>h{<|1pv|W7W=>Ye!wIFpV$$63~-&KN22sb!0sQ^rxA!^{8XH z4EUw5{`BORi~6I_0Ay1@oT9DZBWluAJMFHFK5SFX&a%Dv$KiEoX6TCt-uM3W5%_-@ z{*qh?r9=eJAFr1`1E67{bT1vXIOGIPLLBM-1T!xmHPdj0dy;9Qqs49xH}GLfd9<&e~Ko+0hz!x5BTxTuFBI#dQ<(7`V&N-qNJ3Il8e21nzEu~ zqeApgemZsLEGMw&Q(bs}YRU@uni=lWpAzsXJFr%CE=Qy%6E##(zBl-f7(-93a!O9{ zHlM*3?@P{(uKyL}|I@W{E&)U5Ovzt%;RrEmlMJ8#vx7LPp%+6+s5!%7p)v3Nyb8Wk zfFaI25?+w!3{P@fhdcjI)BjgA1QSl|!A>@+u6jf-aNU>o;-8)PMvZxVgm%_+Hibbm7Ssnc@wmh@JNfCUBo9sjWkP6DN`ukX!irR&sx zEpL>upr{BP$h&eH81m6;AmSB2yQzM#qlV^vSF67K_jw+9pP_#C6H>tgtTq_V^YW1a zt_g#Z%LV~o)32`|x zQT8Liedj6bP3c~78k9+6eE$CJq{m;hRvxn!Cr&L$ah(cQ<%un%eskBLJ2%uV?2!*W zVCtAa!7&JD_|;3&RB!%XdSdUN*4+b+>ClFo2s*5+oOtTdZR$N5)A{wj9_3jDTgsCQ zi3R3=90I)`1UMw>;y=FU?o zo8gL|bZr^_?#JMJl!uge$&y?7WBSYs%-{bCw`_OnkMO`nn4Ih&L`SB={U9wFKrP{u zFpxI@)>8Sc^Pd&zye4NRGt=#;v#74~foE9h|8h$u&&&el7ULKC_DZE5T3|8Mmmkqb zKD9}N>e9EVRt(#M|F)Q?g_I#}cgv}fN99KWpPnU15vL@4mJ?_ppX=4?q0&ij-))_k z@97Ywy+e_ecZ>0;4@PM;C`_i39DWXS8hKopAa-0HJaa{0`NP+4x$G4ng_6utn08+S z?!%<#{@rc#U2k6A3Afu+Th%>oX=pGBBxBDbq+n(b!k{L9nV3)eOxXH>a-jRnqr$SX z-K*^(@D9~&ce@9`6663Y@E25VxfW4F_p{M5|H#r`?;r7dr5Yn&-`!acp-M(CSB<+( zpW6LbKy%AKBUWg@2P@YjgdJpmTnsq@66($4Pwge4EG64y55k#61AIS~rFPZ71G%Mv_A5wkwMTqxeoYp(%TGMAp zKBdLBzTfi3G^eRQ0~gPH2?F>MbDrbIKlmUYb+F#rCnG_grRjIQWr>~BqfcXZU(o-{ zqLEY2`w{CiK%g_^Fcy@*9Uki@=(sjCq(7Eo+RZ~-=xu~#uMV?-uojtFI zzQ7T%YtrN~BuhHPXo!0B^xp#SRB$8X#(AiOn0ktu9@Gdp$Ia?L2aRYaOkJVpvbBPU^{+F&Of0w(2qO~OohKG)QM1~A8+)j0>-UutP7?1 zif~nld`w6zDOxOg;aV-2V;m zoK%z{gw{l6q=G1(cD&jy!GCA|s`$g}4S&_5VEC<#;eIMrdHGj(23=^Xn3{T~fN%wT z*%e212CsHXuEd{I%W3n5(|{iPZ-4)HoA;=k<|CS}AJ34)xm#mmxO2el_^-&ttIb4k z?0Qj(x+JIGdHs`KU|RGGLN43%B+t~em=>kz+ul;XZ~X_up;q~Fr7ckao6dnmbMwos zd>=Omo48f{S2jN4zU+NC5SYw~#PBS|M=a&1y#SPJ+Zj`?r(-~rsWu$Ho${ru$niRT z=^rIFHvXj{z3%bwapGMhD^&I3^6%fVtu7W9RQ?5zj~IfxWq%92d-pDx56K2qrQAB& zI&aB&!u;v=fmqO9MKIW11G*9SEB|N*_>&*Saw0)(z{w<5D3FYjQV(5E##K}DdNf}1MCA7Dp|I6h2;!A zpCC}SzY&BRa=A_r3jX-Nz4})LKme&FP(_P(KXJ*GR3LMMgWVodKjL%&#v{C`1$jns z8nBSDkiT0x@5HU{r0Bm|wD2>*@XKx1f@`rU`OdL1*F3s%1~Umia-u04$7vlBpOcrY z(x1O0>_-TJ0&Oj?Z1kT4#t#F=hf`NEc!i#%Ax`}7xt*r~jGyQmS$i^VID4=TQyWw1 zVq(joUsB`tPhZF2BB2L5n%IiZGZ)yf%)j|TmC_jM2X6gyNgD?OtSl#f) z(|>vC-^DQd@kx2M?Q|PEu>)Ko`^wph9X3(a;$j|QZ`=X?_~&=F@n2D|-aK)z)X?1R z)C4R)ds0|wiIw8~Ax5L_+`MQ01{H~SfcDwQ&#!@XbKC=_`m+CDw=X$TOC6A9`UVDW z@9ga8n3xCv_fzQT>nCk!ty++U&-Y_=hcUgpBJm!p6&VlmwRGQ^`tIG`KWrPySWC$S z0ygx71wR~u`P`jSwC2UZ;=Z8=pP7mDDZ#)9Uvb-UMgk@ zBKx_w!jt^3!T;vBmyZyPfIlp#h6fG0HFHg@Y+HQo97^NziW{t^-qIqf{1Y5U1~U68 z4D}<`nfq?vIyZp%bb6=K*;0MJbmX?1fn$8qas%8~(9^*G4B5mUb{MO~BAP8{e7)G} zCt5SVr2(3>=}g+am1eb_t;8}=XE5X(-hH^|ZSmDxWbf3wB2FZ{mA2t|a*0Ds9*m)b z#d_^_iEarHeo~%824{O1O{yx!4@w}7Mg0ejEJNi6Z|DkA;wY9rBJ25uVpL5(@DL{%7{BbFwqHQMd1y$T^koMx$=x&>+u+sV) z?f`z1%O0StX!T_0OJSD=3BBFLIYSzKs|1Zv5cBu-n(RJqq3)jC7tRJr2AQx-mCLLi zVXq!-&+6>&R7LvNIh2$qSJATaP^}MG47_^krW4XWJ!Q=8)mS~?8_sbLxQBcoQ6K(O z-YvnPw7fW8-iw`+*FW%+qj&+A9m@9$kw_fwaFiHz4%&Dq{=9D*T6^W{YXyw(b5Bu23zhFrZ|VIibB+tUDwrlduE1Zpz(EL`v$Xpd2;)bKs>zmg%Spn!8~K>1Jhoucgp(-;YSqs&4`?%( z$>01Oeoc@Z!y>vjVjc3)he_R*mfx5(2t6XS$rLjETJ{d{9QGn+lXtwDs_)q~1_h=! z!~4BDc9;AIl>~-7x|2XU-YmT#qE(nhvMgz`E?j@ZL+Ykuj{W(kfS7 z_1(tppgY5|fxU9@Z`aOInb*0fTkv`{eo{D+w2?3G9d>CQZ>~yOY1ZJd`60s7o1#2r z6h~lw-U0E_iV-wIL97L*ZiAU>FmCJRaV#A*Y2D1-iz;Cg5WTY%0_-NYwbUUAyMlVM z8ZsERI{R0O4ib1|elofmc;MW_=eDmhTsP=hh73|ZwY0jVUgg(aageO(4h_4cHlFNg znA+r+Fma4l^;sg^X7o&Ii-IxMFq_!I+jR z34F8h4STC^vFBLCs^xg1ZR07te%~6jqx@pz6?3?lC4m2VTvoZ}F+cFsLWrdP`<4y+ zJ%xiho*?A%PHVMR>3Dge!JE24W06m+m2T<4QyJRDf2D)Px)!~9mv`%uz+mZ_Ak4jI{T?QBk+ zKHW_}f$+>-5`=)>_JGgOlJQF}QJ!gAYrHq`<8@jo>>OJbYVtMQ*@aZ=_BwQCG4;>W zO2(ea`rl^>+)1;NTe-k^fZmzDK1ZS-w*vXuh50Xwfvr}RNL)1xZO%u|>t{vrpos;z z3BB5VVIu3avNO3w;rY*5s`>5&m-35^?1`M7-P*2lj&5};uA8LhWq#NF1?6|i0X#bz zeolo~6KA}qD6*b-(XzS$@qy7@a1n47>X$eoxrw18>NK@Rlc%DpqH)fsweCG0`EPKlB0(_<9 z5!muoM!>Yc1s7H-`k>@sm8isx8j5c4sl^&IU2BsWXyUA0*Y9UDm>zL^nep>- z+j}3IQqu!ldpWFQdcD@s?C+nI@2o^!Qnv5*VXq1!Wr5$NxFc^Jl<<%O3JLFK0UsB zQgoI7b4U%Gt>7+}%u_3r?id(*Din}z&&d9)m?5NdYR~mC>YM3#D9L%6Cxt`OI87=q zX})|yaJ^@glS9ZcMNY`0aPC0_%g|))w{fL2b)mU4Hq6&6a-~5GX zk4b~)!f8{~SAAQI>2kE_S2hGm)`t@-s_W!rghjYCE!dcrBYzq;z^p|bg5 zmq*!0MoF3bm5@Lp*%dcpKRqFIeE6)?zq-K8c)7S#^uC>*TZqwa7RxezpusuQ!st1$7$#k-tCuFlH#>cs}|sq#QiwPj?|p< z8Y-=E)T_F`f2%3za|v;aEJBy0yE}c;&X&!C+}Z3b+>|4Z(@Pg~))bu1@7R8sY;0Ge zCfM!S{%fC*64XFj?QVG+`?+^mLinLY+iKBccA1B7wn({JJ*H{*zW_yluugW=BNpJ78%q3=-Vb>A_ujFz!af_`U%8r* zDDPSDb4Yi*$Zrn)&WuKcr-0NUZxf~AiDXRLpg^e zogJ^9D3DM8(H_w|oyijp-xs&Lx2a8W@7)5Pnk>s8va1fN zNiQT7ULq9`Y(iKMHcZA0Y6(BN?g-?|O|bwk0p4Q;8h4AP`CAUsJ6|fs9DE{N0=}8Q z!f#WANstZ*c#baLENm5SjU5wUDN`UzFzmNFD(d-g?g*(#{E$7&Rcq^!&+0xH7EF4& z;4$i&%ZQ$5BQ7rjz00=CesN~n<4^{U_udZr1rLe|;bUiq%25XFG7ce0mU+la>Cha7 zc*Ww$EyJ=xljgdlTR54`c~#V}p9*n2nIo?I+PS}Cdq?S>C7CS$n#QSL7eR-5c3;jd zfxq>w|MkI#&}Jf_2*VBz@7c^WdUx;Q_PjR+@o;i~citnvkIE0c#^{Q{9^r*fIyAb^ zDJvv3*==YVee1W@)$sER@#EqjOErZheG^w|YfQ#A2+H%_w~lFeqxLSHYG3Pit4oTb zaP*pqtnNov2vc;6)pQE?|zOnpX~1nv)W6Y9K7MUM!%Z!kxapUW^nAj=7(G|Z$y z`|tGOtyOB7Rnp#JZSn8Szjl{n^QK zzw==^r~Fcls!Cda6nFYBtZZ)reiQ!Iev+igcFR&4nmNYfNE)bDjcVBbsYqkF-OLf4 zRQl##*Ze8NWw~K>FZ18pvrBZlY#9Rv9x24;EA-IcpWe!yl8fSs`=2F#K&j!gkyHQb z;8YTKO?V9FY9X~h#E%+DXivh0Uah6Tk(OSFA8qZn-r4!Sxjo$*UnfI@yL%m6Ah#xM z>Cm~jO}dth7V71dnb8`oEe}Mt9L_#$FwOFvGfk@M#}ly+vbOWM;PZ0Mqs8R1y{E~g z8lD!5tIa#@T=1cUy^mb)cr}#%PaNz#fQ5jPoCbs z`VxRm$s0 z5;}&>W|YS7Qer<*i>VEM|2@BtEFkqwki;K)0q0^LSzY^QkMksZ;;d-s+EIU9oRjhx zUFUQL%KT{E%ehQlm{OG6S=xV>GM`nKSzE3KPq0+NaBX5s5NZ;?x|Z{~x7~|s$-lFI z5>`b<=~@#;lV!0o<2aYXyD<6ley7u&hBh`G@U=P&Q407eVJX6$@PNB5X0yYF%QyG2h={ID|StK?3d zf$nfE{JV6}&)vS3cHwa!T$XIyHJMMD;`51%4{waMn7;e z3jEr=My_IMU2hNSaa83op2KGg{rWw*x|vw45@G6RHXj(sN6vY3Y`^s(ofh zBZse7{UjCCl;|Cb;tYcxbc^>~SW6esYPnIi@*MeCQ6ibYd_hDuZ6U&Pz?XS;j3BzlL_Vw=0TkvG^^a zuJw7*a(_C+6ZLx|4z4G~h+C$>q7zcNs17vnWfQI7ce`Sp#ZV*HeDM^`~`1UF+V zYw<|Ph^(wJ5UJ}D&yEjYRe+v<&b$RUb$dBK1x+p=CtmP~30(ZchJOIfDiPdN|WES?Pd3aDFOEC`wWBIZYVu{umSSqrVkTDlyJbpHeqQ#4mT?*V4EGJUB% zUUad6_ozYjeIOu^N_)va>u$cgip%HR&C3enw3rTv&8TcKi!Tjut7G+Oy$AW!*JGr{ z9nOYYeuUbiZV*JkM^-&INwYnf7u*6zOSX0<&!NwTjdx~MIVP~~s!0l{!bS?44H6i> z(ls93viK_0@4DL_5rFUT7FViS&zjhZkRmm&zEBZUsub^atb3Qnxw|@zjf-KzE8QJ( zOl0;XspMK6J~ey@sYdE*HabPm-8OMtpQxwwMbRk z@j{K==?@yU9HXflkU0CGcBVFGzd*#{B8&(=Ky7tOj%FavYw{kiG5UA~Hh9#JU$jeX z(5gZm?}p;x!!5}s$A)-E4#{!hi0jt%^WE))-|4&eQInsP_Fv_TfSsn*ILcD8q-K(< z$ryx5_wOq=fumBX?C3x?%8C^hgKc&|0jwv9`}|#aq@+$P=0sL1dooW6E^x^7-AQ@q zl9xF>P=Oj>WGVk$?eCO=rR6H{zw4EIcmSz$?4z)86k=4qXF~Gd%^V~okYu}6dh;2V zn;VEsaNh}pHTzTP#vr#2Umwc@;BTltihaadAiRmxtu#8Z2%-&fZJ)cqV5<2X+@{CU zB% zts}U-h`PjBaGKbs|lU}daZfQ0N5+^+~ zNhL~9%Zec(&im1soh;V%M3`3#I)d1Hq0ZIljZ;>Atp&-u$&@_IopYd}LACz129y z$kV=nFLc0ri3qAl1hwo`U2XdY*TZj5rPuv{Oah$g!7^3o6j@(iAF^PK_bgRMG|A!W z{h~`oW6i(!kwBquKRN9R>@Q3jyhGWDjNmRW4OE6%Sa7v?V?9pqu?a+t0E$HB;bB2s zW#{YWV7jWoW_`Oae&!G!IgPcqCvJ*>#E*Qn_V58kO9Zfm9yey@Dg z^jJ7+B|81C`ydaIDFD?DV5U3=m9kK+j~0TE{H(`7YxGtGodZ`#*QZUV%+1cQ zWFA?+^6``iiCGSL_#aiwrOe*(ulcQy}I7I6FgUD=G)ne`lzfG$!=qa z#f{^3!H9{4vU$zhusd6Jk>4EK-|Q|FZGG$+5A*?#(;Mcs?bc*jp5|6l&F^HSq}THq z6G_=*Q6o=T;gWAorpK$M_kAAoZj9C9`5Usz-7Dk9393j0Xh_+8NCdYUv1}blImIKz zRoz{763>tHdRX}xmM9i)I0^B4PDzwT}>N} z?u-hn!!2nEW+~#^$T-@tpX#QhwW>S|0CT#Dh(B+dH0?+z8>P)3oU}Vw>e>gUQ}9C+ zT;~IK1ncdkQ~MfO9xQ`pvT|RthB}6NBL+XZ&7<2e#}sDmX*xL>4F(IcGh2QC2NL14 zdvOXf_GjD@l0g!w9aT_5=P3`v-mCV<=c2b^UPa&WorOBc5rd+B9p`*|PF!?vp@fwl zb-~sjIzx$>&*q6gTf@rJ`0d%IFg?O5ayLcxZp@y2bwP_{s`Od$tvN_qkIBK*)E7>|T@nh6X&`s5> ztz@S<>3~Dv>uVoyJtS{da*lrcc6A?P`J*H`*k_^4$gfQ&X0w#tHxTJ_^){IDMJvkW zO&WTm41RBP+S%5aeB{bKb9Q=m#O8W?g%VM?;GmTKoMRZ6_>j#MqZ<)+e^gj+Co)VVY-S=QtR9XQzC>)XeEegX_gJ zYx^VCLeUO}0P^h|uA23gz0DktqWI0oMU}@R#5byq4O4z0v@6Z>^~xB{Ki{k^y1V0s z3(%C)SVz2rW(qRUVB3bX<5Jw!!jWX;bU*jNT4>F2rd-N1GVsuek|r_nV%e6p>)CPjLI(D5mv8lxGp{x-BvJ)Iqx%ULeY-GKmDyG;UzWw73v|&yQwaX4Dd4%$6I_ z!3NF(s99S0$a3?867HR~>Kn?s6BpC0?9)_d(0)#e-vn zrn^C#DWoesol#>ykH7$1B|;tFvZ^G*w?QCkR1vqV1UOHw7Ij#E81O+AFY=1xkM2R^ zW}vML*$N|DTsE800?eMX=06nba3X_#!1El&_kSP~Ur}wjg3RtBN5kMJiQvfIkSfYt z(>2JXt)fuPCX6X*+R4#5NX}T*JiEZ2%#FU&x`{y$e-Szm0npbY>BWhkvKCEPYBu4k zoxHDlWr`B=SZ_P?o0jT=yrJzZmzE%#q>_ofpqtJh`N7W6zI~5JPG?FcUr(hd=|Wgm zs7#gSOmq{E!yE0NhXxXNlv1L+csv-0Is49E@t#MI%hr5ppgs7I7e@J^lF40%tNYeV zS^1tqe2}yDzZrGT^p4sSZt+AMx3FqwH@NfB+?cM2G{*X}my?;|B*?ZJcYSvwj!X~U z-sokC5UQ_lo^V!g;&olOs!Fu1jcE9n$JvR8EPxP7X8SsR-^x!tzfOYUrBl?@DdJP; zc0*e=Va=S@fyYBoA1gJ=SECUMjV28xs3Srx3EXg#CA*Y3esBwAkv_ou)PMbvFtgBz z$G5!}K9lx5_Nl592daRi`d-55M;SEx?=RlNGdp~u5(Y!BL@^vp$yGUw08EAM##sA_ z^_&$VVVMw_h@=ZcRP9z(P;lj%pLcZc3|k6fY74FT#M&GhON4|MdGrt-<0EufJcZ^8 zPLzf1nF3sWDV(MzlXV!w>T48fQW`?$12iWKC22jaj9Ku2PLJ+!QjA_7U zJAT(CnRmwAz1HDp@UXjBK$Q77fa2&I(T-zOaf4gjT{;3w9>A>TC}v z_w&rneMLM5YVhgBam?P|@G7r}Xvye!nfwBNvy<8+P^m~xi#BVDli{5QV0)H-=zGJ1 zJ4QN^bD#gN1+dOw`*cuq`X&;Aret>33J}0KZtV|Wr>fuk#PS}%(q!y=iM9A}Jyirp zEAMR#7-T{-6Qgn&(+C|1CJk*Rou9`qmy0#Ixh|brlUF^X@rnJBRap>fT9(6D=|uX* zVNAJZ$lH!PP!j>unmSmtPoxU)y?CUI(!aq%6H|S&>4v*ZS^3;8?yhjOyn&|m_iK+b zpGTS}oQ_=V4@xbbk6QO@g|ue%IEfiG?W+{deHrb3L8xOt_VB1f)_UZWsh26DPOoH( zXl-}5X1A&`@x4fdePYr%#6kCzv%6G>wxT#Ib&zAVK+BflzA9dGQ?7VXAo4>1wrTC6Kvy*k&)zeuz z==2;P;r)^~t+)>`a+Z>kUt0DwJ%Rn>T&z#*@!5IAaeGDbj_;^IiSVY!FhRxH@zF6} zTZdr8`c9NZ#}mlO=8V?2)f*F`aw_ycJ7c_{q+H{LH=Ek)bweA^4dW-?@4i%D@X5zjdi&CL{Edd$LMqoina3l-~33&{FOj@@K! zNb#$+aGfVgv3EWhys^}wWLtze?3F2>rmY;7^?+ezI;X08_O$sq&j~|IQfrgD=QG7; zEoo=)#Sdkbc4S79dq>AbLeZ`aQ|oogK4Zn6`)o&v7@?gC#&b#gZ9I)WdABiaPkPje zg@!1$IxtEQ#urlUAMb!nT{8diJO*36oDbnw$~lx z&Ii-GMi%^rGRAfS9?1-;MVgcmhPFx6dE8@#PZtO3cUI4RTNCN~*dlCD8%MY(PZ8D~)p=%4UK3AQr@ zVbcI`^onJWY-BfmlejlY9C|0VkSuxiw$e!woBNy7t%#7)m)$0-gUSqsVBj+m$27rB zos>x|VILpFWFIKq1m330mi6Rhw+bSHD4cZ+EK=yNtt(|D7(dl2$hX{z zmQ%HgUKUb^qnlcg+txgp4vi7iW)X6I?)kV(IcH|WpR?orc?Fy0PnsjM_RP0udjJzZ z@p`0sy{!oBbEFImPh-`xRiwj~9uz(?9iELWbqWPfpS%^q<~3~MYTF|oSL+zzP^4-w zwyH;QclNM8NpCfY4J_Z4NdL6Gk$;Op>)VIA16(p3q#aWHe`1FY4p~btvNm4ft8A`( z&l9rerH%pEQcj0N?GlX1xU;(DzRH#mVw1#mr-@;4X)ClswG)JB@VxchI?sna_StXa zln(%ym@rqrNKr0Bhhe~?UEOf+^{-6mVcH9vCJ>T>(xe;!-H*r~MA>6`?k*AU%-z+R zVy7)D2i@lIEW&omi<%)#&Ln8&2oL=894K$Yc20b{dVHFhMbxgtGJYb*NgxGLvSyPa zy^djEp|jXrzZ0uax(qYA;qU4xc_=U+R<`)lfkxBETwP@SSE7t>68B>ip6x7yl|I9? z;{x-wg&+5(cg&A9#UTvI&`ilG@`Jp%)!M?;PRf&?kBA9(Jf{=<&NjC?7Yk!z_YTX1RT|$^MO^}SwU766nJ8M?U=^!QC~a| zFumNq8+qMZ5(1MhnLBApqOaC)t}5-FUcMGlR!G=`1Vm;&gCyb?9-R+XT4&|)-JwHFj02}^#))>*8ZHGh(`V=2XRA748g6n?hCCK1yNw_q_O?T$L@5QFiqdD;xCg1 z?!1?7d<4ms#MXeG?C}rb)yc?HjjWL{0N74s>zY;Xwi2)%6%3blEbnGC7D_f2J5ln$ z8AOfbDJQ+xxc9{&yEcO(+V^l%YE+<7Aj7L2K;`TWB}BQMhYG5A4IO{AR{RGG3gGfq z#Dk^Fu$MTkQBCw{Rd)29JEc>^_UhC=6Vx7JmKq)7xnGkwB-(T98i`To`99mL=MBng z?-(_Q>4H?Pqs^rzMH?1VIuDAAPH)REc2<(fv$S02P+#m*EevW;S4l8B*pVqU@Ng4( z*i_JYF%$K$vSr%@2{v6nD2V!GS-a5UyTRrncEeEM;xHm~dj)awR7ojfXmnJ{+PVO= z!8{t*Z|#79QuEnc5iK^c1Z!efgsg0}xmf2$>vY*F)EtM;E=tNOZ%5gwWt(?@wNWVi z-kQg24BQ_DL@?9waL0=GzHHn~v9-n|MZ^&UpD`#o&byy|EKSOjDl5KM6miU}CCu#q zY%%@J*3-XL8pANRNf|?xnyiuozi_L=+n6o|Y>7mN&_$gHg%Wzprege;@2dzZ?G0c4 z)v>~bnob{(UmD+>| z;Eo4&res`hMSwh&0A=muRDX4&3)7=05W$oudz-wx>ks>DgL&DsME0`YP`1hO4ulD=(y=Kp;=NF*97iw|)S z-@?ZD#?DA0@Kc6Oj?8{$qCTF)v3?I+WaDMl?$Y@&8e*YxRteN`Y|!LG0EVZq`tG*% z4bbG{OxFEh^z{SuZFS_N#YEDV1+_yA(uqap48BF;1KABo|Na0D) zD3luUUmfQ1{mAZyzjK=!Na-P=;`^l?K+NxwE97jItit zm%=c!Gs^?^s6eoq{?+#N_d6rG0BHs`g*1^}>8WE##hkuIMhWyCS*xY}A;0hJw>F-C z(@nS?*{Ty)n4b1a-;sUO;nR;Z!0U9u4{$UNE<2!ntR(-w;VFDT` znh(;f{?*_`x`CJG^lL=&_$ZnXOEa_g6BC-CK{GlxH}|bquKt>fH1g+kY4Dzo1|<}0 z&;#f#oBrbwI?CSdvmDLXy2$mC4u(r|ys&GXZe~>@fy)iJ8piYez;DfdOB>tFz6U;@p)bjVh(PcwnfwQj-gj?w-14im5aUxSd%lPIV) z-z$OJwo;O2<~Yo0XG)pT;3mZ{VEYBex=@L@XSE!qxs_Gq@v&P@PEN`BYWO?QDohC2 z6p3ukQ?wN;ET;dfD)OmVhWVDL#%p&muR_gt&X@)@ko8(2V`7RhA5;>Cs0K zLC)OvTd-3$*j`7Zw9$7koBx|`Z((ipT|8L1sI+lFMO9VjmhS3%qRjoz{|d06C$ib$ z5eSRO%uJd*qjcwhRr`0I%&f)8cLso7roT30_@BEa5XgNlvPx%;8yg;`1_jJQMXrTP zGg{gzKfA6V`!rL-G1ecJOL&%gB~iaM7m==Msi(#xpxnT0AqVZ)ix=Z{c!vzR%@-Fp zUr z_fwbr_~_|RDYsU=Hn*mZx;&Se*>`!vZs5W_mwI;i9k!C<5E_r1Q3LM@Lsb)N*S-l* zL*U;m^s^wspiBSn4{u)YRAFgR&>owW;;ES+A?@&v4xbdUlC?BD1_l9TBSPz12&;^&5H6rZvcM< z5EXmJMmvIo)1jHk2AHk*Z^x4jC_N9;;*JOWmwxgD#a_7E+U;(hCYyXgaSLgcDnms< zhsyJNZ%z}%e{%2Pwq)A>FmABl+x69wQ9oMU;GJggLo`FomLa|_Y}k~p{vL!ux1p>J zU0LC^aDHG#@;obEz+ymq?%%WgH5zXk%(wfu!4UNEmU~n5uv(Y86HLKIEFQa?bz5!@ zL91Jsy;IK%-qm&F-a?W{^L{E+iYmrWbf_;tilw3asF|qoxf^10V;@rH;6FZhdzE}7 zJy4$=9omO~6{RGzSk?3ss=;uMWhk)O|9NvD)Audv%#4y2nhAMu7>3ouOz1k;#$_9Y zwPESH0jgoEAkmmRxc+m}i4>JuZ?ZsxuvI&CO#c4OK}$^7)I;gc+&;cw2lT6`fe!#D zVVdw%4;lzOwd1+ke_jIq^1kC;orX7z*VRL}gp-l|xy#Q~U;hpjaTX<@WnUbMehcx$ zj6P-!2U+^Yt<1Sw1b(Yc=MSZ~sBXf$+)Rof!cg7U!i+Nk)OS(QVUGkZKl=wdAl)F` zS&)@4EB3tUF{`i9ahGX|SpPUttI#?lDdZKz%g(*u$#Ycs9`!JAL~U7`V|13`h(k=XmBk6k>_TpCI;| zZd^qr!AHkzEte$q9RJ?QECCsTKC+bn7x2n|o>l5PyWm0}v|*PvxS>i>_x1`(4jMX4 zG2-WSwb#PIyH|e~0my^G*Ip~4UQY=*IPSJk6IL~jJ0Lku@IsXNq_$}})+;U*ks1i- zfe(hmn4XCvboyee2yAlCAn8&0N(cj{Dcf`Xmr(xA7H@5|0Y6<-gPNT(Hl&VPqbSU& zs;iGwCKWA1V*Si%;N!Em22`@B20X7YHPHS|b|eG(uA(T25K*b$ zP=_5!>+0;bGxeD& z;y0XS=;q{B6GeM8zJJ=C- z2>r$*o}|St;U@^VJ4f{lM0q z^_bQ0rnh=HyPxsjM83qszho>m2_*^_Hlk%K!2arR8>Syy!02lL_8ejz%#yP;J*)7T zL^ZH3LUFz%M*sCZ15|o)09Wmgn5^`rVJF=m)piJp<9D?eg+JIyz<>p6yRY+I;?ZA9 z@~>$OgWUt5(Gqt|T4w}xI$AmDfl0ax+QR!hZA$# zXcxj6n>)~9f$~!8pilTuFQOVGDdMf)`14!Q-(o1=g(%(OGJv5ER@u%*Ct{SD zbh8m@zYw8*4Az|JL`5sqOS8Oe07xJYJfI_4a+DeRx3viT#%tvtWb(9{^d?UW?>nAr zVZeBsLdQgZ$>#t3$Yqva6PDH=`}W~ph+9BKhS?Zww^yiXDD957I$sZC<-7lqsNcVu zqe_wn6jaT)nH+A&?+(mJHprwK zyr8=;O_VQJv8ZN=gxz&#A#@^(-#Ihid#u?PYxlc8`R|0k%n^LaRIMr---+3ed|I`_ z`FJf4wTO*xwszbOxb>R)tm8S)|C}`#g*QD$BsG*l2h_marVq9-UM;7v=;l30zhR&t za)(NztcPSI==aI~K7_t^zyzuFzXANANwPyVkn!m@uMp8Enp2mp&cFUAZlyj%F&8aP zzitR_;HAcZ#iJ&)Se$)Po4OdKS!Ig8#-DeYwZD;S<&k&l>&^?!sf(@ZH<)8o;Jw4Q zz11V0lWG@`T75d3#kPsB`m?O|m7v(HL>+j!tc&pQi9?t2K2<{*R<(`n;B?LHAB-r2 zIQ-S+ubAlVUZ}Mte_U3-eJ@(%k6N9IhnDWYR0 z2MPgc1cd-e>0I~kwEr*mKYRXVIVGW2@M5YfMQD~$z4$Zys>#LbqtlB?3awjifwux~ z1#s?ZFd9HjT3E=d&t{LGvos$5(7hx64>Mdt!E6;gUb$Cv@0t7qLatu*tlD4CakO!E zgAxw&NqZ?lGQFf2OWtZY_KT60e*cFNMn3yKC?~{;bODJ1Yre#Kp^K3_WFc)IK#5D5$nk{nu{*Cv)2}No!O3JI9X9Zd6$`8b$BUBY$-JGNM zCnC~B{l&qNLT<*)AFr_U-N=w;yy*wpqq2 z6KHju5^)H0ioXGTKXuV%BLx)Jix=;Xw=LK{N2zM&q|Gn?0}qr%zJuNH*@KvC&6w~V z+~3^_aOxv|KRTu7T9Ea|jASB878};Qgsas15IZVc*y{ZB$YfYW&3fg~^&dv40(rR@ zr6&E$iaGCnl_{M=z^9WjAS_EMLKJHeA%E8bNbAQwX5Gg*S%{G9 zTFWa+-h8b=@+W3r@y5jLieqnMtQ<4YWnuNz-_$nvv9hOY5QPDwe`!;>@IDAXVEm|M z{lz;>*zv)};{4xO;zE91?)N{r#>!lhTKj|)|G9Ng-CNz@=_OHmR z7(`xwc$hHFRnmZQ3WH5D11|h~kj^Ka34u@$KD^a5p!^51mj>Q2tI&+j3*cS*s6p$( z{!BX*a0%*DMnzrl@6HI5gx?=8eGPp7dF|}-E8gm#@>1R)J?Q_b%Gm+n3NiZlmYam& zhOXaq{J-uQ7V zdPu);<$uoU*CYY}0fMLvyxD-`8CB!V!}Y)CkG%GrRv7vmp#vkb~e+yg@ zsLbI{%!s_f`;WvIJ_2D$hh7_*{#y_tX8nWLwTO)2y~rKjq8cP#`-514*C=ZO85tPv z{W2&T?C@WV`R%Ls4sxJV2^J6nTY?EpDh17%YU5i z6_kHZ;}#H-M2bI8BvKDd9z+= zK+KQevG?vn=E?p+$OpjqqY6E7k}3X?AOD_)I1orXw||(3CsI>KStXuAzw%u67=FJ= z_!AHqdYv;eeu01F$G@i$3<27@_YV{KTU*}?|D(W2V&Mxy>eiBC2(J%+Upd!Otu^2| zG(y>fNG-t>|I9{w5Dw;lt7vQF2AVMPkc#0SMluhk#@iS;_QeDfD6dkC(?7U}#DM%s z3b^ZH34osysJ$ltU^deLN3lxAm6tIf0ZzI}#S(uW?gEoAG`i{moFNk2la?ElbQy8@ zUH+jF;1U|H8D&DixYD8fZU3O<)j+vTCH~F2Kbb9IF)$f=#eOoAV&o0i|8(8|uSS1V z5c&Vls}UqXrS_QTrQ1K7wZErvhYBnpt3b4#q0-1EnhAn~dneLKt;;`XxGqLT)N}T; zd7VtocGbJ?T6E%&J?hIZ?Vx`*)A{&+i#P-rb3$9#ZECQDcdFLhlL+lP_)60NKi%!M z9f*%8H~`QICvag+OMUM}Pk?or&*-Jui}NbP zR+7sME4;9-P{ZqNU*_WcOjNX-z2{NO>849lUV-h&Min& zmubw4UKELdDs1Tu_>RvQ%%*?$E2U$3KYfRfh9VP zXgEpKyqJ6JFdxDl53uH;`u!2DG!#q@l`xOvy&NrZp|5r8wRx;qL?gPCLZ0=+9A@(G zICwy9=zomeH__){*X1P^ucIK>^^&%(vR*+;UC$$9+X^k4nok-Y`@`MLb?ZOQGX7=k zg&U9-;0e-Xl&T1UDQba$^IjPL!0CRGSHYy+z9jE@aZ70uDuL@L;E9&QQk>~XXr)%w z=F<5IZG5B0$%w92@pEsUjq<@R8Sd%Gr^a!{(X69-UJb+#p9@d#U_Jry-Q0v_f_0_F z4=0+5hge8J_iwQgPD2~|_H)9rh_mT*k;O2~uwq!1y^YeV{%EACk)Vzd>#t$T6987^ z4so;*1MoX~0|tfUxd3<8nZoI~PVj6`sSFS*p~hi(#95_)ku&j=mgmnPy;!gd_(xtc zUjxLnONxd~&7#GY`}UU`NIV5T;xO$r8V7cG;~K8jxbyqM+(Da~{JfTEv~S%!5QP=H zqG?D`>XR#J=iOhUmX`zr30H=LT!D=rHtCW;y$ZnWN^7>8vAV&&>YCyAta|jpqS97j zVQDQ6bsp7m0cTTqHHIqgO6H8dXEOJb{^+lMT&5_nwy+c(#L_qh;y%HO7-b3fjf$B5 zzCfG)z9_w;4z+romh*E&Q$ifOsq?tE0AgxT+j-o$VpQm4oxN-|Ga=q}cWGF6(lAUw z(cgMCEYjuD;!TV7;3nTn>YJ{UttP#y1ir2Mvhn9{u!G&+Zp#&L_eY$a3-6j?dD8_zw3{8Z6R(hI!VG)e@i0 zQ(mn2>Q}C~PhdB#!|`ZkInIvv^O#)r`X$`Ciz`=N_0?Yi>f%`W=DW_{f`t?@d9$l% zI+!g}$@-Yh;$ajU-9&`Sj&iI3PGosry68T8l8i`}rN=zPKWI4o5u`&xY$4>nx1v9y zVM<;$=SLbp)8OthP*~-mx5xiI&NTVwfoRCQYv1$%z5WfzHO zws`5v+Z_;^$D0pk#`$6qechBrY)*GCCD_^kQ{FIUoLBnV2j+FYn=&&;4_%~kQL#v# z&-Z!l<|lBrH&`LsO%hn6AFDI|+4~v;Wh!0(!Ku>68%0{y6)Fn~W@Aru9xBuVU(8N* zfvPW9Sh_`ne}72HsSZ(5#v+iuCcUm0$v%qfXxUa(S zz_3b8oOwL3< zH$!0PWKAy45Jh~M`TKdv`fF56gcZg7YuOnVEasH{xRkn8!OV=O0$LNrRCo5lvH4SI+Vm09Xp zH-TcA^+*&siBFm=uTLEX^ZwNgk zvF~SE<5{>)Z|5EBvz?=qMe{ZBp}r3{nXeW&E5m?;@jFm4{F-E7@#F30zY?SIi!8$R zE^1xAY!aebm6`T(iTd4S#q^m<=NURiY;84sRAnWZ5fx|-kF@pNO<1bm?b-Dk{if-8 zI!{Sjk?a`sxX!wAJo8}SXgOte(PVGTFpN{^bPo3#cV4m+sm-HQ!Ub0>C%8#+Jnt|m z=`10q{R;s{(FY8^{+HIf?9kVnC7#EFDI+-Q_hjFKOi<>JE&WXQ`cKiCxz+)gwd;L* zYe%0xv#iGsL6jWW;B%h>H{Wq&u_MGmiiXd7{2>a{ZL|A*77Gnby!Dkfe!}?$ry;h9 z000q1DfxQ(5^;grK@za~)x0aVWdEw{lTYx>HMOQ=mG2NT5$~}E#0-3&aaZnUfy|h& zwD*j@Ke;ORfk*hR4G<%a_$mg=2buESv!b>;3++w1w*=izm)fAVVa)`m%wG+Umt+r(Ub7@C&_CR znZJZBMr##TYWVUTe0|JKhIGGTJhowdTEH}A;1SYe(F zg%2>*t(Qs_d`kDwX%Vz3ZKp{~xXGK0Trn*d%{t{gcOsY_M3ddta!kgG_04g87k>}T zQa_`B)x+9)ut)cCR;OziTsY)?8HN^5}JQ5eXsKbDjx)v5UV^##Y z*ZJ|Iu)5ezMf)D?BV9|l$07?!k&b>ZI2%XxB*LdyNlu^@X>~Kzigah-7UtPbQ+93S zPI-OZ(MvZSq~xJX=Q=GY7CsA}XUDE^f!!|lh8MC-#M4kYQA4x*Bd`XI7F;x*Y_bD< z%W>NB8EwJ=Wz*7w!Fn^BajUX!q|c>{i1#uRJ^P7t`ZO#HDjv(BVrRVs-tFia5>`IY zwk8JNA`dXc@MwkNtk+?eu+ZUKhXXN<%6#e}UrT_mY{GlE^=g@K2^`mgm`T_dq#N|R zHuEv(>WmwlX^Umjx+;m=MP0jJVD1btyTz0#p7iDhE{;dgNWoFw{w#38+#JHqH_4|h zEwt=10m7Q457CD(oqI4G#D*LzvH2nNZs+%EmrUoD8jn;KDXK|F~8#2*O z+IB&Om?a5^r!us&6->_e%z*6Ajgc_Vk9)6`1@Oc7nA_(e9AUlX=7YgY-Tk)8B{`R`T zbZs1-+@miKinTyu13pre@UG!tB5$)IS-{<`1%FK(##CD(U&PAIKgf3O`Z;{4FXiIY z)S(%Jc8DpLRBrlpt=McorN^Gaw56Tlab8x8kUA-=!CM~Wx&iO!9g65;0?T(v4N$M} zb-~U{3-mM8DPif5rBejPGu%OJ7>CgAN`FQ~BPU`p`Q?vy6K5IC$w|%=bTQT|$?~F` z@bTz#7kP!)%rsgjJz`~iO@Y(x7M;!A(@y$q#Rto{tsDdI9zO~(Nf!@sTl#pS=4(Z7 zphC?-9lxNhRY}U=Ril`v- zwy%2GP)e+llL&uhznvOdqV+soGmgrdH3!aC<-FLk6740YzcBDC1(-;wLzlM57Ym;h z9CJJgXnH_4aKN#pDxX(xRk3|Bv!5_~nrSn;A7kqQ*V6G@NAj^D?cQ`aHH7c{a6ZJ3 zsYHy3byFr>SIxHO2F1(Ne$n}}OAaE`yWS_i-cPsdjch{^KJR$?_EV8=kcEkG-LGXC zG$UUl{!|KFL(*weIB|lT8Qn^02rE1=bqXj(M zGq>UfP*^b}ZrN{X1I;`U+cz6LE7_cFI&5We!ORLu}QqZsY!}>K7-C13p|urMf({a;JmAo%^wZsA@L#R3}Rl+0z_S z8l65%uYI}6VAAuu&yvilB|M1g7VBou3P<0JFp=~qwD8r6ar0X+-BINzN?1~N=rqqt zGV#M9*K~ij+qi1d##BqED1RxZ=)Hz+#(}}72(!p5P$jxgts?&-{e)GEgxHOBl`A7! zN%*6#5;%-$-M%-&P+2(B-H1=wE8IHQbPO2NMW$R`Cky`7gTOvfBVRe^P-|@0?62Q# zTtV;>A}*&0g5vkw3u#SPGf9`sWo<4X(OeLvmCWZdxY-1<=8m_fn{s1fHZ}HZ{RXN8 zz`nn)9Lmm*;iDU2OYjlF9HO|uO?FP)Dki{(QBY!rQ6!SHK6TfW&!x(z0_n#*d#VAl z*u2Wn2lx&yQOWv02_yj0F*HCu#Fwwqa^H_Umida~PkGO|e>7=eVZuTm{Xl287|Q-8BXGQuF;fh!jM5!yuC3|A_VK&Y z4>nIs*R=$(w8!)$a4c+hf&4S%~gDv`R&UX)Ydfy&FF&2)KbQQDqZ)(k?- zBg8X=3yGq_1^#niPEY0PkFEtkN<)~3PZ;vehOqhW4hWvC&+kLa7Qq2_8Kd{4ya#~) zOi_!2reSd>=X1B$men=Z6BA#HTJ8<7a7`a`pmc&2d!>O8-*4O(_}|tUP90JLjYF?z z3OhkUY|7k*&DT~$44d0pj&<7I51V*=bJu6%-fLktPze_NkTH(ZTb(T{nrYG5*k)Y( z8rR355PE!+68a(g-7r>0$Y5)wAM-cG34(xW5Si8l(-yto0)bi%IdD3hzY?3qw&3tF zMoUmlyDlf0CcoNgA2Z%S;ae|$LkvnWxRu2x(%;K+i`rmd!Vab!!%%xU3y5McYi*CJ?hH+jc-cn0u&G{0P> zwU9e)nY7Gy#vY%c6BE6*mMqzFb|f+T0-=D2A+@Pa>o49vKYDTgGtBD_worDuU#5QA z`}4x>u27@&5Auxw265j~f|zU#;^&Hm9MAdb#?yb^5L-Hz!Od*?8Di^L<3HFJf{b&B z?3qCRb7uQg;a-w-9NQTPb(Ksu8+?0r!U3ig@dBOUkw=3RS+p*)#|xsG--buL>&!&x&rT<%ojVDt%bE~xkC-PJpu@Ahy7u-(E?_( zAFHV|xz{1@b6ew)Y{wOBU$FY!(@<=Nk6i^)1mKRN!66`}ec^^lR28ivm4LWDa zB$(jm=a|JxU?ZN2T=6!*d}w4azYntV)%t~&0Jn@{cQ!^fD0#y8UN}|SJJu8bR8)Ee zPP9t*!gw3z}2V zs`x5EK8xI$%xd1?@P11KPKS3w-wUGiG&0V0U(K}|CKROGTtuCwH8dzMfJ65mbp^B$ zxau+{O5WfWXuj!kwu>NClD7xom21QMsc_@!R%b~skX4>Z)UB290P&?|T{;!EQ?JEV z8vbd{Xq4aWA%0CeF+@0K)liv~x2k;qsSf6%BW{*!B|*<>%FJ>!Na}AjAP!LYz4{-1 z@VYpeZHSro$lyH-N(GR4Zaavu`J$8gAp(h5NbrM6=tVj@jUHa^et*A* z7;6eyx~6L$OVKi1;~zUia@|IbY`d=GkeS)kZB&ZqzDE3o)BR=bghkLe62E_tpfKl1 ztZ&M0i^Xo`5Q<*9k3+91+t4!9$Fll9D5?1q)vaNu{TCm!8D?{i_n@BeCBm!Lt5b6* zqie&OMu<~g`OeZ-Ql>Q{zRhosBjIcuN)-(j2FfVZCEc3qI4lsWi z24aj#8=*o_8Md`Vn{7tPv0APb-lMeCD1nCqHyLDla~*rlKI2od&Gz>%Gu`1@vI6_c z>{esNwWC7@3fz1S%RL3|9(ybO;w`MTi@=g|#f$bZiFj)tut&RGqT?+z4iaBCFKVVW z>ePM~fEFq4PC4|t+A2NFtjUKSn> zA|)hpg%u;3??$uGZh#06S!(fZk9#9w2`?hTZ6PNuyE0Ax)OzI(VE`Sv5|mJxgS%23 zO`-qvMf?SW6cwa1{i{3VL8h?s9g{bR`KLITM3sy3KCF)M~qt6S!cZMq2#LU`vGBqUR0N;J2VE)SuN)B+i zYJs~11V9w5y>hWlV$-#EWqZo4iuw71S`bxtkh=7N3xHr^k!T( zDF>R4jY2PrOa9A~Dxmkhr^lmBg<7gD24;_*`kK*Oh`gLI&vI=Tn@XR%Jxtmqw7LtT zv`*%>mpkpW?rHbXeqTj$nNsHt9Odwbw7NPTpicsDwVsM#m_Zu*d}zBj+S%6t_(Xet z4Qjuj+$D8c%_#(ZcB$x@r7j02|4>75D34S>

vC*{JI5VA9{u=^08%_EFa!)EQL% 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%0A1FuB8fFt;Id~pVr@Zl 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

-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 z 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

(g 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

t-iUX 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½R&3q4QPCG9OmZ?W#32ObU-!Bj4 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 oYNtZP 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⁢%<>=-(5z}ji(3TksrMj=b~ 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

Aq5rA1=0P}2ZXlQsbz>WRq4*aGy)OPu=#*+pI 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 z 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

#p2_VrfU6cx!+^vgM*}l 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%0D?6(;_SX9scym4B|iWp~?v;T2UA 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

c-x4X2#L|6b+fM>p?=KZr}c$z5RZ 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

#p4E-{FW#AC9kNS^jG-2zt;-WYqf+oQoAAdK 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 From 1d2fafca7251b383e32eec0bffdd8f258ecd1c4e Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Sat, 17 Apr 2021 19:30:55 +0200 Subject: [PATCH 041/462] rename identityToken to token Signed-off-by: Erik Larsson --- .../src/scaffolder/tasks/StorageTaskBroker.test.ts | 2 +- plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts | 2 +- plugins/scaffolder-backend/src/scaffolder/tasks/types.ts | 2 +- plugins/scaffolder-backend/src/service/router.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts index e2386fae37..686dfc052f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts @@ -39,7 +39,7 @@ async function createStore(): Promise { describe('StorageTaskBroker', () => { let storage: DatabaseTaskStore; - const fakeSecrets = { identityToken: 'secret' } as TaskSecrets; + const fakeSecrets = { token: 'secret' } as TaskSecrets; beforeAll(async () => { storage = await createStore(); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index acdf32a383..a7acfd1498 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -134,7 +134,7 @@ export class TaskWorker { logger: taskLogger, logStream: stream, input, - token: task.secrets?.identityToken, + token: task.secrets?.token, workspacePath, async createTemporaryDirectory() { const tmpDir = await fs.mkdtemp( diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index 56d2f25e02..d7d57a55ff 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -56,7 +56,7 @@ export type TaskSpec = { }; export type TaskSecrets = { - identityToken: string | undefined; + token: string | undefined; }; export type DispatchResult = { diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index c77007a573..35a57da6a2 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -404,7 +404,7 @@ export async function createRouter( } const result = await taskBroker.dispatch(taskSpec, { - identityToken: token, + token: token, }); res.status(201).json({ id: result.taskId }); From 3f4c4a00ddbc7e8be831fb9d0825622879c36b5e Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Sat, 17 Apr 2021 19:31:22 +0200 Subject: [PATCH 042/462] avoid overusing fancy constructs Signed-off-by: Erik Larsson --- .../actions/builtin/catalog/register.test.ts | 11 +++++++---- .../scaffolder/actions/builtin/catalog/register.ts | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts index 070ad15ab7..16a918e207 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts @@ -84,10 +84,13 @@ describe('catalog:register', () => { catalogInfoUrl: 'http://foo/var', }, }); - expect(addLocation).toBeCalledWith({ - type: 'url', - target: 'http://foo/var', - }); + expect(addLocation).toBeCalledWith( + { + type: 'url', + target: 'http://foo/var', + }, + {}, + ); expect(mockContext.output).toBeCalledWith( 'entityRef', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts index 5d169a73fd..e9710f7da4 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -100,7 +100,7 @@ export function createCatalogRegisterAction(options: { type: 'url', target: catalogInfoUrl, }, - ...(ctx.token ? [{ token: ctx.token }] : []), + ctx.token ? { token: ctx.token } : {}, ); if (result.entities.length >= 1) { const { kind, name, namespace } = getEntityName(result.entities[0]); From 4405be0277f7351c9a9c157d79d4760daa7239de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sat, 17 Apr 2021 23:33:31 +0200 Subject: [PATCH 043/462] Allow entities to be shown in system diagram to live in different namespaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .../src/components/SystemDiagramCard/SystemDiagramCard.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx index 78288c46e9..e601b443de 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx @@ -20,6 +20,7 @@ import { RELATION_PROVIDES_API, RELATION_PART_OF, serializeEntityRef, + ENTITY_DEFAULT_NAMESPACE, } from '@backstage/catalog-model'; import { catalogApiRef, @@ -71,7 +72,10 @@ export function SystemDiagramCard() { return catalogApi.getEntities({ filter: { kind: ['Component', 'API', 'Resource', 'System', 'Domain'], - 'spec.system': currentSystemName, + 'spec.system': [ + currentSystemName, + `${ENTITY_DEFAULT_NAMESPACE}/${currentSystemName}`, + ], }, }); }, [catalogApi, currentSystemName]); From e60d55485ce52448e1dc750c652a57010345b11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sat, 17 Apr 2021 23:41:51 +0200 Subject: [PATCH 044/462] Use different colors for entities kinds in SystemDiagramCard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .../SystemDiagramCard.test.tsx | 8 +- .../SystemDiagramCard/SystemDiagramCard.tsx | 131 +++++++++++++++--- 2 files changed, 114 insertions(+), 25 deletions(-) diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx index baa8c667d2..34dfcfef56 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx @@ -62,9 +62,9 @@ describe('', () => { ); expect(queryByText(/System Diagram/)).toBeInTheDocument(); - expect(queryByText(/system:my-namespace2\/my-system2/)).toBeInTheDocument(); + expect(queryByText(/my-namespace2\/my-system2/)).toBeInTheDocument(); expect( - queryByText(/component:my-namespace\/my-entity/), + queryByText(/my-namespace\/my-entity/), ).not.toBeInTheDocument(); }); @@ -118,7 +118,7 @@ describe('', () => { ); expect(getByText('System Diagram')).toBeInTheDocument(); - expect(getByText('system:my-namespace/my-system')).toBeInTheDocument(); - expect(getByText('component:my-namespace/my-entity')).toBeInTheDocument(); + expect(getByText('my-namespace/my-system')).toBeInTheDocument(); + expect(getByText('my-namespace/my-entity')).toBeInTheDocument(); }); }); diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx index e601b443de..c7a9cfdb01 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx @@ -19,11 +19,13 @@ import { RELATION_DEPENDS_ON, RELATION_PROVIDES_API, RELATION_PART_OF, - serializeEntityRef, + stringifyEntityRef, ENTITY_DEFAULT_NAMESPACE, + parseEntityRef, } from '@backstage/catalog-model'; import { catalogApiRef, + entityRoute, getEntityRelations, useEntity, } from '@backstage/plugin-catalog-react'; @@ -34,26 +36,106 @@ import { Progress, useApi, ResponseErrorPanel, + Link, } from '@backstage/core'; -import { Box, Typography } from '@material-ui/core'; +import { Box, makeStyles, Typography } from '@material-ui/core'; import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; import React from 'react'; import { useAsync } from 'react-use'; +import { BackstageTheme } from '@backstage/theme'; +import { generatePath } from 'react-router'; -function simplifiedEntityName( +const useStyles = makeStyles((theme: BackstageTheme) => ({ + domainNode: { + fill: theme.palette.primary.main, + stroke: theme.palette.border, + }, + systemNode: { + fill: 'coral', + stroke: theme.palette.border, + }, + componentNode: { + fill: 'yellowgreen', + stroke: theme.palette.border, + }, + apiNode: { + fill: theme.palette.gold, + stroke: theme.palette.border, + }, + resourceNode: { + fill: 'grey', + stroke: theme.palette.border, + }, +})); + +// Simplifies the diagram output by hiding the default namespace and kind +function readableEntityName( ref: | Entity | { - kind?: string; + kind: string; namespace?: string; name: string; }, ): string { - // Simplify the diagram output by hiding only the default namespace - return serializeEntityRef(ref) - .toString() + return stringifyEntityRef(ref) .toLocaleLowerCase('en-US') - .replace(':default/', ':'); + .replace(`:${ENTITY_DEFAULT_NAMESPACE}/`, ':') + .split(':')[1]; +} + +function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { + const classes = useStyles(); + const kind = props.node.kind || 'Component'; + const ref = parseEntityRef(props.node.id); + let nodeClass = classes.componentNode; + + switch (kind) { + case 'Domain': + nodeClass = classes.domainNode; + break; + case 'System': + nodeClass = classes.systemNode; + break; + case 'Component': + nodeClass = classes.componentNode; + break; + case 'API': + nodeClass = classes.apiNode; + break; + case 'Resource': + nodeClass = classes.resourceNode; + break; + default: + nodeClass = classes.componentNode; + } + + return ( + + + + + {props.node.name} + + + + + {props.node.kind} + + + ); } /** @@ -63,8 +145,8 @@ function simplifiedEntityName( export function SystemDiagramCard() { const { entity } = useEntity(); const currentSystemName = entity.metadata.name; - const currentSystemNode = simplifiedEntityName(entity); - const systemNodes = new Array<{ id: string }>(); + const currentSystemNode = stringifyEntityRef(entity); + const systemNodes = new Array<{ id: string; kind: string; name: string }>(); const systemEdges = new Array<{ from: string; to: string; label: string }>(); const catalogApi = useApi(catalogApiRef); @@ -83,22 +165,26 @@ export function SystemDiagramCard() { // pick out the system itself systemNodes.push({ id: currentSystemNode, + kind: 'System', + name: readableEntityName(entity), }); // check if the system has an assigned domain // even if the domain object doesn't exist in the catalog, display it in the map const catalogItemDomain = getEntityRelations(entity, RELATION_PART_OF, { - kind: 'domain', + kind: 'Domain', }); catalogItemDomain.forEach(foundDomain => systemNodes.push({ - id: simplifiedEntityName(foundDomain), + id: stringifyEntityRef(foundDomain), + kind: foundDomain.kind, + name: readableEntityName(foundDomain), }), ); catalogItemDomain.forEach(foundDomain => systemEdges.push({ from: currentSystemNode, - to: simplifiedEntityName(foundDomain), + to: stringifyEntityRef(foundDomain), label: 'part of', }), ); @@ -106,7 +192,9 @@ export function SystemDiagramCard() { if (catalogResponse && catalogResponse.items) { for (const catalogItem of catalogResponse.items) { systemNodes.push({ - id: simplifiedEntityName(catalogItem), + id: stringifyEntityRef(catalogItem), + kind: catalogItem.kind, + name: readableEntityName(catalogItem), }); // Check relations of the entity assigned to this system to see @@ -119,8 +207,8 @@ export function SystemDiagramCard() { ); catalogItemRelations_partOf.forEach(foundRelation => systemEdges.push({ - from: simplifiedEntityName(catalogItem), - to: simplifiedEntityName(foundRelation), + from: stringifyEntityRef(catalogItem), + to: stringifyEntityRef(foundRelation), label: 'part of', }), ); @@ -131,9 +219,9 @@ export function SystemDiagramCard() { ); catalogItemRelations_providesApi.forEach(foundRelation => systemEdges.push({ - from: simplifiedEntityName(catalogItem), - to: simplifiedEntityName(foundRelation), - label: 'provides API', + from: stringifyEntityRef(catalogItem), + to: stringifyEntityRef(foundRelation), + label: 'provides', }), ); @@ -143,8 +231,8 @@ export function SystemDiagramCard() { ); catalogItemRelations_dependsOn.forEach(foundRelation => systemEdges.push({ - from: simplifiedEntityName(catalogItem), - to: simplifiedEntityName(foundRelation), + from: stringifyEntityRef(catalogItem), + to: stringifyEntityRef(foundRelation), label: 'depends on', }), ); @@ -164,6 +252,7 @@ export function SystemDiagramCard() { edges={systemEdges} nodeMargin={10} direction={DependencyGraphTypes.Direction.BOTTOM_TOP} + renderNode={RenderNode} /> Date: Sun, 18 Apr 2021 00:54:03 +0200 Subject: [PATCH 045/462] Add changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .changeset/healthy-stingrays-shout.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/healthy-stingrays-shout.md diff --git a/.changeset/healthy-stingrays-shout.md b/.changeset/healthy-stingrays-shout.md new file mode 100644 index 0000000000..c3ce59ce1f --- /dev/null +++ b/.changeset/healthy-stingrays-shout.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +SystemDiagramCard UI improvements From cc9af530b3c29d4d55bb8991b00dbe3bf0b339c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sun, 18 Apr 2021 01:08:08 +0200 Subject: [PATCH 046/462] Fix prettier issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .../components/SystemDiagramCard/SystemDiagramCard.test.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx index 34dfcfef56..738d344941 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx @@ -63,9 +63,7 @@ describe('', () => { expect(queryByText(/System Diagram/)).toBeInTheDocument(); expect(queryByText(/my-namespace2\/my-system2/)).toBeInTheDocument(); - expect( - queryByText(/my-namespace\/my-entity/), - ).not.toBeInTheDocument(); + expect(queryByText(/my-namespace\/my-entity/)).not.toBeInTheDocument(); }); it('shows related systems', async () => { From 693c441923f774c28ef12c99696678147aa7dd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sun, 18 Apr 2021 12:44:02 +0200 Subject: [PATCH 047/462] Use entity route ref instead of generate path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez --- .../SystemDiagramCard/SystemDiagramCard.test.tsx | 11 +++++++++++ .../SystemDiagramCard/SystemDiagramCard.tsx | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx index 738d344941..337e9d12b6 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx @@ -19,6 +19,7 @@ import { catalogApiRef, CatalogApi, EntityProvider, + entityRouteRef, } from '@backstage/plugin-catalog-react'; import { Entity, RELATION_PART_OF } from '@backstage/catalog-model'; import { renderInTestApp } from '@backstage/test-utils'; @@ -59,6 +60,11 @@ describe('', () => { , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, ); expect(queryByText(/System Diagram/)).toBeInTheDocument(); @@ -113,6 +119,11 @@ describe('', () => { , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, ); expect(getByText('System Diagram')).toBeInTheDocument(); diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx index c7a9cfdb01..5fd32a6298 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx @@ -25,7 +25,7 @@ import { } from '@backstage/catalog-model'; import { catalogApiRef, - entityRoute, + entityRouteRef, getEntityRelations, useEntity, } from '@backstage/plugin-catalog-react'; @@ -37,13 +37,13 @@ import { useApi, ResponseErrorPanel, Link, + useRouteRef, } from '@backstage/core'; import { Box, makeStyles, Typography } from '@material-ui/core'; import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; import React from 'react'; import { useAsync } from 'react-use'; import { BackstageTheme } from '@backstage/theme'; -import { generatePath } from 'react-router'; const useStyles = makeStyles((theme: BackstageTheme) => ({ domainNode: { @@ -86,6 +86,7 @@ function readableEntityName( function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { const classes = useStyles(); + const catalogEntityRoute = useRouteRef(entityRouteRef); const kind = props.node.kind || 'Component'; const ref = parseEntityRef(props.node.id); let nodeClass = classes.componentNode; @@ -114,7 +115,7 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { Date: Mon, 19 Apr 2021 04:21:26 +0000 Subject: [PATCH 048/462] chore(deps): bump got from 11.8.0 to 11.8.2 Bumps [got](https://github.com/sindresorhus/got) from 11.8.0 to 11.8.2. - [Release notes](https://github.com/sindresorhus/got/releases) - [Commits](https://github.com/sindresorhus/got/compare/v11.8.0...v11.8.2) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6a926b1d7f..4162d2c3ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14234,9 +14234,9 @@ google-p12-pem@^3.0.3: node-forge "^0.10.0" got@^11.5.2, got@^11.7.0, got@^11.8.0: - version "11.8.0" - resolved "https://registry.npmjs.org/got/-/got-11.8.0.tgz#be0920c3586b07fd94add3b5b27cb28f49e6545f" - integrity sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ== + version "11.8.2" + resolved "https://registry.npmjs.org/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" + integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== dependencies: "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" From adfba5a5032263f1847308f222ab74d008a4521d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Apr 2021 04:41:53 +0000 Subject: [PATCH 049/462] chore(deps): bump @material-ui/core from 4.11.0 to 4.11.3 Bumps [@material-ui/core](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui) from 4.11.0 to 4.11.3. - [Release notes](https://github.com/mui-org/material-ui/releases) - [Changelog](https://github.com/mui-org/material-ui/blob/v4.11.3/CHANGELOG.md) - [Commits](https://github.com/mui-org/material-ui/commits/v4.11.3/packages/material-ui) Signed-off-by: dependabot[bot] --- yarn.lock | 176 +++++++++++++++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6a926b1d7f..7de4e32953 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,10 +1616,10 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.12.5" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" - integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.13.10" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== dependencies: regenerator-runtime "^0.13.4" @@ -3720,21 +3720,21 @@ integrity sha512-aIRd0Z9b/HJ/O24KOaP7dNsXypMnXhpWrpLVYvQB/JesVqXYSbioYND200sR+C14a0LSCp+qWnWCnSXmN1hWGw== "@material-ui/core@^4.11.0", "@material-ui/core@^4.9.1": - version "4.11.0" - resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a" - integrity sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g== + version "4.11.3" + resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz#f22e41775b0bd075e36a7a093d43951bf7f63850" + integrity sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/styles" "^4.10.0" - "@material-ui/system" "^4.9.14" + "@material-ui/styles" "^4.11.3" + "@material-ui/system" "^4.11.3" "@material-ui/types" "^5.1.0" - "@material-ui/utils" "^4.10.2" + "@material-ui/utils" "^4.11.2" "@types/react-transition-group" "^4.2.0" clsx "^1.0.4" hoist-non-react-statics "^3.3.2" popper.js "1.16.1-lts" prop-types "^15.7.2" - react-is "^16.8.0" + react-is "^16.8.0 || ^17.0.0" react-transition-group "^4.4.0" "@material-ui/icons@^4.9.1": @@ -3778,35 +3778,35 @@ react-transition-group "^4.0.0" rifm "^0.7.0" -"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.9.6": - version "4.10.0" - resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071" - integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q== +"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.11.3", "@material-ui/styles@^4.9.6": + version "4.11.3" + resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz#1b8d97775a4a643b53478c895e3f2a464e8916f2" + integrity sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg== dependencies: "@babel/runtime" "^7.4.4" "@emotion/hash" "^0.8.0" "@material-ui/types" "^5.1.0" - "@material-ui/utils" "^4.9.6" + "@material-ui/utils" "^4.11.2" clsx "^1.0.4" csstype "^2.5.2" hoist-non-react-statics "^3.3.2" - jss "^10.0.3" - jss-plugin-camel-case "^10.0.3" - jss-plugin-default-unit "^10.0.3" - jss-plugin-global "^10.0.3" - jss-plugin-nested "^10.0.3" - jss-plugin-props-sort "^10.0.3" - jss-plugin-rule-value-function "^10.0.3" - jss-plugin-vendor-prefixer "^10.0.3" + jss "^10.5.1" + jss-plugin-camel-case "^10.5.1" + jss-plugin-default-unit "^10.5.1" + jss-plugin-global "^10.5.1" + jss-plugin-nested "^10.5.1" + jss-plugin-props-sort "^10.5.1" + jss-plugin-rule-value-function "^10.5.1" + jss-plugin-vendor-prefixer "^10.5.1" prop-types "^15.7.2" -"@material-ui/system@^4.9.14": - version "4.9.14" - resolved "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz#4b00c48b569340cefb2036d0596b93ac6c587a5f" - integrity sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w== +"@material-ui/system@^4.11.3": + version "4.11.3" + resolved "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz#466bc14c9986798fd325665927c963eb47cc4143" + integrity sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/utils" "^4.9.6" + "@material-ui/utils" "^4.11.2" csstype "^2.5.2" prop-types "^15.7.2" @@ -3815,16 +3815,7 @@ resolved "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== -"@material-ui/utils@^4.10.2", "@material-ui/utils@^4.7.1", "@material-ui/utils@^4.9.6": - version "4.10.2" - resolved "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz#3fd5470ca61b7341f1e0468ac8f29a70bf6df321" - integrity sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw== - dependencies: - "@babel/runtime" "^7.4.4" - prop-types "^15.7.2" - react-is "^16.8.0" - -"@material-ui/utils@^4.11.2": +"@material-ui/utils@^4.11.2", "@material-ui/utils@^4.7.1": version "4.11.2" resolved "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz#f1aefa7e7dff2ebcb97d31de51aecab1bb57540a" integrity sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA== @@ -10696,12 +10687,12 @@ css-unit-converter@^1.1.2: resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== -css-vendor@^2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.7.tgz#4e6d53d953c187981576d6a542acc9fb57174bda" - integrity sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg== +css-vendor@^2.0.8: + version "2.0.8" + resolved "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" + integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== dependencies: - "@babel/runtime" "^7.6.2" + "@babel/runtime" "^7.8.3" is-in-browser "^1.0.2" css-what@2.1: @@ -10837,12 +10828,12 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.5, csstype@^2.6.7: +csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.7: version "2.6.9" resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== -csstype@^3.0.6: +csstype@^3.0.2, csstype@^3.0.6: version "3.0.7" resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== @@ -15214,6 +15205,13 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indefinite-observable@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz#574af29bfbc17eb5947793797bddc94c9d859400" + integrity sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ== + dependencies: + symbol-observable "1.2.0" + indent-string@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -16992,72 +16990,74 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jss-plugin-camel-case@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz#8e73ecc4f1d0f8dfe4dd31f6f9f2782588970e78" - integrity sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw== +jss-plugin-camel-case@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz#93d2cd704bf0c4af70cc40fb52d74b8a2554b170" + integrity sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.1.1" + jss "10.6.0" -jss-plugin-default-unit@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz#2df86016dfe73085eead843f5794e3890e9c5c47" - integrity sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg== +jss-plugin-default-unit@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz#af47972486819b375f0f3a9e0213403a84b5ef3b" + integrity sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" -jss-plugin-global@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz#36b0d6d9facb74dfd99590643708a89260747d14" - integrity sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA== +jss-plugin-global@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz#3e8011f760f399cbadcca7f10a485b729c50e3ed" + integrity sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" -jss-plugin-nested@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz#5c3de2b8bda344de1ebcef3a4fd30870a29a8a8c" - integrity sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q== +jss-plugin-nested@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz#5f83c5c337d3b38004834e8426957715a0251641" + integrity sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" tiny-warning "^1.0.2" -jss-plugin-props-sort@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz#34bddcbfaf9430ec8ccdf92729f03bb10caf1785" - integrity sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g== +jss-plugin-props-sort@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz#297879f35f9fe21196448579fee37bcde28ce6bc" + integrity sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" -jss-plugin-rule-value-function@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz#be00dac6fc394aaddbcef5860b9eca6224d96382" - integrity sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw== +jss-plugin-rule-value-function@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz#3c1a557236a139d0151e70a82c810ccce1c1c5ea" + integrity sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" + tiny-warning "^1.0.2" -jss-plugin-vendor-prefixer@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz#8348b20749f790beebab3b6a8f7075b07c2cfcfd" - integrity sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw== +jss-plugin-vendor-prefixer@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz#e1fcd499352846890c38085b11dbd7aa1c4f2c78" + integrity sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ== dependencies: "@babel/runtime" "^7.3.1" - css-vendor "^2.0.7" - jss "10.1.1" + css-vendor "^2.0.8" + jss "10.6.0" -jss@10.1.1, jss@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz#450b27d53761af3e500b43130a54cdbe157ea332" - integrity sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ== +jss@10.6.0, jss@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz#d92ff9d0f214f65ca1718591b68e107be4774149" + integrity sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw== dependencies: "@babel/runtime" "^7.3.1" - csstype "^2.6.5" + csstype "^3.0.2" + indefinite-observable "^2.0.1" is-in-browser "^1.1.3" tiny-warning "^1.0.2" @@ -24772,7 +24772,7 @@ swr@^0.3.0: dependencies: fast-deep-equal "2.0.1" -symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: +symbol-observable@1.2.0, symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== From ec43f706c71f728dfd57dfec20c65b004a71dbf6 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 19 Apr 2021 10:53:57 +0200 Subject: [PATCH 050/462] Copy migrations to migrationsv2 before migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- packages/backend/src/plugins/catalog.ts | 6 +- .../20210302150147_refresh_state.js | 92 +++++++++--------- plugins/catalog-backend/package.json | 1 + .../src/next/NextCatalogBuilder.ts | 28 +++++- .../src/next/NextEntitiesCatalog.ts | 61 ++++++++++++ plugins/catalog-backend/src/next/Stitcher.ts | 96 ++++++++++++++++++- .../next/database/ProcessingDatabaseImpl.ts | 11 --- tsconfig.json | 3 +- 8 files changed, 231 insertions(+), 67 deletions(-) rename plugins/catalog-backend/{migrations => migrationsv2}/20210302150147_refresh_state.js (98%) create mode 100644 plugins/catalog-backend/src/next/NextEntitiesCatalog.ts diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 99ba769736..e58d8cd3eb 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -27,7 +27,11 @@ import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise { - // HIGHLY experimental rework of the software catalog + /* + * ** WARNING ** + * DO NOT enable the experimental catalog, it will brick your database migrations. + * This is solely for internal backstage development. + */ if (process.env.EXPERIMENTAL_CATALOG === '1') { const builder = new NextCatalogBuilder(env); const { diff --git a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js similarity index 98% rename from plugins/catalog-backend/migrations/20210302150147_refresh_state.js rename to plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index a09d892146..56c594ddf2 100644 --- a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -20,52 +20,6 @@ * @param {import('knex').Knex} knex */ exports.up = async function up(knex) { - await knex.schema.createTable('relations', table => { - table.comment('All relations between entities in the catalog'); - table - .text('originating_entity_id') - .references('entity_id') - .inTable('refresh_state') - .onDelete('CASCADE') - .notNullable() - .comment('The entity that provided the relation'); - table - .text('source_entity_ref') - .notNullable() - .comment('The entity reference of the source entity of the relation'); - table - .text('type') - .notNullable() - .comment('The type of the relation between the entities'); - table - .text('target_entity_ref') - .notNullable() - .comment('The entity reference of the target entity of the relation'); - - table.index( - ['source_entity_ref', 'type', 'target_entity_ref'], - 'relations_full_ref_idx', - ); - }); - - await knex.schema.createTable('final_entities', table => { - table.comment( - 'This table contains the final entity result after processing and stitching', - ); - table - .text('entity_id') - .primary() - .notNullable() - .references('entity_id') - .inTable('refresh_state') - .onDelete('CASCADE') - .comment( - 'Entity ID which correspond to the ID in the refresh_state table', - ); - - table.text('finalized_entity').notNullable().comment('The final entity'); - }); - await knex.schema.createTable('refresh_state', table => { table.comment( 'Location refresh states. Every individual location (that was ever directly or indirectly discovered) and entity has an entry in this table. It therefore represents the entire live set of things that the refresh loop considers.', @@ -116,6 +70,24 @@ exports.up = async function up(knex) { table.index('next_update_at', 'refresh_state_next_update_at_idx'); }); + await knex.schema.createTable('final_entities', table => { + table.comment( + 'This table contains the final entity result after processing and stitching', + ); + table + .text('entity_id') + .primary() + .notNullable() + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .comment( + 'Entity ID which correspond to the ID in the refresh_state table', + ); + table.text('etag').notNullable().comment('Etag to be used for caching'); + table.text('finalized_entity').notNullable().comment('The final entity'); + }); + await knex.schema.createTable('refresh_state_references', table => { table.comment( 'Holds edges between refresh state rows. Every time when an entity is processed and emits another entity, an edge will be stored to represent that fact. This is used to detect orphans and ultimately deletions.', @@ -155,6 +127,34 @@ exports.up = async function up(knex) { 'refresh_state_references_target_entity_id_idx', ); }); + + await knex.schema.createTable('relations', table => { + table.comment('All relations between entities in the catalog'); + table + .text('originating_entity_id') + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .text('source_entity_ref') + .notNullable() + .comment('The entity reference of the source entity of the relation'); + table + .text('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .text('target_entity_ref') + .notNullable() + .comment('The entity reference of the target entity of the relation'); + + table.index( + ['source_entity_ref', 'type', 'target_entity_ref'], + 'relations_full_ref_idx', + ); + }); }; /** diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 6011562078..64879df777 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -80,6 +80,7 @@ "files": [ "dist", "migrations/**/*.{js,d.ts}", + "migrationsv2/**/*.{js,d.ts}", "config.d.ts" ], "configSchema": "config.d.ts" diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 95c767407e..b7e860cce2 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common'; +import { + PluginDatabaseManager, + resolvePackagePath, + UrlReader, +} from '@backstage/backend-common'; +import fs from 'fs-extra'; import { DefaultNamespaceEntityPolicy, EntityPolicies, @@ -30,12 +35,10 @@ import { ScmIntegrations } from '@backstage/integration'; import lodash from 'lodash'; import { Logger } from 'winston'; import { - DatabaseEntitiesCatalog, DatabaseLocationsCatalog, EntitiesCatalog, LocationsCatalog, } from '../catalog'; -import { DatabaseManager } from '../database'; import { AnnotateLocationEntityProcessor, BitbucketDiscoveryProcessor, @@ -68,7 +71,9 @@ import { DatabaseLocationProvider } from '../next/DatabaseLocationProvider'; import { LocationStoreImpl } from '../next/LocationStoreImpl'; import { ProcessingStateManagerImpl } from '../next/ProcessingStateManagerImpl'; import { CatalogProcessingEngine } from '../next/types'; +import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; +import { CommonDatabase } from '../database/CommonDatabase'; export type CatalogEnvironment = { logger: Logger; @@ -239,7 +244,20 @@ export class NextCatalogBuilder { const parser = this.parser || defaultEntityDataParser; const dbClient = await database.getClient(); - const db = await DatabaseManager.createDatabase(dbClient, { logger }); + const allMigrations = resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrations', + ); + + const migrationsDir = resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrationsv2', + ); + await fs.copy(allMigrations, migrationsDir); + await dbClient.migrate.latest({ + directory: migrationsDir, + }); + const db = new CommonDatabase(dbClient, logger); const processingDatabase = new ProcessingDatabaseImpl(dbClient, logger); const stateManager = new ProcessingStateManagerImpl(processingDatabase); @@ -251,7 +269,7 @@ export class NextCatalogBuilder { parser, policy, }); - const entitiesCatalog = new DatabaseEntitiesCatalog(db, logger); + const entitiesCatalog = new NextEntitiesCatalog(dbClient, logger); const locationStore = new LocationStoreImpl(db); const dbLocationProvider = new DatabaseLocationProvider(locationStore); diff --git a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts new file mode 100644 index 0000000000..39d3bf2a63 --- /dev/null +++ b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Logger } from 'winston'; +import { Knex } from 'knex'; +import { DbFinalEntitiesRow } from './Stitcher'; +import { EntitiesCatalog } from '../catalog'; +import { EntitiesRequest, EntitiesResponse } from '../catalog/types'; + +export class NextEntitiesCatalog implements EntitiesCatalog { + constructor( + private readonly database: Knex, + private readonly logger: Logger, + ) {} + + async entities(request?: EntitiesRequest): Promise { + if (request?.fields) { + throw new Error('Fields extraction is not implemented'); + } + if (request?.pagination) { + throw new Error('Pagination is not implemented'); + } + if (request?.filter) { + throw new Error('Filters are not implemented'); + } + + const dbResponse = await this.database( + 'final_entities', + ).select(); + + const entities = dbResponse.map(e => JSON.parse(e.finalized_entity)); + + return { + entities, + pageInfo: { + hasNextPage: false, + }, + }; + } + + async removeEntityByUid(_uid: string): Promise { + throw new Error('Not implemented'); + } + + async batchAddOrUpdateEntities(): Promise { + throw new Error('Not implemented'); + } +} diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 8adc93bfad..29e7363b80 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -1,5 +1,3 @@ -import { Transaction } from '../database'; - /* * Copyright 2021 Spotify AB * @@ -18,7 +16,28 @@ import { Transaction } from '../database'; import { Knex } from 'knex'; import { Logger } from 'winston'; +import { Transaction } from '../database'; import { ConflictError } from '@backstage/errors'; +import { + DbRefreshStateReferences, + DbRefreshStateRow, + DbRelationsRow, +} from './database/ProcessingDatabaseImpl'; +import { Entity, parseEntityRef } from '@backstage/catalog-model'; +import { createHash } from 'crypto'; +import stableStringify from 'fast-json-stable-stringify'; + +export type DbFinalEntitiesRow = { + entity_id: string; + etag: string; + finalized_entity: string; +}; + +function generateEntityEtag(entity: Entity) { + return createHash('sha1') + .update(stableStringify({ ...entity })) + .digest('hex'); +} export class Stitcher { constructor( @@ -27,7 +46,74 @@ export class Stitcher { ) {} async stitch(entityRefs: Set) { - console.log(entityRefs); + for (const entityRef of entityRefs) { + await this.transaction(async txOpaque => { + const tx = txOpaque as Knex.Transaction; + const [result] = await tx('refresh_state') + .select('entity_id', 'processed_entity') + .where({ entity_ref: entityRef }); + + if (!result) { + this.logger.debug( + `Unable to stitch ${entityRef}, item does not exist in refresh state table`, + ); + return; + } else if (!result.processed_entity) { + this.logger.debug( + `Unable to stitch ${entityRef}, the entity has not yet been processed`, + ); + return; + } + + const entity: Entity = JSON.parse(result.processed_entity); + + const entityId = entity?.metadata?.uid; + if (!entityId) { + this.logger.error(`missing ID in entity ${JSON.stringify(entity)}`); + return; + } + + const [reference_count_result] = await tx( + 'refresh_state_references', + ) + .where({ target_entity_id: entity.metadata.uid }) + .count({ reference_count: 'target_entity_id' }); + console.log( + 'DEBUG: reference_count_result =', + reference_count_result, + entityId, + ); + if (Number(reference_count_result.reference_count) === 0) { + this.logger.debug(`${entityRef} is orphan`); + entity.metadata.annotations = { + ...entity.metadata.annotations, + ['backstage.io/orphan']: 'true', + }; + } + + const relationResults = await tx('relations') + .where({ originating_entity_id: entityId }) + .select(); + + // TODO: entityRef is lower case and should be uppercase in the final result. + entity.relations = relationResults.map(relation => ({ + type: relation.type, + target: parseEntityRef(relation.target_entity_ref), + })); + entity.metadata.generation = 1; + const etag = generateEntityEtag(entity); + entity.metadata.etag = etag; + console.log(JSON.stringify(entity, null, 2)); + await tx('final_entities') + .insert({ + finalized_entity: JSON.stringify(entity), + entity_id: entityId, + etag, + }) + .onConflict('entity_id') + .merge(['finalized_entity', 'etag']); + }); + } } private async transaction( @@ -45,6 +131,10 @@ export class Stitcher { { // If we explicitly trigger a rollback, don't fail. doNotRejectOnRollback: true, + isolationLevel: + this.database.client.config.client === 'sqlite3' + ? undefined // sqlite3 only supports serializable transactions, ignoring the isolation level param + : 'serializable', }, ); diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts index f479c9a4f8..7c56fcd259 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -27,8 +27,6 @@ import { } from './types'; import type { Logger } from 'winston'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; -import { createHash } from 'crypto'; -import stableStringify from 'fast-json-stable-stringify'; import { v4 as uuid } from 'uuid'; export type DbRefreshStateRow = { @@ -55,12 +53,6 @@ export type DbRefreshStateReferences = { target_entity_id: string; }; -function generateEntityEtag(entity: Entity) { - return createHash('sha1') - .update(stableStringify({ ...entity })) - .digest('hex'); -} - // The number of items that are sent per batch to the database layer, when // doing .batchInsert calls to knex. This needs to be low enough to not cause // errors in the underlying engine due to exceeding query limits, but large @@ -108,9 +100,6 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { // Update fragments - // Update relations - const entityRef = stringifyEntityRef(processedEntity); - // Delete old relations await tx('relations') .where({ originating_entity_id: id }) diff --git a/tsconfig.json b/tsconfig.json index d6cb6f4c96..6139c4a7f0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "packages/*/src", "plugins/*/src", "plugins/*/dev", - "plugins/*/migrations" + "plugins/*/migrations", + "plugins/catalog-backend/migrationsv2" ], "compilerOptions": { "outDir": "dist-types", From 33acc81f9079b7cfd996f3b8e78b4acdf96adb8c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 19 Apr 2021 11:06:15 +0200 Subject: [PATCH 051/462] Remove debug logs and unused variables Signed-off-by: Johan Haals --- .../src/next/CatalogProcessingOrchestratorImpl.ts | 2 +- plugins/catalog-backend/src/next/NextCatalogBuilder.ts | 2 +- plugins/catalog-backend/src/next/NextEntitiesCatalog.ts | 6 +----- plugins/catalog-backend/src/next/Stitcher.ts | 7 +------ 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index fee61cb366..0107c5cd8d 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -97,7 +97,7 @@ export class CatalogProcessingOrchestratorImpl async process( request: EntityProcessingRequest, ): Promise { - const { entity, eager, state } = request; + const { entity } = request; const result = await this.processSingleEntity(entity); diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index b7e860cce2..b196d63897 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -269,7 +269,7 @@ export class NextCatalogBuilder { parser, policy, }); - const entitiesCatalog = new NextEntitiesCatalog(dbClient, logger); + const entitiesCatalog = new NextEntitiesCatalog(dbClient); const locationStore = new LocationStoreImpl(db); const dbLocationProvider = new DatabaseLocationProvider(locationStore); diff --git a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts index 39d3bf2a63..5bddd47f41 100644 --- a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts @@ -14,17 +14,13 @@ * limitations under the License. */ -import { Logger } from 'winston'; import { Knex } from 'knex'; import { DbFinalEntitiesRow } from './Stitcher'; import { EntitiesCatalog } from '../catalog'; import { EntitiesRequest, EntitiesResponse } from '../catalog/types'; export class NextEntitiesCatalog implements EntitiesCatalog { - constructor( - private readonly database: Knex, - private readonly logger: Logger, - ) {} + constructor(private readonly database: Knex) {} async entities(request?: EntitiesRequest): Promise { if (request?.fields) { diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 29e7363b80..f79a247b91 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -78,11 +78,7 @@ export class Stitcher { ) .where({ target_entity_id: entity.metadata.uid }) .count({ reference_count: 'target_entity_id' }); - console.log( - 'DEBUG: reference_count_result =', - reference_count_result, - entityId, - ); + if (Number(reference_count_result.reference_count) === 0) { this.logger.debug(`${entityRef} is orphan`); entity.metadata.annotations = { @@ -103,7 +99,6 @@ export class Stitcher { entity.metadata.generation = 1; const etag = generateEntityEtag(entity); entity.metadata.etag = etag; - console.log(JSON.stringify(entity, null, 2)); await tx('final_entities') .insert({ finalized_entity: JSON.stringify(entity), From ab5ad7ecc3d13abf2552e2a7648a81aef314c0fe Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 19 Apr 2021 11:52:12 +0200 Subject: [PATCH 052/462] Create missing indexes, cleanup in down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Johan Haals --- .../20210302150147_refresh_state.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 56c594ddf2..6abab6270b 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -86,6 +86,7 @@ exports.up = async function up(knex) { ); table.text('etag').notNullable().comment('Etag to be used for caching'); table.text('finalized_entity').notNullable().comment('The final entity'); + table.index('entity_id', 'final_entities_entity_id_idx'); }); await knex.schema.createTable('refresh_state_references', table => { @@ -149,11 +150,8 @@ exports.up = async function up(knex) { .text('target_entity_ref') .notNullable() .comment('The entity reference of the target entity of the relation'); - - table.index( - ['source_entity_ref', 'type', 'target_entity_ref'], - 'relations_full_ref_idx', - ); + table.index('source_entity_ref', 'relations_source_entity_ref_idx'); + table.index('originating_entity_id', 'relations_source_entity_id_idx'); }); }; @@ -170,6 +168,15 @@ exports.down = async function down(knex) { table.dropIndex([], 'refresh_state_entity_ref_idx'); table.dropIndex([], 'refresh_state_next_update_at_idx'); }); - await knex.schema.dropTable('refresh_state'); + await knex.schema.alterTable('final_entities', table => { + table.dropIndex([], 'final_entities_entity_id_idx'); + }); + await knex.schema.alterTable('relations', table => { + table.index('source_entity_ref', 'relations_source_entity_ref_idx'); + table.index('originating_entity_id', 'relations_source_entity_id_idx'); + }); + await knex.schema.dropTable('final_entities'); + await knex.schema.dropTable('relations'); await knex.schema.dropTable('references'); + await knex.schema.dropTable('refresh_state'); }; From 6d9832f563990fd65fee8e4d51b5252e9db0abd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Apr 2021 04:21:26 +0000 Subject: [PATCH 053/462] chore(deps): bump got from 11.8.0 to 11.8.2 Bumps [got](https://github.com/sindresorhus/got) from 11.8.0 to 11.8.2. - [Release notes](https://github.com/sindresorhus/got/releases) - [Commits](https://github.com/sindresorhus/got/compare/v11.8.0...v11.8.2) Signed-off-by: dependabot[bot] Signed-off-by: Javid Aslanov --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6a926b1d7f..4162d2c3ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14234,9 +14234,9 @@ google-p12-pem@^3.0.3: node-forge "^0.10.0" got@^11.5.2, got@^11.7.0, got@^11.8.0: - version "11.8.0" - resolved "https://registry.npmjs.org/got/-/got-11.8.0.tgz#be0920c3586b07fd94add3b5b27cb28f49e6545f" - integrity sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ== + version "11.8.2" + resolved "https://registry.npmjs.org/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" + integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== dependencies: "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" From 4f883d9e08675b3a0ffdc18640a926563e39e844 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Apr 2021 04:41:53 +0000 Subject: [PATCH 054/462] chore(deps): bump @material-ui/core from 4.11.0 to 4.11.3 Bumps [@material-ui/core](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui) from 4.11.0 to 4.11.3. - [Release notes](https://github.com/mui-org/material-ui/releases) - [Changelog](https://github.com/mui-org/material-ui/blob/v4.11.3/CHANGELOG.md) - [Commits](https://github.com/mui-org/material-ui/commits/v4.11.3/packages/material-ui) Signed-off-by: dependabot[bot] Signed-off-by: Javid Aslanov --- yarn.lock | 176 +++++++++++++++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4162d2c3ed..4fc388dc07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,10 +1616,10 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.12.5" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" - integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.13.10" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== dependencies: regenerator-runtime "^0.13.4" @@ -3720,21 +3720,21 @@ integrity sha512-aIRd0Z9b/HJ/O24KOaP7dNsXypMnXhpWrpLVYvQB/JesVqXYSbioYND200sR+C14a0LSCp+qWnWCnSXmN1hWGw== "@material-ui/core@^4.11.0", "@material-ui/core@^4.9.1": - version "4.11.0" - resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a" - integrity sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g== + version "4.11.3" + resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz#f22e41775b0bd075e36a7a093d43951bf7f63850" + integrity sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/styles" "^4.10.0" - "@material-ui/system" "^4.9.14" + "@material-ui/styles" "^4.11.3" + "@material-ui/system" "^4.11.3" "@material-ui/types" "^5.1.0" - "@material-ui/utils" "^4.10.2" + "@material-ui/utils" "^4.11.2" "@types/react-transition-group" "^4.2.0" clsx "^1.0.4" hoist-non-react-statics "^3.3.2" popper.js "1.16.1-lts" prop-types "^15.7.2" - react-is "^16.8.0" + react-is "^16.8.0 || ^17.0.0" react-transition-group "^4.4.0" "@material-ui/icons@^4.9.1": @@ -3778,35 +3778,35 @@ react-transition-group "^4.0.0" rifm "^0.7.0" -"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.9.6": - version "4.10.0" - resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071" - integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q== +"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.11.3", "@material-ui/styles@^4.9.6": + version "4.11.3" + resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz#1b8d97775a4a643b53478c895e3f2a464e8916f2" + integrity sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg== dependencies: "@babel/runtime" "^7.4.4" "@emotion/hash" "^0.8.0" "@material-ui/types" "^5.1.0" - "@material-ui/utils" "^4.9.6" + "@material-ui/utils" "^4.11.2" clsx "^1.0.4" csstype "^2.5.2" hoist-non-react-statics "^3.3.2" - jss "^10.0.3" - jss-plugin-camel-case "^10.0.3" - jss-plugin-default-unit "^10.0.3" - jss-plugin-global "^10.0.3" - jss-plugin-nested "^10.0.3" - jss-plugin-props-sort "^10.0.3" - jss-plugin-rule-value-function "^10.0.3" - jss-plugin-vendor-prefixer "^10.0.3" + jss "^10.5.1" + jss-plugin-camel-case "^10.5.1" + jss-plugin-default-unit "^10.5.1" + jss-plugin-global "^10.5.1" + jss-plugin-nested "^10.5.1" + jss-plugin-props-sort "^10.5.1" + jss-plugin-rule-value-function "^10.5.1" + jss-plugin-vendor-prefixer "^10.5.1" prop-types "^15.7.2" -"@material-ui/system@^4.9.14": - version "4.9.14" - resolved "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz#4b00c48b569340cefb2036d0596b93ac6c587a5f" - integrity sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w== +"@material-ui/system@^4.11.3": + version "4.11.3" + resolved "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz#466bc14c9986798fd325665927c963eb47cc4143" + integrity sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/utils" "^4.9.6" + "@material-ui/utils" "^4.11.2" csstype "^2.5.2" prop-types "^15.7.2" @@ -3815,16 +3815,7 @@ resolved "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== -"@material-ui/utils@^4.10.2", "@material-ui/utils@^4.7.1", "@material-ui/utils@^4.9.6": - version "4.10.2" - resolved "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz#3fd5470ca61b7341f1e0468ac8f29a70bf6df321" - integrity sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw== - dependencies: - "@babel/runtime" "^7.4.4" - prop-types "^15.7.2" - react-is "^16.8.0" - -"@material-ui/utils@^4.11.2": +"@material-ui/utils@^4.11.2", "@material-ui/utils@^4.7.1": version "4.11.2" resolved "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz#f1aefa7e7dff2ebcb97d31de51aecab1bb57540a" integrity sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA== @@ -10696,12 +10687,12 @@ css-unit-converter@^1.1.2: resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== -css-vendor@^2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.7.tgz#4e6d53d953c187981576d6a542acc9fb57174bda" - integrity sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg== +css-vendor@^2.0.8: + version "2.0.8" + resolved "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" + integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== dependencies: - "@babel/runtime" "^7.6.2" + "@babel/runtime" "^7.8.3" is-in-browser "^1.0.2" css-what@2.1: @@ -10837,12 +10828,12 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.5, csstype@^2.6.7: +csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.7: version "2.6.9" resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== -csstype@^3.0.6: +csstype@^3.0.2, csstype@^3.0.6: version "3.0.7" resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== @@ -15214,6 +15205,13 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indefinite-observable@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz#574af29bfbc17eb5947793797bddc94c9d859400" + integrity sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ== + dependencies: + symbol-observable "1.2.0" + indent-string@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -16992,72 +16990,74 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jss-plugin-camel-case@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz#8e73ecc4f1d0f8dfe4dd31f6f9f2782588970e78" - integrity sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw== +jss-plugin-camel-case@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz#93d2cd704bf0c4af70cc40fb52d74b8a2554b170" + integrity sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.1.1" + jss "10.6.0" -jss-plugin-default-unit@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz#2df86016dfe73085eead843f5794e3890e9c5c47" - integrity sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg== +jss-plugin-default-unit@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz#af47972486819b375f0f3a9e0213403a84b5ef3b" + integrity sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" -jss-plugin-global@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz#36b0d6d9facb74dfd99590643708a89260747d14" - integrity sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA== +jss-plugin-global@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz#3e8011f760f399cbadcca7f10a485b729c50e3ed" + integrity sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" -jss-plugin-nested@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz#5c3de2b8bda344de1ebcef3a4fd30870a29a8a8c" - integrity sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q== +jss-plugin-nested@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz#5f83c5c337d3b38004834e8426957715a0251641" + integrity sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" tiny-warning "^1.0.2" -jss-plugin-props-sort@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz#34bddcbfaf9430ec8ccdf92729f03bb10caf1785" - integrity sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g== +jss-plugin-props-sort@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz#297879f35f9fe21196448579fee37bcde28ce6bc" + integrity sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" -jss-plugin-rule-value-function@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz#be00dac6fc394aaddbcef5860b9eca6224d96382" - integrity sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw== +jss-plugin-rule-value-function@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz#3c1a557236a139d0151e70a82c810ccce1c1c5ea" + integrity sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.1.1" + jss "10.6.0" + tiny-warning "^1.0.2" -jss-plugin-vendor-prefixer@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz#8348b20749f790beebab3b6a8f7075b07c2cfcfd" - integrity sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw== +jss-plugin-vendor-prefixer@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz#e1fcd499352846890c38085b11dbd7aa1c4f2c78" + integrity sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ== dependencies: "@babel/runtime" "^7.3.1" - css-vendor "^2.0.7" - jss "10.1.1" + css-vendor "^2.0.8" + jss "10.6.0" -jss@10.1.1, jss@^10.0.3: - version "10.1.1" - resolved "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz#450b27d53761af3e500b43130a54cdbe157ea332" - integrity sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ== +jss@10.6.0, jss@^10.5.1: + version "10.6.0" + resolved "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz#d92ff9d0f214f65ca1718591b68e107be4774149" + integrity sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw== dependencies: "@babel/runtime" "^7.3.1" - csstype "^2.6.5" + csstype "^3.0.2" + indefinite-observable "^2.0.1" is-in-browser "^1.1.3" tiny-warning "^1.0.2" @@ -24772,7 +24772,7 @@ swr@^0.3.0: dependencies: fast-deep-equal "2.0.1" -symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: +symbol-observable@1.2.0, symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== From 9fcbfaaf35ccd6bdedb4700924e7e9d78b841c56 Mon Sep 17 00:00:00 2001 From: Javid Aslanov Date: Mon, 19 Apr 2021 13:15:01 +0400 Subject: [PATCH 055/462] Add aws as an authProvider for k8s integration Signed-off-by: Javid Aslanov --- docs/features/kubernetes/configuration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 8222fbb400..caf29ccf03 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -78,6 +78,7 @@ cluster. Valid values are: | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | | `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. | +| `aws` | This will use AWS credentials to access resources in EKS clusters | ##### `clusters.\*.skipTLSVerify` From a418d0e49636cfc8c94ef141c951f8b571eb831c Mon Sep 17 00:00:00 2001 From: Javid Aslanov Date: Mon, 19 Apr 2021 13:36:10 +0400 Subject: [PATCH 056/462] formatting line Signed-off-by: Javid Aslanov --- docs/features/kubernetes/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index caf29ccf03..00b5236020 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -78,7 +78,7 @@ cluster. Valid values are: | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | | `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. | -| `aws` | This will use AWS credentials to access resources in EKS clusters | +| `aws` | This will use AWS credentials to access resources in EKS clusters | ##### `clusters.\*.skipTLSVerify` From 27ff0bbd3bca0b6ed9035df3c06c6502ee86716d Mon Sep 17 00:00:00 2001 From: Javid Aslanov Date: Mon, 19 Apr 2021 13:15:01 +0400 Subject: [PATCH 057/462] Add aws as an authProvider for k8s integration Signed-off-by: Javid Aslanov --- docs/features/kubernetes/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 00b5236020..caf29ccf03 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -78,7 +78,7 @@ cluster. Valid values are: | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | | `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. | -| `aws` | This will use AWS credentials to access resources in EKS clusters | +| `aws` | This will use AWS credentials to access resources in EKS clusters | ##### `clusters.\*.skipTLSVerify` From cf10afdf32e6791ba33e04fb07821d1aafd7ed87 Mon Sep 17 00:00:00 2001 From: Javid Aslanov Date: Mon, 19 Apr 2021 13:36:10 +0400 Subject: [PATCH 058/462] formatting line Signed-off-by: Javid Aslanov --- docs/features/kubernetes/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index caf29ccf03..00b5236020 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -78,7 +78,7 @@ cluster. Valid values are: | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | | `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. | -| `aws` | This will use AWS credentials to access resources in EKS clusters | +| `aws` | This will use AWS credentials to access resources in EKS clusters | ##### `clusters.\*.skipTLSVerify` From e8e0691bb76fec99a328bf96be2846ccd45a5f8f Mon Sep 17 00:00:00 2001 From: Javid Aslanov Date: Mon, 19 Apr 2021 15:25:51 +0400 Subject: [PATCH 059/462] run prettier Signed-off-by: Javid Aslanov --- docs/features/kubernetes/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 00b5236020..5dbad9cf4a 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -78,7 +78,7 @@ cluster. Valid values are: | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | | `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. | -| `aws` | This will use AWS credentials to access resources in EKS clusters | +| `aws` | This will use AWS credentials to access resources in EKS clusters | ##### `clusters.\*.skipTLSVerify` From c62e43c808bf60a49f5c5eb22fc0fe6b2ef883d3 Mon Sep 17 00:00:00 2001 From: Javid Aslanov Date: Mon, 19 Apr 2021 15:32:34 +0400 Subject: [PATCH 060/462] revert yarn.lock Signed-off-by: Javid Aslanov --- yarn.lock | 182 +++++++++++++++++++++++++++--------------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4fc388dc07..6a926b1d7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,10 +1616,10 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.13.10" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" - integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.12.5" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" @@ -3720,21 +3720,21 @@ integrity sha512-aIRd0Z9b/HJ/O24KOaP7dNsXypMnXhpWrpLVYvQB/JesVqXYSbioYND200sR+C14a0LSCp+qWnWCnSXmN1hWGw== "@material-ui/core@^4.11.0", "@material-ui/core@^4.9.1": - version "4.11.3" - resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz#f22e41775b0bd075e36a7a093d43951bf7f63850" - integrity sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw== + version "4.11.0" + resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a" + integrity sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/styles" "^4.11.3" - "@material-ui/system" "^4.11.3" + "@material-ui/styles" "^4.10.0" + "@material-ui/system" "^4.9.14" "@material-ui/types" "^5.1.0" - "@material-ui/utils" "^4.11.2" + "@material-ui/utils" "^4.10.2" "@types/react-transition-group" "^4.2.0" clsx "^1.0.4" hoist-non-react-statics "^3.3.2" popper.js "1.16.1-lts" prop-types "^15.7.2" - react-is "^16.8.0 || ^17.0.0" + react-is "^16.8.0" react-transition-group "^4.4.0" "@material-ui/icons@^4.9.1": @@ -3778,35 +3778,35 @@ react-transition-group "^4.0.0" rifm "^0.7.0" -"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.11.3", "@material-ui/styles@^4.9.6": - version "4.11.3" - resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz#1b8d97775a4a643b53478c895e3f2a464e8916f2" - integrity sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg== +"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.9.6": + version "4.10.0" + resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071" + integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q== dependencies: "@babel/runtime" "^7.4.4" "@emotion/hash" "^0.8.0" "@material-ui/types" "^5.1.0" - "@material-ui/utils" "^4.11.2" + "@material-ui/utils" "^4.9.6" clsx "^1.0.4" csstype "^2.5.2" hoist-non-react-statics "^3.3.2" - jss "^10.5.1" - jss-plugin-camel-case "^10.5.1" - jss-plugin-default-unit "^10.5.1" - jss-plugin-global "^10.5.1" - jss-plugin-nested "^10.5.1" - jss-plugin-props-sort "^10.5.1" - jss-plugin-rule-value-function "^10.5.1" - jss-plugin-vendor-prefixer "^10.5.1" + jss "^10.0.3" + jss-plugin-camel-case "^10.0.3" + jss-plugin-default-unit "^10.0.3" + jss-plugin-global "^10.0.3" + jss-plugin-nested "^10.0.3" + jss-plugin-props-sort "^10.0.3" + jss-plugin-rule-value-function "^10.0.3" + jss-plugin-vendor-prefixer "^10.0.3" prop-types "^15.7.2" -"@material-ui/system@^4.11.3": - version "4.11.3" - resolved "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz#466bc14c9986798fd325665927c963eb47cc4143" - integrity sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw== +"@material-ui/system@^4.9.14": + version "4.9.14" + resolved "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz#4b00c48b569340cefb2036d0596b93ac6c587a5f" + integrity sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/utils" "^4.11.2" + "@material-ui/utils" "^4.9.6" csstype "^2.5.2" prop-types "^15.7.2" @@ -3815,7 +3815,16 @@ resolved "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== -"@material-ui/utils@^4.11.2", "@material-ui/utils@^4.7.1": +"@material-ui/utils@^4.10.2", "@material-ui/utils@^4.7.1", "@material-ui/utils@^4.9.6": + version "4.10.2" + resolved "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz#3fd5470ca61b7341f1e0468ac8f29a70bf6df321" + integrity sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw== + dependencies: + "@babel/runtime" "^7.4.4" + prop-types "^15.7.2" + react-is "^16.8.0" + +"@material-ui/utils@^4.11.2": version "4.11.2" resolved "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz#f1aefa7e7dff2ebcb97d31de51aecab1bb57540a" integrity sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA== @@ -10687,12 +10696,12 @@ css-unit-converter@^1.1.2: resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== -css-vendor@^2.0.8: - version "2.0.8" - resolved "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" - integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== +css-vendor@^2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.7.tgz#4e6d53d953c187981576d6a542acc9fb57174bda" + integrity sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg== dependencies: - "@babel/runtime" "^7.8.3" + "@babel/runtime" "^7.6.2" is-in-browser "^1.0.2" css-what@2.1: @@ -10828,12 +10837,12 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.7: +csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.5, csstype@^2.6.7: version "2.6.9" resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== -csstype@^3.0.2, csstype@^3.0.6: +csstype@^3.0.6: version "3.0.7" resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== @@ -14225,9 +14234,9 @@ google-p12-pem@^3.0.3: node-forge "^0.10.0" got@^11.5.2, got@^11.7.0, got@^11.8.0: - version "11.8.2" - resolved "https://registry.npmjs.org/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" - integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== + version "11.8.0" + resolved "https://registry.npmjs.org/got/-/got-11.8.0.tgz#be0920c3586b07fd94add3b5b27cb28f49e6545f" + integrity sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ== dependencies: "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" @@ -15205,13 +15214,6 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indefinite-observable@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz#574af29bfbc17eb5947793797bddc94c9d859400" - integrity sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ== - dependencies: - symbol-observable "1.2.0" - indent-string@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -16990,74 +16992,72 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jss-plugin-camel-case@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz#93d2cd704bf0c4af70cc40fb52d74b8a2554b170" - integrity sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A== +jss-plugin-camel-case@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz#8e73ecc4f1d0f8dfe4dd31f6f9f2782588970e78" + integrity sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.6.0" + jss "10.1.1" -jss-plugin-default-unit@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz#af47972486819b375f0f3a9e0213403a84b5ef3b" - integrity sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w== +jss-plugin-default-unit@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz#2df86016dfe73085eead843f5794e3890e9c5c47" + integrity sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.1.1" -jss-plugin-global@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz#3e8011f760f399cbadcca7f10a485b729c50e3ed" - integrity sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w== +jss-plugin-global@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz#36b0d6d9facb74dfd99590643708a89260747d14" + integrity sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.1.1" -jss-plugin-nested@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz#5f83c5c337d3b38004834e8426957715a0251641" - integrity sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g== +jss-plugin-nested@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz#5c3de2b8bda344de1ebcef3a4fd30870a29a8a8c" + integrity sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.1.1" tiny-warning "^1.0.2" -jss-plugin-props-sort@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz#297879f35f9fe21196448579fee37bcde28ce6bc" - integrity sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw== +jss-plugin-props-sort@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz#34bddcbfaf9430ec8ccdf92729f03bb10caf1785" + integrity sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" + jss "10.1.1" -jss-plugin-rule-value-function@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz#3c1a557236a139d0151e70a82c810ccce1c1c5ea" - integrity sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA== +jss-plugin-rule-value-function@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz#be00dac6fc394aaddbcef5860b9eca6224d96382" + integrity sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw== dependencies: "@babel/runtime" "^7.3.1" - jss "10.6.0" - tiny-warning "^1.0.2" + jss "10.1.1" -jss-plugin-vendor-prefixer@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz#e1fcd499352846890c38085b11dbd7aa1c4f2c78" - integrity sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ== +jss-plugin-vendor-prefixer@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz#8348b20749f790beebab3b6a8f7075b07c2cfcfd" + integrity sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw== dependencies: "@babel/runtime" "^7.3.1" - css-vendor "^2.0.8" - jss "10.6.0" + css-vendor "^2.0.7" + jss "10.1.1" -jss@10.6.0, jss@^10.5.1: - version "10.6.0" - resolved "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz#d92ff9d0f214f65ca1718591b68e107be4774149" - integrity sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw== +jss@10.1.1, jss@^10.0.3: + version "10.1.1" + resolved "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz#450b27d53761af3e500b43130a54cdbe157ea332" + integrity sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ== dependencies: "@babel/runtime" "^7.3.1" - csstype "^3.0.2" - indefinite-observable "^2.0.1" + csstype "^2.6.5" is-in-browser "^1.1.3" tiny-warning "^1.0.2" @@ -24772,7 +24772,7 @@ swr@^0.3.0: dependencies: fast-deep-equal "2.0.1" -symbol-observable@1.2.0, symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: +symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== From 734c7d523846cd4eb25712355f2c0f7f2f127fdd Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Mon, 19 Apr 2021 15:04:36 +0200 Subject: [PATCH 061/462] Add IAM policy permissions to s3 tech docs docs (#5359) List minimal permissions needed to write and read tech docs on AWS environment Signed-off-by: Jussi Hallila Co-authored-by: Emma Indal Co-authored-by: Emma Indal --- docs/features/techdocs/using-cloud-storage.md | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index d5a3a68425..23015935da 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -135,7 +135,21 @@ techdocs: bucketName: 'name-of-techdocs-storage-bucket' ``` -**3a. (Recommended) Setup authentication the AWS way, using environment +**3. Create minimal AWS IAM policies to manage TechDocs** + +To _write_ TechDocs into the S3 bucket the IAM policy needs to have at a minimum +permissions to: + +- `s3:ListBucket` to retrieve bucket metadata +- `s3:PutObject` to upload files to the bucket + +To _read_ TechDocs from the S3 bucket the IAM policy needs to have at a minimum +permissions to: + +- `s3:ListBucket` - To retrieve bucket metadata +- `s3:GetObject` - To retrieve files from the bucket + +**4a. (Recommended) Setup authentication the AWS way, using environment variables** You should follow the @@ -166,7 +180,7 @@ more in The AWS Region of the bucket is optional since TechDocs uses AWS SDK V2 and not V3. -**3b. Authentication using app-config.yaml** +**4b. Authentication using app-config.yaml** AWS credentials and region can be provided to the AWS SDK via `app-config.yaml`. If the configs below are present, they will be used over existing `AWS_*` @@ -187,7 +201,7 @@ techdocs: Refer to the [official AWS documentation for obtaining the credentials](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/getting-your-credentials.html). -**3c. Authentication using an assumed role** Users with multiple AWS accounts +**4c. Authentication using an assumed role** Users with multiple AWS accounts may want to use a role for S3 storage that is in a different AWS account. Using the `roleArn` parameter as seen below, you can instruct the TechDocs publisher to assume a role before accessing S3. @@ -207,7 +221,7 @@ Note: Assuming a role requires that primary credentials are already configured at `AWS.config.credentials`. Read more about [assuming roles in AWS](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html). -**4. That's it!** +**5. That's it!** Your Backstage app is now ready to use AWS S3 for TechDocs, to store and read the static generated documentation files. When you start the backend of the app, From d126628a9b4dcd40d3923a25484b65b7db8e8ecb Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 19 Apr 2021 15:24:42 +0200 Subject: [PATCH 062/462] Remove optional entity field Signed-off-by: Johan Haals --- packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts | 1 - .../src/next/CatalogProcessingOrchestratorImpl.ts | 6 +++--- plugins/catalog-backend/src/next/util.ts | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts b/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts index 20f99f15b3..fb452b6ac7 100644 --- a/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts @@ -31,7 +31,6 @@ export interface LocationEntityV1alpha1 extends Entity { type?: string; target?: string; targets?: string[]; - optional?: boolean; }; } diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts index 0107c5cd8d..a8e9b924d0 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts @@ -181,7 +181,7 @@ export class CatalogProcessingOrchestratorImpl // Backwards compatible processing of location entites if (isLocationEntity(entity)) { - const { type = location.type, optional = false } = entity.spec; + const { type = location.type } = entity.spec; const targets = new Array(); if (entity.spec.target) { targets.push(entity.spec.target); @@ -214,9 +214,9 @@ export class CatalogProcessingOrchestratorImpl { type, target, - presence: optional ? 'optional' : 'required', + presence: 'required', }, - Boolean(entity.spec?.optional), + false, emitter.emit, this.options.parser, ); diff --git a/plugins/catalog-backend/src/next/util.ts b/plugins/catalog-backend/src/next/util.ts index 6ff1cde2f0..f8e6f1f978 100644 --- a/plugins/catalog-backend/src/next/util.ts +++ b/plugins/catalog-backend/src/next/util.ts @@ -82,7 +82,6 @@ export function locationSpecToLocationEntity( spec: { type: location.type, target: location.target, - optional: location.presence === 'optional' ? true : undefined, }, }; From 572b078563e82d379dfd9b42da21cea5e2b6f792 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 19 Apr 2021 15:27:59 +0200 Subject: [PATCH 063/462] Find relations by source_entity_ref Signed-off-by: Johan Haals --- plugins/catalog-backend/src/next/Stitcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index f79a247b91..fe7a378338 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -88,7 +88,7 @@ export class Stitcher { } const relationResults = await tx('relations') - .where({ originating_entity_id: entityId }) + .where({ source_entity_ref: entityRef }) .select(); // TODO: entityRef is lower case and should be uppercase in the final result. From 93ecfc111cbac7c7f8b4298245e9c133526c903a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Apr 2021 15:00:24 +0000 Subject: [PATCH 064/462] chore(deps): bump jose from 1.28.0 to 1.28.1 Bumps [jose](https://github.com/panva/jose) from 1.28.0 to 1.28.1. - [Release notes](https://github.com/panva/jose/releases) - [Changelog](https://github.com/panva/jose/blob/v1.28.1/CHANGELOG.md) - [Commits](https://github.com/panva/jose/compare/v1.28.0...v1.28.1) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4fc388dc07..b3efdedbd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16613,9 +16613,9 @@ joi@^17.3.0: "@sideway/pinpoint" "^2.0.0" jose@^1.27.1: - version "1.28.0" - resolved "https://registry.npmjs.org/jose/-/jose-1.28.0.tgz#0803f8c71f43cd293a9d931c555c30531f5ca5dc" - integrity sha512-JmfDRzt/HSj8ipd9TsDtEHoLUnLYavG+7e8F6s1mx2jfVSfXOTaFQsJUydbjJpTnTDHP1+yKL9Ke7ktS/a0Eiw== + version "1.28.1" + resolved "https://registry.npmjs.org/jose/-/jose-1.28.1.tgz#34a0f851a534be59ffab82a6e8845f6874e8c128" + integrity sha512-6JK28rFu5ENp/yxMwM+iN7YeaInnY9B9Bggjkz5fuwLiJhbVrl2O4SJr65bdNBPl9y27fdC3Mymh+FVCvozLIg== dependencies: "@panva/asn1.js" "^1.0.0" From e10512f1fd6543591ddd450be799a6a6e7df7eb9 Mon Sep 17 00:00:00 2001 From: Tim Hansen Date: Mon, 19 Apr 2021 09:47:38 -0600 Subject: [PATCH 065/462] Accidentally a link Signed-off-by: Tim Hansen --- microsite/sidebars.json | 1 + 1 file changed, 1 insertion(+) diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 86e94d9fbd..1ab242ba2d 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -203,6 +203,7 @@ ], "Deployment": [ "deployment/index", + "deployment/docker", "deployment/k8s", "deployment/helm", "deployment/heroku" From 94da2097671c0369278eef8eda4a68bc3c26c702 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Mon, 19 Apr 2021 19:39:37 +0200 Subject: [PATCH 066/462] Sort the table filter options by name Signed-off-by: Dominik Henneke --- .changeset/chatty-parents-search.md | 5 +++++ packages/core/src/components/Table/Table.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/chatty-parents-search.md diff --git a/.changeset/chatty-parents-search.md b/.changeset/chatty-parents-search.md new file mode 100644 index 0000000000..d9b1222d8f --- /dev/null +++ b/.changeset/chatty-parents-search.md @@ -0,0 +1,5 @@ +--- +'@backstage/core': patch +--- + +Sort the table filter options by name. diff --git a/packages/core/src/components/Table/Table.tsx b/packages/core/src/components/Table/Table.tsx index d061be6d60..2251b8304e 100644 --- a/packages/core/src/components/Table/Table.tsx +++ b/packages/core/src/components/Table/Table.tsx @@ -363,7 +363,7 @@ export function Table({ placeholder: 'All results', label: filter.column, multiple: filter.type === 'multiple-select', - items: [...extractDistinctValues(filter.column)].map(value => ({ + items: [...extractDistinctValues(filter.column)].sort().map(value => ({ label: value, value, })), From 89ecdf526a7d1183b7cc4956105be418c6371bcb Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 14 Apr 2021 14:42:50 -0400 Subject: [PATCH 067/462] Update plugin example for composability Signed-off-by: Adam Harvey Signed-off-by: Brett Wright --- .../configure-app-with-plugins.md | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index cdef932127..1753676e19 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -34,23 +34,25 @@ CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. export { plugin as Circleci } from '@backstage/plugin-circleci'; ``` -3. Register the plugin router: +3. Register the plugin in the entity pages: ```jsx // packages/app/src/components/catalog/EntityPage.tsx - -import { Router as CircleCIRouter } from '@backstage/plugin-circleci'; +import { + EntityCircleCIContent, + isCircleCIAvailable, +} from '@backstage/plugin-circleci'; // Then somewhere inside -} -/>; + + +; ``` -Note that stand-alone plugins that are not "attached" to the Software Catalog -would be added outside the `EntityPage`. +This is just one example, but each Backstage instance may integrate content or +cards to suit their needs on different pages, tabs, etc. Note that stand-alone +plugins that are not "attached" to the Software Catalog would be added outside +the `EntityPage`. 4. [Optional] Add proxy config: From 6c3c255ff5fedff10e1d92fc64a407e95b91a995 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Thu, 15 Apr 2021 12:42:03 -0400 Subject: [PATCH 068/462] Fix pluginname Signed-off-by: Adam Harvey Signed-off-by: Brett Wright --- docs/getting-started/configure-app-with-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index 1753676e19..428f768a82 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -31,7 +31,7 @@ CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. ```js // packages/app/src/plugins.ts -export { plugin as Circleci } from '@backstage/plugin-circleci'; +export { plugin as CircleCi } from '@backstage/plugin-circleci'; ``` 3. Register the plugin in the entity pages: From 274fb80198a98ad7818370e043bdb64e1b2c3520 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Thu, 15 Apr 2021 14:41:10 -0400 Subject: [PATCH 069/462] Clarify example Signed-off-by: Adam Harvey Signed-off-by: Brett Wright --- .../configure-app-with-plugins.md | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index 428f768a82..b2f3a37d90 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -36,17 +36,22 @@ export { plugin as CircleCi } from '@backstage/plugin-circleci'; 3. Register the plugin in the entity pages: -```jsx -// packages/app/src/components/catalog/EntityPage.tsx -import { - EntityCircleCIContent, - isCircleCIAvailable, -} from '@backstage/plugin-circleci'; +```diff + // packages/app/src/components/catalog/EntityPage.tsx ++import { ++ EntityCircleCIContent, ++ isCircleCIAvailable, ++} from '@backstage/plugin-circleci'; -// Then somewhere inside - - -; +... + const cicdContent = ( + + ... ++ ++ ++ ; + + ); ``` This is just one example, but each Backstage instance may integrate content or From 21c90863a2485048bcf424985a854b4136bb8ad3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Apr 2021 04:19:34 +0000 Subject: [PATCH 070/462] chore(deps): bump diff from 4.0.2 to 5.0.0 Bumps [diff](https://github.com/kpdecker/jsdiff) from 4.0.2 to 5.0.0. - [Release notes](https://github.com/kpdecker/jsdiff/releases) - [Changelog](https://github.com/kpdecker/jsdiff/blob/master/release-notes.md) - [Commits](https://github.com/kpdecker/jsdiff/compare/v4.0.2...v5.0.0) Signed-off-by: dependabot[bot] Signed-off-by: Brett Wright --- packages/cli/package.json | 2 +- yarn.lock | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 0a8561fa16..548e659e76 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -62,7 +62,7 @@ "commander": "^6.1.0", "css-loader": "^3.5.3", "dashify": "^2.0.0", - "diff": "^4.0.2", + "diff": "^5.0.0", "esbuild": "^0.8.56", "eslint": "^7.1.0", "eslint-config-prettier": "^6.0.0", diff --git a/yarn.lock b/yarn.lock index 1f76456d00..2fe64c785d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11527,11 +11527,16 @@ diff@1.4.0: resolved "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" integrity sha1-fyjS657nsVqX79ic5j3P2qPMur8= -diff@^4.0.1, diff@^4.0.2: +diff@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" From 2730b30b7c543dde0051cbd7de31c19e977ed729 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Thu, 15 Apr 2021 21:05:26 -0400 Subject: [PATCH 071/462] Move diagram to system page Signed-off-by: Adam Harvey Signed-off-by: Brett Wright --- .changeset/sour-plums-enjoy.md | 7 +++++++ packages/app/src/components/catalog/EntityPage.tsx | 7 +++---- .../packages/app/src/components/catalog/EntityPage.tsx | 7 +++---- 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 .changeset/sour-plums-enjoy.md diff --git a/.changeset/sour-plums-enjoy.md b/.changeset/sour-plums-enjoy.md new file mode 100644 index 0000000000..ef68166255 --- /dev/null +++ b/.changeset/sour-plums-enjoy.md @@ -0,0 +1,7 @@ +--- +'@backstage/create-app': patch +--- + +Fix system diagram card to be on the system page + +To apply the same fix to an existing application, in `EntityPage.tsx` simply move the `` for the `/diagram` path from the `groupPage` down into the `systemPage` element. diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index d6f91957a9..d4db2b0e63 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -441,10 +441,6 @@ const groupPage = ( - - - - ); @@ -463,6 +459,9 @@ const systemPage = ( + + + ); diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx index f1aba46c52..a302bb6dd7 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx @@ -208,10 +208,6 @@ const groupPage = ( - - - - ); @@ -230,6 +226,9 @@ const systemPage = ( + + + ); From 8761385311c4c52e19ae6a25c82ff2a6e40f3fde Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 11:16:43 +0200 Subject: [PATCH 072/462] added datadog RUM events Signed-off-by: Brett Wright Signed-off-by: Brett Wright --- app-config.yaml | 6 ++ packages/app/public/index.html | 112 ++++++++++++------------- packages/cli/package.json | 30 +++++++ packages/cli/src/lib/bundler/config.ts | 10 +++ 4 files changed, 100 insertions(+), 58 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index afbda40852..56733436a6 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -2,6 +2,12 @@ app: title: Backstage Example App baseUrl: http://localhost:3000 googleAnalyticsTrackingId: # UA-000000-0 + datadogRum: + clientToken: '123456789' + applicationId: qwerty + # site: # datadoghq.eu default = datadoghq.com + # env: # optional + support: url: https://github.com/backstage/backstage/issues # Used by common ErrorPage items: # Used by common SupportButton component diff --git a/packages/app/public/index.html b/packages/app/public/index.html index 9a665141c0..e55e39f7d6 100644 --- a/packages/app/public/index.html +++ b/packages/app/public/index.html @@ -1,60 +1,34 @@ - - - - - - - - - - - - - - - - <%= app.title %> + + + + + + + + + + <%= app.title %> + - <% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId - === 'string') { %> - + <% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId==='string' ) { %> + <% } %> - - - -
- - - + + + \ No newline at end of file diff --git a/packages/cli/package.json b/packages/cli/package.json index 548e659e76..251b2ab076 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -180,6 +180,36 @@ "UA-000000-0" ] }, + "datadogRum": { + "type": "object", + "description": "Datadog RUM events configuration", + "properties": { + "env": { + "type": "string", + "visibility": "frontend", + "description": "Environment for Datadog RUM events" + }, + "clientToken": { + "type": "string", + "visibility": "frontend", + "description": "clientToken for Datadog RUM events" + }, + "applicationId": { + "type": "string", + "visibility": "frontend", + "description": "applicationId for Datadog RUM events" + }, + "site": { + "type": "string", + "visibility": "frontend", + "description": "site for Datadog RUM events" + } + }, + "required": [ + "clientToken", + "applicationId" + ] + }, "listen": { "type": "object", "description": "Listening configuration for local development", diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index f81e055f69..8837554f22 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -127,6 +127,16 @@ export async function createConfig( googleAnalyticsTrackingId: frontendConfig.getOptionalString( 'app.googleAnalyticsTrackingId', ), + datadogRum: { + env: frontendConfig.getOptionalString('app.datadogRum.env'), + clientToken: frontendConfig.getOptionalString( + 'app.datadogRum.clientToken', + ), + applicationId: frontendConfig.getOptionalString( + 'app.datadogRum.applicationId', + ), + site: frontendConfig.getOptionalString('app.datadogRum.site'), + }, }, }, }), From 1334c7868c7ffd0a0e5ef91021e8619edcc9c813 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 11:47:17 +0200 Subject: [PATCH 073/462] Added doco regarding Datadog installation Signed-off-by: Brett Wright Signed-off-by: Brett Wright --- docs/integrations/datadog-rum/installation.md | 30 +++++++++++++++++++ docs/plugins/observability.md | 5 ++++ 2 files changed, 35 insertions(+) create mode 100644 docs/integrations/datadog-rum/installation.md diff --git a/docs/integrations/datadog-rum/installation.md b/docs/integrations/datadog-rum/installation.md new file mode 100644 index 0000000000..b23f2b4039 --- /dev/null +++ b/docs/integrations/datadog-rum/installation.md @@ -0,0 +1,30 @@ +--- +id: installation +title: Datadog RUM Installation +sidebar_label: Installation +# prettier-ignore +description: Adding Datadog RUM to Your App +--- + +There is a basic [Datadog](https://docs.datadoghq.com/real_user_monitoring/) +integration built into Backstage. You can enable it by adding the following to +your app configuration: + +```yaml +app: + datadogRum: + clientToken: '123456789' + applicationId: qwerty + # site: # datadoghq.eu default = datadoghq.com + # env: # optional +``` + +Replace the clientToken and applicationId with the ones generated for you +datadog. + +optional arguments: + +``` +site: datadoghq.eu # default equals datadoghq.com +env: dev # allow to specify the environment +``` diff --git a/docs/plugins/observability.md b/docs/plugins/observability.md index de6f4bf988..b5a6a0ba60 100644 --- a/docs/plugins/observability.md +++ b/docs/plugins/observability.md @@ -13,6 +13,11 @@ Backstage integrator. See how to install Google Analytics in your app [here](../integrations/google-analytics/installation.md) +## Datadog RUM Events + +See how to install Datadog Events in your app +[here](../integrations/datadog-rum/installation.md) + ## Logging The backend supplies a central [winston](https://github.com/winstonjs/winston) From 479b291242198b44a24b71ad402e18873d14ef19 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 11:52:19 +0200 Subject: [PATCH 074/462] Added changeset Signed-off-by: Brett Wright Signed-off-by: Brett Wright --- .changeset/tiny-ears-love.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tiny-ears-love.md diff --git a/.changeset/tiny-ears-love.md b/.changeset/tiny-ears-love.md new file mode 100644 index 0000000000..2f7502fad7 --- /dev/null +++ b/.changeset/tiny-ears-love.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': major +--- + +Added support for Datadog rum events From 817e7fee1f7a9b5e4e35add761a908f69959f0fd Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 12:51:04 +0200 Subject: [PATCH 075/462] ran Prettier Signed-off-by: Brett Wright Signed-off-by: Brett Wright --- app-config.yaml | 2 +- packages/app/public/index.html | 121 ++++++++++++++++++++++----------- 2 files changed, 81 insertions(+), 42 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index 56733436a6..ac59874878 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -4,7 +4,7 @@ app: googleAnalyticsTrackingId: # UA-000000-0 datadogRum: clientToken: '123456789' - applicationId: qwerty + applicationId: qwerty # site: # datadoghq.eu default = datadoghq.com # env: # optional diff --git a/packages/app/public/index.html b/packages/app/public/index.html index e55e39f7d6..da4d3cf3b8 100644 --- a/packages/app/public/index.html +++ b/packages/app/public/index.html @@ -1,34 +1,60 @@ - - - - - - - - - - - - - - - - - - <%= app.title %> - + + + + + + + + + <%= app.title %> - <% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId==='string' ) { %> - + <% if (app.googleAnalyticsTrackingId && typeof + app.googleAnalyticsTrackingId==='string' ) { %> + - <% } %> - <% if (app.datadogRum.clientToken && app.datadogRum.applicationId ) { %> + <% } %> <% if (app.datadogRum.clientToken && app.datadogRum.applicationId ) + { %> <% } %> - + - - -
- - - - \ No newline at end of file + + From 948c4b6a30d14838ed612137edcd390a5a191276 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 15:23:49 +0200 Subject: [PATCH 076/462] Added Datadog to vocab Signed-off-by: Brett Wright --- .github/styles/vocab.txt | 1 + docs/integrations/datadog-rum/installation.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 226af9bf0a..7d0f36d858 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -13,6 +13,7 @@ Cloudformation Codecov Codehilite Config +Datadog Debounce Discoverability Dockerfile diff --git a/docs/integrations/datadog-rum/installation.md b/docs/integrations/datadog-rum/installation.md index b23f2b4039..50ebe722be 100644 --- a/docs/integrations/datadog-rum/installation.md +++ b/docs/integrations/datadog-rum/installation.md @@ -20,7 +20,7 @@ app: ``` Replace the clientToken and applicationId with the ones generated for you -datadog. +Datadog. optional arguments: From d04a4b7a2d9eea387d55d38a5a7453e2b29fe166 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 16:22:13 +0200 Subject: [PATCH 077/462] Delete sour-plums-enjoy.md Signed-off-by: Brett Wright --- .changeset/sour-plums-enjoy.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .changeset/sour-plums-enjoy.md diff --git a/.changeset/sour-plums-enjoy.md b/.changeset/sour-plums-enjoy.md deleted file mode 100644 index ef68166255..0000000000 --- a/.changeset/sour-plums-enjoy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Fix system diagram card to be on the system page - -To apply the same fix to an existing application, in `EntityPage.tsx` simply move the `` for the `/diagram` path from the `groupPage` down into the `systemPage` element. From a40c2aa853ae5af0acb0355c287b405726b8b55b Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 16:22:39 +0200 Subject: [PATCH 078/462] Delete configure-app-with-plugins.md Signed-off-by: Brett Wright --- .../configure-app-with-plugins.md | 99 ------------------- 1 file changed, 99 deletions(-) delete mode 100644 docs/getting-started/configure-app-with-plugins.md diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md deleted file mode 100644 index b2f3a37d90..0000000000 --- a/docs/getting-started/configure-app-with-plugins.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -id: configure-app-with-plugins -title: Configuring App with plugins -description: Documentation on How Configuring App with plugins ---- - -Backstage plugins customize the app for your needs. There is a -[plugin marketplace](https://backstage.io/plugins) with plugins for many common -infrastructure needs - CI/CD, monitoring, auditing, and more. - -## Adding existing plugins to your app - -The following steps assume that you have -[created a Backstage app](./create-an-app.md) and want to add an existing plugin -to it. We are using the -[CircleCI](https://github.com/backstage/backstage/blob/master/plugins/circleci/README.md) -plugin in this example. - -1. Add the plugin's npm package to the repo: - -```bash -yarn workspace app add @backstage/plugin-circleci -``` - -Note the plugin is added to the `app` package, rather than the root -package.json. Backstage Apps are set up as monorepos with -[yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). Since -CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. - -2. Add the plugin itself to the App: - -```js -// packages/app/src/plugins.ts -export { plugin as CircleCi } from '@backstage/plugin-circleci'; -``` - -3. Register the plugin in the entity pages: - -```diff - // packages/app/src/components/catalog/EntityPage.tsx -+import { -+ EntityCircleCIContent, -+ isCircleCIAvailable, -+} from '@backstage/plugin-circleci'; - -... - const cicdContent = ( - - ... -+ -+ -+ ; - - ); -``` - -This is just one example, but each Backstage instance may integrate content or -cards to suit their needs on different pages, tabs, etc. Note that stand-alone -plugins that are not "attached" to the Software Catalog would be added outside -the `EntityPage`. - -4. [Optional] Add proxy config: - -```yaml -// app-config.yaml -proxy: - '/circleci/api': - target: https://circleci.com/api/v1.1 - headers: - Circle-Token: ${CIRCLECI_AUTH_TOKEN} -``` - -### Adding a plugin page to the Sidebar - -In a standard Backstage app created with -[@backstage/create-app](./create-an-app.md), the sidebar is managed inside -`packages/app/src/components/Root/Root.tsx`. The file exports the entire -`Sidebar` element of your app, which you can extend with additional entries by -adding new `SidebarItem` elements. - -For example, if you install the `api-docs` plugin, a matching `SidebarItem` -could be something like this: - -```tsx -// Import icon from MUI -import ExtensionIcon from '@material-ui/icons/Extension'; - -// ... inside the AppSidebar component -; -``` - -You can also use your own SVGs directly as icon components. Just make sure they -are sized according to the Material UI's -[SvgIcon](https://material-ui.com/api/svg-icon/) default of 24x24px, and set the -extension to `.icon.svg`. For example: - -```ts -import InternalToolIcon from './internal-tool.icon.svg'; -``` From 0f649240bf982f3e9ee8e75b8c47dfd05018d881 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 16:23:13 +0200 Subject: [PATCH 079/462] Delete EntityPage.tsx Signed-off-by: Brett Wright --- .../app/src/components/catalog/EntityPage.tsx | 494 ------------------ 1 file changed, 494 deletions(-) delete mode 100644 packages/app/src/components/catalog/EntityPage.tsx diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx deleted file mode 100644 index d4db2b0e63..0000000000 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { ReactNode, useMemo, useState } from 'react'; -import BadgeIcon from '@material-ui/icons/CallToAction'; -import { EmptyState } from '@backstage/core'; -import { - EntityApiDefinitionCard, - EntityConsumingComponentsCard, - EntityHasApisCard, - EntityProvidingComponentsCard, - EntityProvidedApisCard, - EntityConsumedApisCard, -} from '@backstage/plugin-api-docs'; -import { EntityBadgesDialog } from '@backstage/plugin-badges'; -import { - EntityAboutCard, - EntityHasComponentsCard, - EntityHasSubcomponentsCard, - EntityHasSystemsCard, - EntityLayout, - EntityLinksCard, - EntitySystemDiagramCard, - EntitySwitch, - isComponentType, - isKind, -} from '@backstage/plugin-catalog'; -import { - EntityCircleCIContent, - isCircleCIAvailable, -} from '@backstage/plugin-circleci'; -import { - EntityCloudbuildContent, - isCloudbuildAvailable, -} from '@backstage/plugin-cloudbuild'; -import { - EntityGithubActionsContent, - EntityRecentGithubActionsRunsCard, - isGithubActionsAvailable, -} from '@backstage/plugin-github-actions'; -import { - EntityJenkinsContent, - EntityLatestJenkinsRunCard, - isJenkinsAvailable, -} from '@backstage/plugin-jenkins'; -import { EntityKafkaContent } from '@backstage/plugin-kafka'; -import { EntityKubernetesContent } from '@backstage/plugin-kubernetes'; -import { - EntityLastLighthouseAuditCard, - EntityLighthouseContent, - isLighthouseAvailable, -} from '@backstage/plugin-lighthouse'; -import { - EntityGroupProfileCard, - EntityMembersListCard, - EntityOwnershipCard, - EntityUserProfileCard, -} from '@backstage/plugin-org'; -import { - EntityPagerDutyCard, - isPagerDutyAvailable, -} from '@backstage/plugin-pagerduty'; -import { - EntityRollbarContent, - isRollbarAvailable, -} from '@backstage/plugin-rollbar'; -import { EntitySentryContent } from '@backstage/plugin-sentry'; -import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; -import { EntityTodoContent } from '@backstage/plugin-todo'; -import { Button, Grid } from '@material-ui/core'; -import { - EntityBuildkiteContent, - isBuildkiteAvailable, -} from '@roadiehq/backstage-plugin-buildkite'; -import { - EntityGithubInsightsContent, - EntityGithubInsightsLanguagesCard, - EntityGithubInsightsReadmeCard, - EntityGithubInsightsReleasesCard, - isGithubInsightsAvailable, -} from '@roadiehq/backstage-plugin-github-insights'; -import { - EntityGithubPullRequestsContent, - EntityGithubPullRequestsOverviewCard, - isGithubPullRequestsAvailable, -} from '@roadiehq/backstage-plugin-github-pull-requests'; -import { - EntityTravisCIContent, - EntityTravisCIOverviewCard, - isTravisciAvailable, -} from '@roadiehq/backstage-plugin-travis-ci'; - -const EntityLayoutWrapper = (props: { children?: ReactNode }) => { - const [badgesDialogOpen, setBadgesDialogOpen] = useState(false); - - const extraMenuItems = useMemo(() => { - return [ - { - title: 'Badges', - Icon: BadgeIcon, - onClick: () => setBadgesDialogOpen(true), - }, - ]; - }, []); - - return ( - <> - - {props.children} - - setBadgesDialogOpen(false)} - /> - - ); -}; - -export const cicdContent = ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - Read more - - } - /> - - -); - -const cicdCard = ( - - - - - - - - - - - - - - - - - - - -); - -const errorsContent = ( - - - - - - - - - -); - -const overviewContent = ( - - - - - - - - - - - - - - - - - - {cicdCard} - - - Boolean(isGithubInsightsAvailable(e))}> - - - - - - - - - - - - - - - - - - - - Boolean(isGithubPullRequestsAvailable(e))}> - - - - - - - - - - -); - -const serviceEntityPage = ( - - - {overviewContent} - - - - {cicdContent} - - - - {errorsContent} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -const websiteEntityPage = ( - - - {overviewContent} - - - - {cicdContent} - - - - - - - - {errorsContent} - - - - - - - - - - - - - - - - - - - - - - -); - -const defaultEntityPage = ( - - - {overviewContent} - - - - - - - - - - -); - -const componentPage = ( - - - {serviceEntityPage} - - - - {websiteEntityPage} - - - {defaultEntityPage} - -); - -const apiPage = ( - - - - - - - - - - - - - - - - - - - - - - - - - -); - -const userPage = ( - - - - - - - - - - - - -); - -const groupPage = ( - - - - - - - - - - - - - - - -); - -const systemPage = ( - - - - - - - - - - - - - - - - - - -); - -const domainPage = ( - - - - - - - - - - - - -); - -export const entityPage = ( - - - - - - - - - {defaultEntityPage} - -); From 77a2335997f0956006a4d4c099430794a0b6759f Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 16:23:46 +0200 Subject: [PATCH 080/462] Delete EntityPage.tsx Signed-off-by: Brett Wright --- .../app/src/components/catalog/EntityPage.tsx | 261 ------------------ 1 file changed, 261 deletions(-) delete mode 100644 packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx deleted file mode 100644 index a302bb6dd7..0000000000 --- a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { Button, Grid } from '@material-ui/core'; -import { EmptyState } from '@backstage/core'; -import { - EntityApiDefinitionCard, - EntityConsumedApisCard, - EntityConsumingComponentsCard, - EntityHasApisCard, - EntityProvidedApisCard, - EntityProvidingComponentsCard, -} from '@backstage/plugin-api-docs'; -import { - EntityAboutCard, - EntitySystemDiagramCard, - EntityHasComponentsCard, - EntityHasSystemsCard, - EntityLayout, - EntitySwitch, - isComponentType, - isKind, -} from '@backstage/plugin-catalog'; -import { - isGithubActionsAvailable, - EntityGithubActionsContent, -} from '@backstage/plugin-github-actions'; -import { - EntityUserProfileCard, - EntityGroupProfileCard, - EntityMembersListCard, - EntityOwnershipCard, -} from '@backstage/plugin-org'; -import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; - -const cicdContent = ( - // This is an example of how you can implement your company's logic in entity page. - // You can for example enforce that all components of type 'service' should use GitHubActions - - - - - - - - Read more - - } - /> - - -); - -const overviewContent = ( - - - - - -); - -const serviceEntityPage = ( - - - {overviewContent} - - - - {cicdContent} - - - - - - - - - - - - - - - - - -); - -const websiteEntityPage = ( - - - {overviewContent} - - - - {cicdContent} - - - - - - -); - -const defaultEntityPage = ( - - - {overviewContent} - - - - - - -); - -const componentPage = ( - - - {serviceEntityPage} - - - - {websiteEntityPage} - - - {defaultEntityPage} - -); - -const apiPage = ( - - - - - - - - - - - - - - - - - - - - - - - - - -); - -const userPage = ( - - - - - - - - - - - - -); - -const groupPage = ( - - - - - - - - - - - - - - - -); - -const systemPage = ( - - - - - - - - - - - - - - - - - - -); - -const domainPage = ( - - - - - - - - - - - - -); - -export const entityPage = ( - - - - - - - - - {defaultEntityPage} - -); From 66cd739fec8eeae4c7c02f066e33e6a3cc184104 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 18:58:16 +0200 Subject: [PATCH 081/462] Revert "Delete EntityPage.tsx" This reverts commit 59eda628a87dc470ae1c5d2b7b46ced129fea289. Signed-off-by: Brett Wright --- .../app/src/components/catalog/EntityPage.tsx | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx new file mode 100644 index 0000000000..a302bb6dd7 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx @@ -0,0 +1,261 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Button, Grid } from '@material-ui/core'; +import { EmptyState } from '@backstage/core'; +import { + EntityApiDefinitionCard, + EntityConsumedApisCard, + EntityConsumingComponentsCard, + EntityHasApisCard, + EntityProvidedApisCard, + EntityProvidingComponentsCard, +} from '@backstage/plugin-api-docs'; +import { + EntityAboutCard, + EntitySystemDiagramCard, + EntityHasComponentsCard, + EntityHasSystemsCard, + EntityLayout, + EntitySwitch, + isComponentType, + isKind, +} from '@backstage/plugin-catalog'; +import { + isGithubActionsAvailable, + EntityGithubActionsContent, +} from '@backstage/plugin-github-actions'; +import { + EntityUserProfileCard, + EntityGroupProfileCard, + EntityMembersListCard, + EntityOwnershipCard, +} from '@backstage/plugin-org'; +import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; + +const cicdContent = ( + // This is an example of how you can implement your company's logic in entity page. + // You can for example enforce that all components of type 'service' should use GitHubActions + + + + + + + + Read more + + } + /> + + +); + +const overviewContent = ( + + + + + +); + +const serviceEntityPage = ( + + + {overviewContent} + + + + {cicdContent} + + + + + + + + + + + + + + + + + +); + +const websiteEntityPage = ( + + + {overviewContent} + + + + {cicdContent} + + + + + + +); + +const defaultEntityPage = ( + + + {overviewContent} + + + + + + +); + +const componentPage = ( + + + {serviceEntityPage} + + + + {websiteEntityPage} + + + {defaultEntityPage} + +); + +const apiPage = ( + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const userPage = ( + + + + + + + + + + + + +); + +const groupPage = ( + + + + + + + + + + + + + + + +); + +const systemPage = ( + + + + + + + + + + + + + + + + + + +); + +const domainPage = ( + + + + + + + + + + + + +); + +export const entityPage = ( + + + + + + + + + {defaultEntityPage} + +); From 47b4c33c1f60da9dbf4fa936289b2f77be73bb83 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:00:51 +0200 Subject: [PATCH 082/462] Revert "Delete EntityPage.tsx" This reverts commit 157318b7b261541758c353482d98e0372a4369ce. Signed-off-by: Brett Wright --- .../app/src/components/catalog/EntityPage.tsx | 494 ++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 packages/app/src/components/catalog/EntityPage.tsx diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx new file mode 100644 index 0000000000..d4db2b0e63 --- /dev/null +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -0,0 +1,494 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { ReactNode, useMemo, useState } from 'react'; +import BadgeIcon from '@material-ui/icons/CallToAction'; +import { EmptyState } from '@backstage/core'; +import { + EntityApiDefinitionCard, + EntityConsumingComponentsCard, + EntityHasApisCard, + EntityProvidingComponentsCard, + EntityProvidedApisCard, + EntityConsumedApisCard, +} from '@backstage/plugin-api-docs'; +import { EntityBadgesDialog } from '@backstage/plugin-badges'; +import { + EntityAboutCard, + EntityHasComponentsCard, + EntityHasSubcomponentsCard, + EntityHasSystemsCard, + EntityLayout, + EntityLinksCard, + EntitySystemDiagramCard, + EntitySwitch, + isComponentType, + isKind, +} from '@backstage/plugin-catalog'; +import { + EntityCircleCIContent, + isCircleCIAvailable, +} from '@backstage/plugin-circleci'; +import { + EntityCloudbuildContent, + isCloudbuildAvailable, +} from '@backstage/plugin-cloudbuild'; +import { + EntityGithubActionsContent, + EntityRecentGithubActionsRunsCard, + isGithubActionsAvailable, +} from '@backstage/plugin-github-actions'; +import { + EntityJenkinsContent, + EntityLatestJenkinsRunCard, + isJenkinsAvailable, +} from '@backstage/plugin-jenkins'; +import { EntityKafkaContent } from '@backstage/plugin-kafka'; +import { EntityKubernetesContent } from '@backstage/plugin-kubernetes'; +import { + EntityLastLighthouseAuditCard, + EntityLighthouseContent, + isLighthouseAvailable, +} from '@backstage/plugin-lighthouse'; +import { + EntityGroupProfileCard, + EntityMembersListCard, + EntityOwnershipCard, + EntityUserProfileCard, +} from '@backstage/plugin-org'; +import { + EntityPagerDutyCard, + isPagerDutyAvailable, +} from '@backstage/plugin-pagerduty'; +import { + EntityRollbarContent, + isRollbarAvailable, +} from '@backstage/plugin-rollbar'; +import { EntitySentryContent } from '@backstage/plugin-sentry'; +import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; +import { EntityTodoContent } from '@backstage/plugin-todo'; +import { Button, Grid } from '@material-ui/core'; +import { + EntityBuildkiteContent, + isBuildkiteAvailable, +} from '@roadiehq/backstage-plugin-buildkite'; +import { + EntityGithubInsightsContent, + EntityGithubInsightsLanguagesCard, + EntityGithubInsightsReadmeCard, + EntityGithubInsightsReleasesCard, + isGithubInsightsAvailable, +} from '@roadiehq/backstage-plugin-github-insights'; +import { + EntityGithubPullRequestsContent, + EntityGithubPullRequestsOverviewCard, + isGithubPullRequestsAvailable, +} from '@roadiehq/backstage-plugin-github-pull-requests'; +import { + EntityTravisCIContent, + EntityTravisCIOverviewCard, + isTravisciAvailable, +} from '@roadiehq/backstage-plugin-travis-ci'; + +const EntityLayoutWrapper = (props: { children?: ReactNode }) => { + const [badgesDialogOpen, setBadgesDialogOpen] = useState(false); + + const extraMenuItems = useMemo(() => { + return [ + { + title: 'Badges', + Icon: BadgeIcon, + onClick: () => setBadgesDialogOpen(true), + }, + ]; + }, []); + + return ( + <> + + {props.children} + + setBadgesDialogOpen(false)} + /> + + ); +}; + +export const cicdContent = ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + Read more + + } + /> + + +); + +const cicdCard = ( + + + + + + + + + + + + + + + + + + + +); + +const errorsContent = ( + + + + + + + + + +); + +const overviewContent = ( + + + + + + + + + + + + + + + + + + {cicdCard} + + + Boolean(isGithubInsightsAvailable(e))}> + + + + + + + + + + + + + + + + + + + + Boolean(isGithubPullRequestsAvailable(e))}> + + + + + + + + + + +); + +const serviceEntityPage = ( + + + {overviewContent} + + + + {cicdContent} + + + + {errorsContent} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const websiteEntityPage = ( + + + {overviewContent} + + + + {cicdContent} + + + + + + + + {errorsContent} + + + + + + + + + + + + + + + + + + + + + + +); + +const defaultEntityPage = ( + + + {overviewContent} + + + + + + + + + + +); + +const componentPage = ( + + + {serviceEntityPage} + + + + {websiteEntityPage} + + + {defaultEntityPage} + +); + +const apiPage = ( + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const userPage = ( + + + + + + + + + + + + +); + +const groupPage = ( + + + + + + + + + + + + + + + +); + +const systemPage = ( + + + + + + + + + + + + + + + + + + +); + +const domainPage = ( + + + + + + + + + + + + +); + +export const entityPage = ( + + + + + + + + + {defaultEntityPage} + +); From de00581391ca8e85f3dd8c3951d5af66e2215c36 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:00:57 +0200 Subject: [PATCH 083/462] Revert "Delete configure-app-with-plugins.md" This reverts commit ce16cd5233779e0dbe24b2756027de83484ead84. Signed-off-by: Brett Wright --- .../configure-app-with-plugins.md | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docs/getting-started/configure-app-with-plugins.md diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md new file mode 100644 index 0000000000..b2f3a37d90 --- /dev/null +++ b/docs/getting-started/configure-app-with-plugins.md @@ -0,0 +1,99 @@ +--- +id: configure-app-with-plugins +title: Configuring App with plugins +description: Documentation on How Configuring App with plugins +--- + +Backstage plugins customize the app for your needs. There is a +[plugin marketplace](https://backstage.io/plugins) with plugins for many common +infrastructure needs - CI/CD, monitoring, auditing, and more. + +## Adding existing plugins to your app + +The following steps assume that you have +[created a Backstage app](./create-an-app.md) and want to add an existing plugin +to it. We are using the +[CircleCI](https://github.com/backstage/backstage/blob/master/plugins/circleci/README.md) +plugin in this example. + +1. Add the plugin's npm package to the repo: + +```bash +yarn workspace app add @backstage/plugin-circleci +``` + +Note the plugin is added to the `app` package, rather than the root +package.json. Backstage Apps are set up as monorepos with +[yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). Since +CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. + +2. Add the plugin itself to the App: + +```js +// packages/app/src/plugins.ts +export { plugin as CircleCi } from '@backstage/plugin-circleci'; +``` + +3. Register the plugin in the entity pages: + +```diff + // packages/app/src/components/catalog/EntityPage.tsx ++import { ++ EntityCircleCIContent, ++ isCircleCIAvailable, ++} from '@backstage/plugin-circleci'; + +... + const cicdContent = ( + + ... ++ ++ ++ ; + + ); +``` + +This is just one example, but each Backstage instance may integrate content or +cards to suit their needs on different pages, tabs, etc. Note that stand-alone +plugins that are not "attached" to the Software Catalog would be added outside +the `EntityPage`. + +4. [Optional] Add proxy config: + +```yaml +// app-config.yaml +proxy: + '/circleci/api': + target: https://circleci.com/api/v1.1 + headers: + Circle-Token: ${CIRCLECI_AUTH_TOKEN} +``` + +### Adding a plugin page to the Sidebar + +In a standard Backstage app created with +[@backstage/create-app](./create-an-app.md), the sidebar is managed inside +`packages/app/src/components/Root/Root.tsx`. The file exports the entire +`Sidebar` element of your app, which you can extend with additional entries by +adding new `SidebarItem` elements. + +For example, if you install the `api-docs` plugin, a matching `SidebarItem` +could be something like this: + +```tsx +// Import icon from MUI +import ExtensionIcon from '@material-ui/icons/Extension'; + +// ... inside the AppSidebar component +; +``` + +You can also use your own SVGs directly as icon components. Just make sure they +are sized according to the Material UI's +[SvgIcon](https://material-ui.com/api/svg-icon/) default of 24x24px, and set the +extension to `.icon.svg`. For example: + +```ts +import InternalToolIcon from './internal-tool.icon.svg'; +``` From 5d01971dd33c3d49852e1886cc2f46046419d9a9 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:01:00 +0200 Subject: [PATCH 084/462] Revert "Delete sour-plums-enjoy.md" This reverts commit 7d9de03c4432d82ffad10937f39243f6fa4fcce8. Signed-off-by: Brett Wright --- .changeset/sour-plums-enjoy.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/sour-plums-enjoy.md diff --git a/.changeset/sour-plums-enjoy.md b/.changeset/sour-plums-enjoy.md new file mode 100644 index 0000000000..ef68166255 --- /dev/null +++ b/.changeset/sour-plums-enjoy.md @@ -0,0 +1,7 @@ +--- +'@backstage/create-app': patch +--- + +Fix system diagram card to be on the system page + +To apply the same fix to an existing application, in `EntityPage.tsx` simply move the `` for the `/diagram` path from the `groupPage` down into the `systemPage` element. From 766533df4b95c133953263621e1dd142eb4b7c5f Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:01:03 +0200 Subject: [PATCH 085/462] Revert "Move diagram to system page" This reverts commit 876a468740f25b69d6dc7737586d7d64348daf6a. Signed-off-by: Brett Wright --- .changeset/sour-plums-enjoy.md | 7 ------- packages/app/src/components/catalog/EntityPage.tsx | 7 ++++--- .../packages/app/src/components/catalog/EntityPage.tsx | 7 ++++--- 3 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 .changeset/sour-plums-enjoy.md diff --git a/.changeset/sour-plums-enjoy.md b/.changeset/sour-plums-enjoy.md deleted file mode 100644 index ef68166255..0000000000 --- a/.changeset/sour-plums-enjoy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Fix system diagram card to be on the system page - -To apply the same fix to an existing application, in `EntityPage.tsx` simply move the `` for the `/diagram` path from the `groupPage` down into the `systemPage` element. diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index d4db2b0e63..d6f91957a9 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -441,6 +441,10 @@ const groupPage = ( + + + + ); @@ -459,9 +463,6 @@ const systemPage = ( - - - ); diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx index a302bb6dd7..f1aba46c52 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx @@ -208,6 +208,10 @@ const groupPage = ( + + + + ); @@ -226,9 +230,6 @@ const systemPage = ( - - - ); From 4949915fb32edd6d31bb5b24e1559cf517494bce Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:01:07 +0200 Subject: [PATCH 086/462] Revert "chore(deps): bump diff from 4.0.2 to 5.0.0" This reverts commit 2213de5068443f5036f1ea5a899867086266dc52. Signed-off-by: Brett Wright --- packages/cli/package.json | 2 +- yarn.lock | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 251b2ab076..db7ac2774c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -62,7 +62,7 @@ "commander": "^6.1.0", "css-loader": "^3.5.3", "dashify": "^2.0.0", - "diff": "^5.0.0", + "diff": "^4.0.2", "esbuild": "^0.8.56", "eslint": "^7.1.0", "eslint-config-prettier": "^6.0.0", diff --git a/yarn.lock b/yarn.lock index 2fe64c785d..1f76456d00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11527,16 +11527,11 @@ diff@1.4.0: resolved "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" integrity sha1-fyjS657nsVqX79ic5j3P2qPMur8= -diff@^4.0.1: +diff@^4.0.1, diff@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -diff@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" From f77db9572d05d835154461e5e86a6907f2731d67 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:01:10 +0200 Subject: [PATCH 087/462] Revert "Clarify example" This reverts commit 72eaf17eaa408af347db07881ef6a8b7619c7adf. Signed-off-by: Brett Wright --- .../configure-app-with-plugins.md | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index b2f3a37d90..428f768a82 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -36,22 +36,17 @@ export { plugin as CircleCi } from '@backstage/plugin-circleci'; 3. Register the plugin in the entity pages: -```diff - // packages/app/src/components/catalog/EntityPage.tsx -+import { -+ EntityCircleCIContent, -+ isCircleCIAvailable, -+} from '@backstage/plugin-circleci'; +```jsx +// packages/app/src/components/catalog/EntityPage.tsx +import { + EntityCircleCIContent, + isCircleCIAvailable, +} from '@backstage/plugin-circleci'; -... - const cicdContent = ( - - ... -+ -+ -+ ; - - ); +// Then somewhere inside + + +; ``` This is just one example, but each Backstage instance may integrate content or From 314b8bf1e9e786bdbb31d107aa58ee44ee5eb1ee Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:01:11 +0200 Subject: [PATCH 088/462] Revert "Fix pluginname" This reverts commit cb287be816d8149153cd72df5d6318efe04b04d4. Signed-off-by: Brett Wright --- docs/getting-started/configure-app-with-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index 428f768a82..1753676e19 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -31,7 +31,7 @@ CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. ```js // packages/app/src/plugins.ts -export { plugin as CircleCi } from '@backstage/plugin-circleci'; +export { plugin as Circleci } from '@backstage/plugin-circleci'; ``` 3. Register the plugin in the entity pages: From 50c5808b624bc7f6de4d79587a461ad3c48c6361 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:01:14 +0200 Subject: [PATCH 089/462] Revert "Update plugin example for composability" This reverts commit 7ca780442219d2ec85fb296c3d1584c0d3aab1db. Signed-off-by: Brett Wright --- .../configure-app-with-plugins.md | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index 1753676e19..cdef932127 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -34,25 +34,23 @@ CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. export { plugin as Circleci } from '@backstage/plugin-circleci'; ``` -3. Register the plugin in the entity pages: +3. Register the plugin router: ```jsx // packages/app/src/components/catalog/EntityPage.tsx -import { - EntityCircleCIContent, - isCircleCIAvailable, -} from '@backstage/plugin-circleci'; + +import { Router as CircleCIRouter } from '@backstage/plugin-circleci'; // Then somewhere inside - - -; +} +/>; ``` -This is just one example, but each Backstage instance may integrate content or -cards to suit their needs on different pages, tabs, etc. Note that stand-alone -plugins that are not "attached" to the Software Catalog would be added outside -the `EntityPage`. +Note that stand-alone plugins that are not "attached" to the Software Catalog +would be added outside the `EntityPage`. 4. [Optional] Add proxy config: From 4c89acec0e6d62cdbfda4137d626af82dc52a9ab Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Mon, 19 Apr 2021 19:44:36 +0200 Subject: [PATCH 090/462] change patch to minor Signed-off-by: Brett Wright --- .changeset/tiny-ears-love.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tiny-ears-love.md b/.changeset/tiny-ears-love.md index 2f7502fad7..52218e2ecc 100644 --- a/.changeset/tiny-ears-love.md +++ b/.changeset/tiny-ears-love.md @@ -1,5 +1,5 @@ --- -'@backstage/cli': major +'@backstage/cli': minor --- Added support for Datadog rum events From 909eb5ecc66bedbddd948bf15684c887dd254b96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Apr 2021 19:13:40 +0000 Subject: [PATCH 091/462] chore(deps): bump ssri from 6.0.1 to 6.0.2 Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2. - [Release notes](https://github.com/npm/ssri/releases) - [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md) - [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2) Signed-off-by: dependabot[bot] --- yarn.lock | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/yarn.lock b/yarn.lock index b3efdedbd4..9233744570 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13145,9 +13145,9 @@ fetch-readablestream@^0.2.0: integrity sha512-qu4mXWf4wus4idBIN/kVH+XSer8IZ9CwHP+Pd7DL7TuKNC1hP7ykon4kkBjwJF3EMX2WsFp4hH7gU7CyL7ucXw== figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== figures@^1.7.0: version "1.7.0" @@ -18619,14 +18619,7 @@ minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: safe-buffer "^5.1.2" yallist "^3.0.0" -minipass@^3.0.0, minipass@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" - integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== - dependencies: - yallist "^4.0.0" - -minipass@^3.1.0, minipass@^3.1.3: +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== @@ -24080,20 +24073,13 @@ sshpk@^1.7.0: tweetnacl "~0.14.0" ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" - integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA== - dependencies: - minipass "^3.1.1" - -ssri@^8.0.1: +ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== From 9b9a8f39b60ba68aa21b518f012e6878c51a76af Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Mon, 19 Apr 2021 20:35:56 -0400 Subject: [PATCH 092/462] Remove WIP Signed-off-by: Adam Harvey --- plugins/catalog/README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/README.md b/plugins/catalog/README.md index e9405a41f5..2940fecaa1 100644 --- a/plugins/catalog/README.md +++ b/plugins/catalog/README.md @@ -1,12 +1,25 @@ -# Catalog Frontend - -WORK IN PROGRESS +# Backstage Catalog Frontend This is the frontend part of the default catalog plugin. It will implement the core API for handling your catalog of software, and supply the base views to show and manage them. +## Getting Started + +This frontend plugin can be started in a standalone mode from directly in this package +with `yarn start`. However, it will have limited functionality and that process is +most convenient when developing the catalog frontend plugin itself. + +To evaluate the catalog and have a greater amount of functionality available, from the main +Backstage root folder, instead do: + +```bash +yarn dev +``` + +This will launch both the front and backend in same window, populated some example entities. + ## Links - [Backend part of the plugin](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend) From ac6025f63afce4b964c528803543e414befe8692 Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" Date: Mon, 19 Apr 2021 18:07:49 +0800 Subject: [PATCH 093/462] techdocs-plugin: add feedback link for Github/Gitlab source repos Signed-off-by: Chongyang Adrian, Ke --- .changeset/techdocs-eight-camels-hear.md | 8 ++ .../techdocs/src/reader/components/Reader.tsx | 6 +- .../transformers/addGitFeedbackLink.test.ts | 115 ++++++++++++++++++ .../reader/transformers/addGitFeedbackLink.ts | 86 +++++++++++++ .../techdocs/src/reader/transformers/index.ts | 1 + 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 .changeset/techdocs-eight-camels-hear.md create mode 100644 plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts create mode 100644 plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts diff --git a/.changeset/techdocs-eight-camels-hear.md b/.changeset/techdocs-eight-camels-hear.md new file mode 100644 index 0000000000..0d6c16f725 --- /dev/null +++ b/.changeset/techdocs-eight-camels-hear.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-techdocs': minor +--- + +Add feedback link icon in Techdocs Reader that directs to Gitlab or Github repo issue page with prefilled title and source link. +For link to appear, requires repo_url and edit_uri to be filled in mkdocs.yml, as per https://www.mkdocs.org/user-guide/configuration. edit_uri will need to be specified for self-hosted Gitlab/Github with different hostnames. +Gitlab or Github detection checks for 'gitlab' or 'github' in hostname of source in repo_url; +additionally 'techdocs.feedback.gitlab' and '.github' in app config can be used to specify hostnames that should be recognised as the respective Git hosting for the feedback link. diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index feed758caa..ff4f47dca0 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { EntityName } from '@backstage/catalog-model'; -import { useApi } from '@backstage/core'; +import { useApi, configApiRef } from '@backstage/core'; import { BackstageTheme } from '@backstage/theme'; import { useTheme } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; @@ -31,6 +31,7 @@ import transformer, { rewriteDocLinks, sanitizeDOM, simplifyMkdocsFooter, + addGitFeedbackLink, } from '../transformers'; import { TechDocsNotFound } from './TechDocsNotFound'; import TechDocsProgressBar from './TechDocsProgressBar'; @@ -52,6 +53,7 @@ export const Reader = ({ entityId, onReady }: Props) => { const [loadedPath, setLoadedPath] = useState(''); const [atInitialLoad, setAtInitialLoad] = useState(true); const [newerDocsExist, setNewerDocsExist] = useState(false); + const configApi = useApi(configApiRef); const { value: isSynced, @@ -142,6 +144,7 @@ export const Reader = ({ entityId, onReady }: Props) => { rewriteDocLinks(), removeMkdocsHeader(), simplifyMkdocsFooter(), + addGitFeedbackLink(configApi), injectCss({ css: ` body { @@ -313,6 +316,7 @@ export const Reader = ({ entityId, onReady }: Props) => { name, newerDocsExist, isSynced, + configApi, ]); // docLoadError not considered an error state if sync request is still ongoing diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts new file mode 100644 index 0000000000..cc451c3a25 --- /dev/null +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts @@ -0,0 +1,115 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTestShadowDom } from '../../test-utils'; +import { addGitFeedbackLink } from './addGitFeedbackLink'; + +const configApi = { + getOptionalString: function getOptionalString(key: string) { + return key === 'gitlab' ? 'gitlab.com' : 'github.com'; + }, +}; + +describe('addGitFeedbackLink', () => { + it('adds a feedback link when a Gitlab source edit link is available', () => { + const shadowDom = createTestShadowDom( + ` + + +
+

HeaderText

+ +
+ + `, + { + preTransformers: [addGitFeedbackLink(configApi)], + postTransformers: [], + }, + ); + + expect(shadowDom.querySelector('#git-feedback-link')).toBeTruthy(); + expect( + (shadowDom.querySelector('#git-feedback-link') as HTMLLinkElement)!.href, + ).toEqual( + 'https://gitlab.com/reponame/username/issues/new?issue[title]=Documentation%20Feedback%3A%20HeaderText&issue[description]=Page%20source%3A%0Ahttps%3A%2F%2Fgitlab.com%2Freponame%2Fusername%2Fdocs%2FTestDoc.md%0A%0AFeedback%3A', + ); + }); + + it('adds a feedback link when a Github source edit link is available', () => { + const shadowDom = createTestShadowDom( + ` + + + + + `, + { + preTransformers: [addGitFeedbackLink(configApi)], + postTransformers: [], + }, + ); + + expect(shadowDom.querySelector('#git-feedback-link')).toBeTruthy(); + expect( + (shadowDom.querySelector('#git-feedback-link') as HTMLLinkElement)!.href, + ).toEqual( + 'https://github.com/reponame/username/issues/new?title=Documentation%20Feedback%3A%20HeaderText&body=Page%20source%3A%0Ahttps%3A%2F%2Fgithub.com%2Freponame%2Fusername%2Fdocs%2FTestDoc.md%0A%0AFeedback%3A', + ); + }); + + it('does not add a feedback link when no source edit link is available', () => { + const shadowDom = createTestShadowDom( + ` + + + + + `, + { + preTransformers: [addGitFeedbackLink(configApi)], + postTransformers: [], + }, + ); + + expect(shadowDom.querySelector('#git-feedback-link')).toBeFalsy(); + }); + + it('does not add a feedback link when a Gitlab or Github source edit link is not available', () => { + const shadowDom = createTestShadowDom( + ` + + +
+

Conveyor Pipelines

+ +
+ + `, + { + preTransformers: [addGitFeedbackLink(configApi)], + postTransformers: [], + }, + ); + + expect(shadowDom.querySelector('#git-feedback-link')).toBeFalsy(); + }); +}); diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts new file mode 100644 index 0000000000..d19d90228c --- /dev/null +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts @@ -0,0 +1,86 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Transformer } from './index'; +import FeedbackOutlinedIcon from '@material-ui/icons/FeedbackOutlined'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +// requires repo +export const addGitFeedbackLink = (configApi: any): Transformer => { + return dom => { + // attempting to use selectors that are more likely to be static as MkDocs updates over time + const sourceAnchor = dom.querySelector( + '[title="Edit this page"]', + ) as HTMLAnchorElement; + + // don't show if edit link not available in raw page + if (!sourceAnchor || !sourceAnchor.href) { + return dom; + } + let gitHost = ''; + + const sourceURL = new URL(sourceAnchor.href); + const githubHosts = configApi + .getConfigArray('integrations.github') + .map((integration: any) => integration.data.host); + const gitlabHosts = configApi + .getConfigArray('integrations.gitlab') + .map((integration: any) => integration.data.host); + + // don't show if can't identify edit link hostname as a gitlab/github hosting + if ( + githubHosts.includes(sourceURL.hostname) || + sourceURL.origin.includes('github') + ) { + gitHost = 'github'; + } else if ( + gitlabHosts.includes(sourceURL.hostname) || + sourceURL.origin.includes('gitlab') + ) { + gitHost = 'gitlab'; + } else { + return dom; + } + + // topmost h1 only contains title for whole page + const title = (dom.querySelector('article>h1') as HTMLElement).childNodes[0] + .textContent; + const issueTitle = encodeURIComponent(`Documentation Feedback: ${title}`); + const issueDesc = encodeURIComponent( + `Page source:\n${sourceAnchor.href}\n\nFeedback:`, + ); + const repoPath = sourceURL.pathname.split('/').slice(0, 3).join('/'); + + const feedbackLink = sourceAnchor.cloneNode() as HTMLAnchorElement; + switch (gitHost) { + case 'gitlab': + feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?issue[title]=${issueTitle}&issue[description]=${issueDesc}`; + break; + case 'github': + feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?title=${issueTitle}&body=${issueDesc}`; + break; + default: + return dom; + } + ReactDOM.render(React.createElement(FeedbackOutlinedIcon), feedbackLink); + feedbackLink.style.paddingLeft = '5px'; + feedbackLink.title = 'Leave feedback for this page'; + feedbackLink.id = 'git-feedback-link'; + sourceAnchor?.insertAdjacentElement('beforebegin', feedbackLink); + return dom; + }; +}; diff --git a/plugins/techdocs/src/reader/transformers/index.ts b/plugins/techdocs/src/reader/transformers/index.ts index 4da4cb3add..a005ad470b 100644 --- a/plugins/techdocs/src/reader/transformers/index.ts +++ b/plugins/techdocs/src/reader/transformers/index.ts @@ -15,6 +15,7 @@ */ export * from './addBaseUrl'; +export * from './addGitFeedbackLink'; export * from './rewriteDocLinks'; export * from './addLinkClickListener'; export * from './removeMkdocsHeader'; From 2b440c06055e37a05bfc019bcd28caf108da9fc6 Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" Date: Tue, 20 Apr 2021 13:32:34 +0800 Subject: [PATCH 094/462] add git feedback link: update FAQ and unit testing Signed-off-by: Chongyang Adrian, Ke --- .changeset/techdocs-eight-camels-hear.md | 3 +- docs/features/techdocs/FAQ.md | 12 ++++++ .../transformers/addGitFeedbackLink.test.ts | 37 ++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.changeset/techdocs-eight-camels-hear.md b/.changeset/techdocs-eight-camels-hear.md index 0d6c16f725..5c3df10c89 100644 --- a/.changeset/techdocs-eight-camels-hear.md +++ b/.changeset/techdocs-eight-camels-hear.md @@ -4,5 +4,4 @@ Add feedback link icon in Techdocs Reader that directs to Gitlab or Github repo issue page with prefilled title and source link. For link to appear, requires repo_url and edit_uri to be filled in mkdocs.yml, as per https://www.mkdocs.org/user-guide/configuration. edit_uri will need to be specified for self-hosted Gitlab/Github with different hostnames. -Gitlab or Github detection checks for 'gitlab' or 'github' in hostname of source in repo_url; -additionally 'techdocs.feedback.gitlab' and '.github' in app config can be used to specify hostnames that should be recognised as the respective Git hosting for the feedback link. +To identify issue URL format as Github or Gitlab, the hostname of source in repo_url is checked if it contains 'gitlab' or 'github'. Alternately this is determined by matching to 'host' values from 'integrations' in app-config.yaml. diff --git a/docs/features/techdocs/FAQ.md b/docs/features/techdocs/FAQ.md index 5ce71ebfad..3b479f2a15 100644 --- a/docs/features/techdocs/FAQ.md +++ b/docs/features/techdocs/FAQ.md @@ -45,3 +45,15 @@ metadata annotation is used in the build process of TechDocs. But when annotation should still be present in entity descriptor file (e.g. `catalog-info.yaml`) for Backstage to know that TechDocs is enabled for the entity. + +#### Is it possible for users to suggest changes or provide feedback on a TechDocs page? + +This is supported for TechDocs sites whose source code is hosted in either +GitHub or GitLab. In order to add "edit this page" and "leave feedback" buttons +on a TechDocs page, be sure that you have `repo_url` and `edit_uri` values in +your `mkdocs.yml` files per +[MkDocs instructions](https://www.mkdocs.org/user-guide/configuration). + +If the hostname of your source code hosting URL does not include 'github' or +'gitlab', an `integrations` entry in your `app-config.yaml` pointed at your +source code provider is also needed (only the `host` key is necessary). diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts index cc451c3a25..4c9ea04fe9 100644 --- a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts @@ -18,8 +18,10 @@ import { createTestShadowDom } from '../../test-utils'; import { addGitFeedbackLink } from './addGitFeedbackLink'; const configApi = { - getOptionalString: function getOptionalString(key: string) { - return key === 'gitlab' ? 'gitlab.com' : 'github.com'; + getConfigArray: function getConfigArray(key: string) { + return key === 'integrations.github' + ? [{ data: { host: 'self-hosted-git-hub-provider.com' } }] + : []; }, }; @@ -80,7 +82,7 @@ describe('addGitFeedbackLink', () => { `, @@ -99,8 +101,8 @@ describe('addGitFeedbackLink', () => { `, @@ -112,4 +114,29 @@ describe('addGitFeedbackLink', () => { expect(shadowDom.querySelector('#git-feedback-link')).toBeFalsy(); }); + + it('adds a feedback link when a Gitlab or Github source edit link is not available but hostname matches an integrations host', () => { + const shadowDom = createTestShadowDom( + ` + + + + + `, + { + preTransformers: [addGitFeedbackLink(configApi)], + postTransformers: [], + }, + ); + + expect(shadowDom.querySelector('#git-feedback-link')).toBeTruthy(); + expect( + (shadowDom.querySelector('#git-feedback-link') as HTMLLinkElement)!.href, + ).toEqual( + 'https://self-hosted-git-hub-provider.com/reponame/username/issues/new?title=Documentation%20Feedback%3A%20HeaderText&body=Page%20source%3A%0Ahttps%3A%2F%2Fself-hosted-git-hub-provider.com%2Freponame%2Fusername%2Fdocs%2FTestDoc.md%0A%0AFeedback%3A', + ); + }); }); From 0604a3a9e71931f82b6377eb74030bfa8e1fc914 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Tue, 20 Apr 2021 08:16:30 +0200 Subject: [PATCH 095/462] Added Austalian Greeting Signed-off-by: Brett Wright --- .../CatalogPage/utils/locales/goodAfternoon.locales.json | 1 + .../CatalogPage/utils/locales/goodEvening.locales.json | 1 + .../CatalogPage/utils/locales/goodMorning.locales.json | 1 + 3 files changed, 3 insertions(+) diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json index 4d48666666..ad3c4e4634 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json @@ -11,6 +11,7 @@ "Armenian": "Բարի կէսօր:", "Assamese": "শুভ আবেলি", "Asturian": "Bones tardes", + "Australian": "G'day mate", "Azerbaijani": "Günortanız xeyir", "Bashkir": "хәйерле көн", "Basque": "Arratsalde on", diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json index 890899fcf3..ed68d0332e 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json @@ -10,6 +10,7 @@ "Asante": "Maadwó", "Asturian": "Bona nuechi", "Ateso": "Akwar najokan", + "Australian": "G'day mate", "Aymara": "Winas tartis", "Azerbaijani": "Axşamınız xeyir", "Basque": "Arratsalde on", diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json index febbc32c49..b906155426 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json @@ -4,6 +4,7 @@ "Albanian": "Mirëmëngjes", "Arabic": "صباح الخير", "Armenian": "Paree looys", + "Australian": "G'day mate", "Azerbaijani": "Sabahınız xeyir", "Bengali": "shuprobhat", "Bulgarian": "Dobro utro", From f8585183748910df996d0104629649e34cf5985a Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Tue, 20 Apr 2021 08:20:23 +0200 Subject: [PATCH 096/462] Added changeset Signed-off-by: Brett Wright --- .changeset/gorgeous-pumas-cover.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gorgeous-pumas-cover.md diff --git a/.changeset/gorgeous-pumas-cover.md b/.changeset/gorgeous-pumas-cover.md new file mode 100644 index 0000000000..c4c9facac4 --- /dev/null +++ b/.changeset/gorgeous-pumas-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-welcome': patch +--- + +Australian Greeting From 9b8f596aefb956a0109872f05bd187ea1a833a98 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Tue, 20 Apr 2021 08:29:27 +0200 Subject: [PATCH 097/462] Changed to patch as its a nonbreaking change Signed-off-by: Brett Wright --- .changeset/tiny-ears-love.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tiny-ears-love.md b/.changeset/tiny-ears-love.md index 52218e2ecc..9c3d1613a5 100644 --- a/.changeset/tiny-ears-love.md +++ b/.changeset/tiny-ears-love.md @@ -1,5 +1,5 @@ --- -'@backstage/cli': minor +'@backstage/cli': patch --- Added support for Datadog rum events From 40d1e11cf36f83ee62b5e5e285dd3e629dfabebc Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Mon, 19 Apr 2021 19:58:47 +0200 Subject: [PATCH 098/462] Add a FossaPage that shows the license compliance status of all components in the catalog Signed-off-by: Dominik Henneke --- .changeset/unlucky-starfishes-vanish.md | 21 + plugins/fossa/README.md | 48 +++ plugins/fossa/dev/index.tsx | 74 +++- plugins/fossa/docs/fossa-overview.png | Bin 0 -> 375035 bytes plugins/fossa/package.json | 4 + plugins/fossa/src/api/FossaApi.ts | 14 + plugins/fossa/src/api/FossaClient.test.ts | 378 ++++++++++++------ plugins/fossa/src/api/FossaClient.ts | 132 ++++-- .../components/FossaCard/FossaCard.test.tsx | 186 +++++++++ .../src/components/FossaCard/FossaCard.tsx | 208 +++++----- .../components/FossaPage/FossaPage.test.tsx | 134 +++++++ .../src/components/FossaPage/FossaPage.tsx | 228 +++++++++++ .../fossa/src/components/FossaPage/index.ts | 17 + .../src/components/useProjectName.test.ts | 38 ++ .../src/components/useProjectNames.test.ts | 45 +++ .../fossa/src/components/useProjectNames.ts | 33 ++ plugins/fossa/src/extensions.tsx | 13 +- plugins/fossa/src/index.ts | 2 +- plugins/fossa/src/plugin.ts | 4 + plugins/fossa/src/routes.ts | 21 + 20 files changed, 1350 insertions(+), 250 deletions(-) create mode 100644 .changeset/unlucky-starfishes-vanish.md create mode 100644 plugins/fossa/docs/fossa-overview.png create mode 100644 plugins/fossa/src/components/FossaCard/FossaCard.test.tsx create mode 100644 plugins/fossa/src/components/FossaPage/FossaPage.test.tsx create mode 100644 plugins/fossa/src/components/FossaPage/FossaPage.tsx create mode 100644 plugins/fossa/src/components/FossaPage/index.ts create mode 100644 plugins/fossa/src/components/useProjectName.test.ts create mode 100644 plugins/fossa/src/components/useProjectNames.test.ts create mode 100644 plugins/fossa/src/components/useProjectNames.ts create mode 100644 plugins/fossa/src/routes.ts diff --git a/.changeset/unlucky-starfishes-vanish.md b/.changeset/unlucky-starfishes-vanish.md new file mode 100644 index 0000000000..90ee10a81a --- /dev/null +++ b/.changeset/unlucky-starfishes-vanish.md @@ -0,0 +1,21 @@ +--- +'@backstage/plugin-fossa': patch +--- + +Add a `FossaPage` that shows the license compliance status of all components in the catalog. +This is an optional component that can be registered as a route: + +```diff +// packages/app/src/App.tsx + ++ import { FossaPage } from '@backstage/plugin-fossa'; + +// ... + + const routes = ( + + // ... ++ } /> + + ); +``` diff --git a/plugins/fossa/README.md b/plugins/fossa/README.md index 722d8d2cf3..049a1c25cb 100644 --- a/plugins/fossa/README.md +++ b/plugins/fossa/README.md @@ -75,3 +75,51 @@ spec: owner: CNCF lifecycle: experimental ``` + +## Other Components + +### FOSSA Overview Page + +The plugin provides an optional page that can be used to check the license compliance of all components. + +![FOSSA Overview](./docs/fossa-overview.png) + +Add it to your Backstage application: + +1. Install the FOSSA Plugin (see [Getting Started](#getting-started)). + +2. Register the page: + +```tsx +// packages/app/src/App.tsx + +import { FossaPage } from '@backstage/plugin-fossa'; + +// ... + +const routes = ( + + // ... + } /> + +); +``` + +3. (Optional) Add a Sidebar Icon: + +```tsx +// packages/app/src/components/Root/Root.tsx + +// ... + +export const Root = ({ children }: PropsWithChildren<{}>) => ( + + + // ... + + // ... + + {children} + +); +``` diff --git a/plugins/fossa/dev/index.tsx b/plugins/fossa/dev/index.tsx index 06c71c48b7..9625b24dc2 100644 --- a/plugins/fossa/dev/index.tsx +++ b/plugins/fossa/dev/index.tsx @@ -14,14 +14,19 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; import { Content, Header, Page } from '@backstage/core'; import { createDevApp } from '@backstage/dev-utils'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { + CatalogApi, + catalogApiRef, + EntityProvider, +} from '@backstage/plugin-catalog-react'; import { Grid } from '@material-ui/core'; import React from 'react'; -import { EntityFossaCard } from '../src'; -import { FossaApi, fossaApiRef } from '../src/api'; +import { EntityFossaCard, fossaPlugin } from '../src'; +import { FindingSummary, FossaApi, fossaApiRef } from '../src/api'; +import { FossaPage } from '../src/components/FossaPage'; import { FOSSA_PROJECT_NAME_ANNOTATION } from '../src/components/useProjectName'; const entity = (name?: string) => @@ -34,9 +39,16 @@ const entity = (name?: string) => }, name: name, }, + relations: [ + { + type: RELATION_OWNED_BY, + target: { kind: 'Group', namespace: 'default', name }, + }, + ], } as Entity); createDevApp() + .registerPlugin(fossaPlugin) .registerApi({ api: fossaApiRef, deps: {}, @@ -81,8 +93,58 @@ createDevApp() return undefined; } }, + getFindingSummaries: async () => { + await new Promise(r => setTimeout(r, 1000)); + + return new Map([ + [ + 'zero-deps', + { + timestamp: '2000-01-01T00:00:00Z', + projectUrl: '', + projectDefaultBranch: 'master', + issueCount: 0, + dependencyCount: 0, + }, + ], + [ + 'issues', + { + timestamp: '2001-01-01T00:00:00Z', + projectUrl: '', + projectDefaultBranch: 'develop', + issueCount: 10, + dependencyCount: 15, + }, + ], + [ + 'no-issues', + { + timestamp: '2002-01-01T00:00:00Z', + projectUrl: '', + projectDefaultBranch: 'master', + issueCount: 0, + dependencyCount: 5, + }, + ], + ]); + }, } as FossaApi), }) + .registerApi({ + api: catalogApiRef, + deps: {}, + factory: () => + (({ + getEntities: async () => { + await new Promise(r => setTimeout(r, 1000)); + + return { + items: [entity('zero-deps'), entity('issues'), entity('no-issues')], + }; + }, + } as Partial) as any), + }) .addPage({ title: 'Entity Content', element: ( @@ -130,4 +192,8 @@ createDevApp() ), }) + .addPage({ + title: 'Catalog Overview', + element: , + }) .render(); diff --git a/plugins/fossa/docs/fossa-overview.png b/plugins/fossa/docs/fossa-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..2c6dd972312d50bfc678dc5a2dcf5063e38965cc GIT binary patch literal 375035 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 +P|_a7WOK(M9bA9ykmd7 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

%XTkq>>*!J-9W`*k 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 literal 0 HcmV?d00001 diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index fd94c6b906..39da3638ec 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -33,12 +33,15 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/core": "^0.7.5", + "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.5", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", "cross-fetch": "^3.0.6", + "luxon": "^1.26.0", + "p-limit": "^3.0.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-use": "^15.3.3" @@ -49,6 +52,7 @@ "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", + "@testing-library/react-hooks": "^3.4.2", "@testing-library/user-event": "^12.0.7", "@types/jest": "^26.0.7", "@types/node": "^14.14.32", diff --git a/plugins/fossa/src/api/FossaApi.ts b/plugins/fossa/src/api/FossaApi.ts index 84406e1b1a..15e8b4473e 100644 --- a/plugins/fossa/src/api/FossaApi.ts +++ b/plugins/fossa/src/api/FossaApi.ts @@ -30,5 +30,19 @@ export const fossaApiRef = createApiRef({ }); export type FossaApi = { + /** + * Get the finding summary for a list of projects + * + * @param projectTitles a list of project titles in FOSSA + */ + getFindingSummaries( + projectTitles: Array, + ): Promise>; + + /** + * Get the finding summary of a single project. + * + * @param projectTitle the project title in FOSSA + */ getFindingSummary(projectTitle: string): Promise; }; diff --git a/plugins/fossa/src/api/FossaClient.test.ts b/plugins/fossa/src/api/FossaClient.test.ts index 820210e2b6..24bcad526c 100644 --- a/plugins/fossa/src/api/FossaClient.test.ts +++ b/plugins/fossa/src/api/FossaClient.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { UrlPatternDiscovery, IdentityApi } from '@backstage/core'; +import { IdentityApi, UrlPatternDiscovery } from '@backstage/core'; import { msw } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -52,138 +52,266 @@ describe('FossaClient', () => { }); }); - it('should report finding summary', async () => { - server.use( - rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'count=1&sort=title+&title=our-service&organizationId=8736', - ); - return res( - ctx.json([ + describe('getFindingSummary', () => { + it('should report finding summary', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { + const expectedQuery = + 'count=1000&page=0&sort=title%2B&organizationId=8736&title=our-service'; + if (req.url.searchParams.toString() !== expectedQuery) { + return res( + ctx.status(500), + ctx.body( + `${req.url.searchParams.toString()} !== ${expectedQuery}`, + ), + ); + } + + return res( + ctx.json([ + { + locator: 'custom+8736/our-service', + title: 'our-service', + default_branch: 'develop', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_licensing_issue_count: 5, + unresolved_issue_count: 100, + }, + ], + }, + ]), + ); + }), + ); + + const summary = await client.getFindingSummary('our-service'); + + expect(summary).toEqual({ + timestamp: '2020-01-01T00:00:00Z', + issueCount: 5, + dependencyCount: 160, + projectDefaultBranch: 'develop', + projectUrl: + 'https://app.fossa.com/projects/custom%2B8736%2Four-service', + } as FindingSummary); + }); + + it('should report finding summary without licensing_issue_count', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { + return res( + ctx.json([ + { + locator: 'custom+8736/our-service', + title: 'our-service', + default_branch: 'refs/master', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_issue_count: 100, + }, + ], + }, + ]), + ); + }), + ); + + const summary = await client.getFindingSummary('our-service'); + + expect(summary).toEqual({ + timestamp: '2020-01-01T00:00:00Z', + issueCount: 100, + dependencyCount: 160, + projectDefaultBranch: 'refs/master', + projectUrl: + 'https://app.fossa.com/projects/custom%2B8736%2Four-service', + } as FindingSummary); + }); + + it('should handle empty result', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { + return res(ctx.json([])); + }), + ); + + const summary = await client.getFindingSummary('our-service'); + + expect(summary).toBeUndefined(); + }); + + it('should ignore result with invalid title', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { + return res(ctx.json([{ title: 'our-service-2' }])); + }), + ); + + const summary = await client.getFindingSummary('our-service'); + + expect(summary).toBeUndefined(); + }); + + it('should skip organizationId', async () => { + client = new FossaClient({ discoveryApi, identityApi }); + + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { + const expectedQuery = + 'count=1000&page=0&sort=title%2B&title=our-service'; + if (req.url.searchParams.toString() !== expectedQuery) { + return res( + ctx.status(500), + ctx.body( + `${req.url.searchParams.toString()} !== ${expectedQuery}`, + ), + ); + } + + return res(ctx.json([])); + }), + ); + + const summary = await client.getFindingSummary('our-service'); + + expect(summary).toBeUndefined(); + }); + + it('should handle 404 status', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { + return res(ctx.status(404)); + }), + ); + + await expect(client.getFindingSummary('our-service')).rejects.toThrow(); + }); + }); + + describe('getFindingSummaries', () => { + it('should report finding summary', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { + const expectedQuery = + 'count=1000&page=0&sort=title%2B&organizationId=8736'; + if (req.url.searchParams.toString() !== expectedQuery) { + return res( + ctx.status(500), + ctx.body( + `${req.url.searchParams.toString()} !== ${expectedQuery}`, + ), + ); + } + + return res( + ctx.json([ + { + locator: 'custom+8736/our-service', + title: 'our-service', + default_branch: 'develop', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_licensing_issue_count: 5, + unresolved_issue_count: 100, + }, + ], + }, + { + locator: 'custom+8736/our-service-2', + title: 'our-service-2', + default_branch: 'develop', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_licensing_issue_count: 5, + unresolved_issue_count: 100, + }, + ], + }, + { + locator: 'custom+8736/our-service-3', + title: 'our-service-3', + default_branch: 'develop', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_licensing_issue_count: 5, + unresolved_issue_count: 100, + }, + ], + }, + ]), + ); + }), + ); + + const summary = await client.getFindingSummaries([ + 'our-service', + 'our-service-2', + ]); + + expect(summary).toEqual( + new Map([ + [ + 'our-service', { - locator: 'custom+8736/our-service', - title: 'our-service', - default_branch: 'develop', - revisions: [ - { - updatedAt: '2020-01-01T00:00:00Z', - dependency_count: 160, - unresolved_licensing_issue_count: 5, - unresolved_issue_count: 100, - }, - ], + timestamp: '2020-01-01T00:00:00Z', + issueCount: 5, + dependencyCount: 160, + projectDefaultBranch: 'develop', + projectUrl: + 'https://app.fossa.com/projects/custom%2B8736%2Four-service', }, - ]), - ); - }), - ); - - const summary = await client.getFindingSummary('our-service'); - - expect(summary).toEqual({ - timestamp: '2020-01-01T00:00:00Z', - issueCount: 5, - dependencyCount: 160, - projectDefaultBranch: 'develop', - projectUrl: 'https://app.fossa.com/projects/custom%2B8736%2Four-service', - } as FindingSummary); - }); - - it('should report finding summary without licensing_issue_count', async () => { - server.use( - rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'count=1&sort=title+&title=our-service&organizationId=8736', - ); - return res( - ctx.json([ + ], + [ + 'our-service-2', { - locator: 'custom+8736/our-service', - title: 'our-service', - default_branch: 'refs/master', - revisions: [ - { - updatedAt: '2020-01-01T00:00:00Z', - dependency_count: 160, - unresolved_issue_count: 100, - }, - ], + timestamp: '2020-01-01T00:00:00Z', + issueCount: 5, + dependencyCount: 160, + projectDefaultBranch: 'develop', + projectUrl: + 'https://app.fossa.com/projects/custom%2B8736%2Four-service-2', }, - ]), - ); - }), - ); + ], + ]), + ); + }); - const summary = await client.getFindingSummary('our-service'); + it('should handle empty result', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { + return res(ctx.json([])); + }), + ); - expect(summary).toEqual({ - timestamp: '2020-01-01T00:00:00Z', - issueCount: 100, - dependencyCount: 160, - projectDefaultBranch: 'refs/master', - projectUrl: 'https://app.fossa.com/projects/custom%2B8736%2Four-service', - } as FindingSummary); - }); + const summary = await client.getFindingSummaries([ + 'our-service', + 'our-service-2', + ]); - it('should handle empty result', async () => { - server.use( - rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'count=1&sort=title+&title=our-service&organizationId=8736', - ); - return res(ctx.json([])); - }), - ); + expect(summary).toEqual(new Map()); + }); - const summary = await client.getFindingSummary('our-service'); + it('should handle 404 status', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { + return res(ctx.status(404)); + }), + ); - expect(summary).toBeUndefined(); - }); - - it('should ignore result with invalid title', async () => { - server.use( - rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'count=1&sort=title+&title=our-service&organizationId=8736', - ); - return res(ctx.json([{ title: 'our-service-2' }])); - }), - ); - - const summary = await client.getFindingSummary('our-service'); - - expect(summary).toBeUndefined(); - }); - - it('should skip organizationId', async () => { - client = new FossaClient({ discoveryApi, identityApi }); - - server.use( - rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'count=1&sort=title+&title=our-service', - ); - return res(ctx.status(404)); - }), - ); - - const summary = await client.getFindingSummary('our-service'); - - expect(summary).toBeUndefined(); - }); - - it('should handle 404 status', async () => { - server.use( - rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'count=1&sort=title+&title=our-service&organizationId=8736', - ); - return res(ctx.status(404)); - }), - ); - - const summary = await client.getFindingSummary('our-service'); - - expect(summary).toBeUndefined(); + await expect( + client.getFindingSummaries(['our-service', 'our-service-2']), + ).rejects.toThrow(); + }); }); }); diff --git a/plugins/fossa/src/api/FossaClient.ts b/plugins/fossa/src/api/FossaClient.ts index 5693895901..fb5eb80345 100644 --- a/plugins/fossa/src/api/FossaClient.ts +++ b/plugins/fossa/src/api/FossaClient.ts @@ -15,13 +15,28 @@ */ import { DiscoveryApi, IdentityApi } from '@backstage/core'; +import { ResponseError } from '@backstage/errors'; import fetch from 'cross-fetch'; +import pLimit from 'p-limit'; import { FindingSummary, FossaApi } from './FossaApi'; +type FossaProjectsResponse = { + title: string; + default_branch: string; + locator: string; + revisions: Array<{ + updatedAt: string; + unresolved_licensing_issue_count: number; + unresolved_issue_count: number; + dependency_count: number; + }>; +}; + export class FossaClient implements FossaApi { discoveryApi: DiscoveryApi; identityApi: IdentityApi; organizationId?: string; + private readonly limit = pLimit(5); constructor({ discoveryApi, @@ -37,42 +52,101 @@ export class FossaClient implements FossaApi { this.organizationId = organizationId; } - private async callApi(path: string): Promise { + private async callApi( + path: string, + query: Record, + ): Promise { const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/fossa`; const idToken = await this.identityApi.getIdToken(); - const response = await fetch(`${apiUrl}/${path}`, { - headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, - }); - if (response.status === 200) { - return await response.json(); + const response = await fetch( + `${apiUrl}/${path}?${new URLSearchParams(query).toString()}`, + { + headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, + }, + ); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); } - return undefined; + + return (await response.json()) as T; + } + + async *getProject( + projectTitles: Set, + ): AsyncIterable<{ title: string; summary: FindingSummary }> { + let nextPage = 0; + const pageSize = 1000; + + for (;;) { + const projects = await this.limit( + page => + this.callApi('projects', { + count: pageSize, + page, + sort: 'title+', + ...(this.organizationId && { + organizationId: this.organizationId, + }), + ...(projectTitles.size === 1 && { + title: projectTitles.values().next().value, + }), + }), + nextPage++, + ); + + if (!projects) { + break; + } + + for (const project of projects) { + if (projectTitles.has(project.title) && project.revisions.length > 0) { + const revision = project.revisions[0]; + yield { + title: project.title, + summary: { + timestamp: revision.updatedAt, + issueCount: + revision.unresolved_licensing_issue_count || + revision.unresolved_issue_count, + dependencyCount: revision.dependency_count, + projectDefaultBranch: project.default_branch, + projectUrl: `https://app.fossa.com/projects/${encodeURIComponent( + project.locator, + )}`, + }, + }; + } + } + + if (projects.length < pageSize) { + break; + } + } + } + + async getFindingSummaries( + projectTitles: string[], + ): Promise> { + const map = new Map(); + + if (projectTitles.length === 0) { + return map; + } + + for await (const { title, summary } of this.getProject( + new Set(projectTitles), + )) { + map.set(title, summary); + } + + return map; } async getFindingSummary( projectTitle: string, ): Promise { - const project = await this.callApi( - `projects?count=1&sort=title+&title=${projectTitle}${ - this.organizationId ? `&organizationId=${this.organizationId}` : '' - }`, - ); - - if (!project || project.length === 0 || project[0].title !== projectTitle) { - return undefined; - } - - const revision = project[0].revisions[0]; - return { - timestamp: revision.updatedAt, - issueCount: - revision.unresolved_licensing_issue_count || - revision.unresolved_issue_count, - dependencyCount: revision.dependency_count, - projectDefaultBranch: project[0].default_branch, - projectUrl: `https://app.fossa.com/projects/${encodeURIComponent( - project[0].locator, - )}`, - }; + const summaries = await this.getFindingSummaries([projectTitle]); + return summaries.get(projectTitle); } } diff --git a/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx b/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx new file mode 100644 index 0000000000..0761c85da5 --- /dev/null +++ b/plugins/fossa/src/components/FossaCard/FossaCard.test.tsx @@ -0,0 +1,186 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { FossaApi, fossaApiRef } from '../../api'; +import { FossaCard } from './FossaCard'; + +describe('', () => { + const fossaApi: jest.Mocked = { + getFindingSummary: jest.fn(), + getFindingSummaries: jest.fn(), + }; + let Wrapper: React.ComponentType; + + beforeEach(() => { + const apis = ApiRegistry.with(fossaApiRef, fossaApi); + + Wrapper = ({ children }: { children?: React.ReactNode }) => ( + {children} + ); + }); + + afterEach(() => jest.resetAllMocks()); + + it('shows missing annotation', async () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name', + }, + }; + + const { getByText } = await renderInTestApp( + + + + + , + ); + + expect(getByText(/Missing Annotation/i)).toBeInTheDocument(); + expect(getByText('fossa.io/project-name')).toBeInTheDocument(); + }); + + it('shows error', async () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name', + annotations: { + 'fossa.io/project-name': 'my-name', + }, + }, + }; + + fossaApi.getFindingSummary.mockRejectedValue(new Error('My Error')); + + const { getByText } = await renderInTestApp( + + + + + , + ); + + expect(getByText(/Warning: My Error/i)).toBeInTheDocument(); + }); + + it('shows empty', async () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name', + annotations: { + 'fossa.io/project-name': 'my-name', + }, + }, + }; + + fossaApi.getFindingSummary.mockResolvedValue(undefined); + + const { getByText } = await renderInTestApp( + + + + + , + ); + + expect( + getByText(/There is no Fossa project with title 'my-name'./i), + ).toBeInTheDocument(); + }); + + it('shows fossa issues', async () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name', + annotations: { + 'fossa.io/project-name': 'my-name', + }, + }, + }; + + fossaApi.getFindingSummary.mockResolvedValue({ + timestamp: '2000-01-01T00:00:00Z', + projectDefaultBranch: 'branch/default-branch', + projectUrl: 'http://…', + issueCount: 0, + dependencyCount: 10, + }); + + const { getByText } = await renderInTestApp( + + + + + , + ); + + expect(getByText(/Number of issues/i)).toBeInTheDocument(); + expect( + getByText( + (_, node) => + node?.textContent === + 'Based on 10 Dependencies on branch branch/default-branch.', + ), + ).toBeInTheDocument(); + }); + + it('warns about zero dependencies', async () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name', + annotations: { + 'fossa.io/project-name': 'my-name', + }, + }, + }; + + fossaApi.getFindingSummary.mockResolvedValue({ + timestamp: '2000-01-01T00:00:00Z', + projectDefaultBranch: 'branch/default-branch', + projectUrl: 'http://…', + issueCount: 0, + dependencyCount: 0, + }); + + const { getByText } = await renderInTestApp( + + + + + , + ); + + expect(getByText(/No Dependencies/i)).toBeInTheDocument(); + expect( + getByText(/Please check your FOSSA project settings/i), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/fossa/src/components/FossaCard/FossaCard.tsx b/plugins/fossa/src/components/FossaCard/FossaCard.tsx index 4cc27f5d03..9d2db263c8 100644 --- a/plugins/fossa/src/components/FossaCard/FossaCard.tsx +++ b/plugins/fossa/src/components/FossaCard/FossaCard.tsx @@ -17,14 +17,17 @@ import { EmptyState, InfoCard, + InfoCardVariants, MissingAnnotationEmptyState, Progress, + ResponseErrorPanel, useApi, } from '@backstage/core'; import { useEntity } from '@backstage/plugin-catalog-react'; import { Grid, Tooltip } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import React from 'react'; +import { DateTime } from 'luxon'; +import React, { PropsWithChildren } from 'react'; import { useAsync } from 'react-use'; import { fossaApiRef } from '../../api'; import { @@ -65,109 +68,134 @@ const useStyles = makeStyles(theme => ({ }, })); -export const FossaCard = () => { +const Card = ({ + children, + disabled, + projectUrl, + variant = 'gridItem', +}: PropsWithChildren<{ + disabled?: boolean; + projectUrl?: string; + variant?: InfoCardVariants; +}>) => { + const classes = useStyles(); + + return ( + + {children} + + ); +}; +export const FossaCard = ({ variant }: { variant?: InfoCardVariants }) => { const { entity } = useEntity(); const fossaApi = useApi(fossaApiRef); const projectTitle = useProjectName(entity); - - const { value, loading } = useAsync( + const { value, loading, error } = useAsync( async () => projectTitle ? fossaApi.getFindingSummary(projectTitle) : undefined, [fossaApi, projectTitle], ); - const deepLink = value - ? { - title: 'View more', - link: value.projectUrl, - } - : undefined; - const classes = useStyles(); + if (error) { + return ( + + + + ); + } + + if (loading) { + return ( + + + + ); + } + + if (!projectTitle) { + return ( + + + + ); + } + + if (!value) { + return ( + + + + ); + } + return ( - <> - + - {loading && } - - {!loading && !projectTitle && ( - - )} - - {!loading && projectTitle && !value && ( - - )} - - {value && ( - +

0 || value.dependencyCount === 0 + ? classes.numberError + : classes.numberSuccess + } > - -

0 || value.dependencyCount === 0 - ? classes.numberError - : classes.numberSuccess - } - > - {value.issueCount} -

- {value.dependencyCount > 0 && ( -

Number of issues

- )} - {value.dependencyCount === 0 && ( -

- No Dependencies. -
- Please check your FOSSA project settings. -

- )} - + {value.issueCount} +

+ {value.dependencyCount > 0 && ( +

Number of issues

+ )} + {value.dependencyCount === 0 && ( +

+ No Dependencies. +
+ Please check your FOSSA project settings. +

+ )} + - - Last analyzed on{' '} - {new Date(value.timestamp).toLocaleString('en-US', { - timeZone: 'UTC', - day: 'numeric', - month: 'short', - year: 'numeric', - hour: '2-digit', - minute: '2-digit', - hour12: false, - })} - - - Based on {value.dependencyCount} Dependencies on branch{' '} - - - {value.projectDefaultBranch} - - - . - - - )} - - + + Last analyzed on{' '} + {DateTime.fromISO(value.timestamp).toLocaleString( + DateTime.DATETIME_MED, + )} + + + Based on {value.dependencyCount} Dependencies on branch{' '} + + {value.projectDefaultBranch} + + . + + + ); }; diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx new file mode 100644 index 0000000000..efab6ab091 --- /dev/null +++ b/plugins/fossa/src/components/FossaPage/FossaPage.test.tsx @@ -0,0 +1,134 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { FossaApi, fossaApiRef } from '../../api'; +import { FossaPage } from './FossaPage'; + +describe('', () => { + const catalogApi: jest.Mocked = { + addLocation: jest.fn(), + getEntities: jest.fn(), + getEntityByName: jest.fn(), + getLocationByEntity: jest.fn(), + getLocationById: jest.fn(), + getOriginLocationByEntity: jest.fn(), + removeEntityByUid: jest.fn(), + removeLocationById: jest.fn(), + }; + const fossaApi: jest.Mocked = { + getFindingSummary: jest.fn(), + getFindingSummaries: jest.fn(), + }; + let Wrapper: React.ComponentType; + + beforeEach(() => { + const apis = ApiRegistry.with(fossaApiRef, fossaApi).with( + catalogApiRef, + catalogApi, + ); + + Wrapper = ({ children }: { children?: React.ReactNode }) => ( + {children} + ); + }); + + afterEach(() => jest.resetAllMocks()); + + it('shows fossa issues', async () => { + const entity0: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name-0', + annotations: { + 'fossa.io/project-name': 'my-name-0', + }, + }, + }; + const entity1: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name-1', + annotations: { + 'fossa.io/project-name': 'my-name-1', + }, + }, + }; + const entity2: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name-2', + annotations: { + 'fossa.io/project-name': 'my-name-2', + }, + }, + }; + const entity3: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'my-name-3', + }, + }; + + catalogApi.getEntities.mockResolvedValue({ + items: [entity0, entity1, entity2, entity3], + }); + + fossaApi.getFindingSummaries.mockResolvedValue( + new Map([ + [ + 'my-name-1', + { + timestamp: '2000-01-01T00:00:00Z', + projectDefaultBranch: 'branch/default-branch', + projectUrl: 'http://…', + issueCount: 0, + dependencyCount: 0, + }, + ], + [ + 'my-name-2', + { + timestamp: '2000-01-01T00:00:00Z', + projectDefaultBranch: 'branch/default-branch', + projectUrl: 'http://…', + issueCount: 10, + dependencyCount: 10, + }, + ], + ]), + ); + + const { getByText, getAllByText } = await renderInTestApp( + + + , + ); + + expect(getAllByText(/Not configured/i)).toHaveLength(2); + expect(getByText(/No dependencies/i)).toBeInTheDocument(); + expect(getByText(/0 Issues/i)).toBeInTheDocument(); + expect(getByText(/10 Issues/i)).toBeInTheDocument(); + }); +}); diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.tsx new file mode 100644 index 0000000000..05e1379378 --- /dev/null +++ b/plugins/fossa/src/components/FossaPage/FossaPage.tsx @@ -0,0 +1,228 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + EntityName, + RELATION_OWNED_BY, +} from '@backstage/catalog-model'; +import { + Content, + Header, + Page, + StatusError, + StatusOK, + StatusWarning, + Table, + TableColumn, + TableFilter, + useApi, +} from '@backstage/core'; +import { + catalogApiRef, + EntityRefLink, + EntityRefLinks, + formatEntityRefTitle, + getEntityRelations, +} from '@backstage/plugin-catalog-react'; +import { Tooltip } from '@material-ui/core'; +import { Skeleton } from '@material-ui/lab'; +import { DateTime } from 'luxon'; +import * as React from 'react'; +import { useMemo } from 'react'; +import { useAsync } from 'react-use'; +import { FindingSummary, fossaApiRef } from '../../api'; +import { useProjectNames } from '../useProjectNames'; + +type FossaRow = { + entity: Entity; + resolved: { + name: string; + ownedByRelationsTitle?: string; + ownedByRelations: EntityName[]; + loading: boolean; + details?: FindingSummary; + }; +}; + +const columns: TableColumn[] = [ + { + title: 'Name', + field: 'resolved.name', + highlight: true, + render: ({ entity }) => , + }, + { + title: 'Owner', + field: 'resolved.ownedByRelationsTitle', + highlight: true, + render: ({ resolved }) => ( + + ), + }, + { + title: 'Status', + field: 'resolved.details.issueCount', + // We interpret missing values as '0.5' to be sorted at the end of the projects with issues. + customSort: (a, b) => + (b?.resolved?.details?.issueCount ?? 0.5) - + (a?.resolved?.details?.issueCount ?? 0.5), + render: ({ resolved }) => { + if (resolved.loading) { + return ; + } else if (!resolved.details) { + return Not configured; + } else if (resolved.details.dependencyCount === 0) { + return No dependencies; + } else if (resolved.details.issueCount > 0) { + return {resolved.details.issueCount} Issues; + } + + return {resolved.details.issueCount} Issues; + }, + }, + { + title: 'Dependencies', + field: 'resolved.details.dependencyCount', + render: ({ resolved: { loading, details } }) => { + if (loading) { + return ; + } + + return details?.dependencyCount; + }, + }, + { + title: 'Branch', + field: 'resolved.details.projectDefaultBranch', + render: ({ resolved: { loading, details } }) => { + if (loading) { + return ; + } + + return details?.projectDefaultBranch; + }, + }, + { + title: 'Last Updated', + field: 'resolved.details.timestamp', + render: ({ resolved: { loading, details } }) => { + if (loading) { + return ; + } + + return ( + details?.timestamp && ( + + + {DateTime.fromISO(details.timestamp).toRelative({ + locale: 'en', + })} + + + ) + ); + }, + }, +]; + +const filters: TableFilter[] = [ + { column: 'Owner', type: 'multiple-select' }, + { column: 'Branch', type: 'select' }, +]; + +export const FossaPage = () => { + const catalogApi = useApi(catalogApiRef); + const fossaApi = useApi(fossaApiRef); + + // Get a list of all relevant entities + const { value: entities, loading: entitiesLoading } = useAsync(() => { + return catalogApi.getEntities({ + filter: { kind: 'Component' }, + fields: [ + 'kind', + 'metadata.namespace', + 'metadata.name', + 'metadata.annotations', + 'relations', + ], + }); + }); + + // get the project names of all entities. the idx of both lists match. + const projectNames = useProjectNames(entities?.items); + + // get the summary list + const { value: summaries, loading: summariesLoading } = useAsync( + async () => + await fossaApi.getFindingSummaries( + projectNames.filter(n => n !== undefined) as string[], + ), + [projectNames], + ); + + // compose the rows + const rows: FossaRow[] = useMemo( + () => + entities?.items?.map((entity, idx) => { + const projectName = projectNames[idx]; + const summary = projectName ? summaries?.get(projectName) : undefined; + const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY); + + return { + entity, + resolved: { + name: formatEntityRefTitle(entity), + ownedByRelations, + ownedByRelationsTitle: ownedByRelations + .map(r => formatEntityRefTitle(r, { defaultKind: 'group' })) + .join(', '), + loading: summariesLoading, + details: summary, + }, + }; + }) ?? [], + [projectNames, entities?.items, summaries, summariesLoading], + ); + + return ( + +
+ + + columns={columns} + data={rows} + filters={filters} + isLoading={entitiesLoading} + options={{ + pageSize: 20, + actionsColumnIndex: -1, + loadingType: 'linear', + padding: 'dense', + showEmptyDataSourceMessage: !entitiesLoading, + }} + /> + + + ); +}; diff --git a/plugins/fossa/src/components/FossaPage/index.ts b/plugins/fossa/src/components/FossaPage/index.ts new file mode 100644 index 0000000000..7d6481949e --- /dev/null +++ b/plugins/fossa/src/components/FossaPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { FossaPage } from './FossaPage'; diff --git a/plugins/fossa/src/components/useProjectName.test.ts b/plugins/fossa/src/components/useProjectName.test.ts new file mode 100644 index 0000000000..e85b1f427c --- /dev/null +++ b/plugins/fossa/src/components/useProjectName.test.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { renderHook } from '@testing-library/react-hooks'; +import { useProjectName } from './useProjectName'; + +describe('useProjectName', () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'test', + annotations: { + 'fossa.io/project-name': 'test', + }, + }, + }; + + it('should extract the fossa project name', async () => { + const { result } = renderHook(() => useProjectName(entity)); + + expect(result.current).toBe('test'); + }); +}); diff --git a/plugins/fossa/src/components/useProjectNames.test.ts b/plugins/fossa/src/components/useProjectNames.test.ts new file mode 100644 index 0000000000..ae17fa93d8 --- /dev/null +++ b/plugins/fossa/src/components/useProjectNames.test.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { renderHook } from '@testing-library/react-hooks'; +import { useProjectNames } from './useProjectNames'; + +describe('useProjectNames', () => { + const entity0: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'test', + annotations: { + 'fossa.io/project-name': 'test', + }, + }, + }; + const entity1: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'test', + }, + }; + + it('should extract the fossa project name', async () => { + const { result } = renderHook(() => useProjectNames([entity0, entity1])); + + expect(result.current).toEqual(['test', undefined]); + }); +}); diff --git a/plugins/fossa/src/components/useProjectNames.ts b/plugins/fossa/src/components/useProjectNames.ts new file mode 100644 index 0000000000..c0e11a1e87 --- /dev/null +++ b/plugins/fossa/src/components/useProjectNames.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { useMemo } from 'react'; +import { FOSSA_PROJECT_NAME_ANNOTATION } from './useProjectName'; + +export const useProjectNames = ( + entities: Entity[] | undefined, +): Array => { + return useMemo( + () => + entities?.map( + entity => + entity.metadata.annotations?.[FOSSA_PROJECT_NAME_ANNOTATION] ?? + undefined, + ) ?? [], + [entities], + ); +}; diff --git a/plugins/fossa/src/extensions.tsx b/plugins/fossa/src/extensions.tsx index 38573c2d1f..21e53996ba 100644 --- a/plugins/fossa/src/extensions.tsx +++ b/plugins/fossa/src/extensions.tsx @@ -14,8 +14,12 @@ * limitations under the License. */ -import { createComponentExtension } from '@backstage/core'; +import { + createComponentExtension, + createRoutableExtension, +} from '@backstage/core'; import { fossaPlugin } from './plugin'; +import { rootRoute } from './routes'; export const EntityFossaCard = fossaPlugin.provide( createComponentExtension({ @@ -24,3 +28,10 @@ export const EntityFossaCard = fossaPlugin.provide( }, }), ); + +export const FossaPage = fossaPlugin.provide( + createRoutableExtension({ + component: () => import('./components/FossaPage').then(m => m.FossaPage), + mountPoint: rootRoute, + }), +); diff --git a/plugins/fossa/src/index.ts b/plugins/fossa/src/index.ts index f1b645c29b..929983bb6a 100644 --- a/plugins/fossa/src/index.ts +++ b/plugins/fossa/src/index.ts @@ -15,4 +15,4 @@ */ export { fossaPlugin } from './plugin'; -export { EntityFossaCard } from './extensions'; +export { EntityFossaCard, FossaPage } from './extensions'; diff --git a/plugins/fossa/src/plugin.ts b/plugins/fossa/src/plugin.ts index 638be4a0bf..849769d42c 100644 --- a/plugins/fossa/src/plugin.ts +++ b/plugins/fossa/src/plugin.ts @@ -22,6 +22,7 @@ import { identityApiRef, } from '@backstage/core'; import { fossaApiRef, FossaClient } from './api'; +import { rootRoute } from './routes'; export const fossaPlugin = createPlugin({ id: 'fossa', @@ -41,4 +42,7 @@ export const fossaPlugin = createPlugin({ }), }), ], + routes: { + fossaOverview: rootRoute, + }, }); diff --git a/plugins/fossa/src/routes.ts b/plugins/fossa/src/routes.ts new file mode 100644 index 0000000000..6e8ce07b29 --- /dev/null +++ b/plugins/fossa/src/routes.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createRouteRef } from '@backstage/core'; + +export const rootRoute = createRouteRef({ + id: 'fossa-overview', +}); From e7532b96ed30ea25cce34402b857c7ab87587140 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 20 Apr 2021 10:11:57 +0200 Subject: [PATCH 099/462] Fix typos Signed-off-by: Johan Haals --- plugins/catalog-backend/src/next/LocationStoreImpl.ts | 2 +- .../catalog-backend/src/next/ProcessingStateManagerImpl.ts | 2 +- .../src/next/database/ProcessingDatabaseImpl.ts | 6 +++--- plugins/catalog-backend/src/next/database/types.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/catalog-backend/src/next/LocationStoreImpl.ts b/plugins/catalog-backend/src/next/LocationStoreImpl.ts index 1b9e9bd92c..f970234f09 100644 --- a/plugins/catalog-backend/src/next/LocationStoreImpl.ts +++ b/plugins/catalog-backend/src/next/LocationStoreImpl.ts @@ -78,7 +78,7 @@ export class LocationStoreImpl implements LocationStore { return this.db.transaction(async tx => { const location = await this.db.location(id); if (!location) { - throw new ConflictError(`No location found with with id: ${id}`); + throw new ConflictError(`No location found with id: ${id}`); } await this.db.removeLocation(tx, id); this.notifyDeletion(location); diff --git a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts index 6cd846d791..522a7a327c 100644 --- a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts +++ b/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts @@ -33,7 +33,7 @@ export class ProcessingStateManagerImpl implements ProcessingStateManager { errors: JSON.stringify(result.errors), state: result.state, relations: result.relations, - deferedEntities: result.deferredEntities, + deferredEntities: result.deferredEntities, }); }); } diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts index 7c56fcd259..7e9bf78691 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts @@ -76,7 +76,7 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { state, errors, relations, - deferedEntities, + deferredEntities, } = options; const refreshResult = await tx('refresh_state') @@ -93,7 +93,7 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { // Schedule all deferred entities for future processing. await this.addUnprocessedEntities(tx, { - entities: deferedEntities, + entities: deferredEntities, id, type: 'entity', }); @@ -183,7 +183,7 @@ export class ProcessingDatabaseImpl implements ProcessingDatabase { .select() .where('next_update_at', '<=', tx.fn.now()) .limit(request.processBatchSize) - .orderBy('next_update_at', 'desc'); + .orderBy('next_update_at', 'asc'); await tx('refresh_state') .whereIn( diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index d89a3b23bf..22e9e90c8e 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -32,7 +32,7 @@ export type UpdateProcessedEntityOptions = { state?: Map; errors?: string; relations: EntityRelationSpec[]; - deferedEntities: Entity[]; + deferredEntities: Entity[]; }; export type RefreshStateItem = { From 6c4aaa849508e2a1fdf05862737bb3e3d5769e2f Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 20 Apr 2021 10:56:47 +0200 Subject: [PATCH 100/462] use Default instead of Impl Signed-off-by: Johan Haals --- ...l.ts => DefaultCatalogProcessingEngine.ts} | 2 +- ...> DefaultCatalogProcessingOrchestrator.ts} | 2 +- ...onStoreImpl.ts => DefaultLocationStore.ts} | 2 +- ...pl.ts => DefaultProcessingStateManager.ts} | 2 +- ...cationServiceImpl.ts => DefaultService.ts} | 2 +- .../src/next/NextCatalogBuilder.ts | 20 +++++++++---------- plugins/catalog-backend/src/next/Stitcher.ts | 2 +- ...seImpl.ts => DefaultProcessingDatabase.ts} | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) rename plugins/catalog-backend/src/next/{CatalogProcessingEngineImpl.ts => DefaultCatalogProcessingEngine.ts} (97%) rename plugins/catalog-backend/src/next/{CatalogProcessingOrchestratorImpl.ts => DefaultCatalogProcessingOrchestrator.ts} (99%) rename plugins/catalog-backend/src/next/{LocationStoreImpl.ts => DefaultLocationStore.ts} (98%) rename plugins/catalog-backend/src/next/{ProcessingStateManagerImpl.ts => DefaultProcessingStateManager.ts} (96%) rename plugins/catalog-backend/src/next/{LocationServiceImpl.ts => DefaultService.ts} (97%) rename plugins/catalog-backend/src/next/database/{ProcessingDatabaseImpl.ts => DefaultProcessingDatabase.ts} (99%) diff --git a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts similarity index 97% rename from plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts rename to plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 41ad2bef8e..934ab3a1cc 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingEngineImpl.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -27,7 +27,7 @@ import { Logger } from 'winston'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { Stitcher } from './Stitcher'; -export class CatalogProcessingEngineImpl implements CatalogProcessingEngine { +export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { private subscriptions: Subscription[] = []; private running: boolean = false; diff --git a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts similarity index 99% rename from plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts rename to plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts index a8e9b924d0..f97d86a75a 100644 --- a/plugins/catalog-backend/src/next/CatalogProcessingOrchestratorImpl.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts @@ -82,7 +82,7 @@ function toAbsoluteUrl( } } -export class CatalogProcessingOrchestratorImpl +export class DefaultCatalogProcessingOrchestrator implements CatalogProcessingOrchestrator { constructor( private readonly options: { diff --git a/plugins/catalog-backend/src/next/LocationStoreImpl.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts similarity index 98% rename from plugins/catalog-backend/src/next/LocationStoreImpl.ts rename to plugins/catalog-backend/src/next/DefaultLocationStore.ts index f970234f09..b21fe9da02 100644 --- a/plugins/catalog-backend/src/next/LocationStoreImpl.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -26,7 +26,7 @@ export type LocationMessage = | { all: Location[] } | { added: Location[]; removed: Location[] }; -export class LocationStoreImpl implements LocationStore { +export class DefaultLocationStore implements LocationStore { private subscribers = new Set< ZenObservable.SubscriptionObserver >(); diff --git a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts similarity index 96% rename from plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts rename to plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index 522a7a327c..91090bc139 100644 --- a/plugins/catalog-backend/src/next/ProcessingStateManagerImpl.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -22,7 +22,7 @@ import { ProcessingStateManager, } from './types'; -export class ProcessingStateManagerImpl implements ProcessingStateManager { +export class DefaultProcessingStateManager implements ProcessingStateManager { constructor(private readonly db: ProcessingDatabase) {} async setProcessingItemResult(result: ProcessingItemResult) { diff --git a/plugins/catalog-backend/src/next/LocationServiceImpl.ts b/plugins/catalog-backend/src/next/DefaultService.ts similarity index 97% rename from plugins/catalog-backend/src/next/LocationServiceImpl.ts rename to plugins/catalog-backend/src/next/DefaultService.ts index 4125f96ed1..3935f6e4d0 100644 --- a/plugins/catalog-backend/src/next/LocationServiceImpl.ts +++ b/plugins/catalog-backend/src/next/DefaultService.ts @@ -26,7 +26,7 @@ import { CatalogProcessingOrchestrator, } from './types'; -export class LocationServiceImpl implements LocationService { +export class DefaultLocationService implements LocationService { constructor( private readonly store: LocationStore, private readonly orchestrator: CatalogProcessingOrchestrator, diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index b196d63897..c3e0a6bd9c 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -64,12 +64,12 @@ import { } from '../ingestion/processors/PlaceholderProcessor'; import { defaultEntityDataParser } from '../ingestion/processors/util/parse'; import { LocationAnalyzer } from '../ingestion/types'; -import { CatalogProcessingEngineImpl } from '../next/CatalogProcessingEngineImpl'; -import { CatalogProcessingOrchestratorImpl } from '../next/CatalogProcessingOrchestratorImpl'; -import { ProcessingDatabaseImpl } from '../next/database/ProcessingDatabaseImpl'; +import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; +import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; +import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; import { DatabaseLocationProvider } from '../next/DatabaseLocationProvider'; -import { LocationStoreImpl } from '../next/LocationStoreImpl'; -import { ProcessingStateManagerImpl } from '../next/ProcessingStateManagerImpl'; +import { DefaultLocationStore } from './DefaultLocationStore'; +import { DefaultProcessingStateManager } from './DefaultProcessingStateManager'; import { CatalogProcessingEngine } from '../next/types'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; @@ -259,10 +259,10 @@ export class NextCatalogBuilder { }); const db = new CommonDatabase(dbClient, logger); - const processingDatabase = new ProcessingDatabaseImpl(dbClient, logger); - const stateManager = new ProcessingStateManagerImpl(processingDatabase); + const processingDatabase = new DefaultProcessingDatabase(dbClient, logger); + const stateManager = new DefaultProcessingStateManager(processingDatabase); const integrations = ScmIntegrations.fromConfig(config); - const orchestrator = new CatalogProcessingOrchestratorImpl({ + const orchestrator = new DefaultCatalogProcessingOrchestrator({ processors, integrations, logger, @@ -271,10 +271,10 @@ export class NextCatalogBuilder { }); const entitiesCatalog = new NextEntitiesCatalog(dbClient); - const locationStore = new LocationStoreImpl(db); + const locationStore = new DefaultLocationStore(db); const dbLocationProvider = new DatabaseLocationProvider(locationStore); const stitcher = new Stitcher(dbClient, logger); - const processingEngine = new CatalogProcessingEngineImpl( + const processingEngine = new DefaultCatalogProcessingEngine( logger, [dbLocationProvider], // entityproviders stateManager, diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index fe7a378338..3e5e3ac24b 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -22,7 +22,7 @@ import { DbRefreshStateReferences, DbRefreshStateRow, DbRelationsRow, -} from './database/ProcessingDatabaseImpl'; +} from './database/DefaultProcessingDatabase'; import { Entity, parseEntityRef } from '@backstage/catalog-model'; import { createHash } from 'crypto'; import stableStringify from 'fast-json-stable-stringify'; diff --git a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts similarity index 99% rename from plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts rename to plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index 7e9bf78691..cf2d4e121c 100644 --- a/plugins/catalog-backend/src/next/database/ProcessingDatabaseImpl.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -59,7 +59,7 @@ export type DbRefreshStateReferences = { // enough to get the speed benefits. const BATCH_SIZE = 50; -export class ProcessingDatabaseImpl implements ProcessingDatabase { +export class DefaultProcessingDatabase implements ProcessingDatabase { constructor( private readonly database: Knex, private readonly logger: Logger, From cf101c539c0fabbc22e0c6605402d929c520e352 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 20 Apr 2021 11:15:25 +0200 Subject: [PATCH 101/462] tsconfig: skip adding catalog v2 migrations Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 6139c4a7f0..d6cb6f4c96 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,7 @@ "packages/*/src", "plugins/*/src", "plugins/*/dev", - "plugins/*/migrations", - "plugins/catalog-backend/migrationsv2" + "plugins/*/migrations" ], "compilerOptions": { "outDir": "dist-types", From b2adf03b584f8d690a0e1b0db5b558943d1c6cda Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 20 Apr 2021 11:15:47 +0200 Subject: [PATCH 102/462] catalog-backend: review feedback, reduce scope of `handled` Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .../src/next/DefaultCatalogProcessingOrchestrator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts index f97d86a75a..1880b5d17e 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts @@ -210,7 +210,7 @@ export class DefaultCatalogProcessingOrchestrator for (const processor of this.options.processors) { if (processor.readLocation) { try { - handled = await processor.readLocation( + const read = await processor.readLocation( { type, target, @@ -220,7 +220,7 @@ export class DefaultCatalogProcessingOrchestrator emitter.emit, this.options.parser, ); - if (handled) { + if (read) { break; } } catch (e) { From bd6b2eefb5798d04c281c9f89922e33d326ffb0b Mon Sep 17 00:00:00 2001 From: David Tuite Date: Tue, 20 Apr 2021 11:10:33 +0100 Subject: [PATCH 103/462] Add Datadog plugin to marketplace Signed-off-by: David Tuite --- microsite/data/plugins/datadog.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 microsite/data/plugins/datadog.yaml diff --git a/microsite/data/plugins/datadog.yaml b/microsite/data/plugins/datadog.yaml new file mode 100644 index 0000000000..7d47906a68 --- /dev/null +++ b/microsite/data/plugins/datadog.yaml @@ -0,0 +1,9 @@ +--- +title: Datadog +author: roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=datadog +category: Monitoring +description: Embed Datadog graphs and dashboards in Backstage. +documentation: https://roadie.io/backstage/plugins/datadog +iconUrl: https://roadie.io/images/logos/datadog-white-background.png +npmPackageName: '@roadiehq/backstage-plugin-datadog' From 9fba7470d793bb249e067ea89b328677750663b1 Mon Sep 17 00:00:00 2001 From: David Tuite Date: Tue, 20 Apr 2021 11:24:39 +0100 Subject: [PATCH 104/462] Add utm params to roadie marketplace links Signed-off-by: David Tuite --- microsite/data/plugins/argo-cd.yaml | 4 ++-- microsite/data/plugins/aws-lambda.yaml | 4 ++-- microsite/data/plugins/buildkite.yaml | 4 ++-- microsite/data/plugins/datadog.yaml | 2 +- microsite/data/plugins/firebase-functions.yaml | 4 ++-- microsite/data/plugins/github-insights.yaml | 4 ++-- microsite/data/plugins/github-pull-requests.yaml | 4 ++-- microsite/data/plugins/jira.yaml | 4 ++-- microsite/data/plugins/security-insights.yaml | 4 ++-- microsite/data/plugins/travis-ci.yaml | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/microsite/data/plugins/argo-cd.yaml b/microsite/data/plugins/argo-cd.yaml index ca753f682a..121c833cb4 100644 --- a/microsite/data/plugins/argo-cd.yaml +++ b/microsite/data/plugins/argo-cd.yaml @@ -1,10 +1,10 @@ --- title: Argo CD author: roadie.io -authorUrl: https://roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=argo-cd category: CI/CD description: View Argo CD status for your projects in Backstage. -documentation: https://roadie.io/backstage/plugins/argo-cd +documentation: https://roadie.io/backstage/plugins/argo-cd/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=argo-cd iconUrl: https://roadie.io/images/logos/argo.png npmPackageName: '@roadiehq/backstage-plugin-argo-cd' tags: diff --git a/microsite/data/plugins/aws-lambda.yaml b/microsite/data/plugins/aws-lambda.yaml index cc3d59d188..f20cc0d393 100644 --- a/microsite/data/plugins/aws-lambda.yaml +++ b/microsite/data/plugins/aws-lambda.yaml @@ -1,9 +1,9 @@ --- title: AWS Lambda author: roadie.io -authorUrl: https://roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=aws-lambda category: Infrastructure description: View AWS Lambda functions for your components in Backstage. -documentation: https://roadie.io/backstage/plugins/aws-lambda +documentation: https://roadie.io/backstage/plugins/aws-lambda/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=aws-lambda iconUrl: https://roadie.io/images/logos/lambda.png npmPackageName: '@roadiehq/backstage-plugin-aws-lambda' diff --git a/microsite/data/plugins/buildkite.yaml b/microsite/data/plugins/buildkite.yaml index 16c6960898..4e9b1594d3 100644 --- a/microsite/data/plugins/buildkite.yaml +++ b/microsite/data/plugins/buildkite.yaml @@ -1,10 +1,10 @@ --- title: Buildkite author: roadie.io -authorUrl: https://roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=buildkite category: CI/CD description: View Buildkite CI builds for your service in Backstage. -documentation: https://roadie.io/backstage/plugins/buildkite +documentation: https://roadie.io/backstage/plugins/buildkite/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=buildkite iconUrl: https://roadie.io/images/logos/buildkite.png npmPackageName: '@roadiehq/backstage-plugin-buildkite' tags: diff --git a/microsite/data/plugins/datadog.yaml b/microsite/data/plugins/datadog.yaml index 7d47906a68..266627009c 100644 --- a/microsite/data/plugins/datadog.yaml +++ b/microsite/data/plugins/datadog.yaml @@ -4,6 +4,6 @@ author: roadie.io authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=datadog category: Monitoring description: Embed Datadog graphs and dashboards in Backstage. -documentation: https://roadie.io/backstage/plugins/datadog +documentation: https://roadie.io/backstage/plugins/datadog/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=datadog iconUrl: https://roadie.io/images/logos/datadog-white-background.png npmPackageName: '@roadiehq/backstage-plugin-datadog' diff --git a/microsite/data/plugins/firebase-functions.yaml b/microsite/data/plugins/firebase-functions.yaml index 9a1777754a..0b98948f88 100644 --- a/microsite/data/plugins/firebase-functions.yaml +++ b/microsite/data/plugins/firebase-functions.yaml @@ -1,9 +1,9 @@ --- title: Firebase Functions author: roadie.io -authorUrl: https://roadie.io/ +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=firebase-functions category: Infrastructure description: View Firebase Functions details for your service in Backstage. -documentation: https://roadie.io/backstage/plugins/firebase-functions +documentation: https://roadie.io/backstage/plugins/firebase-functions/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=firebase-functions iconUrl: https://roadie.io/images/logos/firebase.png npmPackageName: '@roadiehq/backstage-plugin-firebase-functions' diff --git a/microsite/data/plugins/github-insights.yaml b/microsite/data/plugins/github-insights.yaml index f127f88a3c..3515065916 100644 --- a/microsite/data/plugins/github-insights.yaml +++ b/microsite/data/plugins/github-insights.yaml @@ -1,9 +1,9 @@ --- title: GitHub Insights author: roadie.io -authorUrl: https://roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=github-insights category: Source Control Mgmt description: View GitHub Insights for your components in Backstage. -documentation: https://roadie.io/backstage/plugins/github-insights +documentation: https://roadie.io/backstage/plugins/github-insights/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=github-insights iconUrl: https://roadie.io/images/logos/insights.png npmPackageName: '@roadiehq/backstage-plugin-github-insights' diff --git a/microsite/data/plugins/github-pull-requests.yaml b/microsite/data/plugins/github-pull-requests.yaml index 4172cdff6b..8fc0dd5a6e 100644 --- a/microsite/data/plugins/github-pull-requests.yaml +++ b/microsite/data/plugins/github-pull-requests.yaml @@ -1,9 +1,9 @@ --- title: GitHub Pull Requests author: roadie.io -authorUrl: https://roadie.io/ +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=github-pull-requests category: Source Control Mgmt description: View GitHub pull requests for your service in Backstage. -documentation: https://roadie.io/backstage/plugins/github-pull-requests +documentation: https://roadie.io/backstage/plugins/github-pull-requests/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=github-pull-requests iconUrl: https://roadie.io/images/logos/github.png npmPackageName: '@roadiehq/backstage-plugin-github-pull-requests' diff --git a/microsite/data/plugins/jira.yaml b/microsite/data/plugins/jira.yaml index c32455c7d5..3342a2594c 100644 --- a/microsite/data/plugins/jira.yaml +++ b/microsite/data/plugins/jira.yaml @@ -1,9 +1,9 @@ --- title: Jira author: roadie.io -authorUrl: https://roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=jira category: Agile Planning description: View Jira summary for your projects in Backstage. -documentation: https://roadie.io/backstage/plugins/jira +documentation: https://roadie.io/backstage/plugins/jira/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=jira iconUrl: https://roadie.io/images/logos/jira.png npmPackageName: '@roadiehq/backstage-plugin-jira' diff --git a/microsite/data/plugins/security-insights.yaml b/microsite/data/plugins/security-insights.yaml index 4f34f79027..1761bdf30a 100644 --- a/microsite/data/plugins/security-insights.yaml +++ b/microsite/data/plugins/security-insights.yaml @@ -1,9 +1,9 @@ --- title: Security Insights author: roadie.io -authorUrl: https://roadie.io/ +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=security-insights category: Security description: View Security Insights for your components in Backstage. -documentation: https://roadie.io/backstage/plugins/security-insights +documentation: https://roadie.io/backstage/plugins/security-insights/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=security-insights iconUrl: https://roadie.io/images/logos/github.png npmPackageName: '@roadiehq/backstage-plugin-security-insights' diff --git a/microsite/data/plugins/travis-ci.yaml b/microsite/data/plugins/travis-ci.yaml index a6b8c6ebd7..7cb108a5d8 100644 --- a/microsite/data/plugins/travis-ci.yaml +++ b/microsite/data/plugins/travis-ci.yaml @@ -1,9 +1,9 @@ --- title: Travis CI author: roadie.io -authorUrl: https://roadie.io/ +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=travis-ci category: CI/CD description: View Travis CI builds for your service in Backstage. -documentation: https://roadie.io/backstage/plugins/travis-ci +documentation: https://roadie.io/backstage/plugins/travis-ci/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=travis-ci iconUrl: https://roadie.io/images/logos/travis.png npmPackageName: '@roadiehq/backstage-plugin-travis-ci' From 295589e13672b40a27fc4a2b45076121ae93a175 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Tue, 20 Apr 2021 14:00:21 +0200 Subject: [PATCH 105/462] Satisfy vale linter. Signed-off-by: Eric Peterson --- .changeset/techdocs-eight-camels-hear.md | 6 +++--- docs/features/techdocs/FAQ.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.changeset/techdocs-eight-camels-hear.md b/.changeset/techdocs-eight-camels-hear.md index 5c3df10c89..8f2479f6bd 100644 --- a/.changeset/techdocs-eight-camels-hear.md +++ b/.changeset/techdocs-eight-camels-hear.md @@ -2,6 +2,6 @@ '@backstage/plugin-techdocs': minor --- -Add feedback link icon in Techdocs Reader that directs to Gitlab or Github repo issue page with prefilled title and source link. -For link to appear, requires repo_url and edit_uri to be filled in mkdocs.yml, as per https://www.mkdocs.org/user-guide/configuration. edit_uri will need to be specified for self-hosted Gitlab/Github with different hostnames. -To identify issue URL format as Github or Gitlab, the hostname of source in repo_url is checked if it contains 'gitlab' or 'github'. Alternately this is determined by matching to 'host' values from 'integrations' in app-config.yaml. +Add feedback link icon in Techdocs Reader that directs to GitLab or GitHub repo issue page with pre-filled title and source link. +For link to appear, requires `repo_url` and `edit_uri` to be filled in mkdocs.yml, as per https://www.mkdocs.org/user-guide/configuration. An `edit_uri` will need to be specified for self-hosted GitLab/GitHub instances with a different host name. +To identify issue URL format as GitHub or GitLab, the host name of source in `repo_url` is checked if it contains `gitlab` or `github`. Alternately this is determined by matching to `host` values from `integrations` in app-config.yaml. diff --git a/docs/features/techdocs/FAQ.md b/docs/features/techdocs/FAQ.md index 3b479f2a15..117471f749 100644 --- a/docs/features/techdocs/FAQ.md +++ b/docs/features/techdocs/FAQ.md @@ -54,6 +54,6 @@ on a TechDocs page, be sure that you have `repo_url` and `edit_uri` values in your `mkdocs.yml` files per [MkDocs instructions](https://www.mkdocs.org/user-guide/configuration). -If the hostname of your source code hosting URL does not include 'github' or -'gitlab', an `integrations` entry in your `app-config.yaml` pointed at your +If the host name of your source code hosting URL does not include `github` or +`gitlab`, an `integrations` entry in your `app-config.yaml` pointed at your source code provider is also needed (only the `host` key is necessary). From 18868f258b5c77a387430d7ebc00417ebce9a018 Mon Sep 17 00:00:00 2001 From: Andrey O <10812297+andreyors@users.noreply.github.com> Date: Mon, 12 Apr 2021 09:38:14 +0200 Subject: [PATCH 106/462] Update Ukrainian and Russian translations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../CatalogPage/utils/locales/goodEvening.locales.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json index 890899fcf3..36d48eaf39 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json @@ -75,7 +75,7 @@ "Quiché": "Xe q’ij", "Romani [Sinte]": "Lashi rachi", "Romanian": "Bunã seara", - "Russian": "Dobry vyecher", + "Russian": "Добрый вечер", "Scottish Gaelic": "Feasgar mhath", "Scots": "Guid eenin", "Sesotho": "Fonane", @@ -91,7 +91,7 @@ "Telugu": "శుభ సాయంత్రం", "Thai": "Sawat-dii torn khum", "Turkish": "İyi akşamlar", - "Ukrainian": "Dobry vechir", + "Ukrainian": "Добрий вечiр", "Uzbek": "Xayrli kech", "Welsh": "Noswaith dda", "Yiddish": "Ah gutn ovnt", From 37f1311d1ebf4dd2153a7723b80ce01b9c39a202 Mon Sep 17 00:00:00 2001 From: Brett Wright Date: Tue, 20 Apr 2021 15:11:40 +0200 Subject: [PATCH 107/462] fixed australian greeting Signed-off-by: Brett Wright --- .../CatalogPage/utils/locales/goodAfternoon.locales.json | 2 +- .../CatalogPage/utils/locales/goodEvening.locales.json | 2 +- .../CatalogPage/utils/locales/goodMorning.locales.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json index ad3c4e4634..72e7782882 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json @@ -11,7 +11,7 @@ "Armenian": "Բարի կէսօր:", "Assamese": "শুভ আবেলি", "Asturian": "Bones tardes", - "Australian": "G'day mate", + "Australian": "G'day", "Azerbaijani": "Günortanız xeyir", "Bashkir": "хәйерле көн", "Basque": "Arratsalde on", diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json index ed68d0332e..636f845c36 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json @@ -10,7 +10,7 @@ "Asante": "Maadwó", "Asturian": "Bona nuechi", "Ateso": "Akwar najokan", - "Australian": "G'day mate", + "Australian": "G'day", "Aymara": "Winas tartis", "Azerbaijani": "Axşamınız xeyir", "Basque": "Arratsalde on", diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json index b906155426..c131d2eb04 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json @@ -4,7 +4,7 @@ "Albanian": "Mirëmëngjes", "Arabic": "صباح الخير", "Armenian": "Paree looys", - "Australian": "G'day mate", + "Australian": "G'day", "Azerbaijani": "Sabahınız xeyir", "Bengali": "shuprobhat", "Bulgarian": "Dobro utro", From 772f60f14b3e7f5cfd0827879c13daf311c9575c Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Tue, 20 Apr 2021 07:10:08 -0400 Subject: [PATCH 108/462] Update plugins/catalog/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Adam Harvey --- plugins/catalog/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog/README.md b/plugins/catalog/README.md index 2940fecaa1..611d2989e8 100644 --- a/plugins/catalog/README.md +++ b/plugins/catalog/README.md @@ -18,7 +18,7 @@ Backstage root folder, instead do: yarn dev ``` -This will launch both the front and backend in same window, populated some example entities. +This will launch both frontend and backend in the same window, populated with some example entities. ## Links From bc30288405c70f10bfa2eb08ba34e9174aaa2933 Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Tue, 23 Mar 2021 14:46:03 -0600 Subject: [PATCH 109/462] Change #0A6EBE to #EFE5B1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- packages/theme/src/themes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index 0cdd41508c..0e592cb521 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -124,8 +124,8 @@ export const darkTheme = createTheme({ errorText: '#CA001B', infoText: '#004e8a', warningText: '#000000', - linkHover: '#2196F3', - link: '#0A6EBE', + linkHover: '#EFE5A1', + link: '#EFE5B1', gold: yellow.A700, navigation: { background: '#424242', From 343913573fa4fcf864991c50f3d6d93579629aee Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 08:23:52 -0600 Subject: [PATCH 110/462] banner link color MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- packages/theme/src/themes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index 0e592cb521..3d9e7f139e 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -46,7 +46,7 @@ export const lightTheme = createTheme({ info: '#2E77D0', error: '#E22134', text: '#FFFFFF', - link: '#000000', + link: '#0A6EBE', }, border: '#E6E6E6', textContrast: '#000000', From 931b21a127aa69eb2851eb68ea10b5d40816285a Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 08:29:49 -0600 Subject: [PATCH 111/462] Add Changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- .changeset/light-horses-hammer.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/light-horses-hammer.md diff --git a/.changeset/light-horses-hammer.md b/.changeset/light-horses-hammer.md new file mode 100644 index 0000000000..4e3159cc1d --- /dev/null +++ b/.changeset/light-horses-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +I've changed the link color in dark theme to #EFE5B1 instead dark blue From f9b206cece589334946e9fe82c72e5767125b97b Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 08:33:48 -0600 Subject: [PATCH 112/462] Revert "Change #0A6EBE to #EFE5B1" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 30d3886ef7cba00ac55c8db9aca7f20eda8a5d2f. Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- packages/theme/src/themes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index 3d9e7f139e..26b58389b9 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -124,8 +124,8 @@ export const darkTheme = createTheme({ errorText: '#CA001B', infoText: '#004e8a', warningText: '#000000', - linkHover: '#EFE5A1', - link: '#EFE5B1', + linkHover: '#2196F3', + link: '#0A6EBE', gold: yellow.A700, navigation: { background: '#424242', From 08b25805d1501ec4e555e9689efe1ffb72d13026 Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 08:38:12 -0600 Subject: [PATCH 113/462] Fixing typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- packages/theme/src/themes.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index 26b58389b9..f67360f176 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -46,7 +46,7 @@ export const lightTheme = createTheme({ info: '#2E77D0', error: '#E22134', text: '#FFFFFF', - link: '#0A6EBE', + link: '#000000', }, border: '#E6E6E6', textContrast: '#000000', @@ -111,7 +111,7 @@ export const darkTheme = createTheme({ info: '#2E77D0', error: '#E22134', text: '#FFFFFF', - link: '#000000', + link: '#0A6EBE', }, border: '#E6E6E6', textContrast: '#FFFFFF', @@ -124,8 +124,8 @@ export const darkTheme = createTheme({ errorText: '#CA001B', infoText: '#004e8a', warningText: '#000000', - linkHover: '#2196F3', - link: '#0A6EBE', + linkHover: '#EFE5A1', + link: '#EFE5B1', gold: yellow.A700, navigation: { background: '#424242', From 9c9df47f4f3f3bd597039eef5e54fef806b4318f Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 13:01:40 -0600 Subject: [PATCH 114/462] Replace color proposed by one Backstage color MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- packages/theme/src/themes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index f67360f176..b6810d9a84 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -111,7 +111,7 @@ export const darkTheme = createTheme({ info: '#2E77D0', error: '#E22134', text: '#FFFFFF', - link: '#0A6EBE', + link: '#FDFB9F', }, border: '#E6E6E6', textContrast: '#FFFFFF', @@ -124,8 +124,8 @@ export const darkTheme = createTheme({ errorText: '#CA001B', infoText: '#004e8a', warningText: '#000000', - linkHover: '#EFE5A1', - link: '#EFE5B1', + linkHover: '#FFED51', + link: '#FDFB9F', gold: yellow.A700, navigation: { background: '#424242', From 7923c2a94606dfb8c9070cf92da76496da8e491e Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 13:06:13 -0600 Subject: [PATCH 115/462] Fix Changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- .changeset/light-horses-hammer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/light-horses-hammer.md b/.changeset/light-horses-hammer.md index 4e3159cc1d..06abf339f1 100644 --- a/.changeset/light-horses-hammer.md +++ b/.changeset/light-horses-hammer.md @@ -2,4 +2,4 @@ '@backstage/theme': patch --- -I've changed the link color in dark theme to #EFE5B1 instead dark blue +Replace the link color in dark theme to #FDFB9F instead dark blue From 8546ef9f0c223ffff1d47be20e1f9dab8bdf8273 Mon Sep 17 00:00:00 2001 From: Victor Perera Date: Wed, 24 Mar 2021 13:39:28 -0600 Subject: [PATCH 116/462] Fix Changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Victor Perera Signed-off-by: Fredrik Adelöw --- .changeset/light-horses-hammer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/light-horses-hammer.md b/.changeset/light-horses-hammer.md index 06abf339f1..0d421c7056 100644 --- a/.changeset/light-horses-hammer.md +++ b/.changeset/light-horses-hammer.md @@ -2,4 +2,4 @@ '@backstage/theme': patch --- -Replace the link color in dark theme to #FDFB9F instead dark blue +Replace the link color in dark theme From 091b3f7363d795ac5a9e8f449d847d67ef933c20 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Tue, 20 Apr 2021 17:04:25 +0200 Subject: [PATCH 117/462] Fix review comments Signed-off-by: Dominik Henneke --- plugins/fossa/dev/index.tsx | 2 +- plugins/fossa/src/api/FossaClient.test.ts | 64 +++++++++++++++++++ plugins/fossa/src/api/FossaClient.ts | 33 ++++------ .../src/components/FossaCard/FossaCard.tsx | 6 +- .../src/components/FossaPage/FossaPage.tsx | 11 +++- ...ectName.test.ts => getProjectName.test.ts} | 42 ++++++++---- .../{useProjectName.ts => getProjectName.ts} | 2 +- .../src/components/useProjectNames.test.ts | 45 ------------- .../fossa/src/components/useProjectNames.ts | 33 ---------- 9 files changed, 118 insertions(+), 120 deletions(-) rename plugins/fossa/src/components/{useProjectName.test.ts => getProjectName.test.ts} (56%) rename plugins/fossa/src/components/{useProjectName.ts => getProjectName.ts} (92%) delete mode 100644 plugins/fossa/src/components/useProjectNames.test.ts delete mode 100644 plugins/fossa/src/components/useProjectNames.ts diff --git a/plugins/fossa/dev/index.tsx b/plugins/fossa/dev/index.tsx index 9625b24dc2..1c2e96807f 100644 --- a/plugins/fossa/dev/index.tsx +++ b/plugins/fossa/dev/index.tsx @@ -27,7 +27,7 @@ import React from 'react'; import { EntityFossaCard, fossaPlugin } from '../src'; import { FindingSummary, FossaApi, fossaApiRef } from '../src/api'; import { FossaPage } from '../src/components/FossaPage'; -import { FOSSA_PROJECT_NAME_ANNOTATION } from '../src/components/useProjectName'; +import { FOSSA_PROJECT_NAME_ANNOTATION } from '../src/components/getProjectName'; const entity = (name?: string) => ({ diff --git a/plugins/fossa/src/api/FossaClient.test.ts b/plugins/fossa/src/api/FossaClient.test.ts index 24bcad526c..29e5b50fcd 100644 --- a/plugins/fossa/src/api/FossaClient.test.ts +++ b/plugins/fossa/src/api/FossaClient.test.ts @@ -287,6 +287,70 @@ describe('FossaClient', () => { ); }); + it('should handle multiple pages', async () => { + server.use( + rest.get(`${mockBaseUrl}/fossa/projects`, (req, res, ctx) => { + const page = req.url.searchParams.get('page'); + + if (page === '0') { + return res( + ctx.json( + [...Array(1000)].map(() => ({ + locator: 'custom+8736/our-service', + title: 'our-service-2', + default_branch: 'develop', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_licensing_issue_count: 5, + unresolved_issue_count: 100, + }, + ], + })), + ), + ); + } + + return res( + ctx.json([ + { + locator: 'custom+8736/our-service', + title: 'our-service', + default_branch: 'develop', + revisions: [ + { + updatedAt: '2020-01-01T00:00:00Z', + dependency_count: 160, + unresolved_licensing_issue_count: 5, + unresolved_issue_count: 100, + }, + ], + }, + ]), + ); + }), + ); + + const summary = await client.getFindingSummaries(['our-service']); + + expect(summary).toEqual( + new Map([ + [ + 'our-service', + { + timestamp: '2020-01-01T00:00:00Z', + issueCount: 5, + dependencyCount: 160, + projectDefaultBranch: 'develop', + projectUrl: + 'https://app.fossa.com/projects/custom%2B8736%2Four-service', + }, + ], + ]), + ); + }); + it('should handle empty result', async () => { server.use( rest.get(`${mockBaseUrl}/fossa/projects`, (_req, res, ctx) => { diff --git a/plugins/fossa/src/api/FossaClient.ts b/plugins/fossa/src/api/FossaClient.ts index fb5eb80345..e8f3ecb7cd 100644 --- a/plugins/fossa/src/api/FossaClient.ts +++ b/plugins/fossa/src/api/FossaClient.ts @@ -55,7 +55,7 @@ export class FossaClient implements FossaApi { private async callApi( path: string, query: Record, - ): Promise { + ): Promise { const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/fossa`; const idToken = await this.identityApi.getIdToken(); const response = await fetch( @@ -75,30 +75,23 @@ export class FossaClient implements FossaApi { async *getProject( projectTitles: Set, ): AsyncIterable<{ title: string; summary: FindingSummary }> { - let nextPage = 0; const pageSize = 1000; - for (;;) { - const projects = await this.limit( - page => - this.callApi('projects', { - count: pageSize, - page, - sort: 'title+', - ...(this.organizationId && { - organizationId: this.organizationId, - }), - ...(projectTitles.size === 1 && { - title: projectTitles.values().next().value, - }), + for (let page = 0; ; page++) { + const projects = await this.limit(() => + this.callApi('projects', { + count: pageSize, + page, + sort: 'title+', + ...(this.organizationId && { + organizationId: this.organizationId, }), - nextPage++, + ...(projectTitles.size === 1 && { + title: projectTitles.values().next().value, + }), + }), ); - if (!projects) { - break; - } - for (const project of projects) { if (projectTitles.has(project.title) && project.revisions.length > 0) { const revision = project.revisions[0]; diff --git a/plugins/fossa/src/components/FossaCard/FossaCard.tsx b/plugins/fossa/src/components/FossaCard/FossaCard.tsx index 9d2db263c8..034ba57dfc 100644 --- a/plugins/fossa/src/components/FossaCard/FossaCard.tsx +++ b/plugins/fossa/src/components/FossaCard/FossaCard.tsx @@ -32,8 +32,8 @@ import { useAsync } from 'react-use'; import { fossaApiRef } from '../../api'; import { FOSSA_PROJECT_NAME_ANNOTATION, - useProjectName, -} from '../useProjectName'; + getProjectName, +} from '../getProjectName'; const useStyles = makeStyles(theme => ({ numberError: { @@ -102,7 +102,7 @@ export const FossaCard = ({ variant }: { variant?: InfoCardVariants }) => { const { entity } = useEntity(); const fossaApi = useApi(fossaApiRef); - const projectTitle = useProjectName(entity); + const projectTitle = getProjectName(entity); const { value, loading, error } = useAsync( async () => projectTitle ? fossaApi.getFindingSummary(projectTitle) : undefined, diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.tsx index 05e1379378..cfc6e8af97 100644 --- a/plugins/fossa/src/components/FossaPage/FossaPage.tsx +++ b/plugins/fossa/src/components/FossaPage/FossaPage.tsx @@ -45,7 +45,7 @@ import * as React from 'react'; import { useMemo } from 'react'; import { useAsync } from 'react-use'; import { FindingSummary, fossaApiRef } from '../../api'; -import { useProjectNames } from '../useProjectNames'; +import { getProjectName } from '../getProjectName'; type FossaRow = { entity: Entity; @@ -63,7 +63,9 @@ const columns: TableColumn[] = [ title: 'Name', field: 'resolved.name', highlight: true, - render: ({ entity }) => , + render: ({ entity }) => ( + + ), }, { title: 'Owner', @@ -170,7 +172,10 @@ export const FossaPage = () => { }); // get the project names of all entities. the idx of both lists match. - const projectNames = useProjectNames(entities?.items); + const projectNames = useMemo( + () => entities?.items?.map(getProjectName) ?? [], + [entities?.items], + ); // get the summary list const { value: summaries, loading: summariesLoading } = useAsync( diff --git a/plugins/fossa/src/components/useProjectName.test.ts b/plugins/fossa/src/components/getProjectName.test.ts similarity index 56% rename from plugins/fossa/src/components/useProjectName.test.ts rename to plugins/fossa/src/components/getProjectName.test.ts index e85b1f427c..461cb18ed7 100644 --- a/plugins/fossa/src/components/useProjectName.test.ts +++ b/plugins/fossa/src/components/getProjectName.test.ts @@ -16,23 +16,37 @@ import { Entity } from '@backstage/catalog-model'; import { renderHook } from '@testing-library/react-hooks'; -import { useProjectName } from './useProjectName'; - -describe('useProjectName', () => { - const entity: Entity = { - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'test', - annotations: { - 'fossa.io/project-name': 'test', - }, - }, - }; +import { getProjectName } from './getProjectName'; +describe('getProjectName', () => { it('should extract the fossa project name', async () => { - const { result } = renderHook(() => useProjectName(entity)); + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'test', + annotations: { + 'fossa.io/project-name': 'test', + }, + }, + }; + + const { result } = renderHook(() => getProjectName(entity)); expect(result.current).toBe('test'); }); + + it('should return undefined', async () => { + const entity: Entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'test', + }, + }; + + const { result } = renderHook(() => getProjectName(entity)); + + expect(result.current).toBeUndefined(); + }); }); diff --git a/plugins/fossa/src/components/useProjectName.ts b/plugins/fossa/src/components/getProjectName.ts similarity index 92% rename from plugins/fossa/src/components/useProjectName.ts rename to plugins/fossa/src/components/getProjectName.ts index 88379ca3fa..3f117dbbda 100644 --- a/plugins/fossa/src/components/useProjectName.ts +++ b/plugins/fossa/src/components/getProjectName.ts @@ -18,7 +18,7 @@ import { Entity } from '@backstage/catalog-model'; export const FOSSA_PROJECT_NAME_ANNOTATION = 'fossa.io/project-name'; -export const useProjectName = (entity: Entity): string | undefined => { +export const getProjectName = (entity: Entity): string | undefined => { return ( entity?.metadata.annotations?.[FOSSA_PROJECT_NAME_ANNOTATION] ?? undefined ); diff --git a/plugins/fossa/src/components/useProjectNames.test.ts b/plugins/fossa/src/components/useProjectNames.test.ts deleted file mode 100644 index ae17fa93d8..0000000000 --- a/plugins/fossa/src/components/useProjectNames.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entity } from '@backstage/catalog-model'; -import { renderHook } from '@testing-library/react-hooks'; -import { useProjectNames } from './useProjectNames'; - -describe('useProjectNames', () => { - const entity0: Entity = { - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'test', - annotations: { - 'fossa.io/project-name': 'test', - }, - }, - }; - const entity1: Entity = { - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'test', - }, - }; - - it('should extract the fossa project name', async () => { - const { result } = renderHook(() => useProjectNames([entity0, entity1])); - - expect(result.current).toEqual(['test', undefined]); - }); -}); diff --git a/plugins/fossa/src/components/useProjectNames.ts b/plugins/fossa/src/components/useProjectNames.ts deleted file mode 100644 index c0e11a1e87..0000000000 --- a/plugins/fossa/src/components/useProjectNames.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entity } from '@backstage/catalog-model'; -import { useMemo } from 'react'; -import { FOSSA_PROJECT_NAME_ANNOTATION } from './useProjectName'; - -export const useProjectNames = ( - entities: Entity[] | undefined, -): Array => { - return useMemo( - () => - entities?.map( - entity => - entity.metadata.annotations?.[FOSSA_PROJECT_NAME_ANNOTATION] ?? - undefined, - ) ?? [], - [entities], - ); -}; From 54c455cfa44bb801da3e5ca4af8a65d5d8eae8bb Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Tue, 20 Apr 2021 17:09:05 +0200 Subject: [PATCH 118/462] Add a link to the fossa details Signed-off-by: Dominik Henneke --- plugins/fossa/dev/index.tsx | 7 ++++++- plugins/fossa/docs/fossa-overview.png | Bin 375035 -> 337907 bytes .../src/components/FossaPage/FossaPage.tsx | 13 ++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/fossa/dev/index.tsx b/plugins/fossa/dev/index.tsx index 1c2e96807f..563c63faf5 100644 --- a/plugins/fossa/dev/index.tsx +++ b/plugins/fossa/dev/index.tsx @@ -140,7 +140,12 @@ createDevApp() await new Promise(r => setTimeout(r, 1000)); return { - items: [entity('zero-deps'), entity('issues'), entity('no-issues')], + items: [ + entity('no-fossa'), + entity('zero-deps'), + entity('issues'), + entity('no-issues'), + ], }; }, } as Partial) as any), diff --git a/plugins/fossa/docs/fossa-overview.png b/plugins/fossa/docs/fossa-overview.png index 2c6dd972312d50bfc678dc5a2dcf5063e38965cc..6298fb95573dea5f3121ade63e2e8814f84d2b98 100644 GIT binary patch literal 337907 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 $D0XxbkZ~+sqYp9>XISC961nseel%I@hs*Kd{4y zfPn)$Kmk9Q+ibo0UimO!jUn4~EP%s!vy-8V-#skhAgO<-WP5;0{!1F5k_*5nl9#a& zf38zEJBePsH*)dgP)p#v<)5UQX}~Qs%K-klk93p&kzNg`W}PO>?{Z_U)*AzI9K?XF z(xa5_nr8?cc|RIqlbC$sRVVfJ?oOc)4oRzUE5{$?;P0Sl_NWphi{jS$ysQ(2+{q!m zN3kYQcRAZ&P7#thL&|u+Exz{6K;cLyd{EL_0XmO{PpDu@eOd}i@h^zM} zEU-Q-3C)T5Qyk(?(BIRxXMfk`Ztu|#(g@hqjk%baC4;5YG|un+A9;G#MEBnxEu}JF z;<@WGt!$df`zl7fa(B*JJu!$ifh@B(qkZ3Ag1k0KA0~rc-L7pvIcd#rF$qXI6$=O0 zGpB+iwz>xkOp6$?*!Rx7<7tFSV;S%mg^H;!#k{{N+iR@xi=}PU{Q*>d9l9o&+VqX{ zSSQBB(SVnm2w_oyPTqjBmCIk^Ye7l`v zDq=HWT23z=A24;9$@u`!*U9$V;neRb{MV#nk04D)7VL#l_r8@irzBn%7|nsj-uQtJx7^|-F5E_=}H3$X`k z%-M5HyLjZQ(Sn?|W1dxo8)~6QK8Le(c$k5smGo6r&z75znzAQ4;|tbCn(N-+uMvrq z7z7V~xlc?|yxvSy093sWGX$S0289Xyg_#rGkW@!s*kGDKJaPR7(++YHF{2L&PQ6oc zM3=vDL+nX-V^PIGyn;fF%E6VJzow0WvXpZ^9689&rkwYJ_CK z*o@i#3XS;@vjWD|_4UdOdH^T%*TP#AKR^HOU|7e_;Ef<)9WedsOq%BOVr&g2Yz;zu znDl!N;|Dqlx9c%^_#8gYo!jP(<`ag8g&`EwS*+5~@1;WspgkvIhc=(=;&N58&!Vv+jnw$=d>j7U{-i{tjyJ;hsD}1w zV@8I@_pkE)$79delf@ID>e!-KU&(&+@UytxW~KRA`qssrTgDM16f4=+OUd>*QZCMe zs~!~)muvQ~fYzWJKTq@(9Z$*tM_eisZo409Ff^}eV=4E*yK-9wJo=XAVAsti%wU~N1NNvj?wXBLBGz1(7 zUM?g@{;CL0IMqkd`eLI^o6+Lf^gaaX0pj$kIMERYHL7Fl!0j=Ut|?D%xPR>S6a-bHVH0b#9OcSlMP z1iCfZn~C#BTz|Pb|NW%!z}Yk#{ytxnlR(jV0yrh>ddT&>yS-x!qNMrrMC{1F*|fAP z$HTc6Q?f>nM81-q@jVYU#gw%4icRd3Web8k_lTfsTc%@lR2g zY(rN2`CmM3=Wk)l z&1qO>_iYqOrf-!&L##vyh0BfW+HBN_!|iM6{=4H1x;I_~lZO>rSP6oVZ;4>UdX70= zFEW)ZZ>FPUc^fG7)$H)Sd(lnP^>q)wzo<#VBpRriv_Ha@6UAnUQ{gvGqZ4_0iIC6mDTkMS`f zw?L(21k^%#?kp2{25|N=gD%JQL7KgW!{SdPelRT1%#Z~m}RHW9Tu7%z(UXg5G>It2nN6Y&kqScxjh!0#(4sbjAPc#YNi%sv9ED zx#1;jI(AFI!aaH0rP_&|R6NCnDq&gmR2Y@}XiJ#-v?t_n^bO}C5iE8N@IX4V)!Xe{aJYdvamv|lyjH9=Fs(+O+#v{+@-*^-+C_mD!;#_@|^`qCidV^DgEP+V2Z>xo|PIArbHcu$JpA zPon)rRZp3Zy}hozXHHhG7*ktf4<3-{;>=9nf;z47j@R^prk$Ck31qm5ZgV)RP+gs} zv(VEA$#Zl09@KYCe*7|DU|B6^-$ODzbQ5Txl?5{Zg{%bCwo6XS*V2;6Gx`_398upl zShL^m)|-GdWnS-$AJ&B@bN2uE9!uxmgT6yqNHO9o}1=Wh&KE&4lN9#ma(3m8|)8LZ5{efCS{AvuYr3#6%dcilw4 ziAriCv?BHZjo#RwtwVfasG@3n&9JQF*$0TV zZmJu`^!boB^7#F<#!EoC=L}B+HIX?b0us8UOY!k>n2NH=( zO~>Y*^KTlWHM*eQM`P0D9(Z_%T#;~o36s|nYo@TpSOcD)iXU%GA6lLb;3dqPO+umOn25R9EX9adxz{|pB z+IUqIE_6vlCs#;hcgS(g%%`!}7gJkvQ?1iMi>W2B{A&dU7fh+0!HOyF zQAI6QzfK`UuD%}0Kpp*C%3yNM^q059ldkO;D6hSVE}PZII#ynwvnW>nd2>@#IIh^c zIiQYY#(Zm4_a)+sh>VS4bP)Em#rtIRuY;f)J`hZM==_&uBu@JCONysVb?NrGEHhV6 zQRbs~)<-L5C?)1nmYkJNKWNzbh01J$4s@!(tG+-j{dG5gmc#v6#CHf$qmFld@ zu_S8jV?glr9Nx^=KTcIzLDw*(g>5W5fF8$41S>M*r2ybX;au~m;>}G{Sk*~%*I|4XTGKvg9MD53IJ=*641Gul69C9?ERC&8A8qf%eGc0sMR23 zUtHGg%UVbQPDZ;tpj+mXvyK~(^FbZDjnhR6e@n9i%I{i)4gN$XOn|vdnwwx+g_$~x ztpd6H<)1K99bobM;9y5^v2!HF!4%WX7!xI-fI3MX8uNb`wsNP=&(!A0KM;1*`Ut0W z1#iU~cj)_1EQ*(ZEwx7hC{Y48aHD3gCOJz&^ye-ZR|B8dRH1L>dVc8l<2Hw1TSn|{ zf3S*;OH=f5y!`h5qIdYF5WV%DTMGFYLaa_Kd&C7p06A1RDo8qEb==9hEy|Y&4qKUb ze0lS>!w(^ zGL*VQ5z@`+KCbpmyY17vgvBqBq$CcqYDtjFMs`>%PY@uFc;umK8T||Lb>X#sZv=kr z2tuzGYNZ_!*^p7=TwRPfyv8^=gb!#zj1mLJD3z(@Uv~H>M87VIFEolQQ>e{v>qGVt zVJzx093k{v!GuRiDXOQ}o}#MlD!&q?Q^pNmQsvE*40`_Uu2e`mygai=R2Org(7>H< zg_xbv)>vv#h;AUm&b55NR$D93tat14Fw494yT!CS46D1`nDvS3g0C@07W=y_U1VM# zkIx;M&~cRsAP#Urf34X8-z_!x^7pa16JIh*zx4%oMI5yBs5p?irogap& ziR*lzq`XHhw3ac8pT zQI3378Q)_6U8&TNk(wwSk7O`gZSWFZfD~7I0}ec>dV>3-&4|Xq@2m1gE##a2edud_ z9*~b)Oe7@oW}RotpupzvBN|$7?G{2Y>v-cO0dwFmPfLtF`n0r+KtTJ`%C+{U#Ahu! z^y{qDD5*AxL;zp5z?>g9%mCHdP9^)MqKzgLDsq>z??2kYXg{nRzU^k7ffg)>UxxT5 z!l6apn7N(TLAjeUS~}$o9vQy&={eK-i7ATX%i%L_dA6lJF_+@{pI`s@sXcGO*ok@5 z(PR!OqWs+hSu%qT#|K7Yuv2Sk%UHU7Y*vFw@MI|tBe`G5?-u_R=krY6 z@>F<*88d_S^2C#svcdc+5}ylQm&`uLNt$(At0#>;uO`@7V-zK~wd-OL(sG!net2LE84>w!*@S*|D;8Lz=pS%z_TYMobZjZgiA z)9Pa8kCpdhI#a|ojFf`J?bKxUFF`02vdF?|K^I?SmKdO+0e2+K?OQFrXZzIab&6T976VRg&h z(w?i^ItXj{i37DxTgQ83nhmF2b{n95IKe~vGO|#zBAVfQ7Z{;K-vh_`?ba#I;hxib z)R>9UA`7c}TQWIG9X~y^*9=Nt9OItnLrlm_gmi#(e5IYT{b?E!1}b`c@rM0%HWOX$ zdfZF)yZ0ME7=HK_m6=p4NObIN{5Kw%61o-Il+3IbXkTZik|oyE4V0UF-{Kq5ew{32 zhDWa0Z1N|(b#)xCq3%z*%XE)IbF#pk=8dA%V*OvXiS<*@n-9}rSL9n)4?e;tTWdRv zZojP{9bNu1f1y60IjvP}wr%ID#*`eDt)CYq4KHi}=J8{YI}b~x+d#OJ?YX8;e<>01rD>ej3D`cw%` zum*EqW0JG@^t!>Im*|Np;6__kNcWqmy%eyo=nc1+XH$po0XS7N`^xi*01kKJ(B18f z(50RNGZ`1DTBE*+%kInaPJ=t&6BiQBw2=H)x1wXR6}*T;cT-B&sb+Py>jybIES8(< z#V{@1=?-(&CH(k@!f~Qg?T%iNw_I~*url%t9toYlHEl5U7nArD#aQ6ctp5?P!VqFS zW2=Y{`H+qj1mv})w{kSMIhPhPg;5g*my=;KOzv2x?{rUsb6qaYMk>H7QlGS(&=7Y6 zZ#gem%K65A3#a#~bUZUzS~3pb0AIrIhwXz$QSp+Qe#mf6kf#uCo<7#Q>h(|pb_;z& zNoiSuIAM5|Vyec4;Aoh*t8JU4v~>gV#Nr40Sj8msEhx+aeucLy+59AWfML+_LZYTy z?2W47(sdkHXO(4-Y-;%jthg-oeEBtAU~PX(G5K$HgZ|ySJH4Cz%d%)cKbVq32ls~f z#e>P0I)alp_CZ+w^VblZ;>5mX@jT9CBY*^kAl01bZ!hDJMic#P5Mn z5KoGWgfLD!ooeNaUG7+0cpK{)NYx44ZH3R*SvozLzuHrjIjmrcpR5V|5gck#_G&aF z>goISRXc>IL&zr9SQe|i z_yl&k-v#Q4AZ*Lh=fx>Q(%TtQUqi$Kpi1_ptnvvk(dAlDWRHgM#>~`QUOP_H%XE5S zO^G3%_0lAM)*z!*Z8%rr^IhUYMThF;k?G=4jrFm4KBbw{#KRGTv*zN;UG$l#;fr*S zo2TF~p+VR}uA&W)1WlHAZf-}Wcmv;O0c}$k5Z^Dp zaSWso>Q4L<@==*17T|Zm!B-!M>rjnE!K`a#^VQWCcON&tTV4uk`Sq+^-o$M2Q`VCg?%%(mT0Rsm!+;2N`&Nzhcv)Eb!(x`_i}jxn%H9lDYV*y>-jH3IQuj`-UsFTAWo$Bp=DsKMH0oDi zAJ=xjICE10LgS4PEg5$c!gXKz9=igF0qtx*w+o3vbr7t;SIXk~B|@S!~hG; z9=cdX26~#|)%UZ#Z;_yPrk#+xVxdGh;sSrSN36}~ok9tN>Z-9XFX8%SUY0k!(=<`L z9CLbH9sd5!>0zUPd?a6oT=g6tj?gz((tlyf$%fi*DdelDo~o zhbD`8sV@$ebpu}$xLTb1$DV$)0#$Utt{{`1a#mETzQUl{7}}f^?_F=0?;t&4tKF|n zVX+!jw&I2<^hP&^vhPa-1(;;)NHRODV*BU14xBO%=KUm~b81R3IB95+st%@Z#8w)Oe%JYiu9l2Z&hfrlz?A0LU*>w4U|RsfxJD$=BEuk#ZELyZ~kG8<_OE`mdY3k|A4& zph*7399s6ueWUdkeT#Ok6lAB;dZX5VjZ+j{l-}i*w%n1$i1O-85|p4B&zzqmiMA7wJaokwBv=VHWK167ZQCy>JYKnjT{F}@Ol1*lGlfdfWx zg6Uj-Sq>>M@?Q9YSz@OumMzVCryVM80aUBdqWIz}tRj!Ep5D+_KS=cRj&gY~sx%|s zEgewU9{gQ>U9t;ZaRYv4_`k~?i$3e*?-92IJ>_+ct3&4nWy%_r)m%`l!@65%ZHzaE zQ_nCxWke@Xh&91ZDic!Nb9EV7Hz43M{1PI1M4K42aU?-(U+gXP-N6?N9k-4bI(X3* z-OD&$f>(71ShA@yS^{k!d2f@?etj{ro69icnQzDahZUmr`@v_f_zZ?p)>H4HW@tn> zhrR25e9$H0&WS0ysLiHC!EO;@bqGL;-gaeO3*-6c=MK&p+}kq|PyhrDdmK`1>>4_k zskvXjSp_UHE+$B6<3C|(@DgUsCnOUIELXY6_qgkZA^^IYFK;GC68dt6^KCngUDBhg zwzT2Kyvm|JV(wW032KF8rnqU+7pCT|B+L$e^Z?D$zJpJEJ8RygGUvSza)p-*FPboU zbv*eXP-O& znM3Inh+H9|VL8i!cf{xO4Yw^Fmxii`c*33jC-YumEo8jmHcl1D6A}Kt^*3K@QstQo zgO`Wdn>dCQ8=*KGf%uN#k1uSE6k_(j^&BIvXEjJTQoQ9)+9D2Ofcq zQu%}GZJe6P~%MN>LE^E6SE#IBb4=p z=gO}e*xciPL;sC2jz|<5w^NYJhb8^)SlkX{x)!)u#llKmz4ObE)s$qzXj+x7QBuk$ zZ>R{xTBH{W-fC2`?zigW(J59B4hFzsXj=tq zqf$zCU47c}Dspb|BFa|+U%j)ZPrlsOrOq!c*;n13`^McBd)pFzFOdw?!kHO~5J?G! z(opSBCi(`a?2>(LZxpzFKNu^4)45i8Sd^yBzR=4FLLGFvyo7omm2zTQu^>4THAb|# zs&xHUk!d(8BwY8kgjGP_fnr@+a1n-FWbGP~F>TD+A2cbXWG;%?9C)20VEumVcq|^W zRul8)nmb9E%cK&xpEHTqMp;B2_|GL;x&&Rgvyz&4?k9i3uH0hw|#b0C>;fDdU0|)tHSIrJHvC+`cC>n`5q5;u)a4~rxQ5>jZ+U2{tHvz%y z4jZv89PnQpu$Si5Zhkgtw)xu9QX8rzoO>}(nD|+XmiIaJ>ho=H3h>#t;w05M{4Ac5* zGR%4%0LYeE5(z6^(F7s+IG>v$Ulf3pPN3AYF%f~)XF_Y;!fL5|Qyi0W6oH+3rdo}8 zUhb%U4nju3Q+twST&$b8H|StS;Rk^o&hlnjF`|**ohN(Z5iafnJz(ys8uI>&5KvMm zs;?4!xvwhqVs2xuwxec1*1NI%a4~&4r7NN&Iy0j(@k_N#(;IHpg5CT89tUvx zx8KjoSUmsqQqshxHvFC`E2(qwgtJ({gWN>bbJ9LlQuMi&`uxs0#m|8NS+q$AV$|+&n>{5nWS){!Y<6l83&F-NM=b3^-BzHD9rY-$z zhqVxHn-MTIy_qCAVIL_Nj6MbrEPjZ+o4EL{>&H}0TNOKkjQRTWRdtQdNemkDb4Ne5 zjPi-20Wn<*e2WYktvRm#n!l=}|GCA+-eHh)0aDhPL-i3Agi6;(&ODNTWb)`t>i*w8 zUp06t7pS9>KBu4li+wMcReZpHx;bQN|CW5ubLbTi{k}Vk)$xAOc$Sft;NjJOlEj}Y z?jE$u0#BqazfE;bH@BPMAW3+jRZ-Usf9Q=9vuq~ZQO2BKlrYAMXeUN}BYt#s^?S{% zB562Stl?(eRF!D{t1=fMg78Q5yyAr&JqXG-Qy*4-NwGXiL|XPj`+BLXJM5|!*unD8 zAX<3Jcw=_4LsX%rz+RgKuA!?7WL={@-C0c7$X2Mixcj8>-SLE%aUUy(VsT0;0>45_QB<#2w*ny z?lLe22U!js;B}F!wEH2#FAjoy5trne=|{(0qv{+=X$c`1uS;&HxoU@)L>YTKqTbi_ z=bR1Op`u`ry9f*DW+|xb&G$vy} z+zLVJkDVC0r1ujl zN>}@d+DD`0^a#s7u-QIgh==zVGn&|D5_qQEW>?v_2u3sUl~`{x3ng*#J2?J z-8<9ztK4FD(zb4v?P+T2l%@hly@xe_zMll%Ccw2&%i>5&@4IY4d89%yC|)5r61uCb>!@u7bHk zKHzEg0ph4<3P5@^96Q~3ZDB`z2MKV6v~oOD^qUp1>*h|q58%@;+2BP5mT?nD8llet zP?2op>U6?p* zUhKg!5(se-gCQ*5|MK5EbWWM%J%WS{l3dOg!CXX!JF}@k<%f53#2TN-c zoeD9s{b?h!B@fm!`LrhvlFUn~L%h1zk}#v7z!g>xT)NLh^?g`oKAyTdIMI`Z_kf)j z@H#4L$wV+;nix!rWXgHUB^ErYdrTFDV`tBH3U^bzVa_2@VQ>AbJmvPeXjU9Vl7 zIqV1;{|DV`zY{vwenvwZO5+v1>-Z4_Ll?ZJt(^mnD47>BPG}xsoLt6fpDlgvkw2xGIgi%)6?1{=t{HjW>C$V?Wq*~iLyh@AtF ze9W5kOvrs{W;`ee;=ot;Y8p(*(gdwyXa1PtUdf|_#{R6!QU^{f)fuopUHxG|FBSzz zun`7f;dkroCg7vV40zwVd8gh`+ewWKgi;M+$UxZP*s_0egf3B)8>(~pk?8J5^M@+n zV2Imr%1>s)Dsy6(K!f2&&OgJmKenWd=GVeGcA`s%K!jRaxkgss4T#{WyFL)Yjf*N} zd9CZrV=#rut;AeM%L>)+pA)5hW$x(hZfpc}xQui~RgZsC-L4EL5w~7YQ$u)XM2~Eh z`rzg!oN~mBw*dIZ9y~GVyvfo=a%wQm!Gc{K6t@cQy}v%d>Yg*UNZh&4VUIa!%QNp# zh9Q@9@b4#T_6luVY-@mDV$4qSz3{xYMuFYKkMlj$n6{Vf=eu#+48|r{pQI3!XgPGR zLUh5bhkj)H;*4jext6lmEoM_dI5MwIwUUE%b_*oKM`kKHe-u6uw9kq1FQi=x-^sLJ zan%yf9-A?5Zhm3?rl}cPL#-XI)b%De#G?mp@IE?ieF+(m$lyW4uje_y`Heqfd!v9t zlPLvsFAN5CtFsrizO-B4$4K#V4odL=5wBf53En~h7Gz4~& z&)n5YZLyPctg?GKs_KpfNvL|D(@JIy3B4vilUu_IEInUWk#T{H0DArm`@ zB$Y>n#R;HqFKSwMW%BObs*{Xd&GgT?1{KsN*XA3JAbK{z`8oWMs69?B5sT_Xd{t&E ztQ2Oq&Og$RsqtET>vLH5T=J1tBGEOp=?Cq!EEP`LX25}$80E7&ZuL{&gzkSC#q%S% z-mBlcO1k#AtEkdL$(Ryfjxx+joIAXLxOXVXeGjVa~sY$&C5}yB?-n3txWmk7weyz}ES<4d=NcK4#1H>lQWjp(R!IKyp14 zf9|3D{BK-IgTB-AN}HJnW9+1bMb{I8RuF=lIJd#?FSF$Kc{#Dm$bFvRNNoXrjnfX`meil_aZ*GWYLsgxgG{;d+Kg8 zx#_Rr#wRPkAfUcF=l-1bpJR2YbRBw>c zI$01eIdMr6#PbJ|nZN_m&Eh9x*clUPeVBAum)7cm)L4l#QdhbRgMY&AK

_8v1 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%0AZuyp*Z+WiWZ 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%0Dt|9TTkZlAek&#?-tqAU#E&{inlAFF9a7&NI;;| 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 VZXV%{;0EBw(#+;K!Suql{{jc5CQ<+Z literal 375035 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%0Adyv^458nhwg2y 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 diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.tsx index cfc6e8af97..4a5c1b9bff 100644 --- a/plugins/fossa/src/components/FossaPage/FossaPage.tsx +++ b/plugins/fossa/src/components/FossaPage/FossaPage.tsx @@ -22,6 +22,7 @@ import { import { Content, Header, + Link, Page, StatusError, StatusOK, @@ -63,6 +64,7 @@ const columns: TableColumn<FossaRow>[] = [ title: 'Name', field: 'resolved.name', highlight: true, + width: 'auto', render: ({ entity }) => ( <EntityRefLink entityRef={entity} defaultKind="Component" /> ), @@ -70,7 +72,6 @@ const columns: TableColumn<FossaRow>[] = [ { title: 'Owner', field: 'resolved.ownedByRelationsTitle', - highlight: true, render: ({ resolved }) => ( <EntityRefLinks entityRefs={resolved.ownedByRelations} @@ -146,6 +147,16 @@ const columns: TableColumn<FossaRow>[] = [ ); }, }, + { + sorting: false, + render: ({ resolved: { loading, details } }) => { + if (loading) { + return <Skeleton animation="pulse" />; + } + + return details && <Link to={details.projectUrl}>View in FOSSA</Link>; + }, + }, ]; const filters: TableFilter[] = [ From 776b92721fc769b7ed26436ceb0a8f9e9dd1525b Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Tue, 20 Apr 2021 17:10:48 +0200 Subject: [PATCH 119/462] Update changeset Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- .changeset/unlucky-starfishes-vanish.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.changeset/unlucky-starfishes-vanish.md b/.changeset/unlucky-starfishes-vanish.md index 90ee10a81a..3bb341bee9 100644 --- a/.changeset/unlucky-starfishes-vanish.md +++ b/.changeset/unlucky-starfishes-vanish.md @@ -3,19 +3,4 @@ --- Add a `FossaPage` that shows the license compliance status of all components in the catalog. -This is an optional component that can be registered as a route: - -```diff -// packages/app/src/App.tsx - -+ import { FossaPage } from '@backstage/plugin-fossa'; - -// ... - - const routes = ( - <FlatRoutes> - // ... -+ <Route path="/fossa" element={<FossaPage />} /> - </FlatRoutes> - ); -``` +See the projects `Readme` on how to use it. From e669a8013f9013e73bdae27cca29274ec99a6e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Tue, 20 Apr 2021 13:50:42 +0200 Subject: [PATCH 120/462] update the standalone frontend contribs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .github/styles/vocab.txt | 1 + contrib/docker/frontend-with-nginx/Dockerfile | 18 ------ .../Dockerfile.dockerbuild | 59 +++++++++++++++++++ .../frontend-with-nginx/Dockerfile.hostbuild | 41 +++++++++++++ contrib/docker/frontend-with-nginx/README.md | 16 +++++ .../docker/multi-stage-frontend/Dockerfile | 23 -------- contrib/docker/multi-stage-frontend/README.md | 19 ------ docs/deployment/docker.md | 2 +- 8 files changed, 118 insertions(+), 61 deletions(-) delete mode 100644 contrib/docker/frontend-with-nginx/Dockerfile create mode 100644 contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild create mode 100644 contrib/docker/frontend-with-nginx/Dockerfile.hostbuild create mode 100644 contrib/docker/frontend-with-nginx/README.md delete mode 100644 contrib/docker/multi-stage-frontend/Dockerfile delete mode 100644 contrib/docker/multi-stage-frontend/README.md diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 226af9bf0a..432cd19f25 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -16,6 +16,7 @@ Config Debounce Discoverability Dockerfile +dockerfiles Dockerize Docusaurus Env diff --git a/contrib/docker/frontend-with-nginx/Dockerfile b/contrib/docker/frontend-with-nginx/Dockerfile deleted file mode 100644 index a444c9de83..0000000000 --- a/contrib/docker/frontend-with-nginx/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM nginx:mainline - -# The purpose of this image is to serve the frontend app content separately. -# By default the Backstage backend uses the app-backend plugin to serve the -# app from the backend itself, but it may be desirable to move the frontend -# content serving to a separate deployment, in which case this image can be used. - -# This dockerfile requires the app to be built on the host first, as it -# simply copies in the build output into the image. - -RUN apt-get update && apt-get -y install jq && rm -rf /var/lib/apt/lists/* - -COPY packages/app/dist /usr/share/nginx/html -COPY docker/default.conf.template /etc/nginx/conf.d/default.conf.template -COPY docker/run.sh /usr/local/bin/run.sh -CMD run.sh - -ENV PORT 80 diff --git a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild new file mode 100644 index 0000000000..dda9779eb0 --- /dev/null +++ b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild @@ -0,0 +1,59 @@ +# The purpose of this image is to serve the frontend app content separately. +# By default the Backstage backend uses the app-backend plugin to serve the +# app from the backend itself, but it may be desirable to move the frontend +# content serving to a separate deployment, in which case this image can be +# used. + +# This dockerfile also performs the build first inside docker. This may come +# with a build time impact, but is sometimes desirable. If you want to run the +# build on the host instead, use the file simply named Dockerfile in this folder +# instead. + +# USAGE: +# +# - Copy this file and the "docker" folder from this directory to your project +# root +# +# - Update your .dockerignore, make sure that the source folders are not +# excluded, but do exclude node_modules and build artifacts: +# +# .git +# node_modules +# packages/*/dist +# packages/*/node_modules +# plugins/*/dist +# plugins/*/node_modules +# +# - Update the copy of this file to add configuration arguments to the "build" +# command, for example: +# +# RUN yarn workspace app build --config <config1> --config <config2> ... +# +# - In your project root, run: +# +# docker build -t backstage-frontend -f Dockerfile.dockerbuild . + + + +FROM node:14-buster AS build + +RUN mkdir /app +COPY . /app +WORKDIR /app + +RUN yarn install +RUN yarn workspace app build + + + +FROM nginx:mainline + +RUN apt-get update && apt-get -y install jq && rm -rf /var/lib/apt/lists/* + +COPY --from=build /app/packages/app/dist /usr/share/nginx/html +COPY docker/default.conf.template /etc/nginx/conf.d/default.conf.template +COPY docker/run.sh /usr/local/bin/run.sh + +CMD run.sh + +ENV PORT 80 diff --git a/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild b/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild new file mode 100644 index 0000000000..6e5912dd67 --- /dev/null +++ b/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild @@ -0,0 +1,41 @@ +# The purpose of this image is to serve the frontend app content separately. +# By default the Backstage backend uses the app-backend plugin to serve the +# app from the backend itself, but it may be desirable to move the frontend +# content serving to a separate deployment, in which case this image can be +# used. + +# This dockerfile requires the app to be built on the host first, as it +# simply copies in the build output into the image. If you want to also perform +# the build itself inside docker, use Dockerfile.build in this folder instead. + + +# USAGE: +# +# - Copy this file and the "docker" folder from this directory to your project +# root +# +# - Add the following line to your .dockerignore to make sure that the built +# frontend actually can be transferred into the docker image: +# +# !packages/app/dist +# +# - In your project root, run: +# +# yarn install +# yarn tsc +# yarn build --config <config1> --config <config2> ... +# docker build -t backstage-frontend -f Dockerfile.hostbuild . + + + +FROM nginx:mainline + +RUN apt-get update && apt-get -y install jq && rm -rf /var/lib/apt/lists/* + +COPY packages/app/dist /usr/share/nginx/html +COPY docker/default.conf.template /etc/nginx/conf.d/default.conf.template +COPY docker/run.sh /usr/local/bin/run.sh + +CMD run.sh + +ENV PORT 80 diff --git a/contrib/docker/frontend-with-nginx/README.md b/contrib/docker/frontend-with-nginx/README.md new file mode 100644 index 0000000000..eae70b8bba --- /dev/null +++ b/contrib/docker/frontend-with-nginx/README.md @@ -0,0 +1,16 @@ +# Frontend with NGINX + +This folder contains Docker images that let you run the Backstage frontend as +a separate image, rather than having it served through the `app-backend` plugin +from the backend. + +Note that when running the frontend like this, the app configuration becomes +embedded into the actual static JavaScript files at build time. This means that +you will have to supply the list of configuration files as part of the command +line at build. + +## Usage + +There are two variants: one that builds inside Docker, and one that builds on +the host. See the comments at the top of the individual dockerfiles for usage +instructions. diff --git a/contrib/docker/multi-stage-frontend/Dockerfile b/contrib/docker/multi-stage-frontend/Dockerfile deleted file mode 100644 index 3190687c52..0000000000 --- a/contrib/docker/multi-stage-frontend/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM node:12-buster AS build - -RUN mkdir /app -COPY . /app -WORKDIR /app - -RUN yarn install -RUN yarn workspace example-app build - -# Contruct backstage-frontend image -FROM nginx:mainline - -RUN apt-get update && apt-get -y install jq && rm -rf /var/lib/apt/lists/* - -# Copy from build stage -COPY --from=build /app/packages/app/dist /usr/share/nginx/html - -COPY docker/default.conf.template /etc/nginx/conf.d/default.conf.template -COPY docker/run.sh /usr/local/bin/run.sh - -CMD run.sh - -ENV PORT 80 diff --git a/contrib/docker/multi-stage-frontend/README.md b/contrib/docker/multi-stage-frontend/README.md deleted file mode 100644 index b6ae4fdc6c..0000000000 --- a/contrib/docker/multi-stage-frontend/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Standalone Dockerfile for frontend - -This directory contains the resources which will help you build backstage without any requirements -other than docker itself. It uses a multi-stage Dockerfile to build and ship backstage. - -## Usage - -You can simply run the following command to build backstage. - -``` -# Make sure you are in the root directory of backstage then run -docker build -t backstage-frontend -f ./contrib/docker/multi-stage-frontend/Dockerfile . -``` - -After a successful build, You can simply run backstage frontend with the following command. - -``` -docker run -it --rm -p 3080:80 backstage-frontend -``` diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index ef178b2977..383cf0615a 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -232,7 +232,7 @@ package, which is done as follows: Once the `app-backend` is removed from the backend, you can use your favorite static file serving method for serving the frontend. An example of how to set up an NGINX image is available in the -[contrib folder in the main repo](https://github.com/backstage/backstage/blob/master/contrib/docker/frontend-with-nginx/Dockerfile) +[contrib folder in the main repo](https://github.com/backstage/backstage/blob/master/contrib/docker/frontend-with-nginx) Note that if you're building a separate docker build of the frontend you probably need to adjust `.dockerignore` appropriately. Most likely by making From f6b8cf96cacda208834e593835eda06a3906d05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Tue, 20 Apr 2021 19:43:39 +0200 Subject: [PATCH 121/462] fix according to designer input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- packages/theme/src/themes.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index b6810d9a84..94cf38656e 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -102,7 +102,8 @@ export const darkTheme = createTheme({ }, }, primary: { - main: '#8CB4E5', + main: '#9CC9FF', + dark: '#82BAFD', }, secondary: { main: '#FF88B2', @@ -111,7 +112,7 @@ export const darkTheme = createTheme({ info: '#2E77D0', error: '#E22134', text: '#FFFFFF', - link: '#FDFB9F', + link: '#000000', }, border: '#E6E6E6', textContrast: '#FFFFFF', @@ -124,8 +125,8 @@ export const darkTheme = createTheme({ errorText: '#CA001B', infoText: '#004e8a', warningText: '#000000', - linkHover: '#FFED51', - link: '#FDFB9F', + linkHover: '#82BAFD', + link: '#9CC9FF', gold: yellow.A700, navigation: { background: '#424242', From 4792df9e789dd28ba0d45cae1833565e06753b3b Mon Sep 17 00:00:00 2001 From: Rian Bogle <rian.bogle@ncendo.com> Date: Sat, 20 Feb 2021 09:58:51 -0700 Subject: [PATCH 122/462] AWS Fargate and Aurora MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .github/styles/vocab.txt | 1 + docs/deployment/fargate.md | 21 +++++++++++++++++++++ docs/deployment/helm.md | 4 +--- microsite/sidebars.json | 3 ++- 4 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 docs/deployment/fargate.md diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 7d0f36d858..4f3377de92 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -21,6 +21,7 @@ Dockerize Docusaurus Env Expedia +Fargate Figma Firekube Fiverr diff --git a/docs/deployment/fargate.md b/docs/deployment/fargate.md new file mode 100644 index 0000000000..eff8a7d570 --- /dev/null +++ b/docs/deployment/fargate.md @@ -0,0 +1,21 @@ +--- +id: fargate +title: Deploying with AWS Fargate and Aurora +sidebar_label: AWS +description: How to deploy Backstage on AWS Fargate and Aurora +--- + +There are any number of ways to deploy backstage containers on AWS. One of the +simplest from a management and ops perspective is to leverage AWS Fargate and +Aurora PostgreSQL, where both the container orchestration and database clusters +are AWS managed services. + +However, to use them properly there are a large number of supporting resources +(VPCs, Security Groups, Load Balancers, Certificate, etc) required. One approach +is to use [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/) to +simplify and automate the creation of the entire infrastructure stack along with +automating the build and deploy of the container. + +Check out the [Backstage On AWS](https://github.com/rbogle/backstage-on-aws) +repository, for a ready to use CDK application for deploying your custom +Backstage app onto AWS ECS Fargate and Aurora. diff --git a/docs/deployment/helm.md b/docs/deployment/helm.md index fd36aeb81f..cbfcb1bc57 100644 --- a/docs/deployment/helm.md +++ b/docs/deployment/helm.md @@ -1,12 +1,10 @@ --- id: helm -title: Deploying Backstage with Helm +title: Deploying with Helm description: How to deploy Backstage with Helm and Kubernetes sidebar_label: Helm --- -# Helm charts - An example Backstage app can be deployed in Kubernetes using the [Backstage Helm charts](https://github.com/backstage/backstage/tree/master/contrib/chart/backstage). diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 1ab242ba2d..ab7e530479 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -206,7 +206,8 @@ "deployment/docker", "deployment/k8s", "deployment/helm", - "deployment/heroku" + "deployment/heroku", + "deployment/fargate" ], "Designing for Backstage": [ "dls/design", From d367f63b53943462f458e8c8178b77b0d63215d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Mar 2021 08:26:26 +0000 Subject: [PATCH 123/462] chore(deps): bump helmet from 4.0.0 to 4.4.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [helmet](https://github.com/helmetjs/helmet) from 4.0.0 to 4.4.1. - [Release notes](https://github.com/helmetjs/helmet/releases) - [Changelog](https://github.com/helmetjs/helmet/blob/main/CHANGELOG.md) - [Commits](https://github.com/helmetjs/helmet/compare/v4.0.0...v4.4.1) Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/grumpy-games-shop.md | 5 +++++ .../src/service/lib/ServiceBuilderImpl.ts | 11 ++--------- yarn.lock | 6 +++--- 3 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 .changeset/grumpy-games-shop.md diff --git a/.changeset/grumpy-games-shop.md b/.changeset/grumpy-games-shop.md new file mode 100644 index 0000000000..7426786f89 --- /dev/null +++ b/.changeset/grumpy-games-shop.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +remove use of deprecated type HelmetOptions diff --git a/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts b/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts index 07da975184..c17545779a 100644 --- a/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts +++ b/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts @@ -18,7 +18,7 @@ import { Config } from '@backstage/config'; import compression from 'compression'; import cors from 'cors'; import express, { Router } from 'express'; -import helmet, { HelmetOptions } from 'helmet'; +import helmet from 'helmet'; import * as http from 'http'; import stoppable from 'stoppable'; import { Logger } from 'winston'; @@ -195,14 +195,7 @@ export class ServiceBuilderImpl implements ServiceBuilder { }); } - private getOptions(): { - port: number; - host: string; - logger: Logger; - corsOptions?: cors.CorsOptions; - httpsSettings?: HttpsSettings; - helmetOptions: HelmetOptions; - } { + private getOptions() { return { port: this.port ?? DEFAULT_PORT, host: this.host ?? DEFAULT_HOST, diff --git a/yarn.lock b/yarn.lock index 370f3f5a7f..6cc6ab938d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14929,9 +14929,9 @@ headers-utils@^1.2.0: integrity sha512-4/BMXcWrJErw7JpM87gF8MNEXcIMLzepYZjNRv/P9ctgupl2Ywa3u1PgHtNhSRq84bHH9Ndlkdy7bSi+bZ9I9A== helmet@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/helmet/-/helmet-4.0.0.tgz#34c187894ed001834f997c688f2b2df19846b193" - integrity sha512-HyoRKKHhWhO6+EBfgRLkuZR4/+NXc1nJB7x0bWwW89i9eoPciK0qUqyZNOA/zowpgrW9C4+J5toqMkZrpBOlkg== + version "4.4.1" + resolved "https://registry.npmjs.org/helmet/-/helmet-4.4.1.tgz#a17e1444d81d7a83ddc6e6f9bc6e2055b994efe7" + integrity sha512-G8tp0wUMI7i8wkMk2xLcEvESg5PiCitFMYgGRc/PwULB0RVhTP5GFdxOwvJwp9XVha8CuS8mnhmE8I/8dx/pbw== hex-color-regex@^1.1.0: version "1.1.0" From c713442c3030717184d9d51900ec6a775a56a44c Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Tue, 20 Apr 2021 14:16:13 -0600 Subject: [PATCH 124/462] Datadog RUM minor doc cleanup Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- docs/integrations/datadog-rum/installation.md | 28 +++++++++++-------- microsite/sidebars.json | 5 ++++ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/integrations/datadog-rum/installation.md b/docs/integrations/datadog-rum/installation.md index 50ebe722be..f96298a33b 100644 --- a/docs/integrations/datadog-rum/installation.md +++ b/docs/integrations/datadog-rum/installation.md @@ -3,28 +3,32 @@ id: installation title: Datadog RUM Installation sidebar_label: Installation # prettier-ignore -description: Adding Datadog RUM to Your App +description: Adding Datadog Real User Monitoring (RUM) to Your App --- -There is a basic [Datadog](https://docs.datadoghq.com/real_user_monitoring/) +Datadog Real User Monitoring (RUM) allows you to visualize and analyze the +real-time performance and user journeys of your application's individual users. +This is an option to profile and monitor the user experience of your Backstage +installation. + +There is a basic [Datadog RUM](https://docs.datadoghq.com/real_user_monitoring/) integration built into Backstage. You can enable it by adding the following to -your app configuration: +your `app-config.yaml`: ```yaml app: datadogRum: clientToken: '123456789' applicationId: qwerty - # site: # datadoghq.eu default = datadoghq.com - # env: # optional + # site: datadoghq.eu + # env: 'staging' ``` -Replace the clientToken and applicationId with the ones generated for you -Datadog. +The `clientToken` and `applicationId` are generated from the Datadog RUM page +following +[these instructions](https://docs.datadoghq.com/real_user_monitoring/browser/). -optional arguments: +There are two optional arguments: -``` -site: datadoghq.eu # default equals datadoghq.com -env: dev # allow to specify the environment -``` +- `site`: The Datadog site of your organization; defaults to `datadoghq.com` +- `env`: The application environment for Datadog events (no default) diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 1ab242ba2d..e2a57bd426 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -109,6 +109,11 @@ "integrations/bitbucket/discovery" ] }, + { + "type": "subcategory", + "label": "Datadog", + "ids": ["integrations/datadog-rum/installation"] + }, { "type": "subcategory", "label": "GitHub", From 68f3e891b8947f91b5f3d101d60a915fad8691df Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Tue, 20 Apr 2021 14:36:19 -0600 Subject: [PATCH 125/462] Move Fargate doc to contrib Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- .../docs/tutorials/aws-fargate-deployment.md | 7 +------ docs/deployment/index.md | 4 +++- microsite/sidebars.json | 3 +-- 3 files changed, 5 insertions(+), 9 deletions(-) rename docs/deployment/fargate.md => contrib/docs/tutorials/aws-fargate-deployment.md (84%) diff --git a/docs/deployment/fargate.md b/contrib/docs/tutorials/aws-fargate-deployment.md similarity index 84% rename from docs/deployment/fargate.md rename to contrib/docs/tutorials/aws-fargate-deployment.md index eff8a7d570..bc530441c6 100644 --- a/docs/deployment/fargate.md +++ b/contrib/docs/tutorials/aws-fargate-deployment.md @@ -1,9 +1,4 @@ ---- -id: fargate -title: Deploying with AWS Fargate and Aurora -sidebar_label: AWS -description: How to deploy Backstage on AWS Fargate and Aurora ---- +# Deploying Backstage with AWS Fargate and Aurora There are any number of ways to deploy backstage containers on AWS. One of the simplest from a management and ops perspective is to leverage AWS Fargate and diff --git a/docs/deployment/index.md b/docs/deployment/index.md index db4ceca6f1..86ad03d1ae 100644 --- a/docs/deployment/index.md +++ b/docs/deployment/index.md @@ -30,7 +30,9 @@ There is also an example of deploying on [Heroku](heroku.md), which only requires the first two steps. An example of deploying Backstage with a [Helm chart](helm.md), a common pattern -in AWS, is also available. +in AWS, is also available. There is also a contrib guide to deploying Backstage +with +[AWS Fargate and Aurora PostgreSQL](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-fargate-deployment.md) Please consider contributing other deployment guides if you get Backstage set up on common infrastructure, it would be a great benefit to the community. diff --git a/microsite/sidebars.json b/microsite/sidebars.json index ab7e530479..1ab242ba2d 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -206,8 +206,7 @@ "deployment/docker", "deployment/k8s", "deployment/helm", - "deployment/heroku", - "deployment/fargate" + "deployment/heroku" ], "Designing for Backstage": [ "dls/design", From 29a7e4be8538f6d6bc909586cbf4db338a270d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=A9dney=20Yuri=20Lima?= <wedneyyuri@gmail.com> Date: Tue, 20 Apr 2021 19:45:18 -0300 Subject: [PATCH 126/462] allow import from HTTP repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wédney Yuri Lima <wedneyyuri@gmail.com> --- .changeset/giant-onions-obey.md | 5 +++++ .../StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx | 4 +++- .../src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .changeset/giant-onions-obey.md diff --git a/.changeset/giant-onions-obey.md b/.changeset/giant-onions-obey.md new file mode 100644 index 0000000000..fbf9faa0a3 --- /dev/null +++ b/.changeset/giant-onions-obey.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-import': patch +--- + +allow import from HTTP repositories diff --git a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx index bfb2434926..3e918db419 100644 --- a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx +++ b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.test.tsx @@ -127,7 +127,9 @@ describe('<StepInitAnalyzeUrl />', () => { expect(catalogImportApi.analyzeUrl).toBeCalledTimes(0); expect(onAnalysisFn).toBeCalledTimes(0); expect(errorApi.post).toBeCalledTimes(0); - expect(getByText('Must start with https://.')).toBeInTheDocument(); + expect( + getByText('Must start with http:// or https://.'), + ).toBeInTheDocument(); }); it('should analyze single location', async () => { diff --git a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx index a33fe388d8..49bd776db5 100644 --- a/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx +++ b/plugins/catalog-import/src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.tsx @@ -132,8 +132,8 @@ export const StepInitAnalyzeUrl = ({ validate: { httpsValidator: (value: any) => (typeof value === 'string' && - value.match(/^https:\/\//) !== null) || - 'Must start with https://.', + value.match(/^http[s]?:\/\//) !== null) || + 'Must start with http:// or https://.', }, })} required From fa1d892930def809a35735231513565c8dab85eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Apr 2021 04:05:50 +0000 Subject: [PATCH 127/462] chore(deps-dev): bump @types/morgan from 1.9.1 to 1.9.2 Bumps [@types/morgan](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/morgan) from 1.9.1 to 1.9.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/morgan) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 85d67f4ed8..e0ab932286 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6281,9 +6281,9 @@ "@types/node" "*" "@types/morgan@^1.9.0": - version "1.9.1" - resolved "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.1.tgz#6457872df95647c1dbc6b3741e8146b71ece74bf" - integrity sha512-2j5IKrgJpEP6xw/uiVb2Xfga0W0sSVD9JP9t7EZLvpBENdB0OKgcnoKS8IsjNeNnZ/86robdZ61Orl0QCFGOXg== + version "1.9.2" + resolved "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.2.tgz#450f958a4d3fb0694a3ba012b09c8106f9a2885e" + integrity sha512-edtGMEdit146JwwIeyQeHHg9yID4WSolQPxpEorHmN3KuytuCHyn2ELNr5Uxy8SerniFbbkmgKMrGM933am5BQ== dependencies: "@types/node" "*" From d56c915b4389379a85ff302f9187f0681895e8c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Apr 2021 04:08:51 +0000 Subject: [PATCH 128/462] chore(deps): bump @types/yup from 0.29.8 to 0.29.11 Bumps [@types/yup](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/yup) from 0.29.8 to 0.29.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/yup) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 85d67f4ed8..e0d58b2bd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6933,9 +6933,9 @@ integrity sha512-/emrKCfQMQmFCqRqqBJ0JueHBT06jBRM3e8OgnvDUcvuExONujIk2hFA5dNsN9Nt41ljGVDdChvCydATZ+KOZw== "@types/yup@^0.29.8": - version "0.29.8" - resolved "https://registry.npmjs.org/@types/yup/-/yup-0.29.8.tgz#83db15735987db9fe5a38772a0fb9500e3c5bf39" - integrity sha512-MBSp62AjB1KrSOI3gX9GekddXU5YYQAVA93+aSl78biBqoSzxg876aQY2KJK5Gnfbpqq7O2cadVX5kPAtBqIXw== + version "0.29.11" + resolved "https://registry.npmjs.org/@types/yup/-/yup-0.29.11.tgz#d654a112973f5e004bf8438122bd7e56a8e5cd7e" + integrity sha512-9cwk3c87qQKZrT251EDoibiYRILjCmxBvvcb4meofCmx1vdnNcR9gyildy5vOHASpOKMsn42CugxUvcwK5eu1g== "@types/zen-observable@^0.8.0": version "0.8.2" From 4d3cbd860131e0e9eedd5ba1696d72568c2b6efc Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Wed, 21 Apr 2021 09:12:39 +0200 Subject: [PATCH 129/462] Update test Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- plugins/fossa/package.json | 1 - plugins/fossa/src/components/getProjectName.test.ts | 9 ++------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 39da3638ec..2f656c476a 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -52,7 +52,6 @@ "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", - "@testing-library/react-hooks": "^3.4.2", "@testing-library/user-event": "^12.0.7", "@types/jest": "^26.0.7", "@types/node": "^14.14.32", diff --git a/plugins/fossa/src/components/getProjectName.test.ts b/plugins/fossa/src/components/getProjectName.test.ts index 461cb18ed7..93f5187890 100644 --- a/plugins/fossa/src/components/getProjectName.test.ts +++ b/plugins/fossa/src/components/getProjectName.test.ts @@ -15,7 +15,6 @@ */ import { Entity } from '@backstage/catalog-model'; -import { renderHook } from '@testing-library/react-hooks'; import { getProjectName } from './getProjectName'; describe('getProjectName', () => { @@ -31,9 +30,7 @@ describe('getProjectName', () => { }, }; - const { result } = renderHook(() => getProjectName(entity)); - - expect(result.current).toBe('test'); + expect(getProjectName(entity)).toBe('test'); }); it('should return undefined', async () => { @@ -45,8 +42,6 @@ describe('getProjectName', () => { }, }; - const { result } = renderHook(() => getProjectName(entity)); - - expect(result.current).toBeUndefined(); + expect(getProjectName(entity)).toBeUndefined(); }); }); From 5f41b3e09fae8cfd73c6238a0122fb926f8c7306 Mon Sep 17 00:00:00 2001 From: ImgBotApp <ImgBotHelp@gmail.com> Date: Wed, 21 Apr 2021 08:23:28 +0000 Subject: [PATCH 130/462] [ImgBot] Optimize images /plugins/fossa/docs/fossa-overview.png -- 329.99kb -> 182.82kb (44.6%) Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com> --- plugins/fossa/docs/fossa-overview.png | Bin 337907 -> 187210 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/plugins/fossa/docs/fossa-overview.png b/plugins/fossa/docs/fossa-overview.png index 6298fb95573dea5f3121ade63e2e8814f84d2b98..3e9482ab55d15288e982eda06420b05f8cb404c8 100644 GIT binary patch literal 187210 zcmb@u2{=^!|Nq}|7nLlHEM*-GB0|Pam<eS_N@UBf46=l=cHf9Gwn3Q2a+?Yj+4rp& z`<BRVWGDN+^M6nG{rUX9zyJ0BU;pd+UH_}=nsa75=gjGx_xtsHKAtbwdpa5y&tExz z;>3xITAGOaCr+GmJ#pepH0>$yitFvNKf&S;J5`kGi4%EI7Y;1Wfag3`n)gvBPI$vk zoOl^@;=~?!>E-N+6EAL@IPvSri4*dPCr+?FPb$|_1aF+RysLpYaZLU9cU49#_~Z#K zgz5vY!G&bc=N!nrnjDijtydx@J3h~!a3{L$4X|Am<ui`C-drntr$bN9`TpbguSM;M zNp2k)9lK4dkx6ntn@oN-jr|P$Jjz|wy|3e0qckE_@X567p}w=<FSk!4uRC9QP%zWG z?f%muZ>!_cQP-8yJ)5`s*Q~s!Fauj$^_6HJ-GC{Z#x1cSO2N3{P4NLP{kGPqx%Z== zh-34XRk+Hv{uiyq+gY+6$#=~BwR0@NgLwSh{<c7?`CW+|Sp(@DS@^@<Qst4d1GZu# z%!2%2ES*n))Ny%?XT`6b&1-H`dGpK#jasAYf3<T;S&a>UzUB1jo3^J^MnPAeuGuTd zyp-j%`x#gHt8NviVEe=jPucC})^3ISZv;yoa9=W1%JOdhyJ+1*I9bJhv2rx7LuSA_ z7Ns+DFw_z=wkblNW$b_JFzobv{DpPiKYvWrO@&B5Ld|7%&Y?wrIldX`%YW`>w>sSs zbKSI_sDLYRU&VZ#jvT*kdI9daf*G6cI73tjlkxmGxl0^mby`ZQ`H<YXF5}rY+Ee|+ zE#yv0NuJ-)bR_1gBjzZ53v+d7#_^eFi{45VzlH@YilD)TohiFIn5gKfezh&kt-~AM zE$3<F-mzDVx%&3n?(Al^wz9XMNV6Nfu-#}B4nEbak>mWHuu-u8*j~K3AbYviRnJ^1 zwpr?%@5Wv)se1ZtZ%NB~)(f<GPoMTacs}5F9qHGO^t;aA`8c7;P<JisMX~m@XogA8 z(9KUd?=wrZqWh#jb=Fd7;TL>}=Y9B)Rj6xae+%C4AA0bOujxz`{;w2G3ulDDOk*v0 za$v|d4PNjUO&Xnuwj--)r!Zakn#6sfGc?$?p>{2)kJH-K%#(4NJ@1~G=M8a|n3-WQ z_>4zc>q#*h&5lL-DUUO2<*!|J?5vzTg)$2CqLY<dwU?h1JeNPxQOJI)8k6zj=A=7Z zXWl-MG9X*^7H?bK>6DXEbwhU<-R6|j>CvM9c5|TD^W1u2<f{)|dwdF4CgnsPds=JM z_1KdH!KzGAmH)Fs<qGO!iY+GfayB34{@u+|&4K=V1Bu@TyT<Ns%E{-RCB9X2(4grJ zKbQTm`R$dy@blT6KkQrIo_4q`{dw2wd4wXkcG@S^Pkpk0xxLfp8Ym5G=DYgntFPvh z&8CKjG&BaS>#7$;2)_5~?!+)WGkI~Zt_2_Q>A_m)tJgHrpRe$?)T#2d1!Nk3omA<` z{<#ibUXvqv$i)(NL&`7nJxgH7G3V`^l#xhe$SSaD939m>@>`UI9anp>x6$-oKlWS9 zKb((mT|bh(yPacP9ngMXdHGQV`uNTJnjF*gnByGVX8)qrqa53FsUbha4r|^B?EesZ z*j)E9f$o#3eAeUW?QA1?aOp2UV_qNkbBL$^WJb5{|M2dshvHlYRfv@B?8oFuzfUY* z6|=los~_TC8HmTvq`gLSJ$~A{Z*ZOKahZMUwGeQVT!I}J=LbzzePTH*&bLneh`ff$ z3A2PPKh)D+i*AXjx)v5-Yy|DBk-(K}8;fiiUL~iz@AZi0=uLl~{7%qV$<^>`b>VzM zS38GXmSgI>sN<ZLsBMbXa`*mz2<q{s$R*=1FTw@}Cv9$-VNAH?vKBd;Ot?qmIcX&O ztfC%a{JHlZHs+Xvw+5J>RUKPz+%0aj-7K2)IP=w@ZF17q;eyb7Y=WEo={4mH5k{49 zW1(nN4P>L&gK?61t9W2Qvm+|E`$Ot?0|l62x%pzg>D`&*2KlUlT`bzWn@HI>99lN0 zUU|89nWp!%>=*gd$jF@mp^T%SUw-A`^VN+%<_|t|D?hcH*Q7UZJmZKKr+i1!=c7a^ z!=`9QNb}c8>PR5t`Mq%++}|FFbKAeBF;|-n@&mzmpwPtBNxbDTJ7L^_ad#*^XB|>) zy1v>`Rpb)hF~XKyk><G6V1K}4RF+y$9f7_GaXa0|<L5h3%9~>6Y_H($H-r|6Revvd zwQ;Ab&$VZ-cfc>(+T5#W&%iZv!@2;h^peQEx%J4%<qOSBqgVbCU2KNqHw>K48rLD> zx2>Zzy&d#5>8rGhu{T*a9&0ejyjL24#lWhi`89k4Y4ZyOhscDy6>SFxO{uvtD}K2g z1<lkDG|R};uvq?Ux~Z-RD?00l6!dxZvXQjm&riS&>o2r<(s;SiPD#8bwR<#n<WO1L z&Ud1JKyxd2AUUF2{*s*Wps{fSLOK8Kp9>eF7VMjxbgePYj_ebdXB96HWx|Vd4fsi6 z&du1z9~*;PCyeW!Jhk*>)3L4=^g(=&Me)jIWm`a7eacb%>rr2KRAoZlTlROVb6wgs z!BIx;oYgCfa)w+r;6^)M1V5SQ+V*O@<>AM`+1^|x>!&KGHhO!X|9JlUtPLSt4UOww zWBn}Z?&PB4Hdh@j)fK@#CqeQ!Gr&rpW3Ed7I%VNZ$oxSHY@r$Ma$G*O-<@rN0(;L# z@hdfhyJ;xO>Eb7d5hd0UI@g>Y&B1^C8HS&to<nd_sAt?jAYZ>mcD1IV<kjT2)?T>F z>OF9n^bUcUgN-HF%ed{l;#ZTQ&Wx{p912S9o&WQmv2k4tZ*OljM+_zFvQ(4-KM^UJ zAW$5h_r7sMi~{?~N=UJm-EF)e*L3tNfs>dh5@~Z)OLssuw}AP1?1wo_yvsnIn9nO= zlUKQ~z*8NUGqvKMZzZ-~hWhIrDGJXDV>6YDXf;#PO#aM$z2wb`fWa}ZzE32Td{EL) ztT|aX^Fhj2juvOT7q_WK-<fCkS+!$>D<!RoDWzVshB|PXyhD2(hAFk;0s?QSr^{5$ zp+?0IKfhn!{$vU(I~sWr0LHqmv3xA*vi{&R>VUnC2-|yu%f1Mey1Q_3fTv@$$Ly5k z2u!kVTrJ4v-BmJ}_i(D|Lx^}Ivf=G;)bKFxB-7Y*)EsYy(87$|<|Th7^!cIbKSdXW zvzyj&&-G;=m7)sQac;8lE^wKdpMJi9_Ni`{h7d!FZydbft3nDHn(Sn#LR9D`T~t#6 zwtx}N<aCjjXirQTKuGci8iwX#gK3Ggq|T_|X3<jw?UMzedEr%f_B=*HFi))T6BeIu zDQL#^^1w4ZorpxFg|0`4`*dJZ$V#Xtcayp-GFO;RjZ5!41TOJa+<V{m*OFV(<o5II z(GcO9rcSie9q)Wq>*+#r?>9JsYc2F<9pU=$6<4J?Sgq|H8sfRK*<=()a4z;OBOLDp zVdrAfNoUQ+@-cDg_3K~4+d&v^dm$`zKOmZ5Ty(U^6b(gM3kZW+KY5InC~HC%mej|i zCgqT0e<-M(BsOi-j^^+LdY!0+aq)~Z6V9=d51HT+d8&nOVb9ghx~K%9h8Zj%i&9^C z=+*nl7GM)}7Le_1{KhFb6B^>E2u;$C%EjIdQXId>l%c7GNI?zLj4=f(y}!guEM?$f z#!!#y8dE;@Nruo92*JN|ZJf9FrbE5<yURXbZ1F1NN<3G5WNlqI>!e$J7BD+pKBj}2 zH33T*Ps|@39W82G4{p-++2@7NvwhYp9lCp5rdBCEY1Ht7R-sg<R@Jg|&Rf3PO?+7; z+dEg>q!HC5xs^AZHtN^h`}x2ysA5Sn)Ff))xGH(~0<<sWETeMN;$p<#b~%DY(&?iZ zpC*b$l|2Nzf_dg9?+X8_-JI0_;KlPNo8MZHFWKL8uKaUxrsn$_ZeH>-t$h9HMqlfG zKR1V=l9-8dSrM$F%EDIEq^D0Yz>UU&eX$_c_WTve@V9rI?N}6qJncu=ivo$`DFX`m z!)XoSd*6o!$U?20*S2dNNw}wWj6-Z(dhb(5`dad^*>q8v-&r?{I9~U|)<WD=95|Dr zRnZn0#8dO0A&ykh!2Y(C(6#Ct)eb>d8)4!~b)vQE?^#!HE!`cmw+;QfdYinPgztZg z9^-uI?J&VcBBx0Qn()nMU$>%V40);1Gdporqc2t0aocZoWw$nGbSuLs3HpTbDm#}R z#jZpqx>+LhB3+cw@*LddT0ZJQl2I?e4_TP=rr`9u>5ndBYqCUI!6z)&$D{2SlYR0v z-Wh3ff7EV)!D#DmN2)%UbwoqK@&3C+J($fN8T&Z4U?OLdQ6d#80(SDATd(3TE6B(J z*NeaFg<)(6*~@#QeWHS~HjHBrX18<9Zo^u6YCn8C{%k8upbMnUxWg?-|4H_&UWx9l z5W2wGVSP9gW0)dX8R|#K@&;yp1LqP+=b1?{9wJ}51zkgv)SY|7*td$jjM2?oDfL5^ zKopcV1>NIsBTcRb1wLq|lOZf*&AwhRAAPsv(3Le6Gg%cw_m-e+G$JxLTe~sBO@Ku< z_h1CZ<_G2OdJYr`y3R>dfzr02&Q8(yFh+l2Y+YoAr;nbv;4^J1xwHmOj9yyN@uLFk z=L4rEUPytee_vo(zbMpmYvV2#yNQ(8eGh~~dyl=JndnUi)Aa+?V$i)HC*<oS{^Rje zxu^%85-m!&m~(PSi8L^tXv2)v6WQS|Vzsc2%X!#DJNy`v0Krp45<T8UOZ2)4?$3x^ zYylJ81zrm)Zz9LgN-;%#U-)TI=xX5{)Er#Jl=yI`-e~^K1@Hbg?J{G$ts3;a)PzBt zof`C#Ex!3uCp7h3RMQRI8J095Pq8(>m;)RJi%L_xAd9?OkQorbIa%<r!A@*!<^pTY zRrL~RyJD2ADVa|a4Nb*x;hQUU@t#5-t!K^oK@Cjf2Co&*FUyXP!KtZr;bdIsYGLy7 z%<ORdBz}(``3iNw$HP2=foS!v!R~N`(d<s%>#>9cCz0OD=rzICc2D?)KqpZAMqNZ9 z7oleuhyXqEx-+<FXX}YO3PC7$cOkIb=12;HlGc=qt^4@85?iT`w}4dnK(stIU}|vu z7;}JweZ97+h*Q*c3X5^&h<ve&evkM7rNGO_*HcsV)@!sKP4`U^Zvl%`Co`?FeUr1r zudoUgumMO}k9YWXYHR(zmT?aMs6u`?VLq{N71y}==S9-7aubF)Sie;D`Q_>g!T%>_ zM_c8Dce!-X5nH43r)($myM-_1Q-LC35zFlx=`wyTdrH^t3}gK6_fiK1xQYCS_iq-i z;Jk^`Mzg%r_LF{LE|*CWs@gkDc`2*Hr*bS5#x>Bof6Cxp!^|qNqQuMvR8UosxcdZk zVZ*$`%n3A=?O<#>bVC1~5d}!9*@<oOGs?(5qt+UGI}W1#hk5ftsYs?4n75}ydSC$9 zklI;20V!qVFV#Y+(2lBPRFFTJXB<U$$1lu@dfK|cId6mg@_~Fk)Pcxdo!f1URkAes z+O*3o(Fq;ZjcD+pWQ1Z^1gaE{q0O;xK7qQa84mtWnSLK)oc_iv>Rl2^!x=ioTvUmr z8K}b2lx@OlDTA=`Rq8_6dksdvT}RZUH+3dOp!kOntr?k9s31_sl&`}E`^moq>Yi0$ zAfM3m$UX|<jgmJ+IAgYps40gOry#z-u3;d-;Is6?A_H$p)}5{s25p*;nU*e$*m+jI z<(rsgC1!S@B$sLS_=+Umb-gX1-PiY9Exp^6U86tPu?r}^52|;!zNzFIt<|1*_dc#G zPAX2oSpI?!->b2^@b!c=-xQ0Tvus0xl?|AmHqD!ZK;J>$h}^!JHJtGbKbENtADDbM zJ<`guU|#TGUViUpvvr?r*?W1B#|cB6qtfT)kjrRG-<m{UxL#{YX1%Z^nuMcD;j*i5 zfl>};w_*v#c$l}E+!Cm5lfu<%!$ZNCVHm%TyBT|NJnO|@3wZr^1Q(Hy))K9mwia=v zY&gal5<j0)J-PZ`Ot3PNXe^N@9cPoKoA+f9wnhhy4@O%mkHDU}hS3o<^G^}kHiA*^ zg@Vu8=Qv|NY{)r0)=<}Z^yIO|>C_^BnRI?=s)VgxV)I#-XAh#4T*Jr(nrw)XwiR6L z<4+B*?pEbu`Ry2qO>SUgUbMM_&s@Tm`VndBU1x~1_PT96aQqCoX;*KRqk1N(cdxYu z^_7u)?A;sS$ugQ$WWEppcQJpW+cOT{cj5lM0w#7l%&OUC0iSr**kn@Kxo5EMF#k@0 zCsKk*a{-z=cgg#iO8fKCl_K~?2`ktWfdN9AnbywHBaRBEfvp$KE2@@GO*fxgm&?UF zntKAhfj?QReVp;KS$}1nogtNQ)bX@sV4_WDLN2f9S9F6k(43)__O@@HrW4F&azDNg z?Gogh`TFM%D|H))@u&3L^KKRD$g1{rcoD7=+tJP7LrQg9dL<-fA>QfMTk>_;#y2d{ zPJ(b$Uo2<YNum^rhG&O5>b-!*AR_`Fv)N&Y9v9vcn};AHobJTg!4%CZY?4w}`{W{a zi5@SY_hQ;(S32<dsW7}1`+Gl~jQ$$UrSZ4^hMtG3GwW}~YmR*m4hNhp+@<E?yWR$O zEtzY#)xG)DaJvOTUte@7gv9DIF4Rig(MS`~b2~4J{ha<KCR0)4X8-i_l68g`A}5Kn z{*Sj1IW^53_U)%DQGc@QxeYF0xnPBY<;1#=vOc7Wr;Z#-Tu>hpQ8<^s{0;Oj>DTZl z(jPkH*RzTtaj);e^<>*0OLX^!8CO7t)3z&%j48jzL5J=9MWri*+`wxCSGhmb+U#{$ zroVRnt`Uz%n<<s^n%Yet-qW3oS(IqZT1wOY^KMM_v2||Z;Sy21*veJ8jQ1lXHo;pZ z)nZ3`dZ5DEYo|x9hHmOO{nPFvk6K?Z<3-?gjP{8Q{U~=%v&aUwk#!WtehRu<v~}8w ztEV*VdBnit=B^T6Zhi>(R~<u%Kd)$|lyt>|SqfNM(~jY;a_0-q*T`~5hZ-6rSqIVz zF0!9xvSQcL^+GfWe-~X9T_fCk6=d|zXx0GC-Zhz1=HTurI>4#1PKbV!wPnwkC7}5A z@fsUARNV8h$7m8?#%v-sKq5z>$u8W8d3yNs&o)EZlDp9owoJ``RvHSGh<ve2F^Zc^ z>S!2Vx~F5u*N&xh@T?*DEEu(PB^Q3EtY6|{vTYLG+uTJSdRk#|U0pRz6>Px=&?)-7 zg(g^x;(NZXFN%3Z&(Njr+T%;<N4eNbI(ol%KlcR|xq(F~HVLZz^8z@YApPHyo@Glv z0t}zcEflgq_5b?DX)KDLkdO6+JJi#?yPSQUXI?)@skwPB;oIWREiZ#rg>+q&pPaF- zIs6NUYpU|z(5meo2Ybi!ea%Yvx#_N+HS_ecM=`utrp&aiH%^W_=G9U{sdLsX@14s1 zU3VXBAOFzah7SFFY~|d3S?YH^6|wv9O8<JU%K{Ayc2sZTh041u#O%r1gIlLRsL1Ae zo0R&x-rd~jX!t9oX*fdfm!&oJ#?c!$PpT=i;@M>d!}dsxY$L-l3CUi3kAYOA`d~5J z5qk0>@uYiZLbhMpRcGh|n4+7<Mu?gP@iJW<uvZePBm)&bmTR+@_o?#@a1fZbDs`FG zMPZ#a_N$SULmcn((VhqUth=3E{(kgpM?U#Q!u({5T2K#zNsX0)z@f6<Ru!r82U(89 zMS8og9Fh&x#PTT!l1|Sib$a>o?7sIlERyc?YCX~G`I916XHvbe_a^Ld5{ZF=h%w!N zH?gnwh=S+`lKFEbHaE(dMak>;F|w%?R$=e5IYT#vK@Ad2Pu*L8tRqRBLiYQ};<HNK z#3N^*&4HBW*H48mfZI&!DKbU+otyFZ^n(|s8y?lqC2Bd-(`V%B1!!w#`=zwUE|F>G z`uErTy%HwxlO@WSU9`oJUK*SJ*hAgG<8}OonOVXdyMe3l_)Be6r(0NS<ck5RgK^0q z8)juLA1?9b5Ere_w>V-&7;`4WtoquQ9GG%F*<v#WbTtfbc4uU<N(OY}=Z!gi#-wuz zKkDY)3h?tDsAV69oWKTeZ@)sTPT42EbAs@P92|yK&Oe|j>U$S!1ql>TtQ<PunOS}; z9{`+){ukTLv)ziv5~a4jrM`EJ9d+y`vR<^i$rP@3AahkG_l1_tgNQ0mb7o8)Y=}1q zu84LZ4{&ZwsnE*NIg`oAbhm*D;`!k)w@XAd<CKVPP>^W@oq2~We4i>nag0>a*Bk9A z(xLW`6s4pA&D!(kjMA)VVON-9js5(()tH)7O!bNH)Mv}hXYt7|RogWB5#_4ZvdDh* zvv{3qK}9IgIb7Z>U(@dmOSM^YjhnYE#&1B6NjWUHkGNFiw)PLdH0;mVG|zBmk9G>w z2y$arLN%c1aXgTzmn|R}VX{cu^0}dB8O42eML%@V*;gQ<!AZ~>g&;JvTS^hy35!JZ zlkuVIF8rXr4$sA6FOrh=gCLTjG`#3>)i)IKn3uRU<giF^jVg4(D#I=65Be>0x&M*5 zn2>RQ+9;s~;n%<^sAGh?u#KZQUgcu<!Esbu>U6;a68d3-Flz{bYb8`PgVrPH6x>B< z{2oUb_zVx)(lXF~hMB6bmq2~*!}nWBar~8wRR^1*t%WV={kdhEo%qzD-Z8J<*y_m; z>xAvI{Y7`R28o8X$mUhm^tPLGWXUZajx@I@C5Ge2{rjtuRW--{b6=~Yw^0p@QC7Np z+Z=9Xkz<mvbAbyk3whgh+u?i=C&tU!(d#lrGaez~0Ug@56GC%~x0Q@kE-uT3Xs8#@ zp;B|pdK9*LcE<aMt`@4~zqPpU_9GLF`9DNCO^UxP=@3I?e`q^<cQ5xGR!iSq?E9Hx z{kc)*Ftb4#)K~d~zg#Q+^3bsIi8;jS^;M0e2yO9w+@LIC-Tv4j8<1oA!@MBIj6RkZ zEVa<8mDu)Br95^f0XW|l*>?8cANo0h3P}6=g|6MAhi2A>Xtg#RDl}N)ui48FeU@2n z|1#&VxJ}NT9acYvPSTI1eV=&|@-kQ=w4Wu}=a>E@8<}zDPTaO?kgEGqw!+)9az2)P zU^j6-5T!xL;hy6AO`rUCsaLWyYVNLI)!0m-TzuFjer<zXE1UPh)xETh#s_Lm)ukHn zES-J`FOZ{Z0rw6+1}QN~hCaWx;o&oWha59I?6d24g0lX_N!=vU@KU{!4aA80z02NL zfmr_U5^~u)-)J&96v*Q_$1L7u#DlqsiiY}77QLd91uTwHisYtJc<SH191rb$#@jKn zN+^;lONJmgrn@9Jh6rpl%AGp))K#-ME|MygUMIDb**mb>Kuo6{C14dB2$<mhT;c;a z^*tiZM=MuCvIDbZLZlpfil%wKc%+s_#)NB7_C}17w*ag2VoK3x%#;1y`^%G3T*|Q$ zc3Rh@+%CGNTO*_HuDKc*FYY|w4IP|PzjilVrUP&+mT52)&YNXBPjmk=01P9!|A9nN zm2!!QVNai$5>7Fy$>t<ccJw+?Xo8su$VAr?XdTa;{Ag4X?nY>gs5QiNk_w5g4gv#j z7Zk`bia-hjtJ^NSU}}K2pvl_7A+ZS{p&P8cZO~XywXbQ<sbgUL(6%_EI4_o|BV;Y? ze!SkSQO}w<%huk6d0R<w;F_p4i^VHC62H2wUYjsf5t?w?q*%88T^^RYN4KwVz4`U5 zicasz5{JZsp?M2~gTvv$E3mbm%<HWqVK?oN^NC59vjeNXWecr{7ypnXNaD`TkdR_j z2@57_zD>@sa2dQck}64ol!=q2DxXUsmXcs14}sRfVtij#Q{`yLX|=9o@WJ2ORcICV zOpf_I1tAdfugo0)^41!%n>G92Es)}6^v3TEf2#eOrn%-cb%B8H4I^lX0DpJL%Oh6- zwa@I$o$Qk+Z1-W!O~NF7Z$7=m`97|-jc1g<P8{}Qe>Tr<=Pv8A3hDrVt%{6m-iIY{ zcPrSb4|U9q-A!@Ut*=XPRP;?}#i07<L-qUX=J7xLuAMGT?SFuwx>~>L8w9B{f6A86 zgE+6%a|Es}tG{eQiXWgNdS~j@G_su^ZVBJ^TNQ5jJyp^XWdSRUJaozoJM5Y_ehTUQ zl0my1er>tgEP7)V#k(RrxPyGETZ}E-o;810Y4v!A6@n(E1Tby&j@;{Rs%df!QBoud zEwOi!q7@!A_oU6%67B6Eff$KC3i<DLVj}PeydYIGbDYI(JIuT_Ld(GG{YFXXOsn?Q zSv}f^kI2G))OZ=XT^3*!ppaF7h6P5`0PL|c)h&oXp$*v+gu#o8=<$}oVQ;Xs^lhCT zB+~v?mMy~G8?gI2K>h-a{20va>Ttb2BJKVTyz9LT)7I+sx2(?4MyiNyU_d#Ol2M|6 z{@yNFp;SD>D}Y)C=wR?)2p0H_ir3=6w4~d=Ht@a7%UD~vnZh*fo-|~IEB4TXOW=Q` z@NSBxf4e!S0wFy1*K3gecq4)B?HmECecvq7OCWE!=HPvF{YDC=<GZJho|3{E4qzr0 zfODBHTzmlQyy2^Gjw)5nZi6*U%J6+9`CQwYL7R&B4w<C*X4rBY=J~*1fFU!W)1&Q} z@5gK0%;I1bR>&&*)fD-PJ?~r6MMpKbOEpc%xG%p*hul08V!;wj#k=cS7oo9J2hjF7 zNpe05QK+q_ATtG2w9Dpk*5_KA_E`l6Z~<LiwT5y1%q{ufvhBA;2fYxYJ{Ay+4!FWE zWI2+=GJpreuaJ*bq^^8+<q>CTSv>zGDWvo=A*p*Hafq{J4o%KaGJh9~W(<Y^K}<k1 zTBP)LMc*yKHqE$Xcg~3^2Viy;p<}ECOvj`fQcg%pLE=wlB<8-u51=Ca?f%)BmIs($ z*RWJ`dKCEVQlZqfS13isen^ol(i2VkmNpxPGC74oDE~*)mO5J!GaG>@2W}A>+9_Oa z1<|5p`|{dA2$dShJR=cXXm)><mvNT$UDkHo2`iebQBs(YmCIxMta6-E7EY`viVR^a zUCZ=y7b~~*c}hS7r&`6kdPz&2M!LjGQ`gn4{;U_*Tg+&FEV$SbpQa!2_axu(kofwr z#CFMD3cz6a18PkTv~Xx(yS7w2N7K5e^xZT&AwJ2Zxn6}1{8woR^s-S``S54PGUtz= zZjtF;GIv**Yv`&7aEa_M%alPDBV`~=V%IpswOrzdv^c_`DnO$yU{PEQ%Ug(sv{1uK z$$~|K-bt7dUP(+UH2Ja8xRHB`$1y2^eNr^sDKe?!gdLEdRXeO1`x{ROb98T=f_MFB z%ZKqWKNRF=WyqV>bk=`zyC(_mL;9pewQu&sMb}5|@gjQ8k(s7n2OuNbe=2qTU^cvD ziuzMP4|4=e*d#SUQVWMc(ao<gZ$fWF*M!9Ygq1HI@k96q-!q*GrLMz5Aeh^DZL*ZQ zMux9f+lX?R=xJww6V8=gYVS~z0A{EJOPzs@;Fs<*#0PU#w!;GFFsK&{HZ3MG{%Z-> zFoGW1mQj7)*Za)0C=%!P`Q`Y2NNplIj7D$g;BL~TuCB1Za<*%ojIF5zA&fprE5E%- z0E7S+Up6jkS}}$ZD`TmA*&^I@aO<=vHHZNWSFit+vTUuIoMDD3A$GMqwRCdGHv%ch zm~(;PdWU!_UB<9XRYjYF8Rd>ixQ5`8{k2y1uP~NfgwV4*Y*-SQR%W2hyLmU-T>bGN zXuuc?atQoZZKNABFK7rLfxu5SedJ0mv|s8Zy*{m7>=u@2jBgK8ojk-Dh;NCu_yn16 z{4x(8rTI}1(4_!e99$<;?Px0J0D_V+`xh#y1;dizZpd<b+@!DxiG=Ib3WNQs>41;Q zeiw8eSA7;ldg0l9`G06dpe|z;l7V4LK$(nRAPS8!7xg2~Wn|XFfIr2GCPnLSETQ-Z zf@MJQ?I~g|TS{WHEih;+EE@0q9CJNcz_{X0u{&Oy3Amz;Ymz+rIcY`jaS~=){Tbi6 zKdkv%S4~NW+nMT48thx$UvA~NWv2DYzD+cTf6G5{Tf6F2Z|}DNZvO85O{w##0U(k> z$je=&yw7kJ-{exB9RhVkx0OFLM%Pu+TlVSltj%gkYR`S8YlR*lOh6qskL0?E{(o-) zw}@f8?vb^3z<%D?_vUQrZiTBL5|Xv}_wf<Z)oWWkM*Rz?(=9LZMMWapws40IK-QRI zS1`X+dqGa7%{Bm0sqtTNXGwlx{w;PzTv8dCtz8lxZYQy1(6cbI%WAQV3vjU=kNmK7 zh?`vbTEo@|**w5i;v_z+EujCPD$CH#N?q`5a!&ne=MMAXTE+fa*_YPkA$KqyGH-h4 z>+?@q8ZX90?g2c1JLK*QzpzzDlF0wiw)EoFlVBQIqsm4L-L1dsOsUJ?#|g3&OZ7xe z?_~;EHe)vAcX0q+zUMxJ3i9(M&bAO~0jr&*0Jn6Rf^ePn{{6k43|iXyVBjh@TMUP> zYl-~TZaD*uUi9<KFS`vu?UT+47kO`ismSJcd$8`H)`f&~a`p8<Zw?Rbf@Nzdn+2my z)J!V3kLiBUQImjL0)LXn_T;4?&$iMO3!wy_Hk)VO`P|okIi&U7u;uH6Z&@*56tXh< z9?NgF6%hy&Zmfy=Gb*i}Ue*k%Q@B)C?D=HlV6#adKOaYPOXYo$?LWS^&%?NT9dk0Y z$JU^TP!8NPy)y%O50#Y>d~!;Abomer<=E_p!1Xz!gn!#tQob&}23eqmC_;Pn0oRx@ znDh*B!&eZ2l$vC=b91Ao=yOqF1{Xk?8ocyKfOQOma<ND%Sk2%cM@Q?WLMg0Ux0^&y z$tk~gLfXb$Bs~xF4Lha76ipRUGQrUr?hEYx65K9g=Y8&otR0MNlgnfwtKuC9z&1kN zBp6o3r(K+oLrQlcbkJTJ*D``2lzFNfk7`rxN93v&u7?7h$O&{JA9~z<lA;!w`nD>7 zKKV*S=NwP$hfNHx$YYJ^o6*hWM5K$e9(I7I+Y#E$F?e4ZRv16VEQ|$$kA_c?l$-GY z{1+?IjxkXwYak<BZ?z^WPJ`ofC+wO$^Vi6GUtp3-b$n~+@soh$oEX2Scmg0)jeauu zY*&YHEfu)}t*6pM6tabc0Nr^b=pO;utLc4`NL!4B|4Vq)|4VqcRsSQaOJ!>Lz>gPL zqp#-$Kjx2B7`<vgSqW^9fhnV@t%?e@hwCVbMV7GdVWu1f{Q}EhZ9n6P$)P9nS`)Z@ z{1tSC{Z)KBD+6+cC$pnXwGPXC|51(}yk{Gi=w^+IC1F2ByR9vk8;eK6I|Z70Zwxp! zF)K(eYP{KUlerC&F>RaS(0w)A4UcKv;UUgT`DWH5pEN|7H$xq3H`48@_^u6XZrI<H z&~H7GRKC9&QvTZK(e=L$Vw-wxsh82|J&PZA5x1djtoD2Eb09ILgZ`LwCA$+B3?u`S zl_j%_P%*D9;s?dq$5O=dw)>LZcF|u0wbCE`^vo|1z%M$Le!KGq&ZE;(iu5EX-0DKB z_<1z0qiW=1e^5UQk@48_kGvbV8Gl$JmdrQoEeZ>;Oz{d2mOxPleFf0T`w}>=l3gN{ z4H6itBq8(y`f)?`d5!+jy~XQP)d==iPedNdwYP8-G&w;ZdM~F|_#JRej>)XZlWPqH z-NnG+a&U@W_JZ*KBm4Gt;CLB6HMm|{iATuN@xJ{4<Pi_``11wDG}=Nx9{$OaAq3~U zwo#K~l#(l`c9uye*#G#K&AER?XWDO-`ElbE19V!0c>_0Q#dx->ECUU-(=`bKI<qPQ zMKvhS1JYwcUJ3nGRfL*s53LWC&>L3oWz^XO`%#1EC5|yi7)un?0P8g#y?Bi>Or4J# zE5Xd%!oRQhI$T@Acut8yvGJV-36C~xPGPWBQNnL!$t;R#iDrC}n2Tw>8L8zQ2~v@y zY*Q&q-ia}(GHySgYh2agt&#pru~l}Iu9z0>oU|06EkInu;s-7w0SHE^n;^}Fs5iBC z-J1c~Hef{A7X6s^I0KLvhb%G(l_Y2h!Gw^aHR7z(WbmbIyJj&TB=DVpE;a*hqAm8z z;g!*n!8=T^e2Ag~03%bfHnfsstWU-644-@$e-2A4g*iJfmX7)vnU40@5RaLgHJ>yM zSL=k@Fg^sTQ}k9p0v4Oi+eSxB1hIr&D3ugir2LtSl|rDQb;4?Ji5z2zAq=8~Aj|3| zfAtKz0PBRCHx03DZo!~!@x1oD{gbuA$g_!4PRKXSf|gn-V&ypussHTvO;tdo+p3Rp zov5wI9_yl519g6&>0P0xf~=U|5^-ErS&lk4^JdJ>qL_iZt9)xTt;q|bWw1d7p+JUU z)%9Ab)YE$vc0_Lh;pF_yd4Ndq1k7_h_gM}F;gB)=15^!UV&>GnI4{U$&M?I&q2`K& z>o*E5Z+{Q7R?v*}qI?%vz{z+DuEl=_39;YF(SGmOGkGr2#u%7ngg3I$`s^;u$iE9X z{+}4W8;koN4|O*s%%$7ywEj6xbhl=Y9V7PmT~EaAz46;vXBSUiT@e^6$rv9a4w{XM zgDE}3ZJF4J?BO1~{{lo3bAJgmJObL$?w(31`s>Qx<#QSMCTHtCx<w86=PTSFWGl1b z86x-kuYUCndwiI*X)PkWB5aw09OSO5e!b-qLK?|PY?80iIJP|awjo}dg66ocsMkrg z*AG|4V~#<k#ALykECr}17vf}~&|;b{Rk-D2DV$+TmDttg2x|PZ%oICgLG`4WHcoz{ z`9rzh=~0!;F|_^h5i-RkT!c;f5O<LL0Mr1BXwrV?rq-Ic&RnKoNHRzy01wc;M;HC^ z3a8lSEQ-JC0;scw12QUoLbDx7RNvYUjGX^x6!SXxHrQbb5S8F}QtO25cG4GO=q~fq z8lQnvpboqBSR#*e<GPO>HzDbPj-KG#LK4kU{&7aURm?W3+(Ug!0WZ9b+S=c!y;p9> z5xZJ$Fl`#sF|d@lQH!{?maq=L?N;&EtIm1zY4Nwaigha&HK%pGB35p-c=suMn$o)d z1Efl~KADz(DyqAoo!AV^a0C&|pqaDUT$vbP>fdodnRy;Wen@o0FVNS={v*(Yqnc*Q zp6F8zij;e=!UOPYq2OUoK$LIU<hL|bU==VLH%WRQZ_|Nf!h%vWhCq+Dw8**i4^Etg zf@*l(2Z|X{O{5}7aD=<PXYtL71)-BC1~@H^a42TG3S&Ki3xfZ1gO+W*&1OrdCwJIy zY@(sdM$|Mx!Vd!<L;b1QFISLM&B<_b3vpeii<77+S;trY1j4z9WhcYdl7R8TrCEY~ zlSERWQc6ENh*rnH1oK})IReV)5Yh#>i|%}Nx+2kjky*N*4AAb40g!`p%r1TZ$;-|2 z8SE!##mUzG2w6@kTgk}Vvo3Mm{S&(jF0i@7j78qUyN^Zrrrq0ugbVLFP2@YLXg=L? zaJt)Ql>h$I-!f2F{zSsBr;5I|=~&f!68n<DI&tACAtgT|&&4m9m-v>fS(0aM(+Rd) zGY5`S(7eN@w&W*~^jXRMkEOHU=79}JN?y{DxHEtd@7B05fp(64eEDSHtgRZrd{({k zl$2RpmQA?Z7D7hfTG!p}20-RgDrW)7mrM?I>%w$|2amb?O}+?WJpRowdCA3@$`hUs zH@!mXaNch6xqumV{{g<;UA`U-(B0u4-FO}P6Y;x6>X$O1=R#{+<h_TMKBP5{t|!F0 z5uMhQ(o1>#AF0bzVA*jx8}qW{x56U=LHLe>c&6(v6Y|hy3*p&4DC@0=pdQ#0Eq7@o zP=aNTkmr&@MY=Em-KU{R2~P)rVd(?lWEGm104!?@a}Z&-Uk&Y_u*gXij+zyNL^5t2 zt>LxYv<G+YzD}|flX}Y;8`Ec#gfC~8hhaWTu#>G@IARa$?b9P`+~>m;pZR_Ago$tZ zD|?w*H>?J{BHX>?li<z3UD*JCOQ^91UWr>rSZ~C|grhVkpuy{3F-Q$e-lUF{Y+bqc zljUw;p3J!5^Rw(togPJJo<Cd@Z}1G0KSE-0AY79tI>v083v`zrULy`9Yku@o<ykQ5 z!6dUl!QUb6ZE=9%gHU>K6$)s<-<TcfK*M-1mR;@t63T({3gLNkkm@OO)0?GAzK5MP zq2+8}O|@<GYlXqZ3o<XBa0!hN>Mr;zN@=1hI%|x&<YB;rd}46eW{D4_W(CM)iD<aX zyJ|s0klCArq=CEbjx6%}|CENB`JPmUh#tRW{;%}ABU|tO1fsRo0gK6Mf}O9zic#Mv zwcD+wrWp*JKpaX-#N$+Yu9O&RBd4Soo3ETw;{KYy_!W<{jgP0YX1Z=e=lo9j!M-*K z!Yt6dd=wLqN(PAW;(i^?)8!YOgr&;Fx!Ko2es3@Wpsk>Dk^X&u9YDg|Nrf^;Wy!-O z36cz>J>(3_5K5H>dE@Co6hi`ovx#(}W!~x#Ku#d~{HQ{^FT{E;`5iZ>m{L~RwTgng z+>)nGmVs=j$p}3y@h1=&9y(HC$yPAPs^o%FETs~wAyAB6s=`v-d^7BAdjH9$jQn04 zA-~9aQ+;6gdystD0PyhU{2nWNDk(yI;Z;_eH}?rN=}`!YYTZ#Wq{Slr$Oech(>qKg zt_U|UB%7_eRUNEXn^W9JMmrfCKY+>LJ%t=N2k#1$!FvaQWC|E}Vr7_evEEc(xE=ft zFN9F#9rviH_X;egu0lq_-`)q3aD#&QrQfp#JI@&=1`b_t2w`4{-G6X>YaCT5iv+Xy z_x*7o*juTBk68L##sNq^5N)Z<0eu{x%L8Bb#Er)0Jb|!K?d4{-mXc~Af@5Nl!YK7i zpJ&s^PFdIu616&4%X7zj0psO#NoO|v0fBvz7&NUJWnx>S&0Q5^s52FW7MNmY#U<XA zHDZB`asJpx8dqHKhH60j*Z`9x6nvn4YwJDg!@DkXd2EHlXL|5^+u~O{y^{&Hdp(<z zkF93!ef8eg{^YOr&ewY4W7=!nmk#wW52&zE_qIx*w}b$l*YuZ-^o&E$kno%7Jafb1 znVyHaNx+#Fm}j7#H<O8_IUgbrNv&NW1^8EUfPpD67wv%vlkCh(U*>TG>phT2iyDW` z;bdc>%Lea2EOadCq8u{Zyl^|X3U9PUm|f(DHb~xK)0j091+wi)puH8#qJE+Dq&IJY zJ@HFHV$=@nIslI&uuDtPwz34XSp#h})#^<Fpe`a26^_M_O(Zhdnl>9?@`I3~=?!}K zX&xtJdMYp=>rmfyXSBmAjqzJ?h#)DN=V1f1HBB4T7LP40pJ_LxI>|fUEuwpCau4?1 zf)2OWsTG~{XI=$l{jr%n1`;w+6^+{HOKDmUeJ%-B6;Du^p8yjE?h+8B!MqiBXOc5) zpH~qOKw>F(E$nwhHdMxi4RAXg6#>%M`^o7rEzq6;yzw*_$YIeV`^jm5HwuAI1pdn# z3p@V^1Ue4(F8~~81p4n^02p<?5a`59yiu}jW6U%F4idoiEQeGVvAvdE`rJ)$<jeKp z;bsnMuMp7qdz7Dr1yLiS;)&;!CK3x>B2H~vcyIRa7s7)p2l61Rh!!q!S9RFo%nRS+ zt+yhFK9Sf3+cK>`zvd~N-Xl*(ZA*LbDK|NhFADo{eQR5C5J=?+x9iY8LvuUX%2~#& zX-_mGrL5zDb+Oc;&OoCK?mK1L2)|W{KeJpwdST@FV%U925OIyoUvKhHDG=&jHm=b? zV%z=yAe=r_9y5b_>I6p2(U_>f4DW=8gJCsXrt7T|sPTq-=9?q$SwBP*vPW^lVb??5 z^3LSlfb)4HfoKBDSN|+|Um<5GOXlG`-pH90C&-0pN76VjA?rc~y2?Vf5KWvQ5?eCF z7#J!b5$XjA{Fc^)VU$pTj?%c+D`-|JgJz&v^TMU@k9}Yt5nvw@%`6RP$+?+>#w-oq z)TK|!jX{;m-a8x?hsvO>hsY?*&2BQWw0*Kd$wk0Y%YA7PPQDx};BsahWkL_?c2A*v z{xF{wSU%V}&$SIWoJr@uOV~BgLeZqa#2YBIJOSRnvZjN0tz7M35^m4*&<D)7v=V&s z+v*}O|7D6b5zALFXI+@;_*#4_l=9f}_~p011=6x3KobGe2X*`yJu;pg3@)vcg@Q{4 z)r_uTTMeM7i8e4PEpr2%U*qk`zA%ooJFuaz%)t3U^|S=>@rS27$h>Q8tCabLebD@i z>(1yQKGCx~VP;g0Ggi1GT<Q|>*HUxa8&?+n4x5gl{**q>LBgT$hfWZAm8=`v)b&`y zzjHh5Q=$C^0-XX)M|+Mo*i{Mv?RtNG*&(6X^bU-e6{B&sPdhXY!Z!h^9=okxOqAKE zyr<O$U=P021SAYJBOqXsnuDE85~04jY@iE+&ZjNA$*z{KmX3gIE69xbaR}Tw{1_|F zT{JurRPq|uR3WF<kI+i@l&K#MJ3|}QWKGFvat-@;<#|{bVTaYN;tzry%X_(K)(fEN zYlq4fLHJHCIRb-qBqf?m`qc8oq*(V`IU$uHzhgaWCD3UTa(;OL-cy3=O^Mx3v+Js# zaY;y3Pgb6|Q4^v2G@BhL8UEbI|BKlD|Hb?^#!<r;{*`;BG_|nv1;8rr?^AP7(4<e~ z)kvH+T5^cn;jHq4zA%6EiPc+xw{JG*`1`h5YXD&y7_}nuu-HW)*cf88ck4^7?thgL z9_QI_PZnM^fYr$WalZ}n8x3_C^DkyuRZ>^`7Z<7`sy?A!I8PjVy~=@$JZ4qV7GJ~$ ztd{&d%4`S$N^buL!zVNCLoLvB#>rubqK`p2d-omAKA(Fx{cC}m0SYAnQ4q;>h>P=F zU_Az^rXsC;m3rE)diFO;g^s6e3WptpUQ-(2yPx_G*aXwzn&++SvoBU)r@|z(x#*T+ zt_aUYw1ozb>()~9rlj1?dHVYe_*LOwwoymO76tDu@mF8`^!Ep9n)0zNN63B<vzelA zwy<NYSDMgg-eY>`osW74;;*R{gwC2J6`2oy{&JPs9wwzG<3{{Gs-6^t0+DT0vV7~m zsE?}(`#ZFH;MeX-4fOmUVZZ+se+{A_Ug<MaBN%@=A(=8Vi4RL}*O;|RK#cjPm>x=6 z&;&<ny<QMcn8VjkmT9M1Np22kINk4%ZYjv&uq&w`JZOAJpD?%nY5VP?@1BkPowDEM zJk^IbB5!jOYQnA7=;~xv2sPT%>t}D&$=sNZ>%CG>H?xyF#)^UubXGn>uJXD|^^~?) z$HvAnoXbl2W`e(*Ei#MM+(A-mgqknK<G01{<bNyBl$@e}2$r%6d7SPY;l}uFQEyAg z3tFT&m5Na_tDuLHbqhY#SWCStwP07t0Bp3e6$rIqM!ueM2yC(j)n<%ce=@EYgl#VD zQa9f&TQeIQjCT#WX0%`g%+j^C(#x1m5-Uh~Gv{It<o=jm-vnOCV&_D!Adj+$|Eo6u zTq>I^1^>SiJWJm|!$sg*{XZZ)K<+R)U7ql+LE-dJ6hEf#`z~My!$s~#DX&1;R5U&v zxl5G)35L7aRF+nuEuLRo{ce^yOMZL%NBdKZZ(!%dOBpw1(>D<uu_G@X7H%ts9%(NW z?PN)RNRSv<R?&jEXj7@4Y><Z*&W4;6N$>U#$<XCe{;|-CNIGx(2HRFF|6{=eTCF72 zuH7b_eJ<X`x6~3*cL!&l<P1bzd16JJ7@JuQw1Yr+YI}ZW=XpJ#1b~J(tdpAR`{6^2 zNh5vd1;_8Wr+|jomnioD!!2^W5hdM5cSHVyTq?<_*qCjEn{quI(7XL}hd8sy$|XiB zymPDYy70Dw9cVlEvp*3g*bb>Y)J9`Uf8wGeH5}^pEDkLIX(P=qv=V6gQZEXYfWFdr zAj@Q^5mGr24F#>AXY6#{rOs?29sz~cleGUx95MuXJ+u5QzE;>>;A2~<5`LTSmyW~4 z>}oCuo`7h{FXluh>5LJeIqy3|fpjFOw-^E)T4s!qpl%Aeg;;z_?WvG<w%R{v=Uj&u zi}w%nHiLFVFj<&Ymgy^Xj>dU$DTBxFN&H8W^&sS1PDc!tNbsGmiuo0(6&|>O%hvw* zNK)Fw_WVvOvjQyGgs;J9O%%pUYq7P2C3D0-?(P!%F#Z~}LQB$_mrG$jY_ETHP?U-| zmJ&6M0d31!DG79fy&3!HPs!gOOTEu#X`O)D@Le&u;@@Q*YdU%OEa6Ig$E1HJgm^8z zuy?XvEl9e}9%PpRR-2_xf{389%#w4qm;LiHbKd95)J}p%WGdI|_>1f2T}7NPO!42O zi585GM6S_v-P>UWG1S&*BWBky5YcqUW8GXp+8W#{P1b7A+N2RP25M?mDNkB^@`IkS z_$2GDGQb2rF;8>67~Xj~eX^0XVHxo?n^u<M>NSy;H~G~?^oqWcW<N6G9xP4`g>C@B zmP8MTbr_mN20ou8v6RgEuhjb;Ck1<^3?O2t%?<|E5P>8T;P$_XUy45ezfQ&nKT3m# zhf}`v`rPg3ZW>VMUm%f@O|gyc{y-!8wqJyhR;_hMOwIglk+gO>!~OpCWsU7a!J!1g zUn#4W^e0C7`#Uk4sJ&Ti+~g!iVkXO(NExtK^f=u@)pvls5|kg)6u$(5G4>k-daqwM z&A194-JLGDUte|YPPj_vM*5?<?az;`4+7G4OHzh~q)S9(jlU9Q8;LSq<IKihsU%Bk zgSbz=QIIkcXAVsJY=`uBRtIM3UowO`{Q;$OcH|h@`Oku#^{wZzrD{$aHAAV4Y`OBw z_SZf4v45BuPDVmi2*fnJJG&LogjHcRe?4l;<RW`2blPa6uLcOLiP;9QD0gumGY_f) z6U&a=)VFwQdk!#Me?vCzQ5Zanx<RD@CaTTnb?fka6oq^U%s-F<nFFVKBFRz(L$#)< z>TzNS@d!*E#zf>c*nrnIEJhtfM?m8yn2M-&AAkpOVH6MqEXD@5ve1bc=Q_;!0;5my zaaXY_vlIK`p>L3b`-qh9m~W86MjmVRlG+y|wIf&FS{uozjLHeMpumNkYPQuoF~S(G zSFcS%Z^Sh(;UrSu52cJ<z%eb|z$lGyo*!tr#1wE&@Ysu&hOkE|dK6>9{Z&l=3ksI8 zZ5?NlTV`b|+Ga9OW0$@~nrE-C@}sY$<a)AyJ-GOXvMz9U|61`?aCBZ|#eLO5et8O1 zoq`+Hy9JHne1Q(P;h*=cp0@*G$5-~$yL;PNC9TZzw^5jxnS-JKNsqDB`>ub<MXZUf zK=vv%pIHfcGY7|8utcdD-p*A;D-X7~uN^@9dGeJenF%SLVjY(@&kd1`k4dCpye9y1 z-k$oDYyjzkn?_K)QHC#p8&6A26bC(qMo%0e1VX2@B2hMW;vYUX%}Zae7_J|;34GnP zopXuxCP6lBpqt+v9z&qXcf7NUly5$(Ckq;3+6wF)8F@1_eSR4Q8LMM*X3g6ge0XcT z_{U9{x7<B}p_~Ej03DYqt?S!b_mvo428hM`-Y51ySZ(}yB~8YqRGF9w0*3$eKK}0R zq~W20xeRIx<Pu;8`~O5Rsa=oT>Qz`v5a|3@*a3~_9Py4d7i;~WG-wEvO8@vlj&vz- zCA2o>KIpe`aSqZLz6!p4yPy1jM{?w}Qkq8Lzc|xgqBz23se*3Y32gQ1_`M*v?ff$! z?!%2n6&P?Z7Ltx8;lZ3S=+vi!QXaSSRhf5rhL~im6~?_0`_>00v<brg$15*6EFN!$ zn_iN{UBH;#`{}OTo#J-W1FEb!1ER#$jb;h(Ys==~SUs)IZg5QW3run@YV>7Q$A36= zT9wlh*0e%t*y62fPZeA|Q>|2}vETqYnmAj>w0v-FpI$61qOLct{K!8@n(O|Xn^lb4 ztmf1j4qBHqhpLg<s`+FjFIhSr{pA;kxP;vNY>@#1qqc`Zn)PwTgTtTi>6zm+j>kC^ zYJ~Ey%Wr#p0y$4(wCVva+6c`A3JMUGl)GRh1zx)iUPGa6OVu|i9WXdA9m#EZBn3!Z za(Lz-1R$}CW4v=|7>OFem_E*yW$Zm2racf9%j`GyRG%6N1DLM{G`xg$_%T{=1kz5h zA-pu~Ezk%m00d-USQ0KdoYqv_|8j?QK1~a#sKtmZRwsz*0A!vKq+vSupQYBoZa(6; zWEj!^|BdM=wz@%d(4_N9g}<@gYqOuK<b%+^{3U$pYI)?h<4}{-MCV;nX-OUyG|vJ8 zSb)WWCeNzhj4_W*0>*M-5gRQXq+bQHpBI><NY9)>tOn4*8UMbb3r+8Q$X><iKp1dj zvz<{SIb(kRWskQ&-Oo;XJay8wfvMo;XYf7(`&|-R`SDhgm};$&nK*0KNG;6P2>aZK zgfONuj8*E4Su@=W?Q7Ma`Rt4;%iJjGTf?7U`Y@QM+thu3pZMdhAD1S`epXHL?MZWw z@kagjPtQ!TMm*}AOje}+HHHPW5Vvi9GkY8sCjmxw5ZN?&Zug*tuU2~p`DTWH>E*`+ zz}@{0a3J2-EZIrA@>+<O83)>tscnKFHO2(byGN#W1aeBbNYpCwu|Nsi!gs(Q?ucHX z-)-Ax7Wm)NGvBf^iHirM$N<oC(6b_b-ZVT;^#N#Dv@DL(x6UUQ0L)I!b%Nf<f4Bdz zV5Ce_d897OOXtZQhl^EPo+j@Wetvn@kVfqmo4RLRiRBmZrm{6KNdE`8fvg5-GX&ZG zQC>9ZEj7MLZ6#czb}MoiEdKaS3#chiFem?)yMYcwUSg9SNS#EZCZz_1)pT4uf%l@A z4e}|sPX@AWmZUm6p1<xdalSHKZ!7Xc@5r4gN@LHqXoB!2Dn0E{%(7II#D`5~_8e=) z{V}ZepL}j#yaZ0-<Ze~QtoVIzhstT1_YYZv$fmAKs^Vx$Sco$S<DUgxhpBIlXuome z*Qk#a10T?C)Bjw!PW;Mf%A9Ahf5P`Opa!}`AI<?cXxm8d%=Gt7EM+@g(4>a9fsE_} z{$<&^aM6(*Xm7`8oXO2Jk4Ytks#1jkplT9dg}v8dl1U_-$+y@i9N7_Xi9j6aQ&kxN zc3P>hqj~~XA-$X$$Qi9+vp&SR{EO-)t|6`lCa!=SH~6y%g20^gnWoSDkKPJOB2`c; zA@;_dhCEK|cFOwzrVWk4-tedg;r518^~9z;tXLJcZnFvthv#{)Z&1@Szw?~E*FAsF z%>R48Ah2Qq0kn;xApT8q0&Ys{qd?50MrnrA{u8BXrfwIQ$CJ5v*!SyLZM+Q&0N;?O z$S+r}*@(MU9}g_~X=AqVuiYCZTL_wc%ORdx^0u?@09t!y!)>H3_x3}rIZS%LRuvXy z{$K_+xBsVTy5&}_YC1n~xWJ#mN%w?b`7V|`P@QaZg(4<JsNp;71Y2J@Y7H_UE*M_H z!Is@IhKu)W{p(AlVMN7yYeCatS=2G`iJmj0@Onq@|3%!J$3wmU;oo&SMVlpCPWELG z5wdR;vJH|FvSe%(5hMFjC)*eiTF7>iXhXK_lwD+!vKv{)KK6aNU!PHD`QE?BeLwEM z?thMR9<&^0KJWMIbzRr<YS6+^w)D)aHK=j8f7Zhj7_vHCI=x{{e8<%Khj!*MAm7+U zCSWS-H4E;!Z}YT*M|3qbK%5giEWBGatf2ue`vxqBB!9r1cSpCWm7B3F7ja}3Gb!cb zOyi<MeQN<UkOanwX~%>=m~0^EWRr8IDXeX_Q#k#lYb5`uZS|`99L~qp;dAWOS1f16 z_ky7^9{gw&lO<m#1q$GSjEif?1@+9%;5bnJ0ZBa~zDhe!H5SK#q&7cYFJwxy+Xe58 zT%#VX-Y`3Dbj*zit?l$M(h;A6CN<v&@8fbHVf(Oj{*cnqI=%&MQ8lH|F{wB(lZ78N zuzbFR{!HNUU4(%SR9&89cjLyS_TNsAR?@59XP*|A;}z)YE>7E5M2fxIxqDGK_~9e2 zbMj!WJdf41#eKL6U$VzZFZ3cBC`uDF?D^%FY_uMJ26_n++Y=dg=%2(n(cI8aZN071 z7%7x<;<X;$$nmU5`0J2>ts3g9488g{E-ZM?*s1kiFA(sK`;s&|@)uDp66>wO8z*-w zchsu*{mBd418&(^1LrVD{OcGeRwdJ;xswboqQ{$7%pX=K=Lkq$j-+{lo5Tsz`wSeY zj(#amn>VtXnD!z3rQA&z!D74_UV$-^&8P<4mAc5xMMtq&@*7~c-n-Ic^e-lYnd$?s z5WJn)0(1WGS3%S>n90ETc@X(%6OJ2ig$>`N!*sB;HUmcPQB1ig5Fm&`1(GIphgmO; z=I3TbG`uW6_Ek(&QcJ{6WesIMk5|Nxl?Ysj&TfC9RMalKs8-oSwrJqXj=etmh%asi z4`V4TzqM@VE|B~0wR*0g;Up+ejO#z<>E)`EZ>>KUdv$EayGrb-;)i*N0X*NczqrvR zhRT<NK_n4|`;6z$-W6!I#J@yr191R8I0UnhC!}FbCOQ-y5>LFD!RMaHIUkKb;&J+s zZ6)tnJ@F_P2%cv^S}0asgT&JZn+1(+9x`UAQ>~sC(;0<C<aQ>UAx86ToL)kTVe^>d z&eiXLgtlm{K<6KoO}gT_^+VU$56>m+nZ9$pAy6ccRRRykMs&=OWx~GqI8)Jc+!gf_ zp>yH6xH-93`8V9I-cLXx=l>d>z>)zD%FYt7<k?EQ;3%UQ<ts4qAk7Kq;EsU41|u2e zJ+Tug3^crG!{E`ML$MLZswHDStuO6f*y?UA@>tOBDr!13ql;<~f3=>VY^VLZL{T4m z91OkVxlLw$L#4V?Mdly<muJrCbF`(`R@E)k>e#RO&rUTc`L;11kAgeYg7u#-?pU7k zS8k<E0Kmk6%D(mo_Z-d6NuhGaZu>~+CZE}aM+v}eyt3&!_a50Ea6E2{c4T8vu3353 z=Kv#=zH|ih$V(DpfZ1AMY1kg`tf0Q7S_WSFS5yWc;ORX6Q-I3R1^*!^71JP85vH^i zX$K9f74e#!bSsP{=8MD){3#zuc`=1Q-BMSG?>N~ju#IuIe=fEKnR3RHp<f}n4*NAz z57i9)NybM69W*$em`rubaCdaS&7&%n%f;Lv@BPc(NZy&4YH4r6pv2Ppl_ey_!+GG# zc;3vfJRMjqqTj-=0Ot}Cd`Eua5F}hY#GPuw*PrH=-z28FOYHBbI@Xc?J%Rk5Y{}f( za_LoPcWk3qsIx0aCD&T_e8PZlpk+ej%#(R~nbZZZXyUwRLr|!-EB63QQ|}@V(#s6_ z2IhX78qS(Xv0teSqV|X_EkF7N!e%eOvsB%Dktii{&i6q?*~V=U%;IWhbk9J%Zk@>a z?29BiK2-&Cbuolj<ms4U+rhYsD)lDL1Y;Elh4Ze7Kg$PtRv%c*J3dp(o&^6I?;3z? zwy8zjZk???=!8KhKU3-nUUH^g_Pzc+^8Q2J8<|guoyHx<;tn3I?xc<v9OKT_RKmL{ z)UN=CM*^?Gy;Z|gU11!EB*V7{M5-%fb*e>jB*FWnt5E=XqJvY4JdS~m8170GGsMMq z*P@ofys9@i@>p_l@_xWVYyRzlJx^20JAo2a`S~-=sy$(voV#KccE2-ZoWVyYy~C9T zv~<ygCE_n^gNoK=C)z%<Rl^ox3wBI7n9ZK)M<sXm*m!fNBdMiG$iwl{OVc+yLdvgm zvR4<Bt6Hwgh9w^97Ikof1~<K$S~N6uKuKTXIAW|T4GAD>f!2ea)q5zJKP3IPtns%w zk+YI_Is`_lU#3P+iodZOMjkPU!94jn{7ESNps#U+8Az8cOqMYOa&yY?6||M8F8e>v z{2HaofP4XQIK<ruQ&pkH-Y#B84DNvjTllT8d+<3KiXNvn)LH!zN#l8B6MD~Z*Z?9T zm5JnZCtlh;<aeKmD1$m8k$MfX`)!VUOkO>K=phv|`(J)(U_a>N8@cz;hezD`#e|R- z$yMcrU)pto7wq8$NA~tdy;rh+k|&Ap710<is!QTr>R6WpfYw6ux%w&GAz!J`kgR># zS#kdMlac2~r<j#Y0s>75;uiTKKmbc2c8RocAeT6u`>6sk3-1gjVSo2QuIR<n>xxT2 zs?w0kWHl;rg9$(u<)~a00;Br%ZqD-+zfGGqooYo(;DTK2L=GLoXM}oXGi9HA&-GIf z1A&Z`^psI<U$*UIJ>bL~g3tgWhCy<SH<YKPXxT}h?~2y=`P6mw+KkZ-yhylJ^?Si- z?m=qWda>6F?zQ68bNEldov3~rHtx48`{X{lDGYo#yHEVX92g8ed<IT+JDzR|ZT55b z+4D}I4gCKki$W7O@!Yo!;`m!Rn->iTGkBhEp0C|U>x$oA>xJ<Ta{2E2T=rJ+9w@~z z$Jcj3d=6kOKcOuU!7XJ47SI8uP7x5q>bX9x7b?-`1eY=xyoe<K!NP00<C8oKf9B?w z16Oy(EeH=9{|PCG{}*8lqi=TS-~PyaU9*$aXv$W`Wx94WVeuvyslLzm9Dd!|MT1gV z|9EC?BKD$}UY%lJ#Ux%pLMlQ_SIo}m#@vS)?aFp0dB`L5Q(L){a0}uG%c7@!WA+cw z^$VFJAV&Mz%Gxr(!qiqh5z;IFW)mFOSnV5_fB)EnRoFX$?=j$Vt{ck)F}n7<y=&SK zm?OtH_DVoz!BOHfJoRI)IHY-;I+D*lXvtW76bMPt5Kl+~OC-)dibNj=vktx|2T3B> zoCPLF)58*`>&=lt;FX`Vwo;yNO5p<<;yX$}ekL@~1R0THCAKlX>7y|L2Acc;c|iPv zM+iIwUTq0}7`Wy`(ME29@*}Sdr1kH2<@97|VvX`58o-AFKF1n0)Wc_jxlZcWQI0%b z`%tYuDPPz5bVDz)eS3Fd;Ji(TS~Tq!iaGJtX+a=*AdhZH#PJi=PK2a<i+?$E-faPO zpi@oR2i9c&x2)TLbuTW)d^Yeq77D<>l;Qwzu^*AL=S*ExulPC?a+fQlnq5_N4wvxr zjVXw-KhXM8-*H5Gw&_KoJ{2M5(>j{8T*0u0VlRt+r;k`xSOH~l*l;X3P?6tPC4$`N zA!ZjnhwL||7Hi);8Q~}w0wvS?I&Ei(tjd#04p*O;D<;8W<xCE?af+=zlL9dKe|zV8 zZ4om#CFyq#$#^NoN)pa&!-~V%J543;#c?pFu^fb4qa*8%ArTNpo($K4YSYzOjf&GZ zC=#2ze|{TaEpVPj6Ir$~R?ab?m6gT3hFi`sqtY77^`!yJ-yJb@o^<y_B1gZdO1Hd0 zkSyXFo>bqO&sh;v{9(I1)eu3q#@O(zTNT-9K3r$P{b|r%A$XO|e3fNY;Z@p)3fUJR zdI2_V@OTqKPT84?W>KgPHC;Gnx#M3>>>Q+@e~wvf@uQQvdD*x}(ug((N&LqTz6K#5 znaSq)^@-qBw224W&VQqF6xHkAC*}uLT_UyEkqoA~NX`n|#>b7KC6juzmQT#xJ0G98 zQX9#c9F><ce8N75x#DHB)c9QJxG#k4>7Vir!%wI6i}+Yn<K%MO?<fhcrj#S9uPQOF zMTw15V=;L8C#gKo<FvP;8-U)Th#iZvM4)j6!X08wee`=|juA!g$yV(CKw=FR8w9}8 z@fyWfMcPSq8pjb_OTmro{(dxoRoA<0gViNFvlJm>a&hn}9LWk=9LI#>doCn)GYO93 z9wdV2%0QT4+U^T*k>AcsAbFj*3%Fm(7czYL*fHZLo7Ei*1*iEpFx&%XHaWZ%#&={{ z;zSlin2o#DD%oG#aL32$BZfmH^7-}yYM&nnxKp?=tar%Z!&wU81>`SfBpJkzb3T?| z<T>+TJz|@z7qjDSR@Z8C6^H1rVIZp`gDn=q(;b>|4-C<)KXEKvKXEM8EBms$6yghi zp9}TX+Z`{sfCAeXC47hE;Xo5(M}9$hF0M^a+`6OMJP|C7>HuYubj*--9jc$ms@T#? zF3+skS_|(MY2NLlwwiG8y&ERe;K!NCWL%ky72q0QuAxJcFV4|Co0m{63*U1cMWAZ9 z!fj|*$LPf-dDS(dfd+(2DGe)U2FwL?jpA9klGqSPyLAOlD|s!+1~G#kHbhDtxuIn@ z(xKTI+QkI<U^P7j$<LDnxjf9Q;5(sbShuSg<g$jir2fe)<wR0-+H2(I+RJ_Q(#1q| z>Ds9L<2M#LXiI`1I0hORx+I`w^GpGb<3u<GY{JM>EUN~d!np3?_MxL1`f?yriG=S4 zd!xKx-bp*39YjkkV+~(QWz&%k2J_GF<-waMz9WR;rhZ~o03^0Az2ni#lkogy)C1y* zZS54Ul+(b&^q59uh^@X^xbcxo>Bx{a1=<-5X^?yS%yyx+i=p>(?<YJWqzUDK5cZo+ z%A1A`hGEI7wlF0nC6BeW{M!?4O=}EX@9#jer8&Q8cc96Tk5y8MxHn8cz|tK@I4dSm zXNKf-78PN;<1dTae;e}S%EjFI5+g+k0OKq-)MKa{Dz%w?a=kxxA?ltRDfZj#OY(LQ zfKx6R<bqfOfNB2-7Q@Dsep6WGqJ8pgBe|dSHLzhmn!75!X7$CDB#2eLD!KuaTAiZ2 z*%G`DV2C`b*F5A_536I9moAr%vu3sIZneMRoa4=LOf>PUk&Z}sbuMJJ(TR9ImPM&5 zi+bKUrG9#Zck=9tffB=~2g_n-2`N1_f+H+`b7BX))WS_bp!(%L^tNZncXhga%T6Sr zn;)cr(4o^7A`iQncF7U3P2k(wH(#s@mW#Y}fV2!rTG3erH}SX$W17`PBsWqX2N;ZE z+!n-+7axUPMe7IY7J#+f*S$E%$RD>XrguH#+3LHI*YNh;6AXh&lrDJPwZJ~-_VMpO z{#Pz;$NUJx83n2GYp65)fT~mk=5iBO*usBxcq@}htYk7L{5jJYBywf)<d!rXl!>*< zPN!q*x28>)vDR)^S5UhfM=P@EeM(vMQ)jj90)G-z6b57E15z`$zjiUYpR~{_vOcoL z#h;`(=?9M6`&mw;*_jta0+o_4+IhoE;gY`ejXC9VA@o^idjD%GuU^ReSIf9_+3TtN zlX**0X<fFi03K}1?)tzCRv4FP5E^Xx0;H{N)hEC>{f`Ld#qwNbtLAr?4z*3NQw$=m z!kw%DSR3qo!<aK(w!?vcz`F)fKQz}%r@30^k$;U<+)k-c@Lr}^C=91S`nsb#sivuR z-FfPui3$bJ@{7ho1KL<?!T0FsWy+3^u)>1aAHNr#Yo|zIuoZ>0TIa9a+RG{3z)j2t zl=p4qz=r`(7a8!%z<?@O3cku`aMl2^>&WetOv*W;sclZt#9COK2d-Af%htc*%yYL0 z&R`;=D=*i!gnc`wr&ZnAbCK+o=@Nk`TqLd@tDN;B>I%WJpr&CngqZTCA`?Td6o*9n zBI<__i6`NOHyMBVNaH4$;J<XQ)Ob-hhAJw*{^C%|N#vK~bU`<3lt$0f6I-(UIcja! zHj58o<v6Xx?HBXW_uJ+V_4HFq%Ixyyp7)Tg?3Y_QMEeA%WYdg7Mmj$-w{ytiLuc$H zD~Bl7=ba?Oj8~e+BqUXUA;W4^X5%q8M*YA>@d~7q*1M6@vMY$sSU61_akO1l$$rK2 zCPP|`IVD(~SOnCMjQSF$kM8fhr0Xk_;39j)g?T5C1utF2bitinIGu|ib4o(Wg=Fwx zxW+8(ePA@Ss_vsN9Xc79z*8$`dJJ(z2~>%F#VsDnr50Ea8G)ftG0>z*bpv128*MRU zx$wObw%~H^dQn5a<6z<0N{NCYgcZBL185f~)6Y%h7HN5J5z|`>gO?z6%v+?j_KFQ* zp5ll+Gz_id3_fS*8wJONa_c>r)AQQCC}zLH*xWkY$y+NE>aK_Q*Z%*Lz<Lf_F@Pe5 z08#82R^>wD(fS?LXB<d}_sPv)Q_nR@D0?<Fx_I-dSVyg{zEY#qpLWgOpb`eY`Vm|0 z8*?*4S+hvsh>y9L;ig}jRirGco6hp8+npu<&#9&Q@2=z1z8;R_t4qD_(o-!N%09gY zoIl7cga&2SE*y%X>h<w;9-NnLO|m8wwsEc7dbg^gXeXxjDVvB%EOmN64#|~D(_aRs z>;RCPA+UBd2|ZK=CP%+fsz-?1JgonXTCFVd7FS*#<Yj^h8K7isiF#Lxa9#}Y^gb9# z9&N{SlN8R0*JC~Bo6KI47zPa5@hn>yJ^0QuH5S5Nmw6m~4tmzPL-^*+Cga!~+yjNc z5bfl4_TQLmxiDAUrcdMmfb;e`*WYT>{ZRgFgK6CbM}5a1x?!T;IlPP}OcS|_K2cWL z9O7ba*39SHx7165vT4LcjxRh80NXA&cruc|n2G0DNmYq#mD_n$CV|aRmdQK*rxo!F z<-ad^-=(6T=RL4iGb2t-0dPj;3W%N+!3_{=QIJ_w3jzY*oL%*i>R97HWf{Twj}gb9 zMVMjWbD&Q5MszKnpQ$%wg51n>VBwp@Jvb9+_^j^*V;2L7w^ogm<QvAC=Uxu`wJy`_ ztRNDNlHE!|rDD4T-Kbq9J;tPkDlUAoSy*Vnq<Bd!twTI+x?D@)%Bv)=x>SWen`pZn z_Lv4camjY!u^4NK0~-+r&z7_Q5{PEX&<PF^Q_Xc5IlPNDIV{;ZeQqYMX{ZY1uE)`e z%4W)?F5dz1TDxrzPR8x;BCPjjF2QW(dSebK?n95q6EaU5IJdUA>jA8i<1lqiCw00Y zf}~8r1UIW|^H=_dx(RTF#Jx(_{*wzhzQ&@ZmmOd*fJwMJ6N-L6?G#qbG*8D7)mV6? zML^oX;Rq?^)*K9S`V-gc$B@+79XTp1<~YDkw}`k2&&ADzo>aA?FJ`)(OR+0TY+&Al z8_z>LOc8(RnV>zh76*&avCcy6dX&8P-}KBKR0%lR`CXj{$aDa&K<Jr#3f^FAfGaG` zo27BxJom6aD4N)S?l)IK?NVGAjrxwfmAk{{{F}*XWhbk?W`dYZqm0liyC&aSxvm%b ze3+v<A0}Qd)Uzu`IP!T9m0UN`XSK+zH2Ktmc8<tM@cX;{kNEuHM?v&iQ3edr-Qjpg z{eZsIgOR)dK<;giZe`MZkAO;Kit=k=|BOV<G*tRN%*@0QZwDM5rPcAGB~`b1CUuzZ z6_8u;cT9CutNPSu^!Vs@GCaDMUkh@ui?XvDE6AJ410%z&@Ra|91iMX8G{$sQzO3g| zUAX~*4fE1Dz<Lca_AchO@dFSy_A2x3T;N+yPK7_G@JVXL?{DBmJUXg!aRW)SA_t08 zAE7Bmes^i{SeE&Q_|f-J(2xplk+XI!x0fh*6ZsXE-Jm`p$Lx8x2}_&8szOePkFGPC zaEO0Geji78q<)V$_$2bBdFC)OeA&bs7xV<}%v#Oy*Q^=d06c$j1PKVh0QZxG2}4+i zni3qK|ILuWlGN1^Nv6rUmElTUf2Iv!?DT>GEmWl)61{M=LT>}pqEu^dlI<Ua$w{$* zF`o5$wI#7eO-mMQ(c7%L?dVjpNtIw6&Blwq2rZ&aC)u!4tawChU0Ce2S+u4T$<@bS zzxt%_p2*ckS!Ljm?1^4gaQw?Yrz-yUC9mtTb%AXh=PNLTIZRbY+@uZ>?08@qX+sf! zb%D<EGR9tVx3@l{ADH0t5!5Ge6`D-^-pQMOv`=hF`tw)9p^DKbLD|%^V$8^v^IL9g z2cvcl_y-Z{B*MEK-=SP4=-O~3cQYlh9wfPUO4N$*$erXx7$Y-sv@XIDKofzaX7*cv z9Y`*UU|5Tf^8cG(Vlrxy@VJ9f-o7@2I@d#*{txDuPmmT%vEgVjl|&hj*Neb%A{yWe zNrrB9$S25Pz4{d>n?5*+1Iil&%4~u);Nm%by|?|LJ;R9@Ozk^diF`J$<PCC;hh|ea zeNE4q;FgYI$o?($ngqEH!zP|?y{}0wMNS|l{dtx_l6ezjDYi!@t_{3~=XSRr)eXQu zi@Vi4?$F@mOlR8D)KsmdsUWg0L0=aiXBP&*OVykSA-<)iKp38;wr)3i2#cLd@UnaQ z>J(rE^gM+mKcAAMj8d@BkhHdHCu!03r+gK6NW9tXssM>vfT<8uY1AV_JbZX=3-b7@ zeb<`8m7`&ks;u5C;wn7;xkr>(IqI}e4gi;`Hdg==vdVH(vU{q@$@vb03%|U6#S|{d z{#d8NZ^<d$A`4=AH!|Vv1zF~z>$w8OPrt=$0t9p9-SOt6Q76g>RS#yt10uMm^97Ia zV4(O1M2XvR7d9ptQ${QpwSZglpHT~3@T;UhU>)~XW%t%oS<k)zui&IRj5d}lHF=+~ z9~Io1#yLLuyP?-AF-yG95#Q_qNMu{ITgBDGFcotHztArJY8av~%!WyDa4S3tp`E)0 z`<<MGhWKw;9OYWU{oT0v>NM>-3t`SSGfHT+>%}bo^x+Wu96e&zjfS0a4v9ez+u!e( z%Cw>-4OIlxJ^>pJl8k-}h_jiyLiXUP2otcCp%E4c#f|4S#K=A$ZXDVGDd=b<=?GYN zbn^sFv`9aT78u$gdX-z9du@2vfaM{st(rUU0}Sda!R>c(0Fx&kYTQiyj~nst;1_^! zx=$RTA9-)ufnQb6O#W)By6*Yj8`gg#Kv00Tka~8C1<-K%7w-cGD8BSP;1=YG2hh~N z17E+gVlM4Nh>qo-DGr>XE5gT#b;%oPIy4gn#Jo{^f%k5|Sz2FEiaL(yA*In8Z@hR6 zCu<%qm~J(~lY6eLS~!lTTx;@n5ShX807D#Gn{-PVZS>gYrk4jM%f<~XBq_uZnCRmM zx^>DzBG;C}LkJ5I@Lgve?w8y=JwCS2;48#yfuD|$rho_MA(ZIsdl#_@z7%Br9^1hZ z&0AhZ{rD*oE}DmX6b}N}WfIBJbD1I8i}bu>{VSw74r0*@Kf#T4;YvwtdzJPh%e8Nx zAc5B?yYyQ@irxR(6M&h_aHZ-mJX;@XtzWlk?0_f2ZN%&$8(y4j;D`dJ0?&+)=>|~N zq;5?7$1?b-0$@<J5JCp(+YPt`F9-og^6!9`RYmM$2p<D_B*e&P4rLk$D99bKWHj;l zuZY-{ZZ#PsDMrC%m8^~HhI5K4li|@E{55Pt$|X9fr<K!35u2E3owZdQp|q$bVfe=0 zv#yhx3b&}i-2^kv^lf`y^pIn<jNCC7Rf?{~R-jbH(tM^+wPDbUCOW{sZdsDWMN59^ z(4Z`f6=zHfL4A6Cym4OAao8-d2CYp_zAVAI!LyXGF(E<LsJ8@w&f{*TRK*^fz!;rv zj!FODo8l-kR;d<sh|GSgAN$S`B<&gK&wXAfUp_nHoDxd9$1nlY4^8+M?5=UTkKp<W z<`S9=izc(i)nh|{=(m#dHo-L*yeZMzwEJXTNF%NDo6lp83E$h#5}Z%(%Z7RZ@cz(S z)7kfzb;Q5y`!BPDNAjS7oxzuwUhZBl=DTUT`dQe0f-Rdg67ZEt2>ekNWOW4CAxXcD z5FTy3KcRj?JLIIrFE<Hw*(K3Dds&Yf0r4xMKBFF8gKSLWinzK_T=eO@B7<(Hc}DJp zi{m>zVWLV+k6SoYp?MR8uYQ((J@I2jk~iE3wq8niW2EgZh7$1u#1tkNxLFPkR;Pv0 z9~NGw3WPoR|Eg3j2|T6tLSXB|%Q7wxLtz6iINs5;o@(OpvW!*?ANRG?@*+_#KLBlT z2I~HQNN|DS4}nD@?2voN5J$!&mtYtAxl;Q(tIq)XWB_{~uERa1QDvF;%??x9NxIr^ zGiQLGZ$000pnce9(ho)6T(*vk6}v)r&)NY&J9gH(#tAK}b#-c+1mwL;SCB3~gMNQZ z;#GuJREfB?ceQwD@XEpG*S}knW0oLx1+xjOvi=b1&DkEGOCVew0O5+b@I9<t2_O%W zQZe>hEB+XUgd9XEQ@t|!_IJ4#o3Ql*{@=7=euq<1Y{*d|bOm-19Ol+0g0i~F<$j&9 zSA`UGo!738jow0PkcQfxj<MgTlL0Z2InXdLH?H8gs|asbx2$@$J?K+cnBwWWF$@Ec z<zlX-PB9JV>x8KXk*A6T{{`ld4CQ{Tad8wl9OuUYn|SYsfBMp%9{xx1IOTLnx@26* zvs%Bft2Y+d8joHrI(J=PCL;4hc<bJ+ntj#pfsK<91_Y99ivi2j&U*pbG*1~>r@s(2 zeU8N&*Ug23>}B#6_G1bZfY;t3`n|PksRHrpL>vr5UYrF2XJNPo7RapmAVv)j8L_2m z^-$K9B2LrYKc^T_*>u3`hjlIxU`B*74sSY;y1vFJ!BLEu4x<a{W>KQ2!Orm?N1%I1 zDXYsCS0adl-s`2-!2eqm;3^_1HwB(o>>6OqM$4YHN=jTgeCa#Y59`{E-^1h%`^AK- z9C3X-hhDNWHu6yQo;5pw9cPch(luX@p*@tv*N|BjU1}ZeXk1pz-D|hzKe}l?Y}l(5 zmnwAY22Z4-x8DTBO$Ix#{rw7WEtPyjfU(`M<+bA5a7gmWR@`I<jRVnZ9)4<fZ#RZq ze0((huLeHa3^O(NBi5>Ic9j5u<j|BemM_Y;Gu5bql+g^^-hlETITc=&0#(Uphxm&G zv)Lcop5=)qV{&`JlM&QP!6vgl&ZeGZ1S;7<#1}YQ68~q@PYW=HL7c!-1=<t@LLF1= zP|Y>FlEI+HM{<)MaSwr_wVzau5NqZcaOfZ6X$rJVm7@Xxi15LpbL!hEUus651c1^E zfC3XRl9()gK+QR+uO=YeJhL@ei=IWujc`r^eut?Pr!z!^QySom2;A}i<_P>%JW$B; zv%|oJ_Ou}K#efl@2wpU8%g8>i+_x4^R;Zvl-e=EQ<gc4>o4lSp5PmX>b>vZCS%rTc z-{Oql1+lb=<-W)*O)w@yaJtKzU#KPakF3;B^Xp$hM11Igj$?r%z_=Eeef>A{Ym=Wi z()L-wEoSZ1(tJ&Ulh!ot&3@MMPmn{cx3Zr^C#U#dyoOv2;S?43|Cm_RSLWDX|KpEJ z>8Prd#3P*u*7w6GAp2qR0Ln@biK=vkg|bgnpQ|Wd6uY4JzgP`~f#_3@S{ps@mWVB> zH@ffx(XO->#9(oH>?cb@cZa3nE}d;vJdD%|9PX3{#r6noN+PAozyel-Gbk`aYEuzl ztzeUWG$TD;Jzk%F20!Po?QlOVzy;&*o%5appR#&AY8)U}NP2qy=RorrO!@F8ygrW@ z0KuuaU&!1O`8Z3wgzwn_X+bx_e~JgnU^7gvq}cyP`$+6?i9B!W@_1ou-Pg#9jS0J* z6TSd(b)DPiS`|3QbVfF#<`CdwAOIKrY#4fn<(!JnB~?@xo)hay#VgXfXdRHG<hH!@ zRGDK)5;bqF=CB5q^HJ=F$7(m&rN87_O-lSZ-zZCi3`9Ja1xW`g=0-m}-F{;tQJB(k z%SXYAqvf3|`rX4Bw9WF>oCXx_iX!&~W#FP_DNw7dmnc)EjACqZzNBBn3Zvc!=Kwh4 zX9^3fu*WHZI7(g-SaMBd+|X?*E5y6kJau5?$}u$*NK+?xd4Y8d+dnU@S+RXVpd~RE zGhv~?0sA5Cd^Aw~XK(UMo57y`#xSVv@b`wBC89&gUbzTu9T39IIGn<zV|*?a&UNrM zPX+0QJJY=ZD@OwoEP=f_g{DFC#t2|M2y)|pl_vkcl_sDfKwW@`bQA#+aJW1S-qO&s z-QTlfD_nuj()!?_Uv<tzT&hQN1>w-saPzMiR%9eXKQsTDaqPllzqknU#^{2iM)7-{ zfry5@c(3dS_4nJi4L=MCt*pWg5?!I>`?~W9u5h;LRIc_%h=%0IabIwO8zf-<@6|{j zl%)E>W>oSm<tZ2;ni5?gQS+#`(^zxKE0e~%wsz3uuN0yk3@3JBh~=-?WI=Y``b+vK zsud^8l1OSYHXgP7rZiWq`cQX4;>1B~>g*G*34hg9IqAEplyx(t?}uMy2i68jrKM0W zgWF&4KX*7dc=2w40rvg(kMLWtkF03cz`1us+Tfc0#bg&B9<s)_#Qzfw@iVY8u0m!i z<Y6|jGO&OF`SrI#aQ|{1Lgsfm7%q{ZC$b+sAb`ApVG4TWGhEV~`|*)O<@%y^nc{k* zHcDY0jC>MLuTMMzHqY%RsbSU<tiJG?z1#`2PbJ!(Suz8h!?#)Cwk5hcSp&t555jte z-j*}-965QY@5A5>;_FjPfB?^A^-z)ZV(Cy=c$4lUNJoKT2c-ajhDb*<skh!P7qYme ziu&f^Eq5r_7GA-T`yWT(AF{WY#&k1<CrggSBx323vd;gEAC1-v$wOjFTGFst?Cal2 z!c(nDR&?TzqZR@+V2_Q^5Mf7UL$UXvqXP_Lbk*b#hDANX!C;qDw;D;rx61#4yz<cq z;1@t~C#?bcn|_XcF0Y#XyzS4e*Sts?bS&hg1Q|?QvN4D#{pBB&soHYvUnwbICGL$E z96}thd=%F~{ojfa2v%BpR7gV6mk5vR@Y}-L<Vf<ZKHo%T7aUuC>2rfomv6-t0ny$X zSvDhJ`^mDAUqNNJGnErMaT!*}J`dd~Q{YT}w>&{&KZ@jTkph`u3#|)bCg)y3kS$45 z7KTrFVEg)P4)i}SS9&X>T$)&(waZWa)4F!70P4NV9yxH-M_e;5(*KSb<Yn{R{E@R4 zLbj|swt^1*Ynk<7ZG`ZkVWJwDbjd7X+hueLk#huR#eS=8i3tEgh7kJ(K6QE8GLO0@ zkgBDN3##`ZsifeH`7)x5rVA^VV>GvSXuLKrgv!w)w^RU3a7#Vq>bFI)O66wM8p)Dx z{p@MZHvUqau`>uhM726%@v$3<`q$s^*TH%da#3)1Yn?;Y%BfRKdV46Q1jH0D`}x11 z!yRGAB{J*?3(Pr?x)K6N1`sBpzeTo#78!`rmgXZU{z$>{X*BVT`6E=)aYE#B(`_tT zKPw|X$P7zzj+EPPws6SOIPg|Tblt%$Ew{<IWh~=BG|>Bqvx0&5nnL}hJKjq;4jWKo z<H9*|!gJ|sTL5)j*-7m&YAt3Z$ZF3g8KhJti}AG?UoZN=)8ND3FjUk8C3CPg70h3Q z#!#a?z4{NjY8{2Ud%&`XqYfc;NGh6*EN!qea%1h*7?*yd(SMe8RC7};uuQTn5;lfo zK(VUG5b4j_zj@d-<K<XusmeR2RoDQ-r;MGDK~-imwe2<7PKSb1Hb@>B^GpklXnKz< zp^SMs3cLabos>$0|I4j-rZ1kY8y<A<$Q9LYu+>pOWRl=eLsg<s?{V%N;<WvY^CzXn zQ6u!&ngk3Ni#5aTwS?w#vh!DYZwpHRjZ7X348gAew|>W-rvNTN7tyni#pB~!XTdMn z$<~M<<hKW+Lh*=8PZV5w?79=4dQr(&J)mKY;TR;Msna#24I~8K8?hfTKHQ14wgEWl zP~`tPzJ$OFe|5G2%$`Uc`3putLC^!u9$*wc5R&2mZUt?GAtgH{d(=gc1`<xaFaXH} z8vfL72CfF`4w1N=5LN~oupEU}C^y`5!d+S0M|#JUSCvY612EFu9y88*+ey}<SLhyR z@9n4FBxkqhTNZTuc`IeV!t?wyL%sJuhaSrb@VDqX*q2`4+Y!B`RHyx3Lh(iYkB+BC zO7qIEqM{t>)RpUvv;y+<$YcV)SMsI;kO!p8a$Alr_IR%xXZI=5(Qm`|_&kCU=fcMl zyS2phtn;I*hxywszg}QlHp0!^N+W#pcf0x-EapqE1^W*%&(q}wjkRWT8kKp%-r4bG zcw+wrMAAu12aMLn3}Wj4ODs8SY;|`eN$Uv7t0ze#XPt#N)B^Z?-POO@#J`lCTB<&Y zpdy}8QDRP=yb?6(5hiZa@X+8=O~yQcCZGjOGN!<Y^ECJy)C!Nnhx?&H+4L@=(wJXj z&2Dj#*GrF;K*0e<gfik%$fn8WOYs|E?W*@XKOu`K15(}*wr{NqYhhpqGQ*#6!xcH8 z7#hoI@I@>*^2|}tR&t=m#)TfE#kl;7Owopr2_JLSf@t&1IJ^T4=hm2Pkb6v2Wxpd# z3OaFK<j-~4jbINw%uBee{x;yraw0?ucOOgu<+%!0h#y(o(WHmElf+H+AAiVLq1I1| z_;{TA)E9s9pn0_MQm^>fsLrjXJypVxRJwd&I-c*CQM;37WL!C?Yry4k9Do>nB=(AG zCDnZUbba_y!qjJBkmqd9=-asJ+zv|wYn{F8_A0VwvXSvRo2pm?|0wO7hjszzr+t5A z_3WTfQ(-Ce5RKjvvWl(^W_TOjfcWbk|Gm=7SC03QOXgCLNx`1e#262GsiDB9$`h#j z&<5(!tmybnTAqy}+dL?#0ZpB9Z)(^l4uvsrgL=Bh_^~&$;gDrsn#z`XJue{b4V!?v zsRcR@V%Qto*P;&R+20nri#$y?^G_mld7wx{+25kNXrf&C3E0oj#H*@j@G-tnZCZDO z{Z~zz4HUwV5pNy1r5(~=_WyL$ssBXBPXiLwlt#T4e6AS8$OVOH$N$lJI>^Z$O{U@? ziq5UG%1yS1O1&`13aIes^n1YJLk2p0Y4og&936Yit6A;WiWPN9bNJHBM_lh~Wat-i z8<HCtm%<SAZ^mU;_dh)O@oT1Ow@(!=&GQqgsMb}lAd5ZZn_q12pb%RO_u8oX&rI(S z#SpHz&x&~bA56aH>@2(inU`YAQ(Kh_WN0UrlCI3w=0n~pGG%!xJ6LicNDSE9c$4`# zH}Fn`gCFNF7XM6R)%WebG-~*59C%uL%P<tn+k(Z83mt&%xdGz8yN3b2S9<y#9_bq_ z)<u%LP?NSWq?_7lt|Ikxw4seo0zY)C1#IwpJuckz7`6=bOE7dBv<yTZ?C^$G^g>up z{{)C;QNKwW5dIS&`d_Qui}`2zkTC-Bc@Xe`0EADFdFgn@+mA+q(pGuU`$&7ht0A{I zzY|cl=LrK}!jC@;n=LUBT4HQA^aGF3exk08Qga(G1{b4WHE8gPYFVKs|N0{SDrs{- zLMbO!@rjVz=`_@Oz4q(ea95hIi#|U#qas+n1$$i{Kvn>N$gshVi>(OT9e>#RiJYUQ z{7EmNdWQJX$D;S<;UWrc(93U3bKWc#HQ%~B7DxN`3P&GZpiW)O&AZ4eKgUivB_CBF z`~za>Zq^J;1o|kfQDp;QQU1QL!F4Nz4{FI^n{5|v;`UKu1Z-+32pUP!k$7TuR2943 z@v-Tug4&(ce;q)KXV4dR;{puX8E7pvk;YY^Vp6)s%;6FTum5NfD^@R3iU@v19p>^} ze0GNWPD{x48<z%3%pH)H{5yirKaf5?Lyjmy*iM#6T<`B7QqOmsZjbqW2qe|O|G+BJ zji4zky<ea-KnX?(3!1v+WG%zV*lM%AtS9kmt?O1Emp-{l*wwO!9%R7E+kIf{;#cRW z9@1MWo)d|~z7?92>Vj$9<Xg95ewoG4bxG`1g7)xRrO#G0HTTYY9Pb?b-6kncl!Q3i zf-kAQVZoQO*e%VonU)#<Fpva!;Io?oSVV2Wt%Knn$<3{k+%<>&W884l_u-(|@ph_0 z>l-lvTk6YLh+!Ka?PUjw^QbCt`&8Xz?qx<MG~W?}MA4rvdDFq;%Io%4j!jF_>cQ$| zacl>lzk%Vmjhm=Ol6&!JlEndrcL^*^%-r`Ks%zDnG6dWBZ?I8(aqsw!6Z(uq|3t(Z z0z~gAY>1c+1}~MAX-EpyghD@==@Ni};NyX&(5J01+DN{Vq3>X5b$*(UvD@4~YEe*Q zKe@H&Yg9yAUN;$a2c2~Jh!00y`)xO^*Rnv}Yq2y!R)rcQTlw5rcoGL@HNL|g#WvWB zS!gBQTL{W<%TBQq+qLV?E-ke)7Z<eGreh~Hm|OENOB4u0H^ZfK;$Dy7d2zJd-=2~x zQZx&m3)pk7U#DA9Ibi{OYSJn0t55)bm^T*X6&W_ra#t!iKbi!kqCf$k?RSmQl{OL9 zcg*<Ylogrm`=yBRU?#V8V0HIa&t7bRP#sq40n{a9lTT#KUyPnN2j&}G`Ne*TGmz6! zeutBnOV1TAP<YtdDOi8OH7ahWOw0}`6I01}es}5A!QQaras4b%9(IJ~`Hn5^BZ5x9 z#6b`9g3%DYtz$}S0-X?8=pNN@iOvQgjbcba7r4?Gy%_-L3SmdUxBlCJR_Ndg*67xa z+(?RjA*v+hKnYdZNuQ!RzfTeYmj09eoABLatVphQ?#7{M9O7et=Nu}wi?j&zOkRcO zFD+l)kO2<by$2ogq(ik9&S-mYZJzXtdSQot&mw7CmU8*XQW&wWl9=}Py*zAYA+Z}X zPSh!jq4i#gC2G(nkF{1n7YZ;MzOTWJ9#Scs7fdjv!JFL(gRi;k_XkxrF|Bfu_=j=I z4C_KS^NY-P<Lp~3K?P?Zac;;4L>q0XpJoew1tPXRKwF8(ppS^v(2P-^{_+b|ti=$r z8fusm`#RZM0c9PA)1ZCl>+-#|s=Nmw{7XK&pHccNJ)AM6k<M&oOKr7Liy{Zs;YUlK z-w1eLZRRosMg**yu{89PiibB`fK*Z$VjKgB>Ha?-{z0q{YV4ytbHT`W@PR|t50QcC z-#%IrhC3wNgP3@Fo~70$X?SL^F8L2F_dID@nA2X9S#J^DpLHc6$czB|h>Zae3UnbS zI`_eZ4E~#Ua5y?-OYmwG6u$Zr6ltrpnYj<yN_f{xa0H!<h)}9B;|RJH(lBk$yOEO0 zBJsp+#7+8a+u`QB-}Kdfb#5`xLy<Mfv#@D`8@n%kET&79hIT?Lm|>zWgzBP-a&#;M zkK>+oNN{bGyLUeLbfiE3Ma7v+IjJ(SO~hY9HOiADBjFde?h+-@YJW|C$$qS-PR4h$ z3xrB!q49;mV0Gi=qMYec5%KcD=Yy;K4XZpYQp@yj(-kqhD^Vk0iz*K_v`NFmhAEby z|3Ro(ZACqeFm<4LDDA#s^@_T~y=#ki72Tnb<z%+<oyCS3u@Mj>*_tY-r#+tD>uEU^ zQdaV6UwrI|af<YyK>-((s1l#O{0=C}9|`;BE>>sMFEQh&?WKP(_9uibgG^9A{Xnk^ zYO-o2<`B61=EP&e|ApBh7<Ee69g#tLsCJs7e}U|X2$39Wa=08JcqE}Xz`=A401NzQ zIb2Rw3hhh}zdEZa9QD2$We?J5)fr8&WdKH9{GKvZ9M~LM!;a_Dt=<f`W{rO^QMm!b z!mymqmS323XlWMx)cP<fKR0%Aow4XxyhIwy73QaOcvY<Y@_t_4)k(fvr=@w7HBH3k zl%;u%4h0ZZw*A#6txcCht#eq#W#6Y_X(z)^gtlhyojvouiTK6n3qwO#Tc?sQQ>e2( z5g8N)FX7%<ruB9DD9m4mqG%@S<hmuEJ(h9<{lXfK*t9-Y_=Lc8T}c1K#ie~yA5mF< z#$W%&;O|0yt<J+xt62TO%6oa!S(t@ClqW()0z8DyYkZ3!u>mgcTPfIcI8>awI@Oj* zhbJ9V+UGSbKwU6QMX8@$^qz2f`SyxInE*2o@Da4#I?KIKtCk|d)Suu68#i*BzW1T> z=;@0<I#6euJCtHU{v6){Tc%@lI+#5Jx{!nft{yl7gP6}vG{5vN<7BRt2g+Sf-6lRi z)XE@VfVo!d^Q8d9^H}4+$iiD(T~jI(HOUB6f`2tqfx7XS3)BswlfK9~5nQv<0v7^J z7w}OVKW|g08pZFz4KzIXV_D#<T%4^L`U4N8oOPa}@sb?aI3o`#OH&i!%pT{Aj@H(g zM~|eiBTY$3Np}m3E|#*CYKu<Z{1h1kPKIxiMWTlqMa?23mdl?ErOKlWe>_6RSxbCp zT^7A+(yQ7DJysb=l=Yz;>b74@F`>bR#R8xQH4I~-Z+!Usm*GA8#}kVi8@{hR<`8{D zXnsaZqN>(bJL%3zUsM%(2@h;eiRr4LVRIc4^xg$q;gHJ87{fS$f{Xg(YkUPq6En6~ z4VL6C-`9Rf7Zyf3$H*QQ5vO8blQ4Ke(OH_888a7d{PJD<$Bg=A$eP*V><wV^;`(V5 z{}PW>KDvfsp#KU0<1AJnOw>b1GteO=2_h1mU4NwfvPYwucs`#kNYQ4_3AZpqXm`XK z!33n_KCjIN3hJ(B$mPAbVKaCfYNq~A{m9_(Vg#r{8DK_WYr71LJW3zc^loZ(2;-26 z)gRZ8E4KJ^6{^Dt`2)jGEG;Z8Ra}QOS5{^R>)PAf`)*Yo-h(r;ncj}*WwH2LHIeZx zSz}pwQD|B`Qyl9TvpM?cqL+CYu|@cLNxOFC;m(S3^xXo9dA}Iep+|1M$qUVy4Kvyj zG&+4{vE$^BoJg3RgfgUR@3%*Clz+27R?u!{1vG=@#wwDI^WZ9vqU2=`G2LWoC7?@C zwJiI4ZXP(MV*~rf_#S;PjA6~UB?>;v88d)&3P{%fYdOu;1)lDlB9WxT(bYV+8L?)d zefrIafw|?8GB9ME*untHa8|ssj^w^K-Ggt<b06@6L?n{b>xj?)=GCF8wg<ks7XVKV zGW>5L_QDmmzQTU~1YrQ^BtjYaHtCS3k@nAPLtlTBNcZX}u~2(jHx*#5;L#Gk`Ktzs z`vqkT_@@ra4r-C1OzIc$0BVsD$8!N}#-NS7X`AiTuC_3NWZ$`Hex0GdLYszYEJ4ZR z&X=%yrM@zIu}R(-ZvC;R8X!s()qd`q7%{VtjL?cK*CLyxMOrlExuVzVWnWvWzK&+< z+q0l?!&Zzfwa#p48T(rDiPop_(!t5{$FPiItzNPfjDh=BV&H1ydBn5D8r5Jvb`iXb zCgYNwV$)ahJKhDCBWNsE3joJSo?33N2r+yBuXFg8WfPpD3Erm3_O{FXUsqEJ$t54A zrCxlMG?`G09`b!MP$c#23gXN<GJT%^R|%ATH6u&|3BbYv9~RhJ!SIhvx=nl~sy3eh z2m-BL^;nt?8hJbJir5pk#U)HCCFZt3v+!n4znh4W?qJc*5s(%)tt(-&0$TBF!fgK> zbXk?y?T8N{mxK|I)!!vkqY(&_09YQ0x_L|ZO%UN>Pj8wqAey46nQX|WiDX}VGBl?> zUT;lRDm=IAFg0)sSW4CFXCKPwD<~zlDAyQHJE%>Mk$tb3bCT8<wkUu&v5W}@aeY;9 z{Sx!9#kCCB%c)KnatOf<a5*0n9!VR{DXW7-p-h)$Q`s&n$(;1n2!Czn>jD=PJ}t@8 z3xi|p6YAOY#T+~?cBbi6Oyb}!2SGxnKtMRn6KGM&hGlP*N)`G=k@M#Zk=qrMfeh>G z2{cF`COaT2O|?&K9^4g^OTimS)Z1~P4ds4IZtHPR<y3ymZiI9G#1dfi8IK>yr-@=U zaK7M^V#zQo@)|vA2^6^@%r007>4Ay=rd5LIj977U>0txEuQyXPd@zrt02eUl_+}6t zc6-|Au6>Iau*jz_mxRkR(yIVZpp!uf4Sh}j&kBX2hfx0KGfotNg6&Rnu!Kv7U}@j0 zH5RP>H)PjC{@!fAIFUY7#-}qa6>00b`9zy6CNuWL`hsWVmfH`BnDJP2w)5AhjG-(m zzTdeY_j>Vcf+s;cjR_xziqOj1;913O+)^#BZ(4umRBtjdAXk#xa?&@r0j{-GGcRak zND<#5<`UCF-bi-Rld-UOD|AzvnuC5PGN!k$_GIXBuWO3~cR$HZHJL2;Nv7#<6Ni40 zz3&t)ANs7^!=gblOt)OticXmLBA+#o_^(o6Y)MB#HxmJguk3pKBB_SUmTpRptG>`) zoE3qA8#Gn`U#&F+cyR#YX37|Zr}n2Db^b~)m7tTpn(`8G3V$6Z@$M>;h4c;RvG2xf zU=(;@2!=sQKR8bV2$mH3HpPrpbGI70g72s>*uqP5*gt*Ta;W(wtERAgUx5;9*<yF} zU+I@!Yh;4TxR%wT$M2<<JxTW9T18O>U%oIJi+;S^5?TIbY3$|xp5;r6o6G4c7hZ7E zS!liUKtHxVvTpIH-8BmGr@)*)pyV5#Oz<3YH|?_+SMvQ*0EyHzlFx)l`rAkn-+~L2 z)E#4CX|k!1&GVl9D`#(QydW8%ZGoG9(%YrTu125We*t@&;^0iJpCSo;B%M*&z-JPU zog~Ra&_gN7@=wy|qtM_B7WC9`-VvjV<krfHj+?g5Tk226w^OY3{Sf#yMJLuLs-+Q} zoX<lDfkCO0@oX~B5KF!{=n~#C-@dH_=&kp#)U=sm-iz_SYA=BZk35+(fk&_m#Z@6l zvIK0dK+&#NI<9Tz39U#4;Y9GgJ`#ff=?+gDZ`dQJ%sFLWE-{YZa5`gu_fZ3x^Hg`{ z{mRTZ?e?UiEn&_gQISr+-R_^Cb|)2~GItdjHLFJ|sZ4PPm<SGtWhZS!(D?M185?#^ zbnzdgAIYIB8WHy@i#%nst$^|}I$|wIKjO;l+WQ7EYlSJP*iS5k5jFgq2hyBWx<7$h zb+yXIx(ls;tiIdI@6YSlag%+bRqM0VcsojUlCxr^mF&`?fEW`c!q@w%M->1k074M7 z5`DQLUa@j)sOx)TdLLBWqu+ho@BwO%j2~(#MCy{A`otWDdzC~}N3d<U%D|tTwJA^F zD%HRA?6%7B#d*ac?KRfy^W62Oq>n#VmA<yxrG+B;4tKjOLqE$rl*zwK&x1O@CiMh- z5%6N3cnG811Dg#8j3|5hSY80G#o>F%r>Kfbgb2Kt1ONr_@gSsbf}@j!QYV+*{Wg6n z*5>Oy?B~6tXEpJFwJx=faypQ0(NaMz&<&fN3XyP|cul*<k6^V5#e?v0rt}T@Q4;^h zp}1uF{!Az|*MfBL^S)24=4MNWjK0G1>(f3TcykhXI_M8{RDT2k;UrMjpdA-D--C>B zS40#8HYncRV5`<mW643T{Vux#lwswzDG_1B=V2#M5%i@b&$?{J`^Ce>2(qEu^6D+` zr37n<1QQFbW(GQ=1*z8yVY!y<ao4-BG&pKZ{IySalxO$Hc%Y@Z_eI!MH?$0Obo)KX zNs_Vr<g>UOrwq)5YpxFW6V2aT^^$6JSfbPxo$y9#i-a{4ePbi*7Sgh=$|(}XY8D?5 z7(AP2EM5)(@wx+uFG$e<)M%Duntx!G8sSd6zne%lD!+Ac@Q-;iKOz-CnHJGVq3pT1 z9-X}3w5G4q+|p{)_6FWh)P0hju;=9h2jLAD^SQEly@k@ax_MXdn^*6+k*X6yA%x$; zL)rY(Bb)eJx%D!pWgbAH0gRf2i2O2hk>*>()CAFfFv^*QBLwObJY_W~*QILH>R7?) zDQFLtGBZ>VHS@pP>zWPG`kx%K_mI2K{#_jPn2V+cQw=8FqYU^U1WR4{iU`)GAjH~~ zPE^Y=RQsQ-2DqF^h`R~y|2=WaoN?;r;5rwb&W`APW4@_OR<_$JK9TWu_zv2ABukgU z4*LDV%Az?W$*|U{vw7;npKqZv8o7|PZVLrwtaUc9Vq)z_XrE8pTCOTm^7C+SB!#>C zy@(HSK5bV&{z4hvG-&}~Lta<y4cmPEc(NF~&Vqz&ItxE-l=LEYq?2%Uv~~B{3^&$n zcsBa5zwAa}@@^&-19|`EOB-)blnNL|)u28RuFsfwI#us<xRXjs*IDdg5RDo1keNEy z8|DQtLIFF5n}ES;T1TpYUIiHV>5)$hkPROqs2QZ_K@0Ven{1idgd`aUFgtyL56(bL z{|c1!+OjT-9M8c;1g6wFzJWwSuH}?OurBoQ{VQT|5mNWw3_*?q7SunvWIlZFan1h& zC96qnlW~S+=X;~@pdU)Dmn2FfgbqtKiXHFsP-dU@AS~=Hi`w956W;F^Q(7l3Wr40y zZiNWEhYf4%NAXvqm8o0%0fcjJsP}<||G5)csfjIUovfka5%jF~NX^-pE3f^Qk>!5+ z07=q<ZLnX5lD`nRx`HN-VSN=k^t~Jf{YhW5qjFZxxKa-dEx>{C*1O?H;@1k<6f4`} z&GndVGHR)>b$92)nqN%IaywZE*8CNl^chk`=4S?;MUoFf&AStM6&v@2@cK_5F|Qf1 zuk(EViIJ{;%J=1{U}^~j;2%TLl^*NJg0)>&*`}bnhs6*2Vrv3Z(gLE`iV^UPadK~` zredi3KJk7HC`s;Cqa~_&QeA|D<%3Z11WZUD07Ub8odwuSo8pCb#*0V1D-7G=v#4=! z4LRF0EW&XTslZs~#UO{Qmf*Lg7>(pP*AUtOywiv!Ge~gXOYN+)?>zWfyz+S5KSwcF z)RTHd?K4{%=N*QBi&DA3@6*rKdbj2wHm<n+qgPWo_WtohDRmRSXE&8F<mIrSB-nGn zT{NM%t2BDyc2IjirhRBGa<*Abdk)-jfL99cmu#|3oA(OtKlY%>^4v);3yIFM`_GRR z-c1s!C@jghWSeOpf;(f<m`FKgbFa9w{uJOGHtWd>+IAe6mSph}V@veetEJ5AkoaWO z64{_{%9EdT+cpBT`LoTvqjw-?5qnYs_5NNGgaqNi&jO$@9$5KQSH#|1VOdScK)BC8 zYf&M(WCTqqy18cIXs8>(IYv=xM^4qrgr+pj;E$WgLL5~7rPT{&<Ql&In@<XJI$Xo~ z;vka_H+IwYnp6sG40K?)bfVG=@q)BpNsNc%Lv6vzqGl?dD$&6HJ?^@B9bY+Z$@E<% zf#l7n7R2pRUH0$kHzO_FMwT4J6qYmNv%E)%SaR`j?1U(}bmi^S*7ssPJ!6f@xS2Z^ z4JLjk^3yqUr@9)O3#Wp0rYq(@QIVB~+Z=pEl?q1krVh&7=3eewz9~v%o+uwmU~pb* z_44TR{$3SO{v)aTy}6G`t5<rayuY=9bM7a}TM=5LOrv7@sW<G1SSx2ke{>yPQRel} z`;VO^CFN~>n%6H{>}upJocI(nEw>(VEV67XY+8q4lB4uEC%LNyA9sezy75l=;iwp1 z^Yr>})a-o6J3m+VU4k_91)co*bd258X3%W-<4a!a_qKV>n$-2)8V*_}x{plBIBvDp z=#mmk*H#Yaw&i<z`N#X{KQ-6K##YU8xxqYPi}F;Ej8V}DX#}vrACNg+&It;=Z_U-z z*Dj*LR%Z9~Iv~z&LbKe{E(`tUtDy<_fmd7C)s?*f&wS7S!qRZUy=AOKQzy4r>!6pS z{C9%5>sAfjfaSNuGapdJDk2B1cY)PO57HgeNOf$o2AsKFKQLf$^4R79-n7(SD4mTd zI0+CnVDkyR698BXo}w*av%-!508!?@c@6<cm;9^yb!V11)mq3TIj^(*2hWv}EFIUT zj<WXE9<NzeQZKd<elD(CN;1hF%P0IvSA_LD2L_(Ll@fTX0^ev$Z&HS(|Eew3)*`?Q z%C|oHkovF=H4X7G{g2GNCX46EMT_~g#LYf^6>VZ|!1i*5hssua89^m~dJYQ>;R~kH z^_XaMrr$kQYc}}r-X}@ezIpv^Qll83*k+?xh40)ji&(|_(&}<g@ksUkFvl0qFCQ6^ zs&g*<LA=sjK^i$YT{gVo<1{>%0nMn4tkoBDVj)Q7Zt2?0uCKDy*={-Yz~67BAz<2n zNzCtZ0!u}P_G`A7^4##v*s(H;Vad;M#I5R77&igT4>lNgKMo=3@Xo^2xd0IIh>e7z z?I8Q|_5J|8?cmjwIjZT`inbGhnnhMCYe8l6qfoqN=GT?cp5#7}pH6f=y#G|PccWB< zqvbit0EJ^!PjVDdqdfv*k^2v<we;tJM;)Qb{FudWU(Qt<I3ew~wt&ce6>^ju^1$Y_ zgulTm$H_T@HYFhM=11W3SiTV!?{eC%`Mw~rB1~mlHFrR%Rx^#X;Az*=QdGZOi48xn zRr6O*#i%AfKzyNq_T4{W7fF8lRhWEE>EAzY3yBmPXwXH+sz1&B$bLRwqDpLhmBj_Y zHNz^!bijyl1jewwc2S+fJJ}Qpz2a9uA9NF-uKlUoBP9n<qF~)qPBpu;jnEsHS<Tv8 z*)Nde)}N7X<H<3Z{+#YzeX|P;3el_i@b-^w-`j4yzcl(vX8F)mfZxzS5OJGO5n0jy zdL!wb7$negBLbGl&KqkJS;fwS-Q<djejJs~d-uk&=p*Do0AD^KdXQN9{09eU`<*$< zIZGzZ))Hd3FErx4su*Y+EEmGNGs$9Ed_t_2m2=kKWbdVh?JaUZaey~xz-;H<Wuj3| z{u@renDOaz?G^`Ek~BS7ArxaWfSc5?M139`d<0E_5S1eCSMmj3`59WyDSoH--vt~! z=N6v?Yz^D@22}YjEna3J`uG^-HLpy4?JJ;Kf7K%2@JOkAed%i**nRWH2d|vI&PgD8 z=UDa>*p2-N8`%AW9^&U6EY8^oeg<R$71&V~C{(ZXnk1*lIP+}!{;qOmHhGaRZnbH2 z6Dx@I-!(6yy@B6b2J|<fXB`zVYi*rhR!sd6AKM{R>_N%y6T2i1AdP$gDtYWS`8!a4 z$XNm6{+>$!_iV2Kt$RXq3}I(GGz!l0Vw4s{pdssKpzhn<2^ihdyk+aN4$B!P&@Bb$ z0U%Oc!Ys;gsqKq^A?!k$(|>(XE;so}2*7M~G?d|vmzjLCWy^@go2?IKlCtDJ;fp58 zo@=vwSxjPg+tI_^?H4|W2Tc%Ux4tj;&91mQZw*$}7YWR^yMI<&(JZ&jJK;{i2DoIO z547y_-R_n1AU^D4Kob9}Kh~r?Z*~R05nWrs6O^{N73bR~9;G`n%{`H%7sa9mVj-0> zQ24`lf|C=a_$2hQ1g90<=9InjwUQx%hwpL~t;N<t`NmTBRJ-{nvw7n?W(Q5~xWp+h z28F78%_e0oS7+{FTHaeP^=!PXr2T|iZ2j44ag$K9JrmAkg~6AeCvL$>Vw6WC@qcml z-eF1a|Nrngr_*WJGE=i<<w`Bhtjq<cVOFM8R+ft#NoDRFh{CBfbCOz_sgO2oDY-HS zQZ90m6DOpis3-_1h^+fX=kxvCzx%p>*L`32{ZDmO*9F4+{dzy2kBJ#mUI#Y5uWOTV zi1x-^NzTP$z|;-mB3s8W+ac2FmIWsqwC0^vG}`F2vA3*o*EZlRp9{?FM3kGI>P@f; zIjrW<eU^hV_U1M2j-p*r{$O@Zakra%>nzGW@t`XdqbSuZvlH$$o*;w*f!f;J&I`v4 z)$f|l98LiXiWzY#{5={-W&EAa&77+rN)X^8ClOqS$Q;=5G}PdYX!I*QQpxY?r|lP~ z`rn1g?vgm0EPLAPPPIF7nQgootKAr!eFP20k9zsgzI)duMON-F<=K9p^WDF^IurMN zENYE`?}+p)`G}&p-ShA$+zKRu?}%Si$1;WzB<%fLf9;gV{zD24x>)Vb2Ed3`{^Swt zZ+wvLaevtd{oEUE|J!<_J6Yes)_C!Sb*=8xmB{*UyB$)~9$JAg?Ee<p{x`_Yd?|24 z=iKeloiX;U4=MW6!K^Yxovow{x(kDvLmhvZb(F!L{`UAs!aZuN{dstc8^vmh>$*=; z3C`h(+Yb}iM>S7ud&I4gJl;nukDO;UQQ?`x)Mi)Tzt%@sJELKY=e8U^>orL{634b{ zze~Xq3tv$<@$+s$xaO9g?9apgJ6CG?+|w3xB(~3U<yE8_?sS@;NqgIdli6!M>R0Hq zY})O5+-2y_FawlMS0$pbXq=c9_OvLoqTQ(+&~y&B3yNKY%?&#s-x)`RJE+GYu%Cl< zsG`VynNlz`5^Ch_A2_5IO)PQA(|}Ilnz@fhkQ^5XPIOH8w~3T)Ir7bmaudv{fRL%v zsJkc%twf?0faMRtl6zZv6HcStx=>Sow>3Mlt7`RGv&qMyfOglt(%9C@2KAf+B!3ZL zpn`l-kPnMq%EdrOa3#g|=PpG@lV$)A20NE*^X^*z77e0d=TjO%W0#G8gKm9AU(A)w zSypJ8{+~`4B1P2`!?ibr#+6Xx-)H09+w1yf<0p|;WE@oUVUFIWh2QG|8PyJJM$vwe zQoq-e`W`N-Z&e=j)S7_LH`Vt2b7k|^;?PLT`+Z;M9vTqof_e*(@%^Kmo1GU|lZ?<{ zT`4?20K`){KU{;Z&8|*4s%W?6(fp79|Ky#r@kjBFOC+<z%Cj$3mkmWXIX-UU{AucW z!@;5;qV07sh9R+^H74@I>2M)<NR$Wq<_{S*xiVEPgs%uBF@Y2?wy>V&@~NV(Lno82 zf}V>-NTR3k7}5CR*1~#8YJyOR87<4W<j$%j?|4-8=VrpIO8nm@0mO+;JVw?}hkjiT z5k-hhtbdg44DyJ)bMifc3c4qt-<X>sbWR%;mpqxy+#mbP&=cfx;A)4_RJ&oOrV`AL zKsUFJ;vX*alE<KVJ?ihc{Nw-wc~_lqNv8RZLJ~#x1VwKw2PF-!PvZuRTnyiUQog0u zPeGYakh&CatO#VXkATqJ%SOBLBVE1f#V(@Sx{ZjQ7SJdImghH$%pEPuEvqAU+W^6{ zY5FScN>gvO@f0NTvQXiH9YL5BP;%2KEh%_%EXbRz)je|n!(MJ_t4;X<_%8p9eE|F4 z$!D$_vnKEL#5G)V58sntk}9~}Xr0(BYq;htQqNcPX)9-a4@}q(JKk4+^H&S6oA;=z zB90g&fj1XlKg%%XIC}Fy-wjfYmuQfg)0=ai{HLApgPXxGx6QwDgpMrGCkKo;#xV*B z9O%d0@y|IBTL9J>5Gi^sTH*4!;Tqpq@Wr%3^$FW)T`}D{M0(zRud2UIQ}m#E00$|C z%TIOMVdk31hFF$kHAgZ!YZ7j8T$P=Sbd$M@GN6Is2i%u3;OJHOkYZmlW7Mw*e8n~$ z8kf5V&vItY0Nuvs^TH!%A}8;A)0mm%^q*SOt4T7EDBm}Q{`d^+RTXYrOBs41!8(<_ z)E%Meh8UcA!p%S<O>VY>V29i9hx)6-*ZDRuNO6E|4Tp*|w57JwB)J$a)gVXS0bC`# z7**k7BDIdHSrn8;e&;8z<FA1OADxEzS$u^Q=pE}=PHPI>t&T_~Iw0jqA;c?s7wqXc zUaz}l6wxE1fiLwiQm<7JEL3jB5S|!qw+a63-@c~E1+s6nz~cZP*}TBCpWqj>C}T8A zz$09?DTvW`^M(V5i3wKL@CanRJ_q%f7uM(fbM&zw>|d!Im<i_eZ!I{!{7;#014E>4 z-q?|hF`@Z_{^Q%8_O8u)K*z3sfrf^w>EkhFBz||l?h+6TUzlq8KU3=F71d0MW<j4^ z{tY?c>Q>IS<r$UK0H>D@m9vuLmU6wIDl;)(YVLT{aJSIUxW99OLxI{&f50sDWZ0!l z1yx`6JqcUvFPA;7E)U}Eqn@H2Z&{wNd(-f<7dZtJC1@I2dp?}{Ehn0sJZ;<^(r?Z# zEUCM4`iZa9r~Vj|7HW4vzM3fHl6-_^H%uPCLukYjl+5j(1N~u2zmm!n>OYPlojT7* z=1z06w>B89$G#lL)j1+~6Mji&dJ~!^<{E99cOXTvuVh;%;_#STNBDhrn?<iLg|#uS z+ugLOo6G!|aoqP($PK@f44`pRSZF`ETYbqpVqaLdU0uKA@I%!&&}^Ccyuki%i~vmV zyx-a#2U$QET<y{^akcwky_acp--&{~qM47OSRIhv&01GGlX~?P@~?l>=^o}(jU7PK zI`!mvS_)+zsJK=FBv`|*dZ)ARPW-Cj1%!Y8FB6fs+Rb**t<VpUfvsF)hfA$TTHfC9 z0BKxl)}EI=OK!Bp0T?CMA5_xpF4L2#0p~SBr9kQ_FNsI}TL1sM;y+6QLOhLdmF{Z; zJ5Iw5-BFp7J6O3x>>ug3%=*q|qorIjmb54lYhr#Z6*6VA#w6UQ$r^rq#ng1-HaxQq zCJSkjhWl3uihGq{EU@%@6_RGEs{%xPCD^-aJO?Amjc_rmCR?|1<V-p*Kt9F9YetRq zcli@P3wa?~6zFy76LqjFg*rhZD3-TgFb`pA#-e^5ehx<ND5Z!}Gw^ZrmOjH=y{}}g zJA%^*Ryv}k1uC4hIKc|2kvp&mKi0ymPS~$XvOLOgI@P6LdiWUr&!=vbS2ZDv5L2p= z{-}BmcBt^@tEab$*hXFJj!{n+Cta5Cl!{R6@t$T|A+So(tu_~!T*6hyM=#I=7K|{W zr4QBYM{Ja->GJe*;Q;i3%6TPoi`;zti7@Nr_{G`QgDU*(%_Zck(?RP3To<aIzeZhr z{P5!r{pT<1UjIfmi8F8YSQoNq`@cy+Kv-?+dHP~b_h}Ay!;op??EK=*b}`d6;_|na zn;R5id7BhL;-DXRV#C#q!>#phu$(tzW7di%EC_)Bc@8f?1Mk$!SY_^B0~jdpm1cLI z`J7Y+I;e1Cwd3{b4%I*n{(sN9)Bcrp#~XUxeRxGh&i&r@xDpZszUJ#qwNMRP!)8K# zM<wM8v^DS0xNn0dTEYdpmblTvm67a(GoFVi7FYwOi=02sbh3&FpPeGN4sL!;{kv_r z?{f5jpoL9xR1UM^6lRU5G^x|jj=WhoTI@%*K}-l^W`)nOa0;lFnrCDchE?C4)+l!~ zu5SM@Rh>Rgj}Vr?)B@P`h5Ei$ti?EZq`PblJW6bT6n2IEgb`AgNxqq*AqO9}+HHR_ zu4`-|JjPxd_gnKJP)sGmQXrQqRA%6E!8F(tt{`3EBbB;5VheU^7F>OaoT}s3f1d-$ z!)NzEi)bj1wKi6RZx2+B^#?>DAyTVg0^{%Cv+v<T1CDBm5<$BS+@!$szM?vg0)lXM z&_DCOghC~f^f8iVjZ`Mi!biQDDD@K+{a6f?xIeZn?FFB~aPX`Sp<4L4nFQ5DEi`!V zSM*vPJ!~{4iF)wb4tNfKv7JsCcO~>+p%k4-IN%VPg_qnpb^UY#fhhF~O!mP35~#Q_ zfpiZr?uxlOck&35Ze^;<Sr}c^Xl`I0nsA4t;4#~!iE||t;qp9?4KcFm5a8;`sQ3Cn zC&C0>sGcC55~K`$RrF{ej%lpU{1wBl*F^d^H^Tbx`Fe#v>n5)AydvKD%jR*0=jBrN zN~11w3)jkk9smx2s(SE0{%5IQu`z4qZKVf?z%rkc1(YP~jauE=P_{)2HGxbIyfn&< zr|;WXbCTs>7)c{Hr<Y4P`I_5bJCa>7Htyl)cvi^aTze-tuPvNz-iZ!HY}1O8SGe6R z)ALW`Fy1@#Pe*8qD!Z^Ej$EdP#F@#tcjwUaLTh;`qsm{@qJ=El9~Cu96ZS^WA?9P` zk|D?T@I5`%6xluu@<hg2>)Br4GWHl@a@E&uk1*&FeRBDH_g2C_%dqWo;=G6%F#Tns zLyVR*c_8O_RTwf&k4SqYJabG_dtuKPzN@aW7sqk(?y2Jh?VVe46fv`}p&(LhM7*~Y zBDJvC0>lp>ySF<UoPi_hT?tL7;kuWHI5IIjMSYv=(pR@QTVDo+H2r14z*|&Ag{Q6q z<c3&bbe!ixYL-71FbcCyPuYP#@6)o43h{|7lYulbAgkjzmPLU6pC&=<Hc<Ar*!k<5 zCo%!N*k!pDKwRA=r`QixTPH@rb{Nn9O7P>flR(u`v}hYM1Jkj92%C`He+tButw`+% z_e2nh;oo4Cg-B&B`%2mz7zFvzD;|LZ(BjQ~45;TKE~)Q3W-@XV$WG(;azG74u|kGf zbMB`jC}MRu|F7zkZ=7aTR5tx$=@(fGoL>tHyRM?~3Y=qK=5%Xu{u&@%P~in@_zy6k zmVd+QVbctFwvXMgnS<};J~@;^9o~=S28XWCE{E!XhX;FZO|OsglGgQTr~UaQT(E}$ z+fp=G)(atM;%F!g+@#Uc`$7h6Q8E~?dV6}saPC+k=@>6reJJF^ti@h#ne(?H_BlRM zuSGQ;Omucb+iRc8MZAz1E?qjetbf~n`V;aYz?UFsQEmxVvgHz^J=cu*Gt^?$g~J%> zFea3mfDzA0t!6Ba#Nv1lTQ>>7CCG|sl+RcOXm5qcmTEEuEHOZICn6Bt16}2O>Tk78 zP^h3X4OekFNH=(`7jG#l@Q@BB`n4CuH9r&U+VZZi1yAQn=hh|NbC1J$Y*X4GFezAi z*RjM+UA?Oc?D+!+-iE(YO`osSqs{AyNE>P-obu3o%@tu@fBcowe!8v43_2B<+h|6| zm;s@>%u3qHZ`H_t1M@fbl=VTrm76c@U7vxBeq$P?VPU(X_lQ8du4(?|F<<$)a?dNX zokW9#kwYawZu+`sHjYYo)^{=JhFuRxx2Svm;l_imUs!=Xf%Y%Q0JhpsxQ6<_ir%ec zL<BI^FC8#dQU)9{f*s@>GsG#~u;AEN$k~LJHQTat(m`8SEFM+{!J?q}zayKFstbJ6 zIhp%seF*f;fQ$FNr0d<@+f;D>k`DV5%|S_t#V9;GWf5d8Jes&&4G7&|YrgI7?9o&} zf&Eu&3IYfPYS>dgVV1rZ7{dvQl=`zEN_=A>@O-`siTV-+gksIQ>y(2MS|xthK??jb zAb0zFTLLQZ{}YwmL7*tTktgS>nuZp9cUAWy3C;R8{q<!P;oJGyBBn<q5A7fRLX}WT za^Z@ZczC^MBbJwbxP=-Zmq|)S_qho;t9O>eu|mFCnPP?DrGExji(wQ_@etv;B_p<D z>6W-zx{PU?mVe7!esF?o>NNrnJoFPzkFe*4g4vE$cm&4lRIHg*T_z8QJfO4yNmuOT zcDYPQWW+YZ2AbVk)I15{DhqRZo;xU(`oNF0zGgmKB4-1hBvxMW32$bsb_>F}XkHRQ zErGqa!VVj0cyCMp#9SX??+NO^R{T+%B+ziUg(Vuz6ba2uWlj74P$*+fl8%_xN_qSP zoH!(Y&N0Y6d~)uy^VY<_5W2$lQqPU<;b4a#!@sjXN$V)kOStM-{@jxT4v_C7$x0b? zarLrm(WCZGA#3on$W7J0Z|GB~t^BwJ$%Bn7J1&jgb3f_%RQM7A{!T0%-$LC6Lc-|p z8}1t>j4YJw=Eq%7M4!gnU;5b^p=uWXxu)~iRVbat&fIvWq2ze1qf!5Y`pX>4P5o+F z8|0pU7VY<Biyi_zx*xY0q$K)7%02Nfdr&jgcOzjG=vzE_gP@jw*ns(NgFLTJWPO^F zO*sKl5)~2kcYr(Y_ag1XJ8AWiwA}9|AUm=92Jr`oVA6O}zOPrWpL8Ye%4QaDxO6Jw z=Us}_f{c21t2J(^|Gb$47?=l__FX?>L;JtD;4Fky8T<Ye)Gt@?;`GqjdolmXMhruZ zM%AZH4pl8m>GQbAlD91%jmhH3bQWlqUe=BXwqEx%mO8@-TfXUr%{(e~=Bq7jp;aZ# zNdm}>%h}Zpu};AY+^sUh;Rx&b(UMwb_1MjRF@U0u5sLDtmpnv`WX;D`J-xn0*9&`` z(Ps$^E)^p9jURCuN76UA+KZl_!t5t#<H2(X6Fqim=ABWMyif=^$ypn*pe39ddI{I( zQ-2hIv($Tg6<Cc>c<F~9Iy)(Y1man=6HT&1C+_!FTS7p*TNwMvdRhq66lTR8up>mz zu?;yyX`i7nP0;O?F^q9yEzjRkR+#AuT}d#E$rPSB04m0CWraxT6DC~xJz7YbYc=H5 zNINY9tmj5csE{xWU6r}Ltne!PvupLfFu-oO%NOrsNlT+F&1&JKp|PvDZy6vv?1itH zdj|%_LAL9}%ii+a;AWsgWk2hTt%ba*0Fs0~xSqH;vw($002=M11)4Yn&3!iIdnvnG z)H)dOWhy>yM<ll&A(u7MAyM)vGdPJO$|qnXchmiABFBSRX|qp09zpT}^%DtxI0zrC z08xuF(|{V;*F=iqEwKnzm~V|?;qFaSImy5mzXt_ksIG)JATx$A%vqSVjKMM{@o0nC zYKcVgHhQ<4eTGLhDi`!Lh0NG<*7;W~<@xTY;N+^~QRBpLT;y08lr+~}hNY1JrwE?a z&a|qEt=^@cY1>dh*kwqUFSrHWRbmc#0I{|B++V$NRw70Bgh6LlW=5B)Yq&`CpBEM| zScGcu^DAC>E!O(q7mffgeCYH7{|T;i3cya)?4lJoG=D+Q9W^yn<?m32r%<iH2>k{8 z6E7E~;HxOrq9r9xb*O?7n;L;Cn59GcesWB1XHHvP#?g=N(;*MqO>)a(&fRIP+v+5R zx1~kDSDW=5PPe5h^T3+Y8&<F}@UVhmYSI;Ff?{`&d)B<SQDlSvx9)8t=oQdCkQu(` z48-O1foe+fqWh5x<#|g8?<W*-ZOHQZsC&Jl4I>p98Yb$@z&XAXWKsP|JB-J)iDh0x z0*N%JhzsBI-WzC$K!3MR|G>`Gzh=`~t&KjZiq^MgNg_!48Iak0`!i<uQ$?iWZP&8! zp54Hn(vh{t`<Lu_-~V18eIqKavEW9{D_@&3aZt%e>tIrV2O*dq=s`GZSQ&-><husk zn(BU2OJK*;Aw-b7U|$3$Xp4)-(-1NsmL4tNRfgd#Glm$73Mcpu*ExemyfbM-Ar)&h zteEXt&&1y|aHUsyi;7)_MHwl;L_M_b5kh4<=g+L>gp=-|&K8%tphn*$%940Fc=W>f zn&7d^L&v9xfS-!nF2{zAY<<?DA_L5Y4#hQ$=VKG_E$PaQ!Lkf1vCxcx8Eh)>$45z@ z02Vs<&e>WC7=h4W+Z2uEX5jO&ndK&tZ7+ow?yOmw%~TG>swgl-PcHF=4Fxj0V5k0k zD;H0ZKWJ9K7Kusf3g%q7riUOC&(73b<~`FHM6r=<0+^AYP5b=dXyL4ie|7WA3{QY1 znn6Y1Nw0Qp5k<<Oa#>d$Mt9KB2GjUt{cxi6m94O>ldKssJRX3azsq=yk%^eLaJ0v4 zd{${x`U#l{5X$z_K1nO>@ECC${METdz}HH_ZRCz>G)dS|^R-_u3cTUkmx3g(Jzh>> zqi<~CNG=oZjhTfbIkSNO_o^X&*ioqtsbKiGf(&~@xep-!BRMtYW?W208fmMS);JqS z5><CGFkH`!93@RTIHf!>GvN^at5KHwJae!}Z>ol|O(e$mT~v^Vo8%S%v3KKAa=9N> zipnpBESb!4b4y?mBRS>IGQ{A+r+^oj(SR&6#^maS=eX0c?bfSMX}&v%SP1%z%UZ!F z7)f^P&X<cFbs1g#5i;xY8a@ZpEMFHTX<!0o5y5@xP(k(|4~p)qS{fY;*g~;zU=u$; z{I&{+>uctcUP3uEgghZy3`lTK$-PHCi2(x_fOt&%a~c@hY;_JJ<Fg+~K|0RKZX;kd z_Xc4hp~l}KmlAg&j<2%}@rwLqITsdC5_-o&SG-#R)a!@M1t8XBIBU|{5pO*|WGZ}c zo-?dyfXcK{$A^HtAE2{r;~y6A9SYky+;uioCNz{n09btfL!_FHtYHdtJUtGd2QjAE zdB2J&RCa(SzhAv9isaD(zuiBT2XEibdj&p2^E?lo1>KDb$S(C)-Gw6W8+d&FxAxe( z-0cEHfLds#t>Js%WP9dTlC+t+Ctnp?C0lK~?gGm?8_g=?soZ*^7jXX0SzbsRmo;AQ zWX)l_EOIKrVWv$F9`;)Q5B=IG^=}W(E~uJOe<vujFAr>I`(EE+{CiN?Odq!n3pE-T zc<q^?9Rhk>@(SD%KZhylEfI%8y@7JTQ1FztI4K2y)N_?yJ6agC0U>J8UmXJGoey%f zA#xeuRPuIbG?_2E=LETfWn`Aa!{5yfSnCSif@oC^dMP3T6%tWCo7bh0q5ZT-m1i12 zbbzSFP|VL?N1k->hyzzg@YBIUA|p-{b5TSCkP=&h3dkudTs5|x?=`~Gw3Ul2ZbkdL zhX?ZUMo;CM%@TbuPBkpg|Kg3JfW5RnsHMd?S|NP_Bc%Z~(;Zva4D<$V4`ZM1=n{kH zjbY6^3@VRmcQg9{XIUsBg8T;VEZE4GW*iIfT$wtqX?C^6fhc<>?w<AWpED|rf7$^N zlv@PHFF2_$%xMIH1G$S$rnkx^<Eh(s)EIqX9>!)5jTQ{^GL8tA4BepeFK<?h<VUe2 z!Nw>FAeVGRElAKt^k~+LXNyPgcE2X)@k<MLHhxWBn-S)Ir#H?aTpdxvM#-jz*pIZl zsCQ`Z7L&<XEi5oc$(MKR$ACKltZM1i$qA0-@6O#QmyMsF(Rki&nF%>y=&V<fU=tgW z)qNp)seo#}B`Q-M-cDpqtV#`@F(=zJL!?V~GlPW4MR!q^1qTEJV9Edob*cu;qp=Kw zNADd!M|#Wtn!AWt4C6%s78IxpwmMhb_%y#X4&;DW5S6Q7UJ3`v?O=o8%ccH4duN{8 zcRyclJz4*61g+%CGfH7*Lrm&<X3e2A${lCnSn5#7DQ?Y~DMj#6o-jV!rW+D&0i2<f zW9W|M)Q1(DGeMXq2*%b{vQF&!Ds?FNR&y>5kRP9SD}dH8P<;hTF@ewJm+iso*g+7u zB`5gAE86Ofb#wl0P#jA4S2<+f;C2G}2$FxJul`O8P?!~!=Fv^#O4gQ8sVmuf{#noc zZJ6=I6=|B$qUG=YnA_KUXtd^Z{|EU(0O1S{j5F?IBv!U%KpK9yYC0DMO0&Zx{jr>0 z?xKvW3B)bmFpzaQ(f6A9i(z--w4XMca=xUxM(chn07H>^hucDQ)}?&^bh*4IST<EL zyb-Gvu<}%Eu}Zl_ir4fY_lFO~SnDAJN|v0#S9{agE_EwD>IhUVwHk4tqii&bz-%~1 zb`7ss3XA(0^d#R;ixO3Er^QGTIsZf*^fW$nJD`2_GpJi!_%q6P_wPF8Zm7(2x_7tx zspE2MDmGb2wzOO9a5j2DPIW%$AMwZQ*C3DM^HR)OcoaXGZ3hP@HIn=wu$|t$t0KHe z!b%LN@webytf#BtJFS1jt7N^$iN#wh3F7Z9#(+2RbZ1TI5kZFl(Vpk{w$+P3I+iki zy{rd?l%)q$T&`@A(H8@Cq9q@3YE5MaQbS-tQ4OyLBR>TwNIB%2M~si3E6MKB9W8LZ z_9g`X!|Bi6U|)mkUa@$oCuy|h*cm<8tg`pXP>LAnbJS2jziv}El7r8nNJ$r5jh(hW zWlg;aJSPp6y>6c>#+J3s?v+OJU#?FmzvDsKD=KGM%4PWyH*0<`opGavf%@PuoFF5~ zXU)c*H*c4p-K6)+DzfT^xoKB;$}LyZJdbe@X$7E@{U<m4bOfzlAltV@a{@$niHc4Q z6}*KsOxX0quT(#@j-z(6iVwL50<83;+nC%J_^MxZknOkU9D~CeAosznb>@NENwc^m z(eWoCSv8C5`H4A+k?G}nm07e|(783~0n)4fTHItJ-+iEIY&p(`X#ToPZGTD`@R=#9 z#+-@I%ygUcum3Xiy?69J*`0M5l@|xPFe@_w0?eF=_YnvWCRVmCT_8PZ5L;I@g&qXC zO_PTX@uI|z*ruB{6BgSioOkS-IFN6;6I!8|d#!mHIqG;F1eWKuYl6lCClw>&7KabU zZZJ<6L2sr5r_%v=gxH?!gqdignz@B`%+&bA2XvxzO(S}_X)f!G20CqA)0jh{CEhGk zjN^)l+>6{3&HSlyH$72Fq>wIuT=ML>`P=OKcAtfk**al(ge;QH323EvuOs}<AZP;e zzeCAEel@*mu*i!HmJZ98dQl_9@(L6s!#cuj!spSCgjsbQH(lnUlg|ThK)KQOfM|ZO zP<$29l#pBJLa2BQ$^W6FFFLL6&z6Xx&|qOFP?m&NyNC7!vFIHuyfdMl6N^6QTL(`I z{{B|tQ0;)(YM)%v>O0KHygWbIQw78Z+7wKimJm5VXV1Cu2yTBNY*cq~5y4%cw80>w zi<OAsAT9rgR<Kh~z^WwLH|2NjiOeDglMwUN*Mj4{ssNZz#FJg}?;5O*k<JjVd`&b! z9a8@E7}t0C6hM-`BmdMYyJ7Qy_`y87igB{W0FFmX$A{MX)iMLD#;!D(sWsMaHZ=pV z9T|^Ki{b!C9bAV-UjuFiw!n9otbtoF&L_7=^LTGhGHEst?N3X>vX%#zjcLT&-$2aS zW}okjgA^5)58wuHxOJ$X@jDJ!yEX`Sg&M6k{j%)+UX_i?UTP+kJfJiJzD33+RS+hp zBh2ckT!9^B!aaPl6D86|+c-`2L(ElG>W^!Ysu3xBzGoZrf{hY0fpb5BX|<g){y*M* zMX<7IkP+}dECRXN=-EBT&p$<~Rh*4D@m;@jX3~{`Qk9Q_tqCCG-2c^h4_?>}gmYJV zssJOT_STa>zNofk=sBm7u!qAieoxTP-y+ym1&fk(W=Dx5!TU5{RcB;3Xnm;Ca62kP zUQu(5r1P`eze1rI!=6Tgf>j@dMV5QaroRy|(Sj*J6m>^8nS&KMbR>(xQN|3dbuy@# z$3mqF7&#|sZ~;s*O(li2dldbO6~xGzW%*8cBtP`bL8C#Mmd6c;nyFh@;g1Xk**(?d zVE%Aq!3;9HI!)kSry1D2ba<7;OYuT8DnNby@M(8-%PBeFDnyr=5Y(DGdq{DgvUj>h zo?Xwm`F(cvnTRdMh(X1;-K*q~f!YIlcBbV~=4dI<ycM;yx0SHXmldu_CKWRDE|G-# z@=$UYwneG|ZjLCxnbI&{H8D#dRxbu(wW?ro&W=)r?g*DljT;>&H4Cm72&O%(EBJ_4 z61%A~<HXMmo1vN$vn67|ZK)q7`XX;*K0R{#e5qfBVB<_GK3b|;;Z#sB6fCXac!u{| z7r(rViE<C0gTm1x6nK7DxtGj*%9*=pxTAWI+uH^tV?c^`T8^K7DxL%QgwY*GbbI_9 z_o`o6duiSzg)}ig8%%jSN`*qi+EBGoVkFqYb>wO~zFxTjgg?k@0VpgNyswWFPK!C$ z=$j$T`uTZ5CatLa^FPIqni0EW0a*eW_S+%vG%wKp1)|Zx3F_dq)6f}I3iyB&jT5XH zfk#{X?O$_rl%^bR&+!E%J&}<Jt^S?u&eV-`EkRl9v@e$p|1%~}PriF$=jzQTZc-LE zfo!wWnv^hno+qsERs%#n?GrAunczdNZ3~qq9%Wmd-6B$V!^<Dz^DhbY8_VN&<MR@6 zzZ!MoG2HJd4@&2ZL8O|dBvHFXnyB*JaNS22qj`Pje?y}GCoB5Dwx=Y`M&D<j6-v2Y zbz)@<NmplU#bq50YYed!^h%l+M9eHW?Z+Yt$(bpxC0aAE3elD(Uu$tMeG@*e|IoyM zFa^LXX^czl75q1@?Dit&aCD;5mN6imC60cp8Z@%<y9`TbNKY*RYICMWZ3c3ir#d4w zwhED~bpmkv{UNg^*AGwbyMC~l01_lRT5c`K1CM`mZxgVZ`OTyPRH%@>eXfU7As;U< zwmf~Z-TFMMf3t&$x+22aI7>C@cv^L#?bAIPa5IQ(1IF6ReJ|s=SBPY3vI~~5<h)b! zw41VbFCIB0M=y1dog@=tPH*;?RHQ1e()6|3Y3vK{rr!3<pJy&b%--?{=xX7}hRK?N zC->HeM7*rKZg8=@itwXfPy29SZW(Skp`16gBl`;M^HH9C515uE@?)<JjI2eE>0)7# z6FdeBR92_hH(et~Pd53g3QlTgD9>RvHI0B!6vO8e9AQ^7E?X@;_1(r9IeVi45cFvn zm9*K9F^^DS>s3RKImx9@H?N)2+J4h!gs(0*99<~a44+|*htqd>4X$cn=D?tLqZPuk zCMfQcFM<|yUou`J=f<sSQ(eP4IZ>MO0RBknoJ?FN*FEH9f@Nk_teK8&rSFNU14Tmu zBNZ`t$v}!N!a#gGcw)=By#Oc%E)z$K=_#Y%c?VUL+Z*TKXg-pH^X?7h#}5DF;_~uY z<<O<N!CSzaqM!BFGS=Vb`%bk1<cYqO{U^km=pChxK%~QWkhcxWp}z0^GxO|SSka2v zSmF0w=}ct=K-|w-=ARN<flTF@k$ltyA8j=1dLmL%oq&+%HH(aJ_N_<zPBiedC8A3+ z)gP+!FYbnxROn9u1wqMdx`!I}#Fdj|(2e0>BS~~r_EF~VRkXn3Jw3DDTIu-PJh1oH z?ZU1q7%unGC;z`I_%;UpkAhFKwzf61hK>Tpfzq-(sl}#_oMLf7MppuiBw9Lz9SR2^ z$5cD`;<@r+qU3jtdx2C_*wW~;YHm}U4k1`Nwth7yTLuutFA%!0ivlIhx4S6V=N3`E z>io(5%-3`6Gv;o08%<M$#gauz2A(dKz+qpw?^Vek$IwQt1bue7dvyGtww966hEbB6 z<?e<gtY$TVIJs2(BC+O$-fnr<m7p05V@iNLIzygwWaq)P--Y8bkfE^I>#z0vaKq|3 zRYgP|W1k*9cy>@OiIY?<6@K~J=y=a}X%nEAqQ`mwbdTg8QpclNp#Z0-4~I%%QcjN^ zJQ^uiqGSiN$`CYk9k><w9r^h0nsOj^DS@Ll<EbNSG(&^~V7~o4%J2&@JIVYQ@WCRK z1!PBiNXnxr+bxYSKaJP}O^bV-={$llB%Nbbh>?5)AJ#teH;CTKiE(m)FY#x06)yS$ z`hIh{Ow^IILmZmZYv@i8q@x$7Fgv2ADgb-oB`yPPj&e7!8>eZNAxH25ak4ev_qy{Z zrD*|*;inSNq=)5GwTJX>KPxXHE|vNbGjfDfGxzk`R9Ig$svTSbcobt?-Ka(=0E&00 z=nZsOHb0gk*OQG05dOvmL?V8^UD#J5cK-hO$`C}nWVm?h0D%8LncNCAm<RNi9^Kmz zg00572UapJfek)-f{Q^)RcF4b)5GH!p<uhv5F}e?<kUfBX=2V}QW1FDT9F-7;Mv@k z&|6?pXdE`xAB^V$$^I@$$fF@gVVq`;-1pQ_0uWdrhQh360mI=t@#Kg_ZSfdj>7Q}u z>~B8lNC*=cLdYkZ-6NU%ny_<=AB=O5;)S({9cDz3A!K+Zh&Qp%2|k~D@!J<!v(hY~ z*yrL6zd=#{X(Q+smA%(@z<6+(AYn{1Sadoorm*U>QioGDfS_$2R3Cb19&k-yl^%B; zn@%Urt}!h)Tv?&kSaGRu@G*6JHm(0z&t>wXgTKrjK5u+L*u(GgLVur#6G%AdOX02Y zRH@ZHeENuure57%Ue+mOK)JyK<-xo!aY<SN<hj@7bYH#t;J7~qJvV?%U?9icU~<3{ zwD#&v=NK1<CHzihe!DHS8QY>xgsGhrGEuX#hRFI)lS5s8d2pFc%F&OAh!b%%pW`2G z_QsbzG%I=#z9+a9M154ej`R*}a}RPTdN#7o<|*(3nt=d7(53rjV*@eSK1SsLr~)pt zWVAixub7$-JM0gsYs!QW72L-;=kpQR+cS`XsIYLTKeA?)fYn*{w>jY8M?%fC=>|mp z;A`RV$grU~v4pEwYpa`y6uGK}?o{Z>SYoOfbm^;jy-bRQ4lT5%`#SW!n9R~fc3n~z z@yIeZNsb&^n?adbXUA4It{_Q5FqmZ|%1B7-nBC_)XV{s@p5wwFbpB4*J6sbdWj_cH zH=+&fBiWC)vR|m_ytDX~Q!rm6-%pv2SE%ueNqy^wbncv;Xs8AEWDH{~UAzcKelJ6% z_%@WwxE?=e(x3VMmf^<{&HFN|uFJrnrALc8#KGRFHXWH(IXp+ze*Yr@aC5Gp??z4o zbr|{dC^z)W2ISVkSazK0t99)dp!=Lw=~aq;w1C)Q==9aUa(Z{8=IP=w*b=a%xCT-R zMApiUUPVib3p~rong#57z6~|A(4r8Qms|}X;_v2{2SeWt=Qi!@*($%2>y2_oclrPq z*><B#xvHFK0l~JEdcbwy)zfJxRQOo3H9xG|qk0(3|C1Bq7GtXm_a!r57-uyu0LzSs zXYc{m_w%38erXh-Jm5S|6pd-iPbUzQr1wqBUZ&)-Qk>}q6<$n$^NQuiu3M#>9lr3H zd!`?*SL=9yu9K^}T>cX{EPR3D2h5Md5=LD)bfM3SP`%jdLP#g3FbHH&J!)a9)+h-{ zYw_IDZk2+RY!ca@v!T$Vo35r2Z&F?(l!)Q!&kX_e<=*r>@K$LGvH)lr(rjjc>ta!O z7~(1zUJpGYE5e78*B-;r>|s_h(RS1Z1ZsZn`i%#BbDC<HpiKERXj^&bXuMnz(|8Wp zK0$E$n*V`-ib0dHQMutBhO*A>ywMn$O<JaYxS=AWxFuv)-?}pgb}4)4N_Mv`kDq-J z;_&`|NsTv3j8=r(**bIt@tDuQ=!Y0~S{1zfz2#Sov5D<$lre_w6oKon0s^`b<;=4j z|K|lw`o%!LI$&<oa5g&;D7O~(>ZxZU|HLWE1K)zuCy?k^Z~a^DWIHg!C={xC0eMf4 zcN|elcIk-HNxgirLSB|3_OD`(m*!=Z?dAkUF|PL~@5X{P1&%IE##El;8Ni6#EfZO; zrDcQaHX7!+BJkNO;A|;mCPN}xN0Q9}wUv54J!}}vY|b>YD!DNI<0_O9G!BD9a1SxS zGbVLV^(UN~C{&zgNS=@WHDN4^sdw?Zl?%s_-JpHd!OuOA<F`@sZ-9{c=(|>NoB6SH zL%1PYG;5Yv-Vj3=418+31-0Zy^^o1q!aX7mg7cjjy(*=26i_2zt-gm;Pl$9GKhmvV z?yf{!$FOLwrRg?7TjYx~>EHpB9-(Cb8`P~pjR1@UA*q@n80M>Dqzlx~i4Jkt{P0(q z8cLMG?p??R;~J6kA|!xp|5k5!Q7?YI*R4`_o=^}^b)SfiNI|^-k5LVNUvl!}rYCP3 zvMgiVzXIY4JQj6)ZF0-k^F{CG6>!yKB5G)ipN>AcR~!D+6pQaYFYlsE)&~48>MAio z`ksulQ`{%?g`aj5E;d85oVJ*+goJ9&m*zxu^%RpFvZ?!mQ#zfwU}v@%Y5Wje`Nu}+ z5V-6Uqs0?Yw}&EzJK8Bqg=1VJ^>O`@jg$b*a+7l^Mi%s~3`l?Qqk}Orj(D6r-%Jco z!(4G7jyub^>q+z51dHhbmCrGf0Tr|Nk`d@aqi?NHM4$lc>)?J66~C~f2IPf(w~lH( z82vy1lF=(O5~q|RwSa>R>@>i&8;jeI`>bf41ZE%<rzCFyS#++p<Wx=~%h_k4tlljt z`toP-Ca{jb3Lk-Q+MiM=NxWzIZVCMPz(a$7t8^4;nr6!0Fd|6y=Xl=vx4Ud605m9I zK~u$lG(95A7ptQaB0<+#LR7*t#Q9DX*Z2Z0m1_*D%+`N!dk>Ov0BaBc>a0Nw|B9-A z%|BaU9zFt}^BGs+^Ofs^<9s71z6D9#6!&1>4I5dRdz4EU?9=4(d|$V$`{O^al3V=8 z1S8@!*8R&ns@PoceC1L`z;D?lHTJPrL1|Am_$uJ18tyv7fkLni$o5{izL~2uh?wmG zj>;749x7cL?i2ou<j;zDx9j6rUe~2U(Xm2xFFj-wnEOt-bAgX2_0uz%&yskO1eKpH zjyYEm$&RO<+d2uLpnN++#c@8Ik*!m~hSdyX_?nvgsT+^A2e+*%=63+&rmCD6{D1>& z0C>8JvU}YrU>H5|2VV+srtf2j`jyMJfHtyi;ZoJUG2rjYP$didHI2XgRU&Kk(g~<y zrImzMv;t3v0cM|G)UdB+6`Uv6H#c0ZNt)?%zkPFlv<eemEjtKRL$mOjo>^%CiFi;1 z^kd*>odu%PRd{tP=82|qC;aC&rGke=kx^mU%pslo!^YLZ!wt+-3P_Cu$0s>uJGd$` zIcX9v6wpAg%&bmHY_ES;Y??_{Z>;Tei4+u&JX$r|fZj7;=NF8GkS^saFJD|pHzr*P zb;V0UZDV_JF>=Ht_~198IZ0PmRy~+lB5VHC#Ou6PMXn=AYfV3q@gYq6lr^sB15{3` z$N+52#d3%<+nTmN5RoluWmy-VjMa^|3fo<<GX5f9tT#U})_MjdN1eJB>O2lsoIk~n z=8UFiT9U5p$v6Dl-|PC9-3obnelvrPN_T$mm|Zf+0<vrG@GIVaDk@iJ>9iC%jtPQ9 zlfG<jQ1l#Bsj9dfzxotZ97yvJpvAjOJUOQ!u1;bsGJ_y?5RP3tbbpc-L*1nC{9XU< zBXTYCjMovE;yeH8%ywh^w-7<0hkm+mbbl)N9q&8Oh9|-5D~{-vhTRz74evXFb5tDG zcdgHZU=f?gE2csc9@uX?)erg(XIQ6Nku3vvwl2mG@dwJ0gN~<N41>d^Pqi)sH?zvH zjw`B}V=Nre(*&nYdmAvWDJ~T0(#yrUF8N1mkC&swZqO6wD*HNY5Uk%ou+#jK_%l33 z7)#y|v)wXmNI)gWIC-@VZ+Mcu4f9ikxI=taD_q5iriV;bq-iRSzhmrN{Ku;RJnV;0 zIhNn`9o-N6`x8IUR9pN?lx49PkScjOKOp9K8lOnvvukX4I7*dRt=>?BB$&hFUt(bG zRV+2y%bf}yZp1)Rwvj*Yay|T@TV+8UQgR&7+vlIh&#b#A8d$*@5voUDq3-SvYU<}X zeY8SmF@SA?b-h(BpLTEb!3f`BqsD<g<j{gs-pt}chDjj=;1V6t<*SC!*TC^$=l^vu zw5h*OXwj9>No@f6NQ-;bf78U&JxL0M9Z^=v@<Z>|83SoGtz%WjHUaNNfG%AHA1_4U z>U(W~Sn?Se*kwFtL@f?OuXrj2Rijoj8Yva*;0Z2x*wE#oj#l=kW|mr^Z*5o%R5q_7 zPfuB0Fq}m1d?A>hm5k*KCCrR*0I%IAh(6;|kPye|C0QlNKfK7=B><Vml6ymIM1Zuj z`dE>$>+22`H%pzU2SDFtO0SxAzWB9zeA+I|VUYe?R@|u)<B(VFplrZ!GI`U&Val{` zM-FI8;#mQDo7QpU^-CO1e7LJsyA6o-ZVqN;PieH@VT}OQ^><GE28Z+BSGs={l;2li z@FEkS()Izp(bAmmS9^FMw!;9gGY*yk;HK)ymuCMnSXXKIglY;!52_GxB5g#H20pKf zwjlDJkbH*8Y}S_)q?GKh%<NWVl=TKV+<FJfMpg&yF*@NIAL)4Q^hI3N<AI5t<sm-? zME}?yH03jw!=t}$^9jwED9w}Lx(f*^-`I(5h#BW6uR0T2Ll15YrGw4U!pI_>3rX|) zP-uD~<!Ci<U8k|4Z{WLB`vQBG1AW?4M$L<9I1pL4jry5{!We0O!)6fCC&rtH&TuE| zD8d-4S^ncW;6kee)5ZkSZjbFLY~P;Xv&X_5BiycBsT^D!jN^D1omM5kIz#bp%F(7v zCYRY{csn3|0-(@{wB8^jHpjal;+u7OGod|w|5?khnJcK#lOy3BzJF<cH46jGx*iAm zXnzzCDbxYHO0}eRDEU0-HUcJqkue~PgO7Fx%ygEh7N)M52#s_2s{d99k(qHGJ(9fQ zRy_-|{IW;eZfVIBTUPSqE*Y+RybvxGy0pY8|K^|c8|S`jvGoI~cs8@#9dU&8aFbb# zaHL*$LZl!IR+&jxi3`nHF4ui+^o)L_hI;V;RklZDVqC*nr%q{Nf@lnQp#B8-6alt# zfNr_mX;R8#5kR0S4KG{>m#ac#HB9^jeQ=qv^?fNh5h?$Xyh2>v{+o<C70@cQcyCe1 z%$}Sac`4-wkm9XjV4dXB6Nj(Qmk>x`sT|kjOkR$`YHqzE9xtbRVt5I+Gh@Q7fK^^Z zhA#XSnLjzul@g29+-@Wlh&h>L37-#({iD0YpL7?wZ-y=hvI$@G-p5zZ;xg7;t-LcK z*~b5VE$?)lmC=QhiyN_OMo%(9(ah{>MZ%ze!IbSAvUj>z2X;XE539=*cB}9?t^d@T zhXzkwSLK7uwY`4~p0M3<zE;=3hgNY!OYPp(Soq$_c+gU#qjBKj=9W{DwOYp<Qk&*X zUwVbH;A=ntBGN+br0ucuEZRj-F9QZ@lk}3u`w`{Tx{nc9iwL@<u5S+PX?BKy4R00v z5}r37v5B$w<|*$4g(Mt!dG^RApejFAJR<ok#iawBz_$zDhH2h<gD8}}5LT$s<O2)Q zrRgUOaX`$(5RFJ{bd=)3L7E-Wh41D70$(3IRLb2$-Z3uWqNJ*-6rEY7-!14wWeYxH z_PVWBj)awrg?#6%@*UQTjzoBk^^@gOsZb1nL#$-<qLKGXn<+XWP+=8bsw5x+3pmmN z@mrO#<nR<;0Lb#!XbchwW5bQ}mqFzdzE~ldI;&IOYAyZDy50IZR307Ku&s&lX#a(B z>xIpnJ5gY`_-Rp;IL?6vP6VYv>+aE3%K69Ee*==8T~`fx>y|YY&*GS}_v~X|e|rIb z3|H>g;W;i4X=UtPM9iP~NZJ34w2OWB8K}DkBk8fs+*#|^F`d%9(EQ6Q<n@>u$sec( zKq7P(Ydo18B_?r-TrPV;*3^*wT}9wpOb(c+4HDwAFJ}*3ZnMG(=T2MI07PZQL}r#2 zah1WuV92oD3!>sN#BYULL7?WVQCewEB6gf+3`G&6;6*P6xJM?LibJmv{1hlruHoeJ z*yb9M%yP!)`81RYCgc0kP|qF4q(|e!7<pna-k^p!OLf<+P$^5ERVv6Ca=tGOi3T*7 z64Bqb^we;IfK0F|Trb7e7Etw<7;j2@WRk?i-S=0xM?Sz*GhjbQ#q58uu0ZWL_u$WC z_xSJ3-0ySv;58SYXp166!=!u?9_#<Rj&)Ph<ocj#+rOxfv})XZ&oXjKfLtYa)c)*A zFts&Jt=XVHrXAULCEMVafX0kiB?FZWpv&1KAe~LZ1F?E+Hi$CQRO-U{Z+izz1wr3R zz$Q0l)QEcs;tX1^93e^)Y1Q!uQS-X1Da<dE#OxLKncN|fx`_Yw<~aP%dJnf+FgFiI zE5edN>0=VW|NRwC+tSD)u<iMeD}ezSq|SdZ10wrmY~W4-PypnX?#9eMh@_ZKbj_@- zz#pon9Gc1WJv(`JV?ji70hPz$ztP+AG^#~)J*^I<Q<BQ^Ely<xrOe#;@)PF*@J`@_ zIp)qk6*I;V*M{0}SI<EMe3S&BgW+9C;9NGozPn^LN}Gs?JREGia7fSJYJ9?XNA!4X zK#jP)!43l)?;(fFOetpxanH*NHB8M@%iG{k8zwkln`#$&gfx%xX9CveZK#P*_1o-6 z@>e2jk7=y8?);gFoheP*W(E$v!l;MK%5dQZ7`MSYF%3gW#-<9QUNT0nzu5rDsc}NZ z{SxpvP9y0_#xj`|K%%+rrp*x@-v&Or(ndN^XBt5Iop||YS;mN#nL839_?|(RTDCYk zZ_=GN`!S&v^-|NEd1B)EnI_oMpUAjs&04he#8%B*p*y>3^pC~G9x@?A;yCw#mvQ^s zkjk6A18;vg15Rre!~o6=>{0#@J{2AQLY{`4bl){-W>DIjdihS2TS3j*{QB>7O)Lc# z+~1U?L*RkM>-wVA0UgflNCwVphde({o+LGeynFpT=;!IMa<nw`dH?o%5`0v_m+|Su zn7v!FKT&4a$?jDz0cIfV_S-d(nsG_jCu)J!^~5<5_QsO})l85mGJ5Zo%%et*$M7-h zmRl<~>DbS4kFBf{7V~4|FQjv0Se4!5k9QbaD~Gah!TcVp^(zoQ3tIPQBwjz}^=H@n z7GChanr6MK(&UgcCc<S_+cLy7K1<>52U}l*>|yWop~9Uf_e5sKJlN!b4!@#3pqqxf zy&>}|n4UAQem`Vj4T9AqiK2&zCYoI1e`_?=wX#h&{-=B9M%Kfw7#5e((AWQ4$Ji7? zU?tXze0S;m{-z#U?Yq#LQxWKRbNY4CR)ayi_WK^pRk1`6q1!BiHHi=f{JzIWvJ*bV z2Rb~NSHrH%PXyg=ZI9Q58C0mw@>lv_Ky$(Um74rP@OBRf8vB1pbmN+>T!vUmVzoI3 z{rw{WeKxmDxr$l#31I#ikU*!ln}fbE=*e*4-D)QdCUU!)8M14A;!?Qf*blpB&lD#l zP#o{T%K^h?zIC7%$hL+lvhfx<`a{j2c%q84ntG_8lR*1tXy5kP{LtmM90t)e>+))W ztjc+?4W!AaqGUima+a42=={4$T2O`frm36&RMNH5@vYm$H-mgk_Q>B+abJ}AhaySq zAyCrSfX`PWJ9QhFO;f86;=>IDRsnLbNP1l;zPtt(k|%v$^;-yNS!{Co#E}AufsaMt znA5iG^lK(R-2Z;#-TzrS(6V9qy|2eBxXnsIISk9WRKOOj6?|U-k6edB50)kOB5)Zr zQB^I@7+vr>=5qDyJMvei4sD|{1`3D}3t2Gp8x#+K{h3odr{O8`-(K0?>*r}?`LXKo zM>kziTa3O}1BH-?oc``_LyPLd%kb#;t%0H@CwOEO`aqSjxgF0yLEz0H*ZIDeaMsJ~ z*hj42RcvAJluJd3mAfVCJ}%}4rD1K{t!Yx~JHfoyPxt+MiTVEL1JVms9D>z<03BAX zEiFaT&Tq<qC$0Uc3L#k(9C;s<%xLeciBilzDq2q@;;3<Ad6A8e1L7YD4``ytG);Zo zx`1mLfI%wXjDOP$$fcv&bId$Ax7dwulY8zv4rq>cn{Lbc`W3PCJ5`f*p)Sy1cll+g zBIInS@GB6+)W7sHi}P?d`S%pJ9sv2|!Bu}e)G1$8w0~ME9vV2pi)>h#=azKsKYckS zNt@L!p*&$RL%XalMvk5<4T}2%nim3_jlWhh`HuOl;ZZXD4tsmM-kzKl*Y+h9^9?r2 z^T;JIpzD%~j$39;$|U*WsJvvyQZZ<Z2ie#aSeMPd%5|XIQ)t|~zr6t%8Gs49ufINa zP5voj{3_IL?+qgtCqdVb=%EhiGu^s4vC9Y2g+MD(+!k~yFr}o-;Dobk5S%MCm<88- zlKs^JOd~qN@4aojtv)qC<y~_`7auuxsOdxY9ez(r&FKXzKtDva$5X9>@!rJxp~*{V zOvpY0<6hf#GCiWlG(c)U{u&B$MTQFhnM1R{z^*2611nLNLZjZLvfd3y+s&-FkM`Tu z<P5#I5JBv@!-zB_D;%q*-3!6V<w_^v7=BdOuzqQ{Td+I_i2T*ffpUpbUMHSl-uX-W zUa2{2u-h%o*Wqs%3j+XiiBt*>ac~KqGjg1~|M4p|K_N)A)zdk7bhfW(tW(UsMnm{J z%?;Rglz9%uBIcZyd+ulkV2>At4}@wDs9S%jb8Qv+>P}zPT`x6SQ)%U*S6c}em<No3 zFklk(wXpuNr0N4Ff&WtrWenBpN4*Gj%3h&ixvBuH;3*E@9Q|ufIvB2Yiwp*co7KdK zV=Ew(7;pO*11mC^dRL1*hQa)f$D<M;IBw&x=wPJM=o`Mn8!Y@YaRurMADPc{uY8z3 z^+W6=)IofsK9PhfoWW$XC#=W??TqcNqMz0v&%^lQgLo$eNZtBcFCQH1cI+FoR3`xQ z3mK=4@+T`9XL-*6wgC^K9*drz(qka~H@R&N0?vR=YUJ;t0I8*X$<{(F>V$%Fy&f#m zd+dE_Gcba#jCMv}C;1$OX%j3T54(dnpQj_izpQ=sz0E)lfh_tVM{ufNzIx9Q%B{`K zMQFaAW#rD^Rqx%o_xp*zn~km?wg2;VdF*vDd*=3v&qe<nx^?iR<KB+GPrG~n`9qNK zV&zF?{XbS;IAQTeCk7Mc!;YHhVlzKyq7Zm$CLe;Ow9_i8ZimqLLx?M04WG;}X(W%Q z=H$^RVU_PvZ&;L^3O97_aeZ1e<e{#Gx4n47hO!%PyKQf?R&%B5!XbLav&-uFJ;Mo) zjn4ZTfM(kcU!{)9nBG>o?}sv5Y2wZ9!yUlGGgqPC#Uw8>S7kDn4&n#9XU-k$ku31< z;4;*1q#fCG^AaV`UB0{H`M#w0vIdRVH_}A6mN$neTVJxzm3C*no&3+QCpbGRRqw*O z5*W<qv8)r8{C;Y9D+A6_=Ju!`B_h9R2?{gz&6B_5SymuIzDR{kc;>RN)$=_{=O$)y zX7yDeHg#9Y@bPzZ;P0h)RnGIq6?D18kyn}f{qT7Ly`!6eoWu_b(TF8iZyMcyw~+L> z^6<U9mCdSQvx9?#!uqBKx(59GGUP;SrXCF)TY-@eoI3ydqf?q-MfcO0jDUxvr7%6I zMX@163G0~eaJAB3_JrDgF$(_Z)@h59FX%z)`_jB(y`3)T-y651YD{NWMU2imZMtbA zlO<etk<tD04nORMi}LtRQMrwww+#5Ha`&ZsuhFrH4C1@$d%i=yTUD_rd8hgvi(Rd~ z2}NRh@z3)FCv`KZHGw*R&tYV5@dwA-xTgiuv-$A3cJ)oZ4LZd#tFF?#j{y`Meb?g( zFYGkp=47Euj*zJD`3}*ZE$WiQd6Un_NZc2H`i<ejjUz8d;5pdsvzJrr@USs0Id7@u zX0Mj;2lm6_-!+z>=qEAmr01SjHAX&j!nO)qMIR0(TPzq;n^Oo5h6jj|(;2ra$}Tfd zQ?kI}vklb0D)?`qJxcDki)Qu(XKSpN<X~8FET|rtV@~{AaNxOEjr5QE*FVLnv)A^# zQJE^=hr2zgWVd^%Hm%7oQ4fCQK<16$l4&8%eJ88SGguEjXPQUxUw?Bi?1S;F%hqXY z;&0Zs;<?5^(SANNJSY@>!s)z4Y*a8mpI&0135g1q+W97|Fneq{Lr$jXTFiPT*=;*~ zChcKzlz~YhtOFU4mz$iOcZ@HD5!P>o(DQE`ADo0IQI0(5+Im}P{GcK`Pf40s%+&lS zFt(VnKZwi!KZtq{uqLnffB4(l)>^8lfG7x91O!2lEh|(30a+pnvXaW)$QB5sRYBPj zWRJ*RhRBwcRFpl!j?BoAu)|0Q+3%sh|8>1y*Fyv$h9~FT=d<o}0>9?2t%Mtp*a-~^ zy|-o}Ak)vHXLZ>L57iWL;2r2STMGNtm7^5KKcDLXQa#|Xcf8aYZruFBmm{C0blrZT ze-=KKtvRDF_BM#KTThKri#x{S2`{qB1Y#~3+S&KZRW-wCSe7;dzM4lTw2v^zT+7lw z4@EVNaAj_P`u6Q^deyXtuBH<v9m2Ow@A6hD)H5{mm)iX13kS!1=dek0IE3$7-E{hA z45np&Ci`m5e-HYG_$OuN@@diequ*lde%|-Kd0t2qn~O*qyNc=9q6WQ7=Q65ysaA(d z2^)i(g;xz@hih)?ByWX0X$hNqck5^tRU=NjCT5VcAOHUI>cb6pNr6Y<k-Q=+WE@AB zZnsxspDk~Emn1zN|GePuBf_}MSUfMX!HLBd@a*bm?wrM9Eh+?T%IBi~5@R!N8@wWp zld*2=A+IqtjQgP#I0)@!wA~)3l)DH!*M|#za1HF-u4}U(wtfKt-TnIa%zf_6{pR>B z^HMAR$ak*Zy5oHtmE-Ysv<`5tmfh%sGBZP6+?FrZMDMaFf|7K41J8QB>Fq+EZS<M> zbd|_M^d=U*$nUi3V-tJ@GK1wAyE=<4W|@T3tp>|rWY34hE0p7LGlMI;D%3V_NUBKC zL{i8KBnA6N^7);w&E-+ItU_7P{s!?h-AER?6pBz%$aRz%?C_o0OWN9)T7jq!2|Dby za~9ir0~nM12e{E>)Ge^y+08z6>%wuaYoSgx51z4J#rxB>0SujNRBj6UVYH)M@S=u5 zSXxY6o}ODeub1?ujn$mHn`N+UTBNa$-ig!T&y7i)azP5_lxHaMH^dp<1mBZGs%eG| zsb(sNuP-4X24*@R3WJTD>Ho$)fDR}n+%Z#oy-s}sogJ1_${{;E^Z=Xil>}K<8qCM< z%l>cFs@Q%s-=}CbNT`$K{<<kR|HiVdDwGFfAvI2E9A8Vk%7qu3FQkT_86OMkif0w= z94zz=ODQps8!YHJk9_4YS*PP&q^n=`h{V-$j~p`=tlnqIf?5{`H$OM6?@?51{rg4a zrq;D^qz(MBiL7S9#?t5clZU(&vWjh@VR>rMpT{HbS`ueQK<SW8=5AE+uG<Wm(gzyj zwRBk<CTfswWShU$`<yeP^o5TkVJ`b|fWXHF#)maKQq?p@sswvwLquWNeWBXlcWsu< zY>z$@yj~?xw27O|EB03kf515;q3R+`i`(|ZxVG;&$iJYl&_AIy+2OOQ?4_C%yjMi* zcZ)jzg_ik`<pIO-4NmLx%~UIBC1Pe9)aCU?j(~U9E2!-kA_5Da4*i_QdubcVN*pko z%9wyiql=k=J?g>LpG5Zk>Iv2e2~Web_!RY;G!d^IXPP3-1|uN3eI`IXsljQb>{&bl z3^`eK_!DkZfJioo+qt$&HP9%X*XgUC(=+(s88W}1CwwbOvX0hzC;Z&Q>eFz|dN6<{ zbf46;)^zvn!9Y2tD%_@?<G06qHp4*e&K`aIN1NWX4&t1svOP!n3I5XwvG?q)7YdM| zTM1k`DKug}eqbtEYHfBr>ohM>R%=!F0z@y+#y$)o+y1$o0J}izFvwlt_cmDNa2+U# zORriE@GB=_@C<94>)Lowi7UQ7YUXj3cWiu)82=U<xcuv;KF&69=VPs-^g(49G|kV& zq)ZwT8C@U|QeNzfe=NmorNJDOMh3h79ElwGLe00G^N#qznDmzu_*3OhUXSslmTKxc z7gz56W*k|xlLYnyRCe@wBA3~4W5fJOUs0(&oToTn#>=8X{j)=4QNBIpH)HeifDXyk z79Om-<+j#3ERpQg!2Mk~+<GJ{qu?J(8KU-ezm#TH>fx6=#wJdGM2U4th{Ok@iXQn6 z)_kA7anK!Se_quM4xWr&Ec3bLP=ByY6O7BRcD0(QsQI5-q^|F!&#Y35T``1j@U(^{ zmZ1}&z5x0TJKXrV2e;s|vrMZ-)po4zG0|8^*GI&>URX76^uTk&b*5~=2ME9wodV>U zP2^ldP}|Z6&(V(cdU8kQ$Jt2&VfJHL_;P!sKo5MSF*BQR;n93p&n2=(1nbq4plTOK zq}L6&<0PRiOh$BPbH0tAkZI#h?K<U-ZzFuXmJN$)vkE2cNBY}PoRlv0d#?}$tFaDv zB2fZe0Z+2e=rg$QY_oXQYrH{x{L(uk*#+kQ0UY!99(E7}$}-sw9iAuVB`c3yYB+%% z@0F3!HwqW4xl!4)NAMDw0-Kj8-e*CzOWn!M3uT7XMMgJ$H(?VT?=^gD%&Qm0+UHxV z3~hj-ozl^we~2yfG!P7m*9VKsBiJxwnzry)D~%Fj=h(N$*CTKeMp=yPq^a%)8E`)u z?6tm1mR!;o3b!;N#Cvw;5kcYQ*F|i(o}8Rk`fj&p6&c<LYKIGI78KYywLFdeSk37d z=B*($OGkn>xeh<2W4Wg-AQByc`%8jzLo14$kM?e|HQJ+v!Tk#_PJV@D5_d{c=p)_= zd*n!3k^Af`WmjCN7$Qgpv^w2ymMQSq*xbY_Cunb5QR0R@<gSU3R({?}t>!-ZPS=My zq@UD%2T=*Ww-K${bwc=_Be_R1KcTa7SmBKK`-^k;%ceU03>u}T^`&qgE@xfy6O@Kl z1O?a$IgW|L^>O;%q;sXy`es96@@FbekJ>5VE|zg|xr9#A>6iFxZ%EQ>B$bQ4jJbpZ zjsZ5o@<==Dz{g3~tGt3fS80teispjdI2)zwr6(vsRDD|2aCy{|z*L$-A<JYbN(%S2 zGWgy>`zX|f&n%KJ?yfbj(0u$SQ`x&s5zjZZ5-=yx%LB>IU5HT?v{8+_2)z<;JSVcV zo#QiJ+LsGMGiZAs+P!Gj_lT}kUQrDt7i*1q*>F#@J!4~=k!)pmwe2}SvgSAcXz`>! zq7hqJ0bFKAdqu0uTze$?@ZMp*t;!>;&n+;Tbp;`x9cT^#Nrqu9o*eCE)%(F1iP8AY z7M>_-sUJR1LmBY2uOB(g!IRv=TdS#J(HE7fpKGAL!``RPbEn+J2)HvGwh8yD*6>og z*e=bcM8ISRn*^ZoSK`}3PU9b4f_=$4#O%W#*2)CDhsNW1Y}(7G)kknr5^WKS;FV^; zDL>4gywtjB-6eh<4e^-~GagLrjxX*(yb<wYq1=01Wj7ysc7d1QD~5_Z?QB$QoyT6o ztwF)8s&dh7J0qgwRH-{Qag8gcY68U>mJ0|(J<Ax2?+#EIj~`~9@#Io1tglD&v!1e^ z0pQBubYFO*ab}w@Dzk+8#{cLljg&GjqaA`O;Zm#p!<u;A`=g~hKC&EbEx=xk4z`Mm z06|2K^136f8zNZ*4l{M@!wcblPVN26ce!r(olt;DdT<}F<F(NjI}n9%GLvylR%d(G zTWt8PqdRBY!iE=T{y`hMyC58lfR5^N2Z^NO)3D!j?IoG-0?90^x`?B1CkIk|_?FpC zi-TaCW<=CK_>A{>Z{#m6a$k5uxxRu#d7e;=FG(vgU$Lcbz>jtpKl}Gb<JW&a;iaeN zZgVEzN>wEyed|e5dUs=;<NA=<J+An+VRKw4L(r4BW_6i=UT9`~IFhgLMyqWDDf52x zsoC<!7Gbg*^eLubjAP;%E?0AZ>mOlu0^4x|7W_3=Ix-qr;Du_iHNfcF^ipJm2!@js z-$R9ceDmxEtc1PRZ8?W~W*qV<Mlubdw(Vu$FW#a-HcOlvQTP?L2g<DzVB*^^lJV`a z&kHhY&fdrcC502PP6&H^;Ld+oCDRHz{3r0$9Pd7!yP~ND!RDznvWmT`4rRuKwdoKl z_7(Fi(=%-DO0Su@!Z(<=9yiurlIRyr-8Nq?0A$BvZ-fj#JcS}ir0pQvRj|%=D?79N zJ$cNpQ563j*;Q*Xt5r9L6<n^`udwmp%9TcQFJ0%*nD>7re()v&_)wt=wd}%m$J3PE zY<6avZ9-%S=>vW2bwcR;4XzUu)Kae92P|^1NE{KqY{k2OJgW7==KG1LXa@tky<DBP zbvY?S2Zz&G*h6%vGLluo6mG(Va}-*FMW-MCUht@U4#u);Z$<ha8hP82;fpe@s4M82 zmEGFnIxQR4CdRY?nH`H@^YLyt+_1iu8BRnB#&qzUSc1(~KxMmOf2cLAR-4snrL<K3 z!$4fTEjk+OpJQF3jG#yj?oN6dJb_@MZXN7vJc@4=PfIH<=hHoC@}AHgS+GCoBj2lk zFN)Yl2O)0NFjCt#2B@8hcC$wgGpw*uqLmdV5bbmO@jhO+Io;*kOsula0K)fl!J`_8 zm@wAdZnS&PU3)jIi}%5F^WX`LT;euKUk5Ij8zMV4{n1Zg`kHycTgmkp+twyzV*Y8a zV&8xQRyWl2=$hfs2}HTFI}X$T-GXxzw_Nw(=pQm~m|S*Xp~Uzv#0fz+jy(T&`kKta zEWgF?8AM2)v1Y@Xj~Fpma-i~KF3fo6^5qt5FH7>J7*i<8$vF8W1dQ|C*Tl$(+Yx$| zn?r4Il2dF+f}-9G?(rX64wuE(oxo*%`7+AT<#Kn5<hd5G^{cU{<(hD%K330i+@hL? zcS&k*d|k=_YoAIr8Eet_@XyBmw;{3{%!nI_{qlDQxMDYU!WAPq|11b8X&6KwelOdl zi%lO`G9bo3QnJsr)nqB&&`B}W_3zV8lWBwIV=>(JT1L1}nEgfiut7v9X3*F1Cg<A2 zoi}(XjuFy~m0F^{XNdG!;u_U?@8-TwX>=NyiXZ1mB*^UAJT5~{umn&%?T2Pl@fLVK z(N}F7!T+pOO~th92AhAU^(0rK8afW+5V@kS4uwTqY@()Hov$Tx7hAIj0~mvHcJ2Eo zx*`GNFzep>&BW$}m|FS9uI2hYXS$$wVq|hhc!p<Z3byGMTj+AcSni!gfx+K@;{+&2 zH8n#HJ}wPMo)P`p5|&b$8)2-mlL7YcG(EDr2JNv(OQ8&AD{nSO<tw%!qaD+CZ^cHh zvehR~=5hWd(wA4}0*aR$r8wbDE7uPx-aQYy;(=yxDco5k2myd@?NUJb^)><Kuv}S$ zSOOhl1SZEnHW&7XQsWzzKyCMfZ#)^tTM%dNf5+`Syez@>S6577F63Caghjhje;dkp zo-SN!R?4;I)RbQ6J6@rp<@OOmRgFvS%q-CRBhJ0>5g@T;`^$HboZkE0Tk-8$+_$u5 z-7dWFHKJN(3-`U@&R(m1DxL-SAmF2~eHGV@L(SbFX*8z@f_1;Q>M08xGoo!wrmRPi zCA(@)j9h!i$SMsZ`bFf07MgaY<e#2x?wiuhAE@UiRX&T+r?SJU@I6_A>7+!4)#nP~ zO+$9&lZmAI#PF`U^+C2-n?MMJx1HFbMC;{UdbyXWg|%e)JrIM<qc3Jo$`$~KBO|K; z0o$+t-HQD9yO_>;qRrk4L^;85{;}>xH^WkW%D{jPp7!KK`bfA!S+P75quy&yon=2K z481uhOu3>>??5J)wtr-aNFk&=hF_4Y#4_n=N51h=U1eh_LHg0TBPG3Z1sBKtjzk8^ z$|hs7wNVv1134D%_g$jlf|>p9c5N<@OxMacE)ET>Ka#$ChLp0s^*Y@76*WY$|NIW- zl`$pKT;Uz5>rr^(38Dec-`C@*Udv~qpm{VTO{b_(gd&w;Ji|92aU;%&*ej(pUWI~+ zU1++AJYDn%Hu2$NhKfS0<c-89uFXZsV&)0HeDvHJG2aJoIf#Zzf0i!xU_pPCo*g|5 zm#V)=toPU%D6kmc1IpiJio%6^b{Bc5sLa*6xI>gp3SMeV85Q&xXENR3Mt5G%E2_8@ zaFp`?Xzx<vqABz=1RgB=i!!>m!@MxeXTSq7hCzO7lm)#vvPv)Q0;0U`>T;$YQ0uG9 zEl|-*Xd4FM<wKp+aUL*RHq`6a3JK5$WPX5P4z}u=UlJy2TDj&_EqSh!8F%JvP`;mS zrVDpwq)31)lYE#-DtHIes&^ZZ>dLps)3y!8!zMbA4a1C0Dse#14veh!hO(?^M?4AU zZ|wux{cCRSXXX&@+N^vvB4-W<sI*CNpAG#!J>K&Rpj)|ITJG8=j)(f4V2ar0OH254 zymIY3DXzj9Q?dMl)TsS!n;6Wt69t))F_66bJ=y;y0c%q(Fi9A)arkM{NcMV!G$`{} zlLx8R5(a;3M*S~7;lYkB+~Y63$^gVZKA3r6aUI+A3Z|Zh*H;qxCCxv-`lxd378$x4 z5_3XjEWRx2)P|oyS<3AIGyzSF${l@dPDGI-uh@lpPG2KNr?((pD4{FHo5NnQ#JY@R z_ia_c%$-;t2O^1Y*hFPW+?v-LxSJxnMxT@gQj?Wu9-}mZ+&&+ox9^p&<=OWjO+$tY zNOV{KJq>L;i(@oj4kL}pbuoqPLS4xxVUAx`HXeF+;dMjCQ038;Z{%)Q>@02;Vt>7! zX<+3u!mVeC4DGZ|BD+HSbh+=J5f2wlr&R-EY$8Z02Ps^+5$;wxF|y5`4UZ$3W(;$4 zwpM0@a$Bx!%Daw_ZFGJvvS}FbkSh=AcRA~r{lYyxP4|4nBf|oBvOrXmh>(y_tMNK? z)VpYZJ#;)#3w8VdRBQ0?L~S%yik$$MK=_dRg-d2lvA^BevR+Z`yE>LLEH^eEUpH)! z?N*;iO>VpB*eewq6RsbV!NxTuuWAXdZ{9q`<d4bGb}k-aFJp2g$44`YvZM@eHhgeb zlwl`m;!|@VsQ0LQDrV9-!zQ<U2hWsRMW;qlEgUxP>xW%YX%(<iLia)~Y(w+Ee`JY= zIJz-H&bIqATk$iV1_M1Qj-@$1eD3_0BEG%fztI+&1#xZ+U^Z=v;&eL-O~3MGTf;O- zwM^_+M*4aHcDg=t?R{V%WH9_N*VZNHN;qkJGR?oOyFu_^-@6R)F&Z6Vqsd|jF{nz- z1DM}DD7P0_ly(mF$@u2qu!Ao+0iCCykcTh62wU4ssmAQnx)Hifqq5nN<=0!AgUF(F zgo*WX7x-exSN|OD>vdgrpH=xPj>(vq#iTiMqgG#VkIa`(F*cZ7`L<+Mhk`EVND$}A zx!TQ6+B9&mv+{9Jy|cFi{tG}Vu6AzD$d1Jqw)s7RokVQFYSIzq@SZsoj>B07>qK?J z(dJS0`0>ILzQa~$PNqvU{<mWdRigvVVVQXXNReN;>?hN0?`IDu#W4AwXnYr=esT8m z`g$EFx2+x-%KM(@fPHe+)1V&vQ<q)sUMk}BYYy?}7HYMOwZlnjq0NQtLqqF@uvc<V z@_-aH7=C>!et>}X#EhOOH<#^?Se8#K7dU1*t7W!+)UiEm>$9)VTDpDl5Xd_<32k%c z)71tozsGf6E$ab5*i$@Qy~{p0)^0K~+<!*krYXyg9iA_?=D96vmqHMtefRt2_ZY9d z%amzgO6OB{kB4$8elRKlc2g%hrQe|ov>_wN>p#bvD7mny5#vzJX`ZXc4ns|FJmX-O zRoASddw4ucb(5Vw4L+qD@d~E9U#mr>cwpFSf5?9}RCD=5KJ6q7&y9Mt^DS2Cn$Bah z{_@C6K<6%<%tR6#pbzqiK@mT+fDH~6D&^NSI<BNbMgeJfg)+j~m{|fmWsX6oDm2gM zN{>?>G69|O7^29G(G5(nVhq7bpQ1*N!HhbC-&y8!1ms1<a@$C*(Kf%yOROCY6E{A{ z4IAJf92S96zJe+7!XQ!)`+{!!Q5C!(nBF5(RMGf?KJ}ng2y(z`DkW`)6Tk9MD*C-0 zwf79CnEb`F`jnqLo0otD{t*bOR_*%su=A5FSs^*IX;~>K>zl}T>*YUQVS4{6OSR1l zoK@|y$QudY*kC#v!tB|j#TW(bGQE6Nn}NY;)4l*z3)<?{Rak5oyue<mw4#S`jQ3{J z+AiogN4yy?x4_{J0WR<dU<n!SYl3RM56TVe$lk=P*@}$dRMz@R;?BJquAG?m+}3#Z z4VD1A7-XeKoH={Yn!89K%z-IGBSd>ea5NB1KDH35XW^latRr{C5q=?UvWRfncb<*b zoPPHV7Uk=Z#!jCU^Md@)>NjhHSBTtP=)!Y7IeLib)mrxj#PV{|=HX_k<^u4Wx;D#W z2di#fA^w#QfWnl!Xqu~{ScGe8gh+w4O(za)@;@j(-YCwEP}Bp{VuQAAWA)xh7P7k` z4q2`+mpu=Kw!B9~W#MH2ji>xuoiIVx`rhRIa=ITOLu(YqPHVDSvpYGxam|AZ0P-zG z`P=Tk-VJ#kpF-hCDr~fOKc%;-#=|9md3BQfz$Ks5!P)=N{o50HWx!A}%1QaRWH_f- zd)*=M3s$w(ED!d~g7R+)*YVcwTc+djoiq{6wmW<Ndy5SGE0v74Tq~8}<_+!qOx&CK zu}E)@7MYsqVRlCDfB*aYf5!T^ANohF*0#RlXwYhzJJIXYKa)FZx7+4(bl-7UgU%UB z;b}uNVxEU0kcnEk0ZP^%;i}}gv}@ePqnL#L@>9z0+xMi@hudrpd7=Q$J!-dmoNe8Z z8mSx%#HRSoHwTHWwF{IiLD}Qi^@!yI(A}SGy|BG(qoOvO@4bw3$E$xz43BBhvp-zB zl!C(TA;N?|-d562!F{QQy}P%CTN?{@R6G7G7aQfp5>>MG+`57zqHdwF4KT9+RJOtB z5G)$=^}>hB%{4XgY>0|VgJCPeSDNvgK)Fua3aQGe>L4LjO8CpC)2{8IlJ(MCFtFBS zq>{nI6TEnu;X`k!6c5?li>q4vzH2`;7B(=(erWvTA8RSWY-6?8ot4>EDnqyS^Amo% z0r$Hdbwj%F0<`|#Ui%w2wNww%w7z!^ZrI`Bv9Lb`i^M-Ow@-yl45`L51luyqye)59 z=UeHkottUtwp08F5_BZVy_q%FcKwkFk0({*@#;f}FZ664cR;C{b(vo-kz2e+>yevI zhO4EjT_{AOE%)zN$)eM{LsP&}0Tt|XhNG4W>hG&h_&M<l%A!Z*96gj~h!<%=N6g;= z2cIWxHbpf$6Gg|Xad+k0o0c3I0nEt?`T6j*wbTa2Q~&jl!AFc#0@OOM`&bE@f5Up~ zz}xY9y=zOSSQ@Zz4j=9C)-HRoR$aXcvmFh@JTp`@nnTFX970PWY}k7_m+D1Z+`;=i zK@I_|JE6wPzrgx!hhVlXqQ(3wS~@>o_M+}?|DC|bDCe9|Ss^%Qa&;3Gv0Jt2Z5+7A zOBi||xwgZLJu+oO$u;zs(Q<aY`BtT8#L07Qq@B!y+@}Lul-Rmx)j|M@!BhGzY${YM z{P8h_Rzrz>U@2B&Y-c$ZdPzMKj3ySFNr;`$Z39&~h{R)&PCOu_s!vfdr%q=-f`G|( zJf)oMLm8Cy=eYSVxZfUhSWD2>H9Fo|-7=YrEKjxO$J)@=!`&1vYqWsjUajtX<Z{rB z!Oe%zOz^*@IQu8JcxJ2)!18v7-K*E#Ao<hsZ|Oq?WR(;yr47TAGpm09#Ea{&wcYt7 z3y2E!5b%Xq1-b0GQlO7v@<)$)ar})j0QZVU9>{TO?~$>N1=g&G2R^P=Y@5?VtNB{N z$<xIT8o}!z{M~w<>gsRf?*L<db6oZ>2r>?do?Yq_v>~Om222sT2MtT*Q_W0TNOiBO z&MZJ!rkmBLqTDa=%u@LU^UFM+9r>+BbvZ_4Wf`Q+yp#%&%O1n2NqBX1HmE5tMRxwK z^RY0`<q{KsZUN)NW9h$a3%uhu(em2C=93?~`#-LC;~yJu7sce(1~klfUL2CjFwqnY zDIYEIU}ivJ_biNUis*?=*ILyieG?eUbuGcq_*CWWa)$xUKGcsKe<o$fPJFYzf>B?6 zI^*|b%lW&;-2)kf^>nZj{&O|zhQHV_%iz$+*njEi_1xESo?%Yti*i|Wg?9E)=!{`S zff;SIbj0Zxdq!n5j7nLb5zNGWZqLwvmb4XzD7e~o@tyq~ZpC1F(*erx$S&vYAnz8+ zu09;av{hQ}C<#U%6?`Y`>tk#n1_dv*fMA*`mJIX~w{4*{w}^gNO{1N18GeuN+MTd@ zuNlQ@Oxfewvqc)AOGluLh3vEhPX;0fBzoK%BGA%XNEN6;nYnBZcFHu}8tz&cfLLZQ zEj&vEvK`*8sxJc#Ac<iGb~q0DPFslHpODFy+o$Pz=<px_1kebZ`xlptS3y4$OSgX5 zZa$)d?!}Qm+6(cDjQ0C-pRzs<SD%G)JhDH~EIX`AFw(PVar>_wVQoriBNAzi<|~|2 zLdWPG5tanELiYP86a@G4_|Q^$uKHmC^slQZ+P|_qs$$}_WMP#Q;50@5`~Jk(5p;we zD4w6pa+Z;Q&ft(xnp=yqQ)^ukbL_GDc&yH6^=)f@w{?m_kJk*JkAuOV%AcE8oDZJ& zB>_&o?~cgfzUdCRVtx!qz9@&Q)kT~M+5Brmt<V^xJ5GB^oA?b|Y@hVY34L+N#&lb& zzCy6hY-D6arYaII-9TZ+xSSQRefk7nG$XhwIKKg-=pCc?`~=UCAJM}KfvqnINI!%0 z|HOME$F7HSEz;w24I?<|K^aZpxqm<!K6K$z1ql@+U2bu&oRZxhJTo<*1eGvOFpXCH zft|oQ80@U%=FtHSM)PzZOzRh=Hov&r>@+UEN61%a2q_dsT#mtp+gW0G$C|ic6;Zhw zW=*G!ao1?KtvQ>+SFH=$o4yqB63LGCm#3uy3Cre~8{uI?*F<$FKr?pdQX^KEqc(A3 z)$)%b@UTRaH{Oo!+8oW*je%bl{*<rwW=5=uBUX~AxnX``Y^yL(OuEBqUQjN(u4PiI z;j><u&ym~ayVyF&s4RBB1Gx!!9fiHVIb+dcHi<SOq7ZWs<#>M2E`)-k2i!c7DVyP2 zt`Zvkn;(KBGrq~>vUM%mjwA!N`FQVMKUsk_E`IfAwly4Dj{h^=Ixh_Kp8Jlo7&*r{ z*BVYb99XqJ6)6-9WOH`pBT|@5ZZ~CDW;{MYpd$){=Jbx)jZ&e_d0KuW?W;|X7C6C= zn&W*UNg4n#Yx35TzWoDaa7v08cGJ2Uo2TYSoGQL<arCh&;av@T!k7r19Vtn6wGt34 zE4vh+hc+idY4Ml4comENQ#8zTi;Q`}79|Oo)G=~x?%uydGv1@4ToczG5MQ`dM#i!d zRM&VWDE3y-n=hH@1n1UA9uKNVN~XH_>|>-F<&!-z?1burY^<y;?}hCF#?NW9VOh6z z_<WBt7_G?Cq#MqtwTyE*z5xDOTmn+Z>jl9o1a6m|F#4>BjjB!cbt;w!tDw*!2G=^` zzND-j0aIPK1LAY!Vr2vlp^3OKiG?u)ou~E79TP|2KY1^v*m`?{nopBL3bQw$*RZ?v zBy2>q%ko9)4XVNzcCS4xiPLrD<MafTU2_bHQG>^jc$<W8d+V+`ASOH{QzUp68wr_; z|MXl%{?|ysh<nh;?=g6H@yP5_0j>(S5c<&nC$3OD6bUi1LP1a(DIAljeb?hW5gXvi z3{5HU1_`p*QbQ#18+-eP1BqWsd=B$1KR)|@vPPEzpl~4A@GX3MP#~y^AGJ+Bvz6H) z`YL+pjLs!4(S%!ktMn19rX0qnZ{etmMIqM;gQ~3kXTI%dHgO8uoKEK;p~eyBtb;8K zc7B~zi2K^=`h}{>+FS2=R3ZRuX7{e}!)!|xszQ9@k{`#v5xbWxjy@s-(eGF!7ejcj zXU;ZHGv#y+S07wW?<MiC(?Mm)#~7OzXodjULI^XuDI2j}pounuw)M2Dz0pWsYW<jW zu#>LiN6a=**I|D+5Gw?NOWxA~pC?2h(cA}!4yb$ZOugofxif{PSA)v#$zp5uvplcX ze-l&R<nnO5_ju}-Z|xZ_Jf>}PI(9hlV+~U)!!#hUKvVZ=0h}qo_!ZuiQt-w9*^xZy zhasJlyuar^ivEKpy%O-*4e04-EQm1R(AWiZ91YqE8{b7oy4HB1d*_K+B6qSadSR~$ z@%>4gnwf6d1?7s74_9+IJQ;x1E!`sS5X+-!!l;PHBsggG4lXm>ZZ^Mxn)&xs-o!32 zD?uqU^@~-|Lz29gAoZ?Wl3cF-v46w+k{EgSiJjxAMpc*cb@G`Z6zZX<WuDn(@jj_B z;V&Pxi{#3sX(!d*BC~I=e>8TzaMGkMvHO?QBYojCyn>L`s&aPMS2aa!kfP&QSC;%H z%;#*FeA%Qd>--ZnOT_h7fs;o2ukR4S$&DiMInlVBr61-bq7ge>ES)Q+4rg#T`&3w8 zv2O;H`r(TQ=UE3g>qzbl<C@?Zn?M1p7zH?Vc=#Z`h@_G4&Ua(TWToEs)`9zYO_{Pg z_iA6!r&pMDz~8<!h;xOipRX`h6mBNW$J3G3x+D|El>^E7H}7@nQ{L8Vj(5l2g3*Sj zZ&EXc$9H??RR$XNhR3|FpQrKb$W!el_J7NqMIrXzE&RL|{J80GJXL*SpFllkc>HAQ zgcc^g<`?LdmV3A8N%lr~<L2Q<hW|6<#*wq+-a34mdrrj2vuIrHsNL5*g++}pe^GXM zEadq@&mChimoH+PZGj+Zk*5trw#@R$^qlB+koZsxnY3PfSSApb3(bW#T7%}d?uYLM zj`>El-}~7{{C<-gM+?&h`vgw0a^=1z?)G-%xH{iC6oWjBAa8drkDvYt__STfGcUx) z{km*Z=Ja%|&y7Es4s#1QD!^@p?N+@$P4p27I*?n1ui0{Ub?RvBr))c8J-q--PEn2P zw8Rf(P}w?Lm55j=N7~AX3uE#7VB`Yy6upnOxqR2>)GU_Sw87EJN0ET4;?H<&<&T3N z90gk|Y$^~cP41dSzx10|swhm{-cE2kl9$WAj5TSrP8^8b)A1FG-VssHDOl0v)c<*K zG%x$s+o1m7IN+BDpO$mj^UJLBwASS%!<+2b2_FfRAG-ofnKCD*(r1psM)&N!k4Aqg zXb~eDMaes>R|>#;qDlMj8(MG9TXnhquzeJam1qI_vdsrJAUo@)OHX*2$fIR;bUN-I zalPxfI1@>nAh2vs?9lRUwJQqcIOPs8B|5bZ4-zUiO%4-6%YaK>6;o?E1{C4(8;QX? zZ?Nk}d+7Kl#<Nb3$AGoocCkfN-&R+goM|+}XCfgGCy8A6a(2GZ$V>}cVXr8$?(lo~ zT<2psCO6EC_zZf7t({m&Zr7;|1IdvWB!T6ENx7#x)hI(%YBtJ$zADIG(Da+oe$87I z(x+Gct6;p!MLb+ROe|wRGvg5NhKgNXUrUW%e9`>Kv#VTm$E+jsei|WR)YkNgyp<t1 zQm;I%+SZS`GaLJg+ysDK!ni6gD`+!}s2M(W^rbJ&1j6~2LNIL}QP(K`U=zYQmU_XH zi9munsBQk3a8`7g?$}8DJ7LeorM7ESn5$k5xhnY`o0%SS7b7vQ-sjE3PX14;ZiSnF zA18OzOv8HXorwh?4EN>l)(=Tg<01vL3>K99S(+V4KCR}@3X|rmr)68rv#sAcS{1Cx z^fweOX;RBPyG}xFdvTZu^w-F{i<9aT9b9@j<6H&f6?wG%f-YP0Bai~1`+I@awOxGI zEVOAH`>XyHlk2}c>z6|tF@DLSmBKLP_hcb~DZ3$v2GMZ6?Sp}ZIz|_c`7Z}?Bl?Mv zb4#n??R-Ecnnp)5ACki4hm_1@tC(EBsKbDK1QvYHrw6>KM^WD!l_z+F$A6-4;~@(z z+9vZ!<&}mGu;S>C{xmXh#8q^XKgiaAfMQ=Wtda4ZvW@Ks!`|eEmD+A3w~m4A7g|6h z>{}zR`;Nx5KclJ;?QXHFia-d@7sV<fyq@71rNe~ij?&eCaI>3>xd&gP;;&+657S$D zF*}8A0w7X2AY~DG^zzaz4+7Pn=i0OKHk(x;okukm)g5thlx=EcczO2lO*6BmM9&b( zV^gG<u=;?7;8Ov_9z*$iW(25dHqpy(P)VJAG#RCcr+V3T?yvU~G-r&tMMVjt4~{<u zypu@j^)P4_2g0(~?f<7Jd+Gg%9#jBs43m)MbsHEXKt;A@2nskRvPHrat5BJ1*ZQRP zbMRNMH!Nw$2bsYl<rqFt*lNFv5dMc8$SWDR=p(~=D@uDn=KlK&EzTo6zb5&0m1S8= z<lYHP@Z;l2lr2Wu2MfCok!{oc*Al9)GL|-21&`=}#_@@?#IXcT0YrbzfIHwI(LlIp z<mEVzz9MfLN`f$5G)T!MrLZ=~a^3`7&W9Rzm&2G-z*q(GHwA~in#p@;Oc=S<dr{eD z5FI+EPVWIHInX<;ym1RoAwTcWY^3y)>E2t{%jQBl%GuvFseK28A2J=q92SXfkJAhP zu$h^_$+w(F44Rz=@!_5N8@Vb3Bfw3eOlk&L89yM*0#;s(ZKan)Z8VyLyM8Q*;hTJv z=Fg&Tg*$!k4ha%v+mL6R*qb<@cXhL~wIy3z7ebT#>;lTV8kS@;z!zH_X-6l3wp9gv zqkXuF9Kd9oH^pvnj25m10jpauih^CoE&?Z0i?$Qa=pY!*-^U<C5LCnK+7@Lte;o^6 z4MlFcpT6e0ckF(eZ5yh2VkF-j37~P=WcqH;BJ(@|*IgT&UWA;(6_~92)ViRlzjOzE zJsgCvFh^J^!P||a<<gsze2g@|d?r9NlR9;SJZ8s+JBTk$xVr_&H4DZM>`rg`&sM-s z_Z0ifg?{DD9DTe8R<RBJc-`53S74Eo?`s;6j-)&d)EV2NHqfYGb`yr0;y;G2h{}^` zc0B0c;5Fk`+zMe(s;eP+5zG+t2r6S(4kF1_%cji?Y=~k(9CGP*E~At6g?8}CqC{-| zOm~AMh#vpQhRPmAZ>I1wUI_J%ZQSdtE{*^+iop95h(RC49eBrsFUAg6imMAEL^Zcy zDh;Jz^ZfLO!rK%8TSw8oE~n8Oy=tSk{hb`lN6TP$m=36-Nlw>;jn>LTrr`KS=P*-n z+NUV=I9fuB8RJ?ID30r9Dp3pFNb(0n>YN-+q1*NHHu&hycR=N0y@ZEZI8U2Gg|pbJ zV%}Z<mI^3<0I6kmWIza(FDl^Cf@JsIo3%6P@RCwFXRtOFA?Egby%laawy=s%d#i8H zVY$1DK*AN%-e-f_XXEEU>)#Ln0ksm!&MZjTdb^3Q`;?aL0N(h`U!5KPsaQcCL8`w2 zi|&XdVD(M{8_#&yrKf;A<<E@hYQ>91IR}6+A1|(^+spa^`W4K^3PgXo(AHfxp4$eT z7DwixC?xdQ4(~C)Obpun7wBP-**ed?e%_sDoXR;Z|I7Dn0^|0p=4wp~qhrTzY<Ev~ z(+Sk9VO^-!@+v(Ac((ary3CaWjM}l}^fhi7#3fie|8f8wM$hebfuNuzKm?gXH4_>+ zNxy&p&>ar|#KBi#6QJn&OwU+=+V&m%0$3UyAsBVE0HWF2Y%H!+{jFlSVQo|TJipiU zX8m9znh>Ky9j@MJaDrV=&{&^p0fBKA;Gr<A-%zVB>;|ma4NQIAqm82dNRAV0$ekJD z)x9|nR_kFbn}LvrueQ*L5$v?|YV{fzZhJFD4ZgQ=O-%k7ISGKVz|I@>H#+==A6CPP z%PZFjjP-W4ryJV@w)5h1(gNZDq^W8cf$UZ^tb;jyjb|Zp8H8;|Zjl#&ymC#u><$fm z`ck%unHd!Cu?B*9tr=!PNc`2-$VbEP7-N<QuU`7*X;&JnbeF77TA-JYBC0@Cqd8&c z$NbAMU18cQZ?`$l)-q7gne%vvEhr&i>Cg(<m;mYsa8ZXr;x^Ki`YHw2(!k(owb`uP z>RX`SPWgyk1=6(+XKJiVR`=-XJjuJs=lEAl!PXvS{G0;7I&*i^yIt!f`#p5?${Mid z%2?lL5b_Q;x%mVrFcx}*3GA@(*i2o!Lvks%g%fx3I8zJYj}rW!;X`)Q(>qop=!9$g z_0Gntf6u&mPq^o<*~gW9|7jE-lvN@;=%`attK9)HZO!iuxp$ty<p)Z}NJJ}nu;}(_ zSJ4pK^#<{Q-Z1&=4L5U*8a&lf@iH?5Qu`VPQn?kCU~>I8X-n+#VI{$Fra^QAksJLA ztuvijQtM7G4QW13l#Q~kGxc$I(~5Ry3>bEMtiL~#^c?WFHXN>*vfJ}G%4uqKalg$M zYto)~?)5I*o}GFu`-?C7aXO(`DWw1`5(jB3zj|)ZdX`A68wb8>2#ta&6_0ckQ;~S6 zTPrQ`4)vT$d6F_&wd4LlUK9kNkLdUs<(;-Z+P&_wZ>`(%L+dfEcK*l}4>`ixAzfAp zPLq%Rw4fMsIy36l_Ca`MNwve6-Z#vpdHxHuB;V7{jwyRdJX`H0t?z=utsOQC;PLj; zaP8R(7H8%($`>RmwM2ZKn>xQt<l=7RRaA-$13u5b*_PoNlw{qPx0nAqwBhq~iQkIx zB1g5b7l!<Su6xeZbg=9uxL4-UDYv+%)<Z$Y*ApBiuPU-IwrSFG;jWf4I@$jTh!UUi z2luH&b`;*-6zA7)t+muZCt<2=Py6o!lGtU)2|i-y+P9XE;8YJSE4D)gXX}9)I(*@x zWu~Z9+4L7X#iyQKqL0FLt_La9^z(VWqIa!$EyJ_?dPUP)%Iv1pvyYOEoA)zof=y?} z)s#{hjz612uRV*4wIIn*Rl_?{><0FeMa`C5H#BD`j4d@N+r@bX5Aj-&GaHYef?ky( zOx2WIg#Br*aMs(nr$pz*v$<#7v79AfvLyK#iTD;fkHxLRPOPnD0Sv44Qt3s(;(>IU zyFxWdzxhnrUBIJEp`8&&FT+3ny~=%g30rm(yiC1V-kA~L;~9ww(A$2VmRWo0IQt8q z)h*^!>@R9>b5@tP**mYH^AjNb?`b~zkk?0AWb85IL*ZKj+%0t!v<!%#*K8?82+Pr~ zHEV8>SY4c2@G)rwD9J1SwC|Cro8?r!5ge%`fh~-gkJrrUQ?T2BJq%W~>zDcs<sVRB z)-aEghC@csDF2n5ir&TB#rBHd$KzWb+9@_0K7y`D(JJMfYerLyf>j7v)jMVnk0=2y z*x}_IMkmy`mG{9{K2PRyV3**bwbVPCF-KItQV#7Nbg3Tt6S(!FJtmiFkc}hC@?pH6 zI28|jc9|2PvymP=P!4_Ninc+v?6lvt8(pGqQsGZ9C3`kyo#hxDX4zf`E6E*O3w<+} zXjYiS`THe3r{h<kY*Rr1u|g@=A#B2!3rnM-54T%3g>~S*BPOpzA-oK_3fsfU;+wFr zLSVwqzu(%nnoqj}&EpHj()B)mjPZ%~$l?hfr8uA)$r&|p#=K<d@PakA8L(=;6C1QD znS0edxrZ||n`RG#rDvwPGg8-WC-#6U^hc6BI9WCKfYW94b8*-IS*+>o*AX3YwJ(c? z7WBg!KXVMOlGk2w46f&Tpn<QN<XiNaBs+oU$v#>UASowQ*x&`%A-Ynuj%T76`;Z;F z0pEz=uf*pdY4%|anmt>59iJs=Wk<w))I?=xK27d)-%l1a34GITu?_iI!$gF*u&e|b zr#`DKIWeY%yOwUfa*$94NrP?4^eG*_T{)+k;v50#sF=<T;)kS#z5RZ*<FL<dv^yY+ z@c9tgZa$@@yVrr-8U9MtoAAcCVD~iNLsbndu<Upzbg!7<QI0}03xebr1%X|gdo8?r zWS({8^1%*2X24fN;87A7^1(0(L-lGu+yxya!{2Q?e}@ShH(`<_W(jwZpOvZh<r&0# zNP`!so3Jdpw`AX9Hp5g@{&jTP(5_@yll(>h4L&oAY=t}!)&gK=#3SpihD%0^g^G@A z^mEcT+wUta569XPRRr7u%eNxbcG+b6NickmT}mq7<6FuS^YM2O0MaYQ`QOr$pc`1B z)?t_B)*ZkFyFBQ6>7?c91ULz#2)RpF<jak=fBkv-OR%MRYW~At6wQ!krfDnu<1QKo zExPa2^xZT|m&=rJ9)ld!2PnMKgWNl{_(O#UHl`w1T9h{acX++>0z;75AN53S@4;~@ zaiBo#!-lX;$P(tDgvpBAqKk3prAKnbEn+%uKNd7@I;c_S+DAJRXa4`};4YAR%ig%~ z#R%(Dx2*H4gDlE=QU~-Ioq|m!W7CEaW7&6LbkjB$ct-8tedi)b1EQISF{Eklh}-xo zxbt20*YJ}r*g=c_p6Xj-#^uk+@IHaD14)~|6n4w;jxg-McFjuzc#|3{*gK#uR)=v` zd(Jr+<3{|k9~>XNLH}-!aY?CaPnOJHYSPxMCjIM=UhHXJtAv9cT=b23iTcJ&A^1^R z*5!hk6#oe;deJY~Q%F&8HEAE2ji&frcoe<)V_jI@2wF39xS|XH8%UkGa^?53JAacR z${ZLBr9OZ?xZ$?L>nD8;FGRzfre<66zsJ1-DFrbJ#9d3fsC9skfH)beYJIn?9@Tsp zy`#uZkZ-)1VQhDCKw>Dtwe!MVO>ZM2h3ydu6okZzO~YBf&u|pjw{Af7H-_NnF+YPK zUAewnv67d1K1h&_ns3HR_$I7k>p5Lct$L|_BJp<T6C^w041y!YRnhb)H-2M=U;_9S zgF22uCJ3s5klPG?Rv!hs$HMCbnmsfwUP#|v1eLAAv#a;+2Tj7&A(Dt$2(Rz_=Sbfb z{<hgM2`lMwwFvR;^_9bW``IR-;UrR0p>|R>Jg$7^y~+Ohg!we%@F9gh8KGn)^ilh; zw+UZHS8#{TSo*NhWFx28ZceNc4FdW(!H+dZ1k)|Ng@^TdVb`e#lGrp}9e7rqDO5b< zPZHp^4e}R>RUXgnxB!^|hc{R+owL&Rp7qWu@RyF_03+w{h^VX;4RMhq<5s7WQc`Xk zLm;dSl$&7$>=qf8xWhjW20aiP&zy7R%gz(eH@hqcKFM(56WM5J-36{ggXTZ0Onwc= zqT&`-QF0RzSFz;;?3Ic&r^{FRt}5AOnKcw9Jru{#2aE0)s=xjbEFh+jx#9?&>ui$C z5h)o-JwO|V?ED<FJbLw*%T5&92lE*Db>AJ)LJcWce?L`^EMq74QRg?pC==!Qdc#Kr zBVo;g%0FN|F%sL%4>on>s0hgrQQCQ9%!(uu+Gp}M>Y^#md5NjC&iZaeZm)VQTNa9O z35;sGcBNGn>@Yai(ER5!&KI(B{c8t4fv6C(!dLh<tWLftgi%$p*7riJrOS1{``Xu( zvj6oo%NKmD^7wIjvGID&Nb8j{_BW7K2EL{~&9X0|s{Jr(_G+*9tcc@CgXq{}^8#<t z`!-`3DgL&qELdbe7^7tO|B^IOU;D@+uh<E2-J&ZmDk#hKaZ?d|p1Q5B{Gj<0xC9D; zmke{+3HtV1u;1(138~MHqczxsQK&!I@y><8zYe(7B)_n^MET<Z_X{_eXPAOX?Zuxt zT>v=)%PW|nZ91pgfaC@#M3_CK{Mso<|HoeTaAR^497MLz8nS77(r3Pv3O?DHthU*m ziWkt(sS0X)wDJrzc&M-+$6`NT$JiSrr`k%if``ggA^{2+6BwcyR)y5<XLib!1^H^F ztU1{CEA{VZ);Sb+EZdKDNU~GQa#n<5MAEE79@J%JN*`oGz4IHK>NKUOk+&iqk;d~= zGa9~ME>UmA)aj0CXRaHpKB!6ZE)t*3{4rbG<tWE!RY9`c(+^X*UgJ9c3;w!cEU#uu z&M^CTA8APun~6!Q)GwW1zD(q^z3=D=4Y*E6kZ^`Cr@uUzFduyYc8!v<8v_wNWuXC} ze*?`#E@y+nxJeeiq;Fd@s<QkaivB+^-FPK8%TKbfVo=Jipd=wRcWF?(xbK%*m|3kU z&%x`Az@(^j$HYYI6+t@3Am)M_AJdYc)%ez`A=@m^at%carG(5rUA3scdj)lJXzg#b z0N8Hq*|&fHsh1A`AOH2e5YyLLVj(s975#ib>0ZP3`e=48^&TVmw^>QLs3Fn343lcw z+G9Bp=K*o;S!@&>U(mSb3jQ&Y?hm0iX`_$E4ourh)*|*eIh63js^srNSM5eldOnGW z;w<%);%!Ix-V9Eo#mjwfSxuM|CaxLJuY0_*8tadZtIYYY#m@A)!K>`G>H6!iu?qK~ zvW=m6{Q0s;jbo;PRRJLtgjt2ZZ|@?}EvqlD4xy!cG;*6Tv87xr-BI{(qTDD<dWKti zHcC<-F#0BPdrSa``IaC?XC!VUc2*gfG<)zkSC;r%hQ;TcLl1u#7~i>pMT~M()RLR* zF9N*6SsFI*wwgeC_-guFY;9K^&K_LroJIqR@%$8WN(VI7y=b(~(?xJ>ZEV}01&oZv zPXox>_Q-`+F`Tq<**AYVh7<M3uQ@(%CtWS2xL055R;H)NtcDS(139k>xAJYXc`&88 zZVeejHW6ei*V-vT7sju3Aa#ZU<LmMyQC(YIo}~QLss^x5DU;-UQccY<C86@;-Fwt} zq|Bsj<#JG~O-MAM&T}V}{Id%8)yn0Fqc@8t;Ze5>Tgds?clS4%Pn&Ik+tHZ&Yt*e* zgG#iHamrgdHs4h3HRV;RiZOt=pyB3+{!4!{Z3Y+(-<U+fb%1&6P_5PozfG3IgH2E| zmHw}?6{VU@fLzZC{|#3@v!M8<){7<;oUZd}ET@OO6{n3G+uc(=khfQqlfS562Bviw zILTzN=)gyO6m*hh1cMS?k~=*Ti+8!;YTNzVA{u#C7iu5rCsElNG(E8zUYt7l;*3l4 zQj_oOoTIGYe5)#8A!}tf2_ra6{2I~bduVm9WF!{+1*m`rnJT#4TC?}b>qak%zgRp) zl*|ye(zgmqIK4YU(P34HTCK?e>4R<RZKde*k&01cvYsxAArX?EL>q8-^Qre{c3!No zFVVPc5Z8$S&5EKC+ogs@>P4T!=C5lfk0uyLhzs;s{Ap2=1~oR|mik8;zNg+B!wTx8 zjxNI-@`<2z?R@0XMX`=xvnGFqJso&3v0#K|OcZ6g&_{2)>%TVBL~PNP1%vccN8B!z z*})oDH>TYa!um6XKuYo0`>$4zB*X-j+nfUG)a^r{bem%oL^R92z$O$U8jl#d{vDe@ zqXL!C!+g|}Thy@tx;hkd?*9(@q)q&#1sHYAG<!S8uf4aFqT=fc40xG>&NilvM4X2Q z=*?f6d*W*}4ib#Or)~YN1=c&)%OVtoyFu|ka9YBi^sS)WlK#Y9VSy=+kNET3SUe7+ zr1pAxUN-2G;Viz8Wi<6>KdAkn&3HedDN4$_VtpXFnEnxtaN#w^fUD>KT~cFlM7_Xy z8=GXji)^G(UDgf*-o58!d^kGcUKcB9qV!q~KD|fJlhg@;UtRBY7voz#V5fEr!lejb zt&r)IVRGqKmI^idcUJ}QoC?OGqc?~#loHzv%daOrH@wY}LMzOxW>Kruc}l}#Saq)- zP|(LBdw1y)v*p9A(fT;b?r7R@-Y1JJg+Z1gHuZC{`v#p9#DFJ6r&MWU1Fp9yGZNAL zBtD5UM_aQe`yDXQGyXwpGwqGpvGeH7A1pV@2kyVjDj313DBgIYLJrPK1;P1MIpGo# z5SHVs&c~_vR?4ks854r;eD3L>uD+1a=rXz<U=1L~*EJ`V^YL&u%eA!mLdBC-nvO`r zhK+J#O~G*qu=_^=RpEiwo!e>we@mD54yyD~%}*ND`1O;{xoQ|#9h;N&3hI||_}}?Z z!~X}NT`nl3QxpzU!BzVeckv4<60B!<*^7qTc|T>V9m$Z7W222u=9CPxpPD}xD<`y= zCXX~j(s3pAiE-YqSL%`N7>LD~w6Xtb9p4yAgNW6{w>586pV{5|M4#k0{-Km~f1k7T zGe(*NM(Ve!qOg0GYg!tJF8UWd9Kmn^oTg-Yv>Y-nZR~z&+5I0`>=x)nxVJ~&#V+3O zK+=(Zy+0CkYoL=qJNB0~$`^cb9gtEAS2~J5SXM?j>0%8mz9-nxx=n<Rx=mV_zI{gh zyK*3Iw+{Q0F8Fv4uaNWf_NSjh8DGi#1v3C@kZ$THS$#TOu9pHo+6;a)f>VMmdCr3+ zAGd9sD2~ejkPWLm?ND6N^DB6pJ^`%o@)y;&wruu!;$<H$$jTq;7we@CiTq}F{wid? z#VC5`l>NnGo4c+l#fNl&j&T*s!r2Bjj}+xR?SD4`kQjNP`$L^?D$PV<8`x{DU(Opx zIvE{9=kZ*Fg<8;lj(aTU`B;T^+|grqF+oBHz~zGr-H_*pUnb}+gcg;}yt&cfWV4BX zPwIw5y%%^vKtE0$M~k;b`qcMsfXL>hY5g|MSEG9^cN>R8O|0hMXwC%oNaPm=+h}c} zO(S|rfU<;jM*2MV4c2QdYO~Tw)wG*epZ-kKY>brbSj*xU#WhRVdsanyQtm;K(%XTc z;;WaKZ9`Yb?*2ze%uB6CJ_DLg*_E_Zp8ojP`aya)WbGh9Dj2k5X=>;~w0_JF7U^K1 za1E)F@moThCMVwvd>N8Me!uvxu<%7S(2p_#<C_rJ01blx(bUm0;E(6{oCQe3?MqYK zIaHrqzouZERJeX1;;wAO1-?04mVBR7Swel>6WivZ(*N|6VC1mD;tG>rp!FDOfbUXe z3Z8tt{+}N5pDJ>gzH;soddJ!{JPH&WZocMa#}{kXKw3KM+2sSNuPAPjb8Z@aadG}i z9d?T|9JPA={l-D_Gq@P_o)94_=@9nI@t!h#BeIo2@Y!QLoF8Uts^Hd7yLVpXBh+|R zI|=)Ft?bR1AI(td|0C+X<JnyQxbg29Jw2x_9jKzJHLH}0)dq3eT0y8$YLruZI|z!1 zb55%^P0U!Sh*hg*i{g|Tu_Cc*x1}OBi4la~m7eGMJ%2=AH0`Ue+kIcx`+BcW11Wd2 z<*2J;L7pO0!i=y_HK>RYe20duhwd33u)b3oZ})e+_K>;jhoW-rmbZ@%3BS$%q8WpZ zqDq6~G0#-HRL{oU`%U>cG-O?=p+!X6Q=FWzpJ!P@?jzVKGapVnKp%!Tp6vBSi|pNH z{6{IBI`B!D^=#P}_y*Vtv7*H{5tKolvks_VC{rNSW4($v)3q(xv(LM_*Rp8O>&jEU zE5Gx0ru7mY5zmyKSVYX%#31pa8r$L2D#0ndV>L`Ka<&}$*7?g*Cb!BRpcnj6&L@8Z zud@{m>XEaT+^%3oEE4kv5TV4!{aT?JR_30ohlCpuB<5X7Q+ruDR%v9qL^j`rn`&ug z2umLqtD4x3&o{baBE?g}dN*%fiHsnYxP(f0yNV_kH22zic<?J?V!Gx1CzKkBlUtQ? zfW!W6%q0F=`^nXZ3-W_3fMS1q4HllFK^k9tfMsy$fH0)=vhZ_hMS27x3@Rao=h`yj z^w3nEEgDP5(w<~_UHMTEItVSV_}GCb^&yvC6AR+=MO$xcQ5(A5o*aKY2PDLMr)y%K z0aB+U8^HhC0t2d${?L-X+s$6t8$f+LR~gCDwrSAuJ9fw<MkpYtt+#*w@8u?z1)MZE zF9H{0haK+n(cQ|$Bo6>xz}w#MMe8o_-5ty6EmY|hPB>#fMEQ^T#f6)M)brQaXme}+ zgq(v)1}N<dhbuL#b=pn}Cs*%&t4nYXU5HulK)$u4mN`<3lJ#vC6q>Q5Oy-^9z@(n{ zxkIPB=MMxCuGKJ|FRbX$%i++l7?;Y=h82}2qeYLd)1S$H4g?wG9D^F`NXeM}o!Ua; zGcF!8b@{>3dKxPu!-etwa5K}|HRxC8odjiR2bF2uhwbO2TA3R6nHNfFU?Ue35ZqF) zlwliZWMs_r17q%onw}_S3y^32cIaBh!2d0`BkzARK1gyl*KHkGMVCfXkaC&i+QxU% zbc<o!6L3ZAY-%H`w5avPYB_JEAi}W&uJ%nsV1%vprB%bX`}}5(JGmyv@6RCQ9+e!0 zv*!7JYXSdsQ!(U#u;o5|qgwvP?t{sJyMpY*!c6)zrEPDwemOX_vZSSTnT_!%UrRM# zkPoaCsm>S;m1thePy)L>kMkV^J2iUhO2rq?C8uqDD9J%(+z!sR%^$g<Z_ub3DA{(T zhpQZgucRvV+x8%Ld!~Q^4%0kDnwMz7Ck=F-kUNg*%hnxNV;kn$WDd|mGFc4kx3ZTb z>^{6ZeX6Ue0371ZxXY#o>ay&U`=Ta-E9hl0eP?TTLMos5*Ol@2KL$+JIOy{Eq`XEb zPe9fGK6?6u{cO~W`n;hfgYu)?>M?rOn<H(5ajl_jLJ6=<a(ZDnPVyWJsgc-R?fxTe zf-=|<VwUV{Um}$H!9!`kVrgdR8HlC~id$VD2A>H$1_Xg1i_><*F3u4}x18q)4DbK( z>t^KHocGigDda0Mk#2YAf9Rs?Gjm{`=9hV%C&hhI_+_Rw?eZmWasHT~Q5p9<A!-A+ zPo>jG!&E!cJ6Xqvc1fRpQOMK4#4;2vi^Y{h91@wjufv)86N}HxnOfG{k<Hj8m|h+} z!>-RRv>BVpP6WB))klyM&7l>$8{h)2|A<MNX_8#jt^Z3O?<Rk!mutKRE}pRu=H_Fx z;mI~&30|=ga@Z$CFN6{QSsY>~LS~ze^nmo8mt>^nW}STIT*F0?ET3#?_?3U7&dv%& z{Qj79&Lg<^DE#ALc5rC~#njgUrBW47H;XUiD`$bzXp~YcNPlU>#e(H-E@SFDE^R*2 zmT8VbML8(tT>_-<+33mJOZ(tVtJ8_0o26{a-av(co~U*GV~5#KDwN10?L(B=9(Yi5 zlhp*npO>tB_fR>cZ^??;yUp{<zwRrniPsu3TL`{cLkDp0iA(T+$)4d%RhIZk_mLu% zd_R^!Xyev9!}{th;#n#WzDJrmL=Z`rCl)zs+O#J*$u-3sh|Lv#OzKq&N}j*k%m{nX zk3pq7P4Nmxk@SO-ovu%BpJ-04h8Za0NrF2soz8*pS$bAJrr3t}kEj51E^Ah_(GJAI z^g|{7du=7|A9a|wVac{zE$v;-5R8U|@XHxibBb_s;gR;Yp@}HP1j8#D^s-zoz}Y&Y z#A39`!wgp6IBSFF+iArJnt}gQz%WOhu9(H@f8NBY?}6;B=^)W9v&zjQIn>AUrS#wH zHuf3k`(DnUR}>$=YKHGUD={oG^*|+BUscCc7`vSH0sMw;a#E^)+?TGqTlVMXZgiZc z2;?37@EXz@LzeG6aC)X^ELn5=5!M-?>D-RH0Jq-7_K9lHb32gmV~0lZtnZunhz!a^ zg`$7Yr0KqiCzeZ8kz<nkNxVU4oP7W+>5(lM4j~>6Dnh~~*m2<vKH46-*SjU{ZuCe) zYVh-+MSCnsCUEq<f8(^3RK#6W;{)7q|9&`|4fyvzoA`?0))zX^$eQA<rZkG#w=Ok5 z^xN3WjyJB1EwQBj1*~l+O+G*zu(o^HAd(k6%Q2CB$a$+Lo`vZ8NAS!}Gh7qpm)`XK z_MpiLRPI5H#}(*e_=(AHe$xpJZ7y0+vrDrlah^+E!H-^}OlSo?W13{*fnmNA%Ay)j z!25%=Pzi<vSK|3r&yXNs@i&|?8cw5?i=>mx_K~plA7xtJg@aISV^q?>A^h-Ni$;O` zA}wwgmu;K<)9gt!aOr}evR1z_A6Bl|-%PVbUjJJhbf*>t&;1F8@(qVdIgRjpU+-vH z7^WNKQxl#bRUP)9*xd+8(;NiZp<(83;p%K~CvuC?Ren(?KLWGDE5Q}F0Gn>rqjA%- z5=CZnFQwIrXC7>>#yoM>B(&In{r4=eH7=lm2<7we41D6^{VTij7Y!zO;ts4g^Ru*D z1gi9?8IOpI4-6~Pa+1hwpOFUIw<KC73)s4LKAcVD2p^-d;zged)Jtu&RVv|$4~jul zY0Wfuq)wdxR(XasBShD%e_oz%VhA{@yqWqJ5Y-vto_d~98kqP|4H1(FqTw?0LF2fH zG|3ryTQXE4;HI!{@y$SZPpCwb+VTrSR3-5Zqgt1MJhiKTN-_O~<bgUaXhxu9+*^7j z$q88rw!k(s;6=`hl7D!>x==}JKZ!v09#+AJZ!)?jMgfZpvZ}!n?L~``{w87y?vDF4 zT?&6DlYcs4o!oa0PJ5YsDn!!qlky2JF7MX>4!l3G^3Fe<HXtoHd(f7vZNQEbNLXXa zbEg4JiGW1cy7<TbBoU&e;~8|_WAOrR0TTBl^2!4t$Qs!LOs5Vyc6d}2fmwIp-I3iI z*V0KYzgCX(a)^MdRJC5u>JGkcJ%Xf(QUHixwXNH0?%k#Qw;-JgfBqezhVb82u7CDz zT;XwA{~m=)q#${<=1#Xhj0ZQEs~6UiV5A!r{&LOZwE@IP>K*@3mL16}Vn<&G*6srG z()cnvct?mJsiXTB%yKHSN{U*Zbh;V)!)hw>(@DBRr4!k$lK3UKvTyZ~3Lt0~X^h4w zaxGqdQ3JIhybn46(S}k~U!3Y1sQ&|WJd0?54*dYNWvIFtV?-p=0+F?4$+8&q8|F(l znpNn1aV5p8)E9i!6#Ek*=%Gyz+2P;{(Ch;(>M4i)VZSYZ>fn4Js?ZfI=LEuiN?!dK zK%jnSbkRnVP5%$Dx&oenDG4edq*}m=K9NMe{gsxghF%xY22$ptwBh;x>?`1IS_b!3 zftNLB#eTM^B_+|TS8Ft2s+jIBFG7D1oX*tE^ni|a2deHv<D`2Z#0Es=x_4Q@*@px) zH?{4~Mh@m;9ovv7frv1&Rc}ErP_<VbBq1NHbhh3h>rL~TWY&koLNeErltxgU3Qt%D zjh0yQ?W2|(Z|`5{!L^$A&tGd#-@<81vDER)j8mO;eIk>DKeCJV2|X)-r_$RBNnshx zr)c=Jp@akk-CEsSdK1QU7Tlw&{K`%zkIHQw`f8e_^9=<%w@1C;&X%P7Ug&M2!q*zC z6mVE5;4GPReaMK@<pv1Yi9!1I7l6iwmfPPiD8^aTxpZR4YSoY9!O6$y^gjPk`P*BP zSF_yUyQR|Ksqw-Lpd?dXkM`ZxQHkC<6h+I06or}7>ib0E`s`1+fs<mrg=|*gyTF^| z1y}LjOX*_FZ6|9XI$F1M;!AD#z#;1Z1vVXLjYL>8d_p3C2NsZG4NaYX*#O^vWLUW2 z6+R;&y^?AkY`7nEDoc=Fp)2ei)`%YXJ3}XbUi;g)cRTJM9jIZWuYAP&!XW2ZwJ*06 zBx;;zZX<xr;QFQX&>HVeCwQ`G;eq0_o>#?nGCZnN*f1gLBcIwF5SryKzL^I}?8wMK zxE89WOdN!NX?vSDx1(heMOfo)sU*6Z1XFLu@A&8(i;lFpxpwZ#Lvc?kG$;f8ZpKI$ z*f1K0LQXrj?v0PFt*F%iJ8Lw3WW_dfyLZZjz^&Q$*$`ZSI*S!sl~f=Tr6GofANSU% zr6Zb))wA5NX66STtLh@|@Z@YlLSF#@ns!LTP>ek<EKSs=WE52?j_<7<;-P2R!OzxY zAet>9lOd`^@9A<;-A@AW1IYBWNHdn3k^W(cbA6yB>7GO}R9Re4jSassv)C8tMuSU+ zc3%%zi(a;WZAHY8HVWRaS*v*esib|rxyRXGNdv(nbT>O@CF^;8Ub)Nm)Ce+7Ptljx z7U7zwXB6#(jHkWAu>LZF=UDJ3+KpJr<hjkcrYEl>8Urwk;Kr-9pz(8oB0^xR)&N$? zZuv~m6!bX0Et>!=zj5PQ<(!61kh=G{&-rA+c&pB997j?bYwZqJI28~ZUjF@UkCpt# zG%&@3ehU#};lx9cM!qTw!w1$1)ylG2F2+LPQRg4)xc4N@3pZTp>dxza_=u-e8C1K@ z0?OE&KzR>N%<MrKQg+gLu6Q3Vt5qKnVi}pb5eSp(@I%eWjNc6E7|Z^BS07M8YrFc? zF3L(w?UGEW#2h4%($Yy}IuI-&4b9m97ITTxDDvXu{j(ydh@B0AM(q#pE_N2)kT3jl zFy+gWIUE+6C!=BPp}EP95E!nhy{CDiaqShmED#U|m2~=h`+iT&YCo^&z<BNC#E!+f ze?)9SEobyv-1gVqLW<h5zI+*DeR;8yVg%fDO`lp9->51ygLay-fcb#$bY{r0gY4X5 zafCv-+)C+@c2si=CEMZrY|&z@yc!JExo(jIp8U(9r+)g+hwtE(<{BuMHG#|8M>~z_ zi6m#Hp$c~~xic&jx~f!s%xy{0s=WexhVb<W1;c8>!X!6yFnzrHhLz%TLO@Cm<w!c2 zT~8pGcweXMbb7_?%?c8By<TY(XGikECW4nbApk!ieQGOCJhFrtaLGRCa?+vC$jXX| zH|hVt&8CNOj1*?=cMRzoD$)eszuLSZfAR6=$ZN6_SC}3oI`)9U>RtmS*a9TOJTf47 zWJzj`i{H0{w2t}H<aDP!YyE1s4W5P5iXk^8?z~UKp0OQdU&Pu99zJKa4v08@Hvk+j zA1c`GfhP#8PDi8-XFdN*8$Zzi*c8C3CzO!4|7K062ipC@p4-aOBq~%pM#IeP9gtAL z-}qoPKZ>*%A2Rnh0LKi9jzN{FGuSZ-ifYjI`>u)Y__z1PbK*d3LS~EA@d2!LdA`I8 zEFS<S)qyQQ#qXtfQ8B$}B=V$Rz@ICwMpKu&@1)pc2L__?7UaHnviUE3%Ogz2J1#9- zUA_wB)vF}QP6UY$aq^9&YU+-p^;W`q*$*jeNqEI0hFWA1sEJLvCA6!F?Yn$PJoxX_ zo;%W@Bva2Xo|!vv2%?yx$pg33^!=YR`$b?`HS^$Rt%)D^Y8g}nu8PBupgfgGLT<M^ z_DYvK)}q@zhV?X(Cbs0q1Q$WyC|T*Y%fS#W=#O#1=A;J0851Pl3$E%^PrPQjWYBnP zqzjahiSM<^8A8`HVw<ru`#_U%8M{soAKq%-d)N4I9{H<t^-Uk-i!&|j;OsBOn6qZ4 zw7ddie`>50LffK@`@3CC=*N-~WeOv()mv!BKUKgWx1DQ}aXxrNxg{A8n)}C}Pqr5Y z+(hq?h>9BT$r0fm``CDHR1q2#q=-9u=~f@(6yMF*nz!<mo4eq!CAaZKs#7YfBd?|u zSXE<vAC|qWy=kGh&)*BA_|cZ63^w7}Q3nK&mN=q}$x5;}fs*HDSc(n}fApzMkH$ZO zu8ja(=cD0m(CS-lW72ijOila9Wv%P2)C+NT^g_$in#Dgj8B+O0`;TOS2o`9?srwBP zOYY=y_4nUke*-77vO0&NH&=rf>(&JEW-Gj-BjWboHGNhYG4Wy$yr*_qI2koysyn$x zWCH(|ZZr0`p+YuBM`y@%m-zNEHajg4ej`+FWMa||ej`rcBS4)c*$(xE7q|6Y)YfBa zi@by3(3RBrfHdetha5Z@7zA$MM`79Yw^v#|dg6Ci0gj|+l4m4L6>;jC%NI{LM&xJ~ zhJ5&>wIuh=N?hk<Xn*8yxhS2FXD3K0!d+&XAJ~zDcAnG^3w3GR|GF>5yHOP;(l5d{ z&O|?MzBx)c!L^zL;9-wj+2^o}&O_yEb~!U<!Z-UQxxYZ7GryOixNB%(t(=s`1#i@1 zbZcL4AMmr}bR=7Ezqwlzp-?u`y6B;T83PAjpVy6iT+<-pT7L3@<?nUG$cE0ALD(pu z=)r&S7j`5EKvJ@5MaOqi1FYJ$SOW*bJY^?X23$EQM|yP}3czVSW5o`h)AewVJ4}Lp zd0so!T$Q*Rj$2GUqs5W(!)UmVM|#J*`a#lJqlHgJL-z*TPtN8U*L%+EfEIKHeaepU zqe{DOz0bT3GL{AIH%@xBMD=`26Kr2HkD^Lf6;{o+Tvo0|0KNlC|1_)5Nu@xKfVcl; zr~hQD?$kaS6x`|2cysnDnDT<NtplLyg>Ik16k7sW$?#Z<P@WOtSnj%nBkjAL6boQz zka&2g{u=>kUOmUXS7MItwQ?R++44uw0)r5XBC0fSBYj0a^#Gs{>ueai2F!$Jx6{m& zM*93NWVf0-DXh8+g=oF4U9}a<X&olrhDONd6&{G)bT4$I2EnL<zjZsj4#2hf=*id0 z;PlqPai{?<7g17DPP?i>(GX{2-lxq&0<bBq$k*QU=W{%z1oRCAbjJ^ZP8oaiW%3SA zU4fu}=-)YUJ&OO`8T%eiMUGxF0ez!wCLT8DZtrN_pY!{H{j%%PbJjJt{uOfvCI~r* zwL8tnijuR$l793y08Cs>3POA+M1_Kt44DNx`umFu=e^xpB24lkIqTq&cAiTkpZltM zmL41RXBwiG0Mh8xB?IvFXX{McS`}vj-Movz3i?ofKEd&i!$Zxl8321|$qkYPJv&|n z$poEpRhZaWd9<*=3p*7t(2`Sy6jMGSoQ!U!2q$<|5^F^$6M#_|Q(4eX&CL$@QF2HQ zzUvSR6%JR$1(Dp+Oh)M$he83lI;OW?2S}7Bs1!A+lJbiW0HKM~A??|brog`5s7!YR zDk(Tx)CGR{Su8<n@k<S)1L2jCF?Gn5$};ne8q$0J<d@+3)6P3MD{&9^Q%mvd^Jear zl0NTPOAG!m@_y~~yHTQKYH+*?K|8B&|1`Atmco6Ib%M4YESAijuCvjM10`0S2sn+v za?0fOo+Yft6kyY|ra@iSG?kF6U8=aUad8$P#Kw`_PsW3}pTu2`Q*r@6rrIlf)BT{` zaOXdNX`-`Lj(!mm<Y*{gN*bZ+Bc9%3C*hDtsI^qq^`_PZ$2$P)9t;4BjCGBr=_dvE zi4eNU#i1wM5V~+O09LX#B$_<D<>lyrnwYZ{{7EjBo|Hl-GWC0^Gb)_qvVbq9{)PNt zTBEpgGZs}rnJy#VQ=?;RUv`vr)6eyIJyiOELp|Dk4cl8(2deq2kZE;!Tw_SC)c)H@ z9*~m~Z9kclVwl@pmdk^1^(@;5T^VX)og>10u>2Bq*Pl#ilmx(Y12wm+QD<xMpd0pS zci9#w<b(+Jf<BcVxA-BS?IS4J7-+9Z8Q^$!Q8D=hjtfO2RnT&|0e+W@+UVcDrRzZw zC3<Z04VQQ1J%SWKY`f58Qfo+^Ae!}S&g({B@8ZWms&z{EUFY0%>?0W{!ExN&QA}?q zTDZ5m`{t5s722tte+bU8mX>uX5Dcs|rP-K1)~yzdZM@g1-a>_md|3DMZHN6gmXNfL zGcJ|l3V;Au+5-+PWwzT9<ZE!8_bD;xljaP&UH$zxj#O|$4Z`k=70~WG3)Ga@b$TW3 zUlm5%#w@3nb-RlUs8{}Rd7oj+r01&R@EKQNoxZ2Q!4(l+-7JQ7N~Zlit3Ed6o2FTB zb@XW=#4+<*l6S5U1^n{C1IDO`BEP5)MeQB!HZMODC;wF%PRQAtpEEr`ubp^q^bk>T z3m&AXV|jUG=%P{S=^?gLr{b0Z*Q_gS`fSk#D2qGeb6w>Bm&fnZ%<ru1Dx+UCQKOdh zj|uHFT3>Z*h0vy;@Kdu9Q45Z_iOcr!61>8J3ZS=M{B3kl``hW(Up23T{-O65Ps|N^ zF3N*b?f(FQt6zA#)orbd#&4yWsW#l)dNc>QWAMb4m}m@1G?})-K0}VtYBK7R$WGVQ z3?N_}&EsOE7(N&fZDmjR;lEI{@gcU3McwnVO`XPd#v-~I&zNmRYGQPEl569&CVfbX z4{NwnL2k}%($znT$!uGf1m58-(vfk7^NJ)%?NqoB?f!%)>j;FMNov%g)2&(J5%kY{ zeggUcmNFVTeMVG3Tkca6=b$Dm3FZ3aH2ekm1<<?eUe0eAhRdDhSH}-zE2leAJ~yom zg{a|tofZtkB^~*Zn)P3Lg&0|=QTSi8RpJ4^d;iK6`5_0{qLp(uuc*(s3U{r4^@H*G z*-ypNsQahGLwit#B69Cqs*0`&af_XHUil^dG5;)lfk1YO|E$IY0wK3pmiF>=XY5hO z8ThFBeXLpEOQ-xOz3Q0z;^SIEN1%fpqIligYkVBmVPy(3<gyHwY<`t=3d<1f_n_7> zm2PXuAE?lYjkZ+*;!eZ$O#>>hq^ewqHF7x?1pOA_nVol_u+}(1ka)duIJ^N8<809b z505d4ZYt3D0oV1vq1Z2=v`Cb~jAykaT%CP!d&EX_4RkQF_qZf#{*LqFVy$(SkbvUV zvZCJMo#@=ch+M_`S?TOs<bG4N|1_be68%rE9`r!3HJ!>|d$04rf^5I}&M!pwZc)BG zN@eW&VrsS|9m$L|<^agrYc5S+dlN<QS-kkO>&X{6D=i0TdKqiV8NiyQ=l!3LV^z8? zYwj7su<O|Qn)sy<6IN~g7sI<US8_-Ouf8`IBJ*=6XhM67-^&oeW{i|HUeLYpv|$0A zEw(!jeriVX<;xr{h1yg5%zw~4fr3s-F%;ir#}-Ez0RB<3SE4-m8+PL6-UbhC2zMh) z0~|7@?+ZkCc75QYP`h4Gnfq@j2Vf3~<eh7i{jM2n1GSCR_|8+Mt@2a*tQGyUrE#;u zAZY50t=A5~ubB}8qM)#GF~P_2UTY5q>o27-L7gFBB;7R$pXA{@>sLq6CCsChaxK$$ zk3`*{oB?*z``Cq!mt~RXHGjz5T6t(T-1ziDGM-2I_`~juadX|*Llz^7TNoP3Tx2n5 zMW3y!#B0DxbyBg^5$*z7@xl?1NJ#%T?xIko{wDF&K*P{k8F+1h9XvUaM3uH^x|ZXa zf417}lkM{E1CIOsg+(wNykp&xLM5h`lFZf92#Th<%S`=K2Un-5Gu!%G;V*sY|J&8K zUdGmr$<XuCn7S?owV#i`kqES_YMm7c-TQ~yPOCdg5O+Me8haFYlmU!G+=)#~?veKx ztQQ~mY7^~ps_!wfr$?k!DC?J^Tj0lwyo-RbJK(bZ6va;p)Mh-YI;!tJ`n^=1Ya+&| zROZ@j{r<StBs;Ee_|T5WC3=qW@wJahqzfYs#2i6~FzEjRbR)-P=j~2yeROXb2?xmn zut#`+hP`3R_hyb2hmX6k+C1P8QzZ*MOT3SiX{@oB0+uK5x6`9lj=K9t&7s?ktM!xI zSJX4~fyXxS<&@|_oAisd2Z9t~uwMd;W*+hsWxjK-&rfg0WFeW0<LQ)0rUP4^KTZ$N zM0o7z_v{Pj02L|RHm`CqbzV&};k~2(0mPeWOR%I)+mSfBd1@IxBUi7VF{X~D9*Bk5 zV}qH2>BMJta48LpMVL$tpcV32+Vz%LAO|8rYTEl=@}R*<O$7}Ul#Ob;0&{3PTRbbB zt^BIuqsOf2x$w$^!|dG$6U&wVya*z&$Io9%H?1D&`bF~`Ou96`g3qc4`8##YK|3OY zD`KO}KhPJ9EEvl^mi6BY<Qtcq0FBDw`RT(!z63*{C420<2P)vbPSIi7&{j9n?)_uY zR7CA)tKPvs&qdMP|0WIWeCgwCinC9shrEwu<ZSB82!wm=L_R(~&(ShCsAVns6g23( zDtl5uRRbaSdQyT9$jYqVkM1p+)XaLYpv%O$i$#<SIDq@9d8mRWSnk5J&A_w;TpbH8 zPy@(R3a4j@bSheujiXx}QO%pMG4qV{E8qA-%Dd&Qdu%1`7#ss=jv;YQwy?Qt6_BEh zPeuLF^@<Tc^wX}j^PkhOwn^H_@)6<?C3ih&8!x{+3z9gUvBi<qGhGS?^IRZL>^#L( zUFI7zxK8@NyoZ1#fIW?K7SA&4@JL5HPV9{@AJXEJy$F~RVbJqCJPZ_Zu%r$x9TM{L zg|z;50jXT;4Ey;5{#5H+XJlTaiA<K;``1?y)S_Rx%11%s32%9ed;9}&@sCPAU_9EM zef-pU7`O^b%AWiqnffBW->t%gy1rP6lgPB{x%1Gb3G(=ks|eyr6Y*6SrPAz^933wd z4vS9=gs164ulBoq_3gV89V!v7QF0lap)G-6zU<lO5_)+=b(|ft`lm;34cQkf2lp#- zq*2Q(^5CeqmkW>n%Q?jgt=v)=X@2419h^Bc&?^F*4wl1JPB6uHS0r&keqUc?HD~eL zC$tGP-+0w9nr+8Se&S%AX#ws`AoBJ}W$w5mj3bRhw-yJ~>m=P3#R7B$>C^;u3+Bb< zY6scl6o=4_vaSEl%%Vdxz7a?AKhQJ@KoG}9c$!EN*mv}(HN|s7_P$0wlzE2|VhFH& zTJvqYqS^`5lYdQI2reRep9jjlTDl8c-IZ8;{@hTnz{fhmMrhIgElVA)Pu2>&z5G2& zId_K}S|z5dygZ^F$foKk0b84$lvidTJab;&dE%^<VXts<%t~s?H)(hKk{kd=w=kLG zJ^#t$;NdgvB983VjmeA`sQ2p3I{nxvz8xmPhwCLeDR|Savd3lMt}>jnaFuLn;HDOH z1F+r0|3Od<=yjH+9auDm)P0e0Qwm2M(SqCSI-d*w%Liwe#Dj`qjYl!VOmn0kD@3&D zk{cqp-fAh3VGhy-ire88$*ERK{Rrr0!Xb{5%-<hYb>}8bL~JFDkz{<t0!#z8?&cCw zNR1>3*hm#f-A;=ONKL)2dt-wc6MxpdD}TX$w5E6mxHEtfUg6BMd^1=9Oa%C?R;l57 z2HW$w^+p{R7nl#ycin?0^ZDg#jeG@*w(I61{?5YyVbz85AlQqA55DnuFA0%4qUEwY z+^p=yrcX*Uy(4TFQ<)*0bFtgR9N3)Kw(nYR(T@z~4h8JPv%kyYjWp`<V{98x&J#(` z!8J{+913vXs}GZKW+&$EINZ3x-we9iUsoy=lKd4KI9ALnpiw^VkRo{GR(aUHrZ`aa z6`050o^=Ivfld=@i;?)(;Rz+fs&xDn{YGExCMD+AoX=nbU_Q9v|M#M&A;Fiqp?%MV zQf@4}uDwmNT1p6*Huk+9cy!Qa8D0S#>ZJaVW6|leOQ4P0H1d&1;f1Iwv=)xMD-B&n z5Nl;P`HFYzIUmuj{~Bu??>=nkXXxagRJe-<O5G~}=t1@}emsWSxpFS{+i9FT8Hn{x zE}&61Z@p&@g6ri5y*KhG{H}iHf+YP=LIc6>hM5j4z>O=z8x^Z-hz6#p%hff!&I)vT z<g69e4**dwXIJ2#bOrv&hS^9Xoh>VPgE1uC5M31qWb)y$2-_!>PL^=s03y!|H|hJo zgu-%aRz!OpptoT;F)KGnwn3@PyN%z>g!<pb=YtRN3(R&4Q_Y6bg`+~IeEi&d-wo)w zoC=p*|AfFkV-A2#Lb$gO<dMj(+nELsRKK{D(%x@OUC+JztSYmGB<>2bD}C{|*}!9v z#RT(vHdsGd$>m8Oi060G6o*@yS6(HGM6Z#~z>Q9zKck?Q;tXvYxhk^L&sqQAuQgbU z9sYiRbTL}!YGkLtastH;#65Tf`d^x?B2l!d|H1il5;bo%TA54nPV1Ai?7mnr4&q3c zZT5rbj~~a&iq(nnGUXvH7{ukiZCP#tHW~$JOW?jVgg*POfg3=1ha_;?1@`wAe%J3p z+<2BDNs`Rm1Ie@(-Vr(NQI#8NX--Gto<Ap79f-hpxLdrzIpHq~EE_b`jf1ZhPLS3S z25sf)xU~Mn<#5{RNr}1Yc&2O)me<}NMnOE$VhG)?kiyPTaR)Quwrz}*ZTtOhAWRp< z3SI6+E!8w*k!hHgR9CAl=dPGug#MNE-AI}{@_y$wq7iv?h2?c*Iw&K(oMBi^R???h zb?(vSXKx!9=3u<eX@|eOVL!Zm8$sowFCHf32g;JvTiyPFM+hDM?;u}dIxJs81C=ik z9tNUCt-zpo2sDtB$|)VeVh{D8$)6`T|8r?30A_OHz!0@&Atzn^&sj}BG-{!;&5oN) zs+}Hv5ksE_4){~Ei>HYyPy7(*&cYryN?b3Vavm;O$wQL0&=I^yQZ{k4o^RSbprqoZ z5;YmXDw5qV=CMcAzzhgdRfX|PNh**N(Y9!l!8dMe$paKnD`f?m%!+I-8HhiO1B$n* zogNi;QlusP7-ZpqeKA__hsqQs(2TmqvAEVcO#bNt&O5>eqFLIdnND2J))~4;OU4~- zogtioU2<8Tq1t+qIbLX1phOY)1jpgnj+J?xQ;H|TByy03OP3Yxnua8#my4LDz@=o4 zw3}Fq*QzAu(fcGQ;`Vx;{AywXH`P@OHBAeXKgoogPw%Mp%O>vXgYg%34{p!w=AdHM zzX&B<fw}1b<|0*VS~l2RG!T$oz%a<C0SB;EUAd|7RdOjSK1T$3D){n^#-Ug2e9m{Z zBB7TxsQ1P1+)1j%;DGcE%2&5QC$T-OXzA>jA*kiq0{v!ydACz|8~WeKLCy?|I2Ady zL-yMH2nv;au461|gv^(tTU!pNIe;M37z!^s#2Gcnhzxyoy|p-h{E!o*ap%tmhRj<< z-LAcdMeP~VicKkqgNFlp%&P>O^R;di0!YHvbGc$|oO<=X@skn;K-&?7lwd3%`Dtw3 z4_SJa`dG7G*L-F+A4uEimthhy>+5##kYfqDr_+I0Oi<-n>`qREtu(kFyLErbb2P2# zqIeh+-9?BtEff*Bf5Q3IAQ2}XV7&*Fiq&n{9=Q9GKYh1Tss;*Ab4%)ii-%w~gyfSF z7F`+?`VT<ZdC)WT?_dpZeJ6+LUwEAN2Ki3ryt@KBUVJzHDDg_m{66$pPI^JevRp~2 zfz_oNy6qGmCcSR2@OD3GY~bo!&AyzYE>BnBtcyNsSEfu(b-zE%q=Vv)7Vw6d%zh1; z+`y&IToH@vFNvM{3Q6SSj;Mehqmi48h4&E{((MV3vA*DYN!iD@BdwQQ4tTw{C2v4^ z^YVB~fDzxvOzAg`=-fTPa>|u|n)xJoBXE*4@T+*#`+oBC3Ap6<08yrg<XlF^VL<^f z3Nr-swSS?UUUjc9DHk?s)TCky)ue@;MYol5+K{x20Y-XIoeZw~=Xw4nJ)rU4G00m8 z!0kXV6>cqxRIE$bWj3bO+!LlMz4jOL_a<zrx$C*@fR}xnpg+q-C)fpWPf{9;^v@_e z2c_{Z%1Pc^C}I|WJeW|3@c-X`uu&IsGG-WYH8mO-LSHKvDrDVLsfzJzJZV%8;s$qh zcTpvH1T(J%WyC3v_Uo8hlKJmV(^iok+b{x(W*QSE;a$Bn^UZz#p1f`6fKqw9Ss?h} zlK@dxcW*vP4~vcWk&t;FVbI;Oo*nU+%j^0>PqAmk`2ZEP1eoOUS?O@zB0-Iya&^p; zK+p>VSa<zWc`(C;pbQC+zU3^8i(%$0uBA4#l0@QAc};*D1@PcLZpS5zwep9_WJU!( zB<i!_svUe50k0$yMJNSu5&LrG!eUG8+6(5K(}3ADeKDT|goGGy&7hIx3ID+K8k<Z? zybY5E#-rXosuWKZUJ+eIGATeRqOWy&fojczp{HeFGM0Co6mZDNFU<?hIRU^~AOxQP zR?Os{)hCH-kJ3_svg@fAyS~A*eT5W?y`{jTO0T?M_Z^#(eN`AGi^Pw^xt4ti1`?-e zd>6u5*&gjxMYxcL9i?h4<)hOG7#w=vRk!dBpJ{6)WwAcx{|)#GBe30Tr6w}k#PmWh z2D)VU{;z{eRdWiOhG4soKE$s5Znz9QnIMUAKY8MXBk5jP<71K&txExdDQtj`f%`@e zNF>f(=V58?5yTNYxYY~=?qizw7&t3y$E^B(o|k7&$q0}fCRSe{CuFRk5~EzwL;KUo zF-xhnn1*2rqQTNM=yE%Mkj|1DFaTQZP*T+k#+tE(<2^u6;ZHLJ$Ky**E2x=vUD}r) za~O;OK%DMRT@GkPY<>iOsKe2`48hF#zTuYO%z;DFA@5+zs@n53`XZm?L(Y$GkWetO zOSkd#*yO<O6BOfuEBePwGwL06HoE6YzzuM=at_flLj*%1nIy>4qMnF&YIwXI=3#*t zOHco7&f}0fIT`VfxnNsi_Mc8lAE*o6`M;*k1y1dXsCAlE3b6TD?8r8bw?@a{QpQ2a z6G&BJl(pVEn9XwrW!_H)Jz!JyPpk7t{dvAjWgV5syo`nLC#{bD?0>iQAv8zkRh_pl z6jrsrOXAe7g4>D4`(g-i%5BhL>if40Y?dEX*>!dozFbZvvfYfG2w@6l6_yaJ^O<|; z;zKf^)uCDgcqpfHyWjcr7R#%-j<X}Xc8jH|!Q=+e=h=UHkbm*XEQd~xZ_%*iOf;JC zwYuG+>zoUy$-SBF2m3{M>{_ll(~O{c9{Phu$`QSYSVX{I(7<eHY=KC7Qs@r|c3zE4 z0!+Ia5%0oN>fA!9(PQ%29uxYcY;?XRgZd+(>9OKDFxKdyS8Kku@U*N27Z`km4EhGN zT#OK90$pYac^zWEbC7<-a(v%*b(DTPZpkfv=k_Tzew>^RfbMiIAEx|hx~ZBrD03Vf zv|9%0L^MwA6g%1oWEp-+w}|)tIlrO(bOSxjn8rJ)zr_j1D|^Y1uHIN9)5KVFr^!)k z@x-DM@~)YntG4kvs@kj;d0CQ&wAWTz)40q~>osb-S@_X4R6<S9KWc{6re4rT3&6?k zXhG?z#3Bj&@?T2pFPNfn(h;_bnk_(~x7*8+;3UyW@<C}%0%`_Z9Fe?>ALhgV`X-hh zKfH;1@5m4525Ehnk&7iEm#dF?TqK(Gs#ASfk0k_j!C&NnSN$NqZ~VYd;?0xE1mZYK zGAWlk9O^5@NI+!)Jp1LJWiz#FcNfl}+W@)d>Xt_~oZatdblRHZa_mH0?5yxpa2m@A zHj5KyWbO4ulXY%!AO4SptT0-LtG9Ik?i1yk5z*rJf6@H2<rYI#3ri9b{T|MT$=8MF z)5wEN^SyRKnWNt&cv*d-n({Qsxzmbq>0P_Bf|<GT@_mw~lc3S?>n*sE-y@U?WiSmT zM$udNW-BxQ0CRu8$Q^$h48ZIPgzM}k9&Z1(Sh9HY;!(Czi_!DrHJus1m&IKQLH(u` z0USqsMkkFI^Su4c1n?@Oo{*fx{_b+!`kb{7Hmh6ZkNTXs==A1UmF)5Qrw}!|te6Jf zFz;l`ir*Y0ox+IsK6M|rns21$@sre|U;O@WM?f%p3M=^}Lszq>j%7##wr3XvIm5^2 zAT2A0kzJN}S6fL44vqBfa+d3dN+z!aG-J&=yrZ2-n{zd(KXT@l7=3x9=IHdSJ6JUh z&elTPem!(95!cn5#jYwQ0HmvcHVRk+b*iH(N+sGKZkuq;xWP4Y-vY$x8!wJmwZ@Vi z!%cQ)u7gDVb-0=^YOhLQ`gS5r)tA{YK5V}4mxzlnT3ZaL(XAQk^UYN)^t1}H4wue} z;;9=wF_}a@jA8GsHT%QQ;(Pe()=~{Z_j)Aw+<=Nc0RHUZ(^N8Wu(-S`yvitA6?z<6 zh<@+*)xdfeyCO3X@yM}&V1pSD*4bwEmhXYam4}AFl4%^tjXOhV5NZDLwHjKf=26E2 ze;xZ#8fAP|o05<}G<!PJ{y4Vs?OiVCXO5FSramtc>bv(^I^PgKRA~+N{;H{mE?H-r z;%4)2tgEsdf$QK;N&HEBj?-Dzn%@{0XZ^Fj#(+|H9z^vE$h1xg$?x(K7<;DD!2>q? zZRPP*x|_DDIKHO#HCW&c|Lh_z1AToo_NY5ZB017}T7&MMP6R2?jU&S&(>xG($*A(t zE1dwlWiqU{*vO)ic-5u^{M^07fa)PtaBp%EYwig>Io{y)n$i$`rDb^Si@|#rNYDqW zlkb@9*m@%<r?GwvHydDaB|EjfY91{-h9cAMElAlFeYz}3+PHhtXed1Phytor{wYO- z{hT)f&9BO)n~4j2Tue21n2D62X3`%FuOKc%)zT110!S~|s=N(d^!nRnpEpn`8S&m0 zi*QoPF;m)#HdLW3ty>th@*6g3u7>A;EVMHdXa<dz{@t?VK!9>bGpCbB)g%p^G%$mS zfuBycG_3LF?$>}0Et&Jvu_bs5ahv=8abBn594Ah<A}GWRZUli1R$uQ}sd`{yn3BEn zACUbM09hRH9dKm!Lg31*T#GS$WMB9_R{z=(+v^YuTvM9Yo3RuwLT~uXi6iqKykL`y zS9Ybk(bm40S*4{ZMFIz`oH>jbuagaSr0AeQ9`Ho@_qJ^=mOc|nZ|;TH8q-(<q;C+^ zo%{ikFv16%8lAT*xiGHz-OE#Aq1**G_p4g)i=}j{S&`<yHohd=Fqi&R$kEe$)_5aF zB=iS%N%@YnB-OY8t$*xR7-gF6q>Xp@6E)c!vpN3ph83RhMOPK0aFaoYb-1}yVd+-$ z;nmLKupG78*ZDS`ub*tqe2msqd#${mDtvVL9D3Gj3wK2~N+ZXQ)nNq+G2B^5asiKb z9lseR-MxyR2W<#?Sv-L1*&H*9`o7eIUr0QMplp2VkTocd^D$GeDz7?Wm=cr`1FRVp z^Ss-239@224dyh#oXfN3Lu^caU9urDqB`UMO7+1t@tF;9t5aqHk_9FZbaf6!)EnDj z_z5Y+L!!y9E`0wN@|$h*-$+p#7SzNL$|U7e;CSYlw3Uv!IMi)bFN2$cM96+8PX8XD z6_~z|m)NfK*SRna^0lA~cTv#mYYl0EflB@2xX&H_O%;L26)391*Zk#ivljwovX0u$ zz$^3GqIQZd?mU2!3ozneMM_+>BCmjP7sLzhpprs(Nd`zvmLG#<fD@Kg@iEWEI`wYt zjAFSPV)VVyU%}&U`?HUC0tu{bMJ?(qP7C3mV1#slq_>Pb%b!HhtT7T2P2|6;xQZ<& zy7LMR8t(-n!5rp*0G(?|#U-3^zvcIm!E@~)mWf&U<D84^4{*fYr2ON;cb3(Us7Y>q z)Giaxw~`Sk5u?J#)jt(I8<7LSO6{CP627y+#HKytBH+7nXL4FM&Y#FhL}y!V{y&6! za9+4?52j}^nQNX-JfN-Y^VVBWG}YbAodTZM;s9>5VC-;CV!cL3cvyzC#$+S}99=GM zul?bWN#0w7r~Y5)8t~M|ka^W%{~aD;WN%b=!=Ec|<vq$sc`Vn>l^c-Fby5=z7^l4A zxxop;!*z$DSqgW=TEljr=+e5Eb-=k)gt;fbln<#Hm_&nQaa+k{=a1E#wRrHFxjh~( zplSYnt%J;s7(GvIBNNSDH|4QU6I|X-a?>N;7YaB%9zk}JSL5g=l}>F?NgPMFhaYGq zqpp?b1ncxvV*x%OXqvVfP&>fGCR-?j>n)s;ao^5RY2xViKHtQ6Mr3e%vW2=V1LG#~ znEDiZCrCQ5x`Iraf&N+h&s!1Q)DR5GY;T5c|1Dl=JDI?l5fB#ocY$TsK>$_wB}8*G zGgo@bI0mLS>%jp8Je7f480maWAR}aF;PrY=kir<BtcI6SYMC)bPlh_NsGH*6VvHeO zwSyJK4qWX)GEWt(Iq~!d#D;<~yS@&6V+Uc5kEZzQ$KkHk^jZE|vg^A@fLQI1QBj1E zZ2MERW7|H)-7rj&`GFBrVuVHGN9@g(v`1tre~l>OK8BA*|3Me=+#66HjlF9qgZ2I@ zem_}g?z_2D%YDFg|GdU_;6T(`k{4ndoYn(Hhy*EWT+)~h-kA!VQc4wj*6LOi8Ti4` zN~%}UH0S`BTm-}~jv=nr0W6%M(=r11-ZLO7DtaL1oFqeUh+j^MxBWI^QaNv~I7{lv z;u{2!_6YG+sb)>=?#=DnSebl45eVkQfo?@mshAga7S^Ese_}=8nqpb4eZt$N*%<Jq z?W1M04SX$28u>5R<}lk#C1w1Ygej9x;uHB*u0#r}WNh;n;j-`l4rORqw^bOp7Ll6S zeZez|uKDRkt5T(^K96conNYIyB)CiC?d}WX>AJ+PFGg#VXSD2eU-O7f>gvm|7hhE0 zsBi^a?j5<EHxoxKS0}Z;YN<rlh)(~FOnRjeq32}-ckdAye$aWK6KY&e?}`+Wo&7SF z8prX$f$$LdNPDLnucaC=e{r0O5WqMbB`F_@ba8A;@v|3=-1st``czUzHz!Sf3jii1 zsewDuf^A`YgblV0v6T!M*THrmds`o1{c7iv+4x(%PxHi++}ioCwBAguAu`f4TQI=@ z6yF8%eDWIjJ)>aN<>IRJ3i;)t+AoR?_d`R!1izf;zsbU|@z;Al-AxIOZ*45=@8Z(0 zbULYOngL%=jrYDdr<e$6Ff?ZSge4|$Ts0`RExX`Tkt=GZsz&@IJ<>Q>CkTUtbLg7^ zZOPK$3i0;uFC)3bpIL2vvv;tUa{;ua{j-SYnVjiBXo7BdDLdO#+AYSImj6>DmlyvR zucluk%>$1pCx#Sg;Eg9g=fXJkV!wg$DEyXSKDWb*+Ti|=AaFFwdw8uH)*v|triM5J z+o#u8XE4jrnUF22=)DIhD!Wd^*R%QlQEi8!t3omDPbewZlC3Ta_6zr*B#SPomNO+h zgMP_E+n;XDy~%D$UY-8;1@(-6Y53h2z84R9H%U5(RUzv|5br7)i+Z*UY7#+!T+ekI zE!wlHpqP3nVv_9l#^Q|ATSAp|{8G%YIcsx3%ftRQCF5{&j;5u#XAWY(e%T)vuCiQo zBlZk^Ob6#KWzHMp-Cf0nwC<h+e@L8-8_-%}4S<3)6d2{}LUIDie1(ECu#Fa}fhhYw zX9|ckEDkiTnWz%qili5k=jDOe0M)&|h%{^wX>HH1iT4Y5J&S_d&zZwj=gr|F#GZ6v z`^8eSJwtsm)zHW4w%y>qj%)YllcPz!AVcH^@l7caS&#n;LFH$luAnAbU;S|p)JB0( zwD%p!b`SlBgf;i$GkVCcX3}>Rzvf!;9Bdk$NdHp$nSt8iYbkd84K0e=I#W48!=E3B zZX)EQ8U3F4U{wBB&39;&1u5K~hVq&>qZkU5-9Z|qV$4#M#H<<lmiOz{b!{%mNNmS~ zTj<!KfcT`!l-ls<Jn+4EKS6GVb?tF|-B4>=gv~>$)52BAH{1lCpPij5s`(3o_rZWW zc9~e{JJp?P!phQUwbAyeIjq`je%3A#{+#my9JB59jS{ZeUwtG$bXhArb?*S}gc>=h z8H#zbaBiXn@;-D-B~*f>OVKH@X_}CbRu}O{Smq0v>Pi(@Vh0>1!0|d%Vp6~owe4I< zq;E#%fRuX?@Nu1_r|l3dO^bx6F+SDJSf}KrS3*><IRNzo{O!W+14*7y8G+>&!ws6V zBDi9ZLX98=>tF{u{s$VM?4+8bjP3DaB+}g`LIftf?%{OxpD56-(p_V)Ijw#L%n>nj zp=uZ&QKWA@UT4%y*k|ZzZYxczrais6qG+Iz^TzJJ+uK?{WrMIxr;Epb_A>!JA>Zn< z|K?8WDGg-3Ie2u1fyI#JMJThuP;`LjGqX9Snp>L<b9@W+j1>5~mrbw;E(Bind<s#O zlAGw0b+~q*TlDCxM5S5T5SSK7G^6uMj_l?amUFN{=TXuWq3Pe48J6J;X6maVhR2DW zh~5Ycy*#}HTt%w;V(^Npz}mCe#qZ{OD!v)pSvWYjdPnmI4a`2xch2wGCmD_(6x=(? zjia0}ybU_7(b9By?h?plJq3^!Um(9P7Sb9J0;(IL9xSl5c}(l@<fbdIiDT!r>tkVn zh#2#=yH#(aJpf#fOvyH5eNE@DVb=rqr77^=R>=T;F20Ka6h+KdlwfKs7$~g~cMtD% zIr6&;Uo7d;G(<-!6{57RMr7-?3@+ZSJvbP)Ypq_{ebso<^4K+nkxS|BR1je2NUtB1 z%fF;6^SW%k@?HcZ&j(~K?dF%ApTCIzA~Z7$Kqn^wb7>YR<v0vmq<}|d@;Mk^amm-| z;z(oQho>FkE8oPtJvoHvMHjB-0f+jktd4o*p@WP|tG8s_<$H_qN#@x<O$)fgZTj!- zBh<*Y6NB7}7}OEu2P+){kof!ioU3bB<={fiSa_fPmQ^27Nq>TT7fOaK&5K1&r%7;N z!)XiHS%DVbfkWUdTDrOfnx^G$;8j4K{JQ=}rq5P*GL)T?0ljl(@v{d_;I8~u&JQC3 zRG8i(FJ)igE_>?HU$q!3(0qV1(z3R{(zIW!FXJC|U%JbD*$Gg#v0ptk-yt6Z@!9ug zIG4;(IPMJoVFC&mR0p+!rOEpt19}k)zeXs1(?_uLr7fYuU`J9YzfJK?_Vwo75u>(P zPv&xyvo%F#2UG~si%8~d{I>qZj_PN%JE1*S(#QI|ga+n|UY&)YC0FJy7=5wYe4GKx zUY&FOD^!9{BN3WRhAjc-M`od`=XQ27gkEn@XaK3Oq$VjEz-my6j<g}Uln^xKxl2P; zqK3(AZojm9Ui(M$etV~+;bD~pa)3^wGP(cCG>CXvKbGE(ecJcAKmOgyKf<ejetlu{ zmyb%o(*eo-ja%U`cvcRNH%Q1*Y8L?eMBvtL*?!aW<z~yl;F0)r)PBoKt`Ga$=R?;L z8~ZTs)(aQZPnuZ$UKiy2b#&NA4$Wqk{swI47Xr`y;(O%Q^CzMo<b!_d1f(877sEL5 z4n5BZBUk|Lqimrshx-JCj&VsPDDbhdp#uXs&k%Sj4xNWqQfv2HcECdOLUMdD%kcN_ zCu8>oh_sdA<ehHNK-U9F0X<5UK#AYN=^4QFhvY~<Gxc99rmwc+_<0khaGFjlmtD3l z?=X~evS-1`;|Saocv}3K>?7y3Vxuo5?txF_tAlqSA$D$|DwsnNf8W1*=Nqy{0%U0E zZ7fZv=^ru8HR&YAy`eid@U&wmc94fKv+pY)gT;#$L9{8;3>=Nk-2hEqN#e72WNFJp zoW`h&mT%X@ELB+SgW0;_A9f{ykk3WXK`Wetg1IY8;OIRTg$Oqe1k*lT8uD%XjwK9_ zpDt~PAR4wJ3b}&`U}>?l#(15A&&YvfP$BZJmk@sgU%c-_rM$oo&n>ihq9xxxXC1OG z(c~FCpigh-dr0Uk=eR36Id^GXFm#HCq$xMoJ1|R~1DT(9%~<B9a|@kyiH%v6-O;DA z6TRE3e7b*TIu!m{=>!Zyku8l~3e|TFZH=9>Mf$Cl_J3QC;oVzp#|&sQX%hb?`J8lw zV$e#>!Q1iyx@`3*@r{Z?>QhS|9@u)YY}Q1pB<~^+c$f_7(D;8wW((JNk=knXh=1f6 z`DETw6vqd;JUioeW|fin`(oj%{HzP9>p7B1#T$GY0ULa<81c*<u?aB7{o*8Sf}(T$ z^}#Yom5VeBzCO*4D{L-@%yy2|lo+c79k%)+d8D`b!vD70TXfbsTM)4?op41zQhvqO zuv8xSqEj1tu9J2iyED)0sD`vVA01z^X)I9?KJ#C`5%kmi(FgG1yH|grN=1XLw`}<1 zkG=D%PQ+);uqtT6frTp|J!G0zq%<Ll8_)yTHPuT3pukmza5BgaRb$J=$Mu85VPl^< zE6DTQlOS6S`jF6@_uv)ab+iShauC1XuGsVD^vi*IQ4WNB9S(C1$rF#@yxiCQSbfem z;8Qj&WtLQ|v9APf>Y9df__$xjl+(!@Ata;@#B5P9q>CGSnaJNVq63Gzj^D*LtXw5M zfbKq~V?mK3R-B*Q?-+I}LYlNRz7aXzVz2)l`Tc#m@i+i(#Eot{#3OhPz*LuT&-;d| z<Ogt9<G;dd&#ENAUFC<TO+Y;u!Xp-f;@dC-!4+)?J|YcIx(0ek*KTfuxcQLKEc+Kt zG$f?%;{m4Zi}Fy^z(vqmlx2fB(9+HBJT)WYLi}lt5!e1zG1_l8exSF(<zwE3sLh8F zv`5GN#d{>*eTLRvxB@b$U}T+NtmyXhURl8~!6#kU=7c~~7SBR*S=NMV^<Ss#Go-yd zj;_LYpO_xnjj(Q>?mAr)4$|g_1%Ck_=)b_S+jimvk3*I=Az!gx9>j$rk%fQ$m@LnX zAv+65-D=P=(fs<eF^9>djo(m`hISc*ic0D2UzO5pye9ROy?J9mcX;78MH7}D4j`o< z%LqWqszM!T@1u_kzn%zxiR?7_TAE~h@XvytP0Oo(6MryQb39&b8hCUh=vI*Nv#{i% zmCpw{@Husy@RjkaJ^NR^nOdO}|B!+ob-Ica?R5dkU$H|YvA|4y8#oH;LEoaf@0l^Q zswp*=R&MON4u)07<#Jfd$2aL;nyjf6CtH7G0XYT~x<7SW>9OAA(r`h)&!^QqhVfw& zML6!yE?2t_^e^d*bK4I<{{5$d;q+mP4^eoOCam2&Z~Q(zR8ykytU}<zn@41aRHAp4 zJ}@FmyFV#QVamp`LE3I&*7Ci`v?P?RL13^;=}p7Ak0jk?p5uD}9c#QYl#}vaB%PeR zhbnqC=n6qG%i%2GsEklq^|&#qnoVLAWP(fo`%r9oaUa22=uQWS;JSNY<x||DbH$Z7 z5Dyyl!VJ?>YbgqV{|T(s6;1|+)Zz7vlx?lXV&x|Bg!n=_`|)}baz=)PwApG**oA_% zC-X5Dxqx-6R!nve21^aClc~G32$t#kw;8QUBPG)^?)g&G*FgmarlZCsxf}tR@W=nh z-djgSxvp`bc42HcB~oru1VQOWR6tr$=@6t-I)||kX&FjdNonZ@r9nbkawMc-h@plV z=02n6>~oIi-aqcTcdfhbT8F*ddppece&6@T^ZcIQQ(PW9F~Mnt9^><g%4DxdG?tm^ zJqNL~@8ivDXj{u8=?&1OQS^OlVZz;e7rv4}4#nd8X#vqo_urNFNDT)h$griim@|j8 zSkcn^D;*1+m+YHQa^cM5>9Zx!6%qtY@s+FPLW$;v>b&z6e%MP;7j)?zc`_te4^yZ* zebc%?5%e<{*$3*h$K0^BkCuUkO!h27qF?41Ay~s<J*HV+0jko;<)v&S-05vL@nUYg z0O#{7r~E84scqL<HZ|W5Pu8$+jPn+GDXEfoO1%Kr*&|gwnKlVq>K>%uwC+t>r}B8R zMsHAT$@SDMN`yifrZ*%SNq8xb{*t--U4=$CqDk{Ek;ikoD@~6;ERaLdcAq6ch$Qqz zJJcO}0#Y=?{V?yLn=yq6&%5{4{i4-I``z|5HL~(Ip{N#={o3NX=w9~T1L6D1<(un; zj*IGLGh%y$m4U8Xr8O#FyP`%JB;&m$4bL$;k#|FdxY*gClMt%;v-H5FjL)zM;tlve z%K&gz7TBmUPL#8vbyx5lmOqPXy+7Q^Cfa?LmQ{XVE#BU#v>s&<Wz9T~qOeTU=y73F z`_Rv!q`?r-rOS4s@~t118+z9%mymDXUYO?H-L?tS>~NLU?m5|_yFSd1ggjtdwNPm% zjY?GPFaLNXLlh>Ezu##)B}~bfskpk`1gQ0^r<w>?%vcH#9C2NaACTwA+K)bfAOsSl zNF09CnKcvJ+1GW#h^gMUopIfrl-1FSFHfk46s@;h7twxmcgZ}-d7`jvSNO{-GQJ7z zRr+j4TkOr&R$C|KqdUHPklV~XJCpjg%GPpMW-et8i+j>skRg>ID(=G<0BDXU$4!6V zjaP>%c-y=u#7HTvxjV5i!mDI!o4<l(z7?{QqYECd5BH=%WV1-u5hWn*v(ephg+b=B zjzM7!gy8+RvOJF$C*{FL)fbE7PAFUwM~FS<P_jHFN>30PY3@23w^hZirbAnJYo5Y` zEt|F{0uq4QQ>{oHs-WJ`>~t`dK#yUJDypKl`)qpXr~1BV@N_v{?SdHQh@uX|3cjhz z?FYk~ezdmFDu-GoXa?5`CB~Mw>KmL8XKkNklC<0_)gSmBHgP+IYH``#*Hj(;@;N6_ zqFBQ&`k1Z2+nz)u4_?|{>!Fwd?b-Ac<v+;zWK5yHBQ=H6n<C0%NTYkyT-q}sHd?~_ zP$~y-R{Ey<(W$E562~`Qk=>TL_gs+iQ?$b_c`3uL2@(ALDjuvp5>b!_CaQFcEmfn3 zf3Rhii`nl6>dOPmSwd*RS;cxYQD$eS=a4bSl~&)*>cQ%MRV;XdOpMvNNF^#IEITEG zBp$$xm4zp<WO}UvC@!{m1Bgn&+f2L!wwATbm*?GX?K`s_uUw+t@Iw`+fams5`KVQ~ z#V0R7HL%m1OK9`{4d&VlWf{Ggw{B2nJMj>?mMnS!lEKovCpW=(x-Z4*Oy17ZwjQ6m zBiqF^e>Y_#z>;2`yz{&n74vqWZux`Mhe#eR=mfXVU|56f7jY=9Q708}9gb*EO53tw zXX1DI>I}s?Yg-tipF=)R-%;xvbL+i31s@;jf@fhm@)3H@D$p8p$|weu`HMcRNr=@> zPEw^R^uIZyg*Id~=FB|Tv)k;W-wICcg&p+}OqE7Y<-Q_7T2dM~AiU5sMr+e0O@i0s zEX+%BmrSZ7it^m|1v}Zn*&&Y!p<ur#g9w7qNu-YOd#!y<=W_<6tawP|*-r93S7V1L zkPhF4Wt_VgF`F{zD?XA6z$-tGSO(6`4n%IL>HzZzba{xk0-;OCVUL5dI%4krOIbTs zzHS|8xD2QlI@zjYxfbSHAbN6NMyFP;MG!i+RZi*<YFf;*FZA4T$hAjADwhbIm&EsN zKs7(8oRzBG#YE){T<FD(Lkgwgq~OD^Hw|WYPSrl_ei^y@xN9~II6BD$p4QvL8@pX0 z%Ts*OEgP&uZ5ymwO0$wu^HmVCXbgVOP&@J5kL;*{I(+I^)m5k*sUr^-1N^a&y3WzA z{-7eX%P0n?H1IJ3q9Vx>yTnTJSHR>~hE(p3<{x{^JmHX$eR&>Lb@ykGqnOMH3Di+5 zkbKQH;A>X&HYTz!L;!4K7Tw-$HNI>zq%g^ccmvII=g9bCw!9!b^F@jx=?|)19fATj zn!fH<B`P|2N<m`xej-c2F|>1H=R&Jj(mcloX&XvoK^JUhcFsCJyT$4*-GwMjxGA-_ z-;JwQ@Y_!Ax|8W8Nd{$1O->P(M$EIP_j11<?@V{R$&3C<gVGI!B<Dl{%0x7!$(`JW z6A)`3&lA4;Vk*~-qlGyJ=VaP_hi<*vubze8A5Yh&+@wLQZqVPjv2re&GP?dUeRNxv z#JR_L1v+dSHu%bq^wB|+wqHIMeupOMr@WzD7o3`Vm7>yA*KUwnH7atJv?mKb_u^xU z=jdBCX?{;=VRi`lvS+U{UiK~R8WIo8!)x++t0K3AlN(S73^HuG>ejqB8ml4urs<?o z%~y8G;?l>StgXlH^^uF{_Z-hyml=C=9=)*3$spvdvKq@X9}#!S!ZB`+5eoi5m3{I? z!fWo`90B}J=NDnLd3Yd{tz^3sikaNiS@)T}HOq6<CiuO)_i8kqG0PXtb^vYQRoNP< zk>&nk-gBIzTxxlv*=`nPSB%aFSK$m~5r;~kT7B0fTvlKF=#7?&CL%+}ru)Gq%)E+3 zA)KA`Wh`9rF7H8a2F#7>KhRLKk)TAWGwiH}VVcbZ8oa$+!|4tBRJFJ*Qm;fkQ2m9w zHZ&$!d}obCtqtlMl-g5DQN~hovuA_6Z(FK~G|D<$y}t{P3)6%V>qWmfi%cln+zrG$ z<_yCYK}{#ARc~#*GQG=Ttwg^VvKQYUgWLr5o(8oR3}!>h-#x+SZ8R5g(d8w}*W7)t zLlI~dEwu#_6{_lZr1QL)rdJj~vqpc^ZzcP1JGow8zQC}!`^@}pTErXRIr#c<65%K3 zB8uMca?3+L@wy&L-&N^U2wE1E!{4v&$=XjJDd=Pb#xulHr~^Z~xpyhvO2*6>bf_SX zjr=R?kb0gXs#W(&5fp)2X5CfH(nEpYy0o2f4~lwl4Asxx<%<@9&UayZ$ovl7yPG@( zc`J~53Kb!*U4Jz{fHjNE_iHyqDP1VCE4~&M<rKe8c<q&YLi7*qx2=j5DiaKHs74xv z)IXycZnL?5$WRtbAH(U{?af|`x?i-q$$|G;A7V3~dpF0{ueF#<s^bj;%Zc;(%bu!7 zOE59~JQoygjhT01@%hGs-=G*oxs0HX`_u)gf{8By^DH>)tx#)nvhvd=;L)Y5Mu7pr z{!T+}b|(@#WUwqJGNQ?&zw0ac*k#Q2K>dvKd^=ztD;p}YXS1We+*jyA%MwA)*z75F zs*Q2Z8!@I>*rjH40W{rK;6=PC!szj&B_*Pyx>x|3dG9?j)yb7o8{mZK;B`0&ogK9C zMg*_h>^(y3UQ(?!F+l#guPWmm9poSsB2t}NwwB&w=g;0QUlrlG>8;gWxs7V0xd|(# z8XQ_;zQ#V{%UhRLb|KIG@5er`%`-?&ZCH1OeCg6!V~uVUw#g6*-5O%BszgeaZSD>3 zh~}?tVpca!GfLtqHbCFFaK&C+N|51NIP_LM(3*-8S2ZWt?Wc0XJ9JQVNI`a^T*))~ zj&DUo3NUTzP$aFzNW0BoVV2it49Xe}Li?FQKhfPg6Cx)(nVi|sx1zE7^0Zp*FO@ZT zL%B&l-Bd2-#PaYT7j-=IM&u!gs<@vn<)&v$?E|yxKJ+kzuSiRS8BI_#uR|m+LV98c zD7Hf}{ffJ%4ZdzdsqxEB8&%z)dZBg&N8E1jy!7euY0)sQIkw2V4aT^O{TCtgWWdS6 z|7-oE=Tskbprhf>iM5`2rF$k~UcE|O5`teJYRN7lnMJx5#fXw>ULBVTkDiG)(vDOV z+=SX>kfW-5;~!Xzv^loYLaiYEnLef1jvYOGdF4flSFwvQJpd~_f)|pj?`&N+=$W5O z=dg~lUXFEtrb|m7M14Y=w%C+OifRHfUg!`)tktLjZ#l*e5-F$9_jWBl{L1pcbO@%N zV+F;9auUT^H2oRWM}ZZ_+3_j|fo%=07{M;udhD`aMNs#9%>xIX9+1B+{a~9*RX&Qr zG%NvjBh<I+FwcHnLzUpIC+^e_EE)|9;|+^-b)n+2?G^(`wzQ?i+c|oPWfN3ou^ppV zDy|$B=4;vK8O{;z8=`RL9NyJhPE1VPX=`X`c+dq&@7^eZn|<bU7(W@kPXqq$`PNCd z#*!ZCZd6?daljliP2p~kHosRH0aTxp$~`{EjAZiYMyD)|p2cAKsU0Pi&`$NtVyJiR z>;8|76^}m7=%>N*z7}_!bMG~m=5*{a&j+&gGiG=jgjBHT3@xB2wsdiP$P9?5|EMqD zfj6>J3G*_v+J@rUTJkeqFA1T%@!|UNz4#w?WbANW_aKym+0INXEIqN`QIW`R^)ds) zI9Blp-`Kx9?Y!n?780y#_I+;e$jIOq0k$6BNDCCp{XM@yry13m^uR6m?Z5bQk~L5d zcHyH0`5Cdng40IN5xoqzcQ|?-McO?C@5SABic@wH`m$2>f{OkFG@wc&HJ}3LMR(4L zDrHX8@}<^GJrV&$sznc>-7HG^FZr?a%6kP2a{FGdRi5TS2F@Nh=d2B_X*QZTNcF-& zG&DTGl4?3ZX38nTodmUcJ`yoc=;d^OR-nN<59JAXmO_+_^HP>}(q`+iay`|kE!-s< z^jOFsxEJ$4z#jRi(KBcMU>g$iF6m+X_&0+#jDh-3>JHdfoP{{*AvXRDlkqZxnc$nm zL|1PovJdNiTXjST4y__0dvkH{KSZJBD@m;#GPTO)YM6PS=Lrm2$PiC&tn;>qqzCzg z(6YBeg|Aw-syx33`TMXQ)%nD61&^35^(6H9nso2!2+iSYzaq>GTCWpF9fTIMbsm~r zJOUM!aZsQy&cN7!{w+yhJb$asZ%U@ny8)3)VC7jfDQAJxj8sV{zZ@WwUSbzd$(!km z$_O^sZ#SX6_-JC6+<LQ6Tx1f74QmxE2`AND>`MQc&D=Y6O{*2^*QDy~@1g>eS&4@{ z>MtgWi5sBgoK{NJT$HYOIm{>xycxdhAHuw`$v9YAjcT9$9Dp}bV~e)}VoeON+RDcW zlIJzbgmpLJjz=bfjVAgI@g_tDLXEJ^pln0hE3B=vY-8&@;l_0EShw8YLt`H@QrgMv zOkk4B<LB840T8jbO)h^H!;TWywcIg2w_W%xlH2y!7oz-DKOEJl0SYoP&sPc+Uaz!~ z)#9d4_Bi^hBQl0m=RZ$ZX7IAaKZM#ky;^k9Ji`ut2=3-y3WQ|dwcDu2PtQr+kSu3< z9;$3CN*z>N+)|~xJ{aXw+biB8tc?@N*zs;2JPZwCmv=3kCrTh6PIeW^GW3~+6si|! zN}A!|Ae;TyY3bXf$}t^|%>`j?l09La7um+lcmtgBpaNoOLcxlBl-JPIMQ<<=AZpr5 zsX&?ndmFmn@Szt&6nDy;AX#Ky^I9j+QLYqN1u6vy(p!cUlV70gE*dg;wsxDVZ*-*# z`gl>NiOpgvpfpZ!6joSeHKfbrGCMCYWwBG>U6o~K9=hZ&dWl^Dcj;lxhr_&`rLOyR z%|E*MY}rQ4E<%z^1opJDLIqO#^GnAK+1_%|dpi0Kcqq^L@Kj>wY@-;PWJGnPf9u3& zjXkh%h9HRzsr=d<QSrg=xTM$KPln0tiTjCr#IQE%&1HFnd^Ne(PU|+Lq)_Vr*npbW ze$go++4((lT6BWG0}mgN+?qc54j(9`T$Ybl);5pfs^{-1US><1FT(AeuR(ehuRt?J z+i~-I$rBN%w0h$mu&A!)2v_{9K9GzIlM>8qzPx!MPaxtxT~0<aAy`zqln>RauwbsJ zhg#5=hcdudS)vuAOUC5=^yRafQ#@HWD_Q!7p%qOY<mJUjm54Dza>)F>DB~sVJSz5~ z6ciy*sj`QLqp!(Wj9I`*t%7A2pUN8Fpx;_Dj#a1t(dfn{W0v9_Wo)&aa7VGid94BJ zAb3ac@%j<Gyadk<I}>W}`-%-hLKwJ%6znd`uyrNUKT{Tms>?by$+tKU#s@1Kw~4kw zrS8M&%qQza@}V=0mQy+sigtEmF@KEIGOya5Idf+D_80GjKah`ZSwIczIrSsCX_Om~ zsKTgd8+wK*f+rC77_~UE;;NLQnrK$&H8#bPDy6oZtkLtH$5R&yPs#ncoI=X&O+l1O z>UV6&8zEURh0!f+qu^qs^Y!LxY=Ju5?s9{BJT`lg9^8n2&Y>oVU7$sRfuzYB4cuH> zL12!=;tT#|KT=2|w4;yonL<YJ^(-<-?i^fC9%;zh2m6LZJY==dK#{q^!LNG>jeQ%; zdJ2Uc%ZC&3d$O1?e9euW)z%>E?$@eCj9#e0>rOp;hwkg>EL&mgd|z#8%eg#z0MW9L zaW}S1>5_Wx0&xXI`uIF_ii6c1NS6qJ73a<&Y55KZIcP3F!sQyys$6Raj%r6`6RP5( zY2lM?2J6+RlHwq!-(|xiWWhW&xAOQpr0?>#LR>W4SWf|j9W@Vj=~g7^wccjCRQpY# zhm+%r)+qsq`i=4{%CQkrxKhD_h^WN^S5xnmQq7gD!lt%XW?WL76>rQ$zu=;41|2-p zbfUjN-QvVpAsjJH&nGT1NE}U6p-=E2ZGwQTb>loU*AL0DSN39x&PXS}_{gC&y%FQ^ zN|jKt*Ffr8QsDKL(aRjsF-_sC-NhlgyLa^<()T<1;>C-ihR`A70i!7u_<csT?N2*e zkt%Gg%xPL)b1f=kyk2p&P_(+tk1+sak3~~#E6fB_Zi(S6FY2MN6i%$7Z?V_=hkJ~N zS;r*I2Gc)IpjPTAuwuB!O%7oXqKtL(Qi!IUyA)XIE5*z6tJXT4T|?|)R^frl_iB@Q z*m_x^{~?=IldH}tCn!q?&Jk<oo*2GR#`7C<UU|lcOcy8pKrHQT#DylgNGPr0(HzYD z#he@LTFm0{5HZxxAzo}}bEmI?JVn08S#-FA!<M100lOE7$$Ve|VP$0#uV`&?r4aY- z+sSrPhB~djHg6PH{Q{{z`lSA<Rw;A=0)q9DrG(OWLlXBRYUvJoXWMZ|B}$H&4Wc4> zZ)1K0TP6rKW!fePY2Swg*<~M>I6o)~AfjC_)D28W2mboFMX3iXdGr@23A1^kzC5aS zx)@I9d#WuhlvTyWu{XTSU_8-AE7C7J@Au^B%kvZj)=lxbD-=T+0w7j)=~9+iQd7C* zoq?#eZF%{FXOk~n8ltak2FTr|m)bt$Zf=|`w0{OJWfrRjSo8hf?DHA#p?3OUHLvTV zTN#T(4JmVM;|FQNy%n;&9XvVjmv#M_r{nwT)vK-AVBNs*MRjBT-GDnEpn4$GqpHs) zM);t`V5isg15Sp(u|s42pU%!U3BFD~qilPs)_wdfOh7Bcbt;+^C#U*Z=Bx7|*jsti z=EdmIZ)d3*oQm@7ivkdDpt#S}%{=4pkO{Llvf@_+z6-TLDCXKd_4XrJK3!P#W2qVi z53d2kT+=j{_O%{r(03(<3=*Q|A|C8O$ngLJRvNNA(Ok$SsQlE5U2gT*dA(H^V!S!M zuUa7cM#or3kTq>0i$IKZc?kJ>nE9iE9tVp(sBAW|pL{XuU16>SRY6>m62fWx#x3~a z#C{!$sGn)5pfnjC+i(1ae%9&DLtBek#hi%$h@qZ9Yv)>JAu*q~L!`3v9d78!!}h9~ z(}JacXCWh*{sBWPCS&Lg%|+G&pibW(KHE|BavNTAoh_!2cup#xA_!HV<9D#LpFi7A z@`iS>47Hh}pvP0K`#~`s3e8oh*y8xJVoT@!i@S|fNzj<29REXj$o}Q-ol<-xbnYV! zQZmi^`sxQPOJaJ_?4o#XS{GKbB%G8Vo5<731E9ov%}f5+y@@Zu^?U6po=l`dFYCbt z*(sGZ*?emDbZm_Bs-m3pK8&Ci)KU1Px>>#`AdZ%xu=*yW#y3)GCy4`xKM~gTCXB!U z5k!&g;5a?$=t*R6T_xN`1wjWuVskk0aVVO}RcW>$!(ubFrAwfg>rq(Sgh(_EYEYma z_=92u9$Sxft`RSh&W2!Zt~L)U-!{ZrF{5r9n-Toryj=3y2@rI^EZt&uiu^kSp*IvU zB`VV`kEZ__1U(q0F36{St>F>#_DVoWFiyB%3_`8Zhb6O&y-AiJl<^~6?ze0Ux8c~r zW&=D~Gk#_h81^983h%f|G?~z3w4#AJ8=kHFi^gCUPuYCFNTf}aH*BJiMh*(McB=Oj zKGJnSq}@Yx@-}tUt;w$egm9W=9ipI8GJnWF0c7=c<z4&2CspmL?ai#>jQ2v4L%g{6 zgrBuaL**;>ozLkNEbMng&$DZjGG)6I{28ORW#XgA=eXrZW;w9Hu}cY=g_li)bbk80 zU5&1I<ONM%?u{t>q#Qk7Ln$Sh$6;xB`c-1LrtN|mzxv(YU`EVquQjXsiOQ(}0L{lo z(l-iPH>W)Nz8`OG#<<q*<-cS~yq_{c&dGY!Z>A;|sqr061|V5_wRcewqVwnJ-hVjQ zt;iTq@n{VKB4=lUB!$c#fHezPb6ushh2GJ&^8@JnY)g~?g{2m_aVz{b6$<o1n%Md+ zg;L0sH>HCIz5*?iu&prcW>BL@3i!d%hv_@XUu>?uBncr75UHTO{E@=414`)!%Xj3; zN$O-IL!(dZ2gM$sEzq0h#lT?*pUN46+}4O`OxRP4N+}ekQ0c~gk6KiUcODBgUj#qU za+v-nM)rq9;k!7q-rSYDqN!j8y@N=D0GmvFs{E@<5d!*O0{v)SS_nkN-C?|VahMWO z4ow-7oy92P@e;3)JafiCAXmljynU8Xokq?7h2F<j=3N933i~Zr*(0T=366!2adD%< zMCgYC?=Q;k%3ppyXZ5N?ZtA#P9s+7jqg|BPQb>#om6u{QN_PDEv+B1TJ<#SV<TR9- zGPasiW=zRYO;ind{@Qds3fBz2GMm~615Z}vF7^@*EYyK%k*gR-(!AD}9|SIUCWsj- zG3eHQ58)s-pWH@@3#1{#1t#URn7zfFcR~te@ott%l`BF#7e;cJ%%I8$J3%yKA#0C0 z>_;IXyedReW@i=p)}5=(z;!=JDpKu!<+6;qjQ1oFaV_4mk7b$*vRSZP;Jkq3<HFJI z+BO<@l@)XC#8|$}=zj#pvuNGY_KY#<YZrhR5=bN7+gcA5#M-fts)1OX?HS`rYs9CD zMv1UpAC6E;*@#P0kwm%c_MDR6mecN0;SDVjK-08Z^>U?AM=SdL3bZeA^v4a$M&6Se zyu9?vNwHS~h5|x`wPTh?PvlpLWQ8bWaD4#Tj2O!_uPYZx_C_H#Lk`DI>|O5{zA)CF z`g$LtiXnpp*pEJBPDN#&q1}~>dCQH!48V`llCguoN)a^Un8YyQD<2sdrL{wgv=1^+ zQSm3JxB%_E4a~S$<(2QHCx@hcEWU?G#v~7vq%S)Th!9!EKj^n!pNR+0)FjlI%dhip zFjmHSo&L!!jB3g;=h!IaNu6p;Cd1Ja_#bD;{q$7v59zmh$x9_Q(hMHV=o4fcVV&<0 z@#NQOHM6Q!Nt5A?F$s4T#hIVdp@p3GaD!{_p}r$TA@TRPb!R7Z>@q8v6#~S87O4<{ zBkvl#7nU*?XYQI-#&?+f*AHJm2t4iTMkqu~7&%8g1syav#497s0%FcrNB@L{Ez=bJ zyE4%b3*4W!ZJ!J1w7`Abyy6_nd^pMiw_mkYq*35*+$73;)r33jZR2TxLR`1x_e>#~ zX4?FWL1x$pr-eYkyuv=Op&km5M86)YATT-DPF`mLmBJU}6qUj$5z4TsaH^7pM5IU{ zqn~oOZY<AGw?<d?oUynSW>v8c;KCq>Afhu9BEjz3M@&<n>2fATe#PKQHh~j?mOZR_ z1-D<F`{zrQ^<pvHC^0aAbi4T@rBjNprN4zH7Ut&Wb2k<b7QY`jIt5IICgkibXoxT) zfBq-A)6W*ua<!oU3q#JTGmgS!dr+h%%`W8vvuH@q5F11iLcMa_T!hkF^=%T7F}{7< zACbAyvl`8<R5-=*Uh2<kRPOd|sH-8&2wv*$vyh=&9r6l;pXwJ+1bTD5CP@ml_0u1n zQ#BvaClYLvI85OW&NznV2CTsquNf~2LMVi}n@1|<1}+#HJPKP+*145I1Yb0%^-0bd zKWM`fb`UC*W1T%j^{^&{cdH197Brv&;Yx*j%Us%K$kYL?f>%<TX0^sRPfC?Z;$|im zccAkP$%+`?BArSu?@$COyohFlPC+idySAlfxP=+QVZs8F-;>H!B-EQQWzd@$C)A6G z0&5W?*}LZ!{14V5A=a!Him%NotiOi9k`M}<?5VI$qaJ7vjANUZpM^5L^9g_<_V4gg zl3YGeq|J`4RoHUJo`fHQTTM~cN&mnQ=D6ft5{LlNW%tAWXng2Z7CqF}$x4<pV>h9& z(27t9(Ynmpi%n<fW)B3rqSb!Z=fE2&%17p>vc%3cq&xaUONhuANd%qYS)f!ffz~E7 zeD2WA7HE>wsS*Z6du0TvbnyyKbhq)R+X5jF-?|sdQg2pIZMyHx(ze=te}-t@7IAPB zNSg8wykgaobb~g`i&f7^ZJ2*bxkRIVI%$oh>|5P^LJW;>Uv-Idhnc*@+)DIjz3YHr zCL<#yGWL!hArw_Sf$SePs~ssQj(i5<puVS4k{l(&%zsL(&x$Z7Z&)gX7_Shs;_i*o z%?pvFeK!}Igq;5f-Mo@v0YdQ0olS)%Ga5O*-MWUord|FnT1Q)#Y$#T72HZQzEc9>G z(3Kn1lDU_WBC;qyrI;?;Q_wn6tJ!$n%O0||O;Xt71^U)Vl`!s-Dq);yHV=g?uNvB( z1$VYj)Pf34CQS1ji?K@CUDIqw&jcTx!p{Wg&_ZV87`eO|BkT4oVrY#7KLon?xXGif z6FY>}#)8(Ozkti>njfi;*;W8FOps!C#i|zO8m+q|>EEy;?6fC-BX);RkYdbL;<^M_ zbvZ2VKAA2(rM&P^?^AVJfj<Jl`fDa(O7Y=aP)eY}+SVDL9p1;efa|7`^-3V=5~<1U zIQ`XtrO*UCQIg8}v(e^4KO+*qCdY`tPWUqBYUUg5uK!^4TK!yL@+I=B&X#1O=YijT z%x_@cwhYX_I47xD<F)Hg$tj6ntq+mJ%}s?!=~sI|n#jSaS|S0n01Zxav`x6ETfIZG zFPvojZI}b^g7Qt7bl3}?F_ASs%u>(Mug1Y;JaGBrju?SNZyZOpE`Db!L?c(X+~G%C z$YseRzYTHYut)Rl5*6daCR`L!1Z=N>)xe{i3)cp6_4amW6Omg(X2#_^t?Y?j>#gir z8hLCwvM)jo{x-(fr{mW{bI6Bog!)XHB_g)q!aTi7D#&lo_a@+YYIdG;Q4eNoZ48+u zhEg(5)G|r_KEl(RWe<4O;VFtuJ1!R7#ZLzC4CEP*V!pnW*-yPXLkoYawH*^JFks=7 zt-JW!{SR0hX2-Q0TL|E((JZwc!)-1KS%3RzKP5|wFP-U#6|xz|Lbq5Hfl2E+>MC<R z_3zhTo^Vw%-oCwcmsZFYzy5^>E+}%}FeP0+Xn-X2YZ%xJ75FSsxB7>EJpcQ}$1eo1 z7x)fWxo^N?*Webi@@n^?$idTmn-M7TR$?<&5wS#lQs=VZ;oq)&blwAP%=NxzAGesJ zQ;H%`ke01En0}<xjyMx*SF<}q`?&GWhQM!^9iTFVnK~!qq6S|?=RZD9x@<64uhM0C zxZH8JGhWPf>6>&(pg8*X3*S9^G6XMa%r3KapTtLEYW8fmSH>z`G5cF1cD0195xupg z-#5r7s`g1g>*N;Gg-T3Kz4rA-OK?F~f`sSR(k^$K?eF){ZPb(r?dTh?_9O+v?`>ny z@Q^i#y{)Fg<G+8m`I_S8g6QE|q!ekt-v}qHE&V=6pRTw6*`}#t2wM_r4LZG<{C$iA z3^y<-@T-@k_`rXh-rslEn?G8-Pr-_;Ni-V%e!cjMaV65|!MArAe*ay_^~j&|lq?s* z@cWpTp3zBoP=M&nq5S<<cdn5p7glm2i|V%_Sy1pX+^(va>9^k;IC;!UCi}m}x_0pY z;!}8=7bm>vf1j_?Ke$sqsw?^Y_xK6Vi<t)ef4}S7r~mtuG$+62f!p!)Zxf_>#7gEX z%Ygrm`ft1U30XF!^r>7*AA?1?-!{Ng!DpJ>MmevGlf=kmCbmEQE-@}in>D^JW;(H@ zeXr!MaSct)Z$lsWlR`(9(H5vbC@j9O5{hQKh(6}~`%RAFBSQ_~HYc8!svEobV+Ff+ z7Nl<5|MA-kJo&muVcK|yhni5R)u0XS%cx1;4fSHDdtLCmI(c&83xx;NE}}-1{rc{n zm<)5uof1D^P>A06o%#FeoriuK-$o@-)EU3C28uC^z(lWu?J|X%WK%9@Q%1*6K0ACo zm{BSi<Nn)K>~vDz_)pIc<4Irs<85)$wahy%GaxOb>?e=Zbp7_OagLJ>euTa4u*KWB zD<5I%2K=c8{OjT;&q?8*VxIgqcIggiVTxFIhG)n@fBX;CR+Uif>q$@A|NP!3y%wrh zLtJb^zXlXc_CJ1>?i<L$?qs>OpfmsZ<?q}e0!V@qUI<UF`Ew$_SjkMSr=t<uW36HA z|0h?lt0v%ADlvhI?_rS+m8hrWJ*{xXjDwt>sQgWXeIf(dUF?d{pK!jLuYSZ^mvg<* zABw9o-D_MPDV@^!udkQbp;ZnAz&F-!Rl{s(a%yv{vuNBHtM=RmowIuN_s2g<QbpCC zLgi;O85f|z2y85se5Ue43!vVD>@5ECWe@P|;1=`d7vGUKSCM*30Hy27=q@P1iT{2O zlD-3l)3XWB@cdCWWh>>~pyJ73dNDz}@xcEc_#0?R_~l$NlU^R_2z=6BgIxfs<g@l~ zr{t4Zi?%(e8CaB0+UFnTocQe-kHAMC)qhu3Z2zx(s%Dl`X3@*$rTCk4b^DyA91Azq z<ox{<P{K$5CA^=W{NJafRr}vO{Mx(!n}`1|=V8@<P~X$WA{?aEuw*A-St~j-0NXna z|8bV@i2ppZ#UJD^=_5y^wnrV^2izAj(pxIgj$IN(wZ^S~PPK@+EWJZhob`=e4;f@t zj4TRTuS64U0p+&SgSLYrPl=t0Qp91ayqwI;ioKOewAY66#FqWaXnE6n2S>-XEV5q{ z@$26=CPDZ;%K0F3C5Mu@9#vaZ+<8W5^u~B~c6Q(vrk3bE)dFTo3c9b@N@M0d*f$lg zo}-IWPp7NIx3#oflcWU9pNjUFX^(DZ@XQ7cQ>W@IFW)+lqZ6IjXERdFx3UTfakBK^ ztR6#92j?Vr9@*R5dw7VtuN$vVw+aXd<W;Sok`y^`;5+xPN%*AQ9Z_s_@7{TYuN;Fr z%R^*IXRJ`y&b5(ZE8^y$0j-@V0_UWs7mq6(D>UoslH3cFe59fhyf$Dz)im*M_xtqu z#c^n3qSENdH9tS!CBAW5@*doU>YsN341iFH6YkE^;F+rD;^t06;|6Q@AI_4G!?0jz zT)=FCJ=9}|n2mQ`CHogdQ;zPEB9bt_sA^$fUmu;g+aHP74;*-M7I3arBb#r1@nn)r zz`nxTS~DZ9T$6U_Di~)yj5B0BRgbDH2)IqKC>}{F?(Xge1qI#mJ!>L4Yhq&3B$goV zzMd4o%{%@;TiZX+`0vHy*ODaSH^5-(RZXFwq#SdfjVGhxa{K=5cy8@JuBeC~mlMXW zs?z43Ac??zeSZt~2}$9BMMmOiX4+}+8wdZ;b-|1y)~DsOFwQXRfGN_O%nn$|JS{c~ zdttztt5dr2nuc8^?wSPefd5N>|5H<st<g30`-Ht9A>~BL`0_uRVZ5Nyar<WacBu|9 zIRi^y-TbQ_)0fc;;AFM&@9BBU)&lcB9|sHA4cdRF@~U1%kxr>?(-`S#ZzoK@zvUar zW3UhOKv%#lOc8Ol{#*#12ugv-1RKt4!iQSlZNev9EAGH0V>l^b*5ZJv;Ig4oO%N|P zYV-%}fPl|AR^@+c=x@{C2mPHk66>WdiEDE*NO_O$QZ0YWf9zlTO(jvX8qm!wvWH&8 zVH%t+@oU#f3+~nngvz{7vCYU<n5v}VxP*{UR84&%5pOo7yfNFAj>dj_95N9=^Y;oU z|52f84?Er8lR?~VwT&~6e+B>fI3vr<X^lL6!d!AlXV?Z@0_HTg$-WG%mgBm8YSX}x z1AhT_^Oo@6H|_q$@u%9O&ER6DPulsd6Hjt>;Qa^hePu-!6i@28j>)WuKl*e4cNXk4 zf#5=`LGGDn!3+{O7<!<uPuKlN#B|+z5FsSo1N;o~i+Uh(Zv;K(xCdvf6RhIzpPtnc zmhBE7KWjabs|V+7Fwa0$ssXvbkvKX!3j3nS4*gkp8RmZ6saF~1xoB-(uk6WRgzMuV zV47m}y?0G;%FJ@X(`Z7F(D*wHpVQpkDP^?x-c>@{+Enw@zt2Vx@C)4{GVyz~(Txqd zr<?&q8aHpjvywOk1Ml4*zzS?F4Q;?-MFM}LDn%$-8wl5`Gt4;=bEy6KU9&>-DLwqT zzmJQNmKF`6W*d#HU1J;4w#UwOr;P>C3R=HoH0jTLc<a^a&@uPb@1J9Z>}I-b8eX5r zj@1zN_kiF@0vo?*w~^Z5jTjO)pAKjCL1KR(4WCN9sL6b<m{}(s?gX$6xoc@s#N94z ztZgm9Wq&M$QOcG}m;_Br^eREpjk|FY@|~8xg)S-o%L0fwdro}y=^FO+>TtTaQ^nf% z&o2@Z#(_}?6i-^k!VNaZJu#ts?TJ!S0tw?FO8L)o<($0lknTqH^Hh;H5Um=;FjaiE z#cWA{;_)V&Z;L0Jf@q^xY#-;4sI9Mq0~&YL)lDr5g)RFo<HqJGOx4w?2x*N0)MOz~ zc7H_my6WT``7E8_)W~fZ<okOw#!$$%2CF;>eX{ypdTKuWC>fQThllKgwd4><)YvR` zzL%#K&s!d=^W%2wQLrMNzUoq?EvT$<k)~T_q_6DuWbN{9@gy8!l~xf1j-Rk1IN;x# zuF81b2<Ddgt+IZtH$nFH_5GLH1;!^GJ(fpYccvJLZtz5|3w?fDVor0bK(+PGHf2+$ zE5|nFoov+(&A3*z-p0x3y)zL78-R3_^!4@Ol+KrOYZcrkMx8>SBs{S1(4yAguHilc zqesQ?Qlu14`e(OZlG>@Aui0Cv=W+P^E%`ZmdU{&OnO(=-)Av1T&ICk`e>rAXy-B6@ z5vZ+)_N8ZN1>aPrHf1$|<)VD5H^T4~hN25hhmYz-%AnHvbv@=&v6Um5oEI<Tu`!FU zw=lQUleP^|gWY6}Na7wE9*@~h!fo}@!-tfJm+R{exUuMBCPekutlWyssw#0YF;5^; z(^V7GsN?i1oIr$}K*XggM)hEFbNAD<3Qf-tf~T5-lF@Ct!4J16b@cR<(aZVG41D9* z=`htEyDJ<VpY81b?TrH2Wh1%uGKu<OY{~^V@em1pk9pRDM|+?iC|t!rqX3h*0~}<{ z_PA%A*wRqpY_F;mVxvO{$ju>Y1FtnWQ0O9yut}6QJk>bJcpaD#AP%KA+W9~aE`i#C zWi0{Pi_fg{nyWr=b8QivgE=~K`x~GbfGO@)<f(>Yy-YY;c>56`IoE%DX}uoBrL_** z*#=z`k90E4Df8T3`SB%+N4M<B=jTTQsCo2DtfOasSROoa%D>Uj^6z;*GvKeEO$h?p z19ui!<jan}_tRBqc(|E8<!}n;pBEcdx)67or9k9<#{amDP6fmOBd21XfG7oBP54W} z)HH2ob_)*YImGnc%eQNbtp;<kIwnY!{{H@M*UH%h&p@H-%>f;3tZWEFkio>?lWDGY zK{Zf(_0wS-#^l!{sH$S>&q=Y6l>pxA7(d?`CsOFKxd80A6GJn+v=e^EeqXN!$VNCY z?P056BJ;*J$^=jWPaC59&I(pKL}KegIcdsmM$LfFB#EunrvX$~MV;pUK-}=iG50!l z0j9S}m*ULR8_c?lY52cS)uWubM(xnxD_iruayzH8;TB(yM~k`UuCaON+>s-k2E(~? z)CL3_%<8N`g-HYeo0rhD1~c;h)^S>^Mw0Aqij~~od5lwjar|5p#_sPo<>y$sdSY2m zwEvg^VlyKDj!uDbE2!nG)q5HD)2Vp$mBtaUNU#qEG9PA*d+*siwkm@KHZ3ee68F;+ zJp8LR{n!)SHv2Vz(%%Gq%cED(_f6Rw<R!N9f>k5QjNVgBc5?tJ{z_HlF}M{#ChkL< z6~En4$1WP`3u1~nl&u1fNV^AQ6OTa+9^3`qFksM>-M5bi4L)6p_#X9|qxQadz)$sd za&n}YM8V9J24A>7DR92s=Z0L+MH9MbTAW)L2;;DLjm0|cGcOMnnhDeGZ`Ts5E&H!D z3b0b(m+g?r=iJ7e2fOW-yOWO-24Hc>&hY}=!`Twyn?XW32DJ&^y&&-e^UVHjicCA> z<P$E)tEvuqMFBV)9Z$V)L)vAoXhf9Cd^H>@5Tc_M&Yac0VQV0J-)wsj3ET5N4Zxv9 z@ffI#V@VJVvkrLgPa+(^NBaDBOTy71G1-*VSGBP)5AY;*6Lmg1CDubg9J}9K0tdgW zw>?Z6RxCl-elkKs|N6~0ShH_CZlu!+0IL^M3}pUe8b6*#Z;Y<RHin})5*kU6``eL; zL4P>nm_s6D)Z8iPvC85}KsdwNzWZb-El!exE>NulFOI0|O17{yQ00n>ic+{aX2ryj z#oWqZ$rb}5P6L<I^kwn{2nC<jOR1@;*s%nU1rE^IUK?i|{WNsN{$*b%`-9NZ9y@<A zwgpf;>-W=La5jt@Pd(<7+rV#h<$>o2lwqAl5y_(m8zfQ4Zk#i(ib;H()~-rA*b($h zJ<G{Dl3qgp0CaYVLw1<ON~R8;`R#1fIFg8%Pzn8LhnD=)nB=Yra^)ZJCpncsS?+A} z@&?oelpXrRe5b?cZwYPveAP;(BH=3q2EHk^Uk2O_#(P_A>O{MCXl=`t4j8#9kmj)m zzN)GUSa3^khlRyON~=bx{k0IR4%%b!>V!0?QaN<cN*hrAu6XtQ>J75ef4%Y%vZ>S& z63C^tzBwmJpO^Pk!Ew4J6ns^oISgHJ#0j9m_yT<4F<)0bEQ=NcE(kDTE4_NIu6!J* zF~gysUbHYhsxRLz^{6t@%m7Sk7B6?g&fO~zh?7FrELrM<=S#cFZEdnKAV{$ad@rD@ z<aW5hDR;g6MSoV^q3_6#KzYH6zn$E1$teRP4wnPie=gTIf9vspe}RU@b!6|T%ZLr& zE<oEaj0!){oT{2ni=A^d=3eV+_yfFo(i74iTT2{d0=7d1N2#Tc{&UmcAom@oI14KV zOXu$i;C}4&l`AXr^m4&;Lq!(7Al9k5b?;Eqpca$&0bn;tv~J4Gb|vNsUo5wt=j#%G zj4K06PP@`2XHB!Nn90DU%yCwQx$y(>`b8@l!%u6VePAEcl-C26TRnPO?WFDz%Adey zVG2$+5K?ocDlz=63%-B?qRBd9_kFfOq>g)Sbb$Pt5eg`f^1HB7KFffswzRaQu#1=Q z6hyuR#nin$-<Ls7sQ3tL5bnJQuxf4d-)x81_ImeGT2&jJV$t6w!4ar`|Nbqh&`Ia4 zq_ZT2_0g~%#i|%+gC@;6JCce^^P1gw6&RpP?jqAyGDu1Yxk}Ei0<(z#Pb5i@f$YD% zlA+JZApGR1NDKJ%`p9nn)dU=P863tGmUb2UMt{n7WZE=|6DFBM^`%ygpvRmS`dZzr zfC|j<HjlAtBte@KM-y+8?2|b@i;<F?RXc$Ma8RPW^H3;QSh$xYVL*|)9QGM=`}q~H zpmCCqn*!gXE3AijaXGNY|AFEz9Y4nq$8YiH2HhZt5@2n?`kN*R#)nftYV&Y&3s#$3 z8fn4;-K!~cUK{|M6y%Ii0_EJ>DS)n#Tv~Ov|C;TH-3I+1=9Fxm(}EEX%!(k%WgKI0 zzWQkXW8c-YK#%sl0Kp^fu4bP0?f6goqua!iWoLF|T*|7^bEVw3yq@G}9F}wgwi}Pf zpS;K5_Wj_LGQ2abZP~M$5pW5%qS+}<%@6WltOEN3>!}<k9O}IY>W8};tA;zfJ?6@Y z@P%`_wa_0>Q-AB6#BKCMYLvcO_SJvG(-b7TO^2_-d9lQ4z6az>k0!TAsTMqDGbk=N zNhBh=SF9Gay>agrh#~S>&|8;^12_e)4fxA4PXXMax~g3S{$zlDOQYo*VC2D^APAd- zCRUB0;+{)of!{i8&u*wdhIqIcAh`g=VtqK8>nAF7qREDyO^uV2M!2(JE`wu17~v~~ z_6n=1e<%IoEwwDzh$%@)OfDfV%X5mKta2%%<uX2e_>QTkQ`jgtC+50hy#BhK-nRS) zRT|wI32NAhx-4lrI}11-eUSEU&knf<g%yF|p{=d^`?bG@?|y%AZs%K4{@p6Djap4a z=BX<^;jOFO`Lq&pbj#I<oh16hzNN$tv^Xwg2OwV93vnQT>h#i#axQb(j}}>wmlMIi z&F1+PP~Dpck@jb<ffFdK&dL7mFv;I=aKNAYMRAf*jvGKlzH@{<G;zP+3%8=GDiQWZ zD?&j*;cdURvT_Ib47NWVJ~ur*?X)r)?QM0LA}J)VTwUA)YYvBN-c$YILy~^Qvw{Fg z%gnrj%K;HO%M*U(@u#N;v3tCppWy&+E)9j%+yZ3j3(H_TS_UfRdSaZ|O4$n$Hwz06 zgfB?J<F$={Pr(6_o%QJRbFhURK_kO1AjG?lxAJp<DgE^X7i<A>r@1%XZ_PbsHx~!P z#K7ENY;cD?<p=JUlS7^)m;i2OaCp$~b^$8Q%G1KZYw2inu8dd5juOFIeG^{~c;3Jv z5xf@U$A8&8G-<294s_BNAh|R-c?VZhuHW>9Wvl`;Fk<;8Az{Bm2>rErP?wYBRetZw zFnR79*vH&@6{|I-`AqMts^YxSl$`3<Ts6y{7>>9sD@j#=j@Up->$?n@_{X#UQxqRK z@Fw(a$K-ugiB$LV-KA*n*zyyZp$59u9>uGA;C7I`NCQu=H+ey)9uCR+wv@y4>+bI# zVB+m38-Rci0TD)u;sAtR*LyAZy~jcy$0T?ZVopRx`eam)d}06^rteH@ufdiF>GmLx z668`PU}dmUHV16JzLRcRe194{=ubKizzaD=Mq!VCsE19OeOZo09O5egr)Y@Jfn);D zco%YOxD@kf)C_Fu9iwA^zs6VggRwG?kz2rIgf8Zt(kiv3FQ+Z6)&ZJe=-ZmA7s&7} z!Zw;6V^Y<(57YjL?gcyy7r@C6di?57%_6L1aJMw8+^*k$<OJqFDFCBtGpBT%7Yc4k z-~ZGUbB$F9>Q;cqB9>16*R1bhYHNQ)>Kr>u2TSy4g8NML7w*bH{gm_Y$qsB)I!Uj$ zQe~;dlduWEVj~Lj^E)jMM;I(Q&-bKOR19C1>?3UstjO%l%qh$k;KJ!2KL{(XwdCGT zb)0&nGl!J`Y^?5e{a;QMO(uBHDebh4nGVnS)F?rSx`25j3HY70DRBJk!1e;H{SX>$ zzPt!w1h!Qe03;9>5ev(=g04k^W>Jjfx?XW1Xl^1s(OaP%{^bFq!66a@e<grU5?u;L zz?<c?d{;bBG%cPPgZ`jzJs_~9)suurf!+{)^8FLI5<hxw+dj?{LGI&0MO?suzuf%P z(s=bq)AKh&T(HN*<`R$pJmi-|=tP~&7YB0S+HU|)0Ad@vk_eyy2y$5}?2?3)BZY6g zB6f`<WaaDy-1d<((L+Qqg(}6w3dLrZ;>HR&4>mOk9-=*NeY$C==>jde^(PkJ<Fv7X zcbI15WC}jLj+6fLQc{cbkz$A2BC~yJ$zL~-_KiQ(^x|0z$?$|Y?}PoNS(%Fc{iT?^ zmFklxb5$MZm<osJ7#O^9*m<xefR83jw}yf1E?=nS1t;iRw#78CO|6}si>pzao0|Y< z$xfXjg^U1QMrY@=(3fGEeSwj&OY4_c?R#!>Jl8;fzt78;J7R^vhfPl#k3^-XrnZJY zu%Q=oQCgPPyno+u>DzTrAIxZZ7z)Ki<Yc#ZqT}?x#nN_RxZ1Nc*O4WkX`iK_u#mQU z{w`a<mgFT>DkGUcI1hDjUAuO-gJ>L-!;!7NxR_VVJ-7?1#xd@fxVqRZsAavS3?wUX zW1p`@k|JH;olZAT{&|Iy^VZFqTgxNqHI~GELU(s}iJ`2C$q$f75cl$zBCzayF!t$W zZ5<s?K+O4gu%IScRUXSI_X2pWud4&FmK|^t%%|+F`xLJ!*JeW#6Vb1qDOp)rB|i7| zKa|h(n(~>cX}%_?mCKxIprdSYqRMPx7axL@4W0T0lD?W-7PtY~*IX0<Zfj~v%G9(p zSs57!zfDO^rKF<D?4=Vm6^tz`C~$CaxN_yn^r!S!TvUqE($XFt9{28r+Gg`)^~c1< z>O6Qb?RI7h=xaDICZ?v55fK7=myHf22sij&Qa=)dhJ`ae@(sWr3WZ|JeNy-Gq=Qeq zsB>m^_VlG+M~UC(4i%$8+KB_IjKAhKFEewYcu+q~`dwb0-Ti^c#6%*{5-r8cuu9DT z#CSXL=Q*Eio_FJNSsCSc@d?yH^?7DnMX-ybvT&d)br~=J^Q1nVxtV>!NalO~hnyU} zV$1%5<3I^rtiB>8B~_jP#Hxe!Kb1_a)XyjQrzHDy^8e?5HGe;F@PO`CSzhbU)%f*Z zUvHlO^T2_8reFX3{jTIMG|xBuE5POnOz!{w`p?<<-)#Kf+YG7?voHJ|#PPKG>3{8| z)6Y-+b8Zi?zowMV{#Ss+|Ni>_a5mmao0`r5;wJH~5X!r{y88V2q2QDIr`OlllaiBx zw{rsLVOd!jup&|u(wDDZRlakl3_^H72Qf1<^YQU5E-VNO9rz@Tm<M)*gM-7gFnUpN z^>}7hmZE|JSYGOP?zF%S;F}n9ZI_|6qL?E5zcO2|4;eKemWc3ha6Pse9y}mkPFmY< z;{E{v#LS)jJ<OSaqsNZ5@dA7Cv9zSFt`3QBMuxK{BKO^?OF83&?d$a2&z(D`HvxX> z7BiBEKqD%2N>TunEGT-@_P5vDnt+_HtFL$daTO>P=szs=WP3$V?^#h%QMdo-sIK0# zj~}n?E~UtafwmM-)~RyK*DZVW`A~h@^?=5t-15v!1umi3j$}PSs{t-*0|6M*ePafE zs6z}##E-%?fCUPHVX5aM!n+q27Z<F8IU!g181B7L0@}MdgfTB+Vxcfde;2g)k2)}^ zhdk34tRQ4K%~McB1V-xsd^bRUgpo1v`}gl{Z3-%spJdL~s5b@ESAqcpX3Wv!$7iRf zFVu)LG1YA@ege3syUQI5-ZhB*1z&4iOibp;DA*9X=+Pirq0_GG;0=F;`7zg>T+j}t zgWk|wU&ejFs{jy4-YkFrXIG0ezdtZEe7~GEn)9ek(?Gk_Hh%ehiG=RD|8SWH*`Q6C z=MNh2oB&e~9A~-L?)p@7NK|-undcA<#IgYy0_z_U5%I%G6{zVneQaA>o9@sA$$L!| z;O~zz0fyLGGp(Y+12bL?ZigNO6)<bSB`}O^XH}j8d%ERGF<igEAbb1vlNgDdMC!2C z>6MFpe2&0Y1H^FEt*NNM0UIPKDOphn^j9}H4+8@N?vr7@<=5vh9zDB2j7ih0_UIqC zBZuP3i^ln2g;lOcNB|NB%5ZOQ&-dla54CUOytTSw1gv_~ln)*}n4h1|&G6(nbtG)1 zZd))=J?I3uH8R}~tcL%kek9*$<1#n*e!wJVe+2^}<VHFq*cQ3AzFtsT0xp96ANStB zf1hiuae>$Pwc!Lfmxrj-kx+C6y${X@buZEIhzJ0ew&Az-wwALpGVU1^JN!`CT>`-D zv?%Vmm5p;4>8gWunl6M@pdtf`H>G9)JZG<Rye(-2)aiZ{(D0e^Pd@ba_O5vGlwBKv zAOPb<N9+c!m>c5){xRHT*FXjd?XgjyR-KLlE}8y&W5ELsdltgR(yz{xbO!f(^GFP@ zNn2v!9^2QlCIt=2IsmmWJ7qR}x^8Y|i-QM?L%&3<166eL#EH8?ncmc5&IFuueSDmt zO^l&IHCP2LybyEe;F=8VyE+dFm7DqfZ6IZ=+UF-(HPaYO9@%YYU&SCw+Iw~r6+vmb z?hVd2sFTXPhiJrHte-sj_+qT3t*xhe8Wu5kX%#l(8Keea#*D!uBZo3FGGH^feC&d4 zb?)Rz`&B+;V7Xs;YHDd^<oar^aqL&|GpS=YHtr8zgMf_@9;eO9`ZX<4%f1i5^R=x* ztih8-xo0nMwP_aM3oqUtxlM|t*HWV9tSC4K&h$ZqN#%~o^6ab`X67(850{URPx2^> zQDd|ARDnjv;iu`RNw_!G*QRP4xag5re{eVX^HgI|wl<I!5Ed{(_+qfX&O==1p$cd$ zSq<m7|C;i>f{IE4uZcfr#1z<AAEt^(^5-)K4@WLDZ>+>7HuveU)Dkd+ucV}!LKt~y zkHnYY2xs$?at$d|D<BYZX#Y?VAsMW0t)lZn*VT)b$uq`>@p6s+LbjtHZJrb@@ACp5 z3=Y9gns+p`+cJD{wg-xuhg(cM+3yxM_$SK-4OhD6Ex$K6%D&7kR}y_2KD2#!Z8V2x zz9NU;GrPr^R=H|j>FqUXdbx(2FTqn!l?i=c63=n3d^8j?YR;bof!!QPGo=tAFZA(L zK2u^;T7y3v!V)POI1i`EG#)-2^0uMbpL~OMRVCentFf^$Xr~~7-$KpHtLjDR_no>P z-p4YY{o)7Q+Wr7Mo$r33$+JZ2fvz8AeSN)+#-<%{%kGu@`w16PXb+v3OMA%^Ad2-u zD2Zs|9#VqN$l8}(Pfu?Qj1=ei!w_m<$s2w1)~)U35h0MTn_8PfvTACm;e^zLII!8k z%<ntXnrd5GQK4-^L@CpjNJ)7i5PH^|y${#Gd05a|1Jg=VV+qDx6a}2`3cZUG9{i<5 zDf;z|4QGOV<25Y^^nu^@Zpxj%g>7hToL6BPn>X}KYwZ{sH_fUnF7M{FGs+eQS5LVY zxS(igXw<WcYicBggj~VgTF5$d=#a3@0aseiA5q;PZOuC4EZh=na*utGtn?;$97me~ zx$TPAa{)FU$XoDaBEV!>&?up6y=%h_8)TBrclxqT$yIxh@hU1RE?>`@^Qb=%B5||M zQa{E`O-(bi9_9rZT@pBM%=kL(!8N+UC|C?I+Qhx_Zk{jr%Pw$MXu<(Iqme6a>9bYm zLk8x4uXAL@lZofm_p$BKe3m9|AY?1<A;CFoi!o~i7R@@(;ni61nb;X{xg>MWTvF${ zeEF*hUrkNT=g*(Ph6GOwc%`ydR1R$_+{|v7P36d+1YK<1rC&UpSK+c86T_xo;gkW> zj;A|IMs^=*6+*)&dpgu%AMZY<@zi4|QQW;?W$4qV8^=9I0`rqXLPDx|!8<X&6-ClL z^hhnc(K35*=9Rb}ZjTe`9XI}<!ovm8MiqyXYNGBX%jRh2-_*DyCRSN)sk@@Sao{`0 zEwH&7XACc32)$B-u-y2@2u=H?Z}|(4GS|^1x0Efn9ycC5eC*r)H9js29(6qUQOa*i zj@`U@)2aGQwtANKyUa{Wh}y7>4iBf$YSf4&_GO$`Q&Y3f>a)B^O-}yU?QqS6UJ&pD z_No1O_O<8q-1~PoX8U=!UNJX?$t=^CInAq$6~b--eH?alsY5-hgd*^wK-=dTk^#M+ z;_6{lxX5Xzkga+5?z<9`Z^1k1<J{FCb5v;G`5ACh1^fV)cg2Y-qN3VVAE~7U)+)Jp zcvP1y*v&+pQf<Z}C(i7H*RAi&{=7o=hmjBcmK_}(puUQ2uUQs5B&k!L=4^Tu1EMvx z=7FZ>2U(tlJ%{V+PWj_?&a^?5Cmv{MbVc(um&^tQM8$(oFw3M*QeMs2IK}W`^Qxoe z1<qj?W|u!W!C50i;A&|#NS&KA7jP{ayceq(+7(clpCo#~PrM%v|6}2|>9w`BTwc>H z=SLJPaE9_qO8lcq6@R+&EOlJqyy&fYmQMK5PXGM(FBQ4D+>(;|uC>o6B-U2+HLYte z)6?}g-<xvK{x<<y?S_E}5VZi2AWADs%Y6cxs252iWE+Qf4PlVbMXw-td5AKD1J@uZ zW_JlqB%sMT_gf#TtCPGqpM_J`Up~NmH2^=qwZeTl(T9#v5D_v`Lh*q<<<Q~7KO8oX zdDW{+F)}i4D(w><Hx?A|ZYH#W&Tw28KMHVac1N%Wv|5norwH0N^ejkcXJ<Ht4@W5C z#)q>B-1(EhqV#zt+89t$QnH?_1A@po`ry+hM2@kENyhe%_5_K&d_jkkmQp1^DwloJ zol{VZt4@#&dQItr!+DHd>R&h`0kcw}`T0qHO*p`;nyPp2KCPjP>^G@$N6fJ@kAM(; zl}N9_EoNwFXh~Clp6vf%?=8csYTK?+<F*ME0SUn(7okX}dW%6yEgED|(v370NF!YW zg3=3c(JV@ZMT61}(z57o*yr?qo_9a*_w9fC$Nu(lynpUoEGKi$>%7J}#yH2-^+A4r z3sjXpM|&mL<7XPP!bB5E^$A;BPU|YLjq{6g5IH^*0|RRO+;nKKppXKfJ3_qa56XW& zXYOzsE6c%CWOe8ikoJ5moKwRkC*K!~hW(PuLp`o#3ZPAvz^Ps`xrGHU$*tr1l4<`@ zjDL?+c<%RjMjQ?oTP1Q#@uEe6^5s~nrL&rtnrb|~#CR~uXkK@v%VHDg(a=M5+CevO zOH-3{&UD4*@D21{See6Yqy|fCef<~J6_E10ISow(Dgm)Jtk@oT0{9f%6MYBb3L@7B zE8PdabXkF=&%5K&{sAsI)r2?{zA*gLFY<|)D~n9@c`B;ZS(mZ1)L~UVKBv`<V0BDR zPV%G|y)et)D68=UXCx89luh^4kBWBJN(~uE+LD#m_0*^6tbyDzfw4>Kh%9*$#@sM` zoPt?~m7QG?RS@V;$tR0Kp~BWr-IgoVQ%SPHC6`f>^vp^F9#A{HtE?P8US%>)<kTu| zEAfBXWvVhBSYQ9RTE3v7DM;A04={*DQ+QNVQ_d^+qjPg|biO=$^#(^{FM{=8?{Ypr zPw+E+AnZU?c1?T@&CmMT+k+Jkk@9#3m+Z3g*U6KazGb7OP+ytVp8>mx*Q?O(3`Ll> z&OZ5xZ}yW-8vDMVcjp8azF*%P#U;NnWjG>g_)kY;zdQ^;d7|oYT;kyG)~-2T^d3;B z2Ctx5FpJ#)3A2$2tRQyfL+~Qjdv1cCV?VuV5*f4vs%joS4K`ci+&FRjGq9M7#wV<w zwqtPVZ%#Kvo_4^OoS|U$5gCIvY@&qm;NXDgUN{A=v%9<T80<P|R3Gt2Fw~xO!o;sE zfH~lq%`X0t&3F<X2+;?%$L=J2lZ9p0@_piM{aR=jJ|!oU7~}XRFe_<fSC}o+Ri`b( z?HqV5CuMypXJ=;}?!-8|x&po)!8<hR^q%>s-XGV=?^4(z-BYikqhq<~FH=GBJt8o3 z{}84k%m?NQp`AK45=WfsjMsuqrGMKM+)H_CN*KwOgJ%h*DtfTd=D76;;9ifqxHn{b zH`R7&mRNqepqc<2AS~yMK5vaKo8scJ*C)=IpG!Y}!hgH#^_w?W0$M%}=oPkpa=cMQ zjmos+?Iq)w33s84y{-SSBm@BVMJO~?85Usa$++PM{S%Om=}8(cF8BqeqEB0Z9&QQ> z3JMAJty4ur(xa%Tsp*ED$EC2(3pKj>n2;4*bI$)~i5iZ^OpEM4T7;hjSEwc+k-wsC z^Th<|6Ts-`x%JNTz57|o;#+)4Zp#GfD^>y`BD;wPGl>(;K`T+C?J3fRF-U)M5ha{T zM?5P}@6b%;>FHVL)it9AK1!75ne;p9{=OYRD|hn0hL>{|FEk8;hr=9f@bJ>pS=Wtw z0a;4s$NJ-v_4B-1m&uRk_qjoz5rI<8yd!EeCCb;C_&XDxAXW``ot2eUL}Xx@R_n=u zy*mYgPu)Ffj=$3<!c5km(xNyyR>JcDnvzZvrK7z1`YFQet?(@*bfxrag{Bd+bb-)j z2~c0Y{Cq&`H|%!r^`r;k7s$%Y>}-5FC-$>O4N>XydSM-qWStEHjL0W_qB?sgw8LB4 z6_@Oflt$~x#yf!96Hj#pPp2z<0?_8rVIUYp3B4f*U7v#n^aM}D?p&ZaqvhdIsgd74 z6qz=l=T8`$oi!T>?A5`hZ&;QC3@Llpv@Xqv8%x}a>;JZ{mGGWOes*9F3r%^v`~yCa zu>gA~0PL8N&En)oW1;0L(+{G#lbV`ZyAk{A+4G|gij)JlYlkYnoQB#FmsLAi5_{^1 zJPpFr@{<p!-DYE(VLV)B1YaI_u)*1;WJiVK(ybhHWF{mhCm*gQ9)xM-kkOiy3_<VJ za0s%9<|S89ehHxn6TyK(-9W$HImdGK>Q|dlXuxP&y|-YrG^6;?EY=ZZ#L}A*61wrb z5BBC%(}aXv*3v6<$rKb6V4ETevS5mQ>u6D6q4!9>AFrs;?EjH$(VIov!eSnQP#;)e z?ZOr1zmdSB8WM$<K9*;6oAYOhy|l2h==R7}Q|Kswy)x?!X+M}jZ0_Gb#zOM5JTQW| zFU;d$7Wt4%S9fHed~0`?8;p?dj(|$NZye<pMtAbg!^Uab0BvVhR#qW%ogY5w(PWSN zzj}#GZXt^ja~GtSkjoV%+k;72b#-+zxi;V6_6j#xxJBAn9v&VN7Ew)D%M~~pbA1BP zMTK;@=%kigXuv$Gx&uD+@c=ud$1#!)M=lDHC%Z(-#qba|jw=GPk-Prf3<l`Hg%JMg zLpIe#lw5+SdN&sccllsjva+&T4@@6fhcZQcS&OF&qO;Mvpz#>{T<t#~hedgs2{M2@ z5ek#Aon2i*L6o{qqbCL)Jnbl85Ob-YtlC@gAD_?6zXQ$y>5hWt=H{y1vMLH`m(7K2 z6I$GLqaO*`tu5mvOMvJ}Jx#Q#JhTOPeCgLa>*^kL6vW2T(j@x0?sd6dbRa#7M@z_d zKq0aZ;}`2zYkLJNWw^>Sv12L&d(r}0xr#((V-Uh%6?o@5Fl~csnKUYsOsuHDJ6mh( zmUh!4d!wYJBsdUN-Z``bG@>8UeK}=;Ri>kvl;v+}ub+(8@HER&Q&5#ZPwFEZK<S{w z)sXwk$d_^`^I3_Cu5G_{9|!JwkA-06iXftV|Ni~^VL>)naC)t0K{kAExUn#Vib@oD z(K_5qQuJplew>|5httEVDJmvc@{5ZP4^>Md+t>vhSe|3bClNYj<zze_FI>2b9qq@W z%^-XOw8qXDK6}vko>@iyga;!G3MFqLOMyRb40Z*>+e7vefhAu~bKXSrVyBLN?dVB( zh+uZ3XO~fMM-EG;6O@b}+Mh=a;~k{M*MA)D{V>W`&z5RTJE%L{Vl*w+E7SHTtRQ_L z_2K@H!)=Kupi8vN&{XFOg;g;G5U^c8xd+Bs(R03wH3jHjZ8HkwSi^T{SxmDcg(>}L zuQ%$+OsuioF>3yzkqxX;Xdo@VjK@NApH~*f{fdRJgu}IhF)O#1h2^nz7Nrq%Wq7?$ zOP%0J^my=~1_lI3>)7%HVj?>xxPiu;zxG)N51Cz8M*8<$YyIxKySpnYwu9{)0t7N< zGf@kljW7z(ile$*_vT4oyFmBjs%v0MSL{Dx2!H%pQqsbnBB0^yVSB@Tup5XEhh{%b zK|@1>LSM2ltGGm=p(yhU^a!VRIi~rnF#iu#(hd}I9!U+2esBbKHI^3_7ynk7Ll59B zn=d966`@;{JE``-JHq!MBrM0o5ko+p8LcB+NVQs<X<_CND>Pc83#0AYJC>JAot8nR z8R=x_YiT!h#amIFLb0JxWsoQUh~Ls4Q%B)dw5MhRR2cC^&Xg@S-SNo&eDO%ElU@jA z=))Snz$}|m&Hq?udf0T6egK??^4~lUrai%*T~VQC13sgb4A1Q-PiNg_@GWMdR5guB zior%~?Z8ZcX%T<V!=A$(T}hNL3O5F($Y!P$Hkb^#O`S%96zE;s8PgxcEe7IZB#3YR z$B1iwrt9uQcn3TwP0>zF%M|!~8YiJawP!-xFK;F-r~oo<a=Qvlv#{_Ej8B@148cf< zkX?eyi4!M)UF})dg*u$iIm5fHWR)M!YtruG6)-R#kAoTlwu^8>bgqs??vT261d7xe z*bd-9SC^L+be*PKugH;qRHsEXH8zs$b_pd+G!p__qi^fK!ocMK^My3RISul5LZfy+ zFR~yw4`4@E+3n5<f$Qi&fY^GEj#6u~$Nd2=Gf=?d7~U6NrPi11c{DnX53JR828OW{ zA6TKpd;7Km+PkB@U52>>6i)ii>(Jwag&<oqt=qA)&7})RL!vL)l1jG>6b<RA$6A$c zrT%|Y0LW^RHv~dtRy7HDVGKcHTc9vV7;!n|cdcr<Hx9q`6h>$9F)>M2h*)=~D?sm> z|AJOP7+nqz9e>7EAR}EurnBr+CwUVvxt;w4Aa21E>;X=X>V#$JD6)!0(#Nm!0$}xQ z<hzbG*9vSJ`VZ7PNAQbH1w<;tb(na#>PcJc2Ys&Y;kvFi{mV5_{sFIoH>jQ|w_>9o z>FxYI$!U2Xm;0$*z)#&75=F6Vmxsi~ndOdJL5W-$5fTzgekoj$EL<HnFNg=$Ggh`L zr;Zv$TgeVYYsGS6($mCa@F5X~-a@meQS!OYPUZE%pR%TATWvqZvdUVzZx3k3X$Met zIRb$+J+SMds2cI%1J(p#O5vrLwE5|t<3%Kzt{V}7ind-k($YQ*t}mv-=nvKF(CPJ= z4y!5jbUfa#bQD0BdmbLZ&<4rkj7hCp8{w??>^hS}qTyP508(vvm#=>Tl1AMK&?%RW zBTx*qLcbUE6paO}Wv;}11BhbM4>C20L<Er=T^Ili$ozZq`#`CWMnwMUxubMp^GgGQ zq9#j*IjkI$DDK{G-2w!Xg07kC@%P;YYRgcnh&%I=2}J7=Vh(>!!mqI?2e791FFvg> zOtPV-N@A+<+xQRYX?-3=1zNjFvL3bsMo_9s=8%pKIu&~J;+&iX&;8s(!`=JN=Pu)} zOG!&Z7xqlB-!~J=NX1b*uzBInc-U`VY}}~`Fa<ja_oIg@DQRhCy+qhe`wPuTJs<A@ zSt<N;764o4t6xiR*<mw3OyxP&qp+CBM_*QJv+@G8lODRO=2jMtx6#THFOjjKITawy zGIFGXzGR;~62+y>qjd<smm!T%-tCvEZrMn?wfxn=Voly2ZkYxKlRV1QI;5shk@QI5 zg~n>FUykxEEiAX>qeofXQDH0mR#uYGSvN}F&2De1?~7;(>K`>hD7D-(18py^oF*q1 z7}VoKW3gD?54_6zgv>bCb+~x%Mb&vzpxEI)+($ZVWkf>Q7mcDg$f!DzDieb#G14yP zuill6y@(>VPJrf9%|py}*cR$yFvg~r>FTwAezHO>^@*F~J0k;1I34ykC2vH9Y^lD7 zJZUhK(bxHbSt>;90NUvQft8Vi0nac)G*)fYsSKFec8i6PgZYsOWyc!7pS<&cu1pJ^ z;MKufYO1KH5Febwr;2Th)HtqegAq-I^Ap{oLX-%;ofs7rWgIPg05?9>#B}yy$2+#a zr9W<9k-BXDqZS6@)=y<yoXruEKIptx4K88l8Xw_V@AAUFhzRMvzCKeNSW|w#J_O9- zfc*mYxrVgPqsqWZT8TIS$D|E%mhjAJW3rz$xe-7?6v}@^9xib<i~&XD;sBllR55V% zcexM%3JsZN*!Ne?Se~ek*iqEe8wGBWbT>%A3IT(Gm8WkqGiN4ZXM1wXJo*|M8g7?M zJehyar(a7_of#Bs*odQ{uknj*`4adCg22aA7hBq8>9b5U%+0YHA>e6A)Ql2GYS^@- zY7|;28HBCAglS;B6?)j1_d13?m^y_e$A-ANy3z$DwTG)IY)T`vD&CR3#pswMU%#6S z4s-9`H_&=I0~3TDq{Ih)pYzw+X1t6N&iRk$WrK8ZKx7zkqXGDZkB1*ja(m)lY%agQ z_P4pNnN=B#sP$MZfCVfn%a#efwzTwn<|mM!CEns~re<bcF&79|Q-EXj_whmeugKl` zZ3wj$L>cc{g?Idv_R|lcDav^{I=@P$0nkIlX6)@OZVa4J{316!gi5xu6fKhM40VJH z-0+Ntar_oiGBTI4HK_cVu3x`DpD74^QT1{m{Y_8&fcd1oI2o;v!@MDER_H91sC{t7 zk3n?@jy5DD<l41s_#Y+0Ic?B7cBN5qX*t3ATW(9w&6SsvL!Y_|WOspH(b=!}T*Gz@ z3moS)hRR=zjg5Z{Y3k|e`9>XM&SVv-23?YGP?dn;d?(zQ-i~^xT$c8L0bs&Jkwu1w z{^s3m_U2f=re*P_+M0g|Xc=auXU~4s_)>IbrMR@b_%{y;Zy)SDcIr0pSGb~CaV^^k zI@SJe=nP3tttplLIC<(6-9lXK1rR9FduRuGRDZXHdDfHC(o!PnQKX$IvH27|#R+CQ z*n~~JiR0s+D!DO|;@mm99-LJE{WI2Ztt$^LuB^Yy-|LQpL6%rgMqzta7M4eQSXO{C zZrgb~>v|$AuaPDcTyyv{(efVz^>|`1`ue$ArOC`|$zyuC2|s_UDeUJBgKPVPke$5% zlYAV%Y`pR3HmImJIL!Eer<_Lxp(o;GW}Z6SJv@-8R<i*i%69Z{zv{4OSf(FlQ=jT` zd4I9~qAf2kzs|PqZK#ToOzX_BTzU)7)!t^O7y+plD(pM2dB1ILmMOferS$<`j^~m= zn)~2E?_@Lz0+z0(hLVe)kQrzXXlA^?`Rrho=LkO;b%!xA5(GVAX69OJCbCe8b^d{v zJI4KGnX@Nblq3Y<t%yxU>{Z9tgub|K+iL4Rbij(PU+s0gM@B+2QE+t70&8y$x&{7~ zzeAu_Pz!Lx)}Nr&jpw1~Y2!zlJy_T9EkS{d5;~6QJXm%?c&D>dRT0&wf#wv+Vd@4( zl6n?l%+^pppg2G~HnVoAOTmox`kefeCknd206g3J4z^srLkj&n(8Ke^b^b)Yn)Bw( znuw5#Fl2azn%a1={SmYngxmRjbF;HqLFX`5g+%T#0CRqGw*&-K=Vw@dJQ;9(o(krF zMMX@>6mzW~(gus=k;%mJJ}D+|K^hJaBZ0o({+_C(_O_PrzX8$?XnJ{p46ar~(xz-j zLA9T=NKQ?iLQ1be14NmK3@?DxJ-KqY6@2(qGt8Ir8kh@u<J2Bo$S7M~>ugK$M#N|@ z)}js+ZL8)&NtgT`KNinKcwHh`2UM0nqc}Oc*2QsrKqsEMQ7`oPptCgybR{y6>8$xq z)26anq)r2Y=FmS};k1ky(47LA3b-c69p^q!0J(zy`War^2p4kd#ECu+Y(fx%(sOhw z@V>Y)=vede@?zT+XI!wqOAxZl1WW>O`?~hk<HXPt_`rv{&JPGv;Fit#kSq*zV268N z=UZ3sWRN+^i|G@{<<oG<MjeDke)Oe4bv#bRJWcz{6~+hzZp`)!&&`>yr;@sE(wfFb zhJ@%jwbs<tWociWk5Aud=gw|Gt{mAhsPFy_t3Q9=!)*|U3{*^fY`m|;#c^NShjL!! z|5jo~LFoXY4(~vxjdfZls;qnAY0?~ET2cgn96&uF`{~UEcz6_}?n%LxS9k<?7!R0U z!RKheE!N043LLjn{L@UY2T51s#9{9;(d2%yv|9b8OMWw-_`;vEE6K{u&5fk4x+W~W zvhn~iEmXNe<t+o7fUB7O3D*W)TiZPR;1@$J#drD<#r$TL$a;YN6gIu)qT-axF08z~ zojSo!{&eWjt{Mz<NH&|M4&NjB*cKQ8Z<9I<9Re@}Ys<&kj*;>}El(!|g}~Upi%1AG zi}12Q(|7#XF~H+<L(OZ^7|BzVB&tMd<Y$X5wc&#uRVE$!fJv-p8*k8-7&k}bV7?E4 z4=9N(lWI1g_z??E<NK!Q<pXVIyE%t?NpfoZKu03Z>w4pox7^*qHVI&LR-6oIy^(z5 z;L(9==!w;_okG?4CVjA>2EDny9x#+==&vCyVK)^pe>w(}=>^mdoyT7!RSC4zC_h~> zXh?4lzVoGEfmw|2){G2~uz~<~BqXZfb9J?~{T{?PTfGZShv{l<5&wnXPyZTS3<RVE zG236hd;yl`l+a&GylkADFr7XOMg@2;Y3b-RpFUlB>s<%$F|ZWN%ga!jVfRE!N%@V6 zac$75w|8`aixfyPdK#LT`1tvc!8}Kv>O${Z;lAsLMx%kRV$7q{Dn2>`TP5HE_<8?; zfC*I+jVbC!U;x$98U$v{a=09nIk5Tc>?WoI@eCgXF9m#7`tf5hT})LUJMx_V|L69} zBS-$vb%2Vh;4r-ZWuap@{=eO7_(1Z1O?e#&K8n~Q{_S%;^6Rhv`PcvN?#5n7W)|m+ zb3{l+idTwJ(7z`q3e*snuA6W?8EQ*Uf9&1rClOiFMV>n=808Cfe{udynsr`m_FY-w zcXp1e)VR=e^xNX1hoqi+FWT(aQ;Xem{k2u5bcdN1p5JH%3&hQ5_x--7=6W`SG9_ed z_|^d(I7dk*;)rFv1Jup|E5O%l*G6G9&SNq{73^Zj2q(ANm#-KclDIj>%BfYdl;PF` zX2A<qw^&(y?EZP#3hw^7$g`ZJ_2-2G-9F$o>%sqLCzexEJ>jjiHs7akT(!<dW=SNg zDqnqdR{}2Tvc%qj{C<3k>|hN@9%2m7!9jBW{%buPh#NjU5L{w0M)i(_W~B`oUTJ#- zAX)zRND3A^2lGA4PXn%qbYpM<mv7(S+cXKJ9B~>aT|Vji&%?Xh^Z;Qj(_|k=WdxY| zP_~6~3WiTjTDUl9I4L@o5-=H=nN!ifHkCb1!-wuFICmz}c7<oB<C5RKs{`hV)Spiu z+nXXyjm!M{^()JoyxrE4o^y>i2@Uvm%t6jMhr9mgxBki)i1d!~aoNUp2C-Z5R`;dg z<UL81l$ft4Ia}*FpXdyyDtNfrE}yc#tz_<!m+ns~CMpVKwt;4VnnED}y=5vS&BMVN zEE7P#18Lj0XD>&P`j_ohLl9ZM;uc2p@)5YPgr-vZ^95=WmQrgg{IY#9-;=&BVh>u4 zdhQUs4RE+mN&U5cV4-IR3kc;6w6ZMtgUU~Um@Cm0^W?vMA%C!@FO!FH9${QZ&WnIK z<IAe$#=9TawLG%T+$<69$d3IwY-V@1#g%KaRV13<Kzr{O-*Wy&+CusJuu#>}1#zEj zay3d8eS+@+8%EE@S>;o)nzltLjV{mO(|(^oU-!s5_rmLr6Oo@)UePSaOv-YY<J1~a znXfG=W%^=P;5IE9;&ihE=y11f9G*_i*C=xR3|2wkOA!>v%mgzjrz*zJUEV0LH(JnT zwxa7^%mp^bU{9@weQ*chGRSljZ@F7Fww@CrJ4@Gyvh210LAVWf`T&I?crFgR8i@6I zP3a4)M$t<jdi*`MHQx{?Z>;ObmA6R<SASYMqujkU5_&4v_s~Wu`Nu*hMe#Wjkr})W z=&UuLqd3piU*6PQfnRuJhgoJ#UfiBD_hU`-_UeN&U4`Gz#U*!FIfiqeH$QLZLBo)s z9Sq&nRHezpB%`JT(alXw127gD9Q*@GseoKq5Kyg#@Bk82IK#rj3yfg0$E+KoQgpCH zSYcGsps;B5bwSGvIj|l;xFQ3&;Qj+w8RMl(2D!q|`QyM{fd_XeGI#_2iyiR80Gs#% zIL(1jX#c6pY*wda{RtN-DGR}=3C<ay{Pp3RKzC6VxF)snyY24{^d;$<58<y~y&9_m z-lp9m<@09)@Ja!EBes32gRwAh)^Y0O0T@^gEh!OH;Nj;-bM%34Xnq(G!bHt@V(cd+ zW#SSOtE@-A1Jzp&BFB>_PgcBOO#*zSgU}inQGzxP8G?qHG1qs(?Cho>YC&F%+hWBg z5-S6vlg7rzn*Z8t?)pFa;{(D?Di@Kg-oJjfC$YY>#q#&0MQo)2!TgS^*4LK3oc!w+ z=c>fTFw<W2#p2#YsE}an>&99OTuC`mWaKZ`ENyF6S<Xc?2#U6B`1Gdc$F7scbJBWq z-E}M+r4Q(*+x;?WTovt49Zs^1irlv~7k7uejXV*#Gd+|GxB3c1Z&j~LptT;xjOx1W zZkwx5nLFtf_nn-sm5&Rv^;^prPLM9;9+-=WDxUdtq7DCLa6NP?lXzwzjC6B#-0SvO z_fgR#Vs#Ndp3RTUUr&<`Cq#pSDX({M?=Ky0n0HATn1{YmTLyY1w{j=*T_8kk*nop8 zuNOSaqH{nxM2^Sv#<hTCzqYnk;64vj1tUz{prG>^fzYUd?@*vy;zf$f_d<3br^+XC zB>;FMB_p%!NDW+2ao<@B;l^!JAz?H)iDHb5Otb4^MVf0v6L%FoC8Z%<Cs?ZenBc`p zolko2I|a?U{iG*cUUc;37*ba!C!ZTi8XD|}ZkYg_-+6h>bnB|96oO6LIKla$Y6*;D z!qghmzp@B9>Ho1&(xNi=PdEgB)C^uz*P?nqdi5Mqi-t#Qx84I9Ua(YX_F!Si-FdL4 zdttZxQ^<th*MM5eN_y>16JqttwDItz%BHd5c)FBG-51yWo7VKN>l0>NmCDOyZwRnh zh(ujEA1l!&u^nMDdR@KK%lOmYf^XEC4prHxLAUR~i8wh!_rknUbH+;Xq|C;Y+`#77 zjqrSp=ALXn(<z85&ZtYiygVYUAesEtYMNGD)~dx%%Y{SiR>3oPflAk3Og&7Q77J+L zen90AZ4Ub-QluU|ZlzHg#l>xlmnli^Z4=tnwza2Rp7;}Z?5r{$%T#G6ei3H9vt@~V zWLSiDrH7H9+4ihhDfZRhbkrz~<8*gKGiXs79Fef}d=5SKmg|Urz1qMK0CqP{WT<3y z13x|2krqrV1wDJ(XtK+;EtCxKo^)oan8hgjG8K(Rw!)q>c^1GpKZGLjiOxb<(a?zH zKvaK7D3KH21#uSP+Z{s?600jKYNy)(EBNf|OJuYVLZ((>Nv?IscRiJ@eGAjRQt$^P zxNoTA_CTtmu(}5AJB9@v;OlGBlM}Di1uuz!^{>0!+}yW^=OBxsR|_`=n%qFPrhr2+ zctU_t9)Zk-<q`PyHK2iD`V%vYIh0Qn&(0b7@ncc%?Ci`oSoS?(8hGqEk|nni2%~Sv zhWIkl_Yar)cOYd&xh#N^en+m|fQ+SLyFSx*<$ALhC#1iJN<XN-*6we3l%@ycZ^ayL zE*O(CWno;ceZ`TRJ)46)+q}8Rb)^v5p6<6vw-0erMaCL#|A?%GzjIPaI}|eUCOvRe zcQr$QRx8!?0$#ITH>@)#Ag|o>agdg{wF7<BOx=T8zal$pZ)RT6LMh)@@?MlaUhsUI zPz*sCnkG3qPJ*(c4!<=LG<Tl~7GoZIOlFB+xSpUo{x=j->pQw@d>`<;qtXu!Hb?h< z`!$+s>)}*K8w?jB!&&l2V$6rc{RMVo<=>Y2<rK)X1Hb|vrf{B{7h{K4yA4J<@7FLu z`JO<cPXJyL$r#{Z6tsQ@{s%Q3G@2h6hZw%bQQ;FWrjg0$bQyxdW*w18gv_GG@TP$Q zO|C=4FvP(k!h=>-wHhdD$yY%whr{uhT2%p*lF{s^$O3(Rw*i$ARv?N-b|?kRS~RWM z&o83@SSWM2fonk@gPAzM>Qrb19*JW>`Q0jn#SGU3(oikDmoRhz+W>n4GWm?bRFj?p zn+w=)BCN8LlSiqbk>rS}g8sh@S~uG=vu<q2qhPgvVod)*qUH>y*j^hcr_lBm=_zF6 z<+^iYa^+PPqoe7dJDaNZfXO5iBd3oe>T5J^ar9;6tE6E2Ao~~oQJ?(hnB3^z<X5iB zo+rO;m8|I{jmjMUaG}q{)F~}vRNLs`6s3eruvBAKXB%Isj07_ede6izbUq)`UF~~7 zDm$#A(uHYYIj3(Q^8qkiPSKhs!!)3}7naH<k`c4JAW-{VP>1p!+`^jg-thWwld+oj z6v9Eh(Xg)&OK+k#<AGBUGn%bP<Y#G!hH`%Gf)@tmOxP*DkpT6853`|Ea2}8;KM#6v ztLLG)9ISATNRaCMnLxgkeqthc2o^ukjs3llo!Zba#j*wB!!G>TnC+3*UO;1EzcwT< zht!{$1noQnUzxd@P`LFCB#H~=1(5UJr=aNlkq2$wm04&h+Jz`;SF^t?jf(N+)cFBh z9cA`qKAf$mg98Dgk3g90+`gowq$F9_2tii&=6|wfq96&EDtBdbllq+D$v$Y{u^jF% z_SlqC|GfaIg8sb#A06yGmQymxi5%L3@@g2-MdhE8-n{q4Y<!S);MbQ!KQ;Bc4{Si@ zlajIdnSE@aF1zO9_I+0z=0?%wu!DMfryKmtCr3C7NHzW{J}YwGKI^WwJfHS=267tI z$-(AgcgOAn<=Z(KTUHo!DQo$nRL*F>+_1@3*3c7n2X{tz`8TH|U7h2~=SdFZlnf%p zYzU!O$nnK;BXOZIx--x0a-zWA!<B{QCwVHFGc#!+)yjl+Q`{fLVVs?}!CS*g<pD$b zm?S+cY?sEkr}2L);B6=U0%kjBNQV3<p-@e{`~YqYyfJu<HpC(6EOlWT-f;6Cw3Zgf zsVkJ#ks9G@IDj_z6%!K^p2yOUoqFR&*42<q9ZUo4#d_9B=gyf8{}IYfN5MhrHwkPI zPP+>xH)`?`4M=ST=F$C`lu~7IoQa{KFfRHB_WuLR`N{dvT2M(g%{PU}(@2`xcr`g9 zMV_SC`p!|LYS?mUQ=P6H`1wx17ynoFnF}mC63x#*W)1AcIIQ2eLO(g~pMuLL|D13Z zmCmb*@}w0wo0aP)%YCjSrs|rYS$|Hac+<KWw0$xL*yor3Y88J^oV1|D^Xu%XI=1CU z(J~tfOawi$nrO0HA1YNSB6lDy!eMOGBe?hqn2ZcQ;L=7_VopSeQ4#7FvX7$)(3S~O zqOW>)sg&v{MrayTUQ{Zd#k39{&(P&?zg$6q5-&aIz4sL45w7|pGoT1ieNw}H{#?`1 zp~N90E6cZcKYTpn;Y0Dcvx{h~6J%Wpy-G$|r2#@n-UB*_^jy6O?WABj51O9OG(5)| z5;(ybA#`~TBo2!gwdVXyG0bsHXc>8V)pIbVBh3NxVTTyH;o;%D;7_cFV2ku)0{Yea zQ7#Z}{~9m-$aLe+sLoS;0_nG%kQQ-`^V$BC!CF6}q^YhvDb^k>$|p~|JZPV(=LLpE zx?)24Sf))CQ&t6MR~^&{u1C}jd?hL+1<9t>4cKDiM>BpiI&#>p=z6u={6o*M3ffp! zmhyt0{Z1_vPNSb%p4XK)wq>6D>a1&d`%cWvLZ49I>Akeusa>Yz=P?`iapQA=8VA8p zWtA+oLg<F#(9=4$QNSld6`POAh%ODuJg_y)aWlA6=gOTsbaX$48-wFd1q;Br%4hxj z2EXxTq?CXozCkn>?khh!Tx?#W&{SK+aIY<FJSy`{vL<c}IDE-b01_oDj*wA#Lg4_c z=H4fm<vyfK|7D03gsnq+G_}qTl*K|d#6njh0Z78Mwv^Jrs|t=)Ag3-c?b7JX94Iik z5jj}y++l4cu{}Y7k^J-4{tQJXqjApZxUop3ogj1(Zj44LNsGs<>Yl)*kudeVuL-AC zuktgY%?GKxKF`@6zW<=$v59XE=(N~TN%TqYRD6L<jsy?8$Om5B&Gm`Lix{rX%%yj> ztEPH2rIkRvwuE@^oN1xf_OsG-waokTTGb7nw=;iF#NQuyCmft=fsOv4d9B;-w@X5W z*rBN;HmcYpJn>*v$0VncLA89tX=;=1;v`$AiRo5K`t=vmRN>LC-2RltQ!gsdz_uYb z$mJu$$(fsuzo2^`yY)GXe4rm}o8snXaC<=nY-}_gsjP4^1;;L|1z?n$Q(y{(5(&Xm z_yr7uZ4%sKNRwkf>j@z?Ipy(?&Y~19;Xn-6I~ubGF`~*G&RATssHLrMrn4)mKk^Vp z_X$ccgt&d_9n89ONYy%TuNYQ;>Ve4G|K+BZ(4m+omFt<HgYM0-CN8|2`L$l+eR6Va zCG)#t{`{wcF}+7rP+Z50p4;tl>NPM)ALkL4b&uZ5CTp}WUW$mu6jFcsAgbu(d=@vR zKMiXPg-cqJjPsEzam`JN8r@#H-?RA*tdBWGJ|C<kpLth=5&05Nb6a(^za%+j){4p* zv}c!IbKAGK2`FQlW_V1=wiR)C|I{lOv9hj8ehQ3>Wu2eL;WQ9Kf9@8%%wQnS6NsBj zW!5JE{y>l>2Q+p$^RcU|tA@-`G22VRb8sOGgF*@=(otOAalI=qqcv?{wlH}Q%q=9U z&`U7-9fN)9qBMgU7RjF)5MpE0`5iEYCOLcdqO^|dJl{Z6IVA4D{$@LyZ`5KtY4Cff zteCY5!k`9>!H)w36AXm>Q&o8ovV))e1ze746Ckp@Tpbsk6pc#g_5x=vtT36L;!gWh zK@lbdX$>Bk4&S)eScxjl`?48y>BYIMchVbH6pE|tm;YLS@e7TOR@Gv9U0ixfk+i2s zm{kcouM<S47iWQej#Jyo^;w4opp+vgv+<XeCv=ZVBIAXk{scuGg~F}pJ7b?_6iiMo zVj5e$f84hW>01wl?Q=0tu$n9cw#?swZon?x1@6l7g-UsTsm*}xc@&^EcvGhFNAGkw z$!vUxgUOls*vYLF2&yF7(xCd|zRE{Hn1q0Z2+uSm64fZdNRvg0U~>XzWI3R%B0d6) z6gCuky?f{H70ic*xTenmMsS#x!)#POUFN+Zm<E}YZk~FSisocz5B-(^t}F2N)+iwx z)qLBn7#T1HfkHJ5u1`WJViaG24iUGnSsxwqzreQz#NK15^2}RH(7?h?&!l=KuaT(h zAsZ?$I}|_GozUw~Nrxl6{Q0iqwx!^9{o9a%9};d=2h;gOoUlk!D_Vp6gFeG}2ic$> z<)m|$jZ}$cv!*{G^n>OyvA`PM$>{6__mhB>^abeTJ`V*4)tKSb*ju`Q7Xpe>Jepct zaro!on_*rEcx0+0Nj*1Y&koed+RmDflwF}F(?~2OAc9!jqr<kWbnJntq1KIK$_01V z(;k+FuqDuT{U#Mc91YSi-bkO)!H)+1;iFnFcsCIDJ9mJO&-)u6VXjlroe1^{s;2$@ zeeJ$#*wy`3V89v0>ArQ88-;R(z)^>a<%<*)iOy3rIBVc$h%PWrW+;`}+PS6nXHh_k zp1hH(x;lB4``-S(m}X%fDG{{2iSNIDJ#*Lx>LX0P^dc%UJRAwG@_tkX)5buJjAh8i z@$+dpReu*16C-?wBObCQ;X#5)P3GV4`X6GCKN!q-lawmRE<I@_6TD@kG=?-YY-h?^ zf-ViEX-!{618x@bno?zK7VXi?11D1FN6iz{GG0x`8H3FF_41xf$XHT}!_Hp3)mX4Z z%97vuj(VZ=gNWmR*pPhykJ$ZHTLE-4N4lH4%UfuWo0{w4=ch7F;YHWB5TeuRb(af| zj=Oam#)I8&1yBO_24KNA-*A3e#`ze~VZM{_h;H<(8am&8X7a8f^~yCN;`6Tp<I=;7 z_B)Nx@f~^c;GS|k-Q=Xj4$x_3OjRTA5wI<KW6bEjF9%hE7SM;~qIVW=M%Yq`&1lI` z#f7qId>|k%Ak=Blr2Pr)kPVC5i!n}6ha4oBAO{r*tbCl)hI3%}ao)bcSb=!5ZDiry z-UDE0Xdp<-E6Bwq=h(IjUC`!S9|fetfS~|VU}QLuWHu=M9Ndo%pjqC6^O0b(4_GYd zuDc-tSeL_m2rp}IU%+vwrVoF%EsRH%h9bmF?-xCQBN$^H&wU5ykDVXo7EGc4hEY2Y zSXThm)3xcqkOu80n4Tu3ndKAQK+=OpYCc$^z>I}`xbcUlQ^O9F#2Q<9`5!YKX<!5s z1`9;BHz_pbet3s}Zy7xQ?87kk3Ptz=TS_8lVAlzgmF0uI-&r`q!h-J`HQWWw@=Gdf zjRn@OlMdRATHIO+>SERoAM|3N*D7oAxNJv+b9L-&1dy+YO7<U)p<vQk&y=rGMPYP3 zZ&_PL#e{r&F_hrgdJFl)6Cp~Tdvk(JdrgKmwq@7Nl&cc_8k;eL%CJ_=#4jLxZN9Kh z&0BcZfZCg4M6|h`Yn53~x>Hhcc~tP^tOlH3&U9C`B~+EQ`f1sThEdEsQS~&=|Kv=y ze<1&<PCVj6tsfH;lc@loHa0pu{N}irCMe4J@s2j|+v711S7cir1}h_CRgmaZWC{`C zPYSI~OlH7@IXB-9!R1KUaN*u~5ORZ|s(}wHYamQj*PRcv2#A9ELQ0(YnIU}RVZeK# z9Df|f!C@VoSB8uau5feb!rW1z8;pC**B5_>s5OI||Fz1P|LiEi;4pydjm>j`l1Ka5 z_r1~Zw}NCIyBixdHrQSt&fyAG;Wi1$4Z-l>MK=mLFG^m#wUNi<gF^$F;d=2PAul7L zw)m)GwyV5}sP*xmK5A_k+{C3=mYuY6F%c;-J9Fa>`;ZFczbeOOsh%?Q)03uq-E1=Y zrl&?X_|EBmJHKYsu{$;ODJyNx4{Nad8TceAxWRKqmHmaq9i2<Si(u|Fa*(@-xj4rG z)j#>b<?LWCE0%n~l$0K1n|lLWsuttAKryHtf7kuaqC!`pcWqrH5V=>N6vLJXv&-iE zko==X=FDE!x4pHMt{*90ULO_F0)ubB7)N=5i*VjvVtj0D2PW3(LJEOyhCw#($>Yb5 z!^%jd@|cP-K1t4i-7vf4@ecV_-g<c<gcW=a96*Z@6$}HZ1Z97oJTcFMat-mTSMSbW z-2$RQF8bCtbACwu8p&2u0IeEJ?}~QpgL81)z|Q(@Jv+}9@&NMaQlcjTOnJiC03(mV z>3_*5&l~>COeq>rD(m>NRl*Bjw*JG;%-<_z$|t=2z0Y^07w4>4B8{k&`K3pJ>zlP9 zq<ue|tSC*hxOOHqMAw<KNRVj}2lCWYOeKx(#W)>iZ*7N<?OO5SN;YCSTN>szS`XFL z4IL<?A$pF*C_>klE$9h1g&mg^s1j`^hAJw}d%h!^c2OZVkS+zXec6_K6fiBJp^92_ z4|6xcaS1CNQn7vm5RZvz-5sa8bO||f4y+qs+cL^8O}PR_7>+mXoyz;}M}S9xp$~8p z3BFj+0x{=~R_@ue$PsnFe<s1soOwL4KkWVc^XJc7gU_Pc>GB`g^YO%WXmdbMa=H#K zO`zo=d1x5a14FPREcC(0L)btfTBS$*`Si<Fq$xr^tq7xhuGdB2xGsCc$?Dc+_><vB zspVzkg(HstBk=yT|5v<^d?u)A&PAq7W7SbQE+%j}NV>Z?<hFHZ5BPWi5aDEF8@>CF z49t7w9}V~`1*9VUY-(z%_D)NiM&dNX!)vbn;rWg{r~3Cd7y0@5y?pr+@(hr4T_iaS z7A90`dMc{gkbl1LIqY(f`Sj=d;V&;K{^wu+U)&9+OpN4zMd<vGe*b@<U*Yb#2u(%1 zYxuePz~l<mv#oEVYK>J&x4z?D%<jvnJXW3=Mx9_;jEq)nVTy3bDZf?m(^jl<@7MZw z{UphxCzR?;o7<?<$QpT|584O7z9*u2(x!q}pPP`4a1d|xA+Uh##E0~ZpV#*b$E*1c zH~yvYZx{Cjk@vuVjP*;+^?=yfY>h&yU{D-;QT%$}|5BI&f$4BR_#4nWgl_OB?y_v> zGm1JrEuVyGs)A;*a`)Y$-fG|)Uj@%lq?MF7fqx7p!FHj{pCqN_g_(MwiEY%59C>~X z5=kJbng`}RAl#A+mObRtA$GY*FR;%-9U6gCx$4fpBxXgNxxyT$v+A2(Ab2LLa$R-~ zuD`aqo*27h_(~oA*GX)UmBQlWefx~(i`nTpt}<qhdzZg7{(3oBsw!lzjd|C=%)R)C zL5!+yp+fQ3vrkjI>#khXZsoTgZhntSd;3EuJVf1`o<bwLzqCFtY4)OhE)co<1=~7m zQYjq*WfN+tP9mNIYxXDqRICU3ZbiIuI`Y1hZO5)us!sq?<&99gK;~uDRdiqln`{81 z=3y~aWudPooM2iyeH=*^G&RlC!y%+E4;)u9zvy|HStj~wkvKT~B^q=OK)V^^M2?~0 zv?B+tmuUkzykI(P#{kYgum>eZ)WU6dz8GRj=oycA@<ZU?0fhI9Z%>55v`^4UjmKih z=Zp7K8H8*NoSjSGP<QwAyqIYxbadDOcA|fHB-7&Bc5>iact*`VTzNa~g@BgcxEz!I zyssSGR^ylE$uC`0VIOW9_o1{<5+11QK~dOq587PI9S^rw{}nH!P!U;^$sO}M(e(1~ z*u@@losRRQj?v~j1`5p|`OYl<2##EyKy`fo#6yA?<q{2LQ$1K1{CzZQ+?C6Bo_Bpz zT(Fggvv7ULNV4JkjHJ9C<0Ax8CEo^5#rF%S@1=M2=T7<&$D5;5%^w6(iiwFKJXAHN z#;?lL?jr6w!@I4mEzpsCBnDxq7p7|99TGCAKfl}qn=0$O(_a%?fO4$iyCor!`016z zAkw>@LBu6UP1*n%43u#=xbB_W7DQ_Ix$0S1WMgp@sAE4H*h{%XGkp&-$o%F@wXVi0 z=CXvF#TJPRrtN-6XXIxpOy9KS%PEI{S+GlHXVk=&%-Ao)Pe{22_sZnEJ(10Jc<q_# zq>^iBQ@402jas8di4fsHo!nG=5P3bZP<GK{n@?S|jQGIuo_e;Hj+R2%fkA7N(svNG zK-gf*NmtQj`g=@4Gi*FRt2186{?k%?X<Kss_>e)FJJp+NDInafT7BF+JwTK+8EW{D zw)lYs*|upROAk>}KOlAx+dp;?F)=VDn)_cs9kgnAAdYs)mgxg`W-F&q*hlL+I`Tn3 z0H{IKwS#tPEF6Zy$5@YUDP2Q9Xj0J8IcS&Wc6M<=js=*HR#R1lfEhuXWUyy9O@dU6 znEY~ebpd^!VsyJYy9&grIjL?U^k*(DEXhQVigBLB*1(+H;sctjzsNC!j#Ncz-Mn4J zzrPE(xnnX)yMMpSFA`;y4yP%d40(RF@ay$RZt_MROR5qy>)AaQetGSK;qvFuL%c6M zQ|NHgGc`IOv&ZdvdHIz<%bjA`O}GvDWS?`zL+0U6w9>I3Qre{cZ})-z%n0#eDl0?a z71Az#v>UK;7VlKAqxa$q_tY-PCkF(O*ywNqtld<GbkEB)>yUmte)nI${pj>GOKUA? z*+WV&ei#st*~$m<+LXy#wF@u5Sv8-c>58!)Z<YyqiRZXAE3d(1eFu$&`r_&s4$tHl z(Mj5(;!P-u;ii9*FQu*C-RB`{mqRRzHor6Y>%(KN+G3K}lU23XEjM-b8FFcwJ3a%= zQBT^V%eB=slBC+IR!k~4r<8pQwSBl;8xLZUa&68~ci+FrYeK~1=G5;~W^$-6bER6h z>~w2isw|ItNcS;>da{(Zo7zeCA3P(ySM1Lxo0Xl<P^rGwl-sZ$SvOL;`S{)J?3u|p zxoNp2`T45r9&=V~vv2IU9z<!xSxdZ4DLM$xFfh5>Enr6R&_ecL-CRfGl_U%@<F_hb zS4&NN%gD};RPLTHk6x^};qWzcD`uC6OozLGS}m1IjX%EiN+F-~FXEPX)A%FvN`Xb| z+IZIpbe8v&u>Pkz>$>;`=PszMTXRni2U1-t(`^5yKxLY(=@Q{ei@hfNZ5p!7h{1!b zv{hmbJC*i@&G6F))GN%3QoA1d?V<WHM~nUJ;@-=s_H-r&vunTLnXcp9^yrN);Ju2v z-hvehp!7$X9>4ED#n`X~KQN{rGkv|u4>fB(%QYrw5Y?%c9ot*;ql!6rm(y^dwESny z+3K(s)2^JF$QGgS+nCjg(OC+Xt+X78m>c3e&+nPC)3>DkewILp^?PV8TkD7TV~|4y z4(4Il0P*5*u(9<4lm_z!wDCw2Bp<_L2&Q8pAxrX4FuI8cr^AIC58al&odUEy38w9_ z@o_$5+!z>D;3Nw^IBFRw{xHu5-d5;s@jOtwH(*t*uUEjlU@C~|+M3`xhS&xKvI797 z7qtHR?E#p5_`qrdXOYZzr2RnhM<G-Vc&W~A;^N=PFk$c8=ixB(-Vcnl1OR(D#lXeY z752*>>q#)mgIfTC*WAGM1F`%<df(r|k3Mh3!0h#Fa1zMC5mlhMNbD_D1KC$yy-rQx zPq@Be3>3v!6<jCm&-<{wKqn^(Er_e<)vPWT*qLFL8FsE>B!U>+KE^GvDI4Y#5a8Om zE`TBT0?!rL+(4RGpXopXLS{jmd3%NeoWSOjsMXs`pf*mcfFWT%9~j(~wKX@$-T(dS z>_-}~_xdjS;~~FoXXpL<_YhS^cKOyb@VX=8m>o1Q!Um!E&w!Z$B9aEu&!MyGGasyh z1O@>}BSvmML?{3|#t28>0IMP`O&WU$2g$*i+Bc*;z+C_h8950IlRB&6BtR+8&CSIc zL7YPk488CNvvF|1-Gt+6I(FcERS@nVL<)j+XBxH299w#NHeqUHEN%_P2Vousrr@f^ zW0sD@11sYS<??r1^->>l<Kds-#1O9AaV@&yQX~!wF4)WT^c-@#J1*lVmqBZVUkr)1 zR}~{WdsYK7M7B5<hst_}|C;CWFoG#hh&w1Y@4J3Lcjby0{EqkDob=5sb4r8P0Un<{ z@IQ$03EnQkj~_pVwx4QOx%f1$0=)&tkc+_k1$SU;dmG$X&tsvloS2<;g<Q6QC>T?B zhpium+ofT!3}8kn3^0N!-)dSwPoONsJZ*U*(h(rBs7m|rZlLq6n30wmKfnk_lOzM5 zmkQG<;5l!4{xEz)bKt1cJVF)fIhJ!^?5bU%QeaOoioH@EQgF<l6|FR|6o>nWMRR22 z76W*KuaHf%^XzxCLTZlOl%P&r<B*!oegnP2f!60RnVgb5xwWhG1<dyj+O_w8O`Z`_ z+0ZGOGLZYhgnQE?`k`f6L#wo-kK*rSDFiu`-t7KDuyVH!x~!=J1%+}Mis$VC#e_VH zgn#sDtsC?b$1EvP*?#>&{@b}S=ZZP`omFEOs7Qo3=b^qqVW?D(yLzrk^V!)((>k%s zavGapepMWw^5*2oy@KbuS6l>CnAJ$u7f6Czuk`45lNXN*wc55-|1e)v^L#urqAq{_ z%BbEfMN<|ry^*(xCd<QJBRlrcOVq&>v%K}}Ucf@<MV9FWI43WK&plGWJo(ViyDtqs zUH;;8zh%~HfKM2I*A-O*$`Qsd{l5a6#ov1@xquw)#F?`PxC*}#pXxokK-b8XaY24a z1{;kN7;>bb*jH)^4l+~FQr}!}{Hyv+>8LVSn%23CGmDO}&xITW_QnQKO2FZCpmX|q z7Mpenb8yITLU30(IO`xU+R`=39_khO72%1Ugtu?smT&Z%;UmC1@X%thgWw1D1=~7h ztMcWCKw)awf|5O!0d9kN&{V)`gpVqR^M^otEpm;3_<8Uj_F0Z)<yN-y8MuKlX)MFX z#|IWEQTJzN7tlEtS*4(DmCiRFZWLF|Ln64&p8=4zEE#y`gd7~mt1#dNnjCxw$tqyv z>x}S(g>TRK049~FsUePXaH(h$PCt{g7<IT+ob2z)O8Wv%lrb+Ug#*GuQ+ti3$H&KK zX0`#M(1^Rjxh6JCG|!ITy>phFoVq6xawMVR%;apqDyxL|8~$cqMFv0rA!@V!y)INj zB%g1z_#s$T>;+^X-vVGv?U&H^FfG@JcwCB3^cR?X%1SJUlkJNP;V8arDkPI(D+h+p zkz&I!V>$Oqq7*uwVSv(b@|gDz<V>Q3gamMG*nByuaLP^$4bxdwf~tlu)4())KJgP2 z@+L2^y+EZc*q`IjDOXE8U$PfNdgjbBls!0^gI9JJ4p0Cc;3DCH;W}_NFrZSP{RE85 z5Z<lj9A~L5#w*+O<43W3Fn9UVckmQ|P-e7igiN0IK(YS;rS2^S9cLZ4M?*42+`RTy zY^wWg93ZkC^O@=qLesH)08K!_3nWjP))Bnh?&bS2nnZ=g&ksk_WXwt%OYw;W_VLP| z^EEwv$j;E5eL1Y{=VT5()ua2UJ4GKrRMHMvP0)8RnD07GV_Kywj>|Y1+{))cQ{04> zL5v#D;bZSv&ziAD;pNPuS!1M!K|x(Tngq*S=Ua)%ur|1@lt9<sPLc0=?)eX<fiKf9 zN)cp5nlbgR>L6NE(9PpiAPy%q)-pet9=pVs=(B}oFCJESVmS2Z9EPN)+r+e_<P>P! z_OtF8xa7;l{TppIQd@mK?{xXcG&mTb?W@#cI2`@{$kDdG|1aY0oL+187u~Py2OjnG zDI}BKtn%iQUG3|5YO*vO;_^#F&swd)?;}>g_yG{4!-<TX#?svkHGU#o6QpkMHyjcv zm|Reiv1StLolA8)CaV?NQ7iH>Qs~6`NY9;h%hqQfG@e~>9e^wN9B<;9d+DzsE*+<v zO4udvaDoUv8YhXl`r4|Sc}urmghB_uEwhm3ug}=|gCW5LJidh-t)NUz=9Q?h<iWRk zh{bIVdEcao%H#{UW=2utLUpBugba1YmwmnJeb4MYH3oY0cl91cddA^;7+qWfa1sb% zR&>12-)~vLuHN|<3}%+-*OBoZn**c)W?$gCQPf=Eu#Xt>@%2?0IDkbU3cCY%@-)Hh z@kv>q06R1U`9I}=xP4<7O5%eKs&8xwUZ<>V61YTAH=d_C!G;M(X25WjKxrGmix?SZ zhg=w!tSB!xkP-&7AmmqwLMxAX0t=~=|1=HCugDu5V<fb^>7eeKHhqT#h^~Fa)i<ex zoD&B}=fDzFvI*XX5(3F{u$SL8N*-fHy!f^aFmq`jafb#4r^4kQKS^@l${AQipo*jD z=6@!=5&oqKbH&x@A#^qZV+`uw!xc5GAV)14djVCxE(YUD;UYJN58!(y=r-5Z<_3zn zd)`bj$swmr(u%w8Zdlk%KqPSu?$}Q)11zhh^)@790pEb=&#-a&Oach{8*w^<=n6d~ z17wkcw{{G}w2-f$IypbjS(yZOieflE34j4Y;esXmg4ZdM%S(?Rv}HzY(XOwqihvCh zWI?c7bF<SS2RZ(ZF4U{`22#DT@dt9uA<Wbw(PZmzi#4%n;3Wd4<1|14h)+rv1?Vva zb7gs-11JHLaaJ(`b_3S8LFh;i9GC^xBpNa{J^naJ&Q7o#4XL%6^H;&a3{ZgJf(qQx z0d_yZz~$%Xt)~DHL^Wzys1`bvZq6`~3khNXYPjWGhqUb%+>OM<Aoj)!B**QhF~Dc% zNJ(3M{GfL2g`rD8b}%UhIZ)4Gnl-t91ilf@Gf1=QSQoqC=~X=JBJI|UOxgh)g$fH~ zeG&{*LTP$kax5MELN++;Dmma*P%^=O15h)(s~;kktt~%!3EC9b=q%#*PTlxuDYUwj zzyLucgh&((BSY!(W8=D)nuNSSUiR^j)L#G`pkqqp3Ub)vg3<6hn}$x#anM0K*Ae!@ zUPv>~%TQdA)=9XSFna$TRWXLpNc48Hnp`$lB|8Xw>#gIRM^jpojON!pEZ81~9-W#+ zFkCiPEUG5q40m=xN!y!ATbaKjow;+9)cJ}(kIGlgYYlhU7g78%v&@xgd=VFX<j!%f zIn?H(lUA_RZz}7()@tcJAVTC~q{i|y0R^e%H>`gnH^bYCnZCfin11Mq7v#U0soYV3 zlae4DpvI0{Qr8))o_H7Glkt+E|D~ODkkX97o{~CaV&naukNxWU+ZCZx>%}ScYHdTC zDYbrpW`>)_0KdRbU8z#SZtM_of@q!1Q`t}6$0RpbtVo;HsP&Frm^ONOmhHDAPOxbD z6NAS$U3pgOa}I^c*wEeN4k9^S*u?z{C_iE=bUj%itL-nnU$v5Jp_F@+v=nytYi}x? zd(!Yizx-!ISvzbBfRV_3T|NsdK1HL-Ze_y5le7Sp50hiG9+aKAyFOl=<|h}HmvdEL z^0wlug_9|yX|@C<5ib6}PCAn}GL{_Fm)#l3rDj>}5E%SM(Ol(zLtpZ61MmnJTIR`< zkfdLTGsd5$)(<kTkrzZw+-d1oUY_@lj|5D}{yFd_=!*yh1a+B0TN7M<POU<92QUN# zc0VmEYe<8sPc|wfg{jsR`X9^^Yg_NNQ^H}m<mc{BU1vZGl=cq6^Lv30UWy~}mfq{R zbO=OXdHC_7#izV40SIvfNBA){YG!vs{B!*}q>xUH@;#bqD=}=MqUnJ{C>l$YsS%;w z=TjTrAr4;R2EF^R-cjRsJrBL*vUt#!ELeehT*<vrb{}9pY|W}Ux(s*-Ap;ueQRE0r zYH)Z$I*s$7xxQra##4SeIO0Wez8MFul~N(?TqRxw_&P#b*HYi-&o^y)ft3+NABpu3 zpwuih%`PkV2~tm{E}Xl^S}6wh{<)c%KFAm^{es2H41NYHR@Oibbee?CvOONk3-^Ir zb@(I<$xUixoFCErB-3aP4vtI3Rn74tsuewr=KP1Cl~9bl<l(!78-p`8A<uLc$~^$T zfq<#NDL%;1v`L1;U<dBqexWZp|LxgHD9Fi#<ikP~dj)hwJu3Z>dyyM-#k5cZ7#?m% z`5-c4w=o*}fPo@74r3KjRDXRvDm4Cbub27e&ENh0gdr>M<11N%{S>kt5IBzVhyYzm zk`uCURW4)@F_O0f$~BrIdd^=cDY6`5W@GcUyUcknB}I?5mCbc6-hT3QIx%}25+5`< zRdusvmcaDC<Z1BUAY{*%ZegEWG*sXB!pw(MdoqmV0Ghk+xNYD$?Gs>92bQ5NPSTrP z=)SpqYTp;iwuH4)LRpES!(Pnja$(N<S17IaHp1txZR@cGU9T+<ebgTV!)=Fp`t3Vm zLaLai4-W(2#fExv66<l3oeK0!sycDm2<ks`QB)4=XzeO7p|cog746MaVto>tv}v`J zDx0%lAYn^z0gE_2MuA#>XYPsWuB@&vxHa61cyqu6EAq@icK?e5c^IKuz+Y?dP|<FF zwu4c}@$WE(7zG)(`56r1VL3M+dhhu?83jVM7<X3Yd`f_?%bpz0No3_ITzRsxa~idN zBM=-n8Pa5!lnrS+ZiX09m9FO+uZA<;(pWUKfhytkh{r<rx*56cEgPZxivT}}QHCyU z?l{|l%!pKzQYOAJGmk+lHm(H=Ma#mHKI1|Kf}~t9w$^Wz%-CmesEGI!t+LxX_<a2i z3`&59k%r9WYU?okgYT+3!`T5H-!$12iNn~riW?Dj*py!IEZ6$c9rpWV&tM?M2ys!2 zC(q4!pRE8Ft@S`|+BA&P8Hn_JoHJbl94j*X4$gRLxZL1)_0z|XS0N^kg=HF<8Q{E% zr^9!>R}AX;T<Zr%akX2F0o|~o-gn6slzZF+3>@^34yh|E-*mZM1eU|13-xL^_$vIv zW&jcXX$IU7s=tC9&SInPup1U1&zY#AFWF~w+w;I}NE(O*j_LYKp64J59dw7BJ+NO~ zONbS)N>B@pjb#^>g7pg<p}J}%sLyzV&Rb}EGjhXKFjRPCMgqEzk?=eKaul&<z}w4p zrsXk7f|20gnW<p&H5uc!1uH=i<x8WiY6;-Pckeg+U+jJ5Ule%Mue){t1|_K?Awx(v z=u#pj0z-og-Ca_vC>_!b3J6GdhcXO}NH-(h-F?rv&+`}D7x&Hevo98fVd59(e9t$! z2g@x0(gJdzd)0HXu0#R)2B}e9@vdYM)*J2SuXh4*1r*CDxa1uJ@(jBhGR<RsEPTO* z3z*fuFN5>Q9@OcJJJWzw0+O&brB?0XI|<;(-TM*qHYDx~OgF*BV`@bR>_Mso!NOu^ zpcY)2j$+-RUFti&kOt6{#F*BgZ&!{lk@zY<_g-l5OT7LAWbO>XJrj^&g3&o7>E=%J zEDR*+8yN*yc7hhbaidqN$-n3ZGqwW41*CV_PT{%n1$F=9EAU&O%lB93MOukx{dk3j z<cO+%+tOK?B;U5a22{e+P}JF$S<#VgcRE?p+>BY@^PGe2{43+puFQT8PgB!gHu>XI zEmM_jUH0L!Kdm8~@0p=2bwGCCW$=~>ziXG}wwE^ga~U_H0d(CdEXYTQAuAKmyk<w^ zXLs1B>J`mnUJ^%eb>vqbcPr?IOfa#Vzwu1LF<LeYV_X?TYZp5BH#Yp~GCa5vPL&gR zUpeZj=wSdVr>xP(_W$jwa|Pun>LP`Qk0^9+5jHhdI?T07u}u6pi>D&Rg*0zGeyt}i z5})+j$C9wkNc^#0si{?0@N14f8XkZ4fOSPPld7>WG6jLniO?)={1*F8?NU*DnFt<Q zKh;9CzT!)dQuUP$FRNFsr*}vwI|)xwS~Yf(6Y~aEF(0p=eXCL}Y)(-Hz}jkl8?QaU zvO;u_c44BT_BeOuI_uIUI8JPA>qJD3H1*Zog`DKe-+0>R;LLq+!J9k>F}gVn%^REv zqHLU;N{*_17;}DT{O-}>)H0(+xyWn^JZ1REN);xAa&KI__RGMQ9q9%EV7Htk=t7~y zCX#M+Z-ep=y!;B7fp)4i&eE#d?Wld9&p-=q3{2S2kgALIt>((G&|ES^8@?xa=a#XC zdUCPR#gielE3BWN>)CGUYsoMGv;iuh)i%Y~uc3msU-<QqFET<mXJLS<%}^7_N6^;u z2?}c7lJaSmO!$iSAt#7o(!&7KW|wn;ljJ^P>FCtB&0W0ec?)&Zg`}j*m+?f#fC9=y z9IzT)(Qg`AyE<DQ0%#qD)%Ok8y-;p30qEi`+W>jaJO3`WPX|I_5AwmC>&e2u>Df6s zV1J&HFgm(ePz6RqT(ZmX+(<)JwQzSg+h3J|^Oz)v?d0)B+!?<CZx|xI*>RZzp(j3S zEtj4IRcUZwpm`&kc}G8*!K+WK@5uP0PVnETe36ueTSt(L+wFCqx$)zI_Z4M_Buc)& zv+`>DptH=LWqeYuZr&bYiX1Hx)*w?c&0B@hA}|O?s=PzIV~jUW54+_=5cnv}Jtyf~ zdrPmpb(agff0(FlA8)4ut(e1YrLJ#dLVm(Q07<wyU!|(Rke4H1z!+=Ckh)*QyIKAz z1O`dpC{>jDxpoJq+f@=<&I~Qyv&5``kc6ixC*5RJbPJ;-Yua^Rwzn<Ilyaxk8Ok|e zSReXTi_c6)>xB1fkUBCHU))o_d)zs4Y4@Q-Bq6~to^%kA)#C-$^d<8EfZUJNx4gb& zLj8Oi#p9-MC`{U*u<vYSiGE`YV0_C*m<5c~HG8yAJAg1_BAN^#F_eac3Gr<4MQVF0 zm1!vlZHaZtZ!mahTXDntUI>LCpa%hRM^#BK?1J%S0-e?@5^R5EtQat$pwivxl?@O{ z@alUtQAs10@hP(h=w743`pF_}X{OM6?@jcTeR2cWttuVXB|Ohj`>u_kTiW3dERnCX zQQ8wBfmgE`xdwsqYsnedv@v?<rpC3%FJRj9vqUKR=2UU^fkW@q$rrEBOL2!d=Hu!K z6b!@W#QUrOx{`4ZspTU1l1y<41Mas)%An>0oXJG>H=OG|2F}o-M53cu${$vd_}*5C zh%QX2%?n2$b3PqLsXjV#@S7kii@)tv4AU+^&q7ja0*N3@z$o8B3AWtLIUi~dV>jZ1 z<7E^Eaus65Sa`N@qJqC+fH+7MMAXms;3LkP110YA0xw)$1D;p4E6{-TGo<(ir~gyH zx`XG^qo(Fbu)Evd*`a`jeX`ik&u@wVoDlE8g);XDmTcR1aH3rq4}8RN<vt<{xGzBO z*#c4`ux^w+Dl?Z`J39fC%jVbEfPn(cJ7@o04Jmm@hVd^-;(#99Poj}%7g7WXXAN+s zoek8KowSc1&j7>icE$jt)>vG9Qrcgkic^WA%4~Np5vxsu4c1H;2>dk1t{ESEIRGgj zCJ)jzDvx6$sSlwi933ZzloB^77)Q{{#@T}j3AEM{6t6Q}A2m(jV!2myp9cmp>4__R zbNocMHe4)e{)mGkT#=0VxoocTt)aQ%`N`<~3XTbGiyn;sTA8Lv99^7-L3?gYqUn#x zTe7{4fr9Kdgr^Vid>-}ckgqoT-&wq(h2I$Glj}r-v^TI6uk230_1-kIL(`R|sKZFU ziXzi$s7eg|u1zUw<VawjG5WG$t%!(vP1bP&1D|tzx(U(@ot%2^f1n{nROJ)XzYKEE zukzBPTz@2{YA}k6bH>x8WNkhnY<w`7Cuq24MoRZj5Rn7+8K7k_`4={e$!<L~fkKgl ziw&%D_&dH?uIcE02)pJ_k$GnwHdwJaKjpxH+H5gMKqCehxajR>1bT!(YF4@YS~!xl zTs3z@>|AMcuuC!hA3{gOU&UU{1rB(nSMMN#%N7*{*2)Rd6$(}E`Twk*IJGIED!$x_ zCl{VWebT*(AWWqN1&MHW8)myWeIV;eAxg%3{2M>UrDCZOU5K)L9Fg7ozAe7sgms25 z_w(<4J2z(<J<K$kypRj6s-SqZR0~0mhQ-6&$Uw-?xgS=0>BSy9r}=|VjlNR&>d&Cg z$_O9=PW{s2dmK4S=KwS{V6#6-2a}3?@(iV0MN1J0!3rR7y!ZkH|F$PxfMAfVb%B@< z&Inc2m<*8Ysig{$Ax6qjL+}m1)Jr#8{u+hWRfv#T0QemDXk-_0W3MursT9A)H)Swk z=5pf(haU<zhb@H*#wmt@L<mMkpmKet`wQ+X7=z_deACd92fZ6e+d(p#nN50&T3B<C zujeT;VwWOAjD+D1B1`DtT{?tDMJh%*E%iz92!6W=!pKg;;utn9$8sV)(uJn}U+$k* zz`Zo3I$7;76at-iOz#yO9UitSu=Vk^02fiq#Vc>U6#_1e1jOpIfG`SR<D74)Q^x1? zvHaGdGh@ESYmQbOfrP8lBVKo2c^2M(4sBu8sO?vik+^WarJ<}8fz%iZQ}I_(afN<A z6s+j@sXz2S2TrPn#jm6dXO#G`eAA--r-sf(Z%0h=ov$osU)lZF+A9-aP-?%a4D6C3 zJk8*n-~<Rrgvyy?8O@2%mp?4UguJH6>{PEkRSL8Czq9<t0bh`?tTbAGXvG~`h@+{D z3Y7Gb(&Q^q-vmU}fFNtlj?B{3jtpTbuwSq|860rs`8dqUp#=G}LM`fJ8JP)=)#{Gl zG?RH;j4=zrKG_=%Kl^g`8#n5PlyO|yqJ5q(c7{?W>mET9#gIL}lg5j>S|7o=sblB0 zho?%nIrh>)Uni_dI$dIUC(&eples)?&Rp!<swn<jmbwNQ!<3dcK-tu%%C`PohSy!E z%8RFn`EmV{M{PRTO*RQddzD%7rPkvy=9kQ=8h3ZN-$!lS*gP=V7UJ8vboK^@6@f%F zr?75a3sFE8g*Dlzc$1i^AczP;y=JX!UG1*b0{EWt9VS{7D`@Z(6Dx$I<@>}joF-u` zf1*1uVSu9bG=BlxLeOYAcnL_sflP84fVm9rHfK1>LAH!Pz^Y*ZN&+Vc8mri!38j&= zFHBjH8c3HVZ?;nVPyqlm@P2<8cmxkO`LC^gi3krb2C5O5gtSnobDxdiWBt=_Czs;p zup7ewt@+YW1NRUI8^$4!Ow7#gU_j8=X9kI@{Y(AXu*g6<2qqJhIT>YTd%!RU?Cbbw zIe+%S4T}-Mty2^!!qCX5ods2g@2CFBmk8Q&i?b=?st+G7-T4A3k#Avlp=1<DxLCj% z4fNM0rn0JI7kSKwo|ei0vI_U!F;GblL_=d@7S@cA9y637>J<0xf$8-e%wNC2+^49i z0-QgZtvYjs?nD0*^SFOvM68Ta4+HXCxZdhEo5=UtlEL`U{L!OF@9oH$8*|gV-Ii@- zV$%cvH5GWD$%3>mpMBX|k{QU@t;uv0>uZ94v)znKwwgkbZvCe`a{=_rRh|B}Uv;xS zf>mR>pU1n}XiO#htsxlGqh|g1lwpLU(#IkkRe7LlsQ)(7OXcf~Mq{?&ibaJ?u1IY0 zf$E%8>ZCSpcBwA5&rz;>Ygo7FTW_B=+J_g9!v2$U(VtA9VKJjPgLM-qr$>va7jH1P z{-DxYZ)VoR1S{TJW7-}LXHjvUPx7F<Fno0kAarz-_m2hO63r?*l!dfi)ggu6wJh;w zfA+k9U5fqxls8#=!8bRDmGS4CBB0z~uZuVbI+BmjyygL&mo;6@Bmt#$_0WVG^NloO zRZTV6nIx3`<plwstI+!4wQ{bux3ygE^3OT3bips&irC;6C?@q6C<6&)scE8-*wC`O znRJtX^FKlDMuG?WmwouMOh3>eTQrg>R9<czfBW_eSYYKGnA~%XY?F?$5s)Xy#y&{{ zVZN={tNRG`+yQ{G{XTm4CS(>ySr$DywTd)o*KbeMeFwv208#i17XfY3a*1b0mN+2_ zDgL$xM^ltvjf>i?i^~z9J_EScUV7zJOFsuPW@%h^m6dqUHLA%GEa2Uae`H!+26QQa zaBwINE=Q|g+yW);wEydsoZL@vaBEz64aYH*@$+H70%vrFtpn>|zwwdU-o8MVQ3)7M z_NHBzkP~Rs1_x6aSy;4-4P_zu911Pqc<&Y9bu%DK)N^tE9YE*>q!<QPkC2=Rv}D%# z<8=H-5UGAQ)g4^D+sC89TG*Vl<g+qD!RlloH3U|*L+xW90%}X%(=QLpg^RanbW|5! zYjnbs0sMGlDLcRFu0&NSeG2~$wEd*`eDTrI8Sxr6fc#BWC@bH;dJ%9vbJQ-Wu_L?P zUA!#Rr9NN^*{2Sha6>7^tTIK5vQ6Qb{0g&JfK6DVF@710S<C!#*F7E7#el8_ts@to zUCwNyKW;dkl>CD6Th2Wie_WZs-ZH|!oZb6Kb8&@1;xCGl^e@dBq{;GUgH*%13MXpq z*<_Ay&O&chGjkB|&+y9eClmfR*t##ik5vfEg{NUof0OW0Pe)Nq0)t!|YwqEyTb*-D zK<TuqLdQdTs<PU~K0hiFYCDIVLsysnE#-Xq5QhA>j~7Ev+xq|aG}kFQYDAk5&Qr(? zaxyc0we2V)+^o2J+)_iiwRU$jFR0+yi?NrfZaeDga3a?aw|Z?zIxhFe%Vq_B4>471 z#J7T4RR!eB##gt>ymRHjQ^URFK@%p?Nt2{dy%Z=({i+JCzc2&Z%!~_;n+-Iv0xX>N zLf}G9;iznM?A4XHpnd<YGBBOm&)@&Ju=eDze=0Z)BN@B$WwzwI1#~#Kup<?+AezcW zF2fw;8@bsFoWmYutt&F^Y;G26ZR3_#F-$Y<YY2*rCICNt<0^og&CWayX8+HpVBDOZ z9qM76(;h@E>MMQ@B*I%K%*)MnUo9PMEQZV})FcG&V8Wmh8C|o3V7Q?V=1JBFWQ6;J zTh+D@xs0oPpwF`7&Rl^q2gBkQOE?}x1e0W@bM5~ABWgXbD|mOiATUUZsW6CWd>jqi z1){^=f~5^^o(lu1GK6F=c-<;c3;_x{Dva1VhSuEY;^ohL2(C^-ga=eLRd0P)%e__Q zK_UXCpn&8+Ce$m3XuZdTL|mMH;A}nOWiqpZm+S%fD3~KbIq!dd7m=a{`2y}BXhd;3 zyZBdq?Ji8o84XzTMupk3t@yx8eiZ67(0_l-3^$m99|QO)K&A35wx6QOADmy~IE;cP zudQy;y+Hd1%?u=g{y~!o;`R!dS?Sq76{2t{d0TK0V-@!-X)m2Y5OPnsp*U2im}{Ae zduhYOFx!XH`?~bSA~E#07`Yb~q4zB8oz|57{XUqx+LM~{fh=BG3tF^COeKB%aq7mi zo8H{|4iSSO9>Ms&-Q9I`6##l?fX!9Rhlmj`rfqP%N$JfHLe17veW<vaN5UWD@%obx zkGaNrve=*Xe+9_LsMkn7rNxg6?5-bkkroF>VrmBmi9RN>x-PjfKa^$eF`xyT;qHg8 z@Kgz39m{FSGpNubWqxKmp2~iU#bUX~!%vs(q)o-%q=IB{v#w9pKIY^Fbu*&SAYaCn zHz6km%aUIrk*FtsiuCPtBQ*^^W&TJOsCe0+l$yzR6NtJeW<_3L>HOpKMlzHCx1!4Y zm-wNK&2*(C2zYZ`nFET;sn`fofU&o4paRb4{Ti4d{8N?2(TNS(<DXfDDMK$ol=gw* z)Z+P~_&(;4PLeaS5Wf9MpW(vcYrEWvc$0-H@6qVSk|9=kwiwsp*BY$C-t~z_Q(aLr z9i%+$7!EzMTFR?9&rHaSta4fJqn?3zS@^y1g`z_6LgM>-2}%UYbx|N7%It!{bjr^@ zu*+n=$jpTV>mHbyRH;^gjirMHj+!w+2-(qvuY!mG$=6Ujd@*?V2M&b^Z+!gdQ+!9r z@$%(><DHy@BqK`x#S3SMYsW~Zq>`@@+8}TyuF%Hbz9|AD)uJNFx(I`PS*@G};5p7y z_SNd+gl&72-4WB4Igp<CWc@(9#5h!4Rjx8)Z=5rbXnaHze1i)0VLV!8uFCz3H)iNc zkoEbQJDc5W=nWnAf457NK%SxX=L?*vbN)n_p_MYNCD7qxQzZ!$RL9CvOh#Z7VPN&b z3mD_Rtob7&-s**cL<W?fzchL5WRh}qb0>in0Fh``+vX?`sF`3G`z1THD*H)c%8Nze zgWq1TUCBJ&12sGe1eE|o;k<)AUkwiUzmu4~c5dlzNZII*V`(}3GpcbN;utX5z)hR} z?Os_*4}q$voWT&0GgYU0JxECaDql(f5k!|`UFIp_p<s?PBzNnfCrhgi?X#N?FQx%k zeoDelYu(pdCmpU37)vw&A#sZP^s*0!Sh@IN-%>aq+$0Y4cKltw&YkoP69>9SFaHVf z1AuDO;fYSLo{AxN%VExdPwZ5P29@6xZo!zpJD&59cSkD;S$-in>TxUP{xNYUpp!G; z>FY92d`-&y^uRs0N*o=a&&B)sU_U+npN94M_gs_;ok1iA3EiC1H^rxW8dM@KDkHzS zuG`)fgW~Auw@<1J&Q4cWAm`RIMv26v8bt27zq7+fTM1E;MZ-9EJ;Rw8iziqsnY&so z;5+bV@<14pB#ok9?OQ*Df7+r2P$!!v^~wigEkEW_8#bL=tQ!%s9>)i&rpp+-S3u*I z`<czckX`CdsKVVx1@lKS#y#LH_}UjA<SM9XkpM@$DQUG_Q2XpcAqm1X&XFx$=Hy+S zCNaG&O13x4Z0VGB#vzVu4G8h2j|XyxuNsgZ?zVlv@kR)U`W>oSX4|(VgNSkmytgwz zMEbknF53?Wi^N?y+piT)E5HEBnL17>AVbu#GYkGk79O;ftCxOA$ie|v<<DoM`h3IB z<4doba%K0t<~e_X{(f!J#PDZr6b7STcs({{jtN&wgL6Hu;JW_=JdMhvqnIjz>Htd! z23+g2v$Ro8%LA)mH6iCDDrd2<xX9;rumQp&2uXqd)g6e0O9KWunNN5~0@lL7mJB%4 zFb*v8nZ=Pp!(q1)cGAMG3<wSuhTvG}N*+baC-V1~5s7jN1Iy3b+Z*i4>_9V-QuumC zx2T}H5CwMTD<2PkT%`sbD)hrkAe$&6`Dl^D5YOEBZoJq?USEF(?g0R?o?J0ibk(RL z$Gx#|tsI7dF)$SHjNIIguxr_WoK6L>>eJ->htQ&@;K>6c0>=GKO-&LK5|*Q7vVo^x zxraYj9vmIDZF(3?t3V$ggKlka&+cB0x$q{l5`_yz^nHg18JY%#K;r^3M~hWB5Dooj zQ5|SxuKMxe;WwIlxMZU-Q2<-9nTR{A*fI+ZFmBb>p73g`R2IXBH&euMB_^{ABE!I< zThxBt5*(q%>`>yIH`&&|``)41TIn6H{Ms9VBP#^lh;Ny+-|xQ;0j|W<c?RuKt$oZO zyLDTDYS8Qbd$P?~huerNmoBxuJL+e_KsZ3kNd5%vo0eRm?g%zPV2}g==nX+1KwbU( z`7@3Q3$o~xwzL5SNUNl2s|Wqs<RqTR1`J-HefkCc9@}!(w9uuq+fx%qJcbfL_NnS( zOTw8@1Kj&EGr!zFHmkABA3^0ok=GpEJ_}?!t+8!lBE&$Sdb5>$Wal{jT9iH^SIsHR z^JZg;Z0f)I8o^93TKk|SF|jB+6O7ydmR%pqR<cTNVXCX2(+@TlIeBaF&(~R9o=s(f zrmp2;!Lx%z)UK5ZQrY#uFqAh95G2BF-X<e13hIpU>mCBwPhqePg%*u?|Lp#E*@aUH z42NOUPX5@0J0|&QT}k$(7h`+D54s<D$>5tp!Wx^Mj`snhZTnjLW$)z^Q-cPA_%Ikk zJ7EFN{mB>cMIvmA?Tv$*_9A-MD01vvUm?)TOAyGA({)b2sO)p?PF~I5uDh+p=-OB( zECeh?=fmc=MwTV&Uu<r}f-9ST{+@x3T6u7LcFP$(;&%}OEnylYC|><Dc&WJN;iog8 zI%XyS4=ddS@Md?a$M0F?udl;Vkd#MB$0L)@+@fk@@+|7$f@8wn2`d-3ay5l5bSAme zqu+bz)T7CU7@$V&Xq;`}<rRqZFrEEMugDFaQyV*~Cl}iLHp7X#25q0o!SGN>NbA-e z!%RSJyn9(jvT}1Hy@Ho;?hi#8Fu#E22@1n@eYp&1flU>C1Bq}1S2p~xTwL!&mw;el zA@02G4SXUF2Y*5sd&~AZu8loeI~Z_*TXL4k$rNYktgo*Rm)YuS7+C-}#F+4=Io9m- zNP|G1l@LsrHC!`?KMe2#S+S&ckz5wSGzaTFJ#9XWmYVIi(kDYgh`3uYSWeK)|GWeP z!gfx@9A}6~IsA$RTP#pGD%sb=j=;svVCo@h5Em6H+Y8PgGyAqM1r-L?wRY{>R=Gon zK>>5~urVYEcAP75EB8<doJ(`Kfv7p>MIii%7Dxl`I5tq2>K$35LRGOFvoW>rTs{Ku z5|=I;%Px+z$GeG3%y`JtcyRTR;XUyDXOOPijdc(#PpRq8hmI4th&aNaxX(X@VmyDP zF_-U&4M9p6MUnVfDsVl4><x3ny`3FR@R_RegEF?Qeq0)ojX{9krc!%;cI^EZ^M=o; z8=XqoonbTDVkoFhE5jO}>P^*oI=J+oz8$`ifp0ml8sJYPzKjjN=|UMPF%8_9fIeiR zdUnysn}dZZ|B;E8ttuJfAVcFZmVHlJFI#52e1)o5oeO3TMbCgK2vysmp~XKTn8Gb* z$JqN%s%4mj<DQ)HyU=n4W2GIXf{e>4%2+m~M9_Y?!1r5ZcVNjzX}snz)bOWBQ<~7Q z`K|uNa^pInxVJ+ssfxIt<IVHSaPR8e@uc}u(`~i-(mXcMwDE?dWu=O?GLM0L9PSXs z4G9&q4h>NlpPPDpXQ4nj8rtLOLVQ!BirC#-VHlrWt!1*D$DHu9V+{Fm&6C@9&~Q|b z!5q4y0u<L!BiK@(E(_o;<$#}@p5+gvgoMCf2!N0D08zG~Dhfqzc)cgu>zrI}LsgA9 z!p_Zn9N?1+R7+q~mbzw>UPtmARR$6P1^Jq6)~D11e+PW+aO>lwA0IY=7*L0eNfQY3 z8hA`mtJbJCXxp!39C|jgIT`2aiqmojdG?=-nl<~Fg`TO)iubClb0Yg91g!ClXuoA= zYd~Bq#g@{>)>a&!UHXW~cOqbWcuoiL^zA|`L?a-eA=jJP<d0{xiwP)lO)$sX+1nf7 zdex?CbFeW9N;BAC%2%D-fv-v@8>c^%-D6sc3yj@g<A*g3DOFsGePl%NIRHU_54Hu) zG$^kIqyxZjiwr7&4z0HYQivd;ZTL{$c|OqzW{hdU)T6$t3S~1(_$B};(90(=kvm?7 z6u@Oy*p-mV^TX?^h1Udt3h*D2=OuldG?>amQwhH^^UTk6cWHJ?_QHkVQBZk8A!NVs z>Fs<QN0%UOiVw)z>hpausPZ5iE1&^h01(j#6Z7n`2eu`mrCGgDpoX%5J8!xP6xk38 z_9?Zreey<Moh(GW#i8LI71Y`QH-}*tutiP8_lIz1Xk6D!@%C_JIT*wSDJ~ru4cO#> zK&l*UAb=Z`-TVc%7}|%RJTYzTlZFbxBtVjYGTyG2)do=lAnN`nulo)G&ogyhfPaEB zN1!qi&V{ZRHuN~P*!OihP(zJ=T*1>efY{gxTUxCE1c^b^P~hH^x$GrQu9^l02adiT z6vo@k*>-kg*RQNr=PirhxKn?3CUm9)Fq5ov<MfUYqS(_xC>=k^TBB159<%K#aPb^( zr5L7A*HUDCi(2r0Q#$W+wbOgeG0)fp2SXoREmkir`Mdq&LeH;8|DBZM0XiQPSLp!M zTH6X=3uEUbB)RwjVdJ^mhJMYcMSV0Jx&JkQ2-8p#78k%~U@Iei)r#Xu`H{pwhp`(y zFr0BX9osyR8-(%=bWm_V1RF^^RwYHawL>)x9b#vZ9z1%>PF6(@<DicMb6!rhd;TNt zUMBiurEi5ObgY{Cy*MR+pB=0GrrN41a<Y~;XBF-%UpBba^xiN$I-2C}U0cxB2L{r0 zu4}2PlHSGrd9A6rvQ+-e#l_gz_}R1XaMXeJ!{Y*c#Hz2=)yd#TV4Xu{SH(Y{yaTbD zATEKvp|P=%({;>%J04mGi0w2P%`=q;Q-53AEm$|e=17KwsDS0T$$-+DlcpeYAT&-+ zPFA@X#JLmXA|b{A&|j4h3O@M#VV^#|DYd=%bN!)+$T@txz~2ClI|bea`46CGnVFeE zsN~@?#IF#^$jAf+1@*gU4EFV<rKdwQ+9~vd*RNlfJ-ouo$Oy?{a3!TpKV*1EKLS31 z0JSB%uJNh-w1d!2Sd4&nXX}M?Z*nYeNLFz{R46PV5?1ZN;9%~YZJz1=>B+A7DU@1B zZhk(Aols_Cqyy3Kw6ru__Rg8;73UN_%gQ5;vj)c8N-`Cy+v@fkZ*^ZNeOqo#=+Bys z92k?$yH%y-wqw{01jW9;qZygM&W(Tu4{)@r`6SwbPXfB~Y|YNnGax6*muS<6Es*G4 z)OT*=rQiQr{4t_=wmTgnLKbYeIS)Klz~2GL&r3+47&V%Gz><<dbKx`Qk2k^D(?);e zLU8Ua|IcO+|MBC;z9xS|##!>-1J&FC9P|zxdoX&a%77#^@D)&m%?yejyRr+<ZsLr7 z#ZPoWF^al__}lW~AMLw2>~bhaK^Kz`%tAmlfkS){PW=hUr@qwqP#Ltthqb-61s@ii zK07e=444JA&s@o0|Ndujcz^~OD(>lx{pZRz#Bcrk-}#HchOl<eTF;2=H%%0BEz1Z6 zuT`+Ywf%YFS^NJyk&gZ4_AFCOYF^THtM2y^D*cB^ZM#B|@yc$=sekcC{xN94c{G5p z@*fNK2V-!W!~=;3Ku$2>O-fAc{Oe9wcsK|X_<^R4)A9mAI*#3-4QRU{nBZf-uptJ1 z2mfPofwMhG`2S!2U%VTQibM$Y|8<YJutAC&KK$oLiu+5s|NrIx`*)+{6~q>RE!A<} z44A~*ZOJ{?H~kjC%Bi9(`86^TA2H<ekp2PZIT9tMZSxhuD$~YNPpDk7Z@c!z%tb{n zKyi!l;6KX)b1Lw(bc!**8{%@cx1!?nM+5^~K<{qCw@)AsFKw9eU#-63K^i%Jh_>%i z=@HUtT|3eJL6FK=wq8U?%yT^OGg)MP759gdifZk%s*TMi2yk#lCvb{@@A?@?@6{@8 z4Zw^yKx4StDc>j?IrT$`=R0*~TG|YleR`gs?ynNHbaZIyV<8Nc&-+5$0$BKhnYStU zATyihLo+KT{`K?cf9vmfcmf;_f&fx3(?0rSH+JAls}&oLgYV+=Lokej(0Nz*nPj)E zR@}%1yx&33j8Ajn+qwS`ez<J@p%`JbG9L@*YW@KX6T~f1DoV`4aTB^li_4KV%uBTi zY()N7&<(G*_0)?Ys#N0Y%v;UPPo<k6pQ)*#cG*!SEZ+Vn*ei%QT4nWG>!I=UlC_V} z+9j8YaPbZD(t%YVq%iP0%hs$Z0}^(J{2sV1^ST$`B*^e9-#+zj%-H&)N=I$;y3y!p z>&#KTn7v8FtohteEdji|4>+<nMw5o?%#O~N^$%Liv84@GuG=0TaUeO>pFfb-y5}Dm z6@`;iqMHQPYo<{}6;A8ghm0uk-vlLQgDeCDAu!7tLEI)KUC_k>y4S*X>6aLdWH4BB zk%BZdU<Bc^OM`4&w*ucAxPFRHM=04)A6Bo&CMTccB>%*g*t%2jgW`?3aH*bSI3<*M zAu4sfH1Oo*oj}>qaMMCnVrtp_EpEB)vu7FT8;!0m5W{Qn(&+dA+$GmOj{cmpPq@o+ z(?0oLznx9sQP^fZE%}uy%&anmQTVaL8!4<!%JD{d?CN%kf#4xHs8#QS4+4Z9(5amL z9LvmCX>zaPP4DgVIsVPt&Xk?w0hD5<gotgzJ)6gH!lSkyAREKK7WAF$tz-f#S1XWl z%J_HJH|G;V*LNvL3{)at)wrX>!#SKc-VEQ>Wd-}jyfbLf^b2upZ&+^8=ajtGpNCg! z4CQmKm0ZF>U7((sR<(hEC3ufPlCq{m1Fh%O)4z=$p~Rof;zaMYz>jd6ZHt8WA0RG> zjxSU_D6c>5+_*P0IoS=jB>01JJ$(v-!jIrR2oD1`@>=yCiJ~_k#3OA+**DGf#HtmX z6Rx%1k!=R|Fec*mxanBnS(=*E4zq|6`&~h&6g3kej*>dSY7@17Cv@xSJQ(p&?Q0Y{ z_Zvy;g-o=_x3Q4O&l1OW#omy#s-?%7CP-My-R)u_=xAYb=3O$83w42PhyO86_!;u^ z$=jL4wolG8`BDnsLRLD!wGsTm?<P`OHI1$olai|c{?9ee%cUC@D`Y;%WBK4cL1E@X zV|84fWW5jskF0}#F8>?VfsrZnYefMdUtfO?Mv5R}I)a&FCJ*mu01-G3G2IZ{?%;qR zr8_sl_39LQ=zv+6@!M5t!LkeqOH8CBBYO)u1wb@tldlDTesD$E-`IdibfDdQ*MoB6 z1q9B*C=BNx2f$sQU6(mGD7VxT!a>(<dk8!-OhchwbJqSIrm+zxKg4}fwfj_(ME^bo zvpWEpz%Dgxi?P{YB9<IFmQ#8`F_@uwjP_f3o^Rt_$9{6ybirJ?T2?huG^1L@usxkF z`S-|&9NR*-)<S!9<a%WU;)eOHpRc3q1$f%pM>(Bk-M$Y0?jnrR+{%&%8^6?U+5c?z z;tJ^vzzY<9BX|JMWvsEv;cBf5-;<?3VjTxL#5aw{j5C32G%@52mh?D)gHRP#6HTOv zr)Oae6nk>z(mB^o6bw6JbdOz}ZX;m4-H%33gQ|&w|3b+1!bcA*z}_ywnJ!#vUr9=; z6~@c+lap+Ab263IklYL}9Cx&>%3OkD@OE~U>psg>;(x_kGvy}O&P>B;KC=kNoy`l1 z0fhrRy)27qfaeHEcBC@@%d9Bj7sUCEgzX=F@@D-$I)%Mltt|lmegMoNH^sKKHsQu5 zBW!s`&z)6im=x6t3pG5Ys*CRZ<**CBUiRw4z5JJn{y=b&GH+wSmVNVA5ThDW&3#L5 zG9vK_Hcx(`mT3<{P4vnpwh3BWnb{Yl*HDu?H7_gqMs=&Zd`Q}ira9Ujy5h34yw-{H zZgk-67r*!0+{Dkg>`koyMCgaI3nsFfbvAh1(P|^^fHkTKl1F~m($Fp--%V%psn->? znc8?iHWae;j)+iMt&ig|FlsAsxDFn$&g(BW2_QN1VGAa#KCyjIAUrqt%>#@fr<<vH zy*C)b!Hez`h}p}vYIu(}`QdaEPlOeMci2nqTMKu<iIc2`&LaX_d+5_c5%|vqRVHF- z-9oQJLduR}<0njxPKxk`0y!AUX4DH>ErbRTvy2xvHa2|y{cUTst`?%eS`Th7$zX~@ zARE?f{}cd>99HxStX;fpcd!bBP)IUf>)$YMIsjibkQ>`WxFCqvs!*Wa*94tE1eE~$ z#9kigiM|;pCnvWC>p>X@hs`Fm3{)J3f%WyCsFclB5BQ<_v!i9u@!_snz;vyEf(X~2 z{acEEu~<L=gjE1{!#vMX1zT=moE0}LE!l|JSe#!F1ev;n4JQD0nq}s(nHPC|amL=b z-~o^rfT^4(jG7_kgq7Jnt*6ckE9|N>l``?DZZ;fp+OZ?>R1-K&UIWCQAsY|VsKOO< zcXR@{CxTcW&OgW$1;OEcPUBzTJp*%Ob)~fAiZ7o(KQkBN<EyNy;)m~nnFIWC3SqYc zI7wFeEjH+RfS3*U7F<?C8^bUsczw%}G1@mT2(n*`m=ogT5kDu15J=u36zKHeO#&&u zhO)t!s|idEfp`Zq-&Z6^B_#@Q^8pbxj&uZ%Q3Qw#pd7C8fZWG`xESgT2>8ec;4_$% z4Fx}0MWNK!3LyA{Gjd{LZcrrx+OLUAm>+bP@`GazcG(z!{qO@g#uQK~IyyTYmN%-3 z=$GhEL52nWDh0cK3p{Q;kcc1v_K&k=C_FvQD*M(wTIf~OVdKLI&{uAy1M_RJd;{MB zYh>zd%M<p1=Unth<RM;F+y9`iW$L!#bs`~w=k%vObybv61$T2NihiB&D6w_o4(cg7 z+1U4H#kcdF*laTOzwt&F(i(GY6>_GYk6Iz0e>Jbm&MVXOd$K1K%Z1XLTFBi;UNzwV z&r87JRXT&`QeL<WOL+^^+uQh%AXI-YF8>@P$4YVIx|dZh8@g5T8vb75t(-wAg@T!Y zyblrl&0H^rt%_S&w{ug5tt@LO9Q;c_4wrh8R7PI+2UHYX>CBD!q<nUEVvN3T46IOs zYwjgk^R|<}KHNR*^9?$Z7&38vJzGpqRr{J=KaxQEo>lc3m<QxzmNYsb8zQr~J1Ydj zLBuoI2A1#Td~P&%1*KM6PhML@!`3Dg1vf)OPQsjOXTT~G?xykRTOOY-jhn_?R_Dq3 zj>${`iy?E7zpFG{L8hCr`jSgf#B(e{_4yW_0F<S+Jc{NE1r@by;R)hTU=c3yA|tf! z;*kr0z|(3dv^%O+mF>}^DNy6^1oD9&h+U~xepMBYWado^KHkL;XzyT$BaS(n0x7sk z=sG?=u{@-3n^k3STaFDuY~y$v_}9k5Dqg79C7>R_dx(HBOOS+Ui9Sr4?QSDrCe({Y zr{Yled*oN~p3x+Tcxum3SLOB8pYFx$;?f_%&_sQdbqW_JA<G)Ys>2es{9g12*lfUE z0D2(A6BlO{ER4Ezz)E}E6dHCraDd+}g*#<o!B{Q-mBZ@DE@;<GTS0re*$0Qr>_%i3 z?nzfv#MoWTf};rHX565(1`R$qWx=(9V|tu-wzb`z?|~V*scIcODEu{)hV}&*Se$;5 zEf?e=#2u7zX227L%&p3&Fne0@`w5O74y-)!oj3=>TZmThLhwFP69yCS1xJ%YRUoZC zSTo()*tl&26cb1i3N7QZBe|+%?Jf_YtsOunS$K)FQ-n$jj3|8}?+ea`zAex^dM{hS zFl^1|`bINZC9RY_3X%J?BK!@w_rn4OmkZlg@PvksKOfn&__C^psSMoB7e2REhR855 z2#n$^;hpZCLxw^ITRaBEM>+6IRYi5=w!SwlPfY=M&^IL!jtAEY(vCeHFPXK>IRN7% zHj@;D$Po#J+&x5yl$Ep74<~YNp7qb<JT`O0TqV&SrR;e%DNE-@>oB5cyw`kwPH?Eb zzHDc3LCdTlx^&-xIUDt3VxTl9Gh5<S!JFr|l|G?FS3di`yrUHH=vvAHscVlv5c7X| zeCf5s%eiATB|f@CU#_7jUwnVFV#`ZTjt;Hg7P~FD?_R#o_G@T}a6r+`;bh6WRREjI z%ETy~F4-CvwCkBBS)JpX<NRi(!#}>9`@>=kdN8(&slxCX=DPd}o<m|ai9GXo4K?|? z4l<#*!eDQHplx=D?>M5}I!gB7NIF?urACSBij8Eswel|Y(&bIhmySry^2*6Bc@_rv zEg4S3zog9S&m6YXT;jE<>iK8T;cufP=6{#Cx9cAlPi2T8eSC&xFOt-6j~_{GbK}LA zaLc^3KAENs?{)l=(i>cbr^9WC+}+2-i^Ntwl+n>vRXW+pP(Ev$@z}ujTbvh7rB_#- z#@D}vZE#pT1qBRA-SGyRz{s;4?w`qO$ih7IRQQ<#VwI@WV17nT=b2E+32QW7`Iv1x zT#eKgF8#_XtL`4PC${#7U?b!?sO6*u7;*QHX6PwBU{QBB9fuOZYM-=rc@)Y!pI~QM zyE~vLFT`~ew74w!Glq?Zf5WCnihdkCc)-%up`=G2rZ;eF31#sa&vyAw%De~A{0s_J zSolIm3#nl8CC4`#0c;E|b#<Z#1K^VTPwWE7Iw1gz9~_Hu%|r6}$^1hfim(@t8}5tW zSKEZIjru0MflLK-DNt1K*VHCCPx<L~ykd`qJHW)5<fqHaUa&*fh8WQA7YWkpb3U%Z zxTps<{VGtp7r^uf1ol*IQ(*m*!fa=ViRCczuDlQGBGPoW1K<FH*a2dT2<6OQV%`0V zrqqlQm0!KG{>eALvo`Juray4c*}^@O;vN&Y8GRC>QKT;gm%XxbaEL#!JAA0#8pErG zGYn0O8~mMNZstMVU~Q|NgjLnhaD{grJaA5yb<W$));1>5qVd?8%2~TL*zRC`uu*^o zC>0CWpd0u!<KDyyTA-zy?@>8C3SH>=+75)Zr%(ZarN}ts8|h9j=T)<eu($blE9Q&( z1jA?Y6XdyIEOgIu(x#bmA3RBdC<XT5b>k>FqQ-(N1!$P_q1K1Wuwff22iwW#6xzff zz2HVQ`Vs)Q<%<s$|I8=RVBRU;ry_1|kz)nAqB~Mwpo9je9&(sTfNF%?{S%y#A<f)Z z{cP;G%ebp7JCp9e^7+a<9nFC#+bmFxAb>U6^;bDtads+Ac|FVMysY&`W9dh6jHkPe z!kMRdQqGWBpMOKj)bWHS|J1R=w8zB3!f`wL-SYI?2quksp}jK`73A3KLEEvduQu7E zw)0)86$V|8OPHOykAy@?(Lc76i3iJU-l3Oua<7RvNMXgp=Pa_mnMrCUyzbeuV$vCZ z&7-1RezJ%?aU7>!>}EkcLQs+N6;Ji`basCn7g4>Fq_~SGyS}PsRaTIB@Xje}wHdd% z%LjS1Heb6`Y{XE}UZl@CG_hGFxLGc^si3^`$kjBzN4AuC{r+ilZg8IdOdwvj*%8e; za|ny4XWRd7`M^C7M&!EP!0Xu&i-&l1$EQ_$ma*nWNX`1MlO-9%A7&$Z<+HNJ2M&Ju z8caSUt4;Jt%vx!sO*$)Ky!HJQtNB;F>atv=HEic9MV1pDPX}|P8!VXyC*0k)vX1jv znyk)E)TL~VB}(<WmXY+<^e9jQJemBsae2iR8}DzjT#LR%$<H}r3zaU+jPRqeuoAjw zS3CV-2t`0b<uqmkGq50*b6D#QHfXU&g%G=Et=p9(gl+<sp^>O)yMPjm9%8;SQv4Id z;^QTImP1N40j|bwDWX1s#q0O{8fiiVdqzH(TnGgQOQLPtlgYFX;32$YbqbQDZgQu$ z$P-W{H7s|4)Q1C~;A6MSV)!%fBpYC_7@bT&S^42TuR&Xcbt@q8=<71_Lc2;w8g>x8 z3yGKan~22iVhxQjKpF{PsbZ)pHcC)u13$%ZIsR{-KmUfh5awR9nFbL=aDL#9pg^}F z*fSfs4@JG5Km8)^UTT55{-tL+A?!2wZa&Y)`o+aR`4Q(_`!H2Z=#Lhne?IiZ9XOP! z(^@K;Hsa3s>0Oi~eSMsuCAZc~8Ga7-f~0%Y-~}3CcXhe|jUSNY_Ygs4+wzb;(Z1)7 zBn2BBPDe*kc8w4_5}vTk1QTwbj^s0&2N{mzVfyUDFlGP6o2n8LrH4|?kO&Y?Gr}xP zKWqBX0s9D#^%Zm>n!ssmetOj_uByq}xAgdGEXR%n$7dF;@_n(Bm7JkGG-|L;6L-ev zJMHr^4Qx+m!ESkKJ)5|`cVCP&J%5>6WpPU%vm@I0-2PvFvV>^K2%_ZsTD!v`{e1N) z_fgVO<vA~T*$3}n%%%732g>V)U1e<NQsVCQN~|R8^}W9;$wV&fGM>=p=4Yeq;LbZk z8icO2GoJl^-7G!IGFUc{AXpWtsx;<+RdQ?o)ppzd{DmEJtAC6CRf(TDq@90hsVWIR zSe-2`EL;rTkHYemZ2kNaxnEn#DL6P%y6K^hf!`QU&yl|Bu{~Og^_NSm*e$KK`zn$8 zIJ{L~d3Ud#K;y1uSNpUI{h@o?Pyfj~J(aFDdk^~F-5VG?p6gi%s$A8e8;!-iCS_G6 zx6Xh4SDf}`OY!D+SP)E%XFJVH@HYP%BHX)GBuNW!Q}ur5*ZsOmd+}XIPh;Da2Xt~n z^*I%cHVyTM*?PrOlul!zMnO^5{B})0>Jn@XF$-_RnnHizh(ds&Ko11#R)p%2j-H+# z=i&kopn7@Ea4R^fOK@AJBx5KqXQ;1_&_cwdCoOO_wduYry#pGL=Yw<-SS{@^M>DBy z9Z(^aCqGAuASAp9EGuWDaJK|(K$!62c;#}ulOL=P!S`xS_|jH@BS9VbSFNlEQ}D6V zAh@}>65aQP0gHk8VAq5Pl*GEn#%?{Z;V4*IW12RA<#cO(z5DuYxWnPQNHndV?=1>L zb0oM{G2LVIw&SON_e48f2hr~6l-QY6k|qWOP)hjbKQ+RA>%AU#BT^M-rFBgY`X*2N zNqBi^J#(lN_&gaq>W=3{&iT$GVXi2mDKF8IpOtmP!UINJlVNc2<iLiL_dHVknW~|i z&pRT8Up?$6_Q>^e<Lx`WBG<&CAA`H;lP6NxgGd$a>x1F7lH)MvCbz7Zgs)rA3CstX z)e2GKq*_9t30%qcm%HX$gn|gz7&h8@{bCS3UelAYsy}rk(8IqQQdj?|vA)VZdhR;M z=LtdMP2rHkoSdOOG^$nKc4*K{lu;Uc!0Jx?(cv$2LBkHUNV=qyuEORRE!*_Lwm!xc z+rjqa=&L))teOJ5Rs_+u8(u;|x`E2%d{lgB;lOLNCGxn2&)?~VN9K7a8zLP-JZm1g zhUSZiRQ{fHiasx?;GQqd#g09-ZiwqGj`F<Wx7nV|J(m+^#?$W;dp?16LJoC#nBV{B zNbiu^C|L|Ch7^1X>nJ2WKZHdPYRKMX<f*E5??_F@>WH&Q5vn9@3hKueXGg1{p4*Al zHfzPqMwvn<Yg;?TeBSQ0W%d{(LiJQv-w0Ebl{*=xp{<eNSvy;1g}W?jD!Ni&yO(Rk z694|Dpu8xcJ9+E#y(9*g`Rd)$(ZKo7x%hKA&b_icAJ+|&m*QnKTsF7bS-Z{y;0eKq zSdwG{%0FE3k@W7Bu6i**`S)M}0t~BDFN}S8eYMRWI*!ROML9m&<18>wpzLfX^jHKW zf|_{^LMoD1zN-Cx6D5Msw(I1|NOV*OgFkj*CqT$Hp}x3ow4Xiq%)|5i7>icA#D^V# zvzKb_dSDSsY1*(WDRKJ-I^k<Kqoqcf`SocZc1O7ehHS{(VX1oDVG2mh_XHL4xfg+Z zx<$n()r(t=_vFnj?!E`)hShz%dVxBu_P1ucLbp{t9(kI4(1rV8zPy$1d5Yk7U?qDM zf5y<MI>>QXVtjTiqthBB=Y}17p)zz}2Ze+Z4NRjXs{bMo+Ih7XfeC$@v++q3|9V#( zP#$5}4HuOGHK!}s!*L+RgSNCC69Tg4v1fbb1Am)(tX9$DHi+>jJ`o)yWn}|>%)-4_ zX47}jZ+?lKF3J-_K*{E5l5JF-uRQ0)C7<3sml-1?j3XtnMoE@|Ahs)#*&-+Ft*dHX zVO4se-TqX#Yox^0v4(%V=7q|i?p21-BZ8$h1QB=VZdJR#IFa0CKxl7_H6XMZyAFwD z19{fwgWz`l5^t!Fd4rDfzFu$s_NX^2kf`oPfd9F$xs-$KnjXz)8PD0PGK232{XBS@ z33upN7poccf`|3l`P{autd%@Z=iD6)x%;_4P<K%^9UasDPsM|R!<NG~anQQ=J0?F^ z=d?Y{UC!5dunB&ltZZwzYiWo5+t*z^@mE-W9{AU3s47vY&q0&Hp>1?Cz+c{_XeWs$ zD)7Mav}d>J-D#bH5k{Zg1sgA&TEDBKqqzeeh)%~ujNRqVGOOXe9M$SvHo=)QVe{5- z8Wnxd@uvlk666Uz+~DF_uyJj;N4sBBs1JMDNTn|=zwg>G{+!e+Fs?fjy!in#ryr9I zMVyn&cKCxSo&wXYVBw>Mc*`o2@BjV<@`hGkVm=_W8jGW?wYT96+-RW*34}IxysAT< z7glt)3l_S8w^+@F`^|7j>QeQA^PchF<(ZNb?)&4oL#AZw9!1HP5k?RfUAyrwIMk(8 z-)W)g(C~mxr?l)j=_KJte}=Mgm^u*5-W@>6P#@hJX%#2YBGf7ZhVIi6L|jQtSsC{V zpQh_-DPR6xm^91v?Pn6MWYCtt8Z~>%)j>Sq6)52?u4Z#`u*p}Bh2nYWH$31j@52mu z3fvtJHDA5@1=T^I)XP*t64`*b$t2gcCkza{(}5f)&u*|UzCCa?H*Z3~M#(q`OoUAB zTMeSMaElu}Hs;*!j=x>bz28o}a{6zv<#@ys#R+J&z*OrgMP+GD%=V!zaHk|hY)4Eo zgtl5}a3JPc;t-*$bjtnT8r9xUqivx`fI9M||LIb2do=6*r@1!;wRKNAP)7&NuE}D$ zD{mYv+FJZqg_xpb=vY@(pa2ncMzy~U(wjFA43^f}w{_7~u(2293-oeZD~{aE56U&d zxJcXGV!k%$wrsXZ-8EWThT4%nPn3FPH=;Va(U~7leeNu7|7tU8kl1RRibL~DUY&`f zxGa`cMGLmThN6*>VwwKx1P5bWocbAs))l1=#{AZU8_Qft8)8ys*SDP{|M#fXX9v{Q ztmK#3-r%YzW3<&!9W{A54}t|-AmkY1vO^?G$#*s{+ihmhq%yyTsg=lWA?@y3fAJHp z?g%%}rK6k4T_>sV5)K>Pv0I~c2BXDO?}fY`=+&34yZmO>sz0qOk2XwTvxnU<-<+da zTR5Q;J4SF;UA3x%9J5y`_uN)#HpCdqM#IG{cwF6`_KZMq<Jp-`1P8*q>k#+<F-{C< zm-)nfxUkc7aLJ1{@JSe04TFCftW>e9e}%7h_~SU0&qu|U89U*|RhMEz!*`q065$&j zClbZS#o;<HIIw|KQceC&5Fc7X_zEVhWo190D~?Mdf}z)LS<OwHvr<5wZd=5Y`y8ot zaDLwJ&62#Bg!=eUc35o_Hb=)ffeW0F4d3K+T`&xYGq@pgPhXH4Eq;tJhuYzm=tZ<C z_I_{p6)?YV7x}$gHfo80g$S6Do~M?qtgN#}$lPD}_ng6X!)CUv*5?3S{9pj~21ywf zB>#{<)3dBKv<y9|w3!;){Px#x-xdMfBgi03t6oS6z+q2iW62ivw3Bk}+Id`ek<LLy zQ;<@XbS@W+wBTWh^^zp5-Jho?5xbgiN&PyOjn<^y=)}Ev%7cQ~74Vsz%>Z5A=?^;G zwBfDMO?fY^%yn)1Vgsh=Cp*H4+Ew}utj?+1{56);gEi_n^JEd$otjGb%91&)?8whw zw+~p=o4jcs^GMy(;$X*0AC)x~{A&Q!LhAZ@P_qbgo<%#BMXzybJ^BykQxZkwRViJD zpH#88_b`%PFqAKH`|D{N$DEaUd()!Y<~o|acnZDF+|}Z*AnGqcF?aY<N2sFi%VKp{ zr@OF@3$8l-5g;VY$u_vI4CV0?4YmEX{beeOLMHc1tDpSL_Vn5X)!5>GJ<!J}_wP=6 zCLd&)9?Uqn)UhYAYb=q~9Xi-0cd0nK8?2}9oXnFT)igpi%j);L&kQiD>+U;NXG=pl zq|BZ;>q8??9<p{)SNojO98$Qda9s?psyp~awfO7HH0aWL%gv3AV}#w`!mXVL{i5|7 z7F!Um4Gfky9y=OfUa2+MTL^98ymsodrlzKV&xmy#wa~RmZ@EsN@Fwa7zB(+#@YWff zv#n@YdN|jv@oO`8n$&SeO0LCiI+CCwRE%UHP~E|{$V;6B69T39&=Bcc(UQiI(n0O` z!n0+6B1FnV9j`4QN6XH&`A<@Z&5wPv-s^{%Fx44Pn}2TU2dKS${)zxy<vy=&a#w)? zw8M#Dtq2Z-i$?8VvokZVg%s{&h*m*aQV&&Vdc37+JFELjVe^d}H>&Ix!|Fzp3%jV( zAJk3xBeq2RfLI(O6VEQx{RQ2xqJyh9aUjas$squ)iEMfjut;lBhCsfi0;C7p0R`ab zt(t?i2G6-ju2%VDy&;>jU&z!PQsRORj@}gjhqk(uZ=UZPMwaj7KB0{dH{tkf*!3VT zlxTmtU?{)6%)5}9+>AWTHHr^lzK5|ga!-aep;H-LmJVyxhwdNHjtr67&&=Ddl#kWe zVr7!{#~PrhgG=8^`s>p6VVm{rO_c#y-MboO+6Qj4H<R-_lCn6*r?^Jd*S15MuWnzJ zQ{8TuM>L<-uyx6Eag~mh1!$|1YLQ+!v|rP9189)1z5)HY{a=5PrfJPTrzG5NwaFGs z@#)bPQe7VK3^<4_P1c*Xqt=Ap(YoWWJ;=G3P*{dKB3(T_=CRDNAmuUAJ92IV&_%U( z&56+yDdTzD<E*#IE}8iz`TYIAheo1Y;KQ~PY{L}`ims8w#6+I#c4&|DYU2FifoU|+ zq-pY5NgH(>1@~YM-%;QmH-<|xIdtq~JujCso@gFaiFK}h3X%r-p9niaEs^t7<18m8 zFDuKm<<mpmye|bQGG-bO1aS^XC4hoKc`m@AoYWxEvR9~>0fKqU!MBAW==4*!>$Vfp zD6%1UPBMf__ox(BCM5i{PRDsECgrF?+%$}KAq%i%uXxgT0!<*YVtHxnnpNkZrk$)A z`G+UJQga}yXl!Fm4MZY)SX_|{k8qQv;z6uTo<?~dU}w0d9D)ju=69Z2ZULdzteprz z2x!^rVD%NXvzV<)T7vib&Z!Rr!f@T=Qn&3-aNOSGeaP;4cA^)|N7u1;2u<YNa8X_! zOT;1&=x4`x)`kid0SyG!$LN+T9NdEi>2G4PIb?Ja*j}>B*u~YJ=*mG?r|b9&9Jut| z5c2Q|jLa26u?kar??^R3IAGX<-^aX&t@n&Md#u+s{6O7EsLdZ&8&qJ+EITQ$fC)N< zhdwx?Q%z7jhFdiF$KFW=W2MoRK0ufU^eLZrw)h|0sOEfoa-Z&QJg-wPz}>JkRQ9Y~ zJh3&UlK^$m3o8`W)-9$kF88*pd0dr8Qt;}^4xPmxvW<exy$?EMuwMO67}8y|*H1oz zkeFycgnY%h`{qqFf%kds@-FS-`DmQ+cho_#<-~|Js;lRux5Hb+2}*^to<rA%|BJoZ zCFibiyQ!5=wil`BGatPXFL8G+hf;JgJnrnU_3~nPsAZPLwfr<FrzT1;8%5YFb#c{; zt5$=xr>j+=9NZsN(AIi@gGUv<vKH0rJv33&0qJ)q6?$F45lOLmT2-f$cQiLhaXgiL zrkW@m{%o{dhAw<wPy>JrLHpOi@~j~%QghwIuXza66O1J1x0AVr_lMi=U~}c^!UK@~ zyQj9wP?s2Vd1zyQ5zaYQWO;rR;pDTRKGUxDVZ`@b$DY>~s)2lx?P!Ne_Aj!Cs3`At z0)dr+r>?40fGy%w30<CNfT^Asaaz6J+w-AxRAr9^gZ}Fp#6&~}*amAdhv(0Ke0nI_ z@Uh#L38<hgLuVgJv|C#IVX%2CngS4}Y!#z5tkp!#A^g2F6n(HC?oBM<ieziOBA>?+ ziYgcu?(65wE=5xyaE_h7fGsj;Z*amoPvbe!e3B$Z4;JcWB<SrU5D2syuL2T$<gWLA z@dPhhJ`u}(z-@ssexF_lhggw(1xxLZksU=w$ZPElrQBoIz!m`v0-|!P53qnj!RWTY z_0zW9DFDO`r0JI9>U3X2il!U}wW7Cq@X0t^Na@%)IXOQ(^oDVP$KKn?Vd$soKL!=c z9|X`{h2gmjxu>h@GtOH)Oi)?O#ppEz)`jAF!JVJbl&w%FbD1GwYvAhC4Mn&k?2ul@ z*g9r48#o+rbW=#VF3P7@FWYEmt?$@gHyvd5+w-)Yu<9OTRzL=7Bh;&t(bxsZ0odD^ z`+S$~fzax=%Yf?YUg=x$s%-`E0ARFGl6qA@kWTtCvkH2CZR_nB<~~KwulUDVqN9n3 ziR4)<72QRgi>Bss@pMf~08VbH#~+lQM*5h^CC~0c)#}q9M@Fu3Ivi&a)V#|eB@#oe zK4&BJa=^l}Wt$uwsk8T5x{;DkPc&(k-Yaa@!81+acG07vsdu4J77mx72Uq;vy(>SE z>})7Q_3FwqQC7?5er>uys53pUZgDe2CCwAj<}boDc2~=J*(@Mc`8_##d{al>&!oDo zu)2T-T0p!s>J8QrCR*;jYF#CPF9hIK$|6-xaJZR#u%-f_bi0xMEA@*BLg8yawTeo$ zH0Z)x3qJ3BJ!S9m)~+aGi7Vi2^Pl#dAT+$ipb=Y{QDlF*_mp{~Ab$|PF>7hnMMA^d zE?~_?&rgIicTGTeEOk}3aBh<7>P&Q#A!a7&@~4K)00wGq_^3r4pt*7ycTibjZHpxW zxAQwJm6P7&?2cP0A<Md#z5}3}`sZ_PiuAF|hT{uDok>|1p`5LlfqqE}YYTG(K&5}S z__ykB1q-bC68m-VO7uccw2>>YRzag_`+wSd&!DRBwp~<XqDB!cK}1mOMv&g6MG;XE zP*Hjj>2*=0w<IViQfz=y6%?fRURDHY(xtbB^xk`2=lYvG@9gv8d^t0F_I}@qGtX!q z7q0dz_kFb+i{3*<6M_P7wXd+`O(&qQYnS}{puc;U{^(!AWxsWzr|X$^gdPMfTx4o0 zk8Tl&mtWV?tohs>ab1M^5WG~CbPz|7{yl(MjNQ8;k0KKpe3xLq=x0n>80OlISYXRV zA5qX9Ux!Xs*ASqH_PA1wMkp6E>+`GY$V%yX@hcnH8ePBV?P%p*5B8vlUOIMsf51;- z_$jy%n*t^xg+jUMjDeRc|MV8u2uf?yJ`$b(Bxo+W-H*f<8Wk9sFwEgSFn4@(uwv9M zD?-ix+K}&XkTbUBkaI7oBa^)<5`@*>390@Hub#^VAZ&!zew_xFQ!I}xP?1`4oJQ9B z!b0(o_ee-)(7z#}rlP_as?DfZ0#hfz?YNA<c;I#CO~b{{@-ovz{LZJZXd|@9pTSr5 zDGpm1FxvArdVZYy4C3VJw)(sH)62mL7ySZJR~r<@z<uQ=?h;6VSw{z7Pv@tXL=EVq zpgJfF$U^V+Fuw`OfTU0*L?fhozw%xggE-0NN9{v0L9S#e6Fv%`g{8@o@`zW$@heyM z306%o+%0WZZzJb}TWQo3_DI~EEdK{PUfu``tW1vRiR)8x6LD+!oD+QXT5!vJmBGP> zFVD1RSXy=0d-iPfdHg}Io$Oo_|N6!m78f^%(p^vK$XTK;*YX>}RBviD@Yv~*Q{o~j zsjIyaOHuK`s<{qT@uN4N6tzg63^@Haq?{gwa_g*g;#G;$22u-)YFcVUeP)&PwT{|e zsApAsP8FX43GV05<55xlAck;L*tRR|=1IM;pfH=O#9Ab2S;QG!bhr^`3VMb;(RQJY zX%ALB0(dWQI>m_I7!@fnm6`Wws%xDG?B3HQrt_9v*HA}A^rkF#TV}j67OP80A(|mD zXN%2hBn`)r4?Qo?#pOmsoLD4)j(Q$XtO-GieIF+NsNKHJgM%Mg)@)Tjf^sBs&pmyL zD;n_->=;+<i!<_J`ADT8X22xoP3{Ur{?xf3!(T6qWTQrjjY~X?0V9wZtkz4jggTDK z)DMiPSVA4tldX+w2i+MJye<O+1I!__z#X0_I(QGhcLZ!!^ymrgk)sGaN7&GL)pSFo zNz{rhsSA0j-n{uN<<u!=(b=SgLjerCb{vd6X#xvL{Z;h?>pz(73w`+j#ISVA``B1k zV=qP(bc+6Ns}13((LtCJxfBl-oCQb}Q9w7z2dpqQ+JJ>_7pEbCDk5jePjt3?{O6z1 z_FlRqH2N`;2wAtVy#t$-HzRLi?r1F6xl4Ta&xx?%oFcehb^8vpEGf3Xa9VIUW)Rt4 zkv<J+z2Jvu@s^t!8y^PWQdej8kRLejyUv*hRik9CW>@a~4csK9)9(pt86@joj`+B^ zr*h^_phP=nMk1rmRM9hEPzQ;-D4^YH4w4J4JGY}PalfY$G%~bh4|f;ukCtY(yu8YM zmdF@K(-9F}iZ@s^fSVY^by3z)$KiJnBE4tfq}{faC<_d)Erhh&$h<I$=2XYz9U?vx z6c<iNA|CyKyePDlav+p$J1U|~f$xW=Biy=1n80nbEykJ?2%up3h9$n9LGq(%t$n^K z8>o_c%J0@l?MX|!pGW)jCm$bKgC&lqu1c%r&se@>UJjH1z$`$Sb!TNWPa-)QUaq_s zjD~|n(4a4Mft|WO8dQo_hQ&F0ATMx{O)J+t{7EQq@d&-5Nhj+OT#EAr!2?X0<O{Ag zj|*E0)HM~dvgY<2>i&8zX;h2bwx)ER+!fXCA@3GXYd2yf&%Sd^h~uNNO6>VXq5h8U z#HWsPQycsK=2{aH5`-RnZTGGT+_V94I{&F2xHxb?!(^q^7XEFlnv}WOz~}TWB%|yh zpVJ8%RQz*S!#i^l3(rNW>pN?-k)4YJwu|f{D+sqJ(iHCn8tFH3%gTs68@z+vcYDIo zmdO4wttErXjNs8o6$j$)(1uTw@xJ^P&wlNG$EMh#(L_Fx8ymN#6f&z@>1Q`dNu}7_ z%uMCTf9~1qx)DdOq1Bc*b3~HW<ox=z@uQ>DOSAE5*@MHpwB?=A&ogxab*`ZDc<Amz zr~`zMft9%)(cG*!jvDFW7%WkTLx0GJ=1<2@EHi_hPPqS>;m7;-CcZqnx#&PdgUWvu zWAljonWzG5*yJA!PeXTbMGY?ai7#wPRn}<@bQk{mbjD3FJ|SU`&XJ-6>+v|q$Kul> zq$G)Yua(hn>x+th$a?@CE)IvzG%CpZ)Qsm02ALEYn~e}XC35bMKlG`i;mH2>=df;Q zpRWjqm)i*RQilLis4Qm0$B#o4`BbyHMuNJ2(pTt&qgyzHgz0)UL@v|IuuEWG8+mJl zPOf%$nCGz<EL~PfK?B}X>e+p0Bae_oROjrf&?P#W3u)|r-cK+ceRXX3IWY#1I>71n zvk{l~bY;$O_m18=QuVrDXKH9(HaOym*rjs1H|%-$iI;bNLmB90DWicpv?M(vwyoNp z1(*WgL*Bi6Hv+_7daJ2%UkH!E&1rx%4S<~o#TM|yuT!?@W`ax&(9x3gypkkb?*^)g zP$?JL56}DHYC=d(B$<elMVr4q99<)})EV-}!Oby`4@dfB!(a1h*eaT~Xs2A|+e&F# z<Jf*DFJWf6Or|KSl-k++!tSOXzTCFPSIjeAt2&OaE-wuU*9JT?W^xf*r_8e32>aej z>i%jW)gFM($f`tU0R7MN!u*yD&OoIWKK=Dl&xY+Q%ngzK;G??uEM@?O|I!s6EtYX_ zb2gywET^{$<K~69SRFabkFk`aw1eGWJ@Uqmo&DYjB@j=&($pzyM-x+JXmwWf*4GVp zdhII>8<gd;*`VZ|7V|uIwM;UA@}0SCTmUCIuj<$+`v|OF*qnKBRy;OVIdp|`Q>mM; zH*W!}y*67680zBJ*1Ic1uLqAof+4^s;3C96$LV^*?**z{y&F{>i|qKwfGm97krUP# zM_~H#ZOYWK)Py!-8JTxcmH{->I+=${j}(wNs>9wo_k77c%98k)(pcOg#d+R&B91>J z=!BWrFG^_}1%3iuO=ex^7!t3CB!gmwQh~rnfmFTfRJXq8c9$vbKF^yFQHNPf<_UHE zy)V5%t}>_pnjGFbNPTEmq{`O5Can`3q0sr;Dk>{rNUwO_ityVYSS2@1ukr5A#@Mp? zzTbP|d*C&ZQaB4vMwbVXioGU@IcF}M*!!W{Tk3Ri{Z}+W!Xnn2#7tgf%z1L{NL&B@ zmY@lQf@Xwn%J+zf25KhcDA`SIomhP>3J!`;16;^<0}s#*L=$wwQkR{UEpZG36(_^V z?{{JJ<9tgvp!E<FzU|cIG6~h-6E;&}>&*%BqBEa?ls(%Fa6vKo-tX@9%op_TXje`Z zFk+1ox~SBlhu*2ZM0B@YXppN1D!)*Uoc<R?^L6jpBrY;mL-+B8iwqp<L~d#HRK`(< z{^tlCu2g1BVIQmsWlGe>93KY(CdhR$E}k*e=$GxIK8(C)`hJ^0`k<W1MEbn+CO$qD zMa6&{V}X9+tA;!r_}=;QkvxTcq+e=IO~|6Omk!<PAYJQ+`Z*gyp(5Q9X*`pxVAn6J zdP04p0G_J~#|SLV^?on>(d!`Nbp1j++%E&Zs<(_a41G%@{P#uEP^sEnF#3|eV~E|I z!E+n=)=6)hWWADrmg$m=EE>%avA+h<tcV8{ir3O%`S}E=aaV~4iQOCQV-a}or*K2i zz|ySdlQ1qTCLjxU_GX!pXkMmdSe}j&@l+hl;dPVNmC`Mto&?)ktC719tR*N9I4w1w zgBs`1A!u%VJux;hJjJ5YZ-9T|aBzl$NpZ-RcG4iptAHEq@W|=}>a$QjQiJy+wSx(< zmBLox5_Pwp^v8~_=E!7iCR@m;G&Ms#K-~<$!xhYmJ3pw&D4CiWnvV4ufN?`*{DCcV z(Cu+^BY!|rVlbYm);~k0g_K1(>qg__<1;r@%Oc^r?#q>@w`Gg!>1&rS-XRtqASE=i z+m@I~u}Fu8Y7F1)DnRZ4fB%8DA;?-A0F`6v3Q>2}LPU+;XN8jAoVWqO9geNJ%%tsz zY|n&{6oVl2k+BFD#Y)zBHnz3FVA2(MF>vR=ZR_-GS~}IZDHaO|)!S4V_x0b)Vf-c5 zFT`pBN9&A?jaBhIf)E1f)h;s0N{0Pg7633velslx4h?wJ5!eSfu0fUeDwKFHfGUBN zfJ?V!_c`j%*eq=9>^@z3)g%xKs5glku6;KDV?x3PE-k3!{lx{1@K!zWd_byD8R_5n zF&EC87cX99x;-|;^QU|_Ud)5-0<l3ZsO{V+JPo(RV?{NRsVU7i--aE62F{mJT-Kum zOLpCG^t-mnkUo>#O7-Pu8jEIc<$=8MBO_B`DB0*%aHYC}g4IIls_;`2393<_frKIz z-{L^KfGmxIMuU)>!vs2qE7h&j8Wn>e(0#pjpy|fA@GaAM&qL{ZzA-eP!xg#)QRyE+ zK|xUK!?;4JR56Iu`=$7*^cGsx|9bdww%I%dMa6^qw>R)D;RhZ@MMV+S8A|FWXT!>u z72#t?1<0&;VcKx3P&pxj!Snnz<q=;#Re}nTh|3^Kcu0*nfBiLkGIwmVZ0Z?;YaX5@ zo|Krq1CMW@zrW96epb~^OXxd}3T)XStg=sqaCa_uJ)>VKI0PO2r=yr!Fb_h7il4`e z0E9^2Z`Em8=7PHUDDRdX694rhtte>GBN7*)7awy!>UC=zM(Svq2`vlI_s-)Nfh%GK z5Ly(-sD@$c<zQt!4BaqRP8aVM^6q~=0lWlmY(6Rcj$ikQKJD*6ett&(oc{00=8p*s z@9&A|dnJK1|2^aUm<QOCo!=k)8_hp24P(y_{a^hLm$R_4Mg9E-m+AgTzQg}L-wEw) zCS$uBYRXF`@@iMAJNa^S$9gk-%+^0?<OQ>}2+FZ{TreJtx<+n3sKnpcJY`%-m)IT> zQefX<kS6H2;ZRvCla-XPQLS~H_{^y{3xkvzp!iyL+<e+JxtCUTqbzBnvtW7kkEdPq z>vsI(riTiwdbe4JOX#$RQo99}sBYcrE~V)rEU(wrhy4#Q*$Oa!>`n!i2_SqFNR7n6 zD+Pi&1zSYLu2qKjwIitqcDeDocRJ`av9WHs@e93%8aC5y462e|jvsz^A4vO6vX}r` zfvF6(=_CDu7^2w}*8&Qu3ljth%_A^TI7+Ohwmu)zj2Xvkd>{5<q2e`zr-%o~2>!D% z`XJv#tBb`^#^6i~6QSh%0;3kU;h;G;4XUxPh%O~{wPQOc9+;hM7@kC4WM|>GRw!&) z>9+L?Nf|-?sJH$NaH6B1N<q{ayECTdaxUbzlg*#}86^ne+f;DnVA4mwjj~0iyff?8 zn=_>>yvoELb^G<eVDn{8YffhlHmm7T30E`iTazw7ElcoPl`PkEcP~@dqGW24@FyYs zAKPZ1Vm{fMaw}XJoXW{>eOfF~WqF1>LR-4t^X;B(y%fV~)hx^ivfDQ;p@+CSw7^hn zYT+2}qkOwJhg;yx{wIVOCc*5cs;VQQ<Rrh-vMhm^Gu~py51$^#Fcp7lC3%_5nJO08 zNbl5<_f_@3pzP-@%ieK#lb!k`{<X$PDml0C_L~`ZmK$-<-Cs-pBwSF*F{Ko?dD5>? z%b#~xU_Enf@FKfWGBh+#wbUQ<z5Oy5u61aj0^+B0YN0yiI^mqnmz7*6({?AZWG{bp z9VnA1ToULfy{QPzt98yj-)`R&Ao1;xG)|)#Iw{5erTgVAW3`hSwk=FDSXf!}tPU9& zZ(naV#q~G2%`p(2Nd4BwL<5HiFEBtfRHrZJqLFs+j$P>lThUYzsz+Swudbdt3e|{a zj%jCheZi0G@^1vpR9ih~eklK>k1Mw9sFP_}d^T=qqQ`oEmD#587Dh`IL1+iIY6E0E z3d5Zu#8BPIE64n=<5p#V6)WAH^d+sWoH4kFyQ9s&<MxiR=P4{~nW0^I<Kq;)1!_wC za%mRRAbS#NBF?#*@+8uB+|;#yBX(LLa4BioShG5|x?(yZXjP-(V6)i#q}Om>+rs2# zR-orp;RVaCsNB%{0sam<+BfN&*+)+kz+XY~NBy;$`EaijmRWWIoSH4KU3E&=(^o<a z7(71tk~v5V?BB*#zRR>-tv;>Pa-KiWdQ{YCgJp`F6X*ZtJJZfwoyA_W9upOtmm)tN zixv<laU-9{NWZs0GI|W#A!jdsa1HQKpt{wy?CIRGM3c&ea<A#Uo3Q8l$^|j)IrfZR z_@ilC>WA!Xdqf5!HCJT5PO{jY*Fe$K+`JIYrKI?IPEL91ccsDNG%<pT<EKA6JkOtl zi6X|psE?F4N3zEEZ#QMWsnvP9^(8%-9fdB-%Ccubk=+^+shDgB9TVjCyiOJ{weD71 zd;dqQY=y<j??0PZYpx8d1Q%~7xhaLZt~k`P<NXy5WPAzDvs!<1Fu`0D|GxIE!Zumz zOlc~x!)WQG!$OuCKu7V|&IQl4r<KIzxK3isx$oQ&e1Exps_iB*vCbmB7wQQavNNzY zPiCvD%grE6?k7nrKJ0#kOByRe-L_3{a@X&_DfYkp3V+);qb!UE$N+gb1sdhowLCwu zMP&&5flt9l-Wm5BYr-vAj*70T2*#Uhep+i1xiWRIZs255seJ|3qMOUY(rRc@RIM;S z`ut|TuG52_?C`9IyJeL4(-+;{Ce$F@ai&fW)Sr&aT0iJIS`d>knI+2Wco*-bqTssq zU{8~pDp1+f2Wu}De0tiW*yGpSH~95XgKvw>j@AC$=+k4e5YT-)rm<=^ceAgBGOs$I zk;LgTQ^~LJMb)LGGu34XpJh1p{=$T0K<BKg-V}G7baiKXrmb6)hGy=&bGeLZtcz`V zvXh+~8Y9hNCzZN{O-Jr-u$en1%xX;~F58zz1+6k0G-SE-EiJC+jw^MX9%G7R;&rkd zOk7Ots_y3e$i!!~;X-21bGWJ3onlfLrWGuHOiaUUBT?SK%yqdSR&9rpW*fQJ_nl0x zTl#EpZ~HolwLc}s++ew3oYK|V84{GHyT;UQp1oA9M^}({fBOBx$N^eiWz8-=$HhU4 zj$$|Wg9?T4_@g+HOWI2}vbS0Xn6hx&^x?DARWGzR>%*d9u{T&raA#v-PU$V-Y)Kc0 z`%NuVJvr7AAJIvJ{;(P6D*0gP8(l&q72mP&JX4sp?n+=Y?vRdOwpcBFWOCSQl8tXO zb8Svo&CyrgrmXI?T|r^`nlzh4SjxGf6$NI|!?ptbD)QX57oP4BVOs2K2?Yq)WB(bd zj_{cTCQ?4P^B9=$#|2@cDk-U{sczIw!EWa{LY_h1Tu6eNzYK(;fZ3OsWE9#6<aI`x z6Pf`lio=iwglYuF3N$q+c*(&YsZKi3SV(%(hVtlLFXe}oRA=}o6cW{&lb9nN4jD26 zNFPkJ+dy;&T~J33ZyE1>P;?N~k0R9$7bF3<uq9^q0zXEm`vaag^Lq#E66C|hpInZ> zbv(K28}$krYI`jTLUxcqh2D1+E))%r--N#et>__kgKUJvBRWz79w0nj4($Ih^ib-a zIh934MD(HzC*xpF%I@_t0SJn0049FpJBz`ttp1>3iXlBJ3J~mi&_IA}z?I?mz0Bkc zcP-wQ3*nUzzk&23V&o^zaqqD<v|vcBAe5$rZV!!mKhEVW(~5O(E*M$yVYs3RkGT_@ zljDHq2Rg35AYzFduG0ipLuRdJGzh6zB}P-I+Ye)+muT5g8&F@nvo~Hp8)|U@rQf4X zcCwq)VSsV=Fp#VF*Ix42#^SH1i*|E99GXSL9viC~s+huF+lJs+ysUY&=DVnQ=$=sF zciH#(;L|l;dE8hxO|*qDEfJpy+K5SXFt8M6*@-n~k{#dQj)B$_ub410;ke1eM}(mA zqs_4)T-rtWQUTnBZkz;Tb`(WE5%B@l4?#bnB^?3iEcRa5zR|Rs@l2ERc(H#@_!O_2 z{%;!T2HfOkU++gIOiObCLuBQRrIx_OBYA^sKiM#P>XO;I+S_Lm>7q%@*cP9)On5oE zGxCI)f3C8w<HSAI`HCiZqP5NH?L9KxaeYIQA~TPXOY7#^Pu#MJQLajdF52S;AD%A# zOH4vDr?9Cn!2L`DIbCa|+I=x`P$=%c+W6=bh009L_M~;(<!pijLVt4ik1c4MH(AIe zx;R+kxN<+Kxc=$rG<u5Ot?hyvg%?yCE%Y6_l1T!(oWg63XXDa5MdjBs7QGF=qza1X zD2;r46CBhbd?`00gFa5+G^f4xt(r#`P<!isEu7+;XctoDS%Tu>jZ+VK987GX^2-@E zbB6?;wN-gH$4{IxSqAF0uTm36p7ut$g|3Yk;Z&N)8~2ooQ>zIyYEM}ksgL8CY=vS* zcPfZaFxtb7TzjITKB6p1PCd|C|98<;hA2!~%V{|qXSMlm%E3e>U9cgMUE+0N3b?R% zgD+MTk4nv0SOSlxPW>{pAe-mtTV**wwbxN;@O2U26_99LzS1w&^W+5!8}m0Idml~V zlmc09=kLFhO_1Bl9{ro$@Ux94j<BEi1cNOy8NUlEsk*uv{GaKGKuKERezb<=%OP$k zW%@gp!3$lNU|m8j{IC*baJ_eMeO=w&jXS0FK1kKqz|GXA<l1G^qR0H=V_aMw7M>O5 z1q9>oA|i?+Uv(#`ndh8-el;IGbiMYc!9jhy-P7S1$hDs$IW{(i!2N)kQpW**rA=g4 zA%3EgvO@^9cx>F#n_0MBGzg=7jo@&DoQT=L7Z=(Wh3Lxb`KCtXfIK(Fsfl|cih<wB z9r0BY*7wXu8wm{Ci9oysT+%GQmckH}14l2`I%j)oLEAPSx<a>QZ4;FlROoy1X2=@> zeIZjA={0=}gLO$^V^nnE#rn7YlF5SQep+-DzK+P<ft*^dgjig{F4gT;M|c_lIoVVD zfraU^`a7;oWEHnRgR7yxijY>m*72<<d?86E_F%Lz#w>@aV`239^$&p5UvH3blAau@ z4z>dcrAO5n8y&UMq{0pKeCGL%&AdsLLQ&@WY9Z%eI=LSZ&ICQqyZypE2diRRZRMs? z$0buoPEv|y5>Z%W@UP`xk#e7qb1}YHx-wI8cTdV2cK_?L>?Tj#I+o%SvROR$S{suT zX?7pbq>v-n!#}S2Y8*&(9`Oi}`c$ZOlYzqlZIc=GWOL)xE(x2BxTn^eN8q!`6Yd<p z=tL_}D3Nf1S)e=HrtH70Z%{FoUi24sm&OYdEXf#=SooqerrN>dyl^NdRYUNkfnsNK zHe1!MBZW1NQRD4_4B?R9IvxyC(ad6Die6-6+sw@u54rSJHD}#eQ+CyfVrg__te1fS zJk1I3(|+dKHWRdK924{t2SgVtM)4lkx-~aH0jYOQaKUlYQ|qGc_o8Vn(PsVI;{d&9 zNr#h{t1Fn!1e&_6<&BPMX)tr->kPlJmE99wF!xL7mHBUv>0t`wG1KmP9WLNGQV#kj z{79OkM5ZZ8(RAHxX<&m5;&^%Ii1eveey!@bpWXKrOHL*V23%3-Cs8uz(3L@_6h1dz zBv{xrz42#m#c8!2a_S71`mTw|Scj#4{`9sZe`tx5%{F++*~v|5c}w`!Q#A-w8K07S z!*kksX*{jgw;(n|#S+m*^`4{fT~5OgREQ8(5gTLSQbJ_|E9`Mo6)i17T;o|uK*mIR z8jfa>na>9zS;+9}MaFgc#Vc!SYC>(uL0oqPJBurJeMH{PYjb5p`alsYf6qbNk*@<R zK$(G;A34$`1X~Y}uT{}hIY8NvtEcp9LfXh~RCqeFP-hcS7NAL*leEaq+qZ9B7m0|s z2ljJn{}Te^LZz^bmp+M0(_%#fLJb%mSS&y9gF}!Jxfr;Nif*l4J~89xwtjLW7HHn3 z%LJjcx;P<%8PK4AJCO_pTWJ#6HC!x&_Q?JxpV0-1B7+)l4H`RcfOi%<PeH_Ee&{tn zE?7WTd_iG77}`jD3@lFLDZ`H9uv1xx0U%w$b$tdmA;2e)J8#~dcZGtrJ^<pK#oI); z4#iY@VIf85cQ@&<_+=ze_s6sl)|5N~j}IFo85$C-u+^ke^z9g2XcB0x(1vwnWrb*H zC@R{1-Y5NVS^`qfnZ7atwa3k9wyc4-+D08RJz<Gjz!mp%z3Va|$_6q(>dfZuEP_an zz|P+YVUFd`2MB%Dr9S9V!>p6_J>ZJH!<u0=@MXF_3a13TBz5?_g^U|N63BTSjs+Y6 z#caPh61pnkiS&jDhFszZ?##9%JecB@^J6WwC*Qb##$Bn#q>*J=OY@N=n^<G5d*1)L zi@1SI>ugjDYj?P!81R$emxAhFvz+BsOn<hzCBEJp?Xq1Yip85<tw3JfxvygndbYrM zc0Xa?dPhamwd0>d+WqOrf>mcJY+4B>m7!Dxy~<yUr>?6d=A*3}UY-MU6P%S_=(C%d z!j(L5a|jaVvw@}w@{`7EI`>K=0s?a4b3d4ye>7WZ@LS%bvw2HEd7@lj)9(Mehvi1M zkXcVNZhBG3i|PmLXf*b3lt(oA+&Vf2ki$Qzc>~SDI{gAkj`B=gh_o7Ed!sOfm#yY} zlFZbro?rYz^MWMW)5d{9%t%fpw)*)fOw@Xb*a~RjfLMM0>1A`Rnx;gam0FU#qEymC zw5W<|ODm6&rlZ3VF(>Q!=G*fZ?><;5lTiK;*%jgP=e&r(V>zwEubMle#@piTM_)FL z7>tc~Hg%F}f4-<=UENU^G#(nA{PLBU%4KvOI346=M5<#a)G`IxXv5OQz5moG9GZ|= z)*D$&j+;jt&0~9zH#5Hd6^&m%T{Pr+?`wi=haj&`i|T5lbki%U$eh{_L8;Lq5v|Hp z*a5J-H4X|V&fMV$iyrK2Mh)ag5c1<I())`a)$e<V8;yOV{3=S#h#T3c<t%#OdNiEx zfi-r2#!FmD2ur-6?utEmrR*nyO7#_a^=jOukC0|Rs77tM^xMGF$Ec_?q8^g!Rnu_c ztzgGka&FzB_=+CEu|npZ*)Y^@Ou5l@Us!C_iQM<_dyxu;ha`7ue;Kp&jR)EQ_U+xF zXf`ZOvLB6!zNFEb5jT*mdUa=Xh}HGdUlUQSi>{YqQb9r4UNsdpOQ=M9LZS`AT?BFm zlheMR0uPHn9`=a02OMNKTsH#>I!MGWG36WcUg#RIQw|-?Wz;cn$Df3pmjcwxE2wNh zk{IR2E5jxv##!M{D6Y3o1A6l0a&Nmyl5F_Mdlb?T@b$DvrMYL02{Wbk!c^{vT7(%a z7w|RT=5vq3GO^7W%bpUJcW=7G!Wm-$sBZ}g7heth`1+ka$7A4z`mXs{#@S+!@A2?k zJI-8ya*kZqTp#5#Z<M?dyM8KYt4-6OZrDj3Kph^%<=f80%SzahXR^BJ$V&9IZ?5={ zLCAyU!Q$W+ZuIcd%I=d_DB+p%Ww|yMdTOj1Frt@AK2CU&+G`!2v}sin5TaF2ld`)d zU40JiEqv!m?F}lP(M@^bfu<5OPYO<|$vGK+DxONPCykb_u+5$>9c@3NU0q_hr3&rw z5gwxr^vkWEm#3YG>j@Z@JnQD#m<(P3wLNRyFMaOBcMcf0F>27buQm0L9dEqu=gnOo zOuy(8KDoAEn14c=V?51JDR{>pgh1#{BTj)NIe21Iob0UYcictyIG@-ONRe=Mus1Sk zDUDe)D47>wjlAS@bxrZX_A)ccfcLc=OlJ9swq+Wm^Lw%k?lDnv%lA$kSf86<9y+Q? zA%&Y~;or*cPvQ)SmgmkLl9a2w+ykdt^2FRW-Eq;0_AX}1NJH7-?UixCn=6a6ZiNM+ z=Y`rA*%e@4F)?x5EhRBD+uk$dP`~?Wk*|jRDZ5E9fXcSz?-!`fPAk(>d$KNE-5`_l z#<djJ-MVd!meh);dxYid_Z;NZWR`s%w0TV=dOSWG?II3TK6N37+5UMSNU|vqoT4QH zm2chiR_(#5-oF)tWxhwSj-6YV0msrXV25LJ&N=m2M8UE5u|WMAz~z+!{XkE{CR)7+ zBUN5SIY(R|#q29km5be65d-t4$fs`yKDeZ$1ir*Kh$bR>XTvX_426F9YwJF}l5x8U z$Z<SKK8LtZ^r@j;yjIE;4;6;^_)A^7Dz8DM$L+d@7>R^-gY*I@)royc##U@tx}jR> zh0#4%PwgjE>x-Io%?WA*2{ZrZxTGSDUi~)`?ORb5O9*<j4|Sup4Zl@~x;gU6qlTgN zawBBdX;(fuu%vQZ8w9X+`Xr)@UTubmA*bPM?Y76A4;p0ASffK<n+fq5ya|toj>C%h zHh=Vh8Ph&CV>~jFIDrUZIxatUszkCzmM%~=ZRNSY{@9k5WQ;zZQ6&ZHtg4dz8^sL? z8hHX$ezQwtYM1*P_sdIuiXO{>ojJ8LDO}q|*^}-L3iAY9{}8t3OlSf#I5}&?e^GDA zo&!QiDF4Ny2dwASUdDa5;-dKbj}@2B(?UkEG~Z{i!pltf;cHmY;l8C<dryw7up7)} zS-yFP+o5<kR5LvOI@!5mwG?oWUQ(jXsKV}}E@WfMY-ht!)3!ou05k^Tp*pPXd74_Q zP5D6~Wut;k8SzOgGlgkIuEGW~%QNADo0j4<Ux35yxZ=n@wpcS8l4R1umY;N4GN-ui z<2Xa4#g}W#swpW0Hv)uZGTp?;0&8*Eu><VK4HVb=%Vb9?(w1H~NpN;iR5y+O-aUrb zO47p4RSHQ*qGf%stHPl+gC@vfej|4N*R|&UQLhZ2nj0HSQfoi9nFvKM(yTq*-jayM zm&tGC+|s#AFJ)90X|5|}EJ(U8)+h)?4m~`3of58iq?$iSp(D#wNs*|RUz7QUYA)JL z_)e2RiKwyqtL7&T(B_*>zsTg2um1Fn%ELy>Byhe~r3(53zx^7E6_t!uzKZ!!nH4=E zG6%|^pPW0-`OA@dTvG@{k&wB5y=YulI75)lgVz^%3>c!8mNbD<kFI+H>ZEKB!*fw6 zt{wo;fR*cLz&f`xKn_HlQ%(mWNWbDmh%`HX3?kV9-ydk-!qMQpcI`vx*iCiykeP%4 znrBx{+Z(M~i3YAhm&a*O&fwr6cIG1=r37PPIfhW71%TS|S}fLH1~Ar)cM$H)A^AsJ zpA&Hk%iX`SMR8u-K`n&o$^SYr4Xfu5I{-BJB`7F31uy~x173_~nQ!PO-p$$lPYCJn zViqBj8<~6jBdK6P5fL+l7D|+esQ~o=C+N8$|A*R-h=3L40|gqjZFtpXIUgN09R~a{ zuCdi`&B9Gn%!<GK&eeo981?QL{_Wr`rWL8$sZYDV;b7*C9~i0?gRTc}wP~z!F;-Z7 zo<c5E23ER0`Kq%)Yhlxr07w(u)!O^N?vd@Wlk$Aj(loiVQqbJ2wJpbqfKKfujU9|1 zKH6UE=BhnzeOg}8wDS1pd^@>H{&4Dg5!;$l|GJm{``~$#ytMm5S3;lDy91!_{-tH{ zXxarGqlDyd_01lk!bxdHWs_}BvkCyz%O>5`e^?>2=5J8N9en)*B{-Lx`FMA#OE_D+ zNhhOge!<hwBUOYtV%teEHi8A}%NyA};h_}p_3obf)57w@hq$!O(l7FzwiC)ay%x77 z&EE2imn|`_YhSZdrBFdH>dhUpsw@Rd<7K5Ww)!Q5gN+phszp8MgGi1EJbi4d=E^&S z@>vY>I~fkrQz0>2%Fh^gH)@J&=du<Q#<~}lyeA|!nt7ak?Z^7Y?1a0;cZ1b(b<#No zk4OfFz|}OKG<-PKE^P38+flJCa`qAZVOaqM{5g)3sT1|$b*`puiSdU5OhxBLQh}&{ zS@E~5sox-R`W<}<pqk=THEL;XBA`4n_jbum_~%igLn-?fmzc|1Yxx&}@GZu|)sD95 zg6a#d5Eo|<Rbr@y&|B!0{`QwH4<moM;b0S7YBs<_&|H~ZxsMhxA7b-}i5<E>H^iSt zV>Fo)J)j^xMH$KJmq(fb(tE-HbwU7f-Fy8HgnIGcxICV?h4!tX-F-m#jNK@P!g*+i zr^N1OM{{3R;qF4>HM+1Bbbv%}Lv%m$0Y@}yA?&Szb=Q#E2Z+-J0$qZ^$jxOQvqOy3 zo;`cCSq8yPy72{8a^#(_Vq(nnOTBMqmLPFq$IZ?7Y~UKivUi~hSM3fOuG2;qy!P_F zRjYR^62A~ukP*6Xb%()#Fl&6j>u7wdR^C50zlI<}r|`6Tg-tYRHH8kyZ<3imX%J#r z3K~lQ!gd08E!$vpk}2|zIvZwx-=t;l;1%E0UNk`A<ikYf#JU%Bs`jGRT&*c-EA!C| zgrkQ!2ewu3BUOpAjMAlt-8zoY{;}ETqbKZl{gK1ecc8*D!LT6ABG*~y82kob=6es( z&Pzp#&z8TW@37j*?Pr^iaA@PJo5B9ZkkP}ouH?6gL*;kt-<5#<d=l!yo@2d~ueSi2 zSB$#ys3*E+QX|u<fpXw;aIo4Yb4y|Va^Qy!-a>QcJB+^CnE_mGcK=!OQAveN>a7O1 zt|&4GHd8eZ2kO{OxEnboO;1dzCL$>3KC3^gR>R%|!Qc%7T{kgt?I8Pf_|vyEuOAd? z7hCljOj&nyHJg7CI@5$b47|VQwes(ok11h+=7wHfXP51-R35^dpmo~`bK$dwt%B@% zJb_ax7kT?kHoaCuMC9w`egj=*5VDnU1~ZV=6$)(1zAx(KBs-<_f#-~}<#nAQs~|LB z&wG_}u|<j1S}yX-#fbkEU}ynme?WXd)8f-lZQVZ2Cc*$_b&^;O6mNXEec;TERws4N zYRH%g!-EBf_55+F7IjsL?>1K#tnOS;kQi1j>X+aoJ72%O{zft=Bm%T9et(<M7rOx+ zXl3LpiT7N;9<P7rKC<@vw&5-MB`{dh;ZiC1@nNS`HGhk)7BNHsDL=fFY9Ij*fO{EW zNxh-3L^_?>0gvAv#oMEyUVdtQ4_RI8V)q(90&x&L&jOAh8okUaq_B9gMEb~y=k|cp z?z_oIN)|ttKKe$y(-yk#p7yV0YlEF)H3Ddb7sU-Cqn%g34jOqD1rso}?AYNP$W_Yx zSh@r9QYNzcYec51Gy{)!5gNfT`r^YWpy9PmI;4wJBY!&bjXc@L9VfZ|RB_)fPwT1L zpo@Hc<*kI^Kvegz#@yR$V+})!dx{y!=MrT<+~$;54yLpg^?$Su_$*)a<}6$0z~1{u ziBJGhx0I(Bw}aN9>u^(QZ$4=SKFqcu?An5Oa6yibMALM~B#gnUTUYL|@{=4~)HZDy zPb#{R|Fib=!w*7D)DZo0QtV7w{tC%CPkYKL+o`6qbt=Af_Kme(F+nc@xH=G49&&3n zHIS9(%uCb0(p!q-onqF;p&+VYbg}UfX^>{7EH$T!YK=TSG}YN8>T*kioMJ*i+>75z z&WdXqC4DGp&ye3s-^<UR<LPN`V(O4awQ#Kb^rs4aM<H8R(8gUgGTTs%LTO_0((ch! z9}Vk`zY5$YcWWxAbC?{vHy(h@H}v}rY4=+<E?|e9j54p9qd#*|Rw<`&rg(&j#g!zr zdbRswvQ;u8lojZF>)Fm`F4;+q?Igs9ZDZS|bQn4F##3A4jM>?uZpWa;MK)?2EWSub z=ps<gTeAq288ZDHQ$qX>^N#|p5yb_~<GW2RSb*KMff9d6QR4ck{RH4!+q?%WuWz^* zWC*%N!iTQ^xdubcoZils%|RgNA-%j=&9(hm!yoW)XPJvl<<AxM?;xHDWh>T*mZD;F zW8<qKM<T}toCkgsV;lHYXLA&y3q<H+6p@bwPue2_psC9*iaB(gEzG7_WwV!A*{s6r zB4T`SO0FKR(Ee#=JVVCXvG)mTjL-Zn>IXIj&pW#U!2Lk7hO!=o1<<&Dx7!bMnmZOk ze8Of|4A?PmupS-1176M%>niU0u$AApZkwexK+AvB{@WkPSB*_t4z?S=qA&iT$)Tpm zyQUA*mlx~@kIhtm4JhQ-xuwBs1`8VFWnN!zsi#x(tGahLw<*-$YD;bM>3L?VQC!m) zrbjDC>UeYggZ}wg<QWyNRqLU-H&)=Os__@ARLXQeMSKTb<^5ka>CN8sXLq;q_k0PA zCt(Ak(FH*h1=w@9BLCn@3_X*YzLt~Koyy9_XV=Eod^LE_wLD0AJ~$ZAVXGZ3RsRS= z4EoK3WfGb%=Ga7Ou;yl1`Yitz=_3TBzHS_7ZJuT=x3qKZ^SFpTgX|`Z--wN2=98C7 zj(Fa_l6GIWtY#1k(M$Z}bw6u~yXGB!J`IsN^R5SIHuNPI+r364OO~b*6HQu$XIk3l zXI{Z5S3&;ksIWL!x<UBc>{z`Tib}!_L(R;g_9AfwHF%uX3O@;o&CGle-6~EcJjT}6 ztnmYIGXa3Qq19q7G2YrHs%>74T3oc8_lmOBGsD)lx|KDij*eeM+}w1EYi#MbfCoqm zaSIz<-O2Lez>~`myWLM>l~=41$`y2497hV#@e6wiimzFK7-s?|b>Er8SfB(-m@OLg zejY2hYWex_v3rh+-g1&*&?|3l+yeg&us{3b10wD#<*97ZMMGqHV4D2Xu)~Z*l*sf> zEjY^8b_w02y`xBDa-0Q{cI4t2t}VQei-|!B@6AK?HdtDdVji#A*aQRxJ+0p%$s{s! zomWy(6r#_K65-_bFnZoQckVpgu{hqA){(k_aL%IlKWQh{5Q%5cuigmBt~Gj!_(P|f z0Xl2r7Ha{=FC<E5RF4px039gy2@!JU=W+<-krBv`&?r!@rR`prltsIwrlT{-HI2H% zljRy`;dD1We{{6CN@zRpwo%l4OsTXQ`pk?b=5nF4x{y1}Fi4mgtxfH+Hk9RP%e5Ty z#cGIKReDG=BemN=Kz<<n*Dh2EFIfaX1g5RihQ$lne_c)9c$NBk!eopvM5Tk*^7!Ma zq<d#hoG|nJ(<9@{f#Oerevp_Od3xt21p_}&NhT3npZ3(|CZr5(7o|$Yd2$qo=Oup> zavNDMAoO5#-niWc2k+SD{Ct+@&XfpETu)Y4kIyM*scrf90fT_1n*$?2=d1j@fXftJ z>y-|_6(egW!J6f0|M<?K*K2@15T)c6#V#GVVLop*(`*-Q>TLI=v_4JHlVQL@2U!d! zbP9SQR^z-H>}*wXWyjl&XpOZWwPS`v6D~MLYjq7aaq!xP1(+KWS}N*{Ntyv~H{MZI zQ=Q&ly|!l9tI*2i;LUzMdp%81Q?V;G-R2d&!ClkcwPhhxFO>Osl?_8r`72|Cp_|yz zAh^gv7EoQ{>l(7oOt<U(Y17X~ox89=#j@XPW^E~tU=yY<+M#M42|W9<!Z6|;Fvn6& zd0RyYVBEg_v4c2kh^P^rK6G@RFGJC<VGV<fA{w4#OZYhY5yrS%?aG0t#A&P3{<R#E zb2x***B75Ag3A`!saOVo3%Q)RnGFv?9FTpQupqVq;`Z-R)-^f6_vs?X4UcBj9U<KW zd%pk4Wo_+uBD;isCzf~8J?IOh7n2^_(ibi8@$)Z$(MOypQnkNOvT<;0_Zhw!3Q^(C zFksAa+ZfXlrhZq@wWSTAIHk-!S5)kmI0;kxnU_i$Hcdp_(tODeClJ!TCvrHbgXi%X z|LY%a6S(V%=R1q{6!%k6nOGki2IW8#$D}WB{o?uu=;1r?>WJ<$+<47ez+aG!m>iE; zHDUM&78jhsaP&kI!HBIJ;R2Kws8m?hd9a1YCyI~N%*QXo_cqif?tdLG;4VPQR|;}7 z_x`pEZ;bpTV#n|KW+>G!HOeZ~!mZN8-(j`;VGcjB;6A0h(29`x%mHazPSq;9D5xVH zX}velNlBiD*SSVbk%}b=bPj#x$gw6ECbRe_ccuN=1#QmePsy4q#v0j!^D3Goru<Xq z@1#4~#c?+7Ay0@WN?%*uT5Iue4yr8eIs=m;f33o^y}n@u!nLz6KNaz_>j;EZix~GV zUHXpBw+GWJI1Q40n>~Cq<6nx{Nle#J76S@PN%0{nDS$HCwz0TR7w#`)Z5GJ1>$}5h zGxqJvaM7A4r=R9PgTZgIwO(m#SrZ#dbSnG1nDXodqmxPw$sS{jih=k^e5maazY!bL zS-VN`JiE$=FX3Q$TkSOaevuUZ?M;1L(XODUEqY-JX;Fh&7TfE{6pi{tre`U0>E^X} z=o$_V?zHJqf44?aZBArY_^uR6o@tpg;m!2k{_Tp2<<jIJ4ifYh3@*=f-d=lsVxeF2 zgSO##L!=TUOj_h2zK;*)lp2R<CYbLy`scSVMzunfx3MWj^mfaqoZ%E=*DAC-_lR(e ztGhzyGC?^aLAfBpW=_c$W_51U<_Xz)#OD}JP=n=eT-d^Wt<v)<Vyb<*II(+P5Y3}Y z#Rn8JAN<_m$G{o8|HuXKWB?u0;lSMZ0*^d(K3d|@1e_SJuYUkjwRfW!>Y1Um&uI8A zDH7Vz(yVWGJt<{JclU6u?cBsb@FHC@)LO6q*&*YQ)z_@lx}lmT5Jl}iNIasZ0z_eC zY|AnLci5x;!SL|nuWaV6$;X{o2%l4%Ln`pN8!=e1>}&T@Pf(AqNV92zhR5Or2`F7U zfU#H-Jr56HE8^a2-^{!8A@AFtyNPWdQu`K9KwM3DFvR7R%gxa67hjIVyX^8Cf(nsH zu=Sw(q0MC;o_tyfemF`+sfoBKU?KHrV4*@a^qzAY%jQatCe{X$<wapwL2YCd9U4$@ zVFAT{@nYNA^F?k-zdS45%s(9xC6SiTu~@Fm>c5IMN~pWQ%4P6V)?GE%-Mpm*{0`y8 zHFE(?Kn}F#iy|1rwT^hOU+F$9WaNUY<=eF}B0=nZn6O-S?Z~$Zub4Zdkt_lpEIBBd zx#~?k1_ujdXTq`;uWc({tcqx{8xLwul<+={sSmD{v@3mpMlx;v{F97!a`Sj)Yu_&T z$dh@7*+z7rf>~1OpAJz6S$hq>T?A3aAu&+#)d|aSB6I-JE5~xDp|>z@7rn#XbX_qd zGnvChs`%o|W_d`Jb97Bs^P}LKI#|<%1d5nD#?W((tW2XBhL~+YxR#?zd6Vl4@q$z6 zl=S11mBCM~Mm)d<Id=H1@V%n;;aO;Tsl%Q=yp?14oCXFjI#~}EPu*?PGfG;VJYX8z z;Q*`gbjwOqwr$Jg;PjxF%dIZRU2!oIVw8a>TW`i{ibHO`o7C$gc8VpL!w0G%d(*0E z+fPY|+!troZB@A#dfdU*<-;sm<Kj~28a)_m<slh>U$oo7akz`V{s$kXtjT4-n%dG_ z?K(RR{=mkP5Och{%6Nmo>H8kYPu^`05FT6MG}cjBw+p(DZ3RZu(=U%uL=h%)P`Xfj z#OWz(deWi~HLP6d5BZTlWR_XZ))g9G%p1sr!x2ac5h+-28lipRErE)E`Gbg!1~m$9 zyAbiQ`%YeA2KCDrP9Xxv+5H}%00N>JA0Kbp`}qkLr>xdiZkMPs3(*tISD3+u5yTV* z3KJ%p+&1*a)|F2yqGaoTc!vJ+6U0oAS!BWN1>3Gv*%8RicKOM>22LeBJ$MA=7S=vE z?oGg*k(GqYgX_XdtBzknOpK-U)*W?dDYWedfKRRiZI7(Rq_VsRBl`;$h`X={175Tt z2S-O5CeGVK_;=%<Kue~u>i>|1h5J4Nj7%`5cZqq2DJ^M(uw!6D5Su%huy;skz+llc zA2l3M>9y|JU+YD1;`Z~H3l#bO{i%mppwsu}61;Y^zIbiSyLZROw|mkCS_)|HZ5G13 z8y)KAM&zjCty}xT9zbuhI$oDZ>{x>6GrYSnf4l_r2du*lwfoCskVpi=7`~5saVki% zy1Ke#2wISE6M`{Ip%-j+<=v>?@e*AtxRc}!@Y@X4hF_6j3q~GNnn!n)=DIH}C+(C@ zEV7JFa~jfY<XS6NwzeK!RbudTCu!9tp{Nt~zdnIp6n*cZ1$$r{kfl^5XMh?K;$VQK z_?b5lN~u7JRaZ5wB-&WuRR(j#QyI+93sc=nz;8$XT#7Kfkd%*;T2q<cf8>mR@VXm} zuv*4F^z3M9s1pM?7^1_)Q*e7=+j;7^XlTX6%TJ1}Z;pNrkZVI(l{DD&o;opl*v=Ky zc(x1_SQnMcEN9vS*3Rlg6_`%R83}udPY$t@m!z}5Cv}ZW6M)Hp$>E}o8#PJje&^@D zE>_cax3_ztIe(YYz28e8=|;9@`5D><jyq)K-AA?^L{nV77>aP(_>3_Lu-hZnH*n+0 zg$wepjm2(#+HqI2ZOY|ONU$UBIpbqUOuFMycWBdCIC@+4NvEM0D;FJm9omsq6uE@x zyjDI_-D)WLLw$~@SvOAx=}qCcM^f4Wji{UbTw7al_Ash&i*6QcO5p^=hEKfV<UxTV zsP)6{qTfrn9?t<KAOvTJ)tw-TS)?3aSMpZp7Ki*ZluWiH4~fevAtoF|(^;#E*Npsr zkf2~VK-m#H^$2<b`(C~82`$Q{2phpp3(3_La{aw8G-#jY4!wT;oF3C3BOHS!5LYCl zHLg3`Us10c-9|{QAk(+Em=#$7+9E|ag*!vbs^WD0><0jZy-1nplKSfpo42XG1WHv< zLSzII5^iOdRWN8oHdC=13p!!s+uVi*6Vo{e^{Jt`JE4j}B!*vrw#dl)mjN6ahc^=8 zXOohVMY~N%y1J-I@iYx*(Pk4iOn_hY0Z`c!;m{H6dQzK`2&@9LK&Ea?)kiL&G7|>6 zisyn#ZKZ5_pb>1b;gZnMcKFlsU|@{swuh1U^4J;O_;L#N&SnOE<bfXvFbf~o_dvX6 zg<&KvmHzOo4bA$WcsIONy?b4y=HtVmk%ZqdM2u#hNU8gYJLJ6$OdnSyY_P|MXws*( zmInI^b|~SsR=W{m4fZ7SQJ#C24=hH4wmSLQ*-UDR>fG|xk*%G4<1iVtbxr*)r06)w z-)CIQSG9(p_zr6mP{4bt3*2JYBi80R4H)#9<v3U0#ulC{`_vOOA<{rM7P@?S#2*@H z<~wf+6Ps<4?wEJkG3%oDb$L*YALDSftjC?VnL%=R;1-6IW~dHnwU#!lWNY|qQWF5_ z(+X1r>?{7uWWN?juMl$wN^tD2aDM?s&U}G|mHV<a44>D*O5*bB=uNPrRST-`2Q2@- ztlYoeJ8CU!rah>;$op%33tkFqiy#M#0K9D5!)x1S1Jm<P)7XtIRKyN6y&>I#sY2ql zqD!01n~eon5(t>hE!IRe&28;RwalsU&H68ft8EtMHSQ-DX~#|SfR)NL3obI}usXh^ z)nZsw;hPWM<Fi&nSGULxxxOpfF)n>>XN~qG=f*18m^*)?pExACML+V~;MiAExlch* zUwsbOV5GkJ7kk~Ka9DrZ$2Q23roKLPrMSiem=*L|>naVC1h2e;{|TG4hjtB$NjMIC z_6Xf!dblGtHkQy#i-jG538Ow=(+oL0fKpI3*-lZ!4yzw>5hBFJyuJ^{DFth2pq|oF zKCmR%LoEBE!bN@z%8%)9pGK5$o0Sn-#qTeZ##4iW<W27?hbrze8YuP)&TU5~>Cc`t zUyop|7C0_o*mkJrX|l<{zyP5Kaukt(hzrQtzP?}npg!E@kMF4w;%kB}7|s|&FzpC@ zen>(#uATmT`9wXsndBKb{o#l|uw6sS7fM5zO3nvOaPi=PCo0Q#90(D|8f$G`M&MD{ zgRj>{TCAa_iuN<RUg5P~hT90=Hy{Hh?)#TlCFegz`sSidl97>F>T8j5w<ClaqQNK` zouK}(T`l~KI|DK2+1?J<J2peA!|8#qEdZ0%4cXBKz_)`$c7ajRY{f2Ptmz~%%ZJEC zg~Y@oZyr%5dp3ANQm2WBciSLit(wqJX*v)i0Oz+hSlo<hf937_OGf5pxtfzY0Jgw( z73#EvP}jv3K5fiR3?w9U2*yR|eTs2aNpqoy>s}M;%`K?j@rEul{!o>grW<S=^<2Nt zOFD<IXP>L3n{4kA1+Wxn<ujUN{8ukfRXLXE*OM&+3&PSRAq{z^AdZ<9nRlACr-*oG zRlNQ)gC8;pzS__gk?(qo^8!s1A@Bl>mvqE-Xc@LIs9jeQa3;SsFOA5BLVuPVlWx+N zut(%+++pBxmBUdhW+t8dZc;!w5_Y%nnVNVzc&cR#WI0rhK~S|3W7PqAQ2+HhXDlVR z55-wa^X6iB_UvkZqF$3M;4!vDV`V&CbhkmKOJ!GHu#%Y^tQJnP!7Sl<wt}2pb@P>9 zCqPtGrsZ2(TgT?wN{@W;!2NSD$t2#SF~?}bTIy~SW|Kkqum;q<v89FOFB1xoDYP&I z!vwioZK#N#e1W04IkNOtQ3w%{BB;_7k%X7ESrwC%q?LT{6Xb2EemYXO=t76*fxngu z5wgUjDaH(*Isf;$j$mN{Y!O~#JPaW$qF0xTubz2{HB1EPhs)D^JC+3s7!Ksx5aBem zOggte!L)+xFmSlF(wR`+BZ3n7L{3;L5cI5cFU@s8kP)wvcJRFNO(laGI@$}s3pCMF zp-aO+;LgQ@UQ?iDJ53U^1}rIcbzJCAfO`zK1sYCS3;5wOfO8oGZAj4NAv@i4>iW={ zi;OX@wY&$wH84#Vm6J=dRVmAT>>%I*wwVX1Cyht#sx>kT^7nY&pi0A~)K}(Z2Knf0 z+juqP<(UOl{DRT3sFZCSHqhLo#^!+%?QX|GtM>L}>-y1Bh(jfU3mjG>a!bYzAMvIA zj~{lKZWr5IiREwZ)U>7FKz0xXAw-S|$k9dsERUD=`;%LCu>Z&Ux~YIv&0??LAu^$+ z*<G@>p8H$B8HR1)O=@ax*2JBQ+7;;^^Z$#Jc#FmFa7<G%v6Jy{zyF)7r-+du)ESZY zfZw&R_Cm~0g=$ezNl8gj(U*~T5Gt)*fmi}9#oNDqkCh<2xqodX*uT$5(dcPr7&lRu zk9_UyT!-xYlofHU0#%>l-exiV5_lWo>ixE54L2bvcO(ioYa)a<P^egY{s;kr8{m5L zyopT0U<?n}Sbby}_|*)XF~udCzo!2DZ)p1c-(!jWZ|Q&j_oMi4Y+nEO%lr4sBeDzr zyN59RyN>@|$N#S5EnEHv<*NL<rT^X1|8D7jxAgza)Tn<?w|`H!e^0l6Pq%+hxBnCI zfYVe`E$z?Pe}}d&kT!OvG2GmS|M>kaef>XCg+C@d{!b>Mp;S5%1BqW3*&_alFWjlR zFX5k@!a6U*f07RWRJ{D3NW=6KszegwzyBoh8T|WMZaMbvBKmjtY}xYfv9aa1f6vP; z|9>uuo&@?GTv8Xg_6}@Z!<l;eft2zCUF`>Y7j&%j@Y@z1E*@@nE<Sc1?mJvU7r1#Y uaPhElab4iz`khoP@&Eb(Gm@^6zQh0b56tj5xf93sH7U8viI?vE`Tqb%zSn91 literal 337907 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%0AAc(J^cD8p9C7pdp5P@7EA%Uc8ZuYkS#qT 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%0AZuyp*Z+WiWZ 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%0Dt|9TTkZlAek&#?-tqAU#E&{inlAFF9a7&NI;;| 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 VZXV%{;0EBw(#+;K!Suql{{jc5CQ<+Z From 50ce875a05389367a8e40be33d0d762564c9d925 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 21 Apr 2021 12:13:20 +0200 Subject: [PATCH 131/462] core-api: fixed confusion around wrong error thrown from routable extensions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/strong-houses-lick.md | 6 ++++++ packages/core-api/src/extensions/extensions.tsx | 15 +++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 .changeset/strong-houses-lick.md diff --git a/.changeset/strong-houses-lick.md b/.changeset/strong-houses-lick.md new file mode 100644 index 0000000000..9739bdfda1 --- /dev/null +++ b/.changeset/strong-houses-lick.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-api': patch +'@backstage/core': patch +--- + +Fixed a potentially confusing error being thrown about misuse of routable extensions where the error was actually something different. diff --git a/packages/core-api/src/extensions/extensions.tsx b/packages/core-api/src/extensions/extensions.tsx index 8ff4055e61..9f6412f960 100644 --- a/packages/core-api/src/extensions/extensions.tsx +++ b/packages/core-api/src/extensions/extensions.tsx @@ -47,12 +47,15 @@ export function createRoutableExtension< // Validate that the routing is wired up correctly in the App.tsx try { useRouteRef(mountPoint); - } catch { - throw new Error( - `Routable extension component with mount point ${mountPoint} was not discovered in the app element tree. ` + - 'Routable extension components may not be rendered by other components and must be ' + - 'directly available as an element within the App provider component.', - ); + } catch (error) { + if (error?.message.startsWith('No path for ')) { + throw new Error( + `Routable extension component with mount point ${mountPoint} was not discovered in the app element tree. ` + + 'Routable extension components may not be rendered by other components and must be ' + + 'directly available as an element within the App provider component.', + ); + } + throw error; } return <InnerComponent {...props} />; }; From e7d2fb93f0a96cb53ae80348eea66b0ae7235f49 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Wed, 24 Feb 2021 16:48:38 -0500 Subject: [PATCH 132/462] Create code-coverage plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to use this plugin, you must set the `backstage.io/code-coverage` annotation on your entity. ```yaml backstage.io/code-coverage: enabled ``` There's a feature to only include files that are in SCM in the coverage report, this is helpful to not count generated files for example. To enable this set the `backstage.io/code-coverage` annotation to `scm-only`. ```yaml backstage.io/code-coverage: scm-only ``` The backend plugin provides API endpoints for submitting code-coverage reports. Currently jacoco and cobertura are supported. These reports are normalized to a json format that is stored in the database. ```json // curl -X POST -H "Content-Type:text/xml" -d @cobertura.xml "localhost:7000/api/code-coverage/Component/default/entity-name?coverageType=cobertura" { "links": [ { "href": "http://localhost:7000/api/code-coverage/Component/default/entity-name", "rel": "coverage" } ] } ``` It also provides some additional API endpoints: * Viewing the latest report * Viewing a more condensed history of code coverage values * Retrieving file contents from source-control, used by the UI Provides a graph of code coverage change over time, as well as a file view where you can see the highlighted lines. Co-authored-by: nissayeva <natashaaay@gmail.com> Signed-off-by: alde <r.dybeck@gmail.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .github/CODEOWNERS | 2 + packages/app/package.json | 1 + .../app/src/components/catalog/EntityPage.tsx | 9 + packages/backend/package.json | 1 + packages/backend/src/index.ts | 5 + packages/backend/src/plugins/codecoverage.ts | 28 + plugins/code-coverage-backend/.eslintrc.js | 3 + plugins/code-coverage-backend/README.md | 150 + .../migrations/20210302_init.js | 50 + plugins/code-coverage-backend/package.json | 50 + plugins/code-coverage-backend/src/index.ts | 17 + plugins/code-coverage-backend/src/run.ts | 33 + .../src/service/CodeCoverageDatabase.test.ts | 199 + .../src/service/CodeCoverageDatabase.ts | 112 + .../src/service/CoverageUtils.test.ts | 325 + .../src/service/CoverageUtils.ts | 168 + .../cobertura-jsoncoverage-files-1.json | 166 + .../cobertura-jsoncoverage-files-2.json | 3952 ++++++++++++ .../cobertura-jsoncoverage-files-3.json | 297 + .../cobertura-jsoncoverage-files-4.json | 351 + .../cobertura-jsoncoverage-files-5.json | 325 + .../__fixtures__/cobertura-sourcefiles-1.txt | 19 + .../__fixtures__/cobertura-sourcefiles-2.txt | 49 + .../__fixtures__/cobertura-sourcefiles-3.txt | 29 + .../__fixtures__/cobertura-sourcefiles-4.txt | 20 + .../__fixtures__/cobertura-sourcefiles-5.txt | 26 + .../__fixtures__/cobertura-testdata-1.xml | 479 ++ .../__fixtures__/cobertura-testdata-2.xml | 5721 +++++++++++++++++ .../__fixtures__/cobertura-testdata-3.xml | 357 + .../__fixtures__/cobertura-testdata-4.xml | 348 + .../__fixtures__/cobertura-testdata-5.xml | 441 ++ .../jacoco-jsoncoverage-files-1.json | 319 + .../__fixtures__/jacoco-sourcefiles-1.txt | 7 + .../__fixtures__/jacoco-testdata-1.xml | 282 + .../src/service/converter/cobertura.test.ts | 56 + .../src/service/converter/cobertura.ts | 126 + .../src/service/converter/index.ts | 23 + .../src/service/converter/jacoco.test.ts | 50 + .../src/service/converter/jacoco.ts | 96 + .../src/service/converter/types.ts | 92 + .../src/service/jsoncoverage-types.ts | 71 + .../src/service/router.test.ts | 79 + .../src/service/router.ts | 229 + .../src/service/standaloneServer.ts | 64 + .../code-coverage-backend/src/setupTests.ts | 17 + plugins/code-coverage/.eslintrc.js | 3 + plugins/code-coverage/README.md | 19 + plugins/code-coverage/dev/index.tsx | 26 + plugins/code-coverage/package.json | 57 + plugins/code-coverage/src/api.ts | 102 + .../CodeCoveragePage/CodeCoveragePage.tsx | 31 + .../src/components/CodeCoveragePage/index.ts | 16 + .../CoverageHistoryChart.tsx | 169 + .../components/CoverageHistoryChart/index.ts | 17 + .../components/FileExplorer/CoverageRow.tsx | 103 + .../components/FileExplorer/FileContent.tsx | 137 + .../components/FileExplorer/FileExplorer.tsx | 280 + .../components/FileExplorer/Highlighter.ts | 54 + .../src/components/FileExplorer/index.ts | 17 + .../code-coverage/src/components/Router.tsx | 34 + plugins/code-coverage/src/dev/index.tsx | 28 + plugins/code-coverage/src/index.ts | 23 + plugins/code-coverage/src/plugin.test.ts | 22 + plugins/code-coverage/src/plugin.ts | 45 + plugins/code-coverage/src/routes.ts | 20 + plugins/code-coverage/src/setupTests.ts | 17 + yarn.lock | 280 +- 67 files changed, 16733 insertions(+), 11 deletions(-) create mode 100644 packages/backend/src/plugins/codecoverage.ts create mode 100644 plugins/code-coverage-backend/.eslintrc.js create mode 100644 plugins/code-coverage-backend/README.md create mode 100644 plugins/code-coverage-backend/migrations/20210302_init.js create mode 100644 plugins/code-coverage-backend/package.json create mode 100644 plugins/code-coverage-backend/src/index.ts create mode 100644 plugins/code-coverage-backend/src/run.ts create mode 100644 plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts create mode 100644 plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts create mode 100644 plugins/code-coverage-backend/src/service/CoverageUtils.test.ts create mode 100644 plugins/code-coverage-backend/src/service/CoverageUtils.ts create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-1.json create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-2.json create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-3.json create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-4.json create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-5.json create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-1.txt create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-2.txt create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-3.txt create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-4.txt create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-5.txt create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-1.xml create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-2.xml create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-3.xml create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-4.xml create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-5.xml create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/jacoco-jsoncoverage-files-1.json create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/jacoco-sourcefiles-1.txt create mode 100644 plugins/code-coverage-backend/src/service/__fixtures__/jacoco-testdata-1.xml create mode 100644 plugins/code-coverage-backend/src/service/converter/cobertura.test.ts create mode 100644 plugins/code-coverage-backend/src/service/converter/cobertura.ts create mode 100644 plugins/code-coverage-backend/src/service/converter/index.ts create mode 100644 plugins/code-coverage-backend/src/service/converter/jacoco.test.ts create mode 100644 plugins/code-coverage-backend/src/service/converter/jacoco.ts create mode 100644 plugins/code-coverage-backend/src/service/converter/types.ts create mode 100644 plugins/code-coverage-backend/src/service/jsoncoverage-types.ts create mode 100644 plugins/code-coverage-backend/src/service/router.test.ts create mode 100644 plugins/code-coverage-backend/src/service/router.ts create mode 100644 plugins/code-coverage-backend/src/service/standaloneServer.ts create mode 100644 plugins/code-coverage-backend/src/setupTests.ts create mode 100644 plugins/code-coverage/.eslintrc.js create mode 100644 plugins/code-coverage/README.md create mode 100644 plugins/code-coverage/dev/index.tsx create mode 100644 plugins/code-coverage/package.json create mode 100644 plugins/code-coverage/src/api.ts create mode 100644 plugins/code-coverage/src/components/CodeCoveragePage/CodeCoveragePage.tsx create mode 100644 plugins/code-coverage/src/components/CodeCoveragePage/index.ts create mode 100644 plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx create mode 100644 plugins/code-coverage/src/components/CoverageHistoryChart/index.ts create mode 100644 plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx create mode 100644 plugins/code-coverage/src/components/FileExplorer/FileContent.tsx create mode 100644 plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx create mode 100644 plugins/code-coverage/src/components/FileExplorer/Highlighter.ts create mode 100644 plugins/code-coverage/src/components/FileExplorer/index.ts create mode 100644 plugins/code-coverage/src/components/Router.tsx create mode 100644 plugins/code-coverage/src/dev/index.tsx create mode 100644 plugins/code-coverage/src/index.ts create mode 100644 plugins/code-coverage/src/plugin.test.ts create mode 100644 plugins/code-coverage/src/plugin.ts create mode 100644 plugins/code-coverage/src/routes.ts create mode 100644 plugins/code-coverage/src/setupTests.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4e21603c63..803ebd6445 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,6 +8,8 @@ /docs/features/techdocs @backstage/techdocs-core /docs/features/search @backstage/techdocs-core /docs/assets/search @backstage/techdocs-core +/plugins/code-coverage @alde @nissayeva +/plugins/code-coverage-backend @alde @nissayeva /plugins/cost-insights @backstage/silver-lining /plugins/cloudbuild @trivago/ebarrios /plugins/search @backstage/techdocs-core diff --git a/packages/app/package.json b/packages/app/package.json index 4d2dbe660a..95e14766c3 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -15,6 +15,7 @@ "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/plugin-circleci": "^0.2.12", "@backstage/plugin-cloudbuild": "^0.2.13", + "@backstage/plugin-code-coverage": "^0.1.0", "@backstage/plugin-cost-insights": "^0.8.4", "@backstage/plugin-explore": "^0.3.2", "@backstage/plugin-gcp-projects": "^0.2.5", diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index d4db2b0e63..601134362d 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -102,6 +102,7 @@ import { EntityTravisCIOverviewCard, isTravisciAvailable, } from '@roadiehq/backstage-plugin-travis-ci'; +import { EntityCodeCoverageContent } from '@backstage/plugin-code-coverage'; const EntityLayoutWrapper = (props: { children?: ReactNode }) => { const [badgesDialogOpen, setBadgesDialogOpen] = useState(false); @@ -303,6 +304,10 @@ const serviceEntityPage = ( <EntityGithubInsightsContent /> </EntityLayout.Route> + <EntityLayout.Route path="/code-coverage" title="Code Coverage"> + <EntityCodeCoverageContent /> + </EntityLayout.Route> + <EntityLayout.Route path="/kafka" title="Kafka"> <EntityKafkaContent /> </EntityLayout.Route> @@ -347,6 +352,10 @@ const websiteEntityPage = ( <EntityGithubInsightsContent /> </EntityLayout.Route> + <EntityLayout.Route path="/code-coverage" title="Code Coverage"> + <EntityCodeCoverageContent /> + </EntityLayout.Route> + <EntityLayout.Route path="/todos" title="TODOs"> <EntityTodoContent /> </EntityLayout.Route> diff --git a/packages/backend/package.json b/packages/backend/package.json index 40e5a1cd2f..984b8b60a5 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -35,6 +35,7 @@ "@backstage/plugin-auth-backend": "^0.3.7", "@backstage/plugin-badges-backend": "^0.1.1", "@backstage/plugin-catalog-backend": "^0.7.0", + "@backstage/plugin-code-coverage-backend": "^0.1.0", "@backstage/plugin-graphql-backend": "^0.1.6", "@backstage/plugin-kubernetes-backend": "^0.3.3", "@backstage/plugin-kafka-backend": "^0.2.3", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index cbbdaecf5e..00ed248df5 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -37,6 +37,7 @@ import { Config } from '@backstage/config'; import healthcheck from './plugins/healthcheck'; import auth from './plugins/auth'; import catalog from './plugins/catalog'; +import codeCoverage from './plugins/codecoverage'; import kubernetes from './plugins/kubernetes'; import kafka from './plugins/kafka'; import rollbar from './plugins/rollbar'; @@ -75,6 +76,9 @@ async function main() { const healthcheckEnv = useHotMemoize(module, () => createEnv('healthcheck')); const catalogEnv = useHotMemoize(module, () => createEnv('catalog')); + const codeCoverageEnv = useHotMemoize(module, () => + createEnv('code-coverage'), + ); const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder')); const authEnv = useHotMemoize(module, () => createEnv('auth')); const proxyEnv = useHotMemoize(module, () => createEnv('proxy')); @@ -90,6 +94,7 @@ async function main() { const apiRouter = Router(); apiRouter.use('/catalog', await catalog(catalogEnv)); + apiRouter.use('/code-coverage', await codeCoverage(codeCoverageEnv)); apiRouter.use('/rollbar', await rollbar(rollbarEnv)); apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); apiRouter.use('/auth', await auth(authEnv)); diff --git a/packages/backend/src/plugins/codecoverage.ts b/packages/backend/src/plugins/codecoverage.ts new file mode 100644 index 0000000000..c06e0e516f --- /dev/null +++ b/packages/backend/src/plugins/codecoverage.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createRouter } from '@backstage/plugin-code-coverage-backend'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin(env: PluginEnvironment) { + return await createRouter({ + config: env.config, + discovery: env.discovery, + database: env.database, + urlReader: env.reader, + logger: env.logger, + }); +} diff --git a/plugins/code-coverage-backend/.eslintrc.js b/plugins/code-coverage-backend/.eslintrc.js new file mode 100644 index 0000000000..16a033dbc6 --- /dev/null +++ b/plugins/code-coverage-backend/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md new file mode 100644 index 0000000000..2e2f5ba91f --- /dev/null +++ b/plugins/code-coverage-backend/README.md @@ -0,0 +1,150 @@ +# code-coverage + +This is the backend part of the code-coverage plugin. It takes care of processing various coverage formats and standardizing them into a single json format, used by the frontend. + +## Configuring your entity + +In order to use this plugin, you must set the `backstage.io/code-coverage` annotation. + +```yaml +backstage.io/code-coverage: enabled +``` + +There's a feature to only include files that are in VCS in the coverage report, this is helpful to not count generated files for example. To enable this set the `backstage.io/code-coverage` annotation to `scm-only`. + +```yaml +backstage.io/code-coverage: scm-only +``` + +Note: This requires the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) to be set. + +## API + +### Adding cobertura report + +POST a cobertura xml to `/:kind/:namespace/:name?coverageType=cobertura` + +Example: + +```json +// curl -X POST -H "Content-Type:text/xml" -d @cobertura.xml "localhost:7000/api/code-coverage/Component/default/entity-name?coverageType=cobertura" +{ + "links": [ + { + "href": "http://localhost:7000/api/code-coverage/Component/default/entity-name", + "rel": "coverage" + } + ] +} +``` + +### Adding jacoco report + +POST a jacoco xml to `/:kind/:namespace/:name?coverageType=jacoco` + +Example: + +```json +// curl -X POST -H "Content-Type:text/xml" -d @jacoco.xml "localhost:7000/api/code-coverage/Component/default/entity-name?coverageType=jacoco" +{ + "links": [ + { + "href": "http://localhost:7000/api/code-coverage/Component/default/entity-name", + "rel": "coverage" + } + ] +} +``` + +### Reading json coverage + +GET `/:kind/:namespace/:name` + +Example: + +```json +// curl localhost:7000/api/code-coverage/Component/default/entity-name +{ + "aggregate": { + "branch": { + "available": 0, + "covered": 0, + "missed": 0, + "percentage": 0 + }, + "line": { + "available": 5, + "covered": 4, + "missed": 1, + "percentage": 80 + } + }, + "entity": { + "kind": "Component", + "name": "entity-name", + "namespace": "default" + }, + "files": [ + { + "branchHits": {}, + "filename": "main.go", + "lineHits": { + "117": 12, + "142": 8, + "34": 8, + "42": 0, + "58": 6 + } + } + ] +} +``` + +### Coverage history + +GET `/:kind/:namespace/:name/history` + +Example + +```json +// curl localhost:7000/api/code-coverage/Component/default/entity-name/history +{ + "entity": { + "kind": "Component", + "name": "entity-name", + "namespace": "default" + }, + "history": [ + { + "branch": { + "available": 0, + "covered": 0, + "missed": 0, + "percentage": 0 + }, + "line": { + "available": 299, + "covered": 116, + "missed": 183, + "percentage": 38.8 + }, + "timestamp": 1615490766141 + }, + { + "branch": { + "available": 0, + "covered": 0, + "missed": 0, + "percentage": 0 + }, + "line": { + "available": 299, + "covered": 116, + "missed": 183, + "percentage": 38.8 + }, + "timestamp": 1615406307929 + } + ] +} +``` diff --git a/plugins/code-coverage-backend/migrations/20210302_init.js b/plugins/code-coverage-backend/migrations/20210302_init.js new file mode 100644 index 0000000000..0edd455e7d --- /dev/null +++ b/plugins/code-coverage-backend/migrations/20210302_init.js @@ -0,0 +1,50 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.createTable('code_coverage', table => { + table.comment('The table of code coverage'); + table + .uuid('id') + .primary() + .notNullable() + .comment('The ID of the code coverage'); + table.text('entity_name').notNullable().comment('entity name'); + table.text('entity_kind').notNullable().comment('entity kind'); + table.text('entity_namespace').notNullable().comment('entity namespace'); + table + .text('coverage') + .notNullable() + .comment('The coverage json as a string'); + table + .dateTime('created_at') + .defaultTo(knex.fn.now()) + .notNullable() + .comment('The timestamp when this entry was created'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.dropTable('code_coverage'); +}; diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json new file mode 100644 index 0000000000..79de777dfa --- /dev/null +++ b/plugins/code-coverage-backend/package.json @@ -0,0 +1,50 @@ +{ + "name": "@backstage/plugin-code-coverage-backend", + "version": "0.1.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "start": "backstage-cli backend:dev", + "build": "backstage-cli backend:build", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/backend-common": "^0.5.4", + "@backstage/catalog-client": "^0.3.6", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", + "@backstage/errors": "^0.1.1", + "@backstage/integration": "^0.5.0", + "@backstage/plugin-catalog-backend": "^0.6.5", + "@types/express": "^4.17.6", + "cross-fetch": "^3.0.6", + "express": "^4.17.1", + "express-promise-router": "^3.0.3", + "express-xml-bodyparser": "^0.3.0", + "knex": "^0.95.1", + "uuid": "^8.3.2", + "winston": "^3.2.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.6.2", + "@types/express-xml-bodyparser": "^0.3.2", + "@types/supertest": "^2.0.8", + "msw": "^0.21.2", + "supertest": "^4.0.2", + "xml2js": "^0.4.23" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/code-coverage-backend/src/index.ts b/plugins/code-coverage-backend/src/index.ts new file mode 100644 index 0000000000..7612c392a2 --- /dev/null +++ b/plugins/code-coverage-backend/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './service/router'; diff --git a/plugins/code-coverage-backend/src/run.ts b/plugins/code-coverage-backend/src/run.ts new file mode 100644 index 0000000000..b96989e4b8 --- /dev/null +++ b/plugins/code-coverage-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts new file mode 100644 index 0000000000..af734dd358 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts @@ -0,0 +1,199 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + getVoidLogger, + SingleConnectionDatabaseManager, +} from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { + CodeCoverageDatabase, + CodeCoverageStore, +} from './CodeCoverageDatabase'; +import { JsonCodeCoverage } from './jsoncoverage-types'; + +const db = SingleConnectionDatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'sqlite3', + connection: ':memory:', + }, + }, + }), +).forPlugin('code-coverage'); + +const coverage: Array<JsonCodeCoverage> = [ + { + metadata: { + generationTime: 1234567890, + vcs: { + location: 'local', + type: 'local', + }, + }, + entity: { + kind: 'Component', + name: 'test-entity', + namespace: 'default', + }, + files: [ + { + filename: 'src/main.py', + lineHits: { + '10': 5, + '11': 4, + '12': 4, + }, + branchHits: {}, + }, + ], + }, + { + metadata: { + generationTime: 2345678901, + vcs: { + location: 'local', + type: 'local', + }, + }, + entity: { + kind: 'Component', + name: 'test-entity', + namespace: 'default', + }, + files: [ + { + filename: 'src/main.py', + lineHits: { + '10': 5, + '11': 4, + '12': 4, + '22': 0, + '23': 0, + '24': 0, + '30': 1, + }, + branchHits: { + '10': { + available: 2, + covered: 1, + missed: 1, + }, + }, + }, + ], + }, +]; + +let database: CodeCoverageStore; +describe('CodeCoverageDatabase', () => { + beforeAll(async () => { + const client = await db.getClient(); + database = await CodeCoverageDatabase.create(client, getVoidLogger()); + database.insertCodeCoverage(coverage[0]); + await new Promise(r => setTimeout(r, 1000)); + database.insertCodeCoverage(coverage[1]); + }); + + describe('insertCodeCoverage', () => { + it('can insert code coverage', async () => { + const ncov = { + metadata: { + generationTime: 3456789012, + vcs: { + location: 'local', + type: 'local', + }, + }, + entity: { + kind: 'Component', + name: 'test-entity-for-insert', + namespace: 'default', + }, + files: [ + { + filename: 'src/main.py', + lineHits: { + '10': 5, + '11': 4, + '12': 4, + }, + branchHits: {}, + }, + ], + }; + const { codeCoverageId } = await database.insertCodeCoverage(ncov); + expect(codeCoverageId.length).not.toBe(0); + }); + }); + + describe('getCodeCoverage', () => { + it("can get coverage that's in the database", async () => { + const cov = await database.getCodeCoverage({ + name: 'test-entity', + kind: 'Component', + namespace: 'default', + }); + expect(cov).toEqual(coverage[1]); + }); + }); + + describe('getHistory', () => { + it("can get history that's in the database", async () => { + const cov = await database.getHistory( + { + name: 'test-entity', + kind: 'Component', + namespace: 'default', + }, + 5, + ); + expect(cov.history.length).toEqual(2); + expect(cov.history).toEqual([ + { + branch: { + available: 2, + covered: 1, + missed: 1, + percentage: 50, + }, + line: { + available: 7, + covered: 4, + missed: 3, + percentage: 57.14, + }, + timestamp: 2345678901, + }, + { + branch: { + available: 0, + covered: 0, + missed: 0, + percentage: 0, + }, + line: { + available: 3, + covered: 3, + missed: 0, + percentage: 100, + }, + timestamp: 1234567890, + }, + ]); + }); + }); +}); diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts new file mode 100644 index 0000000000..44109e8e2e --- /dev/null +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts @@ -0,0 +1,112 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { resolvePackagePath } from '@backstage/backend-common'; +import { NotFoundError } from '@backstage/errors'; +import { EntityName } from '@backstage/catalog-model'; +import { Knex } from 'knex'; +import { v4 as uuid } from 'uuid'; +import { Logger } from 'winston'; +import { aggregateCoverage } from './CoverageUtils'; +import { JsonCodeCoverage, JsonCoverageHistory } from './jsoncoverage-types'; + +export type RawDbCoverageRow = { + id: string; + entity_name: string; + entity_namespace: string; + entity_kind: string; + coverage: string; +}; +export interface CodeCoverageStore { + insertCodeCoverage( + coverage: JsonCodeCoverage, + ): Promise<{ codeCoverageId: string }>; + getCodeCoverage(entity: EntityName): Promise<JsonCodeCoverage>; + getHistory(entity: EntityName, limit: number): Promise<JsonCoverageHistory>; +} + +const migrationsDir = resolvePackagePath( + '@backstage/plugin-code-coverage-backend', + 'migrations', +); +export class CodeCoverageDatabase implements CodeCoverageStore { + static async create(knex: Knex, logger: Logger): Promise<CodeCoverageStore> { + await knex.migrate.latest({ + directory: migrationsDir, + }); + return new CodeCoverageDatabase(knex, logger); + } + + constructor(private readonly db: Knex, private readonly logger: Logger) {} + + async insertCodeCoverage( + coverage: JsonCodeCoverage, + ): Promise<{ codeCoverageId: string }> { + const codeCoverageId = uuid(); + await this.db<RawDbCoverageRow>('code_coverage').insert({ + id: codeCoverageId, + entity_name: coverage.entity.name, + entity_kind: coverage.entity.kind, + entity_namespace: coverage.entity.namespace, + coverage: JSON.stringify(coverage), + }); + return { codeCoverageId }; + } + async getCodeCoverage(entity: EntityName): Promise<JsonCodeCoverage> { + const [result] = await this.db<RawDbCoverageRow>('code_coverage') + .where({ + entity_name: entity.name, + entity_kind: entity.kind, + entity_namespace: entity.namespace, + }) + .orderBy('created_at', 'desc') + .limit(1) + .select(); + if (!result) { + throw new NotFoundError( + `No coverage for entity '${JSON.stringify(entity)}' found`, + ); + } + try { + return JSON.parse(result.coverage); + } catch (error) { + throw new Error(`Failed to parse coverage for '${entity}', ${error}`); + } + } + + async getHistory( + entity: EntityName, + limit: number, + ): Promise<JsonCoverageHistory> { + const res = await this.db<RawDbCoverageRow>('code_coverage') + .where({ + entity_name: entity.name, + entity_kind: entity.kind, + entity_namespace: entity.namespace, + }) + .orderBy('created_at', 'desc') + .limit(limit) + .select(); + + const history = res + .map(r => JSON.parse(r.coverage)) + .map(c => aggregateCoverage(c)); + + return { + entity, + history: history, + }; + } +} diff --git a/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts b/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts new file mode 100644 index 0000000000..5a5cffbced --- /dev/null +++ b/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts @@ -0,0 +1,325 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import fs from 'fs'; +import { Readable } from 'stream'; +import { + calculatePercentage, + aggregateCoverage, + CoverageUtils, +} from './CoverageUtils'; +import { Entity } from '@backstage/catalog-model'; +import { parseString } from 'xml2js'; + +describe('calculatePercentage', () => { + [ + [100, 25, 25], + [100, 100, 100], + [133, 13, 9.77], + [0, 0, 0], + ].forEach(([a, c, e]) => { + it(`${c}/${a} === ${e}`, () => { + expect(calculatePercentage(a, c)).toEqual(e); + }); + }); +}); + +/* eslint-disable no-restricted-syntax */ + +describe('aggregateCoverage', () => { + [ + { + file: 'jacoco-jsoncoverage-files-1.json', + expected: { + branch: { + available: 68, + covered: 48, + missed: 20, + percentage: 70.59, + }, + line: { + available: 162, + covered: 105, + missed: 57, + percentage: 64.81, + }, + timestamp: 1234567890, + }, + }, + { + file: 'cobertura-jsoncoverage-files-1.json', + expected: { + branch: { + available: 0, + covered: 0, + missed: 0, + percentage: 0, + }, + line: { + available: 146, + covered: 145, + missed: 1, + percentage: 99.32, + }, + timestamp: 1234567890, + }, + }, + { + file: 'cobertura-jsoncoverage-files-2.json', + expected: { + branch: { + available: 466, + covered: 380, + missed: 86, + percentage: 81.55, + }, + line: { + available: 2632, + covered: 2079, + missed: 553, + percentage: 78.99, + }, + timestamp: 1234567890, + }, + }, + { + file: 'cobertura-jsoncoverage-files-3.json', + expected: { + branch: { + available: 73, + covered: 49, + missed: 24, + percentage: 67.12, + }, + line: { + available: 110, + covered: 91, + missed: 19, + percentage: 82.73, + }, + timestamp: 1234567890, + }, + }, + { + file: 'cobertura-jsoncoverage-files-4.json', + expected: { + branch: { + available: 0, + covered: 0, + missed: 0, + percentage: 0, + }, + line: { + available: 325, + covered: 0, + missed: 325, + percentage: 0, + }, + timestamp: 1234567890, + }, + }, + { + file: 'cobertura-jsoncoverage-files-5.json', + expected: { + branch: { + available: 38, + covered: 21, + missed: 17, + percentage: 55.26, + }, + line: { + available: 175, + covered: 124, + missed: 51, + percentage: 70.86, + }, + timestamp: 1234567890, + }, + }, + ].forEach(td => { + it(`processes ${td.file}`, () => { + const json = JSON.parse( + fs.readFileSync(`${__dirname}/__fixtures__/${td.file}`).toString(), + ); + const aggregate = aggregateCoverage({ + metadata: { + generationTime: 1234567890, + vcs: { + location: 'foo', + type: 'foo', + }, + }, + entity: { + kind: 'foo', + name: 'foo', + namespace: 'default', + }, + files: json, + }); + + expect(aggregate).toEqual(td.expected); + }); + }); +}); + +describe('CodeCoverageUtils', () => { + const scmFilesFixture = fs + .readFileSync(`${__dirname}/__fixtures__/cobertura-sourcefiles-1.txt`) + .toString() + .split('\n') + .map(f => { + return { path: f }; + }); + const scmIntegraions = { + byUrl: jest.fn().mockReturnValue({ + type: 'local', + title: 'local', + }), + }; + const scmTree = { + files: jest + .fn() + .mockReturnValue(new Promise((r, _e) => r(scmFilesFixture))), + }; + const urlReader = { + readTree: jest.fn().mockReturnValue(new Promise((r, _e) => r(scmTree))), + }; + const utils = new CoverageUtils(scmIntegraions, urlReader); + + describe('validateRequestBody', () => { + it('rejects missing content type', () => { + let err: Error | null = null; + try { + const mockRequest: Partial<Request> = { + // @ts-ignore + headers: {}, + }; + // @ts-ignore + utils.validateRequestBody(mockRequest as Request); + } catch (error) { + err = error; + } + expect(err?.message).toEqual('Content-Type missing'); + }); + + it('rejects unsupported content type', () => { + let err: Error | null = null; + try { + const mockRequest: Partial<Request> = { + headers: { + // @ts-ignore + 'content-type': 'application/json', + }, + }; + + // @ts-ignore + utils.validateRequestBody(mockRequest as Request); + } catch (error) { + err = error; + } + expect(err?.message).toEqual('Illegal Content-Type'); + }); + + it('parses the body', () => { + const mockRequest: Partial<Request> = { + headers: { + // @ts-ignore + 'content-type': 'text/xml', + }, + // @ts-ignore + body: Readable.from( + '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><report name="example"></report>', + ), + }; + + // @ts-ignore + const data: Readable = utils.validateRequestBody(mockRequest as Request); + + expect(data.read()).toContain('<?xml'); + }); + }); + + describe('processCoveragePayload', () => { + const mockRequest: Partial<Request> = { + headers: { + // @ts-ignore + 'content-type': 'text/xml', + }, + // @ts-ignore + body: Readable.from( + '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><report name="example"></report>', + ), + }; + + it('ignores scm if annotation is not set', async () => { + const entity: Entity = { + kind: 'Component', + metadata: { + name: 'test-entity', + namespace: 'test', + }, + apiVersion: 'backstage.io/v1alpha1', + }; + + const { + scmFiles, + sourceLocation, + vcs, + body, // @ts-ignore + } = await utils.processCoveragePayload(entity, mockRequest); + let data; + // in normal flow the express app will already have done this through the middleware + parseString((body as Readable).read(), (_e, r) => { + data = r; + }); + + expect(scmFiles.length).toBe(0); + expect(vcs).toBeUndefined(); + expect(sourceLocation).toBeUndefined(); + expect(data).toEqual({ + report: { + $: { + name: 'example', + }, + }, + }); + }); + + it('populates scm data if annotation is set', async () => { + const entity: Entity = { + kind: 'Component', + metadata: { + name: 'test-entity', + namespace: 'test', + annotations: { + 'backstage.io/code-coverage': 'scm-only', + 'backstage.io/source-location': 'https://github.com/example/test/', + }, + }, + apiVersion: 'backstage.io/v1alpha1', + }; + + const { + scmFiles, + sourceLocation, + vcs, // @ts-ignore + } = await utils.processCoveragePayload(entity, mockRequest); + + expect(scmFiles.length).toBe(scmFiles.length); + expect(vcs).not.toBeUndefined(); + expect(sourceLocation).not.toBeUndefined(); + }); + }); +}); diff --git a/plugins/code-coverage-backend/src/service/CoverageUtils.ts b/plugins/code-coverage-backend/src/service/CoverageUtils.ts new file mode 100644 index 0000000000..0ed1561003 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/CoverageUtils.ts @@ -0,0 +1,168 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Request } from 'express'; +import { UrlReader } from '@backstage/backend-common'; +import { InputError, NotFoundError } from '@backstage/errors'; +import { Entity } from '@backstage/catalog-model'; +import { ScmIntegration, ScmIntegrations } from '@backstage/integration'; +import { + AggregateCoverage, + FileEntry, + JsonCodeCoverage, +} from './jsoncoverage-types'; + +export const calculatePercentage = ( + available: number, + covered: number, +): number => { + if (available === 0) { + return 0; + } + return parseFloat(((covered / available) * 100).toFixed(2)); +}; + +export const aggregateCoverage = (c: JsonCodeCoverage): AggregateCoverage => { + let availableLine = 0; + let coveredLine = 0; + let availableBranch = 0; + let coveredBranch = 0; + c.files.forEach(f => { + availableLine += Object.keys(f.lineHits).length; + coveredLine += Object.values(f.lineHits).filter(l => l > 0).length; + + availableBranch += Object.keys(f.branchHits) + .map(b => parseInt(b, 10)) + .map((b: number) => f.branchHits[b].available) + .filter(Boolean) + .reduce((acc, curr) => acc + curr, 0); + coveredBranch += Object.keys(f.branchHits) + .map(b => parseInt(b, 10)) + .map((b: number) => f.branchHits[b].covered) + .filter(Boolean) + .reduce((acc, curr) => acc + curr, 0); + }); + + return { + timestamp: c.metadata.generationTime, + branch: { + available: availableBranch, + covered: coveredBranch, + missed: availableBranch - coveredBranch, + percentage: calculatePercentage(availableBranch, coveredBranch), + }, + line: { + available: availableLine, + covered: coveredLine, + missed: availableLine - coveredLine, + percentage: calculatePercentage(availableLine, coveredLine), + }, + }; +}; + +export class CoverageUtils { + constructor( + readonly scm: Partial<ScmIntegrations>, + readonly urlReader: Partial<UrlReader>, + ) {} + + async processCoveragePayload( + entity: Entity, + req: Request, + ): Promise<{ + sourceLocation?: string; + vcs?: ScmIntegration; + scmFiles: string[]; + body: {}; + }> { + const enforceScmFiles = + entity.metadata.annotations?.['backstage.io/code-coverage'] === + 'scm-only' || false; + + let sourceLocation: string | undefined = undefined; + let vcs: ScmIntegration | undefined = undefined; + let scmFiles: string[] = []; + + if (enforceScmFiles) { + sourceLocation = + entity.metadata.annotations?.['backstage.io/source-location']; + if (!sourceLocation) { + throw new InputError( + `No "backstage.io/source-location" annotation on entity ${entity.kind}/${entity.metadata.namespace}/${entity.metadata.name}`, + ); + } + + vcs = this.scm.byUrl?.(sourceLocation); + if (!vcs) { + throw new InputError(`Unable to determine SCM from ${sourceLocation}`); + } + + const scmTree = await this.urlReader.readTree?.(sourceLocation); + if (!scmTree) { + throw new NotFoundError(`Unable to read tree from ${sourceLocation}`); + } + scmFiles = (await scmTree.files()).map(f => f.path); + } + + const body = this.validateRequestBody(req); + if (Object.keys(body).length === 0) { + throw new InputError('Unable to parse body'); + } + + return { + sourceLocation, + vcs, + scmFiles, + body, + }; + } + + async buildCoverage( + entity: Entity, + sourceLocation: string | undefined, + vcs: ScmIntegration | undefined, + files: FileEntry[], + ): Promise<JsonCodeCoverage> { + return { + metadata: { + vcs: { + type: vcs?.type || 'unknown', + location: sourceLocation || 'unknown', + }, + generationTime: Date.now(), + }, + entity: { + name: entity.metadata.name, + namespace: entity.metadata.namespace || 'default', + kind: entity.kind, + }, + files, + }; + } + + validateRequestBody(req: Request) { + const contentType = req.headers['content-type']; + if (!contentType) { + throw new InputError('Content-Type missing'); + } else if (!contentType.match(/^text\/xml($|;)/)) { + throw new InputError('Illegal Content-Type'); + } + const body = req.body; + if (!body) { + throw new InputError('Missing request body'); + } + return body; + } +} diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-1.json b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-1.json new file mode 100644 index 0000000000..b5b861254c --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-1.json @@ -0,0 +1,166 @@ +[ + { + "filename": "src/main/scala/com/example/Main.scala", + "lineHits": { + "100": 4, + "103": 2, + "104": 4, + "105": 4, + "112": 2, + "114": 4, + "115": 2, + "124": 3, + "125": 2, + "126": 3, + "127": 3, + "135": 3, + "136": 1, + "138": 2, + "139": 1, + "140": 1, + "143": 1, + "145": 1, + "146": 1, + "147": 1, + "148": 1, + "149": 1, + "150": 1, + "160": 2, + "163": 8, + "164": 4, + "166": 2, + "167": 4, + "168": 6, + "169": 6, + "170": 4, + "178": 1, + "179": 1, + "181": 1, + "182": 1, + "183": 3, + "187": 1, + "188": 3, + "202": 4, + "203": 6, + "204": 4, + "210": 5, + "26": 4, + "27": 4, + "28": 4, + "30": 4, + "33": 4, + "35": 2, + "36": 2, + "37": 4, + "38": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2, + "50": 2, + "52": 2, + "53": 2, + "55": 2, + "56": 2, + "58": 2, + "60": 2, + "61": 2, + "64": 2, + "65": 6, + "68": 4, + "73": 2, + "75": 10, + "77": 4, + "83": 1, + "84": 2, + "85": 3, + "86": 3, + "87": 1, + "88": 6, + "95": 2, + "97": 8, + "99": 2 + }, + "branchHits": {} + }, + { + "filename": "src/main/scala/com/example/Other.scala", + "lineHits": { + "103": 6, + "104": 2, + "105": 5, + "109": 1, + "110": 3, + "111": 3, + "113": 2, + "115": 2, + "116": 2, + "117": 2, + "119": 2, + "123": 3, + "124": 1, + "129": 7, + "132": 2, + "133": 4, + "134": 2, + "138": 1, + "139": 2, + "140": 2, + "142": 4, + "143": 3, + "144": 5, + "145": 3, + "146": 5, + "147": 3, + "149": 2, + "20": 1, + "21": 1, + "23": 1, + "25": 2, + "26": 1, + "27": 2, + "29": 2, + "31": 2, + "32": 2, + "33": 2, + "34": 2, + "37": 0, + "42": 4, + "44": 2, + "45": 2, + "46": 2, + "49": 4, + "50": 10, + "52": 4, + "59": 5, + "61": 4, + "64": 2, + "65": 1, + "66": 1, + "68": 1, + "70": 4, + "71": 2, + "72": 2, + "73": 1, + "74": 2, + "79": 1, + "85": 1, + "86": 3, + "87": 1, + "91": 1, + "92": 4, + "93": 3, + "94": 2 + }, + "branchHits": {} + }, + { + "filename": "src/main/scala/com/example/utils/Util.scala", + "lineHits": { + "13": 2, + "8": 4, + "7": 2 + }, + "branchHits": {} + } +] diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-2.json b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-2.json new file mode 100644 index 0000000000..ddfcc729fd --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-2.json @@ -0,0 +1,3952 @@ +[ + { + "filename": "src/index.ts", + "lineHits": { + "1": 3, + "3": 3, + "5": 3, + "6": 3, + "7": 3, + "8": 3, + "9": 3, + "11": 3, + "12": 3, + "14": 3 + }, + "branchHits": {} + }, + { + "filename": "src/utils.ts", + "lineHits": { + "4": 104, + "7": 1178, + "12": 20, + "16": 2, + "29": 3105, + "33": 1601, + "37": 15, + "56": 20, + "64": 42, + "65": 2, + "1": 18, + "8": 589, + "9": 589, + "15": 1, + "18": 2, + "20": 0, + "22": 2, + "28": 18, + "30": 776, + "34": 1601, + "42": 158, + "48": 1, + "53": 15, + "57": 0, + "58": 1, + "60": 19, + "61": 19, + "63": 19, + "66": 2, + "67": 2, + "68": 2, + "69": 1, + "70": 1, + "73": 19 + }, + "branchHits": { + "8": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "57": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "68": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "69": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "73": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/controller/VideoContextPlayerCoordinator.ts", + "lineHits": { + "50": 8, + "74": 66, + "137": 33, + "143": 5, + "157": 18, + "217": 5, + "240": 5, + "309": 48, + "343": 48, + "357": 48, + "405": 8, + "420": 20, + "442": 19, + "445": 1, + "460": 20, + "466": 20, + "480": 16, + "488": 8, + "520": 16, + "530": 14, + "619": 0, + "627": 2, + "636": 0, + "640": 8, + "651": 8, + "661": 12, + "673": 37, + "690": 8, + "711": 7, + "736": 4, + "740": 29, + "1": 4, + "2": 4, + "31": 4, + "33": 4, + "37": 4, + "39": 4, + "41": 4, + "76": 33, + "77": 33, + "78": 33, + "79": 33, + "80": 33, + "81": 33, + "82": 33, + "83": 33, + "84": 33, + "85": 33, + "86": 33, + "87": 33, + "90": 33, + "91": 33, + "92": 33, + "93": 33, + "94": 33, + "95": 33, + "96": 33, + "100": 33, + "103": 33, + "106": 33, + "107": 33, + "110": 33, + "111": 33, + "112": 33, + "113": 33, + "115": 33, + "116": 33, + "118": 33, + "120": 33, + "121": 33, + "122": 0, + "128": 33, + "131": 33, + "138": 0, + "139": 0, + "147": 1, + "148": 1, + "149": 1, + "150": 1, + "159": 2, + "162": 0, + "164": 0, + "167": 1, + "171": 1, + "174": 1, + "176": 1, + "180": 1, + "183": 7, + "185": 0, + "186": 7, + "188": 7, + "189": 7, + "194": 0, + "196": 0, + "200": 0, + "201": 1, + "203": 1, + "205": 1, + "207": 1, + "209": 1, + "211": 1, + "213": 1, + "225": 1, + "233": 0, + "234": 0, + "245": 1, + "247": 0, + "250": 0, + "253": 1, + "254": 1, + "255": 0, + "258": 0, + "263": 1, + "276": 0, + "278": 1, + "283": 1, + "285": 1, + "286": 0, + "288": 1, + "289": 0, + "291": 0, + "293": 0, + "301": 1, + "315": 24, + "316": 24, + "318": 24, + "319": 24, + "322": 10, + "323": 10, + "325": 0, + "328": 0, + "332": 0, + "333": 0, + "337": 0, + "338": 0, + "341": 24, + "346": 24, + "347": 24, + "351": 24, + "352": 24, + "354": 24, + "359": 24, + "361": 24, + "362": 24, + "363": 0, + "366": 24, + "377": 24, + "378": 24, + "379": 24, + "380": 24, + "381": 24, + "383": 24, + "384": 24, + "386": 24, + "396": 24, + "397": 24, + "406": 4, + "408": 0, + "413": 4, + "418": 20, + "429": 0, + "433": 0, + "434": 0, + "435": 0, + "440": 20, + "443": 19, + "450": 1, + "451": 1, + "452": 1, + "462": 0, + "464": 20, + "468": 20, + "470": 0, + "485": 8, + "490": 0, + "491": 0, + "493": 8, + "496": 0, + "497": 0, + "500": 8, + "502": 8, + "507": 8, + "525": 8, + "527": 8, + "528": 8, + "531": 14, + "534": 0, + "535": 0, + "538": 14, + "539": 14, + "543": 8, + "544": 8, + "549": 8, + "552": 0, + "553": 1, + "554": 1, + "555": 1, + "559": 1, + "561": 1, + "562": 1, + "567": 2, + "570": 1, + "572": 2, + "574": 2, + "575": 2, + "579": 1, + "580": 1, + "582": 1, + "583": 1, + "588": 1, + "589": 1, + "592": 1, + "594": 1, + "595": 1, + "599": 0, + "600": 0, + "605": 0, + "606": 0, + "610": 0, + "615": 0, + "616": 0, + "620": 0, + "621": 0, + "625": 8, + "628": 2, + "629": 0, + "630": 2, + "632": 1, + "647": 4, + "653": 4, + "654": 4, + "656": 4, + "662": 8, + "663": 8, + "665": 0, + "666": 0, + "667": 0, + "675": 8, + "676": 8, + "679": 8, + "680": 8, + "682": 33, + "683": 33, + "684": 33, + "685": 33, + "687": 33, + "694": 4, + "695": 4, + "697": 4, + "698": 4, + "699": 4, + "700": 4, + "720": 1, + "721": 1, + "722": 1, + "726": 0, + "727": 1, + "732": 1, + "734": 2, + "737": 2, + "745": 1, + "746": 1, + "749": 1, + "750": 0, + "752": 1, + "754": 24, + "756": 4 + }, + "branchHits": { + "122": { + "covered": 0, + "missed": 1, + "available": 1 + }, + "138": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "162": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "164": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "185": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "200": { + "covered": 7, + "missed": 0, + "available": 7 + }, + "233": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "234": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "255": { + "covered": 3, + "missed": 0, + "available": 3 + }, + "283": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "286": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "289": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "291": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "293": { + "covered": 2, + "missed": 2, + "available": 4 + }, + "323": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "332": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "351": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "359": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "361": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "363": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "386": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "408": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "470": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "531": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "552": { + "covered": 5, + "missed": 3, + "available": 8 + }, + "579": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "629": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "726": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "749": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "750": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/controller/VideoContextPlayerCoordinatorFactory.ts", + "lineHits": { + "9": 8, + "11": 33, + "14": 66, + "2": 4, + "3": 4, + "4": 4, + "5": 4, + "6": 4, + "12": 33, + "15": 33, + "16": 33, + "17": 33, + "18": 33, + "19": 33, + "20": 33, + "22": 33, + "24": 33, + "25": 33, + "28": 0, + "29": 0, + "32": 33, + "36": 33, + "42": 0, + "47": 33, + "52": 33, + "62": 4 + }, + "branchHits": { + "24": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/controller/index.ts", + "lineHits": { + "1": 3, + "2": 3, + "4": 3, + "5": 3 + }, + "branchHits": {} + }, + { + "filename": "src/controller-x/VideoContextPlayerCoordinatorX.ts", + "lineHits": { + "43": 6, + "59": 60, + "99": 24, + "126": 0, + "132": 0, + "219": 4, + "233": 16, + "290": 3, + "338": 34, + "341": 17, + "362": 34, + "363": 0, + "422": 10, + "435": 8, + "444": 33, + "458": 6, + "466": 4, + "477": 4, + "507": 3, + "1": 3, + "2": 3, + "25": 3, + "26": 3, + "27": 3, + "28": 3, + "29": 3, + "31": 3, + "34": 3, + "57": 30, + "60": 30, + "61": 30, + "62": 30, + "68": 30, + "73": 30, + "74": 0, + "75": 0, + "79": 0, + "81": 30, + "83": 30, + "85": 30, + "86": 30, + "89": 30, + "90": 30, + "92": 30, + "100": 21, + "104": 21, + "109": 21, + "110": 0, + "117": 21, + "121": 21, + "123": 21, + "129": 21, + "136": 3, + "139": 11, + "141": 11, + "142": 0, + "143": 0, + "146": 5, + "147": 5, + "148": 10, + "150": 5, + "155": 5, + "158": 1, + "159": 1, + "160": 1, + "162": 1, + "164": 1, + "166": 1, + "168": 2, + "170": 2, + "174": 1, + "176": 2, + "178": 2, + "180": 1, + "182": 1, + "183": 1, + "185": 1, + "187": 1, + "189": 1, + "191": 0, + "193": 0, + "195": 0, + "198": 0, + "201": 0, + "203": 6, + "206": 3, + "209": 0, + "210": 2, + "212": 2, + "214": 2, + "216": 0, + "223": 1, + "224": 1, + "225": 1, + "226": 1, + "235": 1, + "238": 0, + "240": 0, + "243": 1, + "247": 1, + "250": 1, + "252": 1, + "256": 1, + "259": 7, + "261": 0, + "262": 7, + "264": 7, + "265": 7, + "269": 0, + "273": 0, + "274": 1, + "276": 1, + "278": 1, + "280": 1, + "282": 1, + "284": 1, + "286": 1, + "291": 0, + "293": 0, + "299": 3, + "303": 21, + "306": 21, + "307": 21, + "310": 7, + "311": 7, + "313": 0, + "316": 0, + "320": 0, + "321": 0, + "325": 0, + "328": 21, + "333": 21, + "334": 21, + "335": 21, + "337": 4, + "339": 17, + "350": 0, + "354": 0, + "355": 0, + "356": 0, + "360": 17, + "368": 4, + "371": 21, + "373": 21, + "374": 21, + "376": 21, + "379": 21, + "386": 0, + "390": 21, + "391": 21, + "392": 21, + "393": 21, + "394": 21, + "397": 21, + "398": 21, + "400": 21, + "402": 21, + "412": 0, + "415": 21, + "416": 21, + "424": 7, + "428": 7, + "430": 7, + "436": 5, + "438": 5, + "446": 0, + "447": 0, + "450": 0, + "451": 0, + "453": 30, + "454": 30, + "455": 30, + "459": 3, + "461": 2, + "462": 2, + "467": 1, + "471": 1, + "478": 0, + "479": 1, + "482": 1, + "483": 0, + "486": 1, + "487": 0, + "491": 0, + "493": 0, + "495": 0, + "499": 1, + "508": 0, + "510": 3 + }, + "branchHits": { + "110": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "139": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "182": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "209": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "238": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "240": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "261": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "273": { + "covered": 7, + "missed": 0, + "available": 7 + }, + "311": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "320": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "373": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "376": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "386": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "400": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "478": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "483": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "487": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "491": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "493": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "495": { + "covered": 3, + "missed": 1, + "available": 4 + } + } + }, + { + "filename": "src/controller-x/VideoContextPlayerCoordinatorXObserver.ts", + "lineHits": { + "5": 6, + "9": 3, + "13": 4, + "17": 7, + "24": 3, + "26": 4, + "30": 3, + "32": 3, + "34": 4, + "38": 3, + "40": 3, + "42": 3, + "44": 4, + "48": 3, + "50": 3, + "52": 3, + "54": 4, + "58": 4, + "62": 4, + "66": 4, + "70": 4, + "74": 3, + "76": 3, + "78": 3, + "2": 3, + "10": 3, + "14": 1, + "18": 4, + "20": 2, + "27": 1, + "35": 1, + "45": 1, + "55": 1, + "59": 1, + "63": 1, + "67": 1, + "71": 1, + "79": 3 + }, + "branchHits": {} + }, + { + "filename": "src/controller-x/index.ts", + "lineHits": { + "1": 3, + "2": 3 + }, + "branchHits": {} + }, + { + "filename": "src/events/InternalPlaybackObserver.ts", + "lineHits": { + "17": 22, + "21": 107, + "26": 100, + "32": 0, + "39": 0, + "42": 100, + "48": 89, + "57": 11, + "59": 0, + "63": 100, + "65": 89, + "69": 38, + "71": 27, + "75": 16, + "77": 5, + "81": 12, + "83": 1, + "87": 13, + "89": 2, + "93": 18, + "95": 7, + "99": 12, + "101": 1, + "106": 13, + "108": 2, + "113": 13, + "115": 2, + "120": 109, + "122": 98, + "126": 15, + "128": 4, + "132": 15, + "134": 4, + "138": 104, + "144": 93, + "149": 12, + "151": 1, + "156": 12, + "158": 1, + "163": 12, + "165": 1, + "170": 12, + "172": 1, + "177": 15, + "179": 4, + "184": 19, + "186": 8, + "191": 14, + "193": 3, + "22": 107, + "23": 107, + "31": 89, + "33": 0, + "47": 89, + "49": 0, + "58": 0, + "60": 0, + "64": 89, + "66": 0, + "70": 27, + "72": 0, + "76": 5, + "78": 0, + "82": 1, + "84": 0, + "88": 2, + "90": 0, + "94": 7, + "96": 0, + "100": 1, + "102": 0, + "107": 2, + "109": 0, + "114": 2, + "116": 0, + "121": 98, + "123": 0, + "127": 4, + "129": 0, + "133": 4, + "135": 0, + "143": 93, + "145": 0, + "150": 1, + "152": 0, + "157": 1, + "159": 0, + "164": 1, + "166": 0, + "171": 1, + "173": 0, + "178": 4, + "180": 0, + "185": 8, + "187": 0, + "192": 3, + "194": 0, + "197": 11 + }, + "branchHits": {} + }, + { + "filename": "src/events/PlaybackEventsObserver.ts", + "lineHits": { + "24": 22, + "28": 90, + "36": 100, + "48": 23, + "52": 17, + "56": 100, + "71": 11, + "75": 100, + "88": 38, + "97": 15, + "101": 12, + "105": 12, + "112": 13, + "116": 18, + "124": 12, + "129": 13, + "134": 13, + "142": 109, + "150": 15, + "157": 15, + "165": 104, + "177": 12, + "184": 12, + "191": 12, + "196": 12, + "204": 15, + "211": 19, + "219": 14, + "227": 472, + "13": 11, + "32": 90, + "33": 90, + "41": 89, + "49": 12, + "53": 6, + "61": 89, + "66": 89, + "72": 0, + "80": 89, + "81": 89, + "89": 27, + "90": 27, + "98": 4, + "99": 4, + "102": 1, + "103": 1, + "106": 1, + "107": 1, + "113": 2, + "114": 2, + "117": 7, + "118": 7, + "125": 1, + "126": 1, + "130": 2, + "131": 2, + "135": 2, + "136": 2, + "143": 98, + "144": 98, + "151": 4, + "152": 4, + "158": 4, + "159": 4, + "170": 93, + "171": 93, + "178": 1, + "179": 1, + "185": 1, + "186": 1, + "192": 1, + "193": 1, + "197": 1, + "198": 1, + "205": 4, + "206": 4, + "212": 8, + "213": 8, + "220": 3, + "221": 3, + "228": 461, + "229": 461, + "231": 11 + }, + "branchHits": {} + }, + { + "filename": "src/events/TimeObservable.ts", + "lineHits": { + "4": 26, + "8": 202, + "13": 101, + "14": 0, + "17": 0, + "22": 13, + "27": 0, + "31": 0, + "41": 24, + "46": 11, + "9": 101, + "10": 101, + "15": 0, + "18": 0, + "26": 0, + "28": 0, + "29": 0, + "30": 0, + "33": 0, + "34": 0, + "36": 0, + "45": 11, + "47": 0, + "48": 0, + "52": 0, + "53": 0, + "57": 13 + }, + "branchHits": {} + }, + { + "filename": "src/events/index.ts", + "lineHits": { + "1": 11, + "2": 11, + "4": 11, + "5": 11 + }, + "branchHits": {} + }, + { + "filename": "src/player/BetamaxPlayer.ts", + "lineHits": { + "25": 20, + "31": 14, + "277": 24, + "283": 890, + "288": 456, + "47": 26, + "58": 34, + "74": 34, + "76": 0, + "87": 10, + "95": 10, + "108": 10, + "121": 11, + "134": 10, + "146": 10, + "154": 11, + "162": 10, + "168": 10, + "179": 10, + "191": 0, + "203": 0, + "216": 0, + "228": 10, + "232": 27, + "244": 13, + "252": 11, + "256": 34, + "266": 459, + "8": 10, + "9": 10, + "15": 10, + "17": 10, + "35": 14, + "36": 14, + "37": 14, + "38": 14, + "48": 16, + "62": 17, + "64": 17, + "69": 17, + "77": 0, + "89": 0, + "91": 0, + "97": 0, + "99": 0, + "110": 0, + "112": 0, + "122": 1, + "124": 0, + "126": 1, + "136": 0, + "138": 0, + "148": 0, + "150": 0, + "156": 1, + "157": 1, + "158": 1, + "164": 0, + "170": 0, + "181": 0, + "183": 0, + "193": 0, + "195": 0, + "205": 0, + "207": 0, + "218": 0, + "220": 0, + "229": 0, + "233": 0, + "234": 2, + "238": 2, + "239": 2, + "240": 2, + "246": 3, + "247": 3, + "248": 3, + "253": 1, + "261": 17, + "267": 442, + "270": 17, + "271": 17, + "273": 0, + "278": 0, + "279": 1, + "284": 6, + "285": 6, + "293": 442, + "295": 10 + }, + "branchHits": { + "35": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "229": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "233": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "238": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "278": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/player/BetamaxPlayerFactory.ts", + "lineHits": { + "6": 20, + "9": 68, + "15": 78, + "2": 10, + "3": 10, + "12": 68, + "16": 68, + "19": 68, + "21": 10 + }, + "branchHits": {} + }, + { + "filename": "src/player/PlaybackSession.ts", + "lineHits": { + "50": 20, + "71": 90, + "165": 182, + "170": 2, + "177": 179, + "179": 102, + "90": 91, + "136": 100, + "146": 103, + "185": 178, + "189": 178, + "301": 0, + "310": 0, + "324": 89, + "334": 178, + "339": 979, + "343": 445, + "349": 14, + "351": 44, + "355": 20, + "361": 10, + "365": 15, + "392": 178, + "443": 0, + "458": 14, + "485": 99, + "501": 11, + "514": 14, + "525": 11, + "529": 23, + "558": 29, + "567": 24, + "571": 25, + "581": 15, + "596": 14, + "608": 37, + "619": 10, + "623": 110, + "714": 18, + "719": 16, + "762": 11, + "768": 12, + "782": 13, + "803": 195, + "840": 11, + "844": 180, + "849": 180, + "860": 16, + "869": 221, + "875": 18, + "879": 4, + "885": 18, + "922": 13, + "939": 11, + "952": 101, + "965": 1572, + "969": 784, + "983": 11, + "987": 11, + "991": 19, + "1026": 106, + "1035": 16, + "1040": 18, + "1076": 10, + "1123": 16, + "1134": 11, + "1138": 100, + "1142": 0, + "1146": 0, + "1150": 0, + "1154": 2, + "1158": 0, + "1": 10, + "7": 10, + "8": 10, + "9": 10, + "10": 10, + "11": 10, + "33": 10, + "34": 10, + "42": 10, + "44": 10, + "45": 10, + "48": 10, + "75": 90, + "76": 90, + "77": 90, + "78": 90, + "83": 1, + "87": 1, + "92": 1, + "96": 1, + "97": 1, + "101": 90, + "111": 90, + "116": 90, + "128": 90, + "143": 90, + "150": 1, + "153": 1, + "156": 1, + "159": 1, + "162": 89, + "167": 182, + "169": 92, + "171": 2, + "172": 0, + "181": 0, + "191": 89, + "195": 89, + "199": 89, + "201": 89, + "204": 89, + "208": 89, + "212": 89, + "216": 1, + "220": 1, + "222": 1, + "229": 1, + "232": 89, + "233": 89, + "235": 89, + "236": 89, + "241": 89, + "243": 0, + "245": 89, + "247": 0, + "253": 0, + "259": 89, + "266": 89, + "267": 89, + "268": 89, + "269": 89, + "271": 89, + "273": 89, + "276": 89, + "283": 89, + "286": 89, + "290": 89, + "295": 89, + "300": 89, + "302": 0, + "308": 0, + "312": 0, + "313": 0, + "314": 0, + "316": 0, + "325": 89, + "328": 89, + "329": 89, + "330": 89, + "335": 89, + "340": 890, + "344": 356, + "350": 4, + "352": 40, + "356": 16, + "362": 0, + "368": 3, + "369": 3, + "370": 0, + "374": 2, + "375": 2, + "383": 1, + "384": 1, + "393": 89, + "409": 0, + "410": 0, + "411": 0, + "413": 0, + "426": 10, + "428": 0, + "431": 0, + "434": 3, + "436": 3, + "437": 0, + "440": 0, + "441": 0, + "442": 0, + "444": 0, + "445": 0, + "449": 0, + "451": 2, + "454": 1, + "460": 0, + "465": 1, + "471": 0, + "476": 2, + "477": 0, + "479": 2, + "480": 2, + "486": 89, + "487": 89, + "488": 0, + "489": 1, + "492": 1, + "494": 89, + "502": 1, + "505": 1, + "507": 1, + "515": 4, + "516": 4, + "517": 4, + "522": 4, + "526": 1, + "530": 0, + "532": 1, + "535": 12, + "537": 12, + "538": 12, + "540": 12, + "549": 12, + "550": 12, + "553": 2, + "554": 2, + "559": 19, + "560": 0, + "561": 16, + "562": 16, + "564": 19, + "572": 0, + "574": 6, + "582": 5, + "583": 5, + "590": 4, + "592": 1, + "597": 4, + "601": 4, + "602": 4, + "604": 2, + "609": 27, + "610": 27, + "611": 27, + "612": 27, + "620": 0, + "625": 99, + "639": 100, + "640": 100, + "642": 0, + "643": 6, + "646": 0, + "647": 6, + "650": 100, + "652": 100, + "653": 100, + "654": 100, + "657": 0, + "663": 2, + "664": 2, + "665": 2, + "668": 100, + "671": 0, + "677": 2, + "680": 100, + "683": 100, + "684": 0, + "693": 2, + "695": 98, + "698": 0, + "699": 84, + "701": 100, + "711": 100, + "715": 0, + "716": 0, + "721": 1, + "723": 7, + "726": 2, + "742": 4, + "749": 4, + "755": 5, + "763": 1, + "771": 1, + "774": 1, + "775": 1, + "784": 3, + "787": 3, + "793": 3, + "806": 93, + "808": 6, + "810": 93, + "816": 93, + "823": 0, + "827": 4, + "833": 92, + "841": 1, + "846": 0, + "850": 90, + "851": 90, + "853": 90, + "854": 90, + "861": 6, + "862": 6, + "863": 6, + "864": 6, + "865": 6, + "866": 6, + "870": 211, + "871": 0, + "877": 2, + "880": 2, + "882": 6, + "887": 8, + "888": 8, + "892": 1, + "895": 7, + "896": 7, + "897": 7, + "899": 4, + "900": 4, + "909": 2, + "912": 0, + "915": 0, + "919": 7, + "927": 0, + "929": 3, + "930": 0, + "933": 3, + "936": 0, + "941": 0, + "946": 1, + "949": 0, + "954": 1, + "955": 1, + "957": 90, + "958": 90, + "960": 91, + "961": 91, + "962": 91, + "966": 1562, + "970": 774, + "971": 774, + "972": 774, + "975": 563, + "978": 774, + "984": 1, + "988": 1, + "992": 9, + "995": 0, + "997": 9, + "999": 2, + "1005": 1, + "1008": 9, + "1013": 9, + "1014": 9, + "1021": 9, + "1023": 9, + "1029": 96, + "1030": 96, + "1031": 96, + "1032": 96, + "1036": 6, + "1037": 6, + "1041": 8, + "1042": 8, + "1046": 8, + "1048": 8, + "1052": 8, + "1054": 0, + "1055": 0, + "1056": 0, + "1058": 0, + "1064": 8, + "1069": 0, + "1073": 8, + "1078": 0, + "1084": 10, + "1085": 4, + "1086": 0, + "1087": 0, + "1089": 4, + "1091": 4, + "1093": 4, + "1094": 4, + "1099": 4, + "1100": 0, + "1101": 0, + "1102": 0, + "1105": 8, + "1106": 0, + "1108": 0, + "1112": 0, + "1115": 4, + "1117": 4, + "1118": 4, + "1119": 4, + "1125": 6, + "1135": 1, + "1139": 90, + "1143": 0, + "1147": 0, + "1151": 0, + "1155": 2, + "1159": 0, + "1161": 10 + }, + "branchHits": { + "75": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "167": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "172": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "243": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "247": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "370": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "409": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "410": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "411": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "413": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "428": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "440": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "460": { + "covered": 4, + "missed": 0, + "available": 4 + }, + "471": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "477": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "488": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "530": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "535": { + "covered": 3, + "missed": 0, + "available": 3 + }, + "560": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "572": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "609": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "610": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "642": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "646": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "657": { + "covered": 3, + "missed": 0, + "available": 3 + }, + "671": { + "covered": 5, + "missed": 0, + "available": 5 + }, + "683": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "684": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "698": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "715": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "808": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "823": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "870": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "871": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "880": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "912": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "927": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "930": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "941": { + "covered": 4, + "missed": 0, + "available": 4 + }, + "966": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "997": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "1086": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "1087": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "1101": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "1159": { + "covered": 0, + "missed": 2, + "available": 2 + } + } + }, + { + "filename": "src/player/PlaybackSessionFactory.ts", + "lineHits": { + "10": 20, + "13": 68, + "19": 27, + "70": 17, + "2": 10, + "3": 10, + "4": 10, + "16": 68, + "23": 17, + "25": 0, + "33": 0, + "34": 0, + "35": 0, + "36": 0, + "37": 0, + "38": 0, + "39": 0, + "42": 0, + "53": 0, + "62": 0, + "63": 0, + "68": 17, + "71": 0, + "72": 17, + "78": 10 + }, + "branchHits": { + "23": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "33": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "62": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/player/index.ts", + "lineHits": { + "1": 10, + "2": 10, + "3": 10, + "4": 10, + "5": 10, + "6": 10 + }, + "branchHits": {} + }, + { + "filename": "src/player/player.ts", + "lineHits": { + "9": 24, + "12": 89, + "16": 101, + "18": 89, + "25": 198, + "29": 101, + "37": 12, + "41": 12, + "45": 12, + "49": 12, + "53": 38, + "57": 368, + "61": 28, + "65": 12, + "69": 12, + "73": 12, + "1": 12, + "4": 12, + "5": 12, + "13": 89, + "19": 0, + "22": 89, + "26": 186, + "34": 89, + "38": 0, + "42": 0, + "46": 0, + "50": 0, + "54": 26, + "58": 356, + "62": 16, + "66": 0, + "70": 0, + "74": 0, + "76": 12 + }, + "branchHits": {} + }, + { + "filename": "src/player/shaka.ts", + "lineHits": { + "2": 13, + "5": 13, + "6": 0, + "7": 0, + "10": 13 + }, + "branchHits": { + "6": { + "covered": 2, + "missed": 1, + "available": 3 + } + } + }, + { + "filename": "src/plugins/SPManifestParser.ts", + "lineHits": { + "26": 5, + "40": 14, + "45": 14, + "60": 10, + "67": 9, + "70": 9, + "75": 9, + "87": 14, + "94": 10, + "113": 14, + "152": 14, + "159": 13, + "173": 14, + "175": 44, + "186": 14, + "191": 23, + "211": 0, + "218": 0, + "226": 18, + "227": 26, + "242": 22, + "281": 14, + "289": 16, + "298": 13, + "313": 43, + "332": 0, + "366": 52, + "367": 28, + "368": 6, + "388": 68, + "399": 10, + "405": 4, + "461": 7944, + "467": 3974, + "468": 6, + "18": 9, + "27": 5, + "28": 5, + "29": 5, + "30": 5, + "31": 5, + "32": 5, + "33": 5, + "34": 5, + "35": 5, + "36": 5, + "41": 5, + "47": 0, + "50": 5, + "59": 5, + "61": 5, + "62": 5, + "88": 5, + "91": 5, + "92": 5, + "95": 5, + "98": 5, + "114": 5, + "117": 0, + "120": 0, + "122": 0, + "130": 5, + "134": 0, + "141": 5, + "153": 5, + "154": 5, + "156": 5, + "160": 13, + "174": 5, + "188": 5, + "189": 5, + "192": 18, + "194": 0, + "195": 13, + "196": 13, + "198": 5, + "199": 5, + "201": 0, + "206": 0, + "207": 0, + "210": 0, + "217": 0, + "225": 5, + "228": 13, + "231": 5, + "247": 13, + "249": 13, + "250": 0, + "252": 13, + "257": 0, + "260": 0, + "265": 0, + "284": 5, + "286": 0, + "299": 8, + "319": 34, + "322": 34, + "324": 13, + "327": 13, + "330": 34, + "333": 0, + "338": 0, + "343": 0, + "344": 0, + "345": 0, + "348": 0, + "369": 4, + "373": 2, + "376": 26, + "393": 34, + "395": 34, + "396": 34, + "400": 2, + "402": 0, + "406": 2, + "412": 2, + "417": 8, + "428": 26, + "430": 26, + "431": 26, + "433": 3972, + "439": 3972, + "440": 3972, + "441": 3972, + "446": 34, + "448": 34, + "469": 4, + "474": 2, + "477": 3972, + "487": 9 + }, + "branchHits": { + "194": { + "covered": 2, + "missed": 1, + "available": 3 + }, + "206": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "210": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "217": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "247": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "249": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "250": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "257": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "260": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "265": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "286": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "338": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "343": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "344": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "345": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "348": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/plugins/SpotifyVideoMediaExtension.ts", + "lineHits": { + "9": 16, + "12": 59, + "29": 10, + "34": 12, + "38": 10, + "2": 8, + "3": 8, + "13": 59, + "14": 59, + "18": 59, + "22": 59, + "23": 59, + "30": 2, + "31": 2, + "35": 4, + "42": 2, + "46": 8 + }, + "branchHits": {} + }, + { + "filename": "src/plugins/SpotifyVideoUrl.ts", + "lineHits": { + "7": 16, + "8": 39, + "1": 8, + "9": 31, + "11": 8 + }, + "branchHits": {} + }, + { + "filename": "src/plugins/TextParser.js", + "lineHits": { + "25": 0, + "37": 8, + "47": 8, + "57": 8, + "64": 8, + "78": 8, + "96": 8, + "116": 8, + "30": 0, + "33": 0, + "38": 0, + "48": 0, + "58": 0, + "65": 0, + "79": 0, + "80": 0, + "81": 0, + "84": 0, + "85": 0, + "98": 0, + "101": 0, + "103": 0, + "105": 0, + "117": 0, + "118": 0, + "120": 0, + "122": 0, + "130": 8 + }, + "branchHits": { + "80": { + "covered": 0, + "missed": 3, + "available": 3 + } + } + }, + { + "filename": "src/plugins/VttTextParser.js", + "lineHits": { + "26": 0, + "29": 8, + "37": 8, + "121": 8, + "144": 8, + "223": 8, + "260": 8, + "261": 0, + "285": 8, + "299": 8, + "315": 8, + "330": 8, + "362": 8, + "19": 8, + "20": 8, + "30": 0, + "38": 0, + "40": 0, + "41": 0, + "42": 0, + "45": 0, + "52": 0, + "60": 0, + "72": 0, + "76": 0, + "77": 0, + "78": 0, + "79": 0, + "80": 0, + "81": 0, + "84": 0, + "91": 0, + "92": 0, + "93": 0, + "95": 0, + "96": 0, + "101": 0, + "102": 0, + "103": 0, + "104": 0, + "106": 0, + "110": 0, + "122": 0, + "126": 0, + "129": 0, + "130": 0, + "132": 0, + "145": 0, + "148": 0, + "149": 0, + "154": 0, + "159": 0, + "162": 0, + "163": 0, + "165": 0, + "166": 0, + "170": 0, + "171": 0, + "172": 0, + "173": 0, + "175": 0, + "176": 0, + "183": 0, + "184": 0, + "187": 0, + "192": 0, + "195": 0, + "196": 0, + "199": 0, + "205": 0, + "206": 0, + "210": 0, + "212": 0, + "224": 0, + "225": 0, + "227": 0, + "229": 0, + "231": 0, + "237": 0, + "239": 0, + "242": 0, + "244": 0, + "247": 0, + "250": 0, + "262": 0, + "265": 0, + "270": 0, + "274": 0, + "277": 0, + "286": 0, + "288": 0, + "290": 0, + "300": 0, + "301": 0, + "302": 0, + "303": 0, + "304": 0, + "306": 0, + "316": 0, + "318": 0, + "320": 0, + "334": 0, + "335": 0, + "337": 0, + "338": 0, + "340": 0, + "343": 0, + "344": 0, + "346": 0, + "349": 0, + "352": 0, + "364": 0, + "366": 0, + "370": 0, + "371": 0, + "372": 0, + "373": 0, + "374": 0, + "375": 0, + "378": 0, + "385": 8, + "387": 8 + }, + "branchHits": { + "77": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "148": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "175": { + "covered": 0, + "missed": 3, + "available": 3 + }, + "301": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "303": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "370": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "374": { + "covered": 0, + "missed": 2, + "available": 2 + } + } + }, + { + "filename": "src/plugins/WidevineDownloader.ts", + "lineHits": { + "14": 14, + "21": 14, + "190": 12, + "34": 11, + "40": 4, + "44": 5, + "66": 4, + "69": 0, + "78": 9, + "90": 8, + "107": 11, + "137": 2, + "147": 1, + "165": 14, + "174": 8, + "2": 7, + "9": 7, + "10": 7, + "11": 7, + "12": 7, + "22": 7, + "26": 7, + "27": 7, + "28": 7, + "29": 7, + "36": 0, + "38": 4, + "41": 4, + "46": 0, + "49": 1, + "51": 0, + "59": 0, + "63": 0, + "64": 0, + "70": 0, + "80": 0, + "84": 1, + "86": 1, + "91": 1, + "92": 1, + "93": 1, + "94": 1, + "108": 4, + "111": 0, + "112": 2, + "113": 2, + "120": 1, + "121": 1, + "128": 1, + "129": 1, + "133": 0, + "136": 1, + "139": 1, + "140": 1, + "150": 0, + "152": 0, + "153": 0, + "166": 7, + "171": 0, + "172": 0, + "177": 7, + "179": 6, + "181": 3, + "182": 3, + "183": 3, + "184": 3, + "185": 3, + "187": 3, + "189": 3, + "191": 6, + "193": 3, + "198": 7, + "200": 3, + "201": 1, + "202": 1, + "203": 1, + "205": 1, + "207": 7 + }, + "branchHits": { + "59": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "80": { + "covered": 2, + "missed": 3, + "available": 5 + }, + "111": { + "covered": 4, + "missed": 6, + "available": 10 + }, + "179": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "184": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/plugins/index.ts", + "lineHits": { + "1": 8, + "2": 8, + "3": 8, + "4": 8, + "6": 8, + "7": 8, + "8": 8 + }, + "branchHits": {} + }, + { + "filename": "src/plugins/types.ts", + "lineHits": { + "19": 14, + "20": 7, + "21": 7, + "22": 7, + "23": 7, + "24": 7, + "25": 7, + "26": 7, + "27": 7, + "28": 7, + "29": 7, + "30": 7 + }, + "branchHits": { + "19": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/DefaultEventsCalculator.ts", + "lineHits": { + "34": 108, + "46": 7, + "95": 68, + "108": 17, + "116": 17, + "124": 92, + "145": 92, + "164": 41, + "168": 48, + "181": 41, + "185": 6, + "194": 41, + "198": 2, + "207": 42, + "215": 4, + "229": 41, + "233": 2, + "242": 42, + "246": 50, + "255": 44, + "259": 12, + "276": 42, + "284": 2, + "298": 41, + "302": 2, + "311": 42, + "315": 10, + "326": 42, + "334": 2, + "348": 43, + "352": 22, + "386": 42, + "398": 10, + "417": 45, + "475": 43, + "479": 83, + "483": 86, + "496": 41, + "500": 76, + "505": 86, + "522": 41, + "526": 76, + "531": 86, + "548": 39, + "1": 16, + "11": 16, + "12": 16, + "13": 16, + "37": 35, + "39": 0, + "40": 19, + "43": 0, + "51": 7, + "52": 7, + "55": 0, + "57": 0, + "58": 3, + "65": 3, + "69": 3, + "71": 3, + "78": 2, + "82": 3, + "84": 1, + "87": 1, + "89": 0, + "92": 7, + "99": 52, + "100": 52, + "109": 1, + "111": 1, + "113": 0, + "117": 1, + "119": 1, + "128": 76, + "129": 76, + "130": 0, + "132": 1, + "134": 0, + "136": 1, + "140": 1, + "142": 76, + "149": 76, + "150": 76, + "151": 0, + "152": 1, + "154": 0, + "155": 1, + "159": 1, + "161": 76, + "167": 25, + "184": 25, + "197": 25, + "210": 26, + "214": 26, + "216": 4, + "222": 0, + "232": 25, + "245": 26, + "258": 28, + "261": 0, + "262": 0, + "265": 0, + "266": 0, + "279": 26, + "283": 26, + "285": 2, + "291": 0, + "301": 25, + "314": 26, + "317": 0, + "329": 26, + "333": 26, + "335": 2, + "341": 0, + "351": 27, + "354": 5, + "365": 6, + "375": 0, + "389": 26, + "390": 26, + "397": 26, + "399": 5, + "400": 5, + "433": 86, + "435": 0, + "439": 5, + "444": 3, + "450": 9, + "451": 9, + "454": 9, + "457": 0, + "461": 4, + "466": 4, + "467": 4, + "468": 4, + "472": 29, + "478": 27, + "480": 83, + "499": 25, + "501": 76, + "507": 76, + "508": 76, + "525": 25, + "527": 76, + "533": 76, + "534": 76, + "551": 23 + }, + "branchHits": { + "39": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "55": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "57": { + "covered": 3, + "missed": 1, + "available": 4 + }, + "113": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "129": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "130": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "134": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "150": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "151": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "154": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "222": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "261": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "262": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "265": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "266": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "291": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "317": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "341": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "435": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "457": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/EventsTracker.ts", + "lineHits": { + "16": 32, + "19": 15, + "23": 17, + "40": 17, + "53": 17, + "63": 17, + "71": 17, + "86": 16, + "101": 28, + "117": 16, + "130": 21, + "145": 19, + "160": 25, + "170": 19, + "180": 21, + "195": 17, + "210": 17, + "225": 17, + "240": 17, + "248": 17, + "256": 17, + "271": 17, + "286": 17, + "301": 17, + "14": 16, + "20": 15, + "29": 1, + "44": 1, + "54": 1, + "64": 1, + "76": 1, + "91": 0, + "107": 12, + "121": 0, + "135": 5, + "150": 3, + "161": 9, + "171": 3, + "185": 5, + "200": 1, + "215": 1, + "230": 1, + "241": 1, + "249": 1, + "261": 1, + "276": 1, + "291": 1, + "302": 1, + "310": 16 + }, + "branchHits": {} + }, + { + "filename": "src/tracking/ProductStatesStreamingRulesProvider.ts", + "lineHits": { + "4": 32, + "9": 6, + "14": 2, + "17": 0, + "21": 20, + "10": 3, + "11": 3, + "12": 3, + "15": 2, + "22": 4, + "24": 16 + }, + "branchHits": {} + }, + { + "filename": "src/tracking/VideoPlaybackEvents.ts", + "lineHits": { + "1": 36, + "7": 36, + "17": 36, + "2": 18, + "3": 18, + "4": 18, + "8": 18, + "9": 18, + "10": 18, + "13": 18, + "18": 18, + "19": 18, + "20": 18, + "21": 18, + "22": 18, + "23": 18, + "24": 18, + "25": 18, + "26": 18, + "27": 18, + "28": 18, + "29": 18, + "30": 18, + "31": 18, + "32": 18, + "33": 18, + "34": 18, + "35": 18, + "36": 18, + "37": 18, + "38": 18, + "39": 18, + "40": 18, + "41": 18, + "42": 18, + "45": 18 + }, + "branchHits": { + "1": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "7": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "17": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/index.ts", + "lineHits": { + "1": 15, + "2": 15, + "3": 15, + "4": 15, + "5": 15, + "7": 15, + "8": 15, + "9": 15, + "11": 15, + "12": 15, + "13": 15, + "15": 15, + "16": 15 + }, + "branchHits": {} + }, + { + "filename": "src/tracking/types.ts", + "lineHits": { + "13": 32, + "95": 32, + "10": 16, + "14": 16, + "15": 16, + "16": 16, + "17": 16, + "18": 16, + "19": 16, + "20": 16, + "21": 16, + "22": 16, + "23": 16, + "24": 16, + "25": 16, + "26": 16, + "27": 16, + "28": 16, + "29": 16, + "30": 16, + "31": 16, + "32": 16, + "33": 16, + "34": 16, + "35": 16, + "36": 16, + "37": 16, + "38": 16, + "39": 16, + "40": 16, + "41": 16, + "42": 16, + "43": 16, + "44": 16, + "45": 16, + "46": 16, + "96": 16, + "97": 16, + "98": 16, + "99": 16, + "100": 16, + "101": 16, + "102": 16, + "103": 16, + "104": 16, + "105": 16, + "106": 16, + "107": 16, + "108": 16, + "109": 16, + "110": 16, + "111": 16, + "112": 16, + "113": 16, + "114": 16, + "115": 16, + "116": 16, + "117": 16, + "118": 16, + "119": 16, + "120": 16, + "121": 16, + "122": 16, + "123": 16, + "124": 16, + "125": 16, + "126": 16, + "127": 16, + "128": 16, + "129": 16, + "130": 16, + "131": 16, + "132": 16, + "133": 16, + "134": 16, + "135": 16, + "136": 16, + "137": 16, + "138": 16, + "139": 16, + "140": 16, + "141": 16, + "142": 16, + "143": 16, + "144": 16, + "145": 16, + "146": 16, + "147": 16, + "148": 16 + }, + "branchHits": { + "13": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "95": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/utils.ts", + "lineHits": { + "44": 64, + "109": 225, + "113": 1944, + "115": 1902, + "123": 514, + "128": 486, + "133": 91, + "138": 95, + "143": 239, + "148": 314, + "153": 167, + "158": 91, + "163": 91, + "168": 261, + "173": 167, + "178": 17, + "183": 139, + "188": 93, + "193": 475, + "198": 61, + "203": 95, + "208": 19, + "220": 1501, + "224": 484, + "228": 462, + "232": 900, + "236": 113, + "245": 96, + "250": 460, + "251": 56, + "254": 46, + "259": 158, + "261": 19, + "269": 78, + "2": 17, + "4": 17, + "7": 17, + "9": 17, + "11": 17, + "12": 17, + "13": 17, + "14": 17, + "15": 17, + "16": 17, + "17": 17, + "18": 17, + "19": 17, + "20": 17, + "21": 17, + "22": 17, + "23": 17, + "24": 17, + "26": 17, + "42": 17, + "47": 47, + "48": 47, + "53": 47, + "58": 47, + "63": 47, + "64": 47, + "69": 47, + "74": 47, + "75": 47, + "76": 47, + "77": 47, + "78": 47, + "100": 17, + "102": 17, + "104": 17, + "112": 208, + "126": 497, + "131": 469, + "136": 74, + "141": 78, + "146": 222, + "151": 297, + "156": 150, + "161": 74, + "166": 74, + "171": 244, + "176": 150, + "181": 0, + "186": 122, + "191": 76, + "196": 458, + "201": 44, + "206": 78, + "209": 2, + "211": 17, + "222": 497, + "226": 132, + "230": 110, + "234": 248, + "237": 96, + "239": 96, + "249": 79, + "258": 29, + "262": 19, + "263": 0, + "270": 0, + "271": 0, + "273": 61, + "274": 0, + "275": 0, + "277": 61 + }, + "branchHits": { + "209": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "222": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "226": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "230": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "234": { + "covered": 4, + "missed": 0, + "available": 4 + }, + "263": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "270": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "274": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/endvideo/EndVideoEventsCalculator.ts", + "lineHits": { + "39": 24, + "52": 11, + "71": 6, + "79": 14, + "88": 11, + "92": 19, + "120": 28, + "123": 36, + "145": 20, + "181": 36, + "190": 27, + "206": 25, + "223": 26, + "240": 26, + "258": 42, + "264": 48, + "272": 42, + "276": 2, + "285": 42, + "289": 2, + "298": 43, + "306": 50, + "328": 40, + "332": 46, + "341": 45, + "345": 4, + "356": 43, + "361": 50, + "371": 43, + "375": 89, + "380": 86, + "394": 43, + "398": 87, + "403": 90, + "416": 46, + "420": 91, + "425": 88, + "442": 40, + "1": 15, + "8": 15, + "9": 15, + "28": 15, + "36": 15, + "37": 15, + "41": 0, + "42": 5, + "44": 0, + "46": 0, + "48": 19, + "57": 8, + "61": 0, + "64": 0, + "66": 0, + "68": 3, + "76": 1, + "78": 5, + "81": 7, + "82": 7, + "89": 11, + "94": 11, + "95": 11, + "97": 8, + "99": 0, + "103": 0, + "105": 0, + "106": 1, + "110": 1, + "113": 3, + "114": 3, + "116": 4, + "127": 21, + "128": 0, + "129": 5, + "133": 5, + "134": 5, + "135": 5, + "140": 21, + "141": 21, + "142": 21, + "149": 5, + "151": 5, + "153": 5, + "157": 5, + "159": 0, + "160": 4, + "161": 0, + "162": 1, + "166": 1, + "167": 1, + "168": 1, + "169": 1, + "174": 0, + "175": 0, + "177": 5, + "178": 5, + "184": 21, + "191": 12, + "193": 12, + "211": 10, + "212": 10, + "215": 10, + "228": 11, + "229": 11, + "232": 11, + "241": 11, + "248": 11, + "249": 11, + "261": 27, + "265": 24, + "266": 0, + "275": 27, + "288": 27, + "301": 28, + "305": 28, + "308": 13, + "310": 0, + "312": 13, + "316": 0, + "320": 12, + "331": 25, + "344": 30, + "347": 0, + "359": 28, + "360": 28, + "363": 0, + "374": 28, + "376": 89, + "397": 28, + "399": 87, + "419": 31, + "421": 91, + "445": 25, + "446": 25, + "489": 25 + }, + "branchHits": { + "41": { + "covered": 2, + "missed": 2, + "available": 4 + }, + "105": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "128": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "159": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "161": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "174": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "266": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "310": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "316": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "347": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "363": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/endvideo/EndVideoLoggerFactory.ts", + "lineHits": { + "11": 30, + "19": 14, + "32": 29, + "9": 15, + "26": 14, + "27": 14, + "28": 14, + "29": 14, + "30": 14, + "33": 14, + "41": 15 + }, + "branchHits": {} + }, + { + "filename": "src/tracking/endvideo/EndVideoLoggerTracker.ts", + "lineHits": { + "24": 30, + "38": 14, + "54": 14, + "62": 0, + "96": 0, + "139": 24, + "140": 18, + "141": 18, + "154": 40, + "155": 40, + "156": 40, + "166": 35, + "177": 38, + "1": 15, + "4": 15, + "15": 15, + "16": 15, + "17": 15, + "18": 15, + "21": 15, + "22": 15, + "35": 14, + "45": 14, + "46": 14, + "47": 14, + "48": 14, + "49": 14, + "50": 14, + "52": 14, + "53": 14, + "56": 0, + "57": 0, + "59": 0, + "60": 0, + "61": 0, + "64": 0, + "67": 0, + "73": 15, + "79": 11, + "85": 11, + "86": 0, + "90": 3, + "91": 16, + "94": 11, + "97": 0, + "102": 15, + "107": 2, + "108": 2, + "109": 0, + "111": 4, + "114": 15, + "115": 2, + "116": 2, + "118": 4, + "121": 15, + "122": 7, + "123": 7, + "124": 14, + "127": 15, + "132": 4, + "133": 8, + "135": 3, + "143": 0, + "144": 0, + "145": 0, + "147": 9, + "148": 9, + "149": 9, + "158": 0, + "159": 0, + "161": 20, + "178": 23, + "179": 0, + "184": 15, + "187": 23, + "194": 3, + "197": 11, + "198": 18, + "201": 20, + "205": 40, + "208": 15, + "209": 19, + "218": 38, + "220": 15 + }, + "branchHits": { + "45": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "86": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "109": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "179": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/endvideo/EndVideoReasonEnd.ts", + "lineHits": { + "1": 30, + "2": 15, + "3": 15, + "4": 15, + "5": 15, + "6": 15, + "7": 15, + "8": 15, + "11": 15 + }, + "branchHits": { + "1": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/endvideo/EndVideoTracker.ts", + "lineHits": { + "24": 30, + "64": 13, + "78": 28, + "110": 26, + "118": 27, + "131": 79, + "237": 21, + "255": 44, + "287": 28, + "295": 22, + "355": 20, + "364": 28, + "417": 28, + "419": 17, + "430": 28, + "438": 24, + "458": 25, + "1": 15, + "2": 15, + "15": 15, + "20": 15, + "71": 13, + "72": 13, + "73": 13, + "74": 13, + "75": 13, + "79": 13, + "80": 13, + "81": 13, + "82": 13, + "83": 13, + "84": 13, + "85": 13, + "86": 13, + "87": 13, + "88": 13, + "89": 13, + "90": 13, + "91": 13, + "92": 13, + "93": 13, + "94": 13, + "95": 13, + "96": 13, + "97": 13, + "98": 13, + "99": 13, + "100": 13, + "101": 13, + "102": 13, + "103": 13, + "104": 13, + "105": 13, + "106": 13, + "108": 13, + "109": 13, + "112": 0, + "113": 0, + "115": 13, + "116": 13, + "117": 13, + "120": 14, + "123": 14, + "128": 13, + "133": 5, + "135": 64, + "136": 0, + "138": 0, + "139": 55, + "140": 55, + "141": 55, + "142": 55, + "143": 0, + "146": 0, + "147": 6, + "149": 0, + "150": 1, + "154": 10, + "157": 10, + "166": 64, + "167": 64, + "168": 64, + "170": 0, + "171": 7, + "174": 2, + "177": 2, + "178": 2, + "184": 3, + "185": 3, + "186": 3, + "190": 0, + "191": 0, + "193": 0, + "194": 0, + "197": 64, + "199": 21, + "201": 64, + "203": 2, + "204": 0, + "205": 1, + "209": 3, + "215": 3, + "218": 0, + "219": 10, + "226": 10, + "227": 10, + "229": 10, + "230": 0, + "231": 10, + "233": 10, + "238": 6, + "245": 6, + "247": 3, + "248": 3, + "250": 3, + "251": 3, + "262": 27, + "264": 16, + "269": 27, + "272": 17, + "274": 10, + "283": 27, + "288": 13, + "289": 13, + "290": 13, + "291": 13, + "292": 13, + "293": 13, + "297": 6, + "299": 1, + "301": 2, + "303": 13, + "304": 13, + "305": 17, + "306": 17, + "307": 17, + "310": 12, + "311": 12, + "313": 5, + "314": 5, + "317": 10, + "319": 7, + "320": 7, + "322": 17, + "324": 13, + "328": 0, + "330": 10, + "333": 4, + "335": 6, + "339": 13, + "342": 6, + "347": 13, + "357": 0, + "358": 1, + "360": 4, + "365": 13, + "366": 13, + "367": 0, + "369": 13, + "377": 0, + "405": 0, + "418": 13, + "421": 0, + "422": 0, + "425": 1, + "432": 0, + "436": 12, + "440": 0, + "441": 0, + "442": 0, + "444": 12, + "445": 12, + "446": 12, + "448": 12, + "452": 0, + "455": 1, + "460": 0, + "462": 10, + "463": 10, + "464": 10, + "466": 15 + }, + "branchHits": { + "136": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "138": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "143": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "146": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "149": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "166": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "168": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "170": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "190": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "193": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "204": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "218": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "226": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "227": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "230": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "357": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "360": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "367": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "377": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "405": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/session/PlaybackSessionTracker.ts", + "lineHits": { + "7": 32, + "9": 1, + "14": 17, + "1": 16, + "10": 1, + "11": 1, + "19": 1, + "21": 1, + "22": 1, + "25": 16 + }, + "branchHits": { + "10": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/tracking/session/VideoPlaybackSessionLogger.ts", + "lineHits": { + "6": 30, + "9": 0, + "12": 15, + "13": 0, + "3": 15, + "4": 15, + "10": 0, + "14": 0, + "15": 0, + "18": 15 + }, + "branchHits": {} + } +] diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-3.json b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-3.json new file mode 100644 index 0000000000..625dcde1a0 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-3.json @@ -0,0 +1,297 @@ +[ + { + "filename": "src/atoms/BoxShadow/box-shadow.ts", + "lineHits": { + "4": 5 + }, + "branchHits": {} + }, + { + "filename": "src/atoms/Button/button.tsx", + "lineHits": { + "17": 41, + "34": 41, + "70": 82, + "72": 82, + "74": 41, + "31": 41, + "32": 41, + "35": 0, + "36": 0, + "37": 0, + "38": 0, + "39": 0, + "40": 0, + "41": 0, + "42": 0, + "43": 0, + "47": 41, + "68": 10, + "75": 41 + }, + "branchHits": { + "35": { + "covered": 0, + "missed": 4, + "available": 4 + }, + "70": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "72": { + "covered": 3, + "missed": 0, + "available": 3 + }, + "75": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/atoms/Container/components.ts", + "lineHits": { + "5": 70, + "19": 70, + "20": 70, + "23": 70, + "4": 13, + "13": 13 + }, + "branchHits": {} + }, + { + "filename": "src/atoms/Container/container.tsx", + "lineHits": { + "12": 35, + "20": 35 + }, + "branchHits": {} + }, + { + "filename": "src/atoms/DownArrow/down-arrow.tsx", + "lineHits": { + "3": 28, + "4": 28 + }, + "branchHits": {} + }, + { + "filename": "src/molecules/Hero/components.ts", + "lineHits": { + "26": 20, + "28": 10, + "94": 10, + "103": 20, + "121": 10, + "182": 20, + "203": 5, + "218": 5, + "236": 10, + "241": 10, + "249": 8, + "254": 4, + "264": 4, + "277": 8, + "282": 4, + "294": 8, + "299": 6, + "25": 2, + "29": 10, + "37": 3, + "39": 3, + "40": 3, + "42": 3, + "43": 1, + "44": 1, + "45": 0, + "46": 0, + "48": 1, + "52": 0, + "53": 1, + "57": 0, + "59": 1, + "60": 1, + "63": 3, + "95": 10, + "112": 2, + "122": 10, + "125": 9, + "134": 0, + "151": 1, + "170": 2, + "181": 2, + "194": 2, + "204": 5, + "207": 3, + "209": 0, + "211": 1, + "213": 1, + "219": 5, + "222": 3, + "224": 0, + "226": 0, + "228": 1, + "230": 1, + "245": 2, + "255": 4, + "258": 3, + "260": 1, + "265": 4, + "268": 2, + "270": 1, + "272": 1, + "283": 4, + "286": 2, + "288": 1, + "290": 1, + "298": 2, + "304": 2, + "311": 2, + "319": 2, + "329": 2, + "361": 2, + "371": 2 + }, + "branchHits": { + "29": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "39": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "42": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "43": { + "covered": 3, + "missed": 1, + "available": 4 + }, + "45": { + "covered": 0, + "missed": 4, + "available": 4 + }, + "48": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "53": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "59": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "60": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "95": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "122": { + "covered": 2, + "missed": 2, + "available": 4 + }, + "182": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "204": { + "covered": 4, + "missed": 1, + "available": 5 + }, + "219": { + "covered": 4, + "missed": 2, + "available": 6 + }, + "236": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "241": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "249": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "255": { + "covered": 3, + "missed": 0, + "available": 3 + }, + "265": { + "covered": 4, + "missed": 0, + "available": 4 + }, + "277": { + "covered": 1, + "missed": 0, + "available": 1 + }, + "283": { + "covered": 4, + "missed": 0, + "available": 4 + }, + "294": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "299": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/molecules/Hero/hero.tsx", + "lineHits": { + "40": 10, + "72": 0, + "127": 3, + "56": 10, + "58": 10, + "73": 0, + "128": 3 + }, + "branchHits": { + "73": { + "covered": 0, + "missed": 2, + "available": 2 + } + } + } +] diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-4.json b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-4.json new file mode 100644 index 0000000000..eada26d5ce --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-4.json @@ -0,0 +1,351 @@ +[ + { + "filename": "Sources/TDSOptions.m", + "lineHits": { + "32": 0, + "33": 0, + "34": 0, + "35": 0, + "36": 0, + "37": 0, + "38": 0, + "45": 0, + "46": 0, + "47": 0, + "48": 0, + "49": 0, + "50": 0, + "51": 0, + "52": 0, + "53": 0, + "54": 0, + "55": 0, + "56": 0, + "57": 0, + "58": 0, + "61": 0, + "62": 0, + "63": 0, + "66": 0, + "67": 0, + "68": 0, + "69": 0, + "70": 0, + "71": 0, + "72": 0, + "73": 0, + "74": 0, + "75": 0, + "76": 0, + "77": 0 + }, + "branchHits": {} + }, + { + "filename": "Sources/TDSUserLock.m", + "lineHits": { + "17": 0, + "18": 0, + "19": 0, + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "28": 0, + "29": 0, + "30": 0, + "31": 0, + "32": 0, + "33": 0, + "34": 0, + "35": 0, + "36": 0, + "37": 0, + "38": 0, + "39": 0, + "40": 0, + "43": 0, + "44": 0, + "45": 0, + "46": 0, + "47": 0, + "48": 0, + "49": 0, + "58": 0, + "59": 0, + "60": 0, + "61": 0, + "62": 0, + "63": 0, + "64": 0, + "65": 0, + "66": 0, + "67": 0, + "68": 0, + "69": 0, + "70": 0 + }, + "branchHits": {} + }, + { + "filename": "Sources/TDSUserManager.m", + "lineHits": { + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "28": 0, + "29": 0, + "30": 0, + "31": 0, + "34": 0, + "35": 0, + "36": 0, + "37": 0, + "38": 0, + "39": 0, + "40": 0, + "49": 0, + "50": 0, + "51": 0, + "52": 0, + "53": 0, + "54": 0, + "55": 0, + "56": 0, + "57": 0, + "58": 0, + "59": 0, + "60": 0, + "61": 0, + "62": 0, + "63": 0, + "64": 0, + "65": 0, + "66": 0, + "67": 0, + "68": 0, + "69": 0, + "70": 0, + "74": 0, + "75": 0, + "76": 0, + "77": 0, + "78": 0, + "79": 0, + "80": 0, + "81": 0, + "82": 0, + "83": 0, + "84": 0, + "85": 0, + "86": 0, + "87": 0, + "88": 0, + "89": 0, + "90": 0, + "91": 0, + "92": 0, + "93": 0, + "94": 0, + "101": 0, + "102": 0, + "103": 0, + "104": 0, + "105": 0, + "106": 0, + "107": 0, + "108": 0, + "109": 0, + "110": 0, + "111": 0, + "112": 0, + "113": 0, + "114": 0, + "115": 0, + "116": 0, + "117": 0, + "118": 0, + "119": 0, + "120": 0, + "121": 0, + "122": 0, + "123": 0, + "124": 0, + "125": 0, + "126": 0, + "127": 0, + "128": 0, + "129": 0, + "130": 0, + "131": 0, + "136": 0, + "137": 0, + "138": 0, + "139": 0, + "140": 0, + "141": 0, + "142": 0, + "143": 0, + "144": 0, + "145": 0, + "146": 0, + "147": 0, + "148": 0, + "149": 0, + "150": 0, + "151": 0, + "152": 0, + "153": 0, + "158": 0, + "159": 0, + "160": 0, + "161": 0, + "162": 0, + "163": 0, + "164": 0, + "165": 0, + "166": 0, + "167": 0, + "168": 0, + "169": 0, + "170": 0, + "171": 0, + "172": 0, + "173": 0, + "174": 0, + "175": 0, + "176": 0, + "177": 0, + "178": 0, + "179": 0, + "180": 0, + "181": 0, + "182": 0, + "183": 0, + "184": 0, + "189": 0, + "190": 0, + "191": 0, + "192": 0, + "193": 0, + "194": 0, + "195": 0, + "196": 0, + "197": 0, + "198": 0, + "199": 0, + "200": 0, + "201": 0, + "202": 0, + "203": 0, + "204": 0, + "205": 0, + "206": 0, + "207": 0, + "208": 0, + "209": 0, + "210": 0, + "211": 0, + "212": 0, + "213": 0, + "214": 0, + "215": 0, + "216": 0, + "217": 0, + "218": 0, + "219": 0, + "220": 0, + "221": 0, + "222": 0, + "223": 0, + "224": 0, + "225": 0, + "226": 0, + "227": 0, + "228": 0, + "229": 0, + "230": 0, + "231": 0, + "232": 0, + "233": 0, + "234": 0, + "235": 0, + "236": 0, + "239": 0, + "240": 0, + "241": 0, + "242": 0, + "243": 0, + "244": 0, + "245": 0, + "246": 0, + "247": 0, + "248": 0, + "249": 0, + "252": 0, + "253": 0, + "254": 0, + "255": 0, + "256": 0, + "257": 0, + "258": 0, + "259": 0, + "260": 0, + "261": 0, + "262": 0, + "263": 0, + "264": 0, + "265": 0, + "268": 0, + "269": 0, + "270": 0, + "271": 0, + "272": 0, + "273": 0, + "274": 0, + "275": 0, + "276": 0, + "277": 0, + "278": 0, + "279": 0, + "280": 0, + "281": 0, + "282": 0, + "283": 0, + "284": 0, + "287": 0, + "288": 0, + "289": 0, + "290": 0, + "291": 0, + "292": 0, + "293": 0, + "294": 0, + "295": 0, + "296": 0 + }, + "branchHits": {} + }, + { + "filename": "Sources/TDSUtil.m", + "lineHits": { + "8": 0, + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "20": 0 + }, + "branchHits": {} + } +] diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-5.json b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-5.json new file mode 100644 index 0000000000..41ab6c084f --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-jsoncoverage-files-5.json @@ -0,0 +1,325 @@ +[ + { + "filename": "src/graphql/queries.ts", + "lineHits": { + "1": 3, + "3": 3, + "50": 3, + "65": 3, + "80": 3, + "92": 3, + "138": 3 + }, + "branchHits": {} + }, + { + "filename": "src/graphql/resolvers.ts", + "lineHits": { + "22": 17, + "28": 14, + "36": 16, + "27": 8, + "35": 8, + "43": 9, + "51": 15, + "56": 8, + "61": 8, + "50": 8, + "55": 8, + "60": 8, + "128": 7, + "139": 4, + "145": 8, + "160": 8, + "177": 7, + "185": 13, + "70": 12, + "78": 8, + "81": 8, + "84": 4, + "97": 12, + "103": 8, + "114": 8, + "144": 8, + "159": 8, + "176": 8, + "184": 8, + "1": 4, + "2": 4, + "3": 4, + "5": 4, + "6": 4, + "7": 4, + "8": 4, + "9": 4, + "10": 4, + "14": 4, + "21": 4, + "24": 17, + "32": 10, + "37": 12, + "42": 4, + "45": 9, + "47": 9, + "52": 11, + "57": 4, + "62": 4, + "67": 4, + "73": 8, + "83": 4, + "85": 4, + "86": 4, + "87": 4, + "88": 4, + "94": 4, + "95": 4, + "98": 4, + "104": 4, + "107": 4, + "115": 4, + "118": 4, + "119": 4, + "120": 0, + "124": 4, + "130": 7, + "132": 7, + "134": 7, + "136": 7, + "140": 4, + "151": 4, + "165": 4, + "166": 4, + "167": 4, + "168": 1, + "169": 4, + "178": 3, + "186": 9, + "187": 9, + "193": 2, + "194": 0 + }, + "branchHits": { + "86": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "119": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "166": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "167": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "193": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/graphql/router.ts", + "lineHits": { + "21": 1, + "22": 2, + "43": 21, + "53": 40, + "12": 3, + "14": 3, + "23": 1, + "26": 0, + "32": 1, + "33": 1, + "34": 1, + "37": 0, + "54": 11, + "55": 0, + "57": 11, + "58": 11, + "63": 11, + "64": 11, + "65": 10, + "66": 10, + "68": 1 + }, + "branchHits": { + "23": { + "covered": 3, + "missed": 0, + "available": 3 + }, + "26": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "32": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "55": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "65": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/graphql/schema.ts", + "lineHits": { + "9": 7, + "1": 3, + "2": 3, + "4": 3, + "5": 3, + "11": 0, + "13": 4, + "15": 4, + "16": 4, + "17": 4, + "19": 4 + }, + "branchHits": { + "11": { + "covered": 0, + "missed": 1, + "available": 1 + } + } + }, + { + "filename": "src/graphql/transforms.ts", + "lineHits": { + "9": 10, + "20": 5, + "13": 6, + "14": 2, + "15": 6, + "16": 1, + "17": 6, + "23": 1, + "24": 0, + "25": 1 + }, + "branchHits": { + "13": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "15": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "23": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + }, + { + "filename": "src/workers/primary-worker.js", + "lineHits": { + "16": 0, + "25": 0, + "49": 0, + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "8": 0, + "17": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "27": 0, + "28": 0, + "31": 0, + "33": 0, + "34": 0, + "37": 0, + "38": 0, + "48": 0, + "51": 0, + "53": 0 + }, + "branchHits": { + "17": { + "covered": 0, + "missed": 1, + "available": 1 + }, + "21": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "49": { + "covered": 0, + "missed": 2, + "available": 2 + } + } + }, + { + "filename": "src/workers/secondary-worker.js", + "lineHits": { + "4": 0, + "13": 0, + "2": 0, + "5": 0, + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "14": 0, + "15": 0, + "16": 0, + "18": 0, + "19": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "29": 0 + }, + "branchHits": { + "5": { + "covered": 0, + "missed": 1, + "available": 1 + }, + "9": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "24": { + "covered": 0, + "missed": 2, + "available": 2 + } + } + } +] diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-1.txt b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-1.txt new file mode 100644 index 0000000000..bee95e0bca --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-1.txt @@ -0,0 +1,19 @@ +.dockerignore +.editorconfig +.gitattributes +.gitignore +.gitmodules +.idea/codeStyleSettings.xml +.idea/codeStyles/Project.xml +.idea/codeStyles/codeStyleConfig.xml +.idea/inspectionProfiles/Spotify.xml +.idea/inspectionProfiles/profiles_settings.xml +.mention-bot +.ownership-bot +.slack_mentioner +CONTRIBUTING.md +README.md +WORKSPACE +src/main/scala/com/example/Main.scala +src/main/scala/com/example/Other.scala +src/main/scala/com/example/utils/Util.scala diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-2.txt b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-2.txt new file mode 100644 index 0000000000..b8d13fc792 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-2.txt @@ -0,0 +1,49 @@ +.dockerignore +.editorconfig +.gitattributes +.gitignore +.gitmodules +CONTRIBUTING.md +README.md +WORKSPACE +src/index.ts +src/utils.ts +src/controller/VideoContextPlayerCoordinator.ts +src/controller/VideoContextPlayerCoordinatorFactory.ts +src/controller/index.ts +src/controller-x/VideoContextPlayerCoordinatorX.ts +src/controller-x/VideoContextPlayerCoordinatorXObserver.ts +src/controller-x/index.ts +src/events/InternalPlaybackObserver.ts +src/events/PlaybackEventsObserver.ts +src/events/TimeObservable.ts +src/events/index.ts +src/player/BetamaxPlayer.ts +src/player/BetamaxPlayerFactory.ts +src/player/PlaybackSession.ts +src/player/PlaybackSessionFactory.ts +src/player/index.ts +src/player/player.ts +src/player/shaka.ts +src/plugins/SPManifestParser.ts +src/plugins/SpotifyVideoMediaExtension.ts +src/plugins/SpotifyVideoUrl.ts +src/plugins/TextParser.js +src/plugins/VttTextParser.js +src/plugins/WidevineDownloader.ts +src/plugins/index.ts +src/plugins/types.ts +src/tracking/DefaultEventsCalculator.ts +src/tracking/EventsTracker.ts +src/tracking/ProductStatesStreamingRulesProvider.ts +src/tracking/VideoPlaybackEvents.ts +src/tracking/index.ts +src/tracking/types.ts +src/tracking/utils.ts +src/tracking/endvideo/EndVideoEventsCalculator.ts +src/tracking/endvideo/EndVideoLoggerFactory.ts +src/tracking/endvideo/EndVideoLoggerTracker.ts +src/tracking/endvideo/EndVideoReasonEnd.ts +src/tracking/endvideo/EndVideoTracker.ts +src/tracking/session/PlaybackSessionTracker.ts +src/tracking/session/VideoPlaybackSessionLogger.ts diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-3.txt b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-3.txt new file mode 100644 index 0000000000..fb2d4096ed --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-3.txt @@ -0,0 +1,29 @@ +.dockerignore +.editorconfig +.gitattributes +.gitignore +.gitmodules +.idea/codeStyleSettings.xml +.idea/codeStyles/Project.xml +.idea/codeStyles/codeStyleConfig.xml +.idea/inspectionProfiles/Spotify.xml +.idea/inspectionProfiles/profiles_settings.xml +.mention-bot +.ownership-bot +.slack_mentioner +CONTRIBUTING.md +README.md +WORKSPACE +src/index.ts +src/atoms/BoxShadow/box-shadow.ts +src/atoms/BoxShadow/index.ts +src/atoms/Button/button.tsx +src/atoms/Button/index.ts +src/atoms/Container/components.ts +src/atoms/Container/container.tsx +src/atoms/Container/index.ts +src/atoms/DownArrow/down-arrow.tsx +src/atoms/DownArrow/index.ts +src/molecules/Hero/components.ts +src/molecules/Hero/hero.tsx +src/molecules/Hero/index.ts diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-4.txt b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-4.txt new file mode 100644 index 0000000000..4e0e3699af --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-4.txt @@ -0,0 +1,20 @@ +.dockerignore +.editorconfig +.gitattributes +.gitignore +.gitmodules +.idea/codeStyleSettings.xml +.idea/codeStyles/Project.xml +.idea/codeStyles/codeStyleConfig.xml +.idea/inspectionProfiles/Spotify.xml +.idea/inspectionProfiles/profiles_settings.xml +.mention-bot +.ownership-bot +.slack_mentioner +CONTRIBUTING.md +README.md +WORKSPACE +Sources/TDSOptions.m +Sources/TDSUserLock.m +Sources/TDSUserManager.m +Sources/TDSUtil.m diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-5.txt b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-5.txt new file mode 100644 index 0000000000..d117a9885a --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-sourcefiles-5.txt @@ -0,0 +1,26 @@ +.editorconfig +.eslintignore +.eslintrc.js +.gitignore +.npmrc +.nvmrc +Dockerfile +README.md +babel.config.js +nodemon.json +package.json +prettier.config.js +service-info.yaml +src/graphql/__tests__/resolvers.test.ts +src/graphql/__tests__/transforms.test.ts +src/graphql/queries.ts +src/graphql/resolvers.ts +src/graphql/router.ts +src/graphql/schema.ts +src/graphql/transforms.ts +src/start.ts +src/sysmodel_component.ts +src/workers/primary-worker.js +src/workers/secondary-worker.js +tsconfig.json +yarn.lock diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-1.xml b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-1.xml new file mode 100644 index 0000000000..37e2c8c560 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-1.xml @@ -0,0 +1,479 @@ +<?xml version="1.0"?> +<coverage + line-rate="0.98" lines-valid="312" lines-covered="306" branches-valid="12" branches-covered="12" branch-rate="1.00" complexity="0" version="1.0" timestamp="1567499510503"> + <packages> + <package name="com.example" line-rate="0.98" branch-rate="1.00" complexity="0"> + <classes> + <class + name="com.example.Main" filename="com/example/Main.scala" line-rate="0.97" branch-rate="1.00" complexity="0"> + <methods> + <method + name="com.example/Main/methodOne" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="203" hits="1" branch="false"/> + <line number="202" hits="1" branch="false"/> + <line number="204" hits="1" branch="false"/> + <line number="203" hits="1" branch="false"/> + <line number="202" hits="1" branch="false"/> + <line number="204" hits="1" branch="false"/> + <line number="203" hits="1" branch="false"/> + </lines> + </method> + <method + name="com.example/Main/methodTwo" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="164" hits="1" branch="false"/> + <line number="169" hits="1" branch="false"/> + <line number="170" hits="1" branch="false"/> + <line number="167" hits="1" branch="false"/> + <line number="168" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="168" hits="1" branch="false"/> + <line number="169" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="170" hits="1" branch="false"/> + <line number="167" hits="1" branch="false"/> + <line number="166" hits="1" branch="false"/> + <line number="160" hits="1" branch="false"/> + <line number="168" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="169" hits="1" branch="false"/> + <line number="164" hits="1" branch="false"/> + </lines> + </method> + <method + name="com.example/Main/methodThree" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="97" hits="1" branch="false"/> + <line number="104" hits="1" branch="false"/> + <line number="99" hits="1" branch="false"/> + <line number="95" hits="1" branch="false"/> + <line number="100" hits="1" branch="false"/> + <line number="104" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="100" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + </lines> + </method> + <method + name="com.example/Main/&lt;none&gt;" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="30" hits="1" branch="false"/> + <line number="26" hits="1" branch="false"/> + <line number="28" hits="1" branch="false"/> + <line number="27" hits="1" branch="false"/> + <line number="30" hits="1" branch="false"/> + <line number="26" hits="1" branch="false"/> + <line number="27" hits="1" branch="false"/> + <line number="28" hits="1" branch="false"/> + </lines> + </method> + <method + name="com.example/Main/main" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="56" hits="1" branch="false"/> + <line number="73" hits="1" branch="false"/> + <line number="77" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="44" hits="1" branch="false"/> + <line number="60" hits="1" branch="false"/> + <line number="35" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="37" hits="1" branch="false"/> + <line number="77" hits="1" branch="false"/> + <line number="37" hits="1" branch="false"/> + <line number="52" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="42" hits="1" branch="false"/> + <line number="58" hits="1" branch="false"/> + <line number="68" hits="1" branch="false"/> + <line number="33" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="48" hits="1" branch="false"/> + <line number="64" hits="1" branch="false"/> + <line number="61" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="33" hits="1" branch="false"/> + <line number="46" hits="1" branch="false"/> + <line number="53" hits="1" branch="false"/> + <line number="36" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="38" hits="1" branch="false"/> + <line number="55" hits="1" branch="false"/> + <line number="68" hits="1" branch="false"/> + </lines> + </method> + </methods> + <lines> + <line number="203" hits="1" branch="false"/> + <line number="135" hits="1" branch="false"/> + <line number="149" hits="1" branch="false"/> + <line number="126" hits="1" branch="false"/> + <line number="164" hits="1" branch="false"/> + <line number="169" hits="1" branch="false"/> + <line number="183" hits="1" branch="false"/> + <line number="56" hits="1" branch="false"/> + <line number="138" hits="1" branch="false"/> + <line number="143" hits="1" branch="false"/> + <line number="188" hits="1" branch="false"/> + <line number="170" hits="1" branch="false"/> + <line number="112" hits="1" branch="false"/> + <line number="127" hits="1" branch="false"/> + <line number="86" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="104" hits="1" branch="false"/> + <line number="73" hits="1" branch="false"/> + <line number="77" hits="1" branch="false"/> + <line number="167" hits="1" branch="false"/> + <line number="210" hits="1" branch="false"/> + <line number="88" hits="1" branch="false"/> + <line number="99" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="30" hits="1" branch="false"/> + <line number="84" hits="1" branch="false"/> + <line number="44" hits="1" branch="false"/> + <line number="60" hits="1" branch="false"/> + <line number="182" hits="1" branch="false"/> + <line number="124" hits="1" branch="false"/> + <line number="125" hits="1" branch="false"/> + <line number="168" hits="1" branch="false"/> + <line number="146" hits="1" branch="false"/> + <line number="114" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="35" hits="1" branch="false"/> + <line number="114" hits="1" branch="false"/> + <line number="88" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="85" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="26" hits="1" branch="false"/> + <line number="95" hits="1" branch="false"/> + <line number="28" hits="1" branch="false"/> + <line number="37" hits="1" branch="false"/> + <line number="202" hits="1" branch="false"/> + <line number="210" hits="1" branch="false"/> + <line number="181" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="168" hits="1" branch="false"/> + <line number="85" hits="1" branch="false"/> + <line number="169" hits="1" branch="false"/> + <line number="183" hits="1" branch="false"/> + <line number="148" hits="1" branch="false"/> + <line number="126" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="135" hits="1" branch="false"/> + <line number="100" hits="1" branch="false"/> + <line number="88" hits="1" branch="false"/> + <line number="114" hits="1" branch="false"/> + <line number="204" hits="1" branch="false"/> + <line number="127" hits="1" branch="false"/> + <line number="140" hits="1" branch="false"/> + <line number="104" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="77" hits="1" branch="false"/> + <line number="86" hits="1" branch="false"/> + <line number="188" hits="1" branch="false"/> + <line number="27" hits="1" branch="false"/> + <line number="37" hits="1" branch="false"/> + <line number="170" hits="1" branch="false"/> + <line number="210" hits="1" branch="false"/> + <line number="52" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="115" hits="1" branch="false"/> + <line number="145" hits="1" branch="false"/> + <line number="167" hits="1" branch="false"/> + <line number="42" hits="1" branch="false"/> + <line number="136" hits="1" branch="false"/> + <line number="30" hits="1" branch="false"/> + <line number="124" hits="1" branch="false"/> + <line number="125" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="88" hits="1" branch="false"/> + <line number="84" hits="1" branch="false"/> + <line number="58" hits="1" branch="false"/> + <line number="68" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="33" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="26" hits="1" branch="false"/> + <line number="48" hits="1" branch="false"/> + <line number="64" hits="1" branch="false"/> + <line number="203" hits="1" branch="false"/> + <line number="187" hits="1" branch="false"/> + <line number="179" hits="1" branch="false"/> + <line number="166" hits="1" branch="false"/> + <line number="97" hits="1" branch="false"/> + <line number="127" hits="1" branch="false"/> + <line number="138" hits="1" branch="false"/> + <line number="210" hits="1" branch="false"/> + <line number="188" hits="1" branch="false"/> + <line number="202" hits="1" branch="false"/> + <line number="160" hits="1" branch="false"/> + <line number="168" hits="1" branch="false"/> + <line number="178" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="112" hits="1" branch="false"/> + <line number="135" hits="1" branch="false"/> + <line number="147" hits="1" branch="false"/> + <line number="100" hits="1" branch="false"/> + <line number="85" hits="1" branch="false"/> + <line number="88" hits="1" branch="false"/> + <line number="114" hits="1" branch="false"/> + <line number="204" hits="1" branch="false"/> + <line number="124" hits="1" branch="false"/> + <line number="183" hits="1" branch="false"/> + <line number="61" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="163" hits="1" branch="false"/> + <line number="169" hits="1" branch="false"/> + <line number="33" hits="1" branch="false"/> + <line number="46" hits="1" branch="false"/> + <line number="86" hits="1" branch="false"/> + <line number="53" hits="1" branch="false"/> + <line number="88" hits="1" branch="false"/> + <line number="27" hits="1" branch="false"/> + <line number="36" hits="1" branch="false"/> + <line number="126" hits="1" branch="false"/> + <line number="139" hits="1" branch="false"/> + <line number="150" hits="1" branch="false"/> + <line number="115" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="75" hits="1" branch="false"/> + <line number="164" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="38" hits="1" branch="false"/> + <line number="83" hits="1" branch="false"/> + <line number="87" hits="1" branch="false"/> + <line number="55" hits="1" branch="false"/> + <line number="68" hits="1" branch="false"/> + <line number="28" hits="1" branch="false"/> + <line number="210" hits="1" branch="false"/> + <line number="203" hits="1" branch="false"/> + </lines> + </class> + <class + name="com.example.Other" filename="com/example/Other.scala" line-rate="0.99" branch-rate="1.00" complexity="0"> + <methods> + <method + name="com.example/Other/methodOne" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="42" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="46" hits="1" branch="false"/> + <line number="52" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="44" hits="1" branch="false"/> + <line number="49" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="42" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="52" hits="1" branch="false"/> + <line number="45" hits="1" branch="false"/> + <line number="49" hits="1" branch="false"/> + </lines> + </method> + <method + name="com.example/Other/methodTwo" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="133" hits="1" branch="false"/> + <line number="133" hits="1" branch="false"/> + <line number="134" hits="1" branch="false"/> + <line number="132" hits="1" branch="false"/> + </lines> + </method> + </methods> + <lines> + <line number="91" hits="1" branch="false"/> + <line number="93" hits="1" branch="false"/> + <line number="68" hits="1" branch="false"/> + <line number="42" hits="1" branch="false"/> + <line number="79" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="117" hits="1" branch="false"/> + <line number="59" hits="1" branch="false"/> + <line number="21" hits="1" branch="false"/> + <line number="31" hits="1" branch="false"/> + <line number="111" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="61" hits="1" branch="false"/> + <line number="46" hits="1" branch="false"/> + <line number="25" hits="1" branch="false"/> + <line number="52" hits="1" branch="false"/> + <line number="32" hits="1" branch="false"/> + <line number="144" hits="1" branch="false"/> + <line number="146" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="147" hits="1" branch="false"/> + <line number="109" hits="1" branch="false"/> + <line number="93" hits="1" branch="false"/> + <line number="117" hits="1" branch="false"/> + <line number="104" hits="1" branch="false"/> + <line number="145" hits="1" branch="false"/> + <line number="133" hits="1" branch="false"/> + <line number="142" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="61" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="146" hits="1" branch="false"/> + <line number="44" hits="1" branch="false"/> + <line number="119" hits="1" branch="false"/> + <line number="74" hits="1" branch="false"/> + <line number="143" hits="1" branch="false"/> + <line number="146" hits="1" branch="false"/> + <line number="32" hits="1" branch="false"/> + <line number="111" hits="1" branch="false"/> + <line number="139" hits="1" branch="false"/> + <line number="92" hits="1" branch="false"/> + <line number="70" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="140" hits="1" branch="false"/> + <line number="115" hits="1" branch="false"/> + <line number="93" hits="1" branch="false"/> + <line number="124" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="71" hits="1" branch="false"/> + <line number="86" hits="1" branch="false"/> + <line number="27" hits="1" branch="false"/> + <line number="33" hits="1" branch="false"/> + <line number="49" hits="1" branch="false"/> + <line number="59" hits="1" branch="false"/> + <line number="64" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="110" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="29" hits="1" branch="false"/> + <line number="37" hits="0" branch="false"/> + <line number="66" hits="1" branch="false"/> + <line number="72" hits="1" branch="false"/> + <line number="87" hits="1" branch="false"/> + <line number="59" hits="1" branch="false"/> + <line number="20" hits="1" branch="false"/> + <line number="149" hits="1" branch="false"/> + <line number="25" hits="1" branch="false"/> + <line number="146" hits="1" branch="false"/> + <line number="140" hits="1" branch="false"/> + <line number="113" hits="1" branch="false"/> + <line number="144" hits="1" branch="false"/> + <line number="123" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="59" hits="1" branch="false"/> + <line number="94" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="72" hits="1" branch="false"/> + <line number="85" hits="1" branch="false"/> + <line number="144" hits="1" branch="false"/> + <line number="147" hits="1" branch="false"/> + <line number="65" hits="1" branch="false"/> + <line number="133" hits="1" branch="false"/> + <line number="142" hits="1" branch="false"/> + <line number="116" hits="1" branch="false"/> + <line number="104" hits="1" branch="false"/> + <line number="123" hits="1" branch="false"/> + <line number="110" hits="1" branch="false"/> + <line number="143" hits="1" branch="false"/> + <line number="42" hits="1" branch="false"/> + <line number="50" hits="1" branch="false"/> + <line number="23" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="119" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="74" hits="1" branch="false"/> + <line number="92" hits="1" branch="false"/> + <line number="145" hits="1" branch="false"/> + <line number="31" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="111" hits="1" branch="false"/> + <line number="61" hits="1" branch="false"/> + <line number="70" hits="1" branch="false"/> + <line number="139" hits="1" branch="false"/> + <line number="52" hits="1" branch="false"/> + <line number="86" hits="1" branch="false"/> + <line number="92" hits="1" branch="false"/> + <line number="33" hits="1" branch="false"/> + <line number="45" hits="1" branch="false"/> + <line number="26" hits="1" branch="false"/> + <line number="61" hits="1" branch="false"/> + <line number="70" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="34" hits="1" branch="false"/> + <line number="29" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="134" hits="1" branch="false"/> + <line number="149" hits="1" branch="false"/> + <line number="142" hits="1" branch="false"/> + <line number="145" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="115" hits="1" branch="false"/> + <line number="92" hits="1" branch="false"/> + <line number="113" hits="1" branch="false"/> + <line number="144" hits="1" branch="false"/> + <line number="70" hits="1" branch="false"/> + <line number="73" hits="1" branch="false"/> + <line number="138" hits="1" branch="false"/> + <line number="143" hits="1" branch="false"/> + <line number="146" hits="1" branch="false"/> + <line number="105" hits="1" branch="false"/> + <line number="129" hits="1" branch="false"/> + <line number="49" hits="1" branch="false"/> + <line number="59" hits="1" branch="false"/> + <line number="123" hits="1" branch="false"/> + <line number="132" hits="1" branch="false"/> + <line number="34" hits="1" branch="false"/> + <line number="86" hits="1" branch="false"/> + <line number="144" hits="1" branch="false"/> + <line number="27" hits="1" branch="false"/> + <line number="110" hits="1" branch="false"/> + <line number="116" hits="1" branch="false"/> + <line number="64" hits="1" branch="false"/> + <line number="94" hits="1" branch="false"/> + <line number="71" hits="1" branch="false"/> + <line number="103" hits="1" branch="false"/> + <line number="147" hits="1" branch="false"/> + <line number="142" hits="1" branch="false"/> + </lines> + </class> + </classes> + </package> + <package name="com.example.utils" line-rate="1.00" branch-rate="1.00" complexity="0"> + <classes> + <class + name="com.example.utils.Util" filename="com/example/utils/Util.scala" line-rate="1.00" branch-rate="1.00" complexity="0"> + <methods> + <method + name="com.example.utils/DateFormatUtils/utilMethod" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="13" hits="1" branch="false"/> + </lines> + </method> + <method + name="com.example.utils/DateFormatUtils/utilFunc" signature="()V" line-rate="1.00" branch-rate="1.00" complexity="0"> + <lines> + <line number="8" hits="1" branch="false"/> + <line number="7" hits="1" branch="false"/> + <line number="8" hits="1" branch="false"/> + </lines> + </method> + </methods> + <lines> + <line number="8" hits="1" branch="false"/> + <line number="7" hits="1" branch="false"/> + <line number="13" hits="1" branch="false"/> + <line number="8" hits="1" branch="false"/> + </lines> + </class> + </classes> + </package> + </packages> +</coverage> diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-2.xml b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-2.xml new file mode 100644 index 0000000000..9e94385cbc --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-2.xml @@ -0,0 +1,5721 @@ +<?xml version="1.0" ?> +<coverage branch-rate="0.8154506437768241" branches-covered="380" branches-valid="466" complexity="0" line-rate="0.8407299875570303" lines-covered="2027" lines-valid="2411" timestamp="1575069145" version="2.0.3"> + <sources> + <source>.</source> + </sources> + <packages> + <package branch-rate="0.9" complexity="0" line-rate="0.9736842105263158" name="src"> + <classes> + <class branch-rate="0.0" complexity="0" filename="src/index.ts" line-rate="1.0" name="src.index.ts"> + <methods/> + <lines> + <line branch="false" hits="3" number="1"/> + <line branch="false" hits="3" number="3"/> + <line branch="false" hits="3" number="5"/> + <line branch="false" hits="3" number="6"/> + <line branch="false" hits="3" number="7"/> + <line branch="false" hits="3" number="8"/> + <line branch="false" hits="3" number="9"/> + <line branch="false" hits="3" number="11"/> + <line branch="false" hits="3" number="12"/> + <line branch="false" hits="3" number="14"/> + </lines> + </class> + <class branch-rate="0.9" complexity="0" filename="src/utils.ts" line-rate="0.9642857142857143" name="src.utils.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="19" number="4"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="19" number="4"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="47" number="4"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="589" number="7"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="1" number="12"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="1" number="12"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="2" number="16"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="776" number="29"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="1601" number="33"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="15" number="37"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="20" number="56"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="21" number="64"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="2" number="65"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="18" number="1"/> + <line branch="false" hits="19" number="4"/> + <line branch="false" hits="589" number="7"/> + <line branch="true" condition-coverage="100% (2/2)" hits="589" number="8"/> + <line branch="false" hits="589" number="9"/> + <line branch="false" hits="18" number="12"/> + <line branch="false" hits="1" number="15"/> + <line branch="false" hits="2" number="18"/> + <line branch="false" hits="0" number="20"/> + <line branch="false" hits="2" number="22"/> + <line branch="false" hits="18" number="28"/> + <line branch="false" hits="2329" number="29"/> + <line branch="false" hits="776" number="30"/> + <line branch="false" hits="1601" number="34"/> + <line branch="false" hits="158" number="42"/> + <line branch="false" hits="1" number="48"/> + <line branch="false" hits="15" number="53"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="57"/> + <line branch="false" hits="1" number="58"/> + <line branch="false" hits="19" number="60"/> + <line branch="false" hits="19" number="61"/> + <line branch="false" hits="19" number="63"/> + <line branch="false" hits="21" number="64"/> + <line branch="false" hits="2" number="66"/> + <line branch="false" hits="2" number="67"/> + <line branch="true" condition-coverage="100% (2/2)" hits="2" number="68"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" number="69"/> + <line branch="false" hits="1" number="70"/> + <line branch="true" condition-coverage="100% (2/2)" hits="19" number="73"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.7333333333333333" complexity="0" line-rate="0.8566037735849057" name="src.controller"> + <classes> + <class branch-rate="0.7397260273972602" complexity="0" filename="src/controller/VideoContextPlayerCoordinator.ts" line-rate="0.8516949152542372" name="src.controller.VideoContextPlayerCoordinator.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="4" number="50"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="VideoContextPlayerCoordinator" signature=""> + <lines> + <line branch="false" hits="33" number="74"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="0" number="137"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="1" number="143"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="14" number="157"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="1" number="217"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="1" number="240"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="24" number="309"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="24" number="343"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="24" number="357"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="4" number="405"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="20" number="420"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="19" number="442"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="1" number="445"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="20" number="460"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="20" number="466"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="8" number="480"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="8" number="488"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="8" number="520"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="14" number="530"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="0" number="619"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="2" number="627"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="0" number="636"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="4" number="640"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="4" number="651"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="8" number="661"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="33" number="673"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="4" number="690"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="3" number="711"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="2" number="736"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="25" number="740"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="4" number="1"/> + <line branch="false" hits="4" number="2"/> + <line branch="false" hits="4" number="31"/> + <line branch="false" hits="4" number="33"/> + <line branch="false" hits="4" number="37"/> + <line branch="false" hits="4" number="39"/> + <line branch="false" hits="4" number="41"/> + <line branch="false" hits="4" number="50"/> + <line branch="false" hits="33" number="74"/> + <line branch="false" hits="33" number="76"/> + <line branch="false" hits="33" number="77"/> + <line branch="false" hits="33" number="78"/> + <line branch="false" hits="33" number="79"/> + <line branch="false" hits="33" number="80"/> + <line branch="false" hits="33" number="81"/> + <line branch="false" hits="33" number="82"/> + <line branch="false" hits="33" number="83"/> + <line branch="false" hits="33" number="84"/> + <line branch="false" hits="33" number="85"/> + <line branch="false" hits="33" number="86"/> + <line branch="false" hits="33" number="87"/> + <line branch="false" hits="33" number="90"/> + <line branch="false" hits="33" number="91"/> + <line branch="false" hits="33" number="92"/> + <line branch="false" hits="33" number="93"/> + <line branch="false" hits="33" number="94"/> + <line branch="false" hits="33" number="95"/> + <line branch="false" hits="33" number="96"/> + <line branch="false" hits="33" number="100"/> + <line branch="false" hits="33" number="103"/> + <line branch="false" hits="33" number="106"/> + <line branch="false" hits="33" number="107"/> + <line branch="false" hits="33" number="110"/> + <line branch="false" hits="33" number="111"/> + <line branch="false" hits="33" number="112"/> + <line branch="false" hits="33" number="113"/> + <line branch="false" hits="33" number="115"/> + <line branch="false" hits="33" number="116"/> + <line branch="false" hits="33" number="118"/> + <line branch="false" hits="33" number="120"/> + <line branch="false" hits="33" number="121"/> + <line branch="true" condition-coverage="0% (0/1)" hits="0" number="122"/> + <line branch="false" hits="33" number="128"/> + <line branch="false" hits="33" number="131"/> + <line branch="false" hits="33" number="137"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="138"/> + <line branch="false" hits="0" number="139"/> + <line branch="false" hits="4" number="143"/> + <line branch="false" hits="1" number="147"/> + <line branch="false" hits="1" number="148"/> + <line branch="false" hits="1" number="149"/> + <line branch="false" hits="1" number="150"/> + <line branch="false" hits="4" number="157"/> + <line branch="false" hits="2" number="159"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="162"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="164"/> + <line branch="false" hits="1" number="167"/> + <line branch="false" hits="1" number="171"/> + <line branch="false" hits="1" number="174"/> + <line branch="false" hits="1" number="176"/> + <line branch="false" hits="1" number="180"/> + <line branch="false" hits="7" number="183"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="185"/> + <line branch="false" hits="7" number="186"/> + <line branch="false" hits="7" number="188"/> + <line branch="false" hits="7" number="189"/> + <line branch="false" hits="0" number="194"/> + <line branch="false" hits="0" number="196"/> + <line branch="true" condition-coverage="100% (7/7)" hits="0" number="200"/> + <line branch="false" hits="1" number="201"/> + <line branch="false" hits="1" number="203"/> + <line branch="false" hits="1" number="205"/> + <line branch="false" hits="1" number="207"/> + <line branch="false" hits="1" number="209"/> + <line branch="false" hits="1" number="211"/> + <line branch="false" hits="1" number="213"/> + <line branch="false" hits="4" number="217"/> + <line branch="false" hits="1" number="225"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="233"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="234"/> + <line branch="false" hits="4" number="240"/> + <line branch="false" hits="1" number="245"/> + <line branch="false" hits="0" number="247"/> + <line branch="false" hits="0" number="250"/> + <line branch="false" hits="1" number="253"/> + <line branch="false" hits="1" number="254"/> + <line branch="true" condition-coverage="100% (3/3)" hits="0" number="255"/> + <line branch="false" hits="0" number="258"/> + <line branch="false" hits="1" number="263"/> + <line branch="false" hits="0" number="276"/> + <line branch="false" hits="1" number="278"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" number="283"/> + <line branch="false" hits="1" number="285"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="286"/> + <line branch="false" hits="1" number="288"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="289"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="291"/> + <line branch="true" condition-coverage="50% (2/4)" hits="0" number="293"/> + <line branch="false" hits="1" number="301"/> + <line branch="false" hits="24" number="309"/> + <line branch="false" hits="24" number="315"/> + <line branch="false" hits="24" number="316"/> + <line branch="false" hits="24" number="318"/> + <line branch="false" hits="24" number="319"/> + <line branch="false" hits="10" number="322"/> + <line branch="true" condition-coverage="50% (1/2)" hits="10" number="323"/> + <line branch="false" hits="0" number="325"/> + <line branch="false" hits="0" number="328"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="332"/> + <line branch="false" hits="0" number="333"/> + <line branch="false" hits="0" number="337"/> + <line branch="false" hits="0" number="338"/> + <line branch="false" hits="24" number="341"/> + <line branch="false" hits="24" number="343"/> + <line branch="false" hits="24" number="346"/> + <line branch="false" hits="24" number="347"/> + <line branch="true" condition-coverage="100% (2/2)" hits="24" number="351"/> + <line branch="false" hits="24" number="352"/> + <line branch="false" hits="24" number="354"/> + <line branch="false" hits="24" number="357"/> + <line branch="true" condition-coverage="100% (2/2)" hits="24" number="359"/> + <line branch="true" condition-coverage="100% (2/2)" hits="24" number="361"/> + <line branch="false" hits="24" number="362"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="363"/> + <line branch="false" hits="24" number="366"/> + <line branch="false" hits="24" number="377"/> + <line branch="false" hits="24" number="378"/> + <line branch="false" hits="24" number="379"/> + <line branch="false" hits="24" number="380"/> + <line branch="false" hits="24" number="381"/> + <line branch="false" hits="24" number="383"/> + <line branch="false" hits="24" number="384"/> + <line branch="true" condition-coverage="100% (2/2)" hits="24" number="386"/> + <line branch="false" hits="24" number="396"/> + <line branch="false" hits="24" number="397"/> + <line branch="false" hits="4" number="405"/> + <line branch="false" hits="4" number="406"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="408"/> + <line branch="false" hits="4" number="413"/> + <line branch="false" hits="20" number="418"/> + <line branch="false" hits="0" number="429"/> + <line branch="false" hits="0" number="433"/> + <line branch="false" hits="0" number="434"/> + <line branch="false" hits="0" number="435"/> + <line branch="false" hits="20" number="440"/> + <line branch="false" hits="19" number="443"/> + <line branch="false" hits="1" number="450"/> + <line branch="false" hits="1" number="451"/> + <line branch="false" hits="1" number="452"/> + <line branch="false" hits="0" number="462"/> + <line branch="false" hits="20" number="464"/> + <line branch="false" hits="20" number="468"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="470"/> + <line branch="false" hits="8" number="480"/> + <line branch="false" hits="8" number="485"/> + <line branch="false" hits="0" number="490"/> + <line branch="false" hits="0" number="491"/> + <line branch="false" hits="8" number="493"/> + <line branch="false" hits="0" number="496"/> + <line branch="false" hits="0" number="497"/> + <line branch="false" hits="8" number="500"/> + <line branch="false" hits="8" number="502"/> + <line branch="false" hits="8" number="507"/> + <line branch="false" hits="8" number="520"/> + <line branch="false" hits="8" number="525"/> + <line branch="false" hits="8" number="527"/> + <line branch="false" hits="8" number="528"/> + <line branch="true" condition-coverage="50% (1/2)" hits="14" number="531"/> + <line branch="false" hits="0" number="534"/> + <line branch="false" hits="0" number="535"/> + <line branch="false" hits="14" number="538"/> + <line branch="false" hits="14" number="539"/> + <line branch="false" hits="8" number="543"/> + <line branch="false" hits="8" number="544"/> + <line branch="false" hits="8" number="549"/> + <line branch="true" condition-coverage="62% (5/8)" hits="0" number="552"/> + <line branch="false" hits="1" number="553"/> + <line branch="false" hits="1" number="554"/> + <line branch="false" hits="1" number="555"/> + <line branch="false" hits="1" number="559"/> + <line branch="false" hits="1" number="561"/> + <line branch="false" hits="1" number="562"/> + <line branch="false" hits="2" number="567"/> + <line branch="false" hits="1" number="570"/> + <line branch="false" hits="2" number="572"/> + <line branch="false" hits="2" number="574"/> + <line branch="false" hits="2" number="575"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" number="579"/> + <line branch="false" hits="1" number="580"/> + <line branch="false" hits="1" number="582"/> + <line branch="false" hits="1" number="583"/> + <line branch="false" hits="1" number="588"/> + <line branch="false" hits="1" number="589"/> + <line branch="false" hits="1" number="592"/> + <line branch="false" hits="1" number="594"/> + <line branch="false" hits="1" number="595"/> + <line branch="false" hits="0" number="599"/> + <line branch="false" hits="0" number="600"/> + <line branch="false" hits="0" number="605"/> + <line branch="false" hits="0" number="606"/> + <line branch="false" hits="0" number="610"/> + <line branch="false" hits="0" number="615"/> + <line branch="false" hits="0" number="616"/> + <line branch="false" hits="0" number="620"/> + <line branch="false" hits="0" number="621"/> + <line branch="false" hits="8" number="625"/> + <line branch="false" hits="2" number="628"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="629"/> + <line branch="false" hits="2" number="630"/> + <line branch="false" hits="1" number="632"/> + <line branch="false" hits="4" number="640"/> + <line branch="false" hits="4" number="647"/> + <line branch="false" hits="4" number="651"/> + <line branch="false" hits="4" number="653"/> + <line branch="false" hits="4" number="654"/> + <line branch="false" hits="4" number="656"/> + <line branch="false" hits="4" number="661"/> + <line branch="false" hits="8" number="662"/> + <line branch="false" hits="8" number="663"/> + <line branch="false" hits="0" number="665"/> + <line branch="false" hits="0" number="666"/> + <line branch="false" hits="0" number="667"/> + <line branch="false" hits="4" number="673"/> + <line branch="false" hits="8" number="675"/> + <line branch="false" hits="8" number="676"/> + <line branch="false" hits="8" number="679"/> + <line branch="false" hits="8" number="680"/> + <line branch="false" hits="33" number="682"/> + <line branch="false" hits="33" number="683"/> + <line branch="false" hits="33" number="684"/> + <line branch="false" hits="33" number="685"/> + <line branch="false" hits="33" number="687"/> + <line branch="false" hits="4" number="690"/> + <line branch="false" hits="4" number="694"/> + <line branch="false" hits="4" number="695"/> + <line branch="false" hits="4" number="697"/> + <line branch="false" hits="4" number="698"/> + <line branch="false" hits="4" number="699"/> + <line branch="false" hits="4" number="700"/> + <line branch="false" hits="4" number="711"/> + <line branch="false" hits="1" number="720"/> + <line branch="false" hits="1" number="721"/> + <line branch="false" hits="1" number="722"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="726"/> + <line branch="false" hits="1" number="727"/> + <line branch="false" hits="1" number="732"/> + <line branch="false" hits="2" number="734"/> + <line branch="false" hits="2" number="736"/> + <line branch="false" hits="2" number="737"/> + <line branch="false" hits="4" number="740"/> + <line branch="false" hits="1" number="745"/> + <line branch="false" hits="1" number="746"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="749"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="750"/> + <line branch="false" hits="1" number="752"/> + <line branch="false" hits="24" number="754"/> + <line branch="false" hits="4" number="756"/> + </lines> + </class> + <class branch-rate="0.5" complexity="0" filename="src/controller/VideoContextPlayerCoordinatorFactory.ts" line-rate="0.88" name="src.controller.VideoContextPlayerCoordinatorFactory.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="4" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="VideoContextPlayerCoordinatorFactory" signature=""> + <lines> + <line branch="false" hits="33" number="11"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="33" number="14"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="4" number="2"/> + <line branch="false" hits="4" number="3"/> + <line branch="false" hits="4" number="4"/> + <line branch="false" hits="4" number="5"/> + <line branch="false" hits="4" number="6"/> + <line branch="false" hits="4" number="9"/> + <line branch="false" hits="33" number="12"/> + <line branch="false" hits="33" number="14"/> + <line branch="false" hits="33" number="15"/> + <line branch="false" hits="33" number="16"/> + <line branch="false" hits="33" number="17"/> + <line branch="false" hits="33" number="18"/> + <line branch="false" hits="33" number="19"/> + <line branch="false" hits="33" number="20"/> + <line branch="false" hits="33" number="22"/> + <line branch="true" condition-coverage="50% (1/2)" hits="33" number="24"/> + <line branch="false" hits="33" number="25"/> + <line branch="false" hits="0" number="28"/> + <line branch="false" hits="0" number="29"/> + <line branch="false" hits="33" number="32"/> + <line branch="false" hits="33" number="36"/> + <line branch="false" hits="0" number="42"/> + <line branch="false" hits="33" number="47"/> + <line branch="false" hits="33" number="52"/> + <line branch="false" hits="4" number="62"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/controller/index.ts" line-rate="1.0" name="src.controller.index.ts"> + <methods/> + <lines> + <line branch="false" hits="3" number="1"/> + <line branch="false" hits="3" number="2"/> + <line branch="false" hits="3" number="4"/> + <line branch="false" hits="3" number="5"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.8478260869565217" complexity="0" line-rate="0.8625592417061612" name="src.controller-x"> + <classes> + <class branch-rate="0.8478260869565217" complexity="0" filename="src/controller-x/VideoContextPlayerCoordinatorX.ts" line-rate="0.8313953488372093" name="src.controller-x.VideoContextPlayerCoordinatorX.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="3" number="43"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="VideoContextPlayerCoordinatorX" signature=""> + <lines> + <line branch="false" hits="30" number="59"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="21" number="99"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="0" number="126"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="0" number="132"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="1" number="219"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="13" number="233"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="0" number="290"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="17" number="338"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_37)" signature=""> + <lines> + <line branch="false" hits="17" number="341"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_38)" signature=""> + <lines> + <line branch="false" hits="17" number="362"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="0" number="363"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_40)" signature=""> + <lines> + <line branch="false" hits="7" number="422"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_41)" signature=""> + <lines> + <line branch="false" hits="5" number="435"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_42)" signature=""> + <lines> + <line branch="false" hits="30" number="444"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_43)" signature=""> + <lines> + <line branch="false" hits="3" number="458"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_44)" signature=""> + <lines> + <line branch="false" hits="1" number="466"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_45)" signature=""> + <lines> + <line branch="false" hits="1" number="477"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_46)" signature=""> + <lines> + <line branch="false" hits="0" number="507"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="3" number="1"/> + <line branch="false" hits="3" number="2"/> + <line branch="false" hits="3" number="25"/> + <line branch="false" hits="3" number="26"/> + <line branch="false" hits="3" number="27"/> + <line branch="false" hits="3" number="28"/> + <line branch="false" hits="3" number="29"/> + <line branch="false" hits="3" number="31"/> + <line branch="false" hits="3" number="34"/> + <line branch="false" hits="3" number="43"/> + <line branch="false" hits="30" number="57"/> + <line branch="false" hits="30" number="59"/> + <line branch="false" hits="30" number="60"/> + <line branch="false" hits="30" number="61"/> + <line branch="false" hits="30" number="62"/> + <line branch="false" hits="30" number="68"/> + <line branch="false" hits="30" number="73"/> + <line branch="false" hits="0" number="74"/> + <line branch="false" hits="0" number="75"/> + <line branch="false" hits="0" number="79"/> + <line branch="false" hits="30" number="81"/> + <line branch="false" hits="30" number="83"/> + <line branch="false" hits="30" number="85"/> + <line branch="false" hits="30" number="86"/> + <line branch="false" hits="30" number="89"/> + <line branch="false" hits="30" number="90"/> + <line branch="false" hits="30" number="92"/> + <line branch="false" hits="3" number="99"/> + <line branch="false" hits="21" number="100"/> + <line branch="false" hits="21" number="104"/> + <line branch="false" hits="21" number="109"/> + <line branch="true" condition-coverage="100% (1/1)" hits="0" number="110"/> + <line branch="false" hits="21" number="117"/> + <line branch="false" hits="21" number="121"/> + <line branch="false" hits="21" number="123"/> + <line branch="false" hits="21" number="129"/> + <line branch="false" hits="3" number="136"/> + <line branch="true" condition-coverage="50% (1/2)" hits="11" number="139"/> + <line branch="false" hits="11" number="141"/> + <line branch="false" hits="0" number="142"/> + <line branch="false" hits="0" number="143"/> + <line branch="false" hits="5" number="146"/> + <line branch="false" hits="5" number="147"/> + <line branch="false" hits="10" number="148"/> + <line branch="false" hits="5" number="150"/> + <line branch="false" hits="5" number="155"/> + <line branch="false" hits="1" number="158"/> + <line branch="false" hits="1" number="159"/> + <line branch="false" hits="1" number="160"/> + <line branch="false" hits="1" number="162"/> + <line branch="false" hits="1" number="164"/> + <line branch="false" hits="1" number="166"/> + <line branch="false" hits="2" number="168"/> + <line branch="false" hits="2" number="170"/> + <line branch="false" hits="1" number="174"/> + <line branch="false" hits="2" number="176"/> + <line branch="false" hits="2" number="178"/> + <line branch="false" hits="1" number="180"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" number="182"/> + <line branch="false" hits="1" number="183"/> + <line branch="false" hits="1" number="185"/> + <line branch="false" hits="1" number="187"/> + <line branch="false" hits="1" number="189"/> + <line branch="false" hits="0" number="191"/> + <line branch="false" hits="0" number="193"/> + <line branch="false" hits="0" number="195"/> + <line branch="false" hits="0" number="198"/> + <line branch="false" hits="0" number="201"/> + <line branch="false" hits="6" number="203"/> + <line branch="false" hits="3" number="206"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="209"/> + <line branch="false" hits="2" number="210"/> + <line branch="false" hits="2" number="212"/> + <line branch="false" hits="2" number="214"/> + <line branch="false" hits="0" number="216"/> + <line branch="false" hits="3" number="219"/> + <line branch="false" hits="1" number="223"/> + <line branch="false" hits="1" number="224"/> + <line branch="false" hits="1" number="225"/> + <line branch="false" hits="1" number="226"/> + <line branch="false" hits="3" number="233"/> + <line branch="false" hits="1" number="235"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="238"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="240"/> + <line branch="false" hits="1" number="243"/> + <line branch="false" hits="1" number="247"/> + <line branch="false" hits="1" number="250"/> + <line branch="false" hits="1" number="252"/> + <line branch="false" hits="1" number="256"/> + <line branch="false" hits="7" number="259"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="261"/> + <line branch="false" hits="7" number="262"/> + <line branch="false" hits="7" number="264"/> + <line branch="false" hits="7" number="265"/> + <line branch="false" hits="0" number="269"/> + <line branch="true" condition-coverage="100% (7/7)" hits="0" number="273"/> + <line branch="false" hits="1" number="274"/> + <line branch="false" hits="1" number="276"/> + <line branch="false" hits="1" number="278"/> + <line branch="false" hits="1" number="280"/> + <line branch="false" hits="1" number="282"/> + <line branch="false" hits="1" number="284"/> + <line branch="false" hits="1" number="286"/> + <line branch="false" hits="3" number="290"/> + <line branch="false" hits="0" number="291"/> + <line branch="false" hits="0" number="293"/> + <line branch="false" hits="3" number="299"/> + <line branch="false" hits="21" number="303"/> + <line branch="false" hits="21" number="306"/> + <line branch="false" hits="21" number="307"/> + <line branch="false" hits="7" number="310"/> + <line branch="true" condition-coverage="50% (1/2)" hits="7" number="311"/> + <line branch="false" hits="0" number="313"/> + <line branch="false" hits="0" number="316"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="320"/> + <line branch="false" hits="0" number="321"/> + <line branch="false" hits="0" number="325"/> + <line branch="false" hits="21" number="328"/> + <line branch="false" hits="21" number="333"/> + <line branch="false" hits="21" number="334"/> + <line branch="false" hits="21" number="335"/> + <line branch="false" hits="4" number="337"/> + <line branch="false" hits="17" number="338"/> + <line branch="false" hits="17" number="339"/> + <line branch="false" hits="0" number="350"/> + <line branch="false" hits="0" number="354"/> + <line branch="false" hits="0" number="355"/> + <line branch="false" hits="0" number="356"/> + <line branch="false" hits="17" number="360"/> + <line branch="false" hits="17" number="362"/> + <line branch="false" hits="0" number="363"/> + <line branch="false" hits="4" number="368"/> + <line branch="false" hits="21" number="371"/> + <line branch="true" condition-coverage="100% (2/2)" hits="21" number="373"/> + <line branch="false" hits="21" number="374"/> + <line branch="true" condition-coverage="100% (2/2)" hits="21" number="376"/> + <line branch="false" hits="21" number="379"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="386"/> + <line branch="false" hits="21" number="390"/> + <line branch="false" hits="21" number="391"/> + <line branch="false" hits="21" number="392"/> + <line branch="false" hits="21" number="393"/> + <line branch="false" hits="21" number="394"/> + <line branch="false" hits="21" number="397"/> + <line branch="false" hits="21" number="398"/> + <line branch="true" condition-coverage="100% (2/2)" hits="21" number="400"/> + <line branch="false" hits="21" number="402"/> + <line branch="false" hits="0" number="412"/> + <line branch="false" hits="21" number="415"/> + <line branch="false" hits="21" number="416"/> + <line branch="false" hits="3" number="422"/> + <line branch="false" hits="7" number="424"/> + <line branch="false" hits="7" number="428"/> + <line branch="false" hits="7" number="430"/> + <line branch="false" hits="3" number="435"/> + <line branch="false" hits="5" number="436"/> + <line branch="false" hits="5" number="438"/> + <line branch="false" hits="3" number="444"/> + <line branch="false" hits="0" number="446"/> + <line branch="false" hits="0" number="447"/> + <line branch="false" hits="0" number="450"/> + <line branch="false" hits="0" number="451"/> + <line branch="false" hits="30" number="453"/> + <line branch="false" hits="30" number="454"/> + <line branch="false" hits="30" number="455"/> + <line branch="false" hits="3" number="458"/> + <line branch="false" hits="3" number="459"/> + <line branch="false" hits="2" number="461"/> + <line branch="false" hits="2" number="462"/> + <line branch="false" hits="3" number="466"/> + <line branch="false" hits="1" number="467"/> + <line branch="false" hits="1" number="471"/> + <line branch="false" hits="3" number="477"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="478"/> + <line branch="false" hits="1" number="479"/> + <line branch="false" hits="1" number="482"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="483"/> + <line branch="false" hits="1" number="486"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="487"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="491"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="493"/> + <line branch="true" condition-coverage="75% (3/4)" hits="0" number="495"/> + <line branch="false" hits="1" number="499"/> + <line branch="false" hits="3" number="507"/> + <line branch="false" hits="0" number="508"/> + <line branch="false" hits="3" number="510"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/controller-x/VideoContextPlayerCoordinatorXObserver.ts" line-rate="1.0" name="src.controller-x.VideoContextPlayerCoordinatorXObserver.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="3" number="5"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="VideoContextPlayerCoordinatorXObserver" signature=""> + <lines> + <line branch="false" hits="3" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="1" number="13"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="4" number="17"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="24"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="1" number="26"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="30"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="32"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="1" number="34"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="0" number="38"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="40"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="0" number="42"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="1" number="44"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="0" number="48"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="0" number="50"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="0" number="52"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="1" number="54"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="1" number="58"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="1" number="62"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="1" number="66"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="1" number="70"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="0" number="74"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="0" number="76"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="0" number="78"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="3" number="2"/> + <line branch="false" hits="3" number="5"/> + <line branch="false" hits="3" number="10"/> + <line branch="false" hits="3" number="13"/> + <line branch="false" hits="1" number="14"/> + <line branch="false" hits="3" number="17"/> + <line branch="false" hits="4" number="18"/> + <line branch="false" hits="2" number="20"/> + <line branch="false" hits="3" number="24"/> + <line branch="false" hits="3" number="26"/> + <line branch="false" hits="1" number="27"/> + <line branch="false" hits="3" number="30"/> + <line branch="false" hits="3" number="32"/> + <line branch="false" hits="3" number="34"/> + <line branch="false" hits="1" number="35"/> + <line branch="false" hits="3" number="38"/> + <line branch="false" hits="3" number="40"/> + <line branch="false" hits="3" number="42"/> + <line branch="false" hits="3" number="44"/> + <line branch="false" hits="1" number="45"/> + <line branch="false" hits="3" number="48"/> + <line branch="false" hits="3" number="50"/> + <line branch="false" hits="3" number="52"/> + <line branch="false" hits="3" number="54"/> + <line branch="false" hits="1" number="55"/> + <line branch="false" hits="3" number="58"/> + <line branch="false" hits="1" number="59"/> + <line branch="false" hits="3" number="62"/> + <line branch="false" hits="1" number="63"/> + <line branch="false" hits="3" number="66"/> + <line branch="false" hits="1" number="67"/> + <line branch="false" hits="3" number="70"/> + <line branch="false" hits="1" number="71"/> + <line branch="false" hits="3" number="74"/> + <line branch="false" hits="3" number="76"/> + <line branch="false" hits="3" number="78"/> + <line branch="false" hits="3" number="79"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/controller-x/index.ts" line-rate="1.0" name="src.controller-x.index.ts"> + <methods/> + <lines> + <line branch="false" hits="3" number="1"/> + <line branch="false" hits="3" number="2"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.0" complexity="0" line-rate="0.7894736842105263" name="src.events"> + <classes> + <class branch-rate="0.0" complexity="0" filename="src/events/InternalPlaybackObserver.ts" line-rate="0.7291666666666666" name="src.events.InternalPlaybackObserver.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="11" number="17"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="InternalPlaybackObserver" signature=""> + <lines> + <line branch="false" hits="107" number="21"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="89" number="26"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="0" number="32"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="39"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="89" number="42"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="48"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="57"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="0" number="59"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="89" number="63"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="65"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="27" number="69"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="0" number="71"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="5" number="75"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="0" number="77"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="1" number="81"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="0" number="83"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="2" number="87"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="0" number="89"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="7" number="93"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="0" number="95"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="1" number="99"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="0" number="101"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="2" number="106"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="0" number="108"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="2" number="113"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="0" number="115"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="98" number="120"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="0" number="122"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="4" number="126"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="0" number="128"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="4" number="132"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="0" number="134"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="93" number="138"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_34)" signature=""> + <lines> + <line branch="false" hits="0" number="144"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="1" number="149"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="0" number="151"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_37)" signature=""> + <lines> + <line branch="false" hits="1" number="156"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_38)" signature=""> + <lines> + <line branch="false" hits="0" number="158"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="1" number="163"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_40)" signature=""> + <lines> + <line branch="false" hits="0" number="165"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_41)" signature=""> + <lines> + <line branch="false" hits="1" number="170"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_42)" signature=""> + <lines> + <line branch="false" hits="0" number="172"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_43)" signature=""> + <lines> + <line branch="false" hits="4" number="177"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_44)" signature=""> + <lines> + <line branch="false" hits="0" number="179"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_45)" signature=""> + <lines> + <line branch="false" hits="8" number="184"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_46)" signature=""> + <lines> + <line branch="false" hits="0" number="186"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_47)" signature=""> + <lines> + <line branch="false" hits="3" number="191"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_48)" signature=""> + <lines> + <line branch="false" hits="0" number="193"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="11" number="17"/> + <line branch="false" hits="107" number="22"/> + <line branch="false" hits="107" number="23"/> + <line branch="false" hits="11" number="26"/> + <line branch="false" hits="89" number="31"/> + <line branch="false" hits="0" number="33"/> + <line branch="false" hits="0" number="39"/> + <line branch="false" hits="11" number="42"/> + <line branch="false" hits="89" number="47"/> + <line branch="false" hits="89" number="48"/> + <line branch="false" hits="0" number="49"/> + <line branch="false" hits="11" number="57"/> + <line branch="false" hits="0" number="58"/> + <line branch="false" hits="0" number="59"/> + <line branch="false" hits="0" number="60"/> + <line branch="false" hits="11" number="63"/> + <line branch="false" hits="89" number="64"/> + <line branch="false" hits="89" number="65"/> + <line branch="false" hits="0" number="66"/> + <line branch="false" hits="11" number="69"/> + <line branch="false" hits="27" number="70"/> + <line branch="false" hits="27" number="71"/> + <line branch="false" hits="0" number="72"/> + <line branch="false" hits="11" number="75"/> + <line branch="false" hits="5" number="76"/> + <line branch="false" hits="5" number="77"/> + <line branch="false" hits="0" number="78"/> + <line branch="false" hits="11" number="81"/> + <line branch="false" hits="1" number="82"/> + <line branch="false" hits="1" number="83"/> + <line branch="false" hits="0" number="84"/> + <line branch="false" hits="11" number="87"/> + <line branch="false" hits="2" number="88"/> + <line branch="false" hits="2" number="89"/> + <line branch="false" hits="0" number="90"/> + <line branch="false" hits="11" number="93"/> + <line branch="false" hits="7" number="94"/> + <line branch="false" hits="7" number="95"/> + <line branch="false" hits="0" number="96"/> + <line branch="false" hits="11" number="99"/> + <line branch="false" hits="1" number="100"/> + <line branch="false" hits="1" number="101"/> + <line branch="false" hits="0" number="102"/> + <line branch="false" hits="11" number="106"/> + <line branch="false" hits="2" number="107"/> + <line branch="false" hits="2" number="108"/> + <line branch="false" hits="0" number="109"/> + <line branch="false" hits="11" number="113"/> + <line branch="false" hits="2" number="114"/> + <line branch="false" hits="2" number="115"/> + <line branch="false" hits="0" number="116"/> + <line branch="false" hits="11" number="120"/> + <line branch="false" hits="98" number="121"/> + <line branch="false" hits="98" number="122"/> + <line branch="false" hits="0" number="123"/> + <line branch="false" hits="11" number="126"/> + <line branch="false" hits="4" number="127"/> + <line branch="false" hits="4" number="128"/> + <line branch="false" hits="0" number="129"/> + <line branch="false" hits="11" number="132"/> + <line branch="false" hits="4" number="133"/> + <line branch="false" hits="4" number="134"/> + <line branch="false" hits="0" number="135"/> + <line branch="false" hits="11" number="138"/> + <line branch="false" hits="93" number="143"/> + <line branch="false" hits="93" number="144"/> + <line branch="false" hits="0" number="145"/> + <line branch="false" hits="11" number="149"/> + <line branch="false" hits="1" number="150"/> + <line branch="false" hits="1" number="151"/> + <line branch="false" hits="0" number="152"/> + <line branch="false" hits="11" number="156"/> + <line branch="false" hits="1" number="157"/> + <line branch="false" hits="1" number="158"/> + <line branch="false" hits="0" number="159"/> + <line branch="false" hits="11" number="163"/> + <line branch="false" hits="1" number="164"/> + <line branch="false" hits="1" number="165"/> + <line branch="false" hits="0" number="166"/> + <line branch="false" hits="11" number="170"/> + <line branch="false" hits="1" number="171"/> + <line branch="false" hits="1" number="172"/> + <line branch="false" hits="0" number="173"/> + <line branch="false" hits="11" number="177"/> + <line branch="false" hits="4" number="178"/> + <line branch="false" hits="4" number="179"/> + <line branch="false" hits="0" number="180"/> + <line branch="false" hits="11" number="184"/> + <line branch="false" hits="8" number="185"/> + <line branch="false" hits="8" number="186"/> + <line branch="false" hits="0" number="187"/> + <line branch="false" hits="11" number="191"/> + <line branch="false" hits="3" number="192"/> + <line branch="false" hits="3" number="193"/> + <line branch="false" hits="0" number="194"/> + <line branch="false" hits="11" number="197"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/events/PlaybackEventsObserver.ts" line-rate="0.9878048780487805" name="src.events.PlaybackEventsObserver.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="11" number="24"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="PlaybackEventsObserver" signature=""> + <lines> + <line branch="false" hits="90" number="28"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="89" number="36"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="12" number="48"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="6" number="52"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="89" number="56"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="71"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="89" number="75"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="27" number="88"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="4" number="97"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="1" number="101"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="1" number="105"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="2" number="112"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="7" number="116"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="1" number="124"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="2" number="129"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="2" number="134"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="98" number="142"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="4" number="150"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="4" number="157"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="93" number="165"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="1" number="177"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="1" number="184"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="1" number="191"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="1" number="196"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="4" number="204"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="8" number="211"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="3" number="219"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="461" number="227"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="11" number="13"/> + <line branch="false" hits="11" number="24"/> + <line branch="false" hits="90" number="32"/> + <line branch="false" hits="90" number="33"/> + <line branch="false" hits="11" number="36"/> + <line branch="false" hits="89" number="41"/> + <line branch="false" hits="11" number="48"/> + <line branch="false" hits="12" number="49"/> + <line branch="false" hits="11" number="52"/> + <line branch="false" hits="6" number="53"/> + <line branch="false" hits="11" number="56"/> + <line branch="false" hits="89" number="61"/> + <line branch="false" hits="89" number="66"/> + <line branch="false" hits="11" number="71"/> + <line branch="false" hits="0" number="72"/> + <line branch="false" hits="11" number="75"/> + <line branch="false" hits="89" number="80"/> + <line branch="false" hits="89" number="81"/> + <line branch="false" hits="11" number="88"/> + <line branch="false" hits="27" number="89"/> + <line branch="false" hits="27" number="90"/> + <line branch="false" hits="11" number="97"/> + <line branch="false" hits="4" number="98"/> + <line branch="false" hits="4" number="99"/> + <line branch="false" hits="11" number="101"/> + <line branch="false" hits="1" number="102"/> + <line branch="false" hits="1" number="103"/> + <line branch="false" hits="11" number="105"/> + <line branch="false" hits="1" number="106"/> + <line branch="false" hits="1" number="107"/> + <line branch="false" hits="11" number="112"/> + <line branch="false" hits="2" number="113"/> + <line branch="false" hits="2" number="114"/> + <line branch="false" hits="11" number="116"/> + <line branch="false" hits="7" number="117"/> + <line branch="false" hits="7" number="118"/> + <line branch="false" hits="11" number="124"/> + <line branch="false" hits="1" number="125"/> + <line branch="false" hits="1" number="126"/> + <line branch="false" hits="11" number="129"/> + <line branch="false" hits="2" number="130"/> + <line branch="false" hits="2" number="131"/> + <line branch="false" hits="11" number="134"/> + <line branch="false" hits="2" number="135"/> + <line branch="false" hits="2" number="136"/> + <line branch="false" hits="11" number="142"/> + <line branch="false" hits="98" number="143"/> + <line branch="false" hits="98" number="144"/> + <line branch="false" hits="11" number="150"/> + <line branch="false" hits="4" number="151"/> + <line branch="false" hits="4" number="152"/> + <line branch="false" hits="11" number="157"/> + <line branch="false" hits="4" number="158"/> + <line branch="false" hits="4" number="159"/> + <line branch="false" hits="11" number="165"/> + <line branch="false" hits="93" number="170"/> + <line branch="false" hits="93" number="171"/> + <line branch="false" hits="11" number="177"/> + <line branch="false" hits="1" number="178"/> + <line branch="false" hits="1" number="179"/> + <line branch="false" hits="11" number="184"/> + <line branch="false" hits="1" number="185"/> + <line branch="false" hits="1" number="186"/> + <line branch="false" hits="11" number="191"/> + <line branch="false" hits="1" number="192"/> + <line branch="false" hits="1" number="193"/> + <line branch="false" hits="11" number="196"/> + <line branch="false" hits="1" number="197"/> + <line branch="false" hits="1" number="198"/> + <line branch="false" hits="11" number="204"/> + <line branch="false" hits="4" number="205"/> + <line branch="false" hits="4" number="206"/> + <line branch="false" hits="11" number="211"/> + <line branch="false" hits="8" number="212"/> + <line branch="false" hits="8" number="213"/> + <line branch="false" hits="11" number="219"/> + <line branch="false" hits="3" number="220"/> + <line branch="false" hits="3" number="221"/> + <line branch="false" hits="11" number="227"/> + <line branch="false" hits="461" number="228"/> + <line branch="false" hits="461" number="229"/> + <line branch="false" hits="11" number="231"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/events/TimeObservable.ts" line-rate="0.37037037037037035" name="src.events.TimeObservable.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="13" number="4"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="TimeObservable" signature=""> + <lines> + <line branch="false" hits="101" number="8"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="0" number="13"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="14"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="0" number="17"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="22"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="27"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="0" number="31"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="11" number="41"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="46"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="13" number="4"/> + <line branch="false" hits="101" number="8"/> + <line branch="false" hits="101" number="9"/> + <line branch="false" hits="101" number="10"/> + <line branch="false" hits="101" number="13"/> + <line branch="false" hits="0" number="14"/> + <line branch="false" hits="0" number="15"/> + <line branch="false" hits="0" number="17"/> + <line branch="false" hits="0" number="18"/> + <line branch="false" hits="13" number="22"/> + <line branch="false" hits="0" number="26"/> + <line branch="false" hits="0" number="27"/> + <line branch="false" hits="0" number="28"/> + <line branch="false" hits="0" number="29"/> + <line branch="false" hits="0" number="30"/> + <line branch="false" hits="0" number="31"/> + <line branch="false" hits="0" number="33"/> + <line branch="false" hits="0" number="34"/> + <line branch="false" hits="0" number="36"/> + <line branch="false" hits="13" number="41"/> + <line branch="false" hits="11" number="45"/> + <line branch="false" hits="11" number="46"/> + <line branch="false" hits="0" number="47"/> + <line branch="false" hits="0" number="48"/> + <line branch="false" hits="0" number="52"/> + <line branch="false" hits="0" number="53"/> + <line branch="false" hits="13" number="57"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/events/index.ts" line-rate="1.0" name="src.events.index.ts"> + <methods/> + <lines> + <line branch="false" hits="11" number="1"/> + <line branch="false" hits="11" number="2"/> + <line branch="false" hits="11" number="4"/> + <line branch="false" hits="11" number="5"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.9067796610169492" complexity="0" line-rate="0.834319526627219" name="src.player"> + <classes> + <class branch-rate="0.8" complexity="0" filename="src/player/BetamaxPlayer.ts" line-rate="0.6951219512195121" name="src.player.BetamaxPlayer.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="10" number="25"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="BetamaxPlayer" signature=""> + <lines> + <line branch="false" hits="14" number="31"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="6" number="277"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="442" number="283"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="6" number="283"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="442" number="288"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="16" number="47"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="17" number="58"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="17" number="74"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="0" number="76"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="0" number="87"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="0" number="95"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="0" number="108"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="1" number="121"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="0" number="134"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="0" number="146"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="1" number="154"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="0" number="162"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="0" number="168"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="0" number="179"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="0" number="191"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="0" number="203"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="0" number="216"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="0" number="228"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="17" number="232"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_34)" signature=""> + <lines> + <line branch="false" hits="3" number="244"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="1" number="252"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="17" number="256"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_37)" signature=""> + <lines> + <line branch="false" hits="442" number="266"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="10" number="8"/> + <line branch="false" hits="10" number="9"/> + <line branch="false" hits="10" number="15"/> + <line branch="false" hits="10" number="17"/> + <line branch="false" hits="10" number="25"/> + <line branch="true" condition-coverage="100% (2/2)" hits="14" number="35"/> + <line branch="false" hits="14" number="36"/> + <line branch="false" hits="14" number="37"/> + <line branch="false" hits="14" number="38"/> + <line branch="false" hits="10" number="47"/> + <line branch="false" hits="16" number="48"/> + <line branch="false" hits="17" number="58"/> + <line branch="false" hits="17" number="62"/> + <line branch="false" hits="17" number="64"/> + <line branch="false" hits="17" number="69"/> + <line branch="false" hits="17" number="74"/> + <line branch="false" hits="0" number="76"/> + <line branch="false" hits="0" number="77"/> + <line branch="false" hits="10" number="87"/> + <line branch="false" hits="0" number="89"/> + <line branch="false" hits="0" number="91"/> + <line branch="false" hits="10" number="95"/> + <line branch="false" hits="0" number="97"/> + <line branch="false" hits="0" number="99"/> + <line branch="false" hits="10" number="108"/> + <line branch="false" hits="0" number="110"/> + <line branch="false" hits="0" number="112"/> + <line branch="false" hits="10" number="121"/> + <line branch="false" hits="1" number="122"/> + <line branch="false" hits="0" number="124"/> + <line branch="false" hits="1" number="126"/> + <line branch="false" hits="10" number="134"/> + <line branch="false" hits="0" number="136"/> + <line branch="false" hits="0" number="138"/> + <line branch="false" hits="10" number="146"/> + <line branch="false" hits="0" number="148"/> + <line branch="false" hits="0" number="150"/> + <line branch="false" hits="10" number="154"/> + <line branch="false" hits="1" number="156"/> + <line branch="false" hits="1" number="157"/> + <line branch="false" hits="1" number="158"/> + <line branch="false" hits="10" number="162"/> + <line branch="false" hits="0" number="164"/> + <line branch="false" hits="10" number="168"/> + <line branch="false" hits="0" number="170"/> + <line branch="false" hits="10" number="179"/> + <line branch="false" hits="0" number="181"/> + <line branch="false" hits="0" number="183"/> + <line branch="false" hits="0" number="193"/> + <line branch="false" hits="0" number="195"/> + <line branch="false" hits="0" number="205"/> + <line branch="false" hits="0" number="207"/> + <line branch="false" hits="0" number="218"/> + <line branch="false" hits="0" number="220"/> + <line branch="false" hits="10" number="228"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="229"/> + <line branch="false" hits="10" number="232"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="233"/> + <line branch="false" hits="2" number="234"/> + <line branch="true" condition-coverage="100% (2/2)" hits="2" number="238"/> + <line branch="false" hits="2" number="239"/> + <line branch="false" hits="2" number="240"/> + <line branch="false" hits="10" number="244"/> + <line branch="false" hits="3" number="246"/> + <line branch="false" hits="3" number="247"/> + <line branch="false" hits="3" number="248"/> + <line branch="false" hits="10" number="252"/> + <line branch="false" hits="1" number="253"/> + <line branch="false" hits="17" number="256"/> + <line branch="false" hits="17" number="261"/> + <line branch="false" hits="17" number="266"/> + <line branch="false" hits="442" number="267"/> + <line branch="false" hits="17" number="270"/> + <line branch="false" hits="17" number="271"/> + <line branch="false" hits="0" number="273"/> + <line branch="false" hits="18" number="277"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="278"/> + <line branch="false" hits="1" number="279"/> + <line branch="false" hits="442" number="283"/> + <line branch="false" hits="6" number="284"/> + <line branch="false" hits="6" number="285"/> + <line branch="false" hits="14" number="288"/> + <line branch="false" hits="442" number="293"/> + <line branch="false" hits="10" number="295"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/player/BetamaxPlayerFactory.ts" line-rate="1.0" name="src.player.BetamaxPlayerFactory.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="10" number="6"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="BetamaxPlayerFactory" signature=""> + <lines> + <line branch="false" hits="68" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="68" number="15"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="10" number="2"/> + <line branch="false" hits="10" number="3"/> + <line branch="false" hits="10" number="6"/> + <line branch="false" hits="68" number="12"/> + <line branch="false" hits="10" number="15"/> + <line branch="false" hits="68" number="16"/> + <line branch="false" hits="68" number="19"/> + <line branch="false" hits="10" number="21"/> + </lines> + </class> + <class branch-rate="0.9393939393939394" complexity="0" filename="src/player/PlaybackSession.ts" line-rate="0.8888888888888888" name="src.player.PlaybackSession.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="10" number="50"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="PlaybackSession" signature=""> + <lines> + <line branch="false" hits="90" number="71"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="92" number="165"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="2" number="170"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="89" number="177"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="13" number="179"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="1" number="90"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="90" number="136"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="93" number="146"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="89" number="185"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="89" number="189"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_34)" signature=""> + <lines> + <line branch="false" hits="0" number="301"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="0" number="310"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="89" number="324"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_37)" signature=""> + <lines> + <line branch="false" hits="89" number="334"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_38)" signature=""> + <lines> + <line branch="false" hits="890" number="339"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="356" number="343"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_40)" signature=""> + <lines> + <line branch="false" hits="4" number="349"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_41)" signature=""> + <lines> + <line branch="false" hits="40" number="351"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_42)" signature=""> + <lines> + <line branch="false" hits="16" number="355"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_43)" signature=""> + <lines> + <line branch="false" hits="0" number="361"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_44)" signature=""> + <lines> + <line branch="false" hits="5" number="365"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_45)" signature=""> + <lines> + <line branch="false" hits="89" number="392"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_49)" signature=""> + <lines> + <line branch="false" hits="0" number="443"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_50)" signature=""> + <lines> + <line branch="false" hits="4" number="458"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_51)" signature=""> + <lines> + <line branch="false" hits="89" number="485"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_52)" signature=""> + <lines> + <line branch="false" hits="1" number="501"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_53)" signature=""> + <lines> + <line branch="false" hits="4" number="514"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_54)" signature=""> + <lines> + <line branch="false" hits="1" number="525"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_55)" signature=""> + <lines> + <line branch="false" hits="13" number="529"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_56)" signature=""> + <lines> + <line branch="false" hits="19" number="558"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_57)" signature=""> + <lines> + <line branch="false" hits="12" number="567"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_58)" signature=""> + <lines> + <line branch="false" hits="14" number="571"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_59)" signature=""> + <lines> + <line branch="false" hits="5" number="581"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_60)" signature=""> + <lines> + <line branch="false" hits="4" number="596"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_61)" signature=""> + <lines> + <line branch="false" hits="27" number="608"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_62)" signature=""> + <lines> + <line branch="false" hits="0" number="619"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_63)" signature=""> + <lines> + <line branch="false" hits="100" number="623"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_64)" signature=""> + <lines> + <line branch="false" hits="8" number="714"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_65)" signature=""> + <lines> + <line branch="false" hits="8" number="719"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_66)" signature=""> + <lines> + <line branch="false" hits="1" number="762"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_67)" signature=""> + <lines> + <line branch="false" hits="2" number="768"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_68)" signature=""> + <lines> + <line branch="false" hits="3" number="782"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_69)" signature=""> + <lines> + <line branch="false" hits="185" number="803"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_70)" signature=""> + <lines> + <line branch="false" hits="1" number="840"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_71)" signature=""> + <lines> + <line branch="false" hits="90" number="844"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_72)" signature=""> + <lines> + <line branch="false" hits="90" number="849"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_73)" signature=""> + <lines> + <line branch="false" hits="6" number="860"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_74)" signature=""> + <lines> + <line branch="false" hits="211" number="869"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_75)" signature=""> + <lines> + <line branch="false" hits="8" number="875"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_76)" signature=""> + <lines> + <line branch="false" hits="2" number="879"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_77)" signature=""> + <lines> + <line branch="false" hits="8" number="885"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_78)" signature=""> + <lines> + <line branch="false" hits="3" number="922"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_79)" signature=""> + <lines> + <line branch="false" hits="1" number="939"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_80)" signature=""> + <lines> + <line branch="false" hits="91" number="952"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_81)" signature=""> + <lines> + <line branch="false" hits="1562" number="965"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_82)" signature=""> + <lines> + <line branch="false" hits="774" number="969"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_83)" signature=""> + <lines> + <line branch="false" hits="1" number="983"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_84)" signature=""> + <lines> + <line branch="false" hits="1" number="987"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_85)" signature=""> + <lines> + <line branch="false" hits="9" number="991"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_86)" signature=""> + <lines> + <line branch="false" hits="96" number="1026"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_87)" signature=""> + <lines> + <line branch="false" hits="6" number="1035"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_88)" signature=""> + <lines> + <line branch="false" hits="8" number="1040"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_89)" signature=""> + <lines> + <line branch="false" hits="0" number="1076"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_93)" signature=""> + <lines> + <line branch="false" hits="6" number="1123"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_94)" signature=""> + <lines> + <line branch="false" hits="1" number="1134"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_95)" signature=""> + <lines> + <line branch="false" hits="90" number="1138"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_96)" signature=""> + <lines> + <line branch="false" hits="0" number="1142"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_97)" signature=""> + <lines> + <line branch="false" hits="0" number="1146"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_98)" signature=""> + <lines> + <line branch="false" hits="0" number="1150"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_99)" signature=""> + <lines> + <line branch="false" hits="2" number="1154"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_100)" signature=""> + <lines> + <line branch="false" hits="0" number="1158"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="10" number="1"/> + <line branch="false" hits="10" number="7"/> + <line branch="false" hits="10" number="8"/> + <line branch="false" hits="10" number="9"/> + <line branch="false" hits="10" number="10"/> + <line branch="false" hits="10" number="11"/> + <line branch="false" hits="10" number="33"/> + <line branch="false" hits="10" number="34"/> + <line branch="false" hits="10" number="42"/> + <line branch="false" hits="10" number="44"/> + <line branch="false" hits="10" number="45"/> + <line branch="false" hits="10" number="48"/> + <line branch="false" hits="10" number="50"/> + <line branch="true" condition-coverage="100% (2/2)" hits="90" number="75"/> + <line branch="false" hits="90" number="76"/> + <line branch="false" hits="90" number="77"/> + <line branch="false" hits="90" number="78"/> + <line branch="false" hits="1" number="83"/> + <line branch="false" hits="1" number="87"/> + <line branch="false" hits="90" number="90"/> + <line branch="false" hits="1" number="92"/> + <line branch="false" hits="1" number="96"/> + <line branch="false" hits="1" number="97"/> + <line branch="false" hits="90" number="101"/> + <line branch="false" hits="90" number="111"/> + <line branch="false" hits="90" number="116"/> + <line branch="false" hits="90" number="128"/> + <line branch="false" hits="10" number="136"/> + <line branch="false" hits="90" number="143"/> + <line branch="false" hits="10" number="146"/> + <line branch="false" hits="1" number="150"/> + <line branch="false" hits="1" number="153"/> + <line branch="false" hits="1" number="156"/> + <line branch="false" hits="1" number="159"/> + <line branch="false" hits="89" number="162"/> + <line branch="false" hits="90" number="165"/> + <line branch="true" condition-coverage="100% (2/2)" hits="182" number="167"/> + <line branch="false" hits="92" number="169"/> + <line branch="false" hits="2" number="171"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="172"/> + <line branch="false" hits="90" number="177"/> + <line branch="false" hits="89" number="179"/> + <line branch="false" hits="0" number="181"/> + <line branch="false" hits="89" number="185"/> + <line branch="false" hits="89" number="189"/> + <line branch="false" hits="89" number="191"/> + <line branch="false" hits="89" number="195"/> + <line branch="false" hits="89" number="199"/> + <line branch="false" hits="89" number="201"/> + <line branch="false" hits="89" number="204"/> + <line branch="false" hits="89" number="208"/> + <line branch="false" hits="89" number="212"/> + <line branch="false" hits="1" number="216"/> + <line branch="false" hits="1" number="220"/> + <line branch="false" hits="1" number="222"/> + <line branch="false" hits="1" number="229"/> + <line branch="false" hits="89" number="232"/> + <line branch="false" hits="89" number="233"/> + <line branch="false" hits="89" number="235"/> + <line branch="false" hits="89" number="236"/> + <line branch="false" hits="89" number="241"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="243"/> + <line branch="false" hits="89" number="245"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="247"/> + <line branch="false" hits="0" number="253"/> + <line branch="false" hits="89" number="259"/> + <line branch="false" hits="89" number="266"/> + <line branch="false" hits="89" number="267"/> + <line branch="false" hits="89" number="268"/> + <line branch="false" hits="89" number="269"/> + <line branch="false" hits="89" number="271"/> + <line branch="false" hits="89" number="273"/> + <line branch="false" hits="89" number="276"/> + <line branch="false" hits="89" number="283"/> + <line branch="false" hits="89" number="286"/> + <line branch="false" hits="89" number="290"/> + <line branch="false" hits="89" number="295"/> + <line branch="false" hits="89" number="300"/> + <line branch="false" hits="0" number="302"/> + <line branch="false" hits="0" number="308"/> + <line branch="false" hits="0" number="310"/> + <line branch="false" hits="0" number="312"/> + <line branch="false" hits="0" number="313"/> + <line branch="false" hits="0" number="314"/> + <line branch="false" hits="0" number="316"/> + <line branch="false" hits="89" number="325"/> + <line branch="false" hits="89" number="328"/> + <line branch="false" hits="89" number="329"/> + <line branch="false" hits="89" number="330"/> + <line branch="false" hits="89" number="334"/> + <line branch="false" hits="89" number="335"/> + <line branch="false" hits="89" number="339"/> + <line branch="false" hits="890" number="340"/> + <line branch="false" hits="89" number="343"/> + <line branch="false" hits="356" number="344"/> + <line branch="false" hits="10" number="349"/> + <line branch="false" hits="4" number="350"/> + <line branch="false" hits="4" number="351"/> + <line branch="false" hits="40" number="352"/> + <line branch="false" hits="4" number="355"/> + <line branch="false" hits="16" number="356"/> + <line branch="false" hits="10" number="361"/> + <line branch="false" hits="0" number="362"/> + <line branch="false" hits="10" number="365"/> + <line branch="false" hits="3" number="368"/> + <line branch="false" hits="3" number="369"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="370"/> + <line branch="false" hits="2" number="374"/> + <line branch="false" hits="2" number="375"/> + <line branch="false" hits="1" number="383"/> + <line branch="false" hits="1" number="384"/> + <line branch="false" hits="89" number="392"/> + <line branch="false" hits="89" number="393"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="409"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="410"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="411"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="413"/> + <line branch="false" hits="10" number="426"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="428"/> + <line branch="false" hits="0" number="431"/> + <line branch="false" hits="3" number="434"/> + <line branch="false" hits="3" number="436"/> + <line branch="false" hits="0" number="437"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="440"/> + <line branch="false" hits="0" number="441"/> + <line branch="false" hits="0" number="442"/> + <line branch="false" hits="0" number="444"/> + <line branch="false" hits="0" number="445"/> + <line branch="false" hits="0" number="449"/> + <line branch="false" hits="2" number="451"/> + <line branch="false" hits="1" number="454"/> + <line branch="false" hits="10" number="458"/> + <line branch="true" condition-coverage="100% (4/4)" hits="0" number="460"/> + <line branch="false" hits="1" number="465"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="471"/> + <line branch="false" hits="2" number="476"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="477"/> + <line branch="false" hits="2" number="479"/> + <line branch="false" hits="2" number="480"/> + <line branch="false" hits="10" number="485"/> + <line branch="false" hits="89" number="486"/> + <line branch="false" hits="89" number="487"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="488"/> + <line branch="false" hits="1" number="489"/> + <line branch="false" hits="1" number="492"/> + <line branch="false" hits="89" number="494"/> + <line branch="false" hits="10" number="501"/> + <line branch="false" hits="1" number="502"/> + <line branch="false" hits="1" number="505"/> + <line branch="false" hits="1" number="507"/> + <line branch="false" hits="10" number="514"/> + <line branch="false" hits="4" number="515"/> + <line branch="false" hits="4" number="516"/> + <line branch="false" hits="4" number="517"/> + <line branch="false" hits="4" number="522"/> + <line branch="false" hits="10" number="525"/> + <line branch="false" hits="1" number="526"/> + <line branch="false" hits="10" number="529"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="530"/> + <line branch="false" hits="1" number="532"/> + <line branch="true" condition-coverage="100% (3/3)" hits="12" number="535"/> + <line branch="false" hits="12" number="537"/> + <line branch="false" hits="12" number="538"/> + <line branch="false" hits="12" number="540"/> + <line branch="false" hits="12" number="549"/> + <line branch="false" hits="12" number="550"/> + <line branch="false" hits="2" number="553"/> + <line branch="false" hits="2" number="554"/> + <line branch="false" hits="10" number="558"/> + <line branch="false" hits="19" number="559"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="560"/> + <line branch="false" hits="16" number="561"/> + <line branch="false" hits="16" number="562"/> + <line branch="false" hits="19" number="564"/> + <line branch="false" hits="12" number="567"/> + <line branch="false" hits="11" number="571"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="572"/> + <line branch="false" hits="6" number="574"/> + <line branch="false" hits="10" number="581"/> + <line branch="false" hits="5" number="582"/> + <line branch="false" hits="5" number="583"/> + <line branch="false" hits="4" number="590"/> + <line branch="false" hits="1" number="592"/> + <line branch="false" hits="10" number="596"/> + <line branch="false" hits="4" number="597"/> + <line branch="false" hits="4" number="601"/> + <line branch="false" hits="4" number="602"/> + <line branch="false" hits="2" number="604"/> + <line branch="false" hits="10" number="608"/> + <line branch="true" condition-coverage="100% (2/2)" hits="27" number="609"/> + <line branch="true" condition-coverage="100% (2/2)" hits="27" number="610"/> + <line branch="false" hits="27" number="611"/> + <line branch="false" hits="27" number="612"/> + <line branch="false" hits="10" number="619"/> + <line branch="false" hits="0" number="620"/> + <line branch="false" hits="10" number="623"/> + <line branch="false" hits="99" number="625"/> + <line branch="false" hits="100" number="639"/> + <line branch="false" hits="100" number="640"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="642"/> + <line branch="false" hits="6" number="643"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="646"/> + <line branch="false" hits="6" number="647"/> + <line branch="false" hits="100" number="650"/> + <line branch="false" hits="100" number="652"/> + <line branch="false" hits="100" number="653"/> + <line branch="false" hits="100" number="654"/> + <line branch="true" condition-coverage="100% (3/3)" hits="0" number="657"/> + <line branch="false" hits="2" number="663"/> + <line branch="false" hits="2" number="664"/> + <line branch="false" hits="2" number="665"/> + <line branch="false" hits="100" number="668"/> + <line branch="true" condition-coverage="100% (5/5)" hits="0" number="671"/> + <line branch="false" hits="2" number="677"/> + <line branch="false" hits="100" number="680"/> + <line branch="true" condition-coverage="100% (2/2)" hits="100" number="683"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="684"/> + <line branch="false" hits="2" number="693"/> + <line branch="false" hits="98" number="695"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="698"/> + <line branch="false" hits="84" number="699"/> + <line branch="false" hits="100" number="701"/> + <line branch="false" hits="100" number="711"/> + <line branch="false" hits="10" number="714"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="715"/> + <line branch="false" hits="0" number="716"/> + <line branch="false" hits="8" number="719"/> + <line branch="false" hits="1" number="721"/> + <line branch="false" hits="7" number="723"/> + <line branch="false" hits="2" number="726"/> + <line branch="false" hits="4" number="742"/> + <line branch="false" hits="4" number="749"/> + <line branch="false" hits="5" number="755"/> + <line branch="false" hits="10" number="762"/> + <line branch="false" hits="1" number="763"/> + <line branch="false" hits="10" number="768"/> + <line branch="false" hits="1" number="771"/> + <line branch="false" hits="1" number="774"/> + <line branch="false" hits="1" number="775"/> + <line branch="false" hits="10" number="782"/> + <line branch="false" hits="3" number="784"/> + <line branch="false" hits="3" number="787"/> + <line branch="false" hits="3" number="793"/> + <line branch="false" hits="10" number="803"/> + <line branch="false" hits="93" number="806"/> + <line branch="true" condition-coverage="100% (2/2)" hits="6" number="808"/> + <line branch="false" hits="93" number="810"/> + <line branch="false" hits="93" number="816"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="823"/> + <line branch="false" hits="4" number="827"/> + <line branch="false" hits="92" number="833"/> + <line branch="false" hits="10" number="840"/> + <line branch="false" hits="1" number="841"/> + <line branch="false" hits="90" number="844"/> + <line branch="false" hits="0" number="846"/> + <line branch="false" hits="90" number="849"/> + <line branch="false" hits="90" number="850"/> + <line branch="false" hits="90" number="851"/> + <line branch="false" hits="90" number="853"/> + <line branch="false" hits="90" number="854"/> + <line branch="false" hits="10" number="860"/> + <line branch="false" hits="6" number="861"/> + <line branch="false" hits="6" number="862"/> + <line branch="false" hits="6" number="863"/> + <line branch="false" hits="6" number="864"/> + <line branch="false" hits="6" number="865"/> + <line branch="false" hits="6" number="866"/> + <line branch="false" hits="10" number="869"/> + <line branch="true" condition-coverage="100% (2/2)" hits="211" number="870"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="871"/> + <line branch="false" hits="10" number="875"/> + <line branch="false" hits="2" number="877"/> + <line branch="false" hits="2" number="879"/> + <line branch="true" condition-coverage="50% (1/2)" hits="2" number="880"/> + <line branch="false" hits="6" number="882"/> + <line branch="false" hits="10" number="885"/> + <line branch="false" hits="8" number="887"/> + <line branch="false" hits="8" number="888"/> + <line branch="false" hits="1" number="892"/> + <line branch="false" hits="7" number="895"/> + <line branch="false" hits="7" number="896"/> + <line branch="false" hits="7" number="897"/> + <line branch="false" hits="4" number="899"/> + <line branch="false" hits="4" number="900"/> + <line branch="false" hits="2" number="909"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="912"/> + <line branch="false" hits="0" number="915"/> + <line branch="false" hits="7" number="919"/> + <line branch="false" hits="10" number="922"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="927"/> + <line branch="false" hits="3" number="929"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="930"/> + <line branch="false" hits="3" number="933"/> + <line branch="false" hits="0" number="936"/> + <line branch="false" hits="10" number="939"/> + <line branch="true" condition-coverage="100% (4/4)" hits="0" number="941"/> + <line branch="false" hits="1" number="946"/> + <line branch="false" hits="0" number="949"/> + <line branch="false" hits="10" number="952"/> + <line branch="false" hits="1" number="954"/> + <line branch="false" hits="1" number="955"/> + <line branch="false" hits="90" number="957"/> + <line branch="false" hits="90" number="958"/> + <line branch="false" hits="91" number="960"/> + <line branch="false" hits="91" number="961"/> + <line branch="false" hits="91" number="962"/> + <line branch="false" hits="10" number="965"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1562" number="966"/> + <line branch="false" hits="10" number="969"/> + <line branch="false" hits="774" number="970"/> + <line branch="false" hits="774" number="971"/> + <line branch="false" hits="774" number="972"/> + <line branch="false" hits="563" number="975"/> + <line branch="false" hits="774" number="978"/> + <line branch="false" hits="10" number="983"/> + <line branch="false" hits="1" number="984"/> + <line branch="false" hits="10" number="987"/> + <line branch="false" hits="1" number="988"/> + <line branch="false" hits="10" number="991"/> + <line branch="false" hits="9" number="992"/> + <line branch="false" hits="0" number="995"/> + <line branch="true" condition-coverage="100% (2/2)" hits="9" number="997"/> + <line branch="false" hits="2" number="999"/> + <line branch="false" hits="1" number="1005"/> + <line branch="false" hits="9" number="1008"/> + <line branch="false" hits="9" number="1013"/> + <line branch="false" hits="9" number="1014"/> + <line branch="false" hits="9" number="1021"/> + <line branch="false" hits="9" number="1023"/> + <line branch="false" hits="10" number="1026"/> + <line branch="false" hits="96" number="1029"/> + <line branch="false" hits="96" number="1030"/> + <line branch="false" hits="96" number="1031"/> + <line branch="false" hits="96" number="1032"/> + <line branch="false" hits="10" number="1035"/> + <line branch="false" hits="6" number="1036"/> + <line branch="false" hits="6" number="1037"/> + <line branch="false" hits="10" number="1040"/> + <line branch="false" hits="8" number="1041"/> + <line branch="false" hits="8" number="1042"/> + <line branch="false" hits="8" number="1046"/> + <line branch="false" hits="8" number="1048"/> + <line branch="false" hits="8" number="1052"/> + <line branch="false" hits="0" number="1054"/> + <line branch="false" hits="0" number="1055"/> + <line branch="false" hits="0" number="1056"/> + <line branch="false" hits="0" number="1058"/> + <line branch="false" hits="8" number="1064"/> + <line branch="false" hits="0" number="1069"/> + <line branch="false" hits="8" number="1073"/> + <line branch="false" hits="10" number="1076"/> + <line branch="false" hits="0" number="1078"/> + <line branch="false" hits="10" number="1084"/> + <line branch="false" hits="4" number="1085"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="1086"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="1087"/> + <line branch="false" hits="4" number="1089"/> + <line branch="false" hits="4" number="1091"/> + <line branch="false" hits="4" number="1093"/> + <line branch="false" hits="4" number="1094"/> + <line branch="false" hits="4" number="1099"/> + <line branch="false" hits="0" number="1100"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="1101"/> + <line branch="false" hits="0" number="1102"/> + <line branch="false" hits="8" number="1105"/> + <line branch="false" hits="0" number="1106"/> + <line branch="false" hits="0" number="1108"/> + <line branch="false" hits="0" number="1112"/> + <line branch="false" hits="4" number="1115"/> + <line branch="false" hits="4" number="1117"/> + <line branch="false" hits="4" number="1118"/> + <line branch="false" hits="4" number="1119"/> + <line branch="false" hits="10" number="1123"/> + <line branch="false" hits="6" number="1125"/> + <line branch="false" hits="10" number="1134"/> + <line branch="false" hits="1" number="1135"/> + <line branch="false" hits="10" number="1138"/> + <line branch="false" hits="90" number="1139"/> + <line branch="false" hits="0" number="1143"/> + <line branch="false" hits="0" number="1147"/> + <line branch="false" hits="0" number="1151"/> + <line branch="false" hits="2" number="1155"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="1159"/> + <line branch="false" hits="10" number="1161"/> + </lines> + </class> + <class branch-rate="0.6666666666666666" complexity="0" filename="src/player/PlaybackSessionFactory.ts" line-rate="0.5" name="src.player.PlaybackSessionFactory.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="10" number="10"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="PlaybackSessionFactory" signature=""> + <lines> + <line branch="false" hits="68" number="13"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="17" number="19"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="70"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="10" number="2"/> + <line branch="false" hits="10" number="3"/> + <line branch="false" hits="10" number="4"/> + <line branch="false" hits="10" number="10"/> + <line branch="false" hits="68" number="16"/> + <line branch="false" hits="10" number="19"/> + <line branch="true" condition-coverage="100% (2/2)" hits="17" number="23"/> + <line branch="false" hits="0" number="25"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="33"/> + <line branch="false" hits="0" number="34"/> + <line branch="false" hits="0" number="35"/> + <line branch="false" hits="0" number="36"/> + <line branch="false" hits="0" number="37"/> + <line branch="false" hits="0" number="38"/> + <line branch="false" hits="0" number="39"/> + <line branch="false" hits="0" number="42"/> + <line branch="false" hits="0" number="53"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="62"/> + <line branch="false" hits="0" number="63"/> + <line branch="false" hits="17" number="68"/> + <line branch="false" hits="17" number="70"/> + <line branch="false" hits="0" number="71"/> + <line branch="false" hits="17" number="72"/> + <line branch="false" hits="10" number="78"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/player/index.ts" line-rate="1.0" name="src.player.index.ts"> + <methods/> + <lines> + <line branch="false" hits="10" number="1"/> + <line branch="false" hits="10" number="2"/> + <line branch="false" hits="10" number="3"/> + <line branch="false" hits="10" number="4"/> + <line branch="false" hits="10" number="5"/> + <line branch="false" hits="10" number="6"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/player/player.ts" line-rate="0.7647058823529411" name="src.player.player.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="12" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="Player" signature=""> + <lines> + <line branch="false" hits="89" number="12"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="89" number="16"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="18"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="186" number="25"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="89" number="29"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="37"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="0" number="41"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="0" number="45"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="49"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="26" number="53"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="356" number="57"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="16" number="61"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="0" number="65"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="0" number="69"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="0" number="73"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="12" number="1"/> + <line branch="false" hits="12" number="4"/> + <line branch="false" hits="12" number="5"/> + <line branch="false" hits="12" number="9"/> + <line branch="false" hits="89" number="13"/> + <line branch="false" hits="12" number="16"/> + <line branch="false" hits="89" number="18"/> + <line branch="false" hits="0" number="19"/> + <line branch="false" hits="89" number="22"/> + <line branch="false" hits="12" number="25"/> + <line branch="false" hits="186" number="26"/> + <line branch="false" hits="12" number="29"/> + <line branch="false" hits="89" number="34"/> + <line branch="false" hits="12" number="37"/> + <line branch="false" hits="0" number="38"/> + <line branch="false" hits="12" number="41"/> + <line branch="false" hits="0" number="42"/> + <line branch="false" hits="12" number="45"/> + <line branch="false" hits="0" number="46"/> + <line branch="false" hits="12" number="49"/> + <line branch="false" hits="0" number="50"/> + <line branch="false" hits="12" number="53"/> + <line branch="false" hits="26" number="54"/> + <line branch="false" hits="12" number="57"/> + <line branch="false" hits="356" number="58"/> + <line branch="false" hits="12" number="61"/> + <line branch="false" hits="16" number="62"/> + <line branch="false" hits="12" number="65"/> + <line branch="false" hits="0" number="66"/> + <line branch="false" hits="12" number="69"/> + <line branch="false" hits="0" number="70"/> + <line branch="false" hits="12" number="73"/> + <line branch="false" hits="0" number="74"/> + <line branch="false" hits="12" number="76"/> + </lines> + </class> + <class branch-rate="0.6666666666666666" complexity="0" filename="src/player/shaka.ts" line-rate="0.75" name="src.player.shaka.ts"> + <methods/> + <lines> + <line branch="false" hits="13" number="2"/> + <line branch="false" hits="13" number="5"/> + <line branch="true" condition-coverage="66% (2/3)" hits="0" number="6"/> + <line branch="false" hits="0" number="7"/> + <line branch="false" hits="13" number="10"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.5135135135135135" complexity="0" line-rate="0.6158038147138964" name="src.plugins"> + <classes> + <class branch-rate="0.7878787878787878" complexity="0" filename="src/plugins/SPManifestParser.ts" line-rate="0.9026548672566371" name="src.plugins.SPManifestParser.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="ManifestParser" signature=""> + <lines> + <line branch="false" hits="5" number="26"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="5" number="40"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="5" number="45"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="5" number="60"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="0" number="67"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="70"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="75"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="5" number="87"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="5" number="94"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="5" number="113"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="5" number="152"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="13" number="159"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="5" number="173"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="22" number="175"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="5" number="186"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="18" number="191"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="0" number="211"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="0" number="218"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="13" number="226"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="13" number="227"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="13" number="242"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="5" number="281"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="8" number="289"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="8" number="298"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="34" number="313"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="0" number="332"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="26" number="366"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="2" number="367"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="4" number="368"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="34" number="388"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="2" number="399"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="2" number="405"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="3972" number="461"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_34)" signature=""> + <lines> + <line branch="false" hits="2" number="467"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="4" number="468"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="9" number="18"/> + <line branch="false" hits="5" number="27"/> + <line branch="false" hits="5" number="28"/> + <line branch="false" hits="5" number="29"/> + <line branch="false" hits="5" number="30"/> + <line branch="false" hits="5" number="31"/> + <line branch="false" hits="5" number="32"/> + <line branch="false" hits="5" number="33"/> + <line branch="false" hits="5" number="34"/> + <line branch="false" hits="5" number="35"/> + <line branch="false" hits="5" number="36"/> + <line branch="false" hits="9" number="40"/> + <line branch="false" hits="5" number="41"/> + <line branch="false" hits="9" number="45"/> + <line branch="false" hits="0" number="47"/> + <line branch="false" hits="5" number="50"/> + <line branch="false" hits="5" number="59"/> + <line branch="false" hits="5" number="60"/> + <line branch="false" hits="5" number="61"/> + <line branch="false" hits="5" number="62"/> + <line branch="false" hits="9" number="67"/> + <line branch="false" hits="9" number="70"/> + <line branch="false" hits="9" number="75"/> + <line branch="false" hits="9" number="87"/> + <line branch="false" hits="5" number="88"/> + <line branch="false" hits="5" number="91"/> + <line branch="false" hits="5" number="92"/> + <line branch="false" hits="5" number="94"/> + <line branch="false" hits="5" number="95"/> + <line branch="false" hits="5" number="98"/> + <line branch="false" hits="9" number="113"/> + <line branch="false" hits="5" number="114"/> + <line branch="false" hits="0" number="117"/> + <line branch="false" hits="0" number="120"/> + <line branch="false" hits="0" number="122"/> + <line branch="false" hits="5" number="130"/> + <line branch="false" hits="0" number="134"/> + <line branch="false" hits="5" number="141"/> + <line branch="false" hits="9" number="152"/> + <line branch="false" hits="5" number="153"/> + <line branch="false" hits="5" number="154"/> + <line branch="false" hits="5" number="156"/> + <line branch="false" hits="13" number="160"/> + <line branch="false" hits="9" number="173"/> + <line branch="false" hits="5" number="174"/> + <line branch="false" hits="22" number="175"/> + <line branch="false" hits="9" number="186"/> + <line branch="false" hits="5" number="188"/> + <line branch="false" hits="5" number="189"/> + <line branch="false" hits="5" number="191"/> + <line branch="false" hits="18" number="192"/> + <line branch="true" condition-coverage="66% (2/3)" hits="0" number="194"/> + <line branch="false" hits="13" number="195"/> + <line branch="false" hits="13" number="196"/> + <line branch="false" hits="5" number="198"/> + <line branch="false" hits="5" number="199"/> + <line branch="false" hits="0" number="201"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="206"/> + <line branch="false" hits="0" number="207"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="210"/> + <line branch="false" hits="0" number="211"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="217"/> + <line branch="false" hits="0" number="218"/> + <line branch="false" hits="5" number="225"/> + <line branch="false" hits="5" number="226"/> + <line branch="false" hits="13" number="227"/> + <line branch="false" hits="13" number="228"/> + <line branch="false" hits="5" number="231"/> + <line branch="false" hits="9" number="242"/> + <line branch="true" condition-coverage="100% (2/2)" hits="13" number="247"/> + <line branch="true" condition-coverage="50% (1/2)" hits="13" number="249"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="250"/> + <line branch="false" hits="13" number="252"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="257"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="260"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="265"/> + <line branch="false" hits="9" number="281"/> + <line branch="false" hits="5" number="284"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="286"/> + <line branch="false" hits="8" number="289"/> + <line branch="false" hits="5" number="298"/> + <line branch="false" hits="8" number="299"/> + <line branch="false" hits="9" number="313"/> + <line branch="false" hits="34" number="319"/> + <line branch="false" hits="34" number="322"/> + <line branch="false" hits="13" number="324"/> + <line branch="false" hits="13" number="327"/> + <line branch="false" hits="34" number="330"/> + <line branch="false" hits="0" number="333"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="338"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="343"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="344"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="345"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="348"/> + <line branch="false" hits="26" number="366"/> + <line branch="false" hits="26" number="367"/> + <line branch="false" hits="2" number="368"/> + <line branch="false" hits="4" number="369"/> + <line branch="false" hits="2" number="373"/> + <line branch="false" hits="26" number="376"/> + <line branch="false" hits="34" number="388"/> + <line branch="false" hits="34" number="393"/> + <line branch="false" hits="34" number="395"/> + <line branch="false" hits="34" number="396"/> + <line branch="false" hits="8" number="399"/> + <line branch="false" hits="2" number="400"/> + <line branch="false" hits="0" number="402"/> + <line branch="false" hits="2" number="405"/> + <line branch="false" hits="2" number="406"/> + <line branch="false" hits="2" number="412"/> + <line branch="false" hits="8" number="417"/> + <line branch="false" hits="26" number="428"/> + <line branch="false" hits="26" number="430"/> + <line branch="false" hits="26" number="431"/> + <line branch="false" hits="3972" number="433"/> + <line branch="false" hits="3972" number="439"/> + <line branch="false" hits="3972" number="440"/> + <line branch="false" hits="3972" number="441"/> + <line branch="false" hits="34" number="446"/> + <line branch="false" hits="34" number="448"/> + <line branch="false" hits="3972" number="461"/> + <line branch="false" hits="3972" number="467"/> + <line branch="false" hits="2" number="468"/> + <line branch="false" hits="4" number="469"/> + <line branch="false" hits="2" number="474"/> + <line branch="false" hits="3972" number="477"/> + <line branch="false" hits="9" number="487"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/plugins/SpotifyVideoMediaExtension.ts" line-rate="1.0" name="src.plugins.SpotifyVideoMediaExtension.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="8" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="SpotifyVideoMediaExtension" signature=""> + <lines> + <line branch="false" hits="59" number="12"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="2" number="29"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="4" number="34"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="2" number="38"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="8" number="2"/> + <line branch="false" hits="8" number="3"/> + <line branch="false" hits="8" number="9"/> + <line branch="false" hits="59" number="13"/> + <line branch="false" hits="59" number="14"/> + <line branch="false" hits="59" number="18"/> + <line branch="false" hits="59" number="22"/> + <line branch="false" hits="59" number="23"/> + <line branch="false" hits="8" number="29"/> + <line branch="false" hits="2" number="30"/> + <line branch="false" hits="2" number="31"/> + <line branch="false" hits="8" number="34"/> + <line branch="false" hits="4" number="35"/> + <line branch="false" hits="8" number="38"/> + <line branch="false" hits="2" number="42"/> + <line branch="false" hits="8" number="46"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/plugins/SpotifyVideoUrl.ts" line-rate="1.0" name="src.plugins.SpotifyVideoUrl.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="8" number="7"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="31" number="8"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="8" number="1"/> + <line branch="false" hits="8" number="7"/> + <line branch="false" hits="8" number="8"/> + <line branch="false" hits="31" number="9"/> + <line branch="false" hits="8" number="11"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/plugins/TextParser.js" line-rate="0.3076923076923077" name="src.plugins.TextParser.js"> + <methods> + <method branch-rate="0.0" line-rate="0.0" name="TextParser" signature=""> + <lines> + <line branch="false" hits="0" number="25"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="0" number="37"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="0" number="47"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="0" number="57"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="64"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="0" number="78"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="96"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="116"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="0" number="30"/> + <line branch="false" hits="0" number="33"/> + <line branch="false" hits="8" number="37"/> + <line branch="false" hits="0" number="38"/> + <line branch="false" hits="8" number="47"/> + <line branch="false" hits="0" number="48"/> + <line branch="false" hits="8" number="57"/> + <line branch="false" hits="0" number="58"/> + <line branch="false" hits="8" number="64"/> + <line branch="false" hits="0" number="65"/> + <line branch="false" hits="8" number="78"/> + <line branch="false" hits="0" number="79"/> + <line branch="true" condition-coverage="0% (0/3)" hits="0" number="80"/> + <line branch="false" hits="0" number="81"/> + <line branch="false" hits="0" number="84"/> + <line branch="false" hits="0" number="85"/> + <line branch="false" hits="8" number="96"/> + <line branch="false" hits="0" number="98"/> + <line branch="false" hits="0" number="101"/> + <line branch="false" hits="0" number="103"/> + <line branch="false" hits="0" number="105"/> + <line branch="false" hits="8" number="116"/> + <line branch="false" hits="0" number="117"/> + <line branch="false" hits="0" number="118"/> + <line branch="false" hits="0" number="120"/> + <line branch="false" hits="0" number="122"/> + <line branch="false" hits="8" number="130"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/plugins/VttTextParser.js" line-rate="0.13043478260869565" name="src.plugins.VttTextParser.js"> + <methods> + <method branch-rate="0.0" line-rate="0.0" name="VttTextParser" signature=""> + <lines> + <line branch="false" hits="0" number="26"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="0" number="29"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="0" number="37"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="121"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="0" number="144"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="0" number="223"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="0" number="260"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="0" number="261"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="0" number="285"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="299"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="0" number="315"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="0" number="330"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="0" number="362"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="8" number="19"/> + <line branch="false" hits="8" number="20"/> + <line branch="false" hits="8" number="29"/> + <line branch="false" hits="0" number="30"/> + <line branch="false" hits="8" number="37"/> + <line branch="false" hits="0" number="38"/> + <line branch="false" hits="0" number="40"/> + <line branch="false" hits="0" number="41"/> + <line branch="false" hits="0" number="42"/> + <line branch="false" hits="0" number="45"/> + <line branch="false" hits="0" number="52"/> + <line branch="false" hits="0" number="60"/> + <line branch="false" hits="0" number="72"/> + <line branch="false" hits="0" number="76"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="77"/> + <line branch="false" hits="0" number="78"/> + <line branch="false" hits="0" number="79"/> + <line branch="false" hits="0" number="80"/> + <line branch="false" hits="0" number="81"/> + <line branch="false" hits="0" number="84"/> + <line branch="false" hits="0" number="91"/> + <line branch="false" hits="0" number="92"/> + <line branch="false" hits="0" number="93"/> + <line branch="false" hits="0" number="95"/> + <line branch="false" hits="0" number="96"/> + <line branch="false" hits="0" number="101"/> + <line branch="false" hits="0" number="102"/> + <line branch="false" hits="0" number="103"/> + <line branch="false" hits="0" number="104"/> + <line branch="false" hits="0" number="106"/> + <line branch="false" hits="0" number="110"/> + <line branch="false" hits="8" number="121"/> + <line branch="false" hits="0" number="122"/> + <line branch="false" hits="0" number="126"/> + <line branch="false" hits="0" number="129"/> + <line branch="false" hits="0" number="130"/> + <line branch="false" hits="0" number="132"/> + <line branch="false" hits="8" number="144"/> + <line branch="false" hits="0" number="145"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="148"/> + <line branch="false" hits="0" number="149"/> + <line branch="false" hits="0" number="154"/> + <line branch="false" hits="0" number="159"/> + <line branch="false" hits="0" number="162"/> + <line branch="false" hits="0" number="163"/> + <line branch="false" hits="0" number="165"/> + <line branch="false" hits="0" number="166"/> + <line branch="false" hits="0" number="170"/> + <line branch="false" hits="0" number="171"/> + <line branch="false" hits="0" number="172"/> + <line branch="false" hits="0" number="173"/> + <line branch="true" condition-coverage="0% (0/3)" hits="0" number="175"/> + <line branch="false" hits="0" number="176"/> + <line branch="false" hits="0" number="183"/> + <line branch="false" hits="0" number="184"/> + <line branch="false" hits="0" number="187"/> + <line branch="false" hits="0" number="192"/> + <line branch="false" hits="0" number="195"/> + <line branch="false" hits="0" number="196"/> + <line branch="false" hits="0" number="199"/> + <line branch="false" hits="0" number="205"/> + <line branch="false" hits="0" number="206"/> + <line branch="false" hits="0" number="210"/> + <line branch="false" hits="0" number="212"/> + <line branch="false" hits="8" number="223"/> + <line branch="false" hits="0" number="224"/> + <line branch="false" hits="0" number="225"/> + <line branch="false" hits="0" number="227"/> + <line branch="false" hits="0" number="229"/> + <line branch="false" hits="0" number="231"/> + <line branch="false" hits="0" number="237"/> + <line branch="false" hits="0" number="239"/> + <line branch="false" hits="0" number="242"/> + <line branch="false" hits="0" number="244"/> + <line branch="false" hits="0" number="247"/> + <line branch="false" hits="0" number="250"/> + <line branch="false" hits="8" number="260"/> + <line branch="false" hits="0" number="261"/> + <line branch="false" hits="0" number="262"/> + <line branch="false" hits="0" number="265"/> + <line branch="false" hits="0" number="270"/> + <line branch="false" hits="0" number="274"/> + <line branch="false" hits="0" number="277"/> + <line branch="false" hits="8" number="285"/> + <line branch="false" hits="0" number="286"/> + <line branch="false" hits="0" number="288"/> + <line branch="false" hits="0" number="290"/> + <line branch="false" hits="8" number="299"/> + <line branch="false" hits="0" number="300"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="301"/> + <line branch="false" hits="0" number="302"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="303"/> + <line branch="false" hits="0" number="304"/> + <line branch="false" hits="0" number="306"/> + <line branch="false" hits="8" number="315"/> + <line branch="false" hits="0" number="316"/> + <line branch="false" hits="0" number="318"/> + <line branch="false" hits="0" number="320"/> + <line branch="false" hits="8" number="330"/> + <line branch="false" hits="0" number="334"/> + <line branch="false" hits="0" number="335"/> + <line branch="false" hits="0" number="337"/> + <line branch="false" hits="0" number="338"/> + <line branch="false" hits="0" number="340"/> + <line branch="false" hits="0" number="343"/> + <line branch="false" hits="0" number="344"/> + <line branch="false" hits="0" number="346"/> + <line branch="false" hits="0" number="349"/> + <line branch="false" hits="0" number="352"/> + <line branch="false" hits="8" number="362"/> + <line branch="false" hits="0" number="364"/> + <line branch="false" hits="0" number="366"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="370"/> + <line branch="false" hits="0" number="371"/> + <line branch="false" hits="0" number="372"/> + <line branch="false" hits="0" number="373"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="374"/> + <line branch="false" hits="0" number="375"/> + <line branch="false" hits="0" number="378"/> + <line branch="false" hits="8" number="385"/> + <line branch="false" hits="8" number="387"/> + </lines> + </class> + <class branch-rate="0.47619047619047616" complexity="0" filename="src/plugins/WidevineDownloader.ts" line-rate="0.8356164383561644" name="src.plugins.WidevineDownloader.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="7" number="14"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="WidevineDownloader" signature=""> + <lines> + <line branch="false" hits="7" number="21"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="6" number="190"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="4" number="34"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="4" number="40"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="1" number="44"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="1" number="66"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="0" number="69"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="2" number="78"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="1" number="90"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="4" number="107"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="1" number="137"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="0" number="147"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="7" number="165"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="1" number="174"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="7" number="2"/> + <line branch="false" hits="7" number="9"/> + <line branch="false" hits="7" number="10"/> + <line branch="false" hits="7" number="11"/> + <line branch="false" hits="7" number="12"/> + <line branch="false" hits="7" number="14"/> + <line branch="false" hits="7" number="21"/> + <line branch="false" hits="7" number="22"/> + <line branch="false" hits="7" number="26"/> + <line branch="false" hits="7" number="27"/> + <line branch="false" hits="7" number="28"/> + <line branch="false" hits="7" number="29"/> + <line branch="false" hits="7" number="34"/> + <line branch="false" hits="0" number="36"/> + <line branch="false" hits="4" number="38"/> + <line branch="false" hits="4" number="41"/> + <line branch="false" hits="4" number="44"/> + <line branch="false" hits="0" number="46"/> + <line branch="false" hits="1" number="49"/> + <line branch="false" hits="0" number="51"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="59"/> + <line branch="false" hits="0" number="63"/> + <line branch="false" hits="0" number="64"/> + <line branch="false" hits="3" number="66"/> + <line branch="false" hits="0" number="70"/> + <line branch="false" hits="7" number="78"/> + <line branch="true" condition-coverage="40% (2/5)" hits="0" number="80"/> + <line branch="false" hits="1" number="84"/> + <line branch="false" hits="1" number="86"/> + <line branch="false" hits="7" number="90"/> + <line branch="false" hits="1" number="91"/> + <line branch="false" hits="1" number="92"/> + <line branch="false" hits="1" number="93"/> + <line branch="false" hits="1" number="94"/> + <line branch="false" hits="7" number="107"/> + <line branch="false" hits="4" number="108"/> + <line branch="true" condition-coverage="40% (4/10)" hits="0" number="111"/> + <line branch="false" hits="2" number="112"/> + <line branch="false" hits="2" number="113"/> + <line branch="false" hits="1" number="120"/> + <line branch="false" hits="1" number="121"/> + <line branch="false" hits="1" number="128"/> + <line branch="false" hits="1" number="129"/> + <line branch="false" hits="0" number="133"/> + <line branch="false" hits="1" number="136"/> + <line branch="false" hits="1" number="137"/> + <line branch="false" hits="1" number="139"/> + <line branch="false" hits="1" number="140"/> + <line branch="false" hits="1" number="147"/> + <line branch="false" hits="0" number="150"/> + <line branch="false" hits="0" number="152"/> + <line branch="false" hits="0" number="153"/> + <line branch="false" hits="7" number="165"/> + <line branch="false" hits="7" number="166"/> + <line branch="false" hits="0" number="171"/> + <line branch="false" hits="0" number="172"/> + <line branch="false" hits="7" number="174"/> + <line branch="false" hits="7" number="177"/> + <line branch="true" condition-coverage="50% (1/2)" hits="6" number="179"/> + <line branch="false" hits="3" number="181"/> + <line branch="false" hits="3" number="182"/> + <line branch="false" hits="3" number="183"/> + <line branch="true" condition-coverage="50% (1/2)" hits="3" number="184"/> + <line branch="false" hits="3" number="185"/> + <line branch="false" hits="3" number="187"/> + <line branch="false" hits="3" number="189"/> + <line branch="false" hits="6" number="190"/> + <line branch="false" hits="6" number="191"/> + <line branch="false" hits="3" number="193"/> + <line branch="false" hits="7" number="198"/> + <line branch="false" hits="3" number="200"/> + <line branch="false" hits="1" number="201"/> + <line branch="false" hits="1" number="202"/> + <line branch="false" hits="1" number="203"/> + <line branch="false" hits="1" number="205"/> + <line branch="false" hits="7" number="207"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/plugins/index.ts" line-rate="1.0" name="src.plugins.index.ts"> + <methods/> + <lines> + <line branch="false" hits="8" number="1"/> + <line branch="false" hits="8" number="2"/> + <line branch="false" hits="8" number="3"/> + <line branch="false" hits="8" number="4"/> + <line branch="false" hits="8" number="6"/> + <line branch="false" hits="8" number="7"/> + <line branch="false" hits="8" number="8"/> + </lines> + </class> + <class branch-rate="1.0" complexity="0" filename="src/plugins/types.ts" line-rate="1.0" name="src.plugins.types.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="7" number="19"/> + </lines> + </method> + </methods> + <lines> + <line branch="true" condition-coverage="100% (2/2)" hits="7" number="19"/> + <line branch="false" hits="7" number="20"/> + <line branch="false" hits="7" number="21"/> + <line branch="false" hits="7" number="22"/> + <line branch="false" hits="7" number="23"/> + <line branch="false" hits="7" number="24"/> + <line branch="false" hits="7" number="25"/> + <line branch="false" hits="7" number="26"/> + <line branch="false" hits="7" number="27"/> + <line branch="false" hits="7" number="28"/> + <line branch="false" hits="7" number="29"/> + <line branch="false" hits="7" number="30"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.9701492537313433" complexity="0" line-rate="0.9808612440191388" name="src.tracking"> + <classes> + <class branch-rate="0.9743589743589743" complexity="0" filename="src/tracking/DefaultEventsCalculator.ts" line-rate="0.9754098360655737" name="src.tracking.DefaultEventsCalculator.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="getEventPosition" signature=""> + <lines> + <line branch="false" hits="54" number="34"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="registerBufferingEnd" signature=""> + <lines> + <line branch="false" hits="7" number="46"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="52" number="95"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="1" number="108"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="1" number="116"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="76" number="124"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="76" number="145"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processIdentityFields" signature=""> + <lines> + <line branch="false" hits="25" number="164"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="24" number="168"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMsStartPosition" signature=""> + <lines> + <line branch="false" hits="25" number="181"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="3" number="185"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMsDuration" signature=""> + <lines> + <line branch="false" hits="25" number="194"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="1" number="198"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processStartTime" signature=""> + <lines> + <line branch="false" hits="26" number="207"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="4" number="215"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processDroppedFrames" signature=""> + <lines> + <line branch="false" hits="25" number="229"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="1" number="233"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processEndFields" signature=""> + <lines> + <line branch="false" hits="26" number="242"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="25" number="246"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processVideoFormatChangedFields" signature=""> + <lines> + <line branch="false" hits="28" number="255"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="6" number="259"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMsEncryptionLoadTime" signature=""> + <lines> + <line branch="false" hits="26" number="276"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="2" number="284"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processEncryptionType" signature=""> + <lines> + <line branch="false" hits="25" number="298"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="1" number="302"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processLasUsedSubtitle" signature=""> + <lines> + <line branch="false" hits="26" number="311"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="5" number="315"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processManifestLoadTime" signature=""> + <lines> + <line branch="false" hits="26" number="326"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="2" number="334"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processSeekFields" signature=""> + <lines> + <line branch="false" hits="27" number="348"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="11" number="352"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processBandwidthFields" signature=""> + <lines> + <line branch="false" hits="26" number="386"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="5" number="398"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processBufferingFields" signature=""> + <lines> + <line branch="false" hits="29" number="417"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMsPlayed" signature=""> + <lines> + <line branch="false" hits="27" number="475"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_38)" signature=""> + <lines> + <line branch="false" hits="83" number="479"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="43" number="483"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMsSubtitlesPlayed" signature=""> + <lines> + <line branch="false" hits="25" number="496"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_41)" signature=""> + <lines> + <line branch="false" hits="76" number="500"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_42)" signature=""> + <lines> + <line branch="false" hits="43" number="505"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMsFullscreenPlayed" signature=""> + <lines> + <line branch="false" hits="25" number="522"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_44)" signature=""> + <lines> + <line branch="false" hits="76" number="526"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_45)" signature=""> + <lines> + <line branch="false" hits="43" number="531"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="generatePlaybackSessionMessage" signature=""> + <lines> + <line branch="false" hits="23" number="548"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="16" number="1"/> + <line branch="false" hits="16" number="11"/> + <line branch="false" hits="16" number="12"/> + <line branch="false" hits="16" number="13"/> + <line branch="false" hits="54" number="34"/> + <line branch="false" hits="35" number="37"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="39"/> + <line branch="false" hits="19" number="40"/> + <line branch="false" hits="0" number="43"/> + <line branch="false" hits="7" number="51"/> + <line branch="false" hits="7" number="52"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="55"/> + <line branch="true" condition-coverage="75% (3/4)" hits="0" number="57"/> + <line branch="false" hits="3" number="58"/> + <line branch="false" hits="3" number="65"/> + <line branch="false" hits="3" number="69"/> + <line branch="false" hits="3" number="71"/> + <line branch="false" hits="2" number="78"/> + <line branch="false" hits="3" number="82"/> + <line branch="false" hits="1" number="84"/> + <line branch="false" hits="1" number="87"/> + <line branch="false" hits="0" number="89"/> + <line branch="false" hits="7" number="92"/> + <line branch="false" hits="16" number="95"/> + <line branch="false" hits="52" number="99"/> + <line branch="false" hits="52" number="100"/> + <line branch="false" hits="16" number="108"/> + <line branch="false" hits="1" number="109"/> + <line branch="false" hits="1" number="111"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="113"/> + <line branch="false" hits="16" number="116"/> + <line branch="false" hits="1" number="117"/> + <line branch="false" hits="1" number="119"/> + <line branch="false" hits="16" number="124"/> + <line branch="false" hits="76" number="128"/> + <line branch="true" condition-coverage="100% (2/2)" hits="76" number="129"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="130"/> + <line branch="false" hits="1" number="132"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="134"/> + <line branch="false" hits="1" number="136"/> + <line branch="false" hits="1" number="140"/> + <line branch="false" hits="76" number="142"/> + <line branch="false" hits="16" number="145"/> + <line branch="false" hits="76" number="149"/> + <line branch="true" condition-coverage="100% (2/2)" hits="76" number="150"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="151"/> + <line branch="false" hits="1" number="152"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="154"/> + <line branch="false" hits="1" number="155"/> + <line branch="false" hits="1" number="159"/> + <line branch="false" hits="76" number="161"/> + <line branch="false" hits="16" number="164"/> + <line branch="false" hits="25" number="167"/> + <line branch="false" hits="24" number="168"/> + <line branch="false" hits="16" number="181"/> + <line branch="false" hits="25" number="184"/> + <line branch="false" hits="3" number="185"/> + <line branch="false" hits="16" number="194"/> + <line branch="false" hits="25" number="197"/> + <line branch="false" hits="1" number="198"/> + <line branch="false" hits="16" number="207"/> + <line branch="false" hits="26" number="210"/> + <line branch="false" hits="26" number="214"/> + <line branch="false" hits="4" number="216"/> + <line branch="true" condition-coverage="100% (1/1)" hits="0" number="222"/> + <line branch="false" hits="16" number="229"/> + <line branch="false" hits="25" number="232"/> + <line branch="false" hits="1" number="233"/> + <line branch="false" hits="16" number="242"/> + <line branch="false" hits="26" number="245"/> + <line branch="false" hits="25" number="246"/> + <line branch="false" hits="16" number="255"/> + <line branch="false" hits="28" number="258"/> + <line branch="false" hits="6" number="259"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="261"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="262"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="265"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="266"/> + <line branch="false" hits="16" number="276"/> + <line branch="false" hits="26" number="279"/> + <line branch="false" hits="26" number="283"/> + <line branch="false" hits="2" number="285"/> + <line branch="true" condition-coverage="100% (1/1)" hits="0" number="291"/> + <line branch="false" hits="16" number="298"/> + <line branch="false" hits="25" number="301"/> + <line branch="false" hits="1" number="302"/> + <line branch="false" hits="16" number="311"/> + <line branch="false" hits="26" number="314"/> + <line branch="false" hits="5" number="315"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="317"/> + <line branch="false" hits="16" number="326"/> + <line branch="false" hits="26" number="329"/> + <line branch="false" hits="26" number="333"/> + <line branch="false" hits="2" number="335"/> + <line branch="true" condition-coverage="100% (1/1)" hits="0" number="341"/> + <line branch="false" hits="16" number="348"/> + <line branch="false" hits="27" number="351"/> + <line branch="false" hits="11" number="352"/> + <line branch="false" hits="5" number="354"/> + <line branch="false" hits="6" number="365"/> + <line branch="false" hits="0" number="375"/> + <line branch="false" hits="16" number="386"/> + <line branch="false" hits="26" number="389"/> + <line branch="false" hits="26" number="390"/> + <line branch="false" hits="26" number="397"/> + <line branch="false" hits="5" number="398"/> + <line branch="false" hits="5" number="399"/> + <line branch="false" hits="5" number="400"/> + <line branch="false" hits="16" number="417"/> + <line branch="false" hits="86" number="433"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="435"/> + <line branch="false" hits="5" number="439"/> + <line branch="false" hits="3" number="444"/> + <line branch="false" hits="9" number="450"/> + <line branch="false" hits="9" number="451"/> + <line branch="false" hits="9" number="454"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="457"/> + <line branch="false" hits="4" number="461"/> + <line branch="false" hits="4" number="466"/> + <line branch="false" hits="4" number="467"/> + <line branch="false" hits="4" number="468"/> + <line branch="false" hits="29" number="472"/> + <line branch="false" hits="16" number="475"/> + <line branch="false" hits="27" number="478"/> + <line branch="false" hits="83" number="480"/> + <line branch="false" hits="43" number="483"/> + <line branch="false" hits="16" number="496"/> + <line branch="false" hits="25" number="499"/> + <line branch="false" hits="76" number="501"/> + <line branch="false" hits="43" number="505"/> + <line branch="false" hits="76" number="507"/> + <line branch="false" hits="76" number="508"/> + <line branch="false" hits="16" number="522"/> + <line branch="false" hits="25" number="525"/> + <line branch="false" hits="76" number="527"/> + <line branch="false" hits="43" number="531"/> + <line branch="false" hits="76" number="533"/> + <line branch="false" hits="76" number="534"/> + <line branch="false" hits="16" number="548"/> + <line branch="false" hits="23" number="551"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/tracking/EventsTracker.ts" line-rate="0.9583333333333334" name="src.tracking.EventsTracker.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="16" number="16"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="EventsTracker" signature=""> + <lines> + <line branch="false" hits="15" number="19"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="1" number="23"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="1" number="40"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="1" number="53"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="1" number="63"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="1" number="71"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="0" number="86"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="12" number="101"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="117"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="5" number="130"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="3" number="145"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="9" number="160"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="3" number="170"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="5" number="180"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="1" number="195"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="1" number="210"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="1" number="225"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="1" number="240"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="1" number="248"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="1" number="256"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="1" number="271"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="1" number="286"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="1" number="301"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="16" number="14"/> + <line branch="false" hits="16" number="16"/> + <line branch="false" hits="15" number="20"/> + <line branch="false" hits="16" number="23"/> + <line branch="false" hits="1" number="29"/> + <line branch="false" hits="16" number="40"/> + <line branch="false" hits="1" number="44"/> + <line branch="false" hits="16" number="53"/> + <line branch="false" hits="1" number="54"/> + <line branch="false" hits="16" number="63"/> + <line branch="false" hits="1" number="64"/> + <line branch="false" hits="16" number="71"/> + <line branch="false" hits="1" number="76"/> + <line branch="false" hits="16" number="86"/> + <line branch="false" hits="0" number="91"/> + <line branch="false" hits="16" number="101"/> + <line branch="false" hits="12" number="107"/> + <line branch="false" hits="16" number="117"/> + <line branch="false" hits="0" number="121"/> + <line branch="false" hits="16" number="130"/> + <line branch="false" hits="5" number="135"/> + <line branch="false" hits="16" number="145"/> + <line branch="false" hits="3" number="150"/> + <line branch="false" hits="16" number="160"/> + <line branch="false" hits="9" number="161"/> + <line branch="false" hits="16" number="170"/> + <line branch="false" hits="3" number="171"/> + <line branch="false" hits="16" number="180"/> + <line branch="false" hits="5" number="185"/> + <line branch="false" hits="16" number="195"/> + <line branch="false" hits="1" number="200"/> + <line branch="false" hits="16" number="210"/> + <line branch="false" hits="1" number="215"/> + <line branch="false" hits="16" number="225"/> + <line branch="false" hits="1" number="230"/> + <line branch="false" hits="16" number="240"/> + <line branch="false" hits="1" number="241"/> + <line branch="false" hits="16" number="248"/> + <line branch="false" hits="1" number="249"/> + <line branch="false" hits="16" number="256"/> + <line branch="false" hits="1" number="261"/> + <line branch="false" hits="16" number="271"/> + <line branch="false" hits="1" number="276"/> + <line branch="false" hits="16" number="286"/> + <line branch="false" hits="1" number="291"/> + <line branch="false" hits="16" number="301"/> + <line branch="false" hits="1" number="302"/> + <line branch="false" hits="16" number="310"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/tracking/ProductStatesStreamingRulesProvider.ts" line-rate="1.0" name="src.tracking.ProductStatesStreamingRulesProvider.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="16" number="4"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="ProductStatesStreamingRulesProvider" signature=""> + <lines> + <line branch="false" hits="3" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="2" number="14"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="0" number="17"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="4" number="21"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="16" number="4"/> + <line branch="false" hits="3" number="9"/> + <line branch="false" hits="3" number="10"/> + <line branch="false" hits="3" number="11"/> + <line branch="false" hits="3" number="12"/> + <line branch="false" hits="2" number="15"/> + <line branch="false" hits="16" number="21"/> + <line branch="false" hits="4" number="22"/> + <line branch="false" hits="16" number="24"/> + </lines> + </class> + <class branch-rate="1.0" complexity="0" filename="src/tracking/VideoPlaybackEvents.ts" line-rate="1.0" name="src.tracking.VideoPlaybackEvents.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="18" number="1"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="18" number="7"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="18" number="17"/> + </lines> + </method> + </methods> + <lines> + <line branch="true" condition-coverage="100% (2/2)" hits="18" number="1"/> + <line branch="false" hits="18" number="2"/> + <line branch="false" hits="18" number="3"/> + <line branch="false" hits="18" number="4"/> + <line branch="true" condition-coverage="100% (2/2)" hits="18" number="7"/> + <line branch="false" hits="18" number="8"/> + <line branch="false" hits="18" number="9"/> + <line branch="false" hits="18" number="10"/> + <line branch="false" hits="18" number="13"/> + <line branch="true" condition-coverage="100% (2/2)" hits="18" number="17"/> + <line branch="false" hits="18" number="18"/> + <line branch="false" hits="18" number="19"/> + <line branch="false" hits="18" number="20"/> + <line branch="false" hits="18" number="21"/> + <line branch="false" hits="18" number="22"/> + <line branch="false" hits="18" number="23"/> + <line branch="false" hits="18" number="24"/> + <line branch="false" hits="18" number="25"/> + <line branch="false" hits="18" number="26"/> + <line branch="false" hits="18" number="27"/> + <line branch="false" hits="18" number="28"/> + <line branch="false" hits="18" number="29"/> + <line branch="false" hits="18" number="30"/> + <line branch="false" hits="18" number="31"/> + <line branch="false" hits="18" number="32"/> + <line branch="false" hits="18" number="33"/> + <line branch="false" hits="18" number="34"/> + <line branch="false" hits="18" number="35"/> + <line branch="false" hits="18" number="36"/> + <line branch="false" hits="18" number="37"/> + <line branch="false" hits="18" number="38"/> + <line branch="false" hits="18" number="39"/> + <line branch="false" hits="18" number="40"/> + <line branch="false" hits="18" number="41"/> + <line branch="false" hits="18" number="42"/> + <line branch="false" hits="18" number="45"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/tracking/index.ts" line-rate="1.0" name="src.tracking.index.ts"> + <methods/> + <lines> + <line branch="false" hits="15" number="1"/> + <line branch="false" hits="15" number="2"/> + <line branch="false" hits="15" number="3"/> + <line branch="false" hits="15" number="4"/> + <line branch="false" hits="15" number="5"/> + <line branch="false" hits="15" number="7"/> + <line branch="false" hits="15" number="8"/> + <line branch="false" hits="15" number="9"/> + <line branch="false" hits="15" number="11"/> + <line branch="false" hits="15" number="12"/> + <line branch="false" hits="15" number="13"/> + <line branch="false" hits="15" number="15"/> + <line branch="false" hits="15" number="16"/> + </lines> + </class> + <class branch-rate="1.0" complexity="0" filename="src/tracking/types.ts" line-rate="1.0" name="src.tracking.types.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="16" number="13"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_2)" signature=""> + <lines> + <line branch="false" hits="16" number="95"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="16" number="10"/> + <line branch="true" condition-coverage="100% (2/2)" hits="16" number="13"/> + <line branch="false" hits="16" number="14"/> + <line branch="false" hits="16" number="15"/> + <line branch="false" hits="16" number="16"/> + <line branch="false" hits="16" number="17"/> + <line branch="false" hits="16" number="18"/> + <line branch="false" hits="16" number="19"/> + <line branch="false" hits="16" number="20"/> + <line branch="false" hits="16" number="21"/> + <line branch="false" hits="16" number="22"/> + <line branch="false" hits="16" number="23"/> + <line branch="false" hits="16" number="24"/> + <line branch="false" hits="16" number="25"/> + <line branch="false" hits="16" number="26"/> + <line branch="false" hits="16" number="27"/> + <line branch="false" hits="16" number="28"/> + <line branch="false" hits="16" number="29"/> + <line branch="false" hits="16" number="30"/> + <line branch="false" hits="16" number="31"/> + <line branch="false" hits="16" number="32"/> + <line branch="false" hits="16" number="33"/> + <line branch="false" hits="16" number="34"/> + <line branch="false" hits="16" number="35"/> + <line branch="false" hits="16" number="36"/> + <line branch="false" hits="16" number="37"/> + <line branch="false" hits="16" number="38"/> + <line branch="false" hits="16" number="39"/> + <line branch="false" hits="16" number="40"/> + <line branch="false" hits="16" number="41"/> + <line branch="false" hits="16" number="42"/> + <line branch="false" hits="16" number="43"/> + <line branch="false" hits="16" number="44"/> + <line branch="false" hits="16" number="45"/> + <line branch="false" hits="16" number="46"/> + <line branch="true" condition-coverage="100% (2/2)" hits="16" number="95"/> + <line branch="false" hits="16" number="96"/> + <line branch="false" hits="16" number="97"/> + <line branch="false" hits="16" number="98"/> + <line branch="false" hits="16" number="99"/> + <line branch="false" hits="16" number="100"/> + <line branch="false" hits="16" number="101"/> + <line branch="false" hits="16" number="102"/> + <line branch="false" hits="16" number="103"/> + <line branch="false" hits="16" number="104"/> + <line branch="false" hits="16" number="105"/> + <line branch="false" hits="16" number="106"/> + <line branch="false" hits="16" number="107"/> + <line branch="false" hits="16" number="108"/> + <line branch="false" hits="16" number="109"/> + <line branch="false" hits="16" number="110"/> + <line branch="false" hits="16" number="111"/> + <line branch="false" hits="16" number="112"/> + <line branch="false" hits="16" number="113"/> + <line branch="false" hits="16" number="114"/> + <line branch="false" hits="16" number="115"/> + <line branch="false" hits="16" number="116"/> + <line branch="false" hits="16" number="117"/> + <line branch="false" hits="16" number="118"/> + <line branch="false" hits="16" number="119"/> + <line branch="false" hits="16" number="120"/> + <line branch="false" hits="16" number="121"/> + <line branch="false" hits="16" number="122"/> + <line branch="false" hits="16" number="123"/> + <line branch="false" hits="16" number="124"/> + <line branch="false" hits="16" number="125"/> + <line branch="false" hits="16" number="126"/> + <line branch="false" hits="16" number="127"/> + <line branch="false" hits="16" number="128"/> + <line branch="false" hits="16" number="129"/> + <line branch="false" hits="16" number="130"/> + <line branch="false" hits="16" number="131"/> + <line branch="false" hits="16" number="132"/> + <line branch="false" hits="16" number="133"/> + <line branch="false" hits="16" number="134"/> + <line branch="false" hits="16" number="135"/> + <line branch="false" hits="16" number="136"/> + <line branch="false" hits="16" number="137"/> + <line branch="false" hits="16" number="138"/> + <line branch="false" hits="16" number="139"/> + <line branch="false" hits="16" number="140"/> + <line branch="false" hits="16" number="141"/> + <line branch="false" hits="16" number="142"/> + <line branch="false" hits="16" number="143"/> + <line branch="false" hits="16" number="144"/> + <line branch="false" hits="16" number="145"/> + <line branch="false" hits="16" number="146"/> + <line branch="false" hits="16" number="147"/> + <line branch="false" hits="16" number="148"/> + </lines> + </class> + <class branch-rate="0.9444444444444444" complexity="0" filename="src/tracking/utils.ts" line-rate="0.9702970297029703" name="src.tracking.utils.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="createPlaybackMetadata" signature=""> + <lines> + <line branch="false" hits="47" number="44"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="retrieveEndvideoMetadata" signature=""> + <lines> + <line branch="false" hits="208" number="109"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="972" number="113"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="951" number="115"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="497" number="123"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="469" number="128"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="74" number="133"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="78" number="138"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="222" number="143"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="297" number="148"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="150" number="153"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="74" number="158"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="74" number="163"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="244" number="168"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="150" number="173"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="0" number="178"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="122" number="183"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="76" number="188"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="458" number="193"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="44" number="198"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="78" number="203"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="2" number="208"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="502" number="220"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="497" number="220"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="176" number="224"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="132" number="224"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="176" number="228"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="110" number="228"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="326" number="232"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="248" number="232"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="96" number="236"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="getLastTimestamp" signature=""> + <lines> + <line branch="false" hits="79" number="245"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="230" number="250"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="28" number="251"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="getFirstTimestamp" signature=""> + <lines> + <line branch="false" hits="29" number="254"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_38)" signature=""> + <lines> + <line branch="false" hits="79" number="259"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="19" number="261"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="computeRange" signature=""> + <lines> + <line branch="false" hits="61" number="269"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="17" number="2"/> + <line branch="false" hits="17" number="4"/> + <line branch="false" hits="17" number="7"/> + <line branch="false" hits="17" number="9"/> + <line branch="false" hits="17" number="11"/> + <line branch="false" hits="17" number="12"/> + <line branch="false" hits="17" number="13"/> + <line branch="false" hits="17" number="14"/> + <line branch="false" hits="17" number="15"/> + <line branch="false" hits="17" number="16"/> + <line branch="false" hits="17" number="17"/> + <line branch="false" hits="17" number="18"/> + <line branch="false" hits="17" number="19"/> + <line branch="false" hits="17" number="20"/> + <line branch="false" hits="17" number="21"/> + <line branch="false" hits="17" number="22"/> + <line branch="false" hits="17" number="23"/> + <line branch="false" hits="17" number="24"/> + <line branch="false" hits="17" number="26"/> + <line branch="false" hits="17" number="42"/> + <line branch="false" hits="17" number="44"/> + <line branch="false" hits="47" number="47"/> + <line branch="false" hits="47" number="48"/> + <line branch="false" hits="47" number="53"/> + <line branch="false" hits="47" number="58"/> + <line branch="false" hits="47" number="63"/> + <line branch="false" hits="47" number="64"/> + <line branch="false" hits="47" number="69"/> + <line branch="false" hits="47" number="74"/> + <line branch="false" hits="47" number="75"/> + <line branch="false" hits="47" number="76"/> + <line branch="false" hits="47" number="77"/> + <line branch="false" hits="47" number="78"/> + <line branch="false" hits="17" number="100"/> + <line branch="false" hits="17" number="102"/> + <line branch="false" hits="17" number="104"/> + <line branch="false" hits="17" number="109"/> + <line branch="false" hits="208" number="112"/> + <line branch="false" hits="972" number="113"/> + <line branch="false" hits="951" number="115"/> + <line branch="false" hits="17" number="123"/> + <line branch="false" hits="497" number="126"/> + <line branch="false" hits="17" number="128"/> + <line branch="false" hits="469" number="131"/> + <line branch="false" hits="17" number="133"/> + <line branch="false" hits="74" number="136"/> + <line branch="false" hits="17" number="138"/> + <line branch="false" hits="78" number="141"/> + <line branch="false" hits="17" number="143"/> + <line branch="false" hits="222" number="146"/> + <line branch="false" hits="17" number="148"/> + <line branch="false" hits="297" number="151"/> + <line branch="false" hits="17" number="153"/> + <line branch="false" hits="150" number="156"/> + <line branch="false" hits="17" number="158"/> + <line branch="false" hits="74" number="161"/> + <line branch="false" hits="17" number="163"/> + <line branch="false" hits="74" number="166"/> + <line branch="false" hits="17" number="168"/> + <line branch="false" hits="244" number="171"/> + <line branch="false" hits="17" number="173"/> + <line branch="false" hits="150" number="176"/> + <line branch="false" hits="17" number="178"/> + <line branch="false" hits="0" number="181"/> + <line branch="false" hits="17" number="183"/> + <line branch="false" hits="122" number="186"/> + <line branch="false" hits="17" number="188"/> + <line branch="false" hits="76" number="191"/> + <line branch="false" hits="17" number="193"/> + <line branch="false" hits="458" number="196"/> + <line branch="false" hits="17" number="198"/> + <line branch="false" hits="44" number="201"/> + <line branch="false" hits="17" number="203"/> + <line branch="false" hits="78" number="206"/> + <line branch="false" hits="17" number="208"/> + <line branch="true" condition-coverage="50% (1/2)" hits="2" number="209"/> + <line branch="false" hits="17" number="211"/> + <line branch="false" hits="502" number="220"/> + <line branch="true" condition-coverage="100% (2/2)" hits="497" number="222"/> + <line branch="false" hits="176" number="224"/> + <line branch="true" condition-coverage="100% (2/2)" hits="132" number="226"/> + <line branch="false" hits="176" number="228"/> + <line branch="true" condition-coverage="100% (2/2)" hits="110" number="230"/> + <line branch="false" hits="326" number="232"/> + <line branch="true" condition-coverage="100% (4/4)" hits="248" number="234"/> + <line branch="false" hits="17" number="236"/> + <line branch="false" hits="96" number="237"/> + <line branch="false" hits="96" number="239"/> + <line branch="false" hits="17" number="245"/> + <line branch="false" hits="79" number="249"/> + <line branch="false" hits="230" number="250"/> + <line branch="false" hits="28" number="251"/> + <line branch="false" hits="17" number="254"/> + <line branch="false" hits="29" number="258"/> + <line branch="false" hits="79" number="259"/> + <line branch="false" hits="19" number="262"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="263"/> + <line branch="false" hits="17" number="269"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="270"/> + <line branch="false" hits="0" number="271"/> + <line branch="false" hits="61" number="273"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="274"/> + <line branch="false" hits="0" number="275"/> + <line branch="false" hits="61" number="277"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.8783783783783784" complexity="0" line-rate="0.9074074074074074" name="src.tracking.endvideo"> + <classes> + <class branch-rate="0.8333333333333334" complexity="0" filename="src/tracking/endvideo/EndVideoEventsCalculator.ts" line-rate="0.9304347826086956" name="src.tracking.endvideo.EndVideoEventsCalculator.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="convertReasonEnd" signature=""> + <lines> + <line branch="false" hits="24" number="39"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="sortRange" signature=""> + <lines> + <line branch="false" hits="11" number="52"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="calculateTimeWeightedBitrate" signature=""> + <lines> + <line branch="false" hits="6" number="71"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="7" number="79"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="calculateUnionPlayed" signature=""> + <lines> + <line branch="false" hits="11" number="88"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="19" number="92"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="14" number="120"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="21" number="123"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="5" number="145"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="21" number="181"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="12" number="190"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="10" number="206"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="11" number="223"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="11" number="240"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processEndVideoMetadata" signature=""> + <lines> + <line branch="false" hits="27" number="258"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="24" number="264"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processAudioCodec" signature=""> + <lines> + <line branch="false" hits="27" number="272"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="1" number="276"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processVideoCodec" signature=""> + <lines> + <line branch="false" hits="27" number="285"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="1" number="289"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processUiLatency" signature=""> + <lines> + <line branch="false" hits="28" number="298"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="25" number="306"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processLocalTime" signature=""> + <lines> + <line branch="false" hits="25" number="328"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_27)" signature=""> + <lines> + <line branch="false" hits="23" number="332"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processNewSessionLoaded" signature=""> + <lines> + <line branch="false" hits="30" number="341"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_29)" signature=""> + <lines> + <line branch="false" hits="2" number="345"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processReasonEnd" signature=""> + <lines> + <line branch="false" hits="28" number="356"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="25" number="361"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processUnionPlayed" signature=""> + <lines> + <line branch="false" hits="28" number="371"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="89" number="375"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_34)" signature=""> + <lines> + <line branch="false" hits="43" number="380"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processMaxContinousPlayed" signature=""> + <lines> + <line branch="false" hits="28" number="394"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="87" number="398"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_37)" signature=""> + <lines> + <line branch="false" hits="45" number="403"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="processTimeWeightedBitrate" signature=""> + <lines> + <line branch="false" hits="31" number="416"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="91" number="420"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_40)" signature=""> + <lines> + <line branch="false" hits="44" number="425"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="generateEndVideoMessage" signature=""> + <lines> + <line branch="false" hits="25" number="442"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="15" number="1"/> + <line branch="false" hits="15" number="8"/> + <line branch="false" hits="15" number="9"/> + <line branch="false" hits="15" number="28"/> + <line branch="false" hits="15" number="36"/> + <line branch="false" hits="15" number="37"/> + <line branch="true" condition-coverage="50% (2/4)" hits="0" number="41"/> + <line branch="false" hits="5" number="42"/> + <line branch="false" hits="0" number="44"/> + <line branch="false" hits="0" number="46"/> + <line branch="false" hits="19" number="48"/> + <line branch="false" hits="8" number="57"/> + <line branch="false" hits="0" number="61"/> + <line branch="false" hits="0" number="64"/> + <line branch="false" hits="0" number="66"/> + <line branch="false" hits="3" number="68"/> + <line branch="false" hits="1" number="76"/> + <line branch="false" hits="5" number="78"/> + <line branch="false" hits="7" number="79"/> + <line branch="false" hits="7" number="81"/> + <line branch="false" hits="7" number="82"/> + <line branch="false" hits="11" number="89"/> + <line branch="false" hits="11" number="94"/> + <line branch="false" hits="11" number="95"/> + <line branch="false" hits="8" number="97"/> + <line branch="false" hits="0" number="99"/> + <line branch="false" hits="0" number="103"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="105"/> + <line branch="false" hits="1" number="106"/> + <line branch="false" hits="1" number="110"/> + <line branch="false" hits="3" number="113"/> + <line branch="false" hits="3" number="114"/> + <line branch="false" hits="4" number="116"/> + <line branch="false" hits="14" number="120"/> + <line branch="false" hits="15" number="123"/> + <line branch="false" hits="21" number="127"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="128"/> + <line branch="false" hits="5" number="129"/> + <line branch="false" hits="5" number="133"/> + <line branch="false" hits="5" number="134"/> + <line branch="false" hits="5" number="135"/> + <line branch="false" hits="21" number="140"/> + <line branch="false" hits="21" number="141"/> + <line branch="false" hits="21" number="142"/> + <line branch="false" hits="15" number="145"/> + <line branch="false" hits="5" number="149"/> + <line branch="false" hits="5" number="151"/> + <line branch="false" hits="5" number="153"/> + <line branch="false" hits="5" number="157"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="159"/> + <line branch="false" hits="4" number="160"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="161"/> + <line branch="false" hits="1" number="162"/> + <line branch="false" hits="1" number="166"/> + <line branch="false" hits="1" number="167"/> + <line branch="false" hits="1" number="168"/> + <line branch="false" hits="1" number="169"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="174"/> + <line branch="false" hits="0" number="175"/> + <line branch="false" hits="5" number="177"/> + <line branch="false" hits="5" number="178"/> + <line branch="false" hits="15" number="181"/> + <line branch="false" hits="21" number="184"/> + <line branch="false" hits="15" number="190"/> + <line branch="false" hits="12" number="191"/> + <line branch="false" hits="12" number="193"/> + <line branch="false" hits="15" number="206"/> + <line branch="false" hits="10" number="211"/> + <line branch="false" hits="10" number="212"/> + <line branch="false" hits="10" number="215"/> + <line branch="false" hits="15" number="223"/> + <line branch="false" hits="11" number="228"/> + <line branch="false" hits="11" number="229"/> + <line branch="false" hits="11" number="232"/> + <line branch="false" hits="15" number="240"/> + <line branch="false" hits="11" number="241"/> + <line branch="false" hits="11" number="248"/> + <line branch="false" hits="11" number="249"/> + <line branch="false" hits="15" number="258"/> + <line branch="false" hits="27" number="261"/> + <line branch="false" hits="24" number="264"/> + <line branch="false" hits="24" number="265"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="266"/> + <line branch="false" hits="15" number="272"/> + <line branch="false" hits="27" number="275"/> + <line branch="false" hits="1" number="276"/> + <line branch="false" hits="15" number="285"/> + <line branch="false" hits="27" number="288"/> + <line branch="false" hits="1" number="289"/> + <line branch="false" hits="15" number="298"/> + <line branch="false" hits="28" number="301"/> + <line branch="false" hits="28" number="305"/> + <line branch="false" hits="25" number="306"/> + <line branch="false" hits="13" number="308"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="310"/> + <line branch="false" hits="13" number="312"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="316"/> + <line branch="false" hits="12" number="320"/> + <line branch="false" hits="15" number="328"/> + <line branch="false" hits="25" number="331"/> + <line branch="false" hits="23" number="332"/> + <line branch="false" hits="15" number="341"/> + <line branch="false" hits="30" number="344"/> + <line branch="false" hits="2" number="345"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="347"/> + <line branch="false" hits="15" number="356"/> + <line branch="false" hits="28" number="359"/> + <line branch="false" hits="28" number="360"/> + <line branch="false" hits="25" number="361"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="363"/> + <line branch="false" hits="15" number="371"/> + <line branch="false" hits="28" number="374"/> + <line branch="false" hits="89" number="376"/> + <line branch="false" hits="43" number="380"/> + <line branch="false" hits="15" number="394"/> + <line branch="false" hits="28" number="397"/> + <line branch="false" hits="87" number="399"/> + <line branch="false" hits="45" number="403"/> + <line branch="false" hits="15" number="416"/> + <line branch="false" hits="31" number="419"/> + <line branch="false" hits="91" number="421"/> + <line branch="false" hits="44" number="425"/> + <line branch="false" hits="15" number="442"/> + <line branch="false" hits="25" number="445"/> + <line branch="false" hits="25" number="446"/> + <line branch="false" hits="25" number="489"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/tracking/endvideo/EndVideoLoggerFactory.ts" line-rate="1.0" name="src.tracking.endvideo.EndVideoLoggerFactory.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="15" number="11"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="EndVideoLoggerFactory" signature=""> + <lines> + <line branch="false" hits="14" number="19"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="14" number="32"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="15" number="9"/> + <line branch="false" hits="15" number="11"/> + <line branch="false" hits="14" number="26"/> + <line branch="false" hits="14" number="27"/> + <line branch="false" hits="14" number="28"/> + <line branch="false" hits="14" number="29"/> + <line branch="false" hits="14" number="30"/> + <line branch="false" hits="15" number="32"/> + <line branch="false" hits="14" number="33"/> + <line branch="false" hits="15" number="41"/> + </lines> + </class> + <class branch-rate="1.0" complexity="0" filename="src/tracking/endvideo/EndVideoLoggerTracker.ts" line-rate="0.8227848101265823" name="src.tracking.endvideo.EndVideoLoggerTracker.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="15" number="24"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="EndVideoLoggerTracker" signature=""> + <lines> + <line branch="false" hits="14" number="38"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="0" number="54"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="0" number="62"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="0" number="96"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_43)" signature=""> + <lines> + <line branch="false" hits="9" number="139"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_44)" signature=""> + <lines> + <line branch="false" hits="9" number="140"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_45)" signature=""> + <lines> + <line branch="false" hits="9" number="141"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_46)" signature=""> + <lines> + <line branch="false" hits="20" number="154"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_47)" signature=""> + <lines> + <line branch="false" hits="20" number="155"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_48)" signature=""> + <lines> + <line branch="false" hits="20" number="156"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_49)" signature=""> + <lines> + <line branch="false" hits="20" number="166"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_50)" signature=""> + <lines> + <line branch="false" hits="23" number="177"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="15" number="1"/> + <line branch="false" hits="15" number="4"/> + <line branch="false" hits="15" number="15"/> + <line branch="false" hits="15" number="16"/> + <line branch="false" hits="15" number="17"/> + <line branch="false" hits="15" number="18"/> + <line branch="false" hits="15" number="21"/> + <line branch="false" hits="15" number="22"/> + <line branch="false" hits="15" number="24"/> + <line branch="false" hits="14" number="35"/> + <line branch="true" condition-coverage="100% (2/2)" hits="14" number="45"/> + <line branch="false" hits="14" number="46"/> + <line branch="false" hits="14" number="47"/> + <line branch="false" hits="14" number="48"/> + <line branch="false" hits="14" number="49"/> + <line branch="false" hits="14" number="50"/> + <line branch="false" hits="14" number="52"/> + <line branch="false" hits="14" number="53"/> + <line branch="false" hits="14" number="54"/> + <line branch="false" hits="0" number="56"/> + <line branch="false" hits="0" number="57"/> + <line branch="false" hits="0" number="59"/> + <line branch="false" hits="0" number="60"/> + <line branch="false" hits="0" number="61"/> + <line branch="false" hits="0" number="62"/> + <line branch="false" hits="0" number="64"/> + <line branch="false" hits="0" number="67"/> + <line branch="false" hits="15" number="73"/> + <line branch="false" hits="11" number="79"/> + <line branch="false" hits="11" number="85"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="86"/> + <line branch="false" hits="3" number="90"/> + <line branch="false" hits="16" number="91"/> + <line branch="false" hits="11" number="94"/> + <line branch="false" hits="0" number="97"/> + <line branch="false" hits="15" number="102"/> + <line branch="false" hits="2" number="107"/> + <line branch="false" hits="2" number="108"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="109"/> + <line branch="false" hits="4" number="111"/> + <line branch="false" hits="15" number="114"/> + <line branch="false" hits="2" number="115"/> + <line branch="false" hits="2" number="116"/> + <line branch="false" hits="4" number="118"/> + <line branch="false" hits="15" number="121"/> + <line branch="false" hits="7" number="122"/> + <line branch="false" hits="7" number="123"/> + <line branch="false" hits="14" number="124"/> + <line branch="false" hits="15" number="127"/> + <line branch="false" hits="4" number="132"/> + <line branch="false" hits="8" number="133"/> + <line branch="false" hits="3" number="135"/> + <line branch="false" hits="15" number="139"/> + <line branch="false" hits="9" number="140"/> + <line branch="false" hits="9" number="141"/> + <line branch="false" hits="0" number="143"/> + <line branch="false" hits="0" number="144"/> + <line branch="false" hits="0" number="145"/> + <line branch="false" hits="9" number="147"/> + <line branch="false" hits="9" number="148"/> + <line branch="false" hits="9" number="149"/> + <line branch="false" hits="20" number="154"/> + <line branch="false" hits="20" number="155"/> + <line branch="false" hits="20" number="156"/> + <line branch="false" hits="0" number="158"/> + <line branch="false" hits="0" number="159"/> + <line branch="false" hits="20" number="161"/> + <line branch="false" hits="15" number="166"/> + <line branch="false" hits="15" number="177"/> + <line branch="false" hits="23" number="178"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="179"/> + <line branch="false" hits="15" number="184"/> + <line branch="false" hits="23" number="187"/> + <line branch="false" hits="3" number="194"/> + <line branch="false" hits="11" number="197"/> + <line branch="false" hits="18" number="198"/> + <line branch="false" hits="20" number="201"/> + <line branch="false" hits="40" number="205"/> + <line branch="false" hits="15" number="208"/> + <line branch="false" hits="19" number="209"/> + <line branch="false" hits="38" number="218"/> + <line branch="false" hits="15" number="220"/> + </lines> + </class> + <class branch-rate="1.0" complexity="0" filename="src/tracking/endvideo/EndVideoReasonEnd.ts" line-rate="1.0" name="src.tracking.endvideo.EndVideoReasonEnd.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="15" number="1"/> + </lines> + </method> + </methods> + <lines> + <line branch="true" condition-coverage="100% (2/2)" hits="15" number="1"/> + <line branch="false" hits="15" number="2"/> + <line branch="false" hits="15" number="3"/> + <line branch="false" hits="15" number="4"/> + <line branch="false" hits="15" number="5"/> + <line branch="false" hits="15" number="6"/> + <line branch="false" hits="15" number="7"/> + <line branch="false" hits="15" number="8"/> + <line branch="false" hits="15" number="11"/> + </lines> + </class> + <class branch-rate="0.875" complexity="0" filename="src/tracking/endvideo/EndVideoTracker.ts" line-rate="0.9212121212121213" name="src.tracking.endvideo.EndVideoTracker.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="15" number="24"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="EndVideoTracker" signature=""> + <lines> + <line branch="false" hits="13" number="64"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_5)" signature=""> + <lines> + <line branch="false" hits="13" number="78"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_6)" signature=""> + <lines> + <line branch="false" hits="13" number="110"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="14" number="118"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="64" number="131"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="6" number="237"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="29" number="255"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="13" number="287"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="9" number="295"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="5" number="355"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="13" number="364"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="13" number="417"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="4" number="419"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="13" number="430"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="12" number="438"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="10" number="458"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="15" number="1"/> + <line branch="false" hits="15" number="2"/> + <line branch="false" hits="15" number="15"/> + <line branch="false" hits="15" number="20"/> + <line branch="false" hits="15" number="24"/> + <line branch="false" hits="13" number="71"/> + <line branch="false" hits="13" number="72"/> + <line branch="false" hits="13" number="73"/> + <line branch="false" hits="13" number="74"/> + <line branch="false" hits="13" number="75"/> + <line branch="false" hits="15" number="78"/> + <line branch="false" hits="13" number="79"/> + <line branch="false" hits="13" number="80"/> + <line branch="false" hits="13" number="81"/> + <line branch="false" hits="13" number="82"/> + <line branch="false" hits="13" number="83"/> + <line branch="false" hits="13" number="84"/> + <line branch="false" hits="13" number="85"/> + <line branch="false" hits="13" number="86"/> + <line branch="false" hits="13" number="87"/> + <line branch="false" hits="13" number="88"/> + <line branch="false" hits="13" number="89"/> + <line branch="false" hits="13" number="90"/> + <line branch="false" hits="13" number="91"/> + <line branch="false" hits="13" number="92"/> + <line branch="false" hits="13" number="93"/> + <line branch="false" hits="13" number="94"/> + <line branch="false" hits="13" number="95"/> + <line branch="false" hits="13" number="96"/> + <line branch="false" hits="13" number="97"/> + <line branch="false" hits="13" number="98"/> + <line branch="false" hits="13" number="99"/> + <line branch="false" hits="13" number="100"/> + <line branch="false" hits="13" number="101"/> + <line branch="false" hits="13" number="102"/> + <line branch="false" hits="13" number="103"/> + <line branch="false" hits="13" number="104"/> + <line branch="false" hits="13" number="105"/> + <line branch="false" hits="13" number="106"/> + <line branch="false" hits="13" number="108"/> + <line branch="false" hits="13" number="109"/> + <line branch="false" hits="13" number="110"/> + <line branch="false" hits="0" number="112"/> + <line branch="false" hits="0" number="113"/> + <line branch="false" hits="13" number="115"/> + <line branch="false" hits="13" number="116"/> + <line branch="false" hits="13" number="117"/> + <line branch="false" hits="13" number="118"/> + <line branch="false" hits="14" number="120"/> + <line branch="false" hits="14" number="123"/> + <line branch="false" hits="13" number="128"/> + <line branch="false" hits="15" number="131"/> + <line branch="false" hits="5" number="133"/> + <line branch="false" hits="64" number="135"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="136"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="138"/> + <line branch="false" hits="55" number="139"/> + <line branch="false" hits="55" number="140"/> + <line branch="false" hits="55" number="141"/> + <line branch="false" hits="55" number="142"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="143"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="146"/> + <line branch="false" hits="6" number="147"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="149"/> + <line branch="false" hits="1" number="150"/> + <line branch="false" hits="10" number="154"/> + <line branch="false" hits="10" number="157"/> + <line branch="true" condition-coverage="100% (2/2)" hits="64" number="166"/> + <line branch="false" hits="64" number="167"/> + <line branch="true" condition-coverage="100% (2/2)" hits="64" number="168"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="170"/> + <line branch="false" hits="7" number="171"/> + <line branch="false" hits="2" number="174"/> + <line branch="false" hits="2" number="177"/> + <line branch="false" hits="2" number="178"/> + <line branch="false" hits="3" number="184"/> + <line branch="false" hits="3" number="185"/> + <line branch="false" hits="3" number="186"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="190"/> + <line branch="false" hits="0" number="191"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="193"/> + <line branch="false" hits="0" number="194"/> + <line branch="false" hits="64" number="197"/> + <line branch="false" hits="21" number="199"/> + <line branch="false" hits="64" number="201"/> + <line branch="false" hits="2" number="203"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="204"/> + <line branch="false" hits="1" number="205"/> + <line branch="false" hits="3" number="209"/> + <line branch="false" hits="3" number="215"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="218"/> + <line branch="false" hits="10" number="219"/> + <line branch="true" condition-coverage="100% (2/2)" hits="10" number="226"/> + <line branch="true" condition-coverage="100% (2/2)" hits="10" number="227"/> + <line branch="false" hits="10" number="229"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="230"/> + <line branch="false" hits="10" number="231"/> + <line branch="false" hits="10" number="233"/> + <line branch="false" hits="15" number="237"/> + <line branch="false" hits="6" number="238"/> + <line branch="false" hits="6" number="245"/> + <line branch="false" hits="3" number="247"/> + <line branch="false" hits="3" number="248"/> + <line branch="false" hits="3" number="250"/> + <line branch="false" hits="3" number="251"/> + <line branch="false" hits="15" number="255"/> + <line branch="false" hits="27" number="262"/> + <line branch="false" hits="16" number="264"/> + <line branch="false" hits="27" number="269"/> + <line branch="false" hits="17" number="272"/> + <line branch="false" hits="10" number="274"/> + <line branch="false" hits="27" number="283"/> + <line branch="false" hits="15" number="287"/> + <line branch="false" hits="13" number="288"/> + <line branch="false" hits="13" number="289"/> + <line branch="false" hits="13" number="290"/> + <line branch="false" hits="13" number="291"/> + <line branch="false" hits="13" number="292"/> + <line branch="false" hits="13" number="293"/> + <line branch="false" hits="13" number="295"/> + <line branch="false" hits="6" number="297"/> + <line branch="false" hits="1" number="299"/> + <line branch="false" hits="2" number="301"/> + <line branch="false" hits="13" number="303"/> + <line branch="false" hits="13" number="304"/> + <line branch="false" hits="17" number="305"/> + <line branch="false" hits="17" number="306"/> + <line branch="false" hits="17" number="307"/> + <line branch="false" hits="12" number="310"/> + <line branch="false" hits="12" number="311"/> + <line branch="false" hits="5" number="313"/> + <line branch="false" hits="5" number="314"/> + <line branch="false" hits="10" number="317"/> + <line branch="false" hits="7" number="319"/> + <line branch="false" hits="7" number="320"/> + <line branch="false" hits="17" number="322"/> + <line branch="false" hits="13" number="324"/> + <line branch="false" hits="0" number="328"/> + <line branch="false" hits="10" number="330"/> + <line branch="false" hits="4" number="333"/> + <line branch="false" hits="6" number="335"/> + <line branch="false" hits="13" number="339"/> + <line branch="false" hits="6" number="342"/> + <line branch="false" hits="13" number="347"/> + <line branch="false" hits="15" number="355"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="357"/> + <line branch="false" hits="1" number="358"/> + <line branch="true" condition-coverage="100% (2/2)" hits="4" number="360"/> + <line branch="false" hits="15" number="364"/> + <line branch="false" hits="13" number="365"/> + <line branch="false" hits="13" number="366"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="367"/> + <line branch="false" hits="13" number="369"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="377"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="405"/> + <line branch="false" hits="15" number="417"/> + <line branch="false" hits="13" number="418"/> + <line branch="false" hits="13" number="419"/> + <line branch="false" hits="0" number="421"/> + <line branch="false" hits="0" number="422"/> + <line branch="false" hits="1" number="425"/> + <line branch="false" hits="15" number="430"/> + <line branch="false" hits="0" number="432"/> + <line branch="false" hits="12" number="436"/> + <line branch="false" hits="12" number="438"/> + <line branch="false" hits="0" number="440"/> + <line branch="false" hits="0" number="441"/> + <line branch="false" hits="0" number="442"/> + <line branch="false" hits="12" number="444"/> + <line branch="false" hits="12" number="445"/> + <line branch="false" hits="12" number="446"/> + <line branch="false" hits="12" number="448"/> + <line branch="false" hits="0" number="452"/> + <line branch="false" hits="1" number="455"/> + <line branch="false" hits="15" number="458"/> + <line branch="false" hits="0" number="460"/> + <line branch="false" hits="10" number="462"/> + <line branch="false" hits="10" number="463"/> + <line branch="false" hits="10" number="464"/> + <line branch="false" hits="15" number="466"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="1.0" complexity="0" line-rate="0.7777777777777778" name="src.tracking.session"> + <classes> + <class branch-rate="1.0" complexity="0" filename="src/tracking/session/PlaybackSessionTracker.ts" line-rate="1.0" name="src.tracking.session.PlaybackSessionTracker.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_7)" signature=""> + <lines> + <line branch="false" hits="16" number="7"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="PlaybackSessionTracker" signature=""> + <lines> + <line branch="false" hits="1" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="1" number="14"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="16" number="1"/> + <line branch="false" hits="16" number="7"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="10"/> + <line branch="false" hits="1" number="11"/> + <line branch="false" hits="16" number="14"/> + <line branch="false" hits="1" number="19"/> + <line branch="false" hits="1" number="21"/> + <line branch="false" hits="1" number="22"/> + <line branch="false" hits="16" number="25"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/tracking/session/VideoPlaybackSessionLogger.ts" line-rate="0.5555555555555556" name="src.tracking.session.VideoPlaybackSessionLogger.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="15" number="6"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="VideoPlaybackSessionLogger" signature=""> + <lines> + <line branch="false" hits="0" number="9"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_3)" signature=""> + <lines> + <line branch="false" hits="0" number="12"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_4)" signature=""> + <lines> + <line branch="false" hits="0" number="13"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="15" number="3"/> + <line branch="false" hits="15" number="4"/> + <line branch="false" hits="15" number="6"/> + <line branch="false" hits="0" number="10"/> + <line branch="false" hits="15" number="12"/> + <line branch="false" hits="0" number="13"/> + <line branch="false" hits="0" number="14"/> + <line branch="false" hits="0" number="15"/> + <line branch="false" hits="15" number="18"/> + </lines> + </class> + </classes> + </package> + </packages> +</coverage> diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-3.xml b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-3.xml new file mode 100644 index 0000000000..176152791b --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-3.xml @@ -0,0 +1,357 @@ +<?xml version="1.0" ?> +<coverage lines-valid="524" lines-covered="455" line-rate="0.8683" branches-valid="653" branches-covered="465" branch-rate="0.7121" timestamp="1575309673957" complexity="0" version="0.1"> + <packages> + <package name="src" line-rate="1" branch-rate="1"> + <classes> + <class name="index.ts" filename="src/index.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + </lines> + </class> + </classes> + </package> + <package name="src.atoms.BoxShadow" line-rate="1" branch-rate="1"> + <classes> + <class name="box-shadow.ts" filename="src/atoms/BoxShadow/box-shadow.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + <line number="4" hits="5" branch="false"/> + </lines> + </class> + <class name="index.ts" filename="src/atoms/BoxShadow/index.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + </lines> + </class> + </classes> + </package> + <package name="src.atoms.Button" line-rate="0.4706" branch-rate="0.7646999999999999"> + <classes> + <class name="button.tsx" filename="src/atoms/Button/button.tsx" line-rate="0.4706" branch-rate="0.7646999999999999"> + <methods> + <method name="ButtonComponent" hits="41" signature="()V"> + <lines> + <line number="17" hits="41"/> + </lines> + </method> + <method name="(anonymous_1)" hits="0" signature="()V"> + <lines> + <line number="34" hits="0"/> + </lines> + </method> + <method name="(anonymous_2)" hits="41" signature="()V"> + <lines> + <line number="70" hits="41"/> + </lines> + </method> + <method name="(anonymous_3)" hits="41" signature="()V"> + <lines> + <line number="72" hits="41"/> + </lines> + </method> + <method name="(anonymous_4)" hits="41" signature="()V"> + <lines> + <line number="74" hits="41"/> + </lines> + </method> + </methods> + <lines> + <line number="31" hits="41" branch="false"/> + <line number="32" hits="41" branch="false"/> + <line number="34" hits="41" branch="false"/> + <line number="35" hits="0" branch="true" condition-coverage="0% (0/4)"/> + <line number="36" hits="0" branch="false"/> + <line number="37" hits="0" branch="false"/> + <line number="38" hits="0" branch="false"/> + <line number="39" hits="0" branch="false"/> + <line number="40" hits="0" branch="false"/> + <line number="41" hits="0" branch="false"/> + <line number="42" hits="0" branch="false"/> + <line number="43" hits="0" branch="false"/> + <line number="47" hits="41" branch="false"/> + <line number="68" hits="10" branch="false"/> + <line number="70" hits="41" branch="true" condition-coverage="100% (1/1)"/> + <line number="72" hits="41" branch="true" condition-coverage="100% (3/3)"/> + <line number="75" hits="41" branch="true" condition-coverage="100% (2/2)"/> + </lines> + </class> + <class name="index.ts" filename="src/atoms/Button/index.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + </lines> + </class> + </classes> + </package> + <package name="src.atoms.Container" line-rate="1" branch-rate="1"> + <classes> + <class name="components.ts" filename="src/atoms/Container/components.ts" line-rate="1" branch-rate="1"> + <methods> + <method name="(anonymous_0)" hits="35" signature="()V"> + <lines> + <line number="5" hits="35"/> + </lines> + </method> + <method name="(anonymous_1)" hits="35" signature="()V"> + <lines> + <line number="19" hits="35"/> + </lines> + </method> + <method name="(anonymous_2)" hits="35" signature="()V"> + <lines> + <line number="20" hits="35"/> + </lines> + </method> + <method name="(anonymous_3)" hits="35" signature="()V"> + <lines> + <line number="23" hits="35"/> + </lines> + </method> + </methods> + <lines> + <line number="4" hits="13" branch="false"/> + <line number="5" hits="35" branch="false"/> + <line number="13" hits="13" branch="false"/> + <line number="19" hits="35" branch="false"/> + <line number="20" hits="35" branch="false"/> + <line number="23" hits="35" branch="false"/> + </lines> + </class> + <class name="container.tsx" filename="src/atoms/Container/container.tsx" line-rate="1" branch-rate="1"> + <methods> + <method name="Container" hits="35" signature="()V"> + <lines> + <line number="12" hits="35"/> + </lines> + </method> + </methods> + <lines> + <line number="20" hits="35" branch="false"/> + </lines> + </class> + <class name="index.ts" filename="src/atoms/Container/index.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + </lines> + </class> + </classes> + </package> + <package name="src.atoms.DownArrow" line-rate="1" branch-rate="1"> + <classes> + <class name="down-arrow.tsx" filename="src/atoms/DownArrow/down-arrow.tsx" line-rate="1" branch-rate="1"> + <methods> + <method name="DownArrow" hits="28" signature="()V"> + <lines> + <line number="3" hits="28"/> + </lines> + </method> + </methods> + <lines> + <line number="4" hits="28" branch="false"/> + </lines> + </class> + <class name="index.ts" filename="src/atoms/DownArrow/index.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + </lines> + </class> + </classes> + </package> + <package name="src.molecules.Hero" line-rate="0.8695999999999999" branch-rate="0.7236"> + <classes> + <class name="components.ts" filename="src/molecules/Hero/components.ts" line-rate="0.8769" branch-rate="0.7143"> + <methods> + <method name="(anonymous_0)" hits="10" signature="()V"> + <lines> + <line number="26" hits="10"/> + </lines> + </method> + <method name="(anonymous_1)" hits="10" signature="()V"> + <lines> + <line number="28" hits="10"/> + </lines> + </method> + <method name="(anonymous_2)" hits="10" signature="()V"> + <lines> + <line number="94" hits="10"/> + </lines> + </method> + <method name="(anonymous_3)" hits="10" signature="()V"> + <lines> + <line number="103" hits="10"/> + </lines> + </method> + <method name="(anonymous_4)" hits="10" signature="()V"> + <lines> + <line number="121" hits="10"/> + </lines> + </method> + <method name="(anonymous_5)" hits="10" signature="()V"> + <lines> + <line number="182" hits="10"/> + </lines> + </method> + <method name="(anonymous_6)" hits="5" signature="()V"> + <lines> + <line number="203" hits="5"/> + </lines> + </method> + <method name="(anonymous_7)" hits="5" signature="()V"> + <lines> + <line number="218" hits="5"/> + </lines> + </method> + <method name="(anonymous_8)" hits="5" signature="()V"> + <lines> + <line number="236" hits="5"/> + </lines> + </method> + <method name="(anonymous_9)" hits="5" signature="()V"> + <lines> + <line number="241" hits="5"/> + </lines> + </method> + <method name="(anonymous_10)" hits="4" signature="()V"> + <lines> + <line number="249" hits="4"/> + </lines> + </method> + <method name="(anonymous_11)" hits="4" signature="()V"> + <lines> + <line number="254" hits="4"/> + </lines> + </method> + <method name="(anonymous_12)" hits="4" signature="()V"> + <lines> + <line number="264" hits="4"/> + </lines> + </method> + <method name="(anonymous_13)" hits="4" signature="()V"> + <lines> + <line number="277" hits="4"/> + </lines> + </method> + <method name="(anonymous_14)" hits="4" signature="()V"> + <lines> + <line number="282" hits="4"/> + </lines> + </method> + <method name="(anonymous_15)" hits="4" signature="()V"> + <lines> + <line number="294" hits="4"/> + </lines> + </method> + <method name="(anonymous_16)" hits="3" signature="()V"> + <lines> + <line number="299" hits="3"/> + </lines> + </method> + </methods> + <lines> + <line number="25" hits="2" branch="false"/> + <line number="26" hits="10" branch="false"/> + <line number="29" hits="10" branch="true" condition-coverage="100% (2/2)"/> + <line number="37" hits="3" branch="false"/> + <line number="39" hits="3" branch="true" condition-coverage="100% (2/2)"/> + <line number="40" hits="3" branch="false"/> + <line number="42" hits="3" branch="true" condition-coverage="100% (2/2)"/> + <line number="43" hits="1" branch="true" condition-coverage="75% (3/4)"/> + <line number="44" hits="1" branch="false"/> + <line number="45" hits="0" branch="true" condition-coverage="0% (0/4)"/> + <line number="46" hits="0" branch="false"/> + <line number="48" hits="1" branch="true" condition-coverage="50% (1/2)"/> + <line number="52" hits="0" branch="false"/> + <line number="53" hits="1" branch="true" condition-coverage="50% (1/2)"/> + <line number="57" hits="0" branch="false"/> + <line number="59" hits="1" branch="true" condition-coverage="50% (1/2)"/> + <line number="60" hits="1" branch="true" condition-coverage="50% (1/2)"/> + <line number="63" hits="3" branch="false"/> + <line number="95" hits="10" branch="true" condition-coverage="50% (1/2)"/> + <line number="103" hits="10" branch="false"/> + <line number="112" hits="2" branch="false"/> + <line number="122" hits="10" branch="true" condition-coverage="50% (2/4)"/> + <line number="125" hits="9" branch="false"/> + <line number="134" hits="0" branch="false"/> + <line number="151" hits="1" branch="false"/> + <line number="170" hits="2" branch="false"/> + <line number="181" hits="2" branch="false"/> + <line number="182" hits="10" branch="true" condition-coverage="100% (2/2)"/> + <line number="194" hits="2" branch="false"/> + <line number="204" hits="5" branch="true" condition-coverage="80% (4/5)"/> + <line number="207" hits="3" branch="false"/> + <line number="209" hits="0" branch="false"/> + <line number="211" hits="1" branch="false"/> + <line number="213" hits="1" branch="false"/> + <line number="219" hits="5" branch="true" condition-coverage="66.66666666666666% (4/6)"/> + <line number="222" hits="3" branch="false"/> + <line number="224" hits="0" branch="false"/> + <line number="226" hits="0" branch="false"/> + <line number="228" hits="1" branch="false"/> + <line number="230" hits="1" branch="false"/> + <line number="236" hits="5" branch="true" condition-coverage="100% (1/1)"/> + <line number="241" hits="5" branch="true" condition-coverage="100% (1/1)"/> + <line number="245" hits="2" branch="false"/> + <line number="249" hits="4" branch="true" condition-coverage="50% (1/2)"/> + <line number="255" hits="4" branch="true" condition-coverage="100% (3/3)"/> + <line number="258" hits="3" branch="false"/> + <line number="260" hits="1" branch="false"/> + <line number="265" hits="4" branch="true" condition-coverage="100% (4/4)"/> + <line number="268" hits="2" branch="false"/> + <line number="270" hits="1" branch="false"/> + <line number="272" hits="1" branch="false"/> + <line number="277" hits="4" branch="true" condition-coverage="100% (1/1)"/> + <line number="283" hits="4" branch="true" condition-coverage="100% (4/4)"/> + <line number="286" hits="2" branch="false"/> + <line number="288" hits="1" branch="false"/> + <line number="290" hits="1" branch="false"/> + <line number="294" hits="4" branch="true" condition-coverage="50% (1/2)"/> + <line number="298" hits="2" branch="false"/> + <line number="299" hits="3" branch="true" condition-coverage="50% (1/2)"/> + <line number="304" hits="2" branch="false"/> + <line number="311" hits="2" branch="false"/> + <line number="319" hits="2" branch="false"/> + <line number="329" hits="2" branch="false"/> + <line number="361" hits="2" branch="false"/> + <line number="371" hits="2" branch="false"/> + </lines> + </class> + <class name="hero.tsx" filename="src/molecules/Hero/hero.tsx" line-rate="0.75" branch-rate="0.76"> + <methods> + <method name="Hero" hits="10" signature="()V"> + <lines> + <line number="40" hits="10"/> + </lines> + </method> + <method name="(anonymous_1)" hits="0" signature="()V"> + <lines> + <line number="72" hits="0"/> + </lines> + </method> + <method name="(anonymous_2)" hits="3" signature="()V"> + <lines> + <line number="127" hits="3"/> + </lines> + </method> + </methods> + <lines> + <line number="56" hits="10" branch="false"/> + <line number="58" hits="10" branch="false"/> + <line number="73" hits="0" branch="true" condition-coverage="0% (0/2)"/> + <line number="128" hits="3" branch="false"/> + </lines> + </class> + <class name="index.ts" filename="src/molecules/Hero/index.ts" line-rate="1" branch-rate="1"> + <methods> + </methods> + <lines> + </lines> + </class> + </classes> + </package> + </packages> +</coverage> diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-4.xml b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-4.xml new file mode 100644 index 0000000000..36e36da3be --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-4.xml @@ -0,0 +1,348 @@ +<?xml version="1.0" ?> +<coverage line-rate="0.0" lines-covered="0" lines-valid="325" version="0.1"> + <package line-rate="0.0" name="Sources"> + <classes> + <class filename="Sources/TDSOptions.m" line-rate="0.0" name="TDSOptions.m"> + <lines> + <line hits="0" number="32" /> + <line hits="0" number="33" /> + <line hits="0" number="34" /> + <line hits="0" number="35" /> + <line hits="0" number="36" /> + <line hits="0" number="37" /> + <line hits="0" number="38" /> + <line hits="0" number="45" /> + <line hits="0" number="46" /> + <line hits="0" number="47" /> + <line hits="0" number="48" /> + <line hits="0" number="49" /> + <line hits="0" number="50" /> + <line hits="0" number="51" /> + <line hits="0" number="52" /> + <line hits="0" number="53" /> + <line hits="0" number="54" /> + <line hits="0" number="55" /> + <line hits="0" number="56" /> + <line hits="0" number="57" /> + <line hits="0" number="58" /> + <line hits="0" number="61" /> + <line hits="0" number="62" /> + <line hits="0" number="63" /> + <line hits="0" number="66" /> + <line hits="0" number="67" /> + <line hits="0" number="68" /> + <line hits="0" number="69" /> + <line hits="0" number="70" /> + <line hits="0" number="71" /> + <line hits="0" number="72" /> + <line hits="0" number="73" /> + <line hits="0" number="74" /> + <line hits="0" number="75" /> + <line hits="0" number="76" /> + <line hits="0" number="77" /> + </lines> + </class> + <class filename="Sources/TDSUserLock.m" line-rate="0.0" name="TDSUserLock.m"> + <lines> + <line hits="0" number="17" /> + <line hits="0" number="18" /> + <line hits="0" number="19" /> + <line hits="0" number="20" /> + <line hits="0" number="21" /> + <line hits="0" number="22" /> + <line hits="0" number="23" /> + <line hits="0" number="24" /> + <line hits="0" number="25" /> + <line hits="0" number="26" /> + <line hits="0" number="27" /> + <line hits="0" number="28" /> + <line hits="0" number="29" /> + <line hits="0" number="30" /> + <line hits="0" number="31" /> + <line hits="0" number="32" /> + <line hits="0" number="33" /> + <line hits="0" number="34" /> + <line hits="0" number="35" /> + <line hits="0" number="36" /> + <line hits="0" number="37" /> + <line hits="0" number="38" /> + <line hits="0" number="39" /> + <line hits="0" number="40" /> + <line hits="0" number="43" /> + <line hits="0" number="44" /> + <line hits="0" number="45" /> + <line hits="0" number="46" /> + <line hits="0" number="47" /> + <line hits="0" number="48" /> + <line hits="0" number="49" /> + <line hits="0" number="58" /> + <line hits="0" number="59" /> + <line hits="0" number="60" /> + <line hits="0" number="61" /> + <line hits="0" number="62" /> + <line hits="0" number="63" /> + <line hits="0" number="64" /> + <line hits="0" number="65" /> + <line hits="0" number="66" /> + <line hits="0" number="67" /> + <line hits="0" number="68" /> + <line hits="0" number="69" /> + <line hits="0" number="70" /> + </lines> + </class> + <class filename="Sources/TDSUserManager.m" line-rate="0.0" name="TDSUserManager.m"> + <lines> + <line hits="0" number="24" /> + <line hits="0" number="25" /> + <line hits="0" number="26" /> + <line hits="0" number="27" /> + <line hits="0" number="28" /> + <line hits="0" number="29" /> + <line hits="0" number="30" /> + <line hits="0" number="31" /> + <line hits="0" number="34" /> + <line hits="0" number="35" /> + <line hits="0" number="36" /> + <line hits="0" number="37" /> + <line hits="0" number="38" /> + <line hits="0" number="39" /> + <line hits="0" number="40" /> + <line hits="0" number="49" /> + <line hits="0" number="50" /> + <line hits="0" number="51" /> + <line hits="0" number="52" /> + <line hits="0" number="53" /> + <line hits="0" number="54" /> + <line hits="0" number="55" /> + <line hits="0" number="56" /> + <line hits="0" number="57" /> + <line hits="0" number="58" /> + <line hits="0" number="59" /> + <line hits="0" number="60" /> + <line hits="0" number="61" /> + <line hits="0" number="62" /> + <line hits="0" number="63" /> + <line hits="0" number="64" /> + <line hits="0" number="65" /> + <line hits="0" number="66" /> + <line hits="0" number="67" /> + <line hits="0" number="68" /> + <line hits="0" number="69" /> + <line hits="0" number="70" /> + <line hits="0" number="74" /> + <line hits="0" number="75" /> + <line hits="0" number="76" /> + <line hits="0" number="77" /> + <line hits="0" number="78" /> + <line hits="0" number="79" /> + <line hits="0" number="80" /> + <line hits="0" number="81" /> + <line hits="0" number="82" /> + <line hits="0" number="83" /> + <line hits="0" number="84" /> + <line hits="0" number="85" /> + <line hits="0" number="86" /> + <line hits="0" number="87" /> + <line hits="0" number="88" /> + <line hits="0" number="89" /> + <line hits="0" number="90" /> + <line hits="0" number="91" /> + <line hits="0" number="92" /> + <line hits="0" number="93" /> + <line hits="0" number="94" /> + <line hits="0" number="101" /> + <line hits="0" number="102" /> + <line hits="0" number="103" /> + <line hits="0" number="104" /> + <line hits="0" number="105" /> + <line hits="0" number="106" /> + <line hits="0" number="107" /> + <line hits="0" number="108" /> + <line hits="0" number="109" /> + <line hits="0" number="110" /> + <line hits="0" number="111" /> + <line hits="0" number="112" /> + <line hits="0" number="113" /> + <line hits="0" number="114" /> + <line hits="0" number="115" /> + <line hits="0" number="116" /> + <line hits="0" number="117" /> + <line hits="0" number="118" /> + <line hits="0" number="119" /> + <line hits="0" number="120" /> + <line hits="0" number="121" /> + <line hits="0" number="122" /> + <line hits="0" number="123" /> + <line hits="0" number="124" /> + <line hits="0" number="125" /> + <line hits="0" number="126" /> + <line hits="0" number="127" /> + <line hits="0" number="128" /> + <line hits="0" number="129" /> + <line hits="0" number="130" /> + <line hits="0" number="131" /> + <line hits="0" number="136" /> + <line hits="0" number="137" /> + <line hits="0" number="138" /> + <line hits="0" number="139" /> + <line hits="0" number="140" /> + <line hits="0" number="141" /> + <line hits="0" number="142" /> + <line hits="0" number="143" /> + <line hits="0" number="144" /> + <line hits="0" number="145" /> + <line hits="0" number="146" /> + <line hits="0" number="147" /> + <line hits="0" number="148" /> + <line hits="0" number="149" /> + <line hits="0" number="150" /> + <line hits="0" number="151" /> + <line hits="0" number="152" /> + <line hits="0" number="153" /> + <line hits="0" number="158" /> + <line hits="0" number="159" /> + <line hits="0" number="160" /> + <line hits="0" number="161" /> + <line hits="0" number="162" /> + <line hits="0" number="163" /> + <line hits="0" number="164" /> + <line hits="0" number="165" /> + <line hits="0" number="166" /> + <line hits="0" number="167" /> + <line hits="0" number="168" /> + <line hits="0" number="169" /> + <line hits="0" number="170" /> + <line hits="0" number="171" /> + <line hits="0" number="172" /> + <line hits="0" number="173" /> + <line hits="0" number="174" /> + <line hits="0" number="175" /> + <line hits="0" number="176" /> + <line hits="0" number="177" /> + <line hits="0" number="178" /> + <line hits="0" number="179" /> + <line hits="0" number="180" /> + <line hits="0" number="181" /> + <line hits="0" number="182" /> + <line hits="0" number="183" /> + <line hits="0" number="184" /> + <line hits="0" number="189" /> + <line hits="0" number="190" /> + <line hits="0" number="191" /> + <line hits="0" number="192" /> + <line hits="0" number="193" /> + <line hits="0" number="194" /> + <line hits="0" number="195" /> + <line hits="0" number="196" /> + <line hits="0" number="197" /> + <line hits="0" number="198" /> + <line hits="0" number="199" /> + <line hits="0" number="200" /> + <line hits="0" number="201" /> + <line hits="0" number="202" /> + <line hits="0" number="203" /> + <line hits="0" number="204" /> + <line hits="0" number="205" /> + <line hits="0" number="206" /> + <line hits="0" number="207" /> + <line hits="0" number="208" /> + <line hits="0" number="209" /> + <line hits="0" number="210" /> + <line hits="0" number="211" /> + <line hits="0" number="212" /> + <line hits="0" number="213" /> + <line hits="0" number="214" /> + <line hits="0" number="215" /> + <line hits="0" number="216" /> + <line hits="0" number="217" /> + <line hits="0" number="218" /> + <line hits="0" number="219" /> + <line hits="0" number="220" /> + <line hits="0" number="221" /> + <line hits="0" number="222" /> + <line hits="0" number="223" /> + <line hits="0" number="224" /> + <line hits="0" number="225" /> + <line hits="0" number="226" /> + <line hits="0" number="227" /> + <line hits="0" number="228" /> + <line hits="0" number="229" /> + <line hits="0" number="230" /> + <line hits="0" number="231" /> + <line hits="0" number="232" /> + <line hits="0" number="233" /> + <line hits="0" number="234" /> + <line hits="0" number="235" /> + <line hits="0" number="236" /> + <line hits="0" number="239" /> + <line hits="0" number="240" /> + <line hits="0" number="241" /> + <line hits="0" number="242" /> + <line hits="0" number="243" /> + <line hits="0" number="244" /> + <line hits="0" number="245" /> + <line hits="0" number="246" /> + <line hits="0" number="247" /> + <line hits="0" number="248" /> + <line hits="0" number="249" /> + <line hits="0" number="252" /> + <line hits="0" number="253" /> + <line hits="0" number="254" /> + <line hits="0" number="255" /> + <line hits="0" number="256" /> + <line hits="0" number="257" /> + <line hits="0" number="258" /> + <line hits="0" number="259" /> + <line hits="0" number="260" /> + <line hits="0" number="261" /> + <line hits="0" number="262" /> + <line hits="0" number="263" /> + <line hits="0" number="264" /> + <line hits="0" number="265" /> + <line hits="0" number="268" /> + <line hits="0" number="269" /> + <line hits="0" number="270" /> + <line hits="0" number="271" /> + <line hits="0" number="272" /> + <line hits="0" number="273" /> + <line hits="0" number="274" /> + <line hits="0" number="275" /> + <line hits="0" number="276" /> + <line hits="0" number="277" /> + <line hits="0" number="278" /> + <line hits="0" number="279" /> + <line hits="0" number="280" /> + <line hits="0" number="281" /> + <line hits="0" number="282" /> + <line hits="0" number="283" /> + <line hits="0" number="284" /> + <line hits="0" number="287" /> + <line hits="0" number="288" /> + <line hits="0" number="289" /> + <line hits="0" number="290" /> + <line hits="0" number="291" /> + <line hits="0" number="292" /> + <line hits="0" number="293" /> + <line hits="0" number="294" /> + <line hits="0" number="295" /> + <line hits="0" number="296" /> + </lines> + </class> + <class filename="Sources/TDSUtil.m" line-rate="0.0" name="TDSUtil.m"> + <lines> + <line hits="0" number="8" /> + <line hits="0" number="9" /> + <line hits="0" number="10" /> + <line hits="0" number="11" /> + <line hits="0" number="12" /> + <line hits="0" number="13" /> + <line hits="0" number="16" /> + <line hits="0" number="17" /> + <line hits="0" number="18" /> + <line hits="0" number="19" /> + <line hits="0" number="20" /> + </lines> + </class> + </classes> + </package> +</coverage> diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-5.xml b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-5.xml new file mode 100644 index 0000000000..5bc8e6e45d --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/cobertura-testdata-5.xml @@ -0,0 +1,441 @@ +<?xml version="1.0" ?> +<coverage branch-rate="0.7602339181286549" branches-covered="130" branches-valid="171" complexity="0" line-rate="0.8738738738738738" lines-covered="582" lines-valid="666" timestamp="1575668573" version="2.0.3"> + <sources> + <source>.</source> + </sources> + <packages> + <package branch-rate="0.75" complexity="0" line-rate="0.9672131147540983" name="src.graphql"> + <classes> + <class branch-rate="0.0" complexity="0" filename="src/graphql/queries.ts" line-rate="1.0" name="src.graphql.queries.ts"> + <methods/> + <lines> + <line branch="false" hits="3" number="1"/> + <line branch="false" hits="3" number="3"/> + <line branch="false" hits="3" number="50"/> + <line branch="false" hits="3" number="65"/> + <line branch="false" hits="3" number="80"/> + <line branch="false" hits="3" number="92"/> + <line branch="false" hits="3" number="138"/> + </lines> + </class> + <class branch-rate="0.8" complexity="0" filename="src/graphql/resolvers.ts" line-rate="0.974025974025974" name="src.graphql.resolvers.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_12)" signature=""> + <lines> + <line branch="false" hits="17" number="22"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_13)" signature=""> + <lines> + <line branch="false" hits="10" number="28"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_14)" signature=""> + <lines> + <line branch="false" hits="12" number="36"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_15)" signature=""> + <lines> + <line branch="false" hits="4" number="27"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_16)" signature=""> + <lines> + <line branch="false" hits="4" number="35"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_17)" signature=""> + <lines> + <line branch="false" hits="9" number="43"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_18)" signature=""> + <lines> + <line branch="false" hits="11" number="51"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_19)" signature=""> + <lines> + <line branch="false" hits="4" number="56"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_20)" signature=""> + <lines> + <line branch="false" hits="4" number="61"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_21)" signature=""> + <lines> + <line branch="false" hits="4" number="50"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_22)" signature=""> + <lines> + <line branch="false" hits="4" number="55"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_23)" signature=""> + <lines> + <line branch="false" hits="4" number="60"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_24)" signature=""> + <lines> + <line branch="false" hits="7" number="128"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_25)" signature=""> + <lines> + <line branch="false" hits="4" number="139"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_26)" signature=""> + <lines> + <line branch="false" hits="4" number="145"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_28)" signature=""> + <lines> + <line branch="false" hits="4" number="160"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_30)" signature=""> + <lines> + <line branch="false" hits="3" number="177"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_31)" signature=""> + <lines> + <line branch="false" hits="9" number="185"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_32)" signature=""> + <lines> + <line branch="false" hits="8" number="70"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_33)" signature=""> + <lines> + <line branch="false" hits="4" number="78"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_34)" signature=""> + <lines> + <line branch="false" hits="4" number="81"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_35)" signature=""> + <lines> + <line branch="false" hits="4" number="84"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_36)" signature=""> + <lines> + <line branch="false" hits="4" number="97"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_37)" signature=""> + <lines> + <line branch="false" hits="4" number="97"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_38)" signature=""> + <lines> + <line branch="false" hits="4" number="103"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_39)" signature=""> + <lines> + <line branch="false" hits="4" number="114"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_40)" signature=""> + <lines> + <line branch="false" hits="4" number="144"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_41)" signature=""> + <lines> + <line branch="false" hits="4" number="159"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_42)" signature=""> + <lines> + <line branch="false" hits="4" number="176"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_43)" signature=""> + <lines> + <line branch="false" hits="4" number="184"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="4" number="1"/> + <line branch="false" hits="4" number="2"/> + <line branch="false" hits="4" number="3"/> + <line branch="false" hits="4" number="5"/> + <line branch="false" hits="4" number="6"/> + <line branch="false" hits="4" number="7"/> + <line branch="false" hits="4" number="8"/> + <line branch="false" hits="4" number="9"/> + <line branch="false" hits="4" number="10"/> + <line branch="false" hits="4" number="14"/> + <line branch="false" hits="4" number="21"/> + <line branch="false" hits="17" number="24"/> + <line branch="false" hits="4" number="27"/> + <line branch="false" hits="4" number="28"/> + <line branch="false" hits="10" number="32"/> + <line branch="false" hits="4" number="35"/> + <line branch="false" hits="4" number="36"/> + <line branch="false" hits="12" number="37"/> + <line branch="false" hits="4" number="42"/> + <line branch="false" hits="9" number="45"/> + <line branch="false" hits="9" number="47"/> + <line branch="false" hits="4" number="50"/> + <line branch="false" hits="4" number="51"/> + <line branch="false" hits="11" number="52"/> + <line branch="false" hits="4" number="55"/> + <line branch="false" hits="4" number="56"/> + <line branch="false" hits="4" number="57"/> + <line branch="false" hits="4" number="60"/> + <line branch="false" hits="4" number="61"/> + <line branch="false" hits="4" number="62"/> + <line branch="false" hits="4" number="67"/> + <line branch="false" hits="4" number="70"/> + <line branch="false" hits="8" number="73"/> + <line branch="false" hits="4" number="78"/> + <line branch="false" hits="4" number="81"/> + <line branch="false" hits="4" number="83"/> + <line branch="false" hits="4" number="85"/> + <line branch="true" condition-coverage="100% (2/2)" hits="4" number="86"/> + <line branch="false" hits="4" number="87"/> + <line branch="false" hits="4" number="88"/> + <line branch="false" hits="4" number="94"/> + <line branch="false" hits="4" number="95"/> + <line branch="false" hits="4" number="97"/> + <line branch="false" hits="4" number="98"/> + <line branch="false" hits="4" number="103"/> + <line branch="false" hits="4" number="104"/> + <line branch="false" hits="4" number="107"/> + <line branch="false" hits="4" number="114"/> + <line branch="false" hits="4" number="115"/> + <line branch="false" hits="4" number="118"/> + <line branch="true" condition-coverage="50% (1/2)" hits="4" number="119"/> + <line branch="false" hits="0" number="120"/> + <line branch="false" hits="4" number="124"/> + <line branch="false" hits="7" number="130"/> + <line branch="false" hits="7" number="132"/> + <line branch="false" hits="7" number="134"/> + <line branch="false" hits="7" number="136"/> + <line branch="false" hits="4" number="140"/> + <line branch="false" hits="4" number="144"/> + <line branch="false" hits="4" number="145"/> + <line branch="false" hits="4" number="151"/> + <line branch="false" hits="4" number="159"/> + <line branch="false" hits="4" number="160"/> + <line branch="false" hits="4" number="165"/> + <line branch="true" condition-coverage="100% (2/2)" hits="4" number="166"/> + <line branch="true" condition-coverage="100% (2/2)" hits="4" number="167"/> + <line branch="false" hits="1" number="168"/> + <line branch="false" hits="4" number="169"/> + <line branch="false" hits="4" number="176"/> + <line branch="false" hits="4" number="177"/> + <line branch="false" hits="3" number="178"/> + <line branch="false" hits="4" number="184"/> + <line branch="false" hits="4" number="185"/> + <line branch="false" hits="9" number="186"/> + <line branch="false" hits="9" number="187"/> + <line branch="true" condition-coverage="50% (1/2)" hits="2" number="193"/> + <line branch="false" hits="0" number="194"/> + </lines> + </class> + <class branch-rate="0.7272727272727273" complexity="0" filename="src/graphql/router.ts" line-rate="0.9444444444444444" name="src.graphql.router.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="handleApolloClientError" signature=""> + <lines> + <line branch="false" hits="1" number="21"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_8)" signature=""> + <lines> + <line branch="false" hits="1" number="22"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="graphqlRoute" signature=""> + <lines> + <line branch="false" hits="18" number="43"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="11" number="53"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_11)" signature=""> + <lines> + <line branch="false" hits="11" number="53"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="3" number="12"/> + <line branch="false" hits="3" number="14"/> + <line branch="false" hits="1" number="22"/> + <line branch="true" condition-coverage="100% (3/3)" hits="1" number="23"/> + <line branch="true" condition-coverage="50% (1/2)" hits="0" number="26"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" number="32"/> + <line branch="false" hits="1" number="33"/> + <line branch="false" hits="1" number="34"/> + <line branch="false" hits="0" number="37"/> + <line branch="false" hits="3" number="43"/> + <line branch="false" hits="18" number="53"/> + <line branch="false" hits="11" number="54"/> + <line branch="true" condition-coverage="100% (2/2)" hits="0" number="55"/> + <line branch="false" hits="11" number="57"/> + <line branch="false" hits="11" number="58"/> + <line branch="false" hits="11" number="63"/> + <line branch="false" hits="11" number="64"/> + <line branch="true" condition-coverage="50% (1/2)" hits="10" number="65"/> + <line branch="false" hits="10" number="66"/> + <line branch="false" hits="1" number="68"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/graphql/schema.ts" line-rate="1.0" name="src.graphql.schema.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="getGraphqlSchema" signature=""> + <lines> + <line branch="false" hits="4" number="9"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="3" number="1"/> + <line branch="false" hits="3" number="2"/> + <line branch="false" hits="3" number="4"/> + <line branch="false" hits="3" number="5"/> + <line branch="false" hits="3" number="9"/> + <line branch="true" condition-coverage="0% (0/1)" hits="0" number="11"/> + <line branch="false" hits="4" number="13"/> + <line branch="false" hits="4" number="15"/> + <line branch="false" hits="4" number="16"/> + <line branch="false" hits="4" number="17"/> + <line branch="false" hits="4" number="19"/> + </lines> + </class> + <class branch-rate="0.8333333333333334" complexity="0" filename="src/graphql/transforms.ts" line-rate="0.9" name="src.graphql.transforms.ts"> + <methods> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_0)" signature=""> + <lines> + <line branch="false" hits="6" number="9"/> + </lines> + </method> + <method branch-rate="1.0" line-rate="1.0" name="(anonymous_1)" signature=""> + <lines> + <line branch="false" hits="1" number="20"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="4" number="9"/> + <line branch="true" condition-coverage="100% (2/2)" hits="6" number="13"/> + <line branch="false" hits="2" number="14"/> + <line branch="true" condition-coverage="100% (2/2)" hits="6" number="15"/> + <line branch="false" hits="1" number="16"/> + <line branch="false" hits="6" number="17"/> + <line branch="false" hits="4" number="20"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" number="23"/> + <line branch="false" hits="0" number="24"/> + <line branch="false" hits="1" number="25"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.0" complexity="0" line-rate="0.0" name="src.workers"> + <classes> + <class branch-rate="0.0" complexity="0" filename="src/workers/primary-worker.js" line-rate="0.0" name="src.workers.primary-worker.js"> + <methods> + <method branch-rate="0.0" line-rate="0.0" name="doWork" signature=""> + <lines> + <line branch="false" hits="0" number="16"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="0" number="25"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_10)" signature=""> + <lines> + <line branch="false" hits="0" number="49"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="0" number="2"/> + <line branch="false" hits="0" number="3"/> + <line branch="false" hits="0" number="4"/> + <line branch="false" hits="0" number="5"/> + <line branch="false" hits="0" number="6"/> + <line branch="false" hits="0" number="8"/> + <line branch="false" hits="0" number="16"/> + <line branch="true" condition-coverage="0% (0/1)" hits="0" number="17"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="21"/> + <line branch="false" hits="0" number="22"/> + <line branch="false" hits="0" number="23"/> + <line branch="false" hits="0" number="24"/> + <line branch="false" hits="0" number="25"/> + <line branch="false" hits="0" number="27"/> + <line branch="false" hits="0" number="28"/> + <line branch="false" hits="0" number="31"/> + <line branch="false" hits="0" number="33"/> + <line branch="false" hits="0" number="34"/> + <line branch="false" hits="0" number="37"/> + <line branch="false" hits="0" number="38"/> + <line branch="false" hits="0" number="48"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="49"/> + <line branch="false" hits="0" number="51"/> + <line branch="false" hits="0" number="53"/> + </lines> + </class> + <class branch-rate="0.0" complexity="0" filename="src/workers/secondary-worker.js" line-rate="0.0" name="src.workers.secondary-worker.js"> + <methods> + <method branch-rate="0.0" line-rate="0.0" name="doWork" signature=""> + <lines> + <line branch="false" hits="0" number="4"/> + </lines> + </method> + <method branch-rate="0.0" line-rate="0.0" name="(anonymous_9)" signature=""> + <lines> + <line branch="false" hits="0" number="13"/> + </lines> + </method> + </methods> + <lines> + <line branch="false" hits="0" number="2"/> + <line branch="false" hits="0" number="4"/> + <line branch="true" condition-coverage="0% (0/1)" hits="0" number="5"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="9"/> + <line branch="false" hits="0" number="10"/> + <line branch="false" hits="0" number="11"/> + <line branch="false" hits="0" number="12"/> + <line branch="false" hits="0" number="13"/> + <line branch="false" hits="0" number="14"/> + <line branch="false" hits="0" number="15"/> + <line branch="false" hits="0" number="16"/> + <line branch="false" hits="0" number="18"/> + <line branch="false" hits="0" number="19"/> + <line branch="false" hits="0" number="22"/> + <line branch="false" hits="0" number="23"/> + <line branch="true" condition-coverage="0% (0/2)" hits="0" number="24"/> + <line branch="false" hits="0" number="25"/> + <line branch="false" hits="0" number="26"/> + <line branch="false" hits="0" number="27"/> + <line branch="false" hits="0" number="29"/> + </lines> + </class> + </classes> + </package> + </packages> +</coverage> diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-jsoncoverage-files-1.json b/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-jsoncoverage-files-1.json new file mode 100644 index 0000000000..b37f019305 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-jsoncoverage-files-1.json @@ -0,0 +1,319 @@ +[ + { + "filename": "src/main/java/com/example/Main.kt", + "lineHits": { + "28": 0, + "31": 0, + "36": 0, + "37": 0, + "38": 0, + "39": 0, + "40": 0, + "41": 0, + "42": 0, + "43": 0, + "44": 0, + "45": 0, + "46": 0, + "47": 0, + "48": 0, + "49": 0, + "50": 0, + "52": 0, + "53": 0, + "56": 0, + "57": 0, + "58": 0, + "59": 0, + "60": 0, + "62": 0, + "65": 0, + "66": 0, + "67": 0, + "69": 0, + "70": 0, + "71": 0, + "72": 0, + "74": 0, + "76": 0, + "77": 0, + "78": 0, + "79": 0, + "81": 0, + "82": 0, + "83": 0, + "84": 0, + "85": 0, + "86": 0, + "87": 0, + "88": 0, + "89": 0, + "92": 0, + "93": 0 + }, + "branchHits": {} + }, + { + "filename": "src/main/java/com/example/Parser.kt", + "lineHits": { + "5": 9, + "10": 7, + "12": 8, + "13": 2, + "14": 3, + "16": 28, + "17": 1, + "19": 4, + "20": 16, + "21": 18, + "22": 12, + "23": 5, + "24": 14, + "25": 22, + "26": 9, + "28": 7, + "29": 1, + "32": 2, + "34": 13, + "36": 0, + "37": 0, + "38": 0, + "39": 0, + "40": 0, + "43": 7, + "44": 0, + "46": 2, + "49": 7, + "50": 1, + "53": 5, + "54": 3, + "55": 18, + "56": 3, + "57": 1, + "58": 3, + "59": 3, + "60": 5, + "62": 1, + "64": 6, + "65": 2, + "69": 5, + "70": 14, + "71": 8, + "72": 20, + "73": 16, + "74": 22, + "75": 3, + "76": 2, + "77": 19, + "78": 1, + "79": 13, + "80": 5, + "81": 4, + "83": 4, + "84": 12, + "85": 10, + "86": 7, + "87": 9, + "94": 10, + "95": 5, + "96": 4, + "98": 9, + "99": 12, + "100": 10, + "101": 7, + "102": 4, + "103": 9, + "104": 10, + "105": 5, + "106": 10, + "107": 4, + "108": 3, + "109": 2, + "110": 5, + "111": 2, + "113": 1, + "114": 7, + "116": 3, + "117": 12, + "118": 26, + "119": 10, + "120": 7, + "122": 3, + "123": 9, + "124": 14, + "125": 2, + "126": 3 + }, + "branchHits": { + "12": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "16": { + "covered": 2, + "missed": 2, + "available": 4 + }, + "24": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "25": { + "covered": 6, + "missed": 2, + "available": 8 + }, + "38": { + "covered": 0, + "missed": 4, + "available": 4 + }, + "43": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "44": { + "covered": 0, + "missed": 2, + "available": 2 + }, + "55": { + "covered": 4, + "missed": 0, + "available": 4 + }, + "70": { + "covered": 1, + "missed": 3, + "available": 4 + }, + "73": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "75": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "77": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "79": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "85": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "94": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "100": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "104": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "108": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "119": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "124": { + "covered": 2, + "missed": 0, + "available": 2 + } + } + }, + { + "filename": "src/main/java/com/example/models/Thing.kt", + "lineHits": { + "9": 8, + "10": 3, + "11": 0, + "14": 8, + "15": 3, + "16": 1, + "19": 8, + "20": 3, + "21": 0, + "24": 3, + "25": 3, + "26": 1, + "29": 11, + "30": 3, + "31": 3, + "32": 3, + "35": 12, + "36": 12, + "37": 1, + "40": 5, + "41": 3, + "44": 3, + "45": 1, + "48": 12, + "49": 3, + "50": 3, + "51": 0 + }, + "branchHits": { + "14": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "15": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "24": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "25": { + "covered": 1, + "missed": 1, + "available": 2 + }, + "35": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "36": { + "covered": 2, + "missed": 0, + "available": 2 + }, + "44": { + "covered": 1, + "missed": 1, + "available": 2 + } + } + } +] diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-sourcefiles-1.txt b/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-sourcefiles-1.txt new file mode 100644 index 0000000000..84e69b0b4b --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-sourcefiles-1.txt @@ -0,0 +1,7 @@ +pom.xml +src/main/java/com/example/Parser.kt +src/main/java/com/example/Main.kt +src/main/java/com/example/models/Thing.kt +src/main/resources/app.conf +src/test/java/com/example/ParserTest.kt +src/test/resources/logback-test.xml diff --git a/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-testdata-1.xml b/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-testdata-1.xml new file mode 100644 index 0000000000..d07dd81b50 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/__fixtures__/jacoco-testdata-1.xml @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<report name="example"> + <sessioninfo id="743a5357362a-f32e3def" start="1575926125817" dump="1575926133882"/> + <package name="com/example"> + <sourcefile name="Main.kt"> + <line nr="28" mi="6" ci="0" mb="0" cb="0"/> + <line nr="31" mi="7" ci="0" mb="0" cb="0"/> + <line nr="36" mi="3" ci="0" mb="0" cb="0"/> + <line nr="37" mi="12" ci="0" mb="0" cb="0"/> + <line nr="38" mi="2" ci="0" mb="0" cb="0"/> + <line nr="39" mi="2" ci="0" mb="0" cb="0"/> + <line nr="40" mi="5" ci="0" mb="0" cb="0"/> + <line nr="41" mi="5" ci="0" mb="0" cb="0"/> + <line nr="42" mi="3" ci="0" mb="0" cb="0"/> + <line nr="43" mi="3" ci="0" mb="0" cb="0"/> + <line nr="44" mi="3" ci="0" mb="0" cb="0"/> + <line nr="45" mi="3" ci="0" mb="0" cb="0"/> + <line nr="46" mi="3" ci="0" mb="0" cb="0"/> + <line nr="47" mi="4" ci="0" mb="0" cb="0"/> + <line nr="48" mi="4" ci="0" mb="0" cb="0"/> + <line nr="49" mi="4" ci="0" mb="0" cb="0"/> + <line nr="50" mi="1" ci="0" mb="0" cb="0"/> + <line nr="52" mi="8" ci="0" mb="0" cb="0"/> + <line nr="53" mi="19" ci="0" mb="0" cb="0"/> + <line nr="56" mi="1" ci="0" mb="0" cb="0"/> + <line nr="57" mi="8" ci="0" mb="0" cb="0"/> + <line nr="58" mi="1" ci="0" mb="0" cb="0"/> + <line nr="59" mi="24" ci="0" mb="0" cb="0"/> + <line nr="60" mi="2" ci="0" mb="0" cb="0"/> + <line nr="62" mi="1" ci="0" mb="0" cb="0"/> + <line nr="65" mi="5" ci="0" mb="0" cb="0"/> + <line nr="66" mi="5" ci="0" mb="0" cb="0"/> + <line nr="67" mi="3" ci="0" mb="0" cb="0"/> + <line nr="69" mi="1" ci="0" mb="0" cb="0"/> + <line nr="70" mi="1" ci="0" mb="0" cb="0"/> + <line nr="71" mi="1" ci="0" mb="0" cb="0"/> + <line nr="72" mi="7" ci="0" mb="0" cb="0"/> + <line nr="74" mi="2" ci="0" mb="0" cb="0"/> + <line nr="76" mi="3" ci="0" mb="0" cb="0"/> + <line nr="77" mi="7" ci="0" mb="0" cb="0"/> + <line nr="78" mi="5" ci="0" mb="0" cb="0"/> + <line nr="79" mi="5" ci="0" mb="0" cb="0"/> + <line nr="81" mi="1" ci="0" mb="0" cb="0"/> + <line nr="82" mi="1" ci="0" mb="0" cb="0"/> + <line nr="83" mi="2" ci="0" mb="0" cb="0"/> + <line nr="84" mi="9" ci="0" mb="0" cb="0"/> + <line nr="85" mi="3" ci="0" mb="0" cb="0"/> + <line nr="86" mi="1" ci="0" mb="0" cb="0"/> + <line nr="87" mi="3" ci="0" mb="0" cb="0"/> + <line nr="88" mi="1" ci="0" mb="0" cb="0"/> + <line nr="89" mi="6" ci="0" mb="0" cb="0"/> + <line nr="92" mi="6" ci="0" mb="0" cb="0"/> + <line nr="93" mi="1" ci="0" mb="0" cb="0"/> + <counter type="INSTRUCTION" missed="219" covered="0"/> + <counter type="LINE" missed="48" covered="0"/> + <counter type="COMPLEXITY" missed="8" covered="0"/> + <counter type="METHOD" missed="8" covered="0"/> + <counter type="CLASS" missed="6" covered="0"/> + </sourcefile> + <sourcefile name="Parser.kt"> + <line nr="5" mi="0" ci="9" mb="0" cb="0"/> + <line nr="10" mi="0" ci="7" mb="0" cb="0"/> + <line nr="12" mi="1" ci="8" mb="1" cb="1"/> + <line nr="13" mi="0" ci="2" mb="0" cb="0"/> + <line nr="14" mi="0" ci="3" mb="0" cb="0"/> + <line nr="16" mi="2" ci="28" mb="2" cb="2"/> + <line nr="17" mi="0" ci="1" mb="0" cb="0"/> + <line nr="19" mi="0" ci="4" mb="0" cb="0"/> + <line nr="20" mi="0" ci="16" mb="0" cb="0"/> + <line nr="21" mi="0" ci="18" mb="0" cb="0"/> + <line nr="22" mi="0" ci="12" mb="0" cb="0"/> + <line nr="23" mi="0" ci="5" mb="0" cb="0"/> + <line nr="24" mi="0" ci="14" mb="0" cb="2"/> + <line nr="25" mi="1" ci="22" mb="2" cb="6"/> + <line nr="26" mi="0" ci="9" mb="0" cb="0"/> + <line nr="28" mi="0" ci="7" mb="0" cb="0"/> + <line nr="29" mi="0" ci="1" mb="0" cb="0"/> + <line nr="32" mi="0" ci="2" mb="0" cb="0"/> + <line nr="34" mi="0" ci="13" mb="0" cb="0"/> + <line nr="36" mi="2" ci="0" mb="0" cb="0"/> + <line nr="37" mi="9" ci="0" mb="0" cb="0"/> + <line nr="38" mi="37" ci="0" mb="4" cb="0"/> + <line nr="39" mi="3" ci="0" mb="0" cb="0"/> + <line nr="40" mi="1" ci="0" mb="0" cb="0"/> + <line nr="43" mi="0" ci="7" mb="1" cb="1"/> + <line nr="44" mi="20" ci="0" mb="2" cb="0"/> + <line nr="46" mi="0" ci="2" mb="0" cb="0"/> + <line nr="49" mi="0" ci="7" mb="0" cb="0"/> + <line nr="50" mi="0" ci="1" mb="0" cb="0"/> + <line nr="53" mi="0" ci="5" mb="0" cb="0"/> + <line nr="54" mi="0" ci="3" mb="0" cb="0"/> + <line nr="55" mi="0" ci="18" mb="0" cb="4"/> + <line nr="56" mi="0" ci="3" mb="0" cb="0"/> + <line nr="57" mi="0" ci="1" mb="0" cb="0"/> + <line nr="58" mi="0" ci="3" mb="0" cb="0"/> + <line nr="59" mi="0" ci="3" mb="0" cb="0"/> + <line nr="60" mi="0" ci="5" mb="0" cb="0"/> + <line nr="62" mi="0" ci="1" mb="0" cb="0"/> + <line nr="64" mi="0" ci="6" mb="0" cb="0"/> + <line nr="65" mi="0" ci="2" mb="0" cb="0"/> + <line nr="69" mi="2" ci="5" mb="0" cb="0"/> + <line nr="70" mi="17" ci="14" mb="3" cb="1"/> + <line nr="71" mi="1" ci="8" mb="0" cb="0"/> + <line nr="72" mi="0" ci="20" mb="0" cb="0"/> + <line nr="73" mi="0" ci="16" mb="0" cb="2"/> + <line nr="74" mi="0" ci="22" mb="0" cb="0"/> + <line nr="75" mi="2" ci="3" mb="1" cb="1"/> + <line nr="76" mi="0" ci="2" mb="0" cb="0"/> + <line nr="77" mi="0" ci="19" mb="0" cb="2"/> + <line nr="78" mi="0" ci="1" mb="0" cb="0"/> + <line nr="79" mi="0" ci="13" mb="0" cb="2"/> + <line nr="80" mi="0" ci="5" mb="0" cb="0"/> + <line nr="81" mi="0" ci="4" mb="0" cb="0"/> + <line nr="83" mi="0" ci="4" mb="0" cb="0"/> + <line nr="84" mi="0" ci="12" mb="0" cb="0"/> + <line nr="85" mi="0" ci="10" mb="0" cb="2"/> + <line nr="86" mi="0" ci="7" mb="0" cb="0"/> + <line nr="87" mi="0" ci="9" mb="0" cb="0"/> + <line nr="94" mi="0" ci="10" mb="0" cb="2"/> + <line nr="95" mi="0" ci="5" mb="0" cb="0"/> + <line nr="96" mi="0" ci="4" mb="0" cb="0"/> + <line nr="98" mi="0" ci="9" mb="0" cb="0"/> + <line nr="99" mi="0" ci="12" mb="0" cb="0"/> + <line nr="100" mi="0" ci="10" mb="0" cb="2"/> + <line nr="101" mi="0" ci="7" mb="0" cb="0"/> + <line nr="102" mi="0" ci="4" mb="0" cb="0"/> + <line nr="103" mi="0" ci="9" mb="0" cb="0"/> + <line nr="104" mi="0" ci="10" mb="0" cb="2"/> + <line nr="105" mi="0" ci="5" mb="0" cb="0"/> + <line nr="106" mi="0" ci="10" mb="0" cb="0"/> + <line nr="107" mi="0" ci="4" mb="0" cb="0"/> + <line nr="108" mi="0" ci="3" mb="0" cb="2"/> + <line nr="109" mi="0" ci="2" mb="0" cb="0"/> + <line nr="110" mi="0" ci="5" mb="0" cb="0"/> + <line nr="111" mi="0" ci="2" mb="0" cb="0"/> + <line nr="113" mi="0" ci="1" mb="0" cb="0"/> + <line nr="114" mi="0" ci="7" mb="0" cb="0"/> + <line nr="116" mi="0" ci="3" mb="0" cb="0"/> + <line nr="117" mi="0" ci="12" mb="0" cb="0"/> + <line nr="118" mi="0" ci="26" mb="0" cb="0"/> + <line nr="119" mi="0" ci="10" mb="0" cb="2"/> + <line nr="120" mi="0" ci="7" mb="0" cb="0"/> + <line nr="122" mi="0" ci="3" mb="0" cb="0"/> + <line nr="123" mi="0" ci="9" mb="0" cb="0"/> + <line nr="124" mi="0" ci="14" mb="0" cb="2"/> + <line nr="125" mi="0" ci="2" mb="0" cb="0"/> + <line nr="126" mi="0" ci="3" mb="0" cb="0"/> + <counter type="INSTRUCTION" missed="98" covered="642"/> + <counter type="BRANCH" missed="16" covered="38"/> + <counter type="LINE" missed="6" covered="81"/> + <counter type="COMPLEXITY" missed="15" covered="20"/> + <counter type="METHOD" missed="3" covered="5"/> + <counter type="CLASS" missed="2" covered="2"/> + </sourcefile> + </package> + <package name="com/example/models"> + <sourcefile name="Thing.kt"> + <line nr="9" mi="0" ci="8" mb="0" cb="0"/> + <line nr="10" mi="4" ci="3" mb="0" cb="0"/> + <line nr="11" mi="3" ci="0" mb="0" cb="0"/> + <line nr="14" mi="0" ci="8" mb="0" cb="2"/> + <line nr="15" mi="9" ci="3" mb="1" cb="1"/> + <line nr="16" mi="0" ci="1" mb="0" cb="0"/> + <line nr="19" mi="0" ci="8" mb="0" cb="0"/> + <line nr="20" mi="4" ci="3" mb="0" cb="0"/> + <line nr="21" mi="3" ci="0" mb="0" cb="0"/> + <line nr="24" mi="5" ci="3" mb="1" cb="1"/> + <line nr="25" mi="9" ci="3" mb="1" cb="1"/> + <line nr="26" mi="0" ci="1" mb="0" cb="0"/> + <line nr="29" mi="0" ci="11" mb="0" cb="0"/> + <line nr="30" mi="0" ci="3" mb="0" cb="0"/> + <line nr="31" mi="4" ci="3" mb="0" cb="0"/> + <line nr="32" mi="4" ci="3" mb="0" cb="0"/> + <line nr="35" mi="0" ci="12" mb="0" cb="2"/> + <line nr="36" mi="0" ci="12" mb="0" cb="2"/> + <line nr="37" mi="0" ci="1" mb="0" cb="0"/> + <line nr="40" mi="0" ci="5" mb="0" cb="0"/> + <line nr="41" mi="4" ci="3" mb="0" cb="0"/> + <line nr="44" mi="9" ci="3" mb="1" cb="1"/> + <line nr="45" mi="0" ci="1" mb="0" cb="0"/> + <line nr="48" mi="0" ci="12" mb="0" cb="0"/> + <line nr="49" mi="0" ci="3" mb="0" cb="0"/> + <line nr="50" mi="0" ci="3" mb="0" cb="0"/> + <line nr="51" mi="3" ci="0" mb="0" cb="0"/> + <counter type="INSTRUCTION" missed="61" covered="119"/> + <counter type="BRANCH" missed="4" covered="10"/> + <counter type="LINE" missed="3" covered="24"/> + <counter type="COMPLEXITY" missed="12" covered="16"/> + <counter type="METHOD" missed="8" covered="13"/> + <counter type="CLASS" missed="0" covered="5"/> + </sourcefile> + </package> + <package name="com/example/generated"> + <sourcefile name="Untracked.kt"> + <line nr="12" mi="8" ci="0" mb="0" cb="0"/> + <line nr="17" mi="6" ci="0" mb="0" cb="0"/> + <line nr="20" mi="8" ci="0" mb="0" cb="0"/> + <line nr="21" mi="2" ci="0" mb="0" cb="0"/> + <line nr="22" mi="3" ci="0" mb="0" cb="0"/> + <line nr="23" mi="4" ci="0" mb="0" cb="0"/> + <line nr="24" mi="13" ci="0" mb="0" cb="0"/> + <line nr="27" mi="7" ci="0" mb="0" cb="0"/> + <line nr="28" mi="5" ci="0" mb="4" cb="0"/> + <line nr="29" mi="19" ci="0" mb="0" cb="0"/> + <line nr="30" mi="4" ci="0" mb="0" cb="0"/> + <line nr="31" mi="3" ci="0" mb="0" cb="0"/> + <line nr="32" mi="1" ci="0" mb="0" cb="0"/> + <line nr="33" mi="1" ci="0" mb="0" cb="0"/> + <line nr="34" mi="2" ci="0" mb="0" cb="0"/> + <line nr="35" mi="2" ci="0" mb="0" cb="0"/> + <line nr="39" mi="23" ci="0" mb="0" cb="0"/> + <line nr="40" mi="3" ci="0" mb="0" cb="0"/> + <line nr="41" mi="3" ci="0" mb="0" cb="0"/> + <line nr="42" mi="1" ci="0" mb="0" cb="0"/> + <line nr="43" mi="5" ci="0" mb="0" cb="0"/> + <line nr="44" mi="3" ci="0" mb="2" cb="0"/> + <line nr="45" mi="21" ci="0" mb="0" cb="0"/> + <line nr="46" mi="13" ci="0" mb="0" cb="0"/> + <line nr="48" mi="1" ci="0" mb="0" cb="0"/> + <line nr="51" mi="9" ci="0" mb="0" cb="0"/> + <line nr="52" mi="2" ci="0" mb="0" cb="0"/> + <line nr="53" mi="3" ci="0" mb="0" cb="0"/> + <line nr="54" mi="4" ci="0" mb="0" cb="0"/> + <line nr="55" mi="13" ci="0" mb="0" cb="0"/> + <line nr="58" mi="7" ci="0" mb="0" cb="0"/> + <line nr="59" mi="5" ci="0" mb="4" cb="0"/> + <line nr="60" mi="19" ci="0" mb="0" cb="0"/> + <line nr="61" mi="4" ci="0" mb="0" cb="0"/> + <line nr="62" mi="3" ci="0" mb="0" cb="0"/> + <line nr="63" mi="1" ci="0" mb="0" cb="0"/> + <line nr="64" mi="1" ci="0" mb="0" cb="0"/> + <line nr="65" mi="2" ci="0" mb="0" cb="0"/> + <line nr="66" mi="2" ci="0" mb="0" cb="0"/> + <line nr="70" mi="23" ci="0" mb="0" cb="0"/> + <line nr="71" mi="1" ci="0" mb="0" cb="0"/> + <line nr="72" mi="2" ci="0" mb="0" cb="0"/> + <line nr="73" mi="3" ci="0" mb="0" cb="0"/> + <line nr="74" mi="1" ci="0" mb="0" cb="0"/> + <line nr="75" mi="5" ci="0" mb="0" cb="0"/> + <line nr="76" mi="3" ci="0" mb="2" cb="0"/> + <line nr="77" mi="21" ci="0" mb="0" cb="0"/> + <line nr="78" mi="13" ci="0" mb="0" cb="0"/> + <line nr="80" mi="1" ci="0" mb="0" cb="0"/> + <line nr="82" mi="1" ci="0" mb="0" cb="0"/> + <line nr="84" mi="15" ci="0" mb="0" cb="0"/> + <line nr="87" mi="1" ci="5" mb="0" cb="0"/> + <line nr="89" mi="0" ci="5" mb="0" cb="0"/> + <line nr="90" mi="0" ci="6" mb="0" cb="0"/> + <line nr="91" mi="0" ci="8" mb="0" cb="0"/> + <line nr="92" mi="0" ci="8" mb="0" cb="0"/> + <line nr="93" mi="0" ci="8" mb="0" cb="0"/> + <line nr="94" mi="0" ci="8" mb="0" cb="0"/> + <line nr="95" mi="0" ci="8" mb="0" cb="0"/> + <line nr="96" mi="0" ci="8" mb="0" cb="0"/> + <line nr="97" mi="0" ci="8" mb="0" cb="0"/> + <line nr="98" mi="0" ci="8" mb="0" cb="0"/> + <line nr="99" mi="0" ci="8" mb="0" cb="0"/> + <line nr="100" mi="0" ci="9" mb="0" cb="0"/> + <line nr="101" mi="0" ci="8" mb="0" cb="0"/> + <line nr="102" mi="0" ci="8" mb="0" cb="0"/> + <line nr="103" mi="0" ci="7" mb="0" cb="0"/> + <line nr="107" mi="2" ci="8" mb="0" cb="0"/> + <line nr="108" mi="0" ci="8" mb="0" cb="0"/> + <line nr="109" mi="0" ci="8" mb="0" cb="0"/> + <line nr="110" mi="0" ci="3" mb="0" cb="0"/> + <line nr="113" mi="2" ci="9" mb="0" cb="0"/> + <line nr="114" mi="0" ci="8" mb="0" cb="0"/> + <line nr="115" mi="0" ci="8" mb="0" cb="0"/> + <line nr="116" mi="0" ci="8" mb="0" cb="0"/> + <line nr="117" mi="0" ci="8" mb="0" cb="0"/> + <line nr="118" mi="0" ci="8" mb="0" cb="0"/> + <line nr="119" mi="0" ci="8" mb="0" cb="0"/> + <line nr="120" mi="0" ci="3" mb="0" cb="0"/> + <counter type="INSTRUCTION" missed="345" covered="212"/> + <counter type="BRANCH" missed="12" covered="0"/> + <counter type="LINE" missed="51" covered="28"/> + <counter type="COMPLEXITY" missed="19" covered="1"/> + <counter type="METHOD" missed="13" covered="1"/> + <counter type="CLASS" missed="9" covered="1"/> + </sourcefile> + </package> +</report> diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts new file mode 100644 index 0000000000..72d4018f94 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { parseString } from 'xml2js'; +import fs from 'fs'; +import { Cobertura } from './cobertura'; +import { CoberturaXML } from './types'; +import { getVoidLogger } from '@backstage/backend-common'; + +/* eslint-disable no-restricted-syntax */ + +describe('convert cobertura', () => { + const converter = new Cobertura(getVoidLogger()); + [1, 2, 3, 4, 5].forEach(idx => { + let fixture: CoberturaXML; + parseString( + fs.readFileSync( + `${__dirname}/../__fixtures__/cobertura-testdata-${idx}.xml`, + ), + (_e, r) => { + fixture = r; + }, + ); + const expected = JSON.parse( + fs + .readFileSync( + `${__dirname}/../__fixtures__/cobertura-jsoncoverage-files-${idx}.json`, + ) + .toString(), + ); + const scmFiles = fs + .readFileSync( + `${__dirname}/../__fixtures__/cobertura-sourcefiles-${idx}.txt`, + ) + .toString() + .split('\n'); + + it(`${idx} converts a cobertura report`, () => { + const files = converter.convert(fixture, scmFiles); + + expect(files).toEqual(expected); + }); + }); +}); diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.ts new file mode 100644 index 0000000000..72eeb25b56 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/cobertura.ts @@ -0,0 +1,126 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { BranchHit, FileEntry } from '../jsoncoverage-types'; +import { CoberturaXML, InnerClass, LineHit } from './types'; +import { Logger } from 'winston'; +import { Converter } from '.'; + +export class Cobertura extends Converter { + constructor(readonly logger: Logger) { + super(logger); + } + + /** + * convert cobertura into shared json coverage format + * + * @param xml cobertura xml object + * @param scmFiles list of files that are commited to SCM + */ + convert(xml: CoberturaXML, scmFiles: string[]): FileEntry[] { + const ppc = xml.coverage.packages + ?.flatMap(p => p.package) + .filter(Boolean) + .flatMap(p => p.classes); + const pc = xml.coverage.package?.filter(Boolean).flatMap(p => p.classes); + + const classes = [ppc, pc] + .flat() + .filter(Boolean) + .flatMap(c => c.class) + .filter(Boolean); + const jscov: Array<FileEntry> = []; + + classes.forEach(c => { + const packageAndFilename = c.$.filename; + const lines = this.extractLines(c); + const lineHits: Record<number, number> = {}; + const branchHits: Record<number, BranchHit> = {}; + + lines.forEach(l => { + if (!lineHits[l.number]) { + lineHits[l.number] = 0; + } + lineHits[l.number] += l.hits; + if (l.branch && l['condition-coverage']) { + const bh = this.parseBranch(l['condition-coverage']); + if (bh) { + branchHits[l.number] = bh; + } + } + }); + + const currentFile = scmFiles.find(f => f.endsWith(packageAndFilename)); + this.logger.info(`matched ${packageAndFilename} to ${currentFile}`); + if ( + scmFiles.length === 0 || + (Object.keys(lineHits).length > 0 && currentFile) + ) { + jscov.push({ + filename: currentFile || packageAndFilename, + branchHits: branchHits, + lineHits: lineHits, + }); + } + }); + + return jscov; + } + + /** + * Parses branch coverage information from condition-coverage + * + * @param condition condition-coverage value from line coverage + */ + private parseBranch(condition: string): BranchHit | null { + const pattern = /[0-9\.]+\%\s\(([0-9]+)\/([0-9]+)\)/; + const match = condition.match(pattern); + if (!match) { + return null; + } + const covered = parseInt(match[1], 10); + const available = parseInt(match[2], 10); + return { + covered: covered, + missed: available - covered, + available: available, + }; + } + + /** + * Extract line hits from a class coverage entry + * + * @param clz class coverage information + */ + private extractLines(clz: InnerClass): Array<LineHit> { + const classLines = clz.lines.flatMap(l => l.line); + const methodLines = clz.methods + ?.flatMap(m => m.method) + .filter(Boolean) + .flatMap(m => m.lines) + .filter(Boolean) + .flatMap(l => l.line); + const lines = [classLines, methodLines].flat().filter(Boolean); + const lineHits = lines.map(l => { + return { + number: parseInt((l.$.number as unknown) as string, 10), + hits: parseInt((l.$.hits as unknown) as string, 10), + 'condition-coverage': l.$['condition-coverage'], + branch: l.$.branch, + }; + }); + return lineHits; + } +} diff --git a/plugins/code-coverage-backend/src/service/converter/index.ts b/plugins/code-coverage-backend/src/service/converter/index.ts new file mode 100644 index 0000000000..083af10f68 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Logger } from 'winston'; +import { FileEntry } from '../jsoncoverage-types'; + +export abstract class Converter { + constructor(readonly logger: Logger) {} + + abstract convert(xml: any, scmFiles: Array<string>): Array<FileEntry>; +} diff --git a/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts b/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts new file mode 100644 index 0000000000..48202748da --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { parseString } from 'xml2js'; +import fs from 'fs'; +import { Jacoco } from './jacoco'; +import { JacocoXML } from './types'; +import { getVoidLogger } from '@backstage/backend-common'; + +/* eslint-disable no-restricted-syntax */ + +describe('convert jacoco', () => { + const converter = new Jacoco(getVoidLogger()); + let fixture: JacocoXML; + parseString( + fs.readFileSync(`${__dirname}/../__fixtures__/jacoco-testdata-1.xml`), + (_e, r) => { + fixture = r; + }, + ); + const expected = JSON.parse( + fs + .readFileSync( + `${__dirname}/../__fixtures__/jacoco-jsoncoverage-files-1.json`, + ) + .toString(), + ); + const scmFiles = fs + .readFileSync(`${__dirname}/../__fixtures__/jacoco-sourcefiles-1.txt`) + .toString() + .split('\n'); + + it('converts a jacoco report', () => { + const files = converter.convert(fixture, scmFiles); + + expect(files.sort()).toEqual(expected.sort()); + }); +}); diff --git a/plugins/code-coverage-backend/src/service/converter/jacoco.ts b/plugins/code-coverage-backend/src/service/converter/jacoco.ts new file mode 100644 index 0000000000..fe60f9378c --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/jacoco.ts @@ -0,0 +1,96 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { BranchHit, FileEntry } from '../jsoncoverage-types'; +import { JacocoSourceFile, JacocoXML } from './types'; +import { Logger } from 'winston'; +import { Converter } from '.'; + +type ParsedLine = { + number: number; + missed_instructions: number; + covered_instructions: number; + missed_branches: number; + covered_branches: number; +}; + +export class Jacoco extends Converter { + constructor(readonly logger: Logger) { + super(logger); + } + + /** + * Converts jacoco into shared json coverage format + * + * @param xml jacoco xml object + * @param scmFiles list of files that are commited to SCM + */ + convert(xml: JacocoXML, scmFiles: Array<string>): Array<FileEntry> { + const jscov: Array<FileEntry> = []; + + xml.report.package.forEach(r => { + const packageName = r.$.name; + r.sourcefile.forEach(sf => { + const fileName = sf.$.name; + const lines = this.extractLines(sf); + const lineHits: Record<number, number> = {}; + const branchHits: Record<number, BranchHit> = {}; + lines.forEach(l => { + if (!lineHits[l.number]) { + lineHits[l.number] = 0; + } + lineHits[l.number] += l.covered_instructions; + const ab = l.covered_branches + l.missed_branches; + if (ab > 0) { + branchHits[l.number] = { + covered: l.covered_branches, + missed: l.missed_branches, + available: ab, + }; + } + }); + + const packageAndFilename = `${packageName}/${fileName}`; + const currentFile = scmFiles.find(f => f.endsWith(packageAndFilename)); + this.logger.info(`matched ${packageAndFilename} to ${currentFile}`); + if (Object.keys(lineHits).length > 0 && currentFile) { + jscov.push({ + filename: currentFile, + branchHits: branchHits, + lineHits: lineHits, + }); + } + }); + }); + + return jscov; + } + + private extractLines(sourcefile: JacocoSourceFile): ParsedLine[] { + const parsed: ParsedLine[] = []; + + sourcefile.line.forEach(l => { + parsed.push({ + number: parseInt(l.$.nr, 10), + missed_instructions: parseInt(l.$.mi, 10), + covered_instructions: parseInt(l.$.ci, 10), + missed_branches: parseInt(l.$.mb, 10), + covered_branches: parseInt(l.$.cb, 10), + }); + }); + + return parsed; + } +} diff --git a/plugins/code-coverage-backend/src/service/converter/types.ts b/plugins/code-coverage-backend/src/service/converter/types.ts new file mode 100644 index 0000000000..35e70faae4 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/types.ts @@ -0,0 +1,92 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// *** Cobertura *** +export type CoberturaXML = { + coverage: Coverage; +}; + +export type Coverage = { + packages: Array<Package>; + package: Array<InnerPackage>; +}; + +export type Package = { + package: Array<InnerPackage>; +}; + +export type InnerPackage = { + classes: Array<Class>; +}; +export type Class = { + class: Array<InnerClass>; +}; +export type InnerClass = { + $: { + filename: string; + }; + lines: Array<Line>; + methods: Array<Method>; +}; +export type Method = { + method: Array<InnerMethod>; +}; +export type InnerMethod = { + lines: Array<Line>; +}; +export type Line = { + line: Array<InnerLine>; +}; + +export type InnerLine = { + $: LineHit; +}; + +export type LineHit = { + branch?: boolean; + 'condition-coverage'?: string; + number: number; + hits: number; +}; + +// *** Jacoco *** +export type JacocoXML = { + report: JacocoReport; +}; +export type JacocoReport = { + package: JacocoPackage[]; +}; +export type JacocoPackage = { + $: { + name: string; + }; + sourcefile: JacocoSourceFile[]; +}; +export type JacocoSourceFile = { + $: { + name: string; + }; + line: JacocoLine[]; +}; +export type JacocoLine = { + $: { + nr: string; + mi: string; + ci: string; + mb: string; + cb: string; + }; +}; diff --git a/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts b/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts new file mode 100644 index 0000000000..f1ef3dd694 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts @@ -0,0 +1,71 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { EntityName } from '@backstage/catalog-model'; + +export type JsonCodeCoverage = { + metadata: CoverageMetadata; + entity: EntityName; + files: Array<FileEntry>; +}; + +export type JsonCoverageHistory = { + entity: EntityName; + history: Array<CoverageHistory>; +}; + +export type CoverageHistory = { + line: { + available: number; + covered: number; + }; + branch: BranchHit; +}; + +export type CoverageMetadata = { + vcs: { + type: string; + location: string; + }; + generationTime: number; +}; + +export type BranchHit = { + covered: number; + missed: number; + available: number; +}; + +export type FileEntry = { + filename: string; + lineHits: Record<number, number>; + branchHits: Record<number, BranchHit>; +}; + +export type AggregateCoverage = { + timestamp: number; + line: { + available: number; + covered: number; + missed: number; + percentage: number; + }; + branch: { + available: number; + covered: number; + missed: number; + percentage: number; + }; +}; diff --git a/plugins/code-coverage-backend/src/service/router.test.ts b/plugins/code-coverage-backend/src/service/router.test.ts new file mode 100644 index 0000000000..e18cd75c2f --- /dev/null +++ b/plugins/code-coverage-backend/src/service/router.test.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import express from 'express'; +import request from 'supertest'; +import { + getVoidLogger, + PluginDatabaseManager, + PluginEndpointDiscovery, + SingleConnectionDatabaseManager, + UrlReaders, +} from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { createRouter } from './router'; + +function createDatabase(): PluginDatabaseManager { + return SingleConnectionDatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'sqlite3', + connection: ':memory:', + }, + }, + }), + ).forPlugin('code-coverage'); +} + +const testDiscovery: jest.Mocked<PluginEndpointDiscovery> = { + getBaseUrl: jest + .fn() + .mockResolvedValue('http://localhost:7000/api/code-coverage'), + getExternalBaseUrl: jest.fn(), +}; +const mockUrlReader = UrlReaders.default({ + logger: getVoidLogger(), + config: new ConfigReader({}), +}); + +describe('createRouter', () => { + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter({ + config: new ConfigReader({}), + database: createDatabase(), + discovery: testDiscovery, + urlReader: mockUrlReader, + logger: getVoidLogger(), + }); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /health', () => { + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); +}); diff --git a/plugins/code-coverage-backend/src/service/router.ts b/plugins/code-coverage-backend/src/service/router.ts new file mode 100644 index 0000000000..3f3dcf8a1e --- /dev/null +++ b/plugins/code-coverage-backend/src/service/router.ts @@ -0,0 +1,229 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; +import xmlparser from 'express-xml-bodyparser'; +import { CatalogClient } from '@backstage/catalog-client'; +import { + errorHandler, + PluginDatabaseManager, + PluginEndpointDiscovery, + UrlReader, +} from '@backstage/backend-common'; +import { InputError, NotFoundError } from '@backstage/errors'; +import { Config } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import { CodeCoverageDatabase } from './CodeCoverageDatabase'; +import { aggregateCoverage, CoverageUtils } from './CoverageUtils'; +import { Cobertura } from './converter/cobertura'; +import { Jacoco } from './converter/jacoco'; +import { Converter } from './converter'; + +export interface RouterOptions { + config: Config; + discovery: PluginEndpointDiscovery; + database: PluginDatabaseManager; + urlReader: UrlReader; + logger: Logger; +} + +export interface CodeCoverageApi { + name: string; +} + +export const makeRouter = async ( + options: RouterOptions, +): Promise<express.Router> => { + const { config, logger, discovery, database, urlReader } = options; + + const codeCoverageDatabase = await CodeCoverageDatabase.create( + await database.getClient(), + logger, + ); + const codecovUrl = await discovery.getExternalBaseUrl('code-coverage'); + const catalogApi = new CatalogClient({ discoveryApi: discovery }); + const scm = ScmIntegrations.fromConfig(config); + + const router = Router(); + router.use(xmlparser()); + router.use(express.json()); + + const utils = new CoverageUtils(scm, urlReader); + + router.get('/health', async (_req, res) => { + res.status(200).json({ status: 'ok' }); + }); + + router.get('/:kind/:namespace/:name', async (req, res) => { + const { kind, namespace, name } = req.params; + const entity = await catalogApi.getEntityByName({ kind, namespace, name }); + if (!entity) { + throw new NotFoundError( + `No entity found matching ${kind}/${namespace}/${name}`, + ); + } + const stored = await codeCoverageDatabase.getCodeCoverage({ + kind, + namespace, + name, + }); + + const aggregate = aggregateCoverage(stored); + + res.status(200).json({ + ...stored, + aggregate: { + line: aggregate.line, + branch: aggregate.branch, + }, + }); + }); + + router.get('/:kind/:namespace/:name/history', async (req, res) => { + const { kind, namespace, name } = req.params; + const entity = await catalogApi.getEntityByName({ kind, namespace, name }); + if (!entity) { + throw new NotFoundError( + `No entity found matching ${kind}/${namespace}/${name}`, + ); + } + const { limit } = req.query; + const history = await codeCoverageDatabase.getHistory( + { + kind, + namespace, + name, + }, + parseInt(limit?.toString() || '10', 10), + ); + + res.status(200).json(history); + }); + + router.get('/:kind/:namespace/:name/file-content', async (req, res) => { + const { kind, namespace, name } = req.params; + const entity = await catalogApi.getEntityByName({ kind, namespace, name }); + if (!entity) { + throw new NotFoundError( + `No entity found matching ${kind}/${namespace}/${name}`, + ); + } + const { path } = req.query; + if (!path) { + throw new InputError('Need path query parameter'); + } + + const sourceLocation = + entity.metadata.annotations?.['backstage.io/source-location']; + if (!sourceLocation) { + throw new InputError( + `No "backstage.io/source-location" annotation on entity ${entity.kind}/${entity.metadata.namespace}/${entity.metadata.name}`, + ); + } + + const vcs = scm.byUrl(sourceLocation); + if (!vcs) { + throw new InputError(`Unable to determine SCM from ${sourceLocation}`); + } + + const scmTree = await urlReader.readTree(sourceLocation); + const scmFile = (await scmTree.files()).find(f => f.path === path); + if (!scmFile) { + res.status(400).json({ + message: "couldn't find file in SCM", + file: path, + scm: vcs.title, + }); + return; + } + const content = await scmFile?.content(); + if (!content) { + res.status(400).json({ + message: "couldn't process content of file in SCM", + file: path, + scm: vcs.title, + }); + return; + } + + const data = content.toString(); + res.status(200).contentType('text/plain').send(data); + }); + + router.post('/:kind/:namespace/:name/', async (req, res) => { + const { kind, namespace, name } = req.params; + const { coverageType } = req.query; + let converter: Converter; + if (!coverageType) { + throw new InputError('Need coverageType query parameter'); + } else if (coverageType === 'jacoco') { + converter = new Jacoco(logger); + } else if (coverageType === 'cobertura') { + converter = new Cobertura(logger); + } else { + throw new NotFoundError(`unsupported coverage type '${coverageType}`); + } + const entity = await catalogApi.getEntityByName({ kind, namespace, name }); + if (!entity) { + throw new NotFoundError( + `No entity found matching ${kind}/${namespace}/${name}`, + ); + } + const { + sourceLocation, + vcs, + scmFiles, + body, + } = await utils.processCoveragePayload(entity, req); + + const files = converter.convert(body, scmFiles); + if (!files || files.length === 0) { + throw new InputError(`Unable to parse body as ${coverageType}`); + } + + const coverage = await utils.buildCoverage( + entity, + sourceLocation, + vcs, + files, + ); + await codeCoverageDatabase.insertCodeCoverage(coverage); + + res.status(201).json({ + links: [ + { + rel: 'coverage', + href: `${codecovUrl}/${kind}/${namespace}/${name}`, + }, + ], + }); + }); + + router.use(errorHandler()); + return router; +}; + +export async function createRouter( + options: RouterOptions, +): Promise<express.Router> { + const logger = options.logger; + + logger.info('Initializing Code Coverage backend'); + + return makeRouter(options); +} diff --git a/plugins/code-coverage-backend/src/service/standaloneServer.ts b/plugins/code-coverage-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..8a3c4eaea1 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/standaloneServer.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceBuilder, + loadBackendConfig, + SingleHostDiscovery, + UrlReaders, + useHotMemoize, +} from '@backstage/backend-common'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; +import { DatabaseManager } from '@backstage/plugin-catalog-backend'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise<Server> { + const logger = options.logger.child({ service: 'code-coverage-backend' }); + const config = await loadBackendConfig({ logger, argv: process.argv }); + + const db = useHotMemoize(module, () => + DatabaseManager.createInMemoryDatabaseConnection(), + ); + + logger.debug('Starting application server...'); + const router = await createRouter({ + database: { getClient: () => db }, + config, + discovery: SingleHostDiscovery.fromConfig(config), + urlReader: UrlReaders.default({ logger, config }), + logger, + }); + + const service = createServiceBuilder(module) + .enableCors({ origin: 'http://localhost:3000' }) + .addRouter('/code-coverage', router); + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/code-coverage-backend/src/setupTests.ts b/plugins/code-coverage-backend/src/setupTests.ts new file mode 100644 index 0000000000..ba33cf996b --- /dev/null +++ b/plugins/code-coverage-backend/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; diff --git a/plugins/code-coverage/.eslintrc.js b/plugins/code-coverage/.eslintrc.js new file mode 100644 index 0000000000..13573efa9c --- /dev/null +++ b/plugins/code-coverage/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint')], +}; diff --git a/plugins/code-coverage/README.md b/plugins/code-coverage/README.md new file mode 100644 index 0000000000..b93ad7a091 --- /dev/null +++ b/plugins/code-coverage/README.md @@ -0,0 +1,19 @@ +# code-coverage + +This is the frontend part of the code-coverage plugin. It takes care of processing various coverage formats and standardizing them into a single json format, used by the frontend. + +## Configuring your entity + +In order to use this plugin, you must set the `backstage.io/code-coverage` annotation. + +```yaml +backstage.io/code-coverage: enabled +``` + +There's a feature to only include files that are in VCS in the coverage report, this is helpful to not count generated files for example. To enable this set the `backstage.io/code-coverage` annotation to `scm-only`. + +```yaml +backstage.io/code-coverage: scm-only +``` + +Note: This requires the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) to be set. diff --git a/plugins/code-coverage/dev/index.tsx b/plugins/code-coverage/dev/index.tsx new file mode 100644 index 0000000000..9eabafb976 --- /dev/null +++ b/plugins/code-coverage/dev/index.tsx @@ -0,0 +1,26 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { codeCoveragePlugin, CodeCoveragePage } from '../src/plugin'; + +createDevApp() + .registerPlugin(codeCoveragePlugin) + .addPage({ + element: <CodeCoveragePage />, + title: 'Root Page', + }) + .render(); diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json new file mode 100644 index 0000000000..75be2cab92 --- /dev/null +++ b/plugins/code-coverage/package.json @@ -0,0 +1,57 @@ +{ + "name": "@backstage/plugin-code-coverage", + "version": "0.1.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "build": "backstage-cli plugin:build", + "start": "backstage-cli plugin:serve", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "diff": "backstage-cli plugin:diff", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", + "@backstage/core": "^0.6.2", + "@backstage/core-api": "^0.2.12", + "@backstage/dev-utils": "^0.1.11", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/theme": "^0.2.3", + "@material-ui/core": "^4.11.0", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.45", + "@types/highlightjs": "^10.1.0", + "highlight.js": "^10.6.0", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router": "6.0.0-beta.0", + "react-router-dom": "6.0.0-beta.0", + "react-use": "^15.3.3", + "recharts": "^1.8.5" + }, + "devDependencies": { + "@backstage/cli": "^0.6.1", + "@backstage/test-utils": "^0.1.7", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^10.4.1", + "@testing-library/user-event": "^12.0.7", + "@types/jest": "^26.0.7", + "@types/node": "^12.0.0", + "@types/recharts": "^1.8.15", + "cross-fetch": "^3.0.6", + "msw": "^0.21.2" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts new file mode 100644 index 0000000000..da18bde267 --- /dev/null +++ b/plugins/code-coverage/src/api.ts @@ -0,0 +1,102 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core'; +import { Config } from '@backstage/config'; +import { EntityName } from '@backstage/catalog-model'; + +export class FetchError extends Error { + get name(): string { + return this.constructor.name; + } + + static async forResponse(resp: Response): Promise<FetchError> { + return new FetchError( + `Request failed with status code ${ + resp.status + }.\nReason: ${await resp.text()}`, + ); + } +} + +export type CodeCoverageApi = { + url: string; + getCoverageForEntity: (entity: EntityName) => Promise<any>; + getFileContentFromEntity: ( + entity: EntityName, + filePath: string, + ) => Promise<any>; + getCoverageHistoryForEntity: ( + entity: EntityName, + limit?: number, + ) => Promise<any>; +}; + +export const codeCoverageApiRef = createApiRef<CodeCoverageApi>({ + id: 'plugin.code-coverage.service', + description: 'Used by the code coverage plugin to make requests', +}); + +export class CodeCoverageRestApi implements CodeCoverageApi { + static fromConfig(config: Config) { + return new CodeCoverageRestApi(config.getString('backend.baseUrl')); + } + + constructor(public url: string) {} + + private async fetch<T = any | string>( + input: string, + init?: RequestInit, + ): Promise<T | string> { + const resp = await fetch(`${this.url}${input}`, init); + if (!resp.ok) throw await FetchError.forResponse(resp); + if (resp.headers.get('content-type')?.includes('application/json')) { + return await resp.json(); + } + return await resp.text(); + } + + async getCoverageForEntity({ + kind, + namespace, + name, + }: EntityName): Promise<any> { + return await this.fetch<any>( + `/api/code-coverage/${kind}/${namespace}/${name}`, + ); + } + + async getFileContentFromEntity( + { kind, namespace, name }: EntityName, + filePath: string, + ): Promise<any> { + return await this.fetch<any>( + `/api/code-coverage/${kind}/${namespace}/${name}/file-content?path=${filePath}`, + ); + } + + async getCoverageHistoryForEntity( + { kind, namespace, name }: EntityName, + limit?: number, + ): Promise<any> { + const hasValidLimit = limit && limit > 0; + return await this.fetch<any>( + `/api/code-coverage/${kind}/${namespace}/${name}/history${ + hasValidLimit ? `?limit=${limit}` : '' + }`, + ); + } +} diff --git a/plugins/code-coverage/src/components/CodeCoveragePage/CodeCoveragePage.tsx b/plugins/code-coverage/src/components/CodeCoveragePage/CodeCoveragePage.tsx new file mode 100644 index 0000000000..47811b93cd --- /dev/null +++ b/plugins/code-coverage/src/components/CodeCoveragePage/CodeCoveragePage.tsx @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Content, ContentHeader, Page } from '@backstage/core'; +import { CoverageHistoryChart } from '../CoverageHistoryChart'; +import { FileExplorer } from '../FileExplorer'; + +export const CodeCoveragePage = () => { + return ( + <Page themeId="tool"> + <Content> + <ContentHeader title="Code coverage" /> + <CoverageHistoryChart /> + <FileExplorer /> + </Content> + </Page> + ); +}; diff --git a/plugins/code-coverage/src/components/CodeCoveragePage/index.ts b/plugins/code-coverage/src/components/CodeCoveragePage/index.ts new file mode 100644 index 0000000000..c5479c0098 --- /dev/null +++ b/plugins/code-coverage/src/components/CodeCoveragePage/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { CodeCoveragePage } from './CodeCoveragePage'; diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx new file mode 100644 index 0000000000..a7bfeceb19 --- /dev/null +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -0,0 +1,169 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { + Box, + Card, + CardContent, + MenuItem, + Select, + Typography, +} from '@material-ui/core'; +import { + LineChart, + XAxis, + YAxis, + Tooltip, + Legend, + Line, + CartesianGrid, + ResponsiveContainer, +} from 'recharts'; +import { useAsync } from 'react-use'; +import { useApi } from '@backstage/core-api'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { codeCoverageApiRef } from '../../api'; +import { Progress } from '@backstage/core'; +import { Alert } from '@material-ui/lab'; +import TrendingDownIcon from '@material-ui/icons/TrendingDown'; +import TrendingUpIcon from '@material-ui/icons/TrendingUp'; +import TrendingFlatIcon from '@material-ui/icons/TrendingFlat'; + +type Coverage = 'line' | 'branch'; + +const getTrendIcon = (trend: number) => { + switch (true) { + case trend > 0: + return <TrendingUpIcon style={{ color: 'green' }} />; + case trend < 0: + return <TrendingDownIcon style={{ color: 'red' }} />; + case trend === 0: + default: + return <TrendingFlatIcon />; + } +}; + +export const CoverageHistoryChart = () => { + const { entity } = useEntity(); + const codeCoverageApi = useApi(codeCoverageApiRef); + const { + loading: loadingHistory, + error: errorHistory, + value: valueHistory, + } = useAsync( + async () => + await codeCoverageApi.getCoverageHistoryForEntity({ + kind: entity.kind, + namespace: entity.metadata.namespace || 'default', + name: entity.metadata.name, + }), + ); + + if (loadingHistory) { + return <Progress />; + } else if (errorHistory) { + return <Alert severity="error">{errorHistory.message}</Alert>; + } + + if (!valueHistory.history.length) { + return ( + <Box> + <Card> + <CardContent> + <Box mb={2} display="flex" justifyContent="space-between"> + <Typography variant="h5">History</Typography> + </Box> + No coverage history found + </CardContent> + </Card> + </Box> + ); + } + + const oldestCoverage = valueHistory.history[0]; + const [latestCoverage] = valueHistory.history.slice(-1); + + const getTrendForCoverage = (type: Coverage) => { + if (!oldestCoverage[type].percentage) { + return 0; + } + return ( + ((latestCoverage[type].percentage - oldestCoverage[type].percentage) / + oldestCoverage[type].percentage) * + 100 + ); + }; + + const lineTrend = getTrendForCoverage('line'); + const branchTrend = getTrendForCoverage('branch'); + + return ( + <Box> + <Card> + <CardContent> + <Box mb={2} display="flex" justifyContent="space-between"> + <Typography variant="h5">History</Typography> + <Select> + <MenuItem>7</MenuItem> + </Select> + </Box> + <Box px={6} display="flex"> + <Box display="flex" mr={4}> + {getTrendIcon(lineTrend)} + <Typography> + Current line: {latestCoverage.line.percentage}%<br />( + {Math.floor(lineTrend)}% change over{' '} + {valueHistory.history.length} builds) + </Typography> + </Box> + <Box display="flex"> + {getTrendIcon(branchTrend)} + <Typography> + Current branch: {latestCoverage.branch.percentage}%<br />( + {Math.floor(branchTrend)}% change over{' '} + {valueHistory.history.length} builds) + </Typography> + </Box> + </Box> + <ResponsiveContainer width="100%" height={300}> + <LineChart + data={valueHistory.history} + margin={{ right: 48, top: 32 }} + > + <CartesianGrid strokeDasharray="3 3" /> + <XAxis dataKey="timestamp" /> + <YAxis dataKey="line.percentage" /> + <YAxis dataKey="branch.percentage" /> + <Tooltip /> + <Legend /> + <Line + type="monotone" + dataKey="branch.percentage" + stroke="#8884d8" + /> + <Line + type="monotone" + dataKey="line.percentage" + stroke="#82ca9d" + /> + </LineChart> + </ResponsiveContainer> + </CardContent> + </Card> + </Box> + ); +}; diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/index.ts b/plugins/code-coverage/src/components/CoverageHistoryChart/index.ts new file mode 100644 index 0000000000..b9dd72e34b --- /dev/null +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { CoverageHistoryChart } from './CoverageHistoryChart'; diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx new file mode 100644 index 0000000000..a4eabf715d --- /dev/null +++ b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx @@ -0,0 +1,103 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { FC } from 'react'; + +// styles +import { makeStyles } from '@material-ui/core'; +import { red, green } from '@material-ui/core/colors'; + +const useStyles = makeStyles(theme => ({ + lineNumberCell: { + color: `${theme.palette.grey[500]}`, + fontSize: '90%', + borderRight: `1px solid ${theme.palette.grey[500]}`, + paddingRight: '8px', + textAlign: 'right', + }, + hitCountCell: { + width: '50px', + borderRight: `1px solid ${theme.palette.grey[500]}`, + textAlign: 'center', + color: 'white', // need to enforce this color since it needs to stand out against colored background + paddingLeft: `${theme.spacing(1)}`, + paddingRight: `${theme.spacing(1)}`, + }, + countRoundedRectangle: { + borderRadius: '45px', + fontSize: '90%', + padding: '1px 3px 1px 3px', + width: '50px', + }, + hitCountRoundedRectangle: { + backgroundColor: `${green[500]}`, + }, + notHitCountRoundedRectangle: { + backgroundColor: `${red[500]}`, + }, + codeLine: { + paddingLeft: `${theme.spacing(1)}`, + whiteSpace: 'pre', + fontSize: '90%', + }, + hitCodeLine: { + backgroundColor: `${green[100]}`, + }, + notHitCodeLine: { + backgroundColor: `${red[100]}`, + }, +})); + +type CodeRowProps = { + lineNumber: number; + lineContent: string; + lineHits?: number | null; +}; +const CodeRow: FC<CodeRowProps> = ({ + lineNumber, + lineContent, + lineHits = null, +}: CodeRowProps) => { + const classes = useStyles(); + const hitCountRoundedRectangleClass = [classes.countRoundedRectangle]; + const lineContentClass = [classes.codeLine]; + + let hitRoundedRectangle = null; + if (lineHits !== null) { + if (lineHits > 0) { + hitCountRoundedRectangleClass.push(classes.hitCountRoundedRectangle); + lineContentClass.push(classes.hitCodeLine); + } else { + hitCountRoundedRectangleClass.push(classes.notHitCountRoundedRectangle); + lineContentClass.push(classes.notHitCodeLine); + } + hitRoundedRectangle = ( + <div className={hitCountRoundedRectangleClass.join(' ')}>{lineHits}</div> + ); + } + + return ( + <tr> + <td className={classes.lineNumberCell}>{lineNumber}</td> + <td className={classes.hitCountCell}>{hitRoundedRectangle}</td> + <td + className={lineContentClass.join(' ')} + dangerouslySetInnerHTML={{ __html: lineContent }} + /> + </tr> + ); +}; + +export default CodeRow; diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx new file mode 100644 index 0000000000..7b1bc2c070 --- /dev/null +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -0,0 +1,137 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { FC, useEffect } from 'react'; +import { useApi } from '@backstage/core-api'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { useAsync } from 'react-use'; +import { codeCoverageApiRef } from '../../api'; +import { Progress } from '@backstage/core'; +import { Alert } from '@material-ui/lab'; +import { makeStyles, Paper } from '@material-ui/core'; +import { highlightLines } from './Highlighter'; +import { FileCoverage } from './FileExplorer'; +import CoverageRow from './CoverageRow'; + +type Props = { + filename: string; + coverage: FileCoverage; +}; + +const getContent = async (value: any) => { + let blob = value; + if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) { + blob = new Blob([value], { type: 'application/octet-stream' }); + } + return value; +}; + +const useStyles = makeStyles(theme => ({ + paper: { + margin: 'auto', + top: '2em', + width: '80%', + backgroundColor: theme.palette.background.paper, + border: '2px solid #000', + boxShadow: theme.shadows[5], + padding: theme.spacing(2, 4, 3), + overflow: 'scroll', + }, + coverageFileViewTable: { + borderSpacing: '0px', + width: '80%', + marginTop: theme.spacing(2), + }, +})); + +type FormattedLinesProps = { + highlightedLines: string[]; + lineHits: Record<number, number>; +}; +const FormattedLines: FC<FormattedLinesProps> = ({ + highlightedLines, + lineHits, +}: FormattedLinesProps) => { + return ( + <> + {highlightedLines.map((lineContent, idx) => { + const line = idx + 1; + return ( + <CoverageRow + key={line} + lineNumber={line} + lineContent={lineContent} + lineHits={lineHits[line]} + /> + ); + })} + </> + ); +}; + +export const FileContent = ({ filename, coverage }: Props) => { + const { entity } = useEntity(); + const codeCoverageApi = useApi(codeCoverageApiRef); + const { loading, error, value } = useAsync( + async () => + await codeCoverageApi.getFileContentFromEntity( + { + kind: entity.kind, + namespace: entity.metadata.namespace || 'default', + name: entity.metadata.name, + }, + filename, + ), + ); + + useEffect(() => { + if (value) getContent(value); + }, [value]); + + const classes = useStyles(); + + if (loading) { + return <Progress />; + } else if (error) { + return <Alert severity="error">{error.message}</Alert>; + } + + const [language] = filename.split('.').slice(-1); + const highlightedLines = highlightLines(language, value.split('\n')); + + // List of formatted nodes containing highlighted code + // lineHits array where lineHits[i] is number of hits for line i + 1 + const lineHits = Object.entries(coverage.lineHits).reduce( + (acc: Record<string, number>, next: [string, number]) => { + acc[next[0]] = next[1]; + return acc; + }, + {}, + ); + + return ( + <Paper variant="outlined" className={classes.paper}> + <table className={classes.coverageFileViewTable}> + <tbody> + <FormattedLines + highlightedLines={highlightedLines} + lineHits={lineHits} + /> + </tbody> + </table> + </Paper> + ); +}; diff --git a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx new file mode 100644 index 0000000000..11baa419f4 --- /dev/null +++ b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx @@ -0,0 +1,280 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useApi } from '@backstage/core-api'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { Progress, Table, TableColumn } from '@backstage/core'; +import { + Box, + Card, + CardContent, + Modal, + Tooltip, + Typography, +} from '@material-ui/core'; +import React, { Fragment, useEffect, useState } from 'react'; +import { useAsync } from 'react-use'; +import { codeCoverageApiRef } from '../../api'; +import { Alert } from '@material-ui/lab'; +import DescriptionIcon from '@material-ui/icons/Description'; +import { FileContent } from './FileContent'; + +export type FileCoverage = { + filename: string; + branchHits: { [branch: number]: number }; + lineHits: { [line: number]: number }; +}; + +type FileStructureObject = Record<string, any>; + +type CoverageTableRow = { + filename?: string; + files: CoverageTableRow[]; + coverage: number; + missing: number; + tracked: number; + path: string; + tableData?: { id: number }; +}; + +const buildFileStructure = (row: CoverageTableRow) => { + const dataGroupedByPath: FileStructureObject = row.files.reduce( + (acc: FileStructureObject, cur: CoverageTableRow) => { + let path = cur.filename; + if (row.path) { + path = path?.split(`${row.path}/`)[1]; + } + const pathArray = path?.split('/'); + + if (!pathArray) { + return acc; + } + if (!acc.hasOwnProperty(pathArray[0])) { + acc[pathArray[0]] = []; + } + acc[pathArray[0]].push(cur); + return acc; + }, + {}, + ); + + row.files = Object.keys(dataGroupedByPath).map(pathGroup => { + return buildFileStructure({ + path: pathGroup, + files: dataGroupedByPath.hasOwnProperty('files') + ? dataGroupedByPath.files + : dataGroupedByPath[pathGroup], + coverage: + dataGroupedByPath[pathGroup].reduce( + (acc: number, cur: CoverageTableRow) => acc + cur.coverage, + 0, + ) / dataGroupedByPath[pathGroup].length, + missing: dataGroupedByPath[pathGroup].reduce( + (acc: number, cur: CoverageTableRow) => acc + cur.missing, + 0, + ), + tracked: dataGroupedByPath[pathGroup].reduce( + (acc: number, cur: CoverageTableRow) => acc + cur.tracked, + 0, + ), + }); + }); + return row; +}; + +const formatInitialData = (value: any) => { + return buildFileStructure({ + path: '', + coverage: value.aggregate.line.percentage, + missing: value.aggregate.line.missed, + tracked: value.aggregate.line.available, + files: value.files.map((fc: FileCoverage) => { + return { + path: '', + filename: fc.filename, + coverage: Math.floor( + (Object.values(fc.lineHits).filter((hits: number) => hits > 0) + .length / + Object.values(fc.lineHits).length) * + 100, + ), + missing: Object.values(fc.lineHits).filter(hits => !hits).length, + tracked: Object.values(fc.lineHits).length, + }; + }), + }); +}; + +export const FileExplorer = () => { + const { entity } = useEntity(); + const [curData, setCurData] = useState<CoverageTableRow | undefined>(); + const [tableData, setTableData] = useState<CoverageTableRow[] | undefined>(); + const [curPath, setCurPath] = useState(''); + const [modalOpen, setModalOpen] = useState(false); + const [curFile, setCurFile] = useState(''); + const codeCoverageApi = useApi(codeCoverageApiRef); + const { loading, error, value } = useAsync( + async () => + await codeCoverageApi.getCoverageForEntity({ + kind: entity.kind, + namespace: entity.metadata.namespace || 'default', + name: entity.metadata.name, + }), + ); + + useEffect(() => { + if (!value) return; + const data = formatInitialData(value); + setCurData(data); + if (data.files) setTableData(data.files); + }, [value]); + + if (loading) { + return <Progress />; + } else if (error) { + return <Alert severity="error">{error.message}</Alert>; + } + + const moveDownIntoPath = (path: string) => { + const nextPathData = tableData!.find( + (d: CoverageTableRow) => d.path === path, + ); + if (nextPathData && nextPathData.files) { + setTableData(nextPathData.files); + } + }; + + const moveUpIntoPath = (path: string) => { + const pathArray = path.split('/').filter(p => p.length); + let data = curData?.files; + pathArray.forEach(p => { + data = data?.find(d => d.path === p)?.files; + }); + setCurPath(path); + setTableData(data); + }; + + const columns: TableColumn<CoverageTableRow>[] = [ + { + title: 'Path', + type: 'string', + field: 'path', + render: (row: CoverageTableRow) => { + if (row.files?.length) { + return ( + <div + role="button" + tabIndex={row.tableData!.id} + style={{ color: 'lightblue', cursor: 'pointer' }} + onKeyDown={() => { + setCurPath(`${curPath}/${row.path}`); + moveDownIntoPath(row.path); + }} + onClick={() => { + setCurPath(`${curPath}/${row.path}`); + moveDownIntoPath(row.path); + }} + > + {row.path} + </div> + ); + } + + return ( + <Box display="flex" alignItems="center"> + {row.path} + <Tooltip title="View file content"> + <DescriptionIcon + fontSize="small" + style={{ color: 'lightblue', cursor: 'pointer' }} + onClick={() => { + setCurFile(`${curPath.slice(1)}/${row.path}`); + setModalOpen(true); + }} + /> + </Tooltip> + </Box> + ); + }, + }, + { + title: 'Coverage', + type: 'numeric', + field: 'coverage', + render: (row: CoverageTableRow) => `${row.coverage}%`, + }, + { + title: 'Missing lines', + type: 'numeric', + field: 'missing', + }, + { + title: 'Tracked lines', + type: 'numeric', + field: 'tracked', + }, + ]; + + const pathArray = curPath.split('/'); + const lastPathElementIndex = pathArray.length - 1; + const fileCoverage = value.files.find((f: FileCoverage) => + f.filename.endsWith(curFile), + ); + + return ( + <Box mt={8}> + <Card> + <CardContent> + <Box mb={2} display="flex" justifyContent="space-between"> + <Typography variant="h5">Explore Files</Typography> + </Box> + <Box mb={2} display="flex"> + {pathArray.map((pathElement, idx) => ( + <Fragment key={pathElement || 'root'}> + <div + role="button" + tabIndex={idx} + style={{ + color: `${idx !== lastPathElementIndex && 'lightblue'}`, + cursor: `${idx !== lastPathElementIndex && 'pointer'}`, + }} + onKeyDown={() => moveUpIntoPath(pathElement)} + onClick={() => moveUpIntoPath(pathElement)} + > + {pathElement || 'root'} + </div> + <div>{'\u00A0/\u00A0'}</div> + </Fragment> + ))} + </Box> + <Table + emptyContent={<>No files found</>} + data={tableData || []} + columns={columns} + /> + <Modal + open={modalOpen} + onClick={event => event.stopPropagation()} + onClose={() => setModalOpen(false)} + style={{ overflow: 'scroll' }} + > + <FileContent filename={curFile} coverage={fileCoverage} /> + </Modal> + </CardContent> + </Card> + </Box> + ); +}; diff --git a/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts b/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts new file mode 100644 index 0000000000..fda1a11f11 --- /dev/null +++ b/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import 'highlight.js/styles/atom-one-dark.css'; +import highlight from 'highlight.js'; + +/* + * Given a file extension, repo name, and array of code lines, return a Promise resolving + * to an array of formatted lines with html/css formatting. + * + * @param {String} fileExtension The extension of the source file + * @param {String} repo The name of the code repository + * @param {Array<String>} lines The source code lines + * + * @returns {Promise<Array<String>>} Promise of formatted lines + * + * @see http://highlightjs.readthedocs.io/en/latest/api.html#highlight-name-value-ignore-illegals-continuation + */ +export const highlightLines = (fileExtension: string, lines: Array<string>) => { + const formattedLines: Array<string> = []; + let state: CompiledMode | Language | undefined; + let fileformat = fileExtension; + if (fileExtension === 'm') { + fileformat = 'objectivec'; + } + if (fileExtension === 'tsx') { + fileformat = 'typescript'; + } + if (fileExtension === 'jsx') { + fileformat = 'javascript'; + } + if (fileExtension === 'kt') { + fileformat = 'kotlin'; + } + + lines.forEach(line => { + const result = highlight.highlight(fileformat, line, true, state); + state = result.top; + formattedLines.push(result.value); + }); + return formattedLines; +}; diff --git a/plugins/code-coverage/src/components/FileExplorer/index.ts b/plugins/code-coverage/src/components/FileExplorer/index.ts new file mode 100644 index 0000000000..88da4059bd --- /dev/null +++ b/plugins/code-coverage/src/components/FileExplorer/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { FileExplorer } from './FileExplorer'; diff --git a/plugins/code-coverage/src/components/Router.tsx b/plugins/code-coverage/src/components/Router.tsx new file mode 100644 index 0000000000..12be6ef5a8 --- /dev/null +++ b/plugins/code-coverage/src/components/Router.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Entity } from '@backstage/catalog-model'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { MissingAnnotationEmptyState } from '@backstage/core'; +import { CodeCoveragePage } from './CodeCoveragePage'; + +export const isCodeCoverageAvailable = (entity: Entity) => + Boolean(entity.metadata.annotations?.['backstage.io/code-coverage']); + +export const Router = () => { + const { entity } = useEntity(); + + if (!isCodeCoverageAvailable(entity)) { + return ( + <MissingAnnotationEmptyState annotation="backstage.io/code-coverage" /> + ); + } + return <CodeCoveragePage />; +}; diff --git a/plugins/code-coverage/src/dev/index.tsx b/plugins/code-coverage/src/dev/index.tsx new file mode 100644 index 0000000000..5c944b097a --- /dev/null +++ b/plugins/code-coverage/src/dev/index.tsx @@ -0,0 +1,28 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createDevApp } from '@backstage/dev-utils'; +import { codeCoveragePlugin } from '../plugin'; +import { codeCoverageApiRef, CodeCoverageRestApi } from '../api'; + +createDevApp() + .registerPlugin(codeCoveragePlugin) + .registerApi({ + api: codeCoverageApiRef, + deps: {}, + factory: () => new CodeCoverageRestApi('http://localhost:3000'), + }) + .render(); diff --git a/plugins/code-coverage/src/index.ts b/plugins/code-coverage/src/index.ts new file mode 100644 index 0000000000..84010e64ac --- /dev/null +++ b/plugins/code-coverage/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { codeCoveragePlugin, EntityCodeCoverageContent } from './plugin'; +export { + Router, + isCodeCoverageAvailable, + isCodeCoverageAvailable as isPluginApplicableToEntity, +} from './components/Router'; + +// export { createBackendRouter } from './backend/router'; diff --git a/plugins/code-coverage/src/plugin.test.ts b/plugins/code-coverage/src/plugin.test.ts new file mode 100644 index 0000000000..9a34c66965 --- /dev/null +++ b/plugins/code-coverage/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { codeCoveragePlugin } from './plugin'; + +describe('code-coverage', () => { + it('should export plugin', () => { + expect(codeCoveragePlugin).toBeDefined(); + }); +}); diff --git a/plugins/code-coverage/src/plugin.ts b/plugins/code-coverage/src/plugin.ts new file mode 100644 index 0000000000..fa5f31d9cc --- /dev/null +++ b/plugins/code-coverage/src/plugin.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + configApiRef, + createApiFactory, + createPlugin, + createRoutableExtension, +} from '@backstage/core'; +import { codeCoverageApiRef, CodeCoverageRestApi } from './api'; + +import { rootRouteRef } from './routes'; + +export const codeCoveragePlugin = createPlugin({ + id: 'code-coverage', + routes: { + root: rootRouteRef, + }, + apis: [ + createApiFactory({ + api: codeCoverageApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => CodeCoverageRestApi.fromConfig(configApi), + }), + ], +}); + +export const EntityCodeCoverageContent = codeCoveragePlugin.provide( + createRoutableExtension({ + component: () => import('./components/Router').then(m => m.Router), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/code-coverage/src/routes.ts b/plugins/code-coverage/src/routes.ts new file mode 100644 index 0000000000..9eaf7859f5 --- /dev/null +++ b/plugins/code-coverage/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core'; + +export const rootRouteRef = createRouteRef({ + title: 'code-coverage', +}); diff --git a/plugins/code-coverage/src/setupTests.ts b/plugins/code-coverage/src/setupTests.ts new file mode 100644 index 0000000000..0cec5b395d --- /dev/null +++ b/plugins/code-coverage/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/yarn.lock b/yarn.lock index a9b95da3ec..baf771b351 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1623,6 +1623,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.10.3": + version "7.13.10" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1679,6 +1686,138 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@backstage/backend-common@^0.5.4": + version "0.5.6" + resolved "https://registry.npmjs.org/@backstage/backend-common/-/backend-common-0.5.6.tgz#e49840eaa6738f6697319ccdfff04ce40cc54b72" + integrity sha512-BzKlcTZLAVDpH87fi2TCWIFO9DfVdaPIIZ8gZSorCuLLErG4X7CS/zQiujJZ/zD5HGtO2QB57fuRkwjBMhJhhw== + dependencies: + "@backstage/cli-common" "^0.1.1" + "@backstage/config" "^0.1.2" + "@backstage/config-loader" "^0.5.1" + "@backstage/integration" "^0.5.1" + "@octokit/rest" "^18.0.12" + "@types/cors" "^2.8.6" + "@types/dockerode" "^3.2.1" + "@types/express" "^4.17.6" + archiver "^5.0.2" + compression "^1.7.4" + concat-stream "^2.0.0" + cors "^2.8.5" + cross-fetch "^3.0.6" + dockerode "^3.2.1" + express "^4.17.1" + express-promise-router "^3.0.3" + fs-extra "^9.0.1" + git-url-parse "^11.4.4" + helmet "^4.0.0" + isomorphic-git "^1.8.0" + knex "^0.95.1" + lodash "^4.17.15" + logform "^2.1.1" + minimatch "^3.0.4" + minimist "^1.2.5" + morgan "^1.10.0" + selfsigned "^1.10.7" + stoppable "^1.1.0" + tar "^6.0.5" + unzipper "^0.10.11" + winston "^3.2.1" + +"@backstage/config-loader@^0.5.1": + version "0.5.1" + resolved "https://registry.npmjs.org/@backstage/config-loader/-/config-loader-0.5.1.tgz#a80f2047e209d2f41b17ad715c632ab142385b39" + integrity sha512-PmwXERs5BIf77sUIg3Fhp/elkR6ELj0czmpUgP4cuEdtazi0WcmdjCUC2DjgsKJWvYggsL1o372QKHh/M5AMTQ== + dependencies: + "@backstage/cli-common" "^0.1.1" + "@backstage/config" "^0.1.1" + ajv "^7.0.3" + fs-extra "^9.0.0" + json-schema "^0.2.5" + json-schema-merge-allof "^0.7.0" + typescript-json-schema "^0.47.0" + yaml "^1.9.2" + yup "^0.29.3" + +"@backstage/core@^0.6.2": + version "0.6.3" + resolved "https://registry.npmjs.org/@backstage/core/-/core-0.6.3.tgz#574ca46ab59e18af07fcf3a248c4428d4dfcc302" + integrity sha512-OSpnvotyCkb6fL02T1Z5TLcogRlOzVIH8YBfNlKeo/Xo/JnlVp1uSpQxCWjAW/lzGK5gp6oh3ezFRjm69mTwSA== + dependencies: + "@backstage/config" "^0.1.3" + "@backstage/core-api" "^0.2.11" + "@backstage/theme" "^0.2.3" + "@material-ui/core" "^4.11.0" + "@material-ui/icons" "^4.9.1" + "@material-ui/lab" "4.0.0-alpha.45" + "@testing-library/react-hooks" "^3.4.2" + "@types/dagre" "^0.7.44" + "@types/prop-types" "^15.7.3" + "@types/react" "^16.9" + "@types/react-sparklines" "^1.7.0" + "@types/react-text-truncate" "^0.14.0" + classnames "^2.2.6" + clsx "^1.1.0" + d3-selection "^2.0.0" + d3-shape "^2.0.0" + d3-zoom "^2.0.0" + dagre "^0.8.5" + immer "^8.0.1" + lodash "^4.17.15" + material-table "^1.69.1" + prop-types "^15.7.2" + qs "^6.9.4" + rc-progress "^3.0.0" + react "^16.12.0" + react-dom "^16.12.0" + react-helmet "6.1.0" + react-hook-form "^6.6.0" + react-markdown "^5.0.2" + react-router "6.0.0-beta.0" + react-router-dom "6.0.0-beta.0" + react-sparklines "^1.7.0" + react-syntax-highlighter "^13.5.1" + react-text-truncate "^0.16.0" + react-use "^15.3.3" + remark-gfm "^1.0.0" + zen-observable "^0.8.15" + +"@backstage/plugin-catalog-backend@^0.6.5": + version "0.6.7" + resolved "https://registry.npmjs.org/@backstage/plugin-catalog-backend/-/plugin-catalog-backend-0.6.7.tgz#97d0ed6db6aeb04e09ed0fee05e76bacf66cc179" + integrity sha512-Ey9PXyUjmi8IxQNSXBhF6Sl2SmZ/iXCFHXnffH8XCdBFTZS8HDRE2tSOlIIU4XQKd6lJVuAGTekas2DkaS9/lA== + dependencies: + "@azure/msal-node" "^1.0.0-beta.3" + "@backstage/backend-common" "^0.6.0" + "@backstage/catalog-model" "^0.7.4" + "@backstage/config" "^0.1.4" + "@backstage/errors" "^0.1.1" + "@backstage/integration" "^0.5.1" + "@backstage/plugin-search-backend-node" "^0.1.2" + "@backstage/search-common" "^0.1.1" + "@octokit/graphql" "^4.5.8" + "@types/express" "^4.17.6" + "@types/ldapjs" "^1.0.9" + aws-sdk "^2.840.0" + codeowners-utils "^1.0.2" + core-js "^3.6.5" + cross-fetch "^3.0.6" + express "^4.17.1" + express-promise-router "^4.1.0" + fs-extra "^9.0.0" + git-url-parse "^11.4.4" + glob "^7.1.6" + knex "^0.95.1" + ldapjs "^2.2.0" + lodash "^4.17.15" + morgan "^1.10.0" + p-limit "^3.0.2" + qs "^6.9.4" + uuid "^8.0.0" + winston "^3.2.1" + yaml "^1.9.2" + yn "^4.0.0" + yup "^0.29.3" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -5520,6 +5659,20 @@ lz-string "^1.4.4" pretty-format "^26.6.2" +"@testing-library/dom@^7.22.3": + version "7.30.3" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-7.30.3.tgz#779ea9bbb92d63302461800a388a5a890ac22519" + integrity sha512-7JhIg2MW6WPwyikH2iL3o7z+FTVgSOd2jqCwTAHqK7Qal2gRRYiUQyURAxtbK9VXm/UTyG9bRihv8C5Tznr2zw== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^4.2.2" + chalk "^4.1.0" + dom-accessibility-api "^0.5.4" + lz-string "^1.4.4" + pretty-format "^26.6.2" + "@testing-library/jest-dom@^5.10.1": version "5.11.9" resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.11.9.tgz#e6b3cd687021f89f261bd53cbe367041fbd3e975" @@ -5550,6 +5703,14 @@ "@babel/runtime" "^7.5.4" "@types/testing-library__react-hooks" "^3.4.0" +"@testing-library/react@^10.4.1": + version "10.4.9" + resolved "https://registry.npmjs.org/@testing-library/react/-/react-10.4.9.tgz#9faa29c6a1a217bf8bbb96a28bd29d7a847ca150" + integrity sha512-pHZKkqUy0tmiD81afs8xfiuseXfU/N7rAX3iKjeZYje86t9VaB0LrxYVa+OOsvkrveX5jCK3IjajVn2MbePvqA== + dependencies: + "@babel/runtime" "^7.10.3" + "@testing-library/dom" "^7.22.3" + "@testing-library/react@^11.2.5": version "11.2.6" resolved "https://registry.npmjs.org/@testing-library/react/-/react-11.2.6.tgz#586a23adc63615985d85be0c903f374dab19200b" @@ -5902,6 +6063,14 @@ dependencies: "@types/express" "*" +"@types/express-xml-bodyparser@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@types/express-xml-bodyparser/-/express-xml-bodyparser-0.3.2.tgz#8566883271d4a28fc57b471d06e6c08047496acb" + integrity sha512-qX01S9eZI/XY48OLI7+5GnofaFG3VyBEn0oIrY5rxkq/T0U2EBpiUfM0scILUluIR6UGBHMM5C2b8Pmir3Xrtw== + dependencies: + "@types/express" "*" + "@types/xml2js" "*" + "@types/express@*", "@types/express@4.17.7", "@types/express@^4.17.6", "@types/express@^4.17.7": version "4.17.7" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz#42045be6475636d9801369cd4418ef65cdb0dd59" @@ -5968,6 +6137,13 @@ dependencies: "@types/unist" "*" +"@types/highlightjs@^10.1.0": + version "10.1.0" + resolved "https://registry.npmjs.org/@types/highlightjs/-/highlightjs-10.1.0.tgz#bf16135e3c736db053f026a1fa8ff3aa247ef5c1" + integrity sha512-xCmqJdhDi4EqrfNDU5ZfZV2ejhszpWBkJS/jYCoAHZhQBBUGnE26l0AzHsZHoe37z4ZETFoZn8HKTIFDjRrfwA== + dependencies: + highlight.js "^10.1.0" + "@types/history@*": version "4.7.5" resolved "https://registry.npmjs.org/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860" @@ -6313,6 +6489,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-10.17.35.tgz#58058f29b870e6ae57b20e4f6e928f02b7129f56" integrity sha512-gXx7jAWpMddu0f7a+L+txMplp3FnHl53OhQIF9puXKq3hDGY/GjH+MF04oWnV/adPSCrbtHumDCFwzq2VhltWA== +"@types/node@^12.0.0": + version "12.20.10" + resolved "https://registry.npmjs.org/@types/node/-/node-12.20.10.tgz#4dcb8a85a8f1211acafb88d72fafc7e3d2685583" + integrity sha512-TxCmnSSppKBBOzYzPR2BR25YlX5Oay8z2XGwFBInuA/Co0V9xJhLlW4kjbxKtgeNo3NOMbQP1A5Rc03y+XecPw== + "@types/node@^12.7.1": version "12.12.58" resolved "https://registry.npmjs.org/@types/node/-/node-12.12.58.tgz#46dae9b2b9ee5992818c8f7cee01ff4ce03ab44c" @@ -6901,7 +7082,7 @@ dependencies: "@types/node" "*" -"@types/xml2js@^0.4.7": +"@types/xml2js@*", "@types/xml2js@^0.4.7": version "0.4.8" resolved "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.8.tgz#84c120c864a5976d0b5cf2f930a75d850fc2b03a" integrity sha512-EyvT83ezOdec7BhDaEcsklWy7RSIdi6CNe95tmOAK0yx/Lm30C9K75snT3fYayK59ApC2oyW+rcHErdG05FHJA== @@ -9990,7 +10171,7 @@ compare-versions@^3.6.0: resolved "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== -component-emitter@^1.2.1, component-emitter@^1.3.0: +component-emitter@^1.2.0, component-emitter@^1.2.1, component-emitter@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== @@ -10294,7 +10475,7 @@ cookie@^0.4.1, cookie@~0.4.1: resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== -cookiejar@^2.1.2: +cookiejar@^2.1.0, cookiejar@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== @@ -12844,6 +13025,15 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" +express-promise-router@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/express-promise-router/-/express-promise-router-3.0.3.tgz#5e6d22a5a3f013d71833172fe8d7ab780c3f6b70" + integrity sha1-Xm0ipaPwE9cYMxcv6NereAw/a3A= + dependencies: + is-promise "^2.1.0" + lodash.flattendeep "^4.0.0" + methods "^1.0.0" + express-promise-router@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/express-promise-router/-/express-promise-router-4.1.0.tgz#79160e145c27610ba411bceb0552a36f11dbab4f" @@ -12867,6 +13057,13 @@ express-session@^1.17.1: safe-buffer "5.2.0" uid-safe "~2.1.5" +express-xml-bodyparser@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/express-xml-bodyparser/-/express-xml-bodyparser-0.3.0.tgz#b1f5a98adf6c6e412c4ccba634234b82945c62be" + integrity sha1-sfWpit9sbkEsTMumNCNLgpRcYr4= + dependencies: + xml2js "^0.4.11" + express@^4.0.0, express@^4.17.0, express@^4.17.1: version "4.17.1" resolved "https://registry.npmjs.org/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -13434,7 +13631,7 @@ fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.0.5, for tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@^2.3.2, form-data@^2.5.0: +form-data@^2.3.1, form-data@^2.3.2, form-data@^2.5.0: version "2.5.1" resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== @@ -13475,7 +13672,7 @@ format@^0.2.0: resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= -formidable@^1.2.2: +formidable@^1.2.0, formidable@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== @@ -14672,6 +14869,11 @@ hex-color-regex@^1.1.0: resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +highlight.js@^10.1.0, highlight.js@^10.6.0: + version "10.7.2" + resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360" + integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg== + highlight.js@^10.1.1, highlight.js@^10.4.1, highlight.js@~10.4.0: version "10.4.1" resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.1.tgz#d48fbcf4a9971c4361b3f95f302747afe19dbad0" @@ -15120,6 +15322,11 @@ immer@8.0.1: resolved "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== +immer@^8.0.1: + version "8.0.4" + resolved "https://registry.npmjs.org/immer/-/immer-8.0.4.tgz#3a21605a4e2dded852fb2afd208ad50969737b7a" + integrity sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ== + immer@^9.0.1: version "9.0.1" resolved "https://registry.npmjs.org/immer/-/immer-9.0.1.tgz#1116368e051f9a0fd188c5136b6efb74ed69c57f" @@ -18336,7 +18543,7 @@ meros@^1.1.2: resolved "https://registry.npmjs.org/meros/-/meros-1.1.4.tgz#c17994d3133db8b23807f62bec7f0cb276cfd948" integrity sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ== -methods@^1.0.0, methods@^1.1.2, methods@~1.1.2: +methods@^1.0.0, methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= @@ -18449,7 +18656,7 @@ mime-types@^2.0.8, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, m dependencies: mime-db "1.46.0" -mime@1.6.0, mime@^1.4.0: +mime@1.6.0, mime@^1.4.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -21585,6 +21792,13 @@ qs@6.7.0: resolved "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.5.1: + version "6.10.1" + resolved "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" + integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + dependencies: + side-channel "^1.0.4" + qs@^6.5.2, qs@^6.6.0, qs@^6.7.0, qs@^6.9.1, qs@^6.9.4, qs@^6.9.6: version "6.9.6" resolved "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" @@ -22160,7 +22374,7 @@ react-string-replace@^0.4.1: dependencies: lodash "^4.17.4" -react-syntax-highlighter@^13.5.0: +react-syntax-highlighter@^13.5.0, react-syntax-highlighter@^13.5.1: version "13.5.3" resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz#9712850f883a3e19eb858cf93fad7bb357eea9c6" integrity sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg== @@ -22454,7 +22668,7 @@ read@1, read@~1.0.1: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -23634,6 +23848,15 @@ side-channel@^1.0.2: es-abstract "^1.17.0-next.1" object-inspect "^1.7.0" +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + sigmund@~1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -24588,6 +24811,22 @@ sucrase@^3.17.1: pirates "^4.0.1" ts-interface-checker "^0.1.9" +superagent@^3.8.3: + version "3.8.3" + resolved "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" + integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA== + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.2.0" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.3.5" + superagent@^6.1.0: version "6.1.0" resolved "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz#09f08807bc41108ef164cfb4be293cebd480f4a6" @@ -24605,6 +24844,14 @@ superagent@^6.1.0: readable-stream "^3.6.0" semver "^7.3.2" +supertest@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/supertest/-/supertest-4.0.2.tgz#c2234dbdd6dc79b6f15b99c8d6577b90e4ce3f36" + integrity sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ== + dependencies: + methods "^1.1.2" + superagent "^3.8.3" + supertest@^6.1.3: version "6.1.3" resolved "https://registry.npmjs.org/supertest/-/supertest-6.1.3.tgz#3f49ea964514c206c334073e8dc4e70519c7403f" @@ -25586,6 +25833,17 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript-json-schema@^0.47.0: + version "0.47.0" + resolved "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.47.0.tgz#84dde5460b127c6774da81bf70b23c7e04857b13" + integrity sha512-A6NVwSOTSsNDHfaqDcDeKwwyXEeKqBHoAr20jcetnYj4e8C6zVFofAVhAuwsBXCRYiWEE/lyHrcxpsSpbIk0Mg== + dependencies: + "@types/json-schema" "^7.0.6" + glob "^7.1.6" + json-stable-stringify "^1.0.1" + typescript "^4.1.3" + yargs "^16.2.0" + typescript-json-schema@^0.49.0: version "0.49.0" resolved "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.49.0.tgz#442f6347ca85fb0d9811f217fb0d6537b68734b3" @@ -26095,7 +26353,7 @@ uuid@^7.0.3: resolved "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== -uuid@^8.0.0, uuid@^8.2.0, uuid@^8.3.0: +uuid@^8.0.0, uuid@^8.2.0, uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -26833,7 +27091,7 @@ xml2js@0.4.19: sax ">=0.6.0" xmlbuilder "~9.0.1" -xml2js@^0.4.19, xml2js@^0.4.23: +xml2js@^0.4.11, xml2js@^0.4.19, xml2js@^0.4.23: version "0.4.23" resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== From 0e57ec3f91ace25cb53c77ccfea3525eef35d6e3 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 11:36:19 -0400 Subject: [PATCH 133/462] Update URLs to be more consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET /report?entity=<ref> POST /report?entity=<ref>&coverageType=<cobertura|jacoco> GET /history?entity=<ref> GET /file-content?entity=<ref>&path=<filepath> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage-backend/README.md | 16 +-- .../migrations/20210302_init.js | 4 +- .../src/service/CodeCoverageDatabase.test.ts | 17 ++-- .../src/service/CodeCoverageDatabase.ts | 43 ++++---- .../src/service/CoverageUtils.ts | 2 +- .../src/service/router.ts | 98 ++++++++++--------- plugins/code-coverage/src/api.ts | 26 +++-- 7 files changed, 105 insertions(+), 101 deletions(-) diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md index 2e2f5ba91f..3229dc940f 100644 --- a/plugins/code-coverage-backend/README.md +++ b/plugins/code-coverage-backend/README.md @@ -22,12 +22,12 @@ Note: This requires the [`backstage.io/source-location` annotation](https://back ### Adding cobertura report -POST a cobertura xml to `/:kind/:namespace/:name?coverageType=cobertura` +POST a cobertura xml to `/report` Example: ```json -// curl -X POST -H "Content-Type:text/xml" -d @cobertura.xml "localhost:7000/api/code-coverage/Component/default/entity-name?coverageType=cobertura" +// curl -X POST -H "Content-Type:text/xml" -d @cobertura.xml "localhost:7000/api/code-coverage/report?entity=component:default/entity-name&coverageType=cobertura" { "links": [ { @@ -40,12 +40,12 @@ Example: ### Adding jacoco report -POST a jacoco xml to `/:kind/:namespace/:name?coverageType=jacoco` +POST a jacoco xml to `/report` Example: ```json -// curl -X POST -H "Content-Type:text/xml" -d @jacoco.xml "localhost:7000/api/code-coverage/Component/default/entity-name?coverageType=jacoco" +// curl -X POST -H "Content-Type:text/xml" -d @jacoco.xml "localhost:7000/api/code-coverage/report?entity=component:default/entity-name&coverageType=jacoco" { "links": [ { @@ -58,12 +58,12 @@ Example: ### Reading json coverage -GET `/:kind/:namespace/:name` +GET `/report` Example: ```json -// curl localhost:7000/api/code-coverage/Component/default/entity-name +// curl localhost:7000/api/code-coverage/report?entity=component:default/entity-name { "aggregate": { "branch": { @@ -102,12 +102,12 @@ Example: ### Coverage history -GET `/:kind/:namespace/:name/history` +GET `/history` Example ```json -// curl localhost:7000/api/code-coverage/Component/default/entity-name/history +// curl localhost:7000/api/code-coverage/history?entity=component:default/entity-name { "entity": { "kind": "Component", diff --git a/plugins/code-coverage-backend/migrations/20210302_init.js b/plugins/code-coverage-backend/migrations/20210302_init.js index 0edd455e7d..b156a9d08d 100644 --- a/plugins/code-coverage-backend/migrations/20210302_init.js +++ b/plugins/code-coverage-backend/migrations/20210302_init.js @@ -27,9 +27,7 @@ exports.up = async function up(knex) { .primary() .notNullable() .comment('The ID of the code coverage'); - table.text('entity_name').notNullable().comment('entity name'); - table.text('entity_kind').notNullable().comment('entity kind'); - table.text('entity_namespace').notNullable().comment('entity namespace'); + table.text('entity').notNullable().comment('entity string reference'); table .text('coverage') .notNullable() diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts index af734dd358..108146287d 100644 --- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts @@ -17,6 +17,7 @@ import { getVoidLogger, SingleConnectionDatabaseManager, } from '@backstage/backend-common'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { CodeCoverageDatabase, @@ -142,11 +143,13 @@ describe('CodeCoverageDatabase', () => { describe('getCodeCoverage', () => { it("can get coverage that's in the database", async () => { - const cov = await database.getCodeCoverage({ - name: 'test-entity', - kind: 'Component', - namespace: 'default', - }); + const cov = await database.getCodeCoverage( + stringifyEntityRef({ + name: 'test-entity', + kind: 'Component', + namespace: 'default', + }), + ); expect(cov).toEqual(coverage[1]); }); }); @@ -154,11 +157,11 @@ describe('CodeCoverageDatabase', () => { describe('getHistory', () => { it("can get history that's in the database", async () => { const cov = await database.getHistory( - { + stringifyEntityRef({ name: 'test-entity', kind: 'Component', namespace: 'default', - }, + }), 5, ); expect(cov.history.length).toEqual(2); diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts index 44109e8e2e..cb83c2f606 100644 --- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts @@ -15,7 +15,7 @@ */ import { resolvePackagePath } from '@backstage/backend-common'; import { NotFoundError } from '@backstage/errors'; -import { EntityName } from '@backstage/catalog-model'; +import { parseEntityName, stringifyEntityRef } from '@backstage/catalog-model'; import { Knex } from 'knex'; import { v4 as uuid } from 'uuid'; import { Logger } from 'winston'; @@ -24,17 +24,15 @@ import { JsonCodeCoverage, JsonCoverageHistory } from './jsoncoverage-types'; export type RawDbCoverageRow = { id: string; - entity_name: string; - entity_namespace: string; - entity_kind: string; + entity: string; coverage: string; }; export interface CodeCoverageStore { insertCodeCoverage( coverage: JsonCodeCoverage, ): Promise<{ codeCoverageId: string }>; - getCodeCoverage(entity: EntityName): Promise<JsonCodeCoverage>; - getHistory(entity: EntityName, limit: number): Promise<JsonCoverageHistory>; + getCodeCoverage(entity: string): Promise<JsonCodeCoverage>; + getHistory(entity: string, limit: number): Promise<JsonCoverageHistory>; } const migrationsDir = resolvePackagePath( @@ -55,22 +53,22 @@ export class CodeCoverageDatabase implements CodeCoverageStore { coverage: JsonCodeCoverage, ): Promise<{ codeCoverageId: string }> { const codeCoverageId = uuid(); + this.logger.error(JSON.stringify(coverage.entity)); + const entity = stringifyEntityRef({ + kind: coverage.entity.kind, + namespace: coverage.entity.namespace, + name: coverage.entity.name, + }); await this.db<RawDbCoverageRow>('code_coverage').insert({ id: codeCoverageId, - entity_name: coverage.entity.name, - entity_kind: coverage.entity.kind, - entity_namespace: coverage.entity.namespace, + entity: entity, coverage: JSON.stringify(coverage), }); return { codeCoverageId }; } - async getCodeCoverage(entity: EntityName): Promise<JsonCodeCoverage> { + async getCodeCoverage(entity: string): Promise<JsonCodeCoverage> { const [result] = await this.db<RawDbCoverageRow>('code_coverage') - .where({ - entity_name: entity.name, - entity_kind: entity.kind, - entity_namespace: entity.namespace, - }) + .where({ entity: entity }) .orderBy('created_at', 'desc') .limit(1) .select(); @@ -87,15 +85,11 @@ export class CodeCoverageDatabase implements CodeCoverageStore { } async getHistory( - entity: EntityName, + entity: string, limit: number, ): Promise<JsonCoverageHistory> { const res = await this.db<RawDbCoverageRow>('code_coverage') - .where({ - entity_name: entity.name, - entity_kind: entity.kind, - entity_namespace: entity.namespace, - }) + .where({ entity: entity }) .orderBy('created_at', 'desc') .limit(limit) .select(); @@ -104,8 +98,13 @@ export class CodeCoverageDatabase implements CodeCoverageStore { .map(r => JSON.parse(r.coverage)) .map(c => aggregateCoverage(c)); + const entityName = parseEntityName(entity); return { - entity, + entity: { + name: entityName.name, + kind: entityName.kind, + namespace: entityName.namespace, + }, history: history, }; } diff --git a/plugins/code-coverage-backend/src/service/CoverageUtils.ts b/plugins/code-coverage-backend/src/service/CoverageUtils.ts index 0ed1561003..031e72434a 100644 --- a/plugins/code-coverage-backend/src/service/CoverageUtils.ts +++ b/plugins/code-coverage-backend/src/service/CoverageUtils.ts @@ -16,7 +16,7 @@ import { Request } from 'express'; import { UrlReader } from '@backstage/backend-common'; import { InputError, NotFoundError } from '@backstage/errors'; -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityName } from '@backstage/catalog-model'; import { ScmIntegration, ScmIntegrations } from '@backstage/integration'; import { AggregateCoverage, diff --git a/plugins/code-coverage-backend/src/service/router.ts b/plugins/code-coverage-backend/src/service/router.ts index 3f3dcf8a1e..576bc26a31 100644 --- a/plugins/code-coverage-backend/src/service/router.ts +++ b/plugins/code-coverage-backend/src/service/router.ts @@ -33,6 +33,11 @@ import { aggregateCoverage, CoverageUtils } from './CoverageUtils'; import { Cobertura } from './converter/cobertura'; import { Jacoco } from './converter/jacoco'; import { Converter } from './converter'; +import { + EntityRef, + parseEntityName, + parseEntityRef, +} from '@backstage/catalog-model'; export interface RouterOptions { config: Config; @@ -69,19 +74,17 @@ export const makeRouter = async ( res.status(200).json({ status: 'ok' }); }); - router.get('/:kind/:namespace/:name', async (req, res) => { - const { kind, namespace, name } = req.params; - const entity = await catalogApi.getEntityByName({ kind, namespace, name }); - if (!entity) { - throw new NotFoundError( - `No entity found matching ${kind}/${namespace}/${name}`, - ); + /** + * /report?entity=component:default/mycomponent + */ + router.get('/report', async (req, res) => { + const { entity } = req.query; + const entityName = parseEntityName(entity as EntityRef); + const entityLookup = await catalogApi.getEntityByName(entityName); + if (!entityLookup) { + throw new NotFoundError(`No entity found matching ${entity}`); } - const stored = await codeCoverageDatabase.getCodeCoverage({ - kind, - namespace, - name, - }); + const stored = await codeCoverageDatabase.getCodeCoverage(entity as string); const aggregate = aggregateCoverage(stored); @@ -94,45 +97,45 @@ export const makeRouter = async ( }); }); - router.get('/:kind/:namespace/:name/history', async (req, res) => { - const { kind, namespace, name } = req.params; - const entity = await catalogApi.getEntityByName({ kind, namespace, name }); - if (!entity) { - throw new NotFoundError( - `No entity found matching ${kind}/${namespace}/${name}`, - ); + /** + * /history?entity=component:default/mycomponent + */ + router.get('/history', async (req, res) => { + const { entity } = req.query; + const entityName = parseEntityName(entity as EntityRef); + const entityLookup = await catalogApi.getEntityByName(entityName); + if (!entityLookup) { + throw new NotFoundError(`No entity found matching ${entity}`); } const { limit } = req.query; const history = await codeCoverageDatabase.getHistory( - { - kind, - namespace, - name, - }, + entity as string, parseInt(limit?.toString() || '10', 10), ); res.status(200).json(history); }); - router.get('/:kind/:namespace/:name/file-content', async (req, res) => { - const { kind, namespace, name } = req.params; - const entity = await catalogApi.getEntityByName({ kind, namespace, name }); - if (!entity) { - throw new NotFoundError( - `No entity found matching ${kind}/${namespace}/${name}`, - ); + /** + * /file-content?entity=component:default/mycomponent&path=src/some-file.go + */ + router.get('/file-content', async (req, res) => { + const { entity, path } = req.query; + const entityName = parseEntityName(entity as EntityRef); + const entityLookup = await catalogApi.getEntityByName(entityName); + if (!entityLookup) { + throw new NotFoundError(`No entity found matching ${entity}`); } - const { path } = req.query; + if (!path) { throw new InputError('Need path query parameter'); } const sourceLocation = - entity.metadata.annotations?.['backstage.io/source-location']; + entityLookup.metadata.annotations?.['backstage.io/source-location']; if (!sourceLocation) { throw new InputError( - `No "backstage.io/source-location" annotation on entity ${entity.kind}/${entity.metadata.namespace}/${entity.metadata.name}`, + `No "backstage.io/source-location" annotation on entity ${entity}`, ); } @@ -165,9 +168,17 @@ export const makeRouter = async ( res.status(200).contentType('text/plain').send(data); }); - router.post('/:kind/:namespace/:name/', async (req, res) => { - const { kind, namespace, name } = req.params; - const { coverageType } = req.query; + /** + * /report?entity=component:default/mycomponent&coverageType=cobertura + */ + router.post('/report', async (req, res) => { + const { entity, coverageType } = req.query; + const entityName = parseEntityName(entity as EntityRef); + const entityLookup = await catalogApi.getEntityByName(entityName); + if (!entityLookup) { + throw new NotFoundError(`No entity found matching ${entity}`); + } + let converter: Converter; if (!coverageType) { throw new InputError('Need coverageType query parameter'); @@ -178,18 +189,13 @@ export const makeRouter = async ( } else { throw new NotFoundError(`unsupported coverage type '${coverageType}`); } - const entity = await catalogApi.getEntityByName({ kind, namespace, name }); - if (!entity) { - throw new NotFoundError( - `No entity found matching ${kind}/${namespace}/${name}`, - ); - } + const { sourceLocation, vcs, scmFiles, body, - } = await utils.processCoveragePayload(entity, req); + } = await utils.processCoveragePayload(entityLookup, req); const files = converter.convert(body, scmFiles); if (!files || files.length === 0) { @@ -197,7 +203,7 @@ export const makeRouter = async ( } const coverage = await utils.buildCoverage( - entity, + entityLookup, sourceLocation, vcs, files, @@ -208,7 +214,7 @@ export const makeRouter = async ( links: [ { rel: 'coverage', - href: `${codecovUrl}/${kind}/${namespace}/${name}`, + href: `${codecovUrl}/report?entity=${entity}`, }, ], }); diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index da18bde267..000ff132e9 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -16,7 +16,7 @@ import { createApiRef } from '@backstage/core'; import { Config } from '@backstage/config'; -import { EntityName } from '@backstage/catalog-model'; +import { EntityName, stringifyEntityRef } from '@backstage/catalog-model'; export class FetchError extends Error { get name(): string { @@ -69,33 +69,31 @@ export class CodeCoverageRestApi implements CodeCoverageApi { return await resp.text(); } - async getCoverageForEntity({ - kind, - namespace, - name, - }: EntityName): Promise<any> { - return await this.fetch<any>( - `/api/code-coverage/${kind}/${namespace}/${name}`, - ); + async getCoverageForEntity(entityName: EntityName): Promise<any> { + const entity = stringifyEntityRef(entityName); + return await this.fetch<any>(`/api/code-coverage/report?entity=${entity}`); } async getFileContentFromEntity( - { kind, namespace, name }: EntityName, + entityName: EntityName, filePath: string, ): Promise<any> { + const entity = stringifyEntityRef(entityName); return await this.fetch<any>( - `/api/code-coverage/${kind}/${namespace}/${name}/file-content?path=${filePath}`, + /// file-content?entity=component:default/mycomponent&path=src/some-file.go + `/api/code-coverage/file-content?entity=${entity}&path=${filePath}`, ); } async getCoverageHistoryForEntity( - { kind, namespace, name }: EntityName, + entityName: EntityName, limit?: number, ): Promise<any> { + const entity = stringifyEntityRef(entityName); const hasValidLimit = limit && limit > 0; return await this.fetch<any>( - `/api/code-coverage/${kind}/${namespace}/${name}/history${ - hasValidLimit ? `?limit=${limit}` : '' + `/api/code-coverage/history?entity=${entity}${ + hasValidLimit ? `&limit=${limit}` : '' }`, ); } From bf02f21eb9dcd3217382e5986c40a96108384f07 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 11:51:04 -0400 Subject: [PATCH 134/462] Address minor code style comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit move code out of `converter/index.ts`. change Converter to be an interface. remove unused function remove commented out import Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/service/converter/Converter.ts | 20 +++++++++++++++++++ .../src/service/converter/cobertura.ts | 6 +++--- .../src/service/converter/index.ts | 10 +++------- .../src/service/converter/jacoco.ts | 6 +++--- .../components/FileExplorer/FileContent.tsx | 14 +------------ .../components/FileExplorer/Highlighter.ts | 7 +++---- plugins/code-coverage/src/index.ts | 2 -- 7 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 plugins/code-coverage-backend/src/service/converter/Converter.ts diff --git a/plugins/code-coverage-backend/src/service/converter/Converter.ts b/plugins/code-coverage-backend/src/service/converter/Converter.ts new file mode 100644 index 0000000000..20c6920c99 --- /dev/null +++ b/plugins/code-coverage-backend/src/service/converter/Converter.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { FileEntry } from '../jsoncoverage-types'; + +export interface Converter { + convert(xml: unknown, scmFiles: Array<string>): Array<FileEntry>; +} diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.ts index 72eeb25b56..fd3cfe9c01 100644 --- a/plugins/code-coverage-backend/src/service/converter/cobertura.ts +++ b/plugins/code-coverage-backend/src/service/converter/cobertura.ts @@ -16,11 +16,11 @@ import { BranchHit, FileEntry } from '../jsoncoverage-types'; import { CoberturaXML, InnerClass, LineHit } from './types'; import { Logger } from 'winston'; -import { Converter } from '.'; +import { Converter } from './Converter'; -export class Cobertura extends Converter { +export class Cobertura implements Converter { constructor(readonly logger: Logger) { - super(logger); + this.logger = logger; } /** diff --git a/plugins/code-coverage-backend/src/service/converter/index.ts b/plugins/code-coverage-backend/src/service/converter/index.ts index 083af10f68..8ea7a41f65 100644 --- a/plugins/code-coverage-backend/src/service/converter/index.ts +++ b/plugins/code-coverage-backend/src/service/converter/index.ts @@ -13,11 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Logger } from 'winston'; -import { FileEntry } from '../jsoncoverage-types'; -export abstract class Converter { - constructor(readonly logger: Logger) {} - - abstract convert(xml: any, scmFiles: Array<string>): Array<FileEntry>; -} +export * from './Converter'; +export { Cobertura } from './cobertura'; +export { Jacoco } from './jacoco'; diff --git a/plugins/code-coverage-backend/src/service/converter/jacoco.ts b/plugins/code-coverage-backend/src/service/converter/jacoco.ts index fe60f9378c..8dfcf0cb51 100644 --- a/plugins/code-coverage-backend/src/service/converter/jacoco.ts +++ b/plugins/code-coverage-backend/src/service/converter/jacoco.ts @@ -16,7 +16,7 @@ import { BranchHit, FileEntry } from '../jsoncoverage-types'; import { JacocoSourceFile, JacocoXML } from './types'; import { Logger } from 'winston'; -import { Converter } from '.'; +import { Converter } from './Converter'; type ParsedLine = { number: number; @@ -26,9 +26,9 @@ type ParsedLine = { covered_branches: number; }; -export class Jacoco extends Converter { +export class Jacoco implements Converter { constructor(readonly logger: Logger) { - super(logger); + this.logger = logger; } /** diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index 7b1bc2c070..358cd72f24 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { FC, useEffect } from 'react'; +import React, { FC } from 'react'; import { useApi } from '@backstage/core-api'; import { useEntity } from '@backstage/plugin-catalog-react'; import { useAsync } from 'react-use'; @@ -31,14 +31,6 @@ type Props = { coverage: FileCoverage; }; -const getContent = async (value: any) => { - let blob = value; - if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) { - blob = new Blob([value], { type: 'application/octet-stream' }); - } - return value; -}; - const useStyles = makeStyles(theme => ({ paper: { margin: 'auto', @@ -97,10 +89,6 @@ export const FileContent = ({ filename, coverage }: Props) => { ), ); - useEffect(() => { - if (value) getContent(value); - }, [value]); - const classes = useStyles(); if (loading) { diff --git a/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts b/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts index fda1a11f11..39f56200b6 100644 --- a/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts +++ b/plugins/code-coverage/src/components/FileExplorer/Highlighter.ts @@ -20,11 +20,10 @@ import highlight from 'highlight.js'; * Given a file extension, repo name, and array of code lines, return a Promise resolving * to an array of formatted lines with html/css formatting. * - * @param {String} fileExtension The extension of the source file - * @param {String} repo The name of the code repository - * @param {Array<String>} lines The source code lines + * @param fileExtension The extension of the source file + * @param lines The source code lines * - * @returns {Promise<Array<String>>} Promise of formatted lines + * @returns Promise of formatted lines * * @see http://highlightjs.readthedocs.io/en/latest/api.html#highlight-name-value-ignore-illegals-continuation */ diff --git a/plugins/code-coverage/src/index.ts b/plugins/code-coverage/src/index.ts index 84010e64ac..7542f963b5 100644 --- a/plugins/code-coverage/src/index.ts +++ b/plugins/code-coverage/src/index.ts @@ -19,5 +19,3 @@ export { isCodeCoverageAvailable, isCodeCoverageAvailable as isPluginApplicableToEntity, } from './components/Router'; - -// export { createBackendRouter } from './backend/router'; From 5813a89427d49d9e62115d8bbbe43415bdf0a7b0 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:03:53 -0400 Subject: [PATCH 135/462] fix types in frontend api client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage-backend/src/index.ts | 2 ++ plugins/code-coverage/package.json | 1 + plugins/code-coverage/src/api.ts | 31 ++++++++++++------- .../components/FileExplorer/FileContent.tsx | 10 +++++- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/plugins/code-coverage-backend/src/index.ts b/plugins/code-coverage-backend/src/index.ts index 7612c392a2..12de31b541 100644 --- a/plugins/code-coverage-backend/src/index.ts +++ b/plugins/code-coverage-backend/src/index.ts @@ -15,3 +15,5 @@ */ export * from './service/router'; + +export * from './service/jsoncoverage-types'; diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 75be2cab92..47d065a092 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -26,6 +26,7 @@ "@backstage/core-api": "^0.2.12", "@backstage/dev-utils": "^0.1.11", "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/plugin-code-coverage-backend": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index 000ff132e9..f386fa03fe 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -17,6 +17,10 @@ import { createApiRef } from '@backstage/core'; import { Config } from '@backstage/config'; import { EntityName, stringifyEntityRef } from '@backstage/catalog-model'; +import { + JsonCodeCoverage, + JsonCoverageHistory, +} from '@backstage/plugin-code-coverage-backend'; export class FetchError extends Error { get name(): string { @@ -34,15 +38,15 @@ export class FetchError extends Error { export type CodeCoverageApi = { url: string; - getCoverageForEntity: (entity: EntityName) => Promise<any>; + getCoverageForEntity: (entity: EntityName) => Promise<JsonCodeCoverage>; getFileContentFromEntity: ( entity: EntityName, filePath: string, - ) => Promise<any>; + ) => Promise<string>; getCoverageHistoryForEntity: ( entity: EntityName, limit?: number, - ) => Promise<any>; + ) => Promise<JsonCoverageHistory>; }; export const codeCoverageApiRef = createApiRef<CodeCoverageApi>({ @@ -57,7 +61,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { constructor(public url: string) {} - private async fetch<T = any | string>( + private async fetch<T = unknown | string | JsonCoverageHistory>( input: string, init?: RequestInit, ): Promise<T | string> { @@ -69,18 +73,21 @@ export class CodeCoverageRestApi implements CodeCoverageApi { return await resp.text(); } - async getCoverageForEntity(entityName: EntityName): Promise<any> { + async getCoverageForEntity( + entityName: EntityName, + ): Promise<JsonCodeCoverage> { const entity = stringifyEntityRef(entityName); - return await this.fetch<any>(`/api/code-coverage/report?entity=${entity}`); + return (await this.fetch<JsonCodeCoverage>( + `/api/code-coverage/report?entity=${entity}`, + )) as JsonCodeCoverage; } async getFileContentFromEntity( entityName: EntityName, filePath: string, - ): Promise<any> { + ): Promise<string> { const entity = stringifyEntityRef(entityName); - return await this.fetch<any>( - /// file-content?entity=component:default/mycomponent&path=src/some-file.go + return await this.fetch<string>( `/api/code-coverage/file-content?entity=${entity}&path=${filePath}`, ); } @@ -88,13 +95,13 @@ export class CodeCoverageRestApi implements CodeCoverageApi { async getCoverageHistoryForEntity( entityName: EntityName, limit?: number, - ): Promise<any> { + ): Promise<JsonCoverageHistory> { const entity = stringifyEntityRef(entityName); const hasValidLimit = limit && limit > 0; - return await this.fetch<any>( + return (await this.fetch<JsonCoverageHistory>( `/api/code-coverage/history?entity=${entity}${ hasValidLimit ? `&limit=${limit}` : '' }`, - ); + )) as JsonCoverageHistory; } } diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index 358cd72f24..72c8b27a12 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -93,9 +93,17 @@ export const FileContent = ({ filename, coverage }: Props) => { if (loading) { return <Progress />; - } else if (error) { + } + if (error) { return <Alert severity="error">{error.message}</Alert>; } + if (!value) { + return ( + <Alert severity="error"> + Unable to retrieve file content for {filename} + </Alert> + ); + } const [language] = filename.split('.').slice(-1); const highlightedLines = highlightLines(language, value.split('\n')); From aa1812c580ade33553258a32e7a1f6cc6a242c8d Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:08:42 -0400 Subject: [PATCH 136/462] encodeURI on all params in frontend api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage/src/api.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index f386fa03fe..1443f9de72 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -76,7 +76,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { async getCoverageForEntity( entityName: EntityName, ): Promise<JsonCodeCoverage> { - const entity = stringifyEntityRef(entityName); + const entity = encodeURI(stringifyEntityRef(entityName)); return (await this.fetch<JsonCodeCoverage>( `/api/code-coverage/report?entity=${entity}`, )) as JsonCodeCoverage; @@ -86,9 +86,11 @@ export class CodeCoverageRestApi implements CodeCoverageApi { entityName: EntityName, filePath: string, ): Promise<string> { - const entity = stringifyEntityRef(entityName); + const entity = encodeURI(stringifyEntityRef(entityName)); return await this.fetch<string>( - `/api/code-coverage/file-content?entity=${entity}&path=${filePath}`, + `/api/code-coverage/file-content?entity=${entity}&path=${encodeURI( + filePath, + )}`, ); } @@ -96,11 +98,11 @@ export class CodeCoverageRestApi implements CodeCoverageApi { entityName: EntityName, limit?: number, ): Promise<JsonCoverageHistory> { - const entity = stringifyEntityRef(entityName); + const entity = encodeURI(stringifyEntityRef(entityName)); const hasValidLimit = limit && limit > 0; return (await this.fetch<JsonCoverageHistory>( `/api/code-coverage/history?entity=${entity}${ - hasValidLimit ? `&limit=${limit}` : '' + hasValidLimit ? `&limit=${encodeURI(`${limit}`)}` : '' }`, )) as JsonCoverageHistory; } From 07768e8b9ede09255dd4156add5f27b44d0b36d5 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:22:51 -0400 Subject: [PATCH 137/462] use theme colors for trend icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/service/jsoncoverage-types.ts | 2 +- .../src/service/router.ts | 6 +---- plugins/code-coverage/package.json | 1 + .../CoverageHistoryChart.tsx | 25 +++++++++++++++---- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts b/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts index f1ef3dd694..34fcf57968 100644 --- a/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts +++ b/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts @@ -23,7 +23,7 @@ export type JsonCodeCoverage = { export type JsonCoverageHistory = { entity: EntityName; - history: Array<CoverageHistory>; + history: Array<AggregateCoverage>; }; export type CoverageHistory = { diff --git a/plugins/code-coverage-backend/src/service/router.ts b/plugins/code-coverage-backend/src/service/router.ts index 576bc26a31..aba5326f5d 100644 --- a/plugins/code-coverage-backend/src/service/router.ts +++ b/plugins/code-coverage-backend/src/service/router.ts @@ -33,11 +33,7 @@ import { aggregateCoverage, CoverageUtils } from './CoverageUtils'; import { Cobertura } from './converter/cobertura'; import { Jacoco } from './converter/jacoco'; import { Converter } from './converter'; -import { - EntityRef, - parseEntityName, - parseEntityRef, -} from '@backstage/catalog-model'; +import { EntityRef, parseEntityName } from '@backstage/catalog-model'; export interface RouterOptions { config: Config; diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 47d065a092..e17d894b43 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -30,6 +30,7 @@ "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", + "@material-ui/styles": "^4.11.0", "@material-ui/lab": "4.0.0-alpha.45", "@types/highlightjs": "^10.1.0", "highlight.js": "^10.6.0", diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index a7bfeceb19..3e8d9b6387 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -19,6 +19,7 @@ import { Box, Card, CardContent, + makeStyles, MenuItem, Select, Typography, @@ -42,15 +43,26 @@ import { Alert } from '@material-ui/lab'; import TrendingDownIcon from '@material-ui/icons/TrendingDown'; import TrendingUpIcon from '@material-ui/icons/TrendingUp'; import TrendingFlatIcon from '@material-ui/icons/TrendingFlat'; +import { BackstageTheme } from '@backstage/theme'; +import { ClassNameMap } from '@material-ui/styles'; type Coverage = 'line' | 'branch'; -const getTrendIcon = (trend: number) => { +const useStyles = makeStyles<BackstageTheme>(theme => ({ + trendDown: { + color: theme.palette.status.warning, + }, + trendUp: { + color: theme.palette.status.ok, + }, +})); + +const getTrendIcon = (trend: number, classes: ClassNameMap) => { switch (true) { case trend > 0: - return <TrendingUpIcon style={{ color: 'green' }} />; + return <TrendingUpIcon className={classes.trendUp} />; case trend < 0: - return <TrendingDownIcon style={{ color: 'red' }} />; + return <TrendingDownIcon className={classes.trendDown} />; case trend === 0: default: return <TrendingFlatIcon />; @@ -72,11 +84,14 @@ export const CoverageHistoryChart = () => { name: entity.metadata.name, }), ); + const classes = useStyles(); if (loadingHistory) { return <Progress />; } else if (errorHistory) { return <Alert severity="error">{errorHistory.message}</Alert>; + } else if (!valueHistory) { + return <Alert severity="warning">No history found.</Alert>; } if (!valueHistory.history.length) { @@ -123,7 +138,7 @@ export const CoverageHistoryChart = () => { </Box> <Box px={6} display="flex"> <Box display="flex" mr={4}> - {getTrendIcon(lineTrend)} + {getTrendIcon(lineTrend, classes)} <Typography> Current line: {latestCoverage.line.percentage}%<br />( {Math.floor(lineTrend)}% change over{' '} @@ -131,7 +146,7 @@ export const CoverageHistoryChart = () => { </Typography> </Box> <Box display="flex"> - {getTrendIcon(branchTrend)} + {getTrendIcon(branchTrend, classes)} <Typography> Current branch: {latestCoverage.branch.percentage}%<br />( {Math.floor(branchTrend)}% change over{' '} From bd0e05632a6131a87b96e73bc253dafd82d3981c Mon Sep 17 00:00:00 2001 From: Rickard Dybeck <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:45:43 -0400 Subject: [PATCH 138/462] use theme spacing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../code-coverage/src/components/FileExplorer/CoverageRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx index a4eabf715d..99d173a9ce 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx @@ -24,7 +24,7 @@ const useStyles = makeStyles(theme => ({ color: `${theme.palette.grey[500]}`, fontSize: '90%', borderRight: `1px solid ${theme.palette.grey[500]}`, - paddingRight: '8px', + paddingRight: theme.spacing(1), textAlign: 'right', }, hitCountCell: { From 8e09c5fa2d9d394355822cf6426d2b1e573a2f49 Mon Sep 17 00:00:00 2001 From: Rickard Dybeck <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:46:33 -0400 Subject: [PATCH 139/462] remove string interpolation for theme spacing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../code-coverage/src/components/FileExplorer/CoverageRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx index 99d173a9ce..659bd4cb1d 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx @@ -32,7 +32,7 @@ const useStyles = makeStyles(theme => ({ borderRight: `1px solid ${theme.palette.grey[500]}`, textAlign: 'center', color: 'white', // need to enforce this color since it needs to stand out against colored background - paddingLeft: `${theme.spacing(1)}`, + paddingLeft: theme.spacing(1), paddingRight: `${theme.spacing(1)}`, }, countRoundedRectangle: { From 25b40a66a673674fe8ebe737972b022a60e59a75 Mon Sep 17 00:00:00 2001 From: Rickard Dybeck <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:47:31 -0400 Subject: [PATCH 140/462] don't wrap color in string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../code-coverage/src/components/FileExplorer/CoverageRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx index 659bd4cb1d..b213ad05de 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx @@ -42,7 +42,7 @@ const useStyles = makeStyles(theme => ({ width: '50px', }, hitCountRoundedRectangle: { - backgroundColor: `${green[500]}`, + backgroundColor: green[500], }, notHitCountRoundedRectangle: { backgroundColor: `${red[500]}`, From 10f5e0c7ec7de06f378a194de7d999dee33215e6 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 12:55:10 -0400 Subject: [PATCH 141/462] fix error panels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage/package.json | 5 +- plugins/code-coverage/src/api.ts | 5 +- .../CoverageHistoryChart.tsx | 7 ++- .../components/FileExplorer/FileContent.tsx | 4 +- .../components/FileExplorer/FileExplorer.tsx | 31 ++++++---- yarn.lock | 61 +------------------ 6 files changed, 36 insertions(+), 77 deletions(-) diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index e17d894b43..eabd961f4b 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -22,16 +22,17 @@ "dependencies": { "@backstage/catalog-model": "^0.7.2", "@backstage/config": "^0.1.3", - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.7.5", "@backstage/core-api": "^0.2.12", "@backstage/dev-utils": "^0.1.11", + "@backstage/errors": "^0.1.0", "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/plugin-code-coverage-backend": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/styles": "^4.11.0", - "@material-ui/lab": "4.0.0-alpha.45", + "@material-ui/lab": "4.0.0-alpha.57", "@types/highlightjs": "^10.1.0", "highlight.js": "^10.6.0", "react": "^16.13.1", diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index 1443f9de72..1a1bd542ae 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -21,6 +21,7 @@ import { JsonCodeCoverage, JsonCoverageHistory, } from '@backstage/plugin-code-coverage-backend'; +import { ResponseError } from '@backstage/errors'; export class FetchError extends Error { get name(): string { @@ -66,7 +67,9 @@ export class CodeCoverageRestApi implements CodeCoverageApi { init?: RequestInit, ): Promise<T | string> { const resp = await fetch(`${this.url}${input}`, init); - if (!resp.ok) throw await FetchError.forResponse(resp); + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } if (resp.headers.get('content-type')?.includes('application/json')) { return await resp.json(); } diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index 3e8d9b6387..4f4f442315 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -38,7 +38,7 @@ import { useAsync } from 'react-use'; import { useApi } from '@backstage/core-api'; import { useEntity } from '@backstage/plugin-catalog-react'; import { codeCoverageApiRef } from '../../api'; -import { Progress } from '@backstage/core'; +import { Progress, ResponseErrorPanel } from '@backstage/core'; import { Alert } from '@material-ui/lab'; import TrendingDownIcon from '@material-ui/icons/TrendingDown'; import TrendingUpIcon from '@material-ui/icons/TrendingUp'; @@ -88,8 +88,9 @@ export const CoverageHistoryChart = () => { if (loadingHistory) { return <Progress />; - } else if (errorHistory) { - return <Alert severity="error">{errorHistory.message}</Alert>; + } + if (errorHistory) { + return <ResponseErrorPanel error={errorHistory} />; } else if (!valueHistory) { return <Alert severity="warning">No history found.</Alert>; } diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index 72c8b27a12..6844557307 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -23,12 +23,12 @@ import { Progress } from '@backstage/core'; import { Alert } from '@material-ui/lab'; import { makeStyles, Paper } from '@material-ui/core'; import { highlightLines } from './Highlighter'; -import { FileCoverage } from './FileExplorer'; import CoverageRow from './CoverageRow'; +import { FileEntry } from '@backstage/plugin-code-coverage-backend'; type Props = { filename: string; - coverage: FileCoverage; + coverage: FileEntry; }; const useStyles = makeStyles(theme => ({ diff --git a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx index 11baa419f4..da20ba0ed6 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx @@ -16,7 +16,12 @@ import { useApi } from '@backstage/core-api'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { Progress, Table, TableColumn } from '@backstage/core'; +import { + Progress, + ResponseErrorPanel, + Table, + TableColumn, +} from '@backstage/core'; import { Box, Card, @@ -28,15 +33,10 @@ import { import React, { Fragment, useEffect, useState } from 'react'; import { useAsync } from 'react-use'; import { codeCoverageApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; import DescriptionIcon from '@material-ui/icons/Description'; import { FileContent } from './FileContent'; - -export type FileCoverage = { - filename: string; - branchHits: { [branch: number]: number }; - lineHits: { [line: number]: number }; -}; +import { Alert } from '@material-ui/lab'; +import { FileEntry } from '@backstage/plugin-code-coverage-backend'; type FileStructureObject = Record<string, any>; @@ -101,7 +101,7 @@ const formatInitialData = (value: any) => { coverage: value.aggregate.line.percentage, missing: value.aggregate.line.missed, tracked: value.aggregate.line.available, - files: value.files.map((fc: FileCoverage) => { + files: value.files.map((fc: FileEntry) => { return { path: '', filename: fc.filename, @@ -145,7 +145,12 @@ export const FileExplorer = () => { if (loading) { return <Progress />; } else if (error) { - return <Alert severity="error">{error.message}</Alert>; + return <ResponseErrorPanel error={error} />; + } + if (!value) { + return ( + <Alert severity="warning">No code coverage found for ${entity}</Alert> + ); } const moveDownIntoPath = (path: string) => { @@ -230,10 +235,14 @@ export const FileExplorer = () => { const pathArray = curPath.split('/'); const lastPathElementIndex = pathArray.length - 1; - const fileCoverage = value.files.find((f: FileCoverage) => + const fileCoverage = value.files.find((f: FileEntry) => f.filename.endsWith(curFile), ); + if (!fileCoverage) { + return null; + } + return ( <Box mt={8}> <Card> diff --git a/yarn.lock b/yarn.lock index baf771b351..79f7d85b38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,14 +1616,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.13.10" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" - integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.3": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.13.10" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== @@ -1738,49 +1731,6 @@ yaml "^1.9.2" yup "^0.29.3" -"@backstage/core@^0.6.2": - version "0.6.3" - resolved "https://registry.npmjs.org/@backstage/core/-/core-0.6.3.tgz#574ca46ab59e18af07fcf3a248c4428d4dfcc302" - integrity sha512-OSpnvotyCkb6fL02T1Z5TLcogRlOzVIH8YBfNlKeo/Xo/JnlVp1uSpQxCWjAW/lzGK5gp6oh3ezFRjm69mTwSA== - dependencies: - "@backstage/config" "^0.1.3" - "@backstage/core-api" "^0.2.11" - "@backstage/theme" "^0.2.3" - "@material-ui/core" "^4.11.0" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.45" - "@testing-library/react-hooks" "^3.4.2" - "@types/dagre" "^0.7.44" - "@types/prop-types" "^15.7.3" - "@types/react" "^16.9" - "@types/react-sparklines" "^1.7.0" - "@types/react-text-truncate" "^0.14.0" - classnames "^2.2.6" - clsx "^1.1.0" - d3-selection "^2.0.0" - d3-shape "^2.0.0" - d3-zoom "^2.0.0" - dagre "^0.8.5" - immer "^8.0.1" - lodash "^4.17.15" - material-table "^1.69.1" - prop-types "^15.7.2" - qs "^6.9.4" - rc-progress "^3.0.0" - react "^16.12.0" - react-dom "^16.12.0" - react-helmet "6.1.0" - react-hook-form "^6.6.0" - react-markdown "^5.0.2" - react-router "6.0.0-beta.0" - react-router-dom "6.0.0-beta.0" - react-sparklines "^1.7.0" - react-syntax-highlighter "^13.5.1" - react-text-truncate "^0.16.0" - react-use "^15.3.3" - remark-gfm "^1.0.0" - zen-observable "^0.8.15" - "@backstage/plugin-catalog-backend@^0.6.5": version "0.6.7" resolved "https://registry.npmjs.org/@backstage/plugin-catalog-backend/-/plugin-catalog-backend-0.6.7.tgz#97d0ed6db6aeb04e09ed0fee05e76bacf66cc179" @@ -3917,7 +3867,7 @@ react-transition-group "^4.0.0" rifm "^0.7.0" -"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.11.3", "@material-ui/styles@^4.9.6": +"@material-ui/styles@^4.10.0", "@material-ui/styles@^4.11.0", "@material-ui/styles@^4.11.3", "@material-ui/styles@^4.9.6": version "4.11.3" resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz#1b8d97775a4a643b53478c895e3f2a464e8916f2" integrity sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg== @@ -15322,11 +15272,6 @@ immer@8.0.1: resolved "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== -immer@^8.0.1: - version "8.0.4" - resolved "https://registry.npmjs.org/immer/-/immer-8.0.4.tgz#3a21605a4e2dded852fb2afd208ad50969737b7a" - integrity sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ== - immer@^9.0.1: version "9.0.1" resolved "https://registry.npmjs.org/immer/-/immer-9.0.1.tgz#1116368e051f9a0fd188c5136b6efb74ed69c57f" @@ -22374,7 +22319,7 @@ react-string-replace@^0.4.1: dependencies: lodash "^4.17.4" -react-syntax-highlighter@^13.5.0, react-syntax-highlighter@^13.5.1: +react-syntax-highlighter@^13.5.0: version "13.5.3" resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz#9712850f883a3e19eb858cf93fad7bb357eea9c6" integrity sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg== From 57a10500cd9d471d41a1bbaeb6094f3ffe7148cd Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 13:06:01 -0400 Subject: [PATCH 142/462] add code-coverage annotation to well-known-annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../software-catalog/well-known-annotations.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 0053c14b79..5cfe8f39ef 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -273,6 +273,20 @@ project within your organization. Specifying this annotation may enable SonarQube related features in Backstage for that entity. +### backstage.io/code-coverage + +```yaml +# Example: +metadata: + annotations: + backstage.io/code-coverage: scm-only +``` + +The value of this annotation controls the code-coverage backstage plugin. If set +to smc-only the plugin will only take into account files stored in source +control (e.g. ignoring generated code). If set to any other non-false:y value +all files covered by a coverage report will be taken into account. + ## Deprecated Annotations The following annotations are deprecated, and only listed here to aid in From 9132deaa768a01ec4259554d8e743a8d7845714e Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 13:58:31 -0400 Subject: [PATCH 143/462] fix file content explorer, use getEntitySourceLocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../code-coverage-backend/src/service/router.ts | 14 +++++++++----- .../src/components/FileExplorer/FileContent.tsx | 6 +++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/plugins/code-coverage-backend/src/service/router.ts b/plugins/code-coverage-backend/src/service/router.ts index aba5326f5d..f2e34cd07a 100644 --- a/plugins/code-coverage-backend/src/service/router.ts +++ b/plugins/code-coverage-backend/src/service/router.ts @@ -33,7 +33,11 @@ import { aggregateCoverage, CoverageUtils } from './CoverageUtils'; import { Cobertura } from './converter/cobertura'; import { Jacoco } from './converter/jacoco'; import { Converter } from './converter'; -import { EntityRef, parseEntityName } from '@backstage/catalog-model'; +import { + EntityRef, + getEntitySourceLocation, + parseEntityName, +} from '@backstage/catalog-model'; export interface RouterOptions { config: Config; @@ -127,20 +131,20 @@ export const makeRouter = async ( throw new InputError('Need path query parameter'); } - const sourceLocation = - entityLookup.metadata.annotations?.['backstage.io/source-location']; + const sourceLocation = getEntitySourceLocation(entityLookup); + if (!sourceLocation) { throw new InputError( `No "backstage.io/source-location" annotation on entity ${entity}`, ); } - const vcs = scm.byUrl(sourceLocation); + const vcs = scm.byUrl(sourceLocation.target); if (!vcs) { throw new InputError(`Unable to determine SCM from ${sourceLocation}`); } - const scmTree = await urlReader.readTree(sourceLocation); + const scmTree = await urlReader.readTree(sourceLocation.target); const scmFile = (await scmTree.files()).find(f => f.path === path); if (!scmFile) { res.status(400).json({ diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index 6844557307..e4ade53f37 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -19,7 +19,7 @@ import { useApi } from '@backstage/core-api'; import { useEntity } from '@backstage/plugin-catalog-react'; import { useAsync } from 'react-use'; import { codeCoverageApiRef } from '../../api'; -import { Progress } from '@backstage/core'; +import { Progress, ResponseErrorPanel } from '@backstage/core'; import { Alert } from '@material-ui/lab'; import { makeStyles, Paper } from '@material-ui/core'; import { highlightLines } from './Highlighter'; @@ -95,11 +95,11 @@ export const FileContent = ({ filename, coverage }: Props) => { return <Progress />; } if (error) { - return <Alert severity="error">{error.message}</Alert>; + return <ResponseErrorPanel error={error} />; } if (!value) { return ( - <Alert severity="error"> + <Alert severity="warning"> Unable to retrieve file content for {filename} </Alert> ); From b64e81b80d4cd7e50d9beb6bd55ef3253025e048 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 13:59:04 -0400 Subject: [PATCH 144/462] use discoveryApi to find code-coverage-backend api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage/src/api.ts | 25 ++++++++++++------------- plugins/code-coverage/src/plugin.ts | 6 +++--- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index 1a1bd542ae..2fa2dab05a 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createApiRef } from '@backstage/core'; +import { createApiRef, DiscoveryApi } from '@backstage/core'; import { Config } from '@backstage/config'; import { EntityName, stringifyEntityRef } from '@backstage/catalog-model'; import { @@ -38,7 +38,7 @@ export class FetchError extends Error { } export type CodeCoverageApi = { - url: string; + discovery: DiscoveryApi; getCoverageForEntity: (entity: EntityName) => Promise<JsonCodeCoverage>; getFileContentFromEntity: ( entity: EntityName, @@ -56,17 +56,18 @@ export const codeCoverageApiRef = createApiRef<CodeCoverageApi>({ }); export class CodeCoverageRestApi implements CodeCoverageApi { - static fromConfig(config: Config) { - return new CodeCoverageRestApi(config.getString('backend.baseUrl')); - } + url: string = ''; - constructor(public url: string) {} + constructor(public discovery: DiscoveryApi) {} private async fetch<T = unknown | string | JsonCoverageHistory>( - input: string, + path: string, init?: RequestInit, ): Promise<T | string> { - const resp = await fetch(`${this.url}${input}`, init); + if (!this.url) { + this.url = await this.discovery.getBaseUrl('code-coverage'); + } + const resp = await fetch(`${this.url}${path}`, init); if (!resp.ok) { throw await ResponseError.fromResponse(resp); } @@ -81,7 +82,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { ): Promise<JsonCodeCoverage> { const entity = encodeURI(stringifyEntityRef(entityName)); return (await this.fetch<JsonCodeCoverage>( - `/api/code-coverage/report?entity=${entity}`, + `/report?entity=${entity}`, )) as JsonCodeCoverage; } @@ -91,9 +92,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { ): Promise<string> { const entity = encodeURI(stringifyEntityRef(entityName)); return await this.fetch<string>( - `/api/code-coverage/file-content?entity=${entity}&path=${encodeURI( - filePath, - )}`, + `/file-content?entity=${entity}&path=${encodeURI(filePath)}`, ); } @@ -104,7 +103,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { const entity = encodeURI(stringifyEntityRef(entityName)); const hasValidLimit = limit && limit > 0; return (await this.fetch<JsonCoverageHistory>( - `/api/code-coverage/history?entity=${entity}${ + `/history?entity=${entity}${ hasValidLimit ? `&limit=${encodeURI(`${limit}`)}` : '' }`, )) as JsonCoverageHistory; diff --git a/plugins/code-coverage/src/plugin.ts b/plugins/code-coverage/src/plugin.ts index fa5f31d9cc..68e8291bc4 100644 --- a/plugins/code-coverage/src/plugin.ts +++ b/plugins/code-coverage/src/plugin.ts @@ -14,10 +14,10 @@ * limitations under the License. */ import { - configApiRef, createApiFactory, createPlugin, createRoutableExtension, + discoveryApiRef, } from '@backstage/core'; import { codeCoverageApiRef, CodeCoverageRestApi } from './api'; @@ -31,8 +31,8 @@ export const codeCoveragePlugin = createPlugin({ apis: [ createApiFactory({ api: codeCoverageApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => CodeCoverageRestApi.fromConfig(configApi), + deps: { discoveryApi: discoveryApiRef }, + factory: ({ discoveryApi }) => new CodeCoverageRestApi(discoveryApi), }), ], }); From d4b2b0869d849589476f466653abcbb07566c9cd Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 14:07:12 -0400 Subject: [PATCH 145/462] use getEntitySourceLocation in CoverageUtils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/service/CoverageUtils.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/plugins/code-coverage-backend/src/service/CoverageUtils.ts b/plugins/code-coverage-backend/src/service/CoverageUtils.ts index 031e72434a..4850ac9b1b 100644 --- a/plugins/code-coverage-backend/src/service/CoverageUtils.ts +++ b/plugins/code-coverage-backend/src/service/CoverageUtils.ts @@ -16,7 +16,11 @@ import { Request } from 'express'; import { UrlReader } from '@backstage/backend-common'; import { InputError, NotFoundError } from '@backstage/errors'; -import { Entity, EntityName } from '@backstage/catalog-model'; +import { + Entity, + getEntitySourceLocation, + stringifyEntityRef, +} from '@backstage/catalog-model'; import { ScmIntegration, ScmIntegrations } from '@backstage/integration'; import { AggregateCoverage, @@ -96,11 +100,18 @@ export class CoverageUtils { let scmFiles: string[] = []; if (enforceScmFiles) { - sourceLocation = - entity.metadata.annotations?.['backstage.io/source-location']; + try { + const sl = getEntitySourceLocation(entity); + sourceLocation = sl.target; + } catch (e: unknown) { + // TODO: logging + } + if (!sourceLocation) { throw new InputError( - `No "backstage.io/source-location" annotation on entity ${entity.kind}/${entity.metadata.namespace}/${entity.metadata.name}`, + `No "backstage.io/source-location" annotation on entity ${stringifyEntityRef( + entity, + )}`, ); } From 50ce122fca75f39cf96640e8b8f9ce4fd854bfcc Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 15:07:20 -0400 Subject: [PATCH 146/462] Stop using React.FC, use CardHeader instead of Box MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../CoverageHistoryChart.tsx | 108 ++++++++---------- .../components/FileExplorer/CoverageRow.tsx | 4 +- .../components/FileExplorer/FileContent.tsx | 4 +- .../components/FileExplorer/FileExplorer.tsx | 80 ++++++------- 4 files changed, 87 insertions(+), 109 deletions(-) diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index 4f4f442315..f9927a17d3 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -19,9 +19,8 @@ import { Box, Card, CardContent, + CardHeader, makeStyles, - MenuItem, - Select, Typography, } from '@material-ui/core'; import { @@ -97,16 +96,10 @@ export const CoverageHistoryChart = () => { if (!valueHistory.history.length) { return ( - <Box> - <Card> - <CardContent> - <Box mb={2} display="flex" justifyContent="space-between"> - <Typography variant="h5">History</Typography> - </Box> - No coverage history found - </CardContent> - </Card> - </Box> + <Card> + <CardHeader title="History" /> + <CardContent>No coverage history found</CardContent> + </Card> ); } @@ -128,58 +121,47 @@ export const CoverageHistoryChart = () => { const branchTrend = getTrendForCoverage('branch'); return ( - <Box> - <Card> - <CardContent> - <Box mb={2} display="flex" justifyContent="space-between"> - <Typography variant="h5">History</Typography> - <Select> - <MenuItem>7</MenuItem> - </Select> + <Card> + <CardHeader title="History" /> + <CardContent> + <Box px={6} display="flex"> + <Box display="flex" mr={4}> + {getTrendIcon(lineTrend, classes)} + <Typography> + Current line: {latestCoverage.line.percentage}%<br />( + {Math.floor(lineTrend)}% change over {valueHistory.history.length}{' '} + builds) + </Typography> </Box> - <Box px={6} display="flex"> - <Box display="flex" mr={4}> - {getTrendIcon(lineTrend, classes)} - <Typography> - Current line: {latestCoverage.line.percentage}%<br />( - {Math.floor(lineTrend)}% change over{' '} - {valueHistory.history.length} builds) - </Typography> - </Box> - <Box display="flex"> - {getTrendIcon(branchTrend, classes)} - <Typography> - Current branch: {latestCoverage.branch.percentage}%<br />( - {Math.floor(branchTrend)}% change over{' '} - {valueHistory.history.length} builds) - </Typography> - </Box> + <Box display="flex"> + {getTrendIcon(branchTrend, classes)} + <Typography> + Current branch: {latestCoverage.branch.percentage}%<br />( + {Math.floor(branchTrend)}% change over{' '} + {valueHistory.history.length} builds) + </Typography> </Box> - <ResponsiveContainer width="100%" height={300}> - <LineChart - data={valueHistory.history} - margin={{ right: 48, top: 32 }} - > - <CartesianGrid strokeDasharray="3 3" /> - <XAxis dataKey="timestamp" /> - <YAxis dataKey="line.percentage" /> - <YAxis dataKey="branch.percentage" /> - <Tooltip /> - <Legend /> - <Line - type="monotone" - dataKey="branch.percentage" - stroke="#8884d8" - /> - <Line - type="monotone" - dataKey="line.percentage" - stroke="#82ca9d" - /> - </LineChart> - </ResponsiveContainer> - </CardContent> - </Card> - </Box> + </Box> + <ResponsiveContainer width="100%" height={300}> + <LineChart + data={valueHistory.history} + margin={{ right: 48, top: 32 }} + > + <CartesianGrid strokeDasharray="3 3" /> + <XAxis dataKey="timestamp" /> + <YAxis dataKey="line.percentage" /> + <YAxis dataKey="branch.percentage" /> + <Tooltip /> + <Legend /> + <Line + type="monotone" + dataKey="branch.percentage" + stroke="#8884d8" + /> + <Line type="monotone" dataKey="line.percentage" stroke="#82ca9d" /> + </LineChart> + </ResponsiveContainer> + </CardContent> + </Card> ); }; diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx index b213ad05de..4af4fbbf4e 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { FC } from 'react'; +import React from 'react'; // styles import { makeStyles } from '@material-ui/core'; @@ -65,7 +65,7 @@ type CodeRowProps = { lineContent: string; lineHits?: number | null; }; -const CodeRow: FC<CodeRowProps> = ({ +const CodeRow = ({ lineNumber, lineContent, lineHits = null, diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index e4ade53f37..703489f587 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { FC } from 'react'; +import React from 'react'; import { useApi } from '@backstage/core-api'; import { useEntity } from '@backstage/plugin-catalog-react'; import { useAsync } from 'react-use'; @@ -53,7 +53,7 @@ type FormattedLinesProps = { highlightedLines: string[]; lineHits: Record<number, number>; }; -const FormattedLines: FC<FormattedLinesProps> = ({ +const FormattedLines = ({ highlightedLines, lineHits, }: FormattedLinesProps) => { diff --git a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx index da20ba0ed6..704edcdf15 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx @@ -26,9 +26,9 @@ import { Box, Card, CardContent, + CardHeader, Modal, Tooltip, - Typography, } from '@material-ui/core'; import React, { Fragment, useEffect, useState } from 'react'; import { useAsync } from 'react-use'; @@ -244,46 +244,42 @@ export const FileExplorer = () => { } return ( - <Box mt={8}> - <Card> - <CardContent> - <Box mb={2} display="flex" justifyContent="space-between"> - <Typography variant="h5">Explore Files</Typography> - </Box> - <Box mb={2} display="flex"> - {pathArray.map((pathElement, idx) => ( - <Fragment key={pathElement || 'root'}> - <div - role="button" - tabIndex={idx} - style={{ - color: `${idx !== lastPathElementIndex && 'lightblue'}`, - cursor: `${idx !== lastPathElementIndex && 'pointer'}`, - }} - onKeyDown={() => moveUpIntoPath(pathElement)} - onClick={() => moveUpIntoPath(pathElement)} - > - {pathElement || 'root'} - </div> - <div>{'\u00A0/\u00A0'}</div> - </Fragment> - ))} - </Box> - <Table - emptyContent={<>No files found</>} - data={tableData || []} - columns={columns} - /> - <Modal - open={modalOpen} - onClick={event => event.stopPropagation()} - onClose={() => setModalOpen(false)} - style={{ overflow: 'scroll' }} - > - <FileContent filename={curFile} coverage={fileCoverage} /> - </Modal> - </CardContent> - </Card> - </Box> + <Card> + <CardHeader title="Explore Files" /> + <CardContent> + <Box mb={2} display="flex"> + {pathArray.map((pathElement, idx) => ( + <Fragment key={pathElement || 'root'}> + <div + role="button" + tabIndex={idx} + style={{ + color: `${idx !== lastPathElementIndex && 'lightblue'}`, + cursor: `${idx !== lastPathElementIndex && 'pointer'}`, + }} + onKeyDown={() => moveUpIntoPath(pathElement)} + onClick={() => moveUpIntoPath(pathElement)} + > + {pathElement || 'root'} + </div> + <div>{'\u00A0/\u00A0'}</div> + </Fragment> + ))} + </Box> + <Table + emptyContent={<>No files found</>} + data={tableData || []} + columns={columns} + /> + <Modal + open={modalOpen} + onClick={event => event.stopPropagation()} + onClose={() => setModalOpen(false)} + style={{ overflow: 'scroll' }} + > + <FileContent filename={curFile} coverage={fileCoverage} /> + </Modal> + </CardContent> + </Card> ); }; From 24acde68321711350f975cfd03b966949e64cf4e Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 15:10:22 -0400 Subject: [PATCH 147/462] set dependency on entity for FileContent#useAsync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../code-coverage/src/components/FileExplorer/FileContent.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index 703489f587..0d7f495daf 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -87,6 +87,7 @@ export const FileContent = ({ filename, coverage }: Props) => { }, filename, ), + [entity], ); const classes = useStyles(); From eb6a17971af5d241b3c257f89673bcc0e6d62f75 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 15:16:16 -0400 Subject: [PATCH 148/462] Fix theming of CoverageRow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/components/FileExplorer/CoverageRow.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx index 4af4fbbf4e..8b9da9d9e8 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx @@ -17,7 +17,6 @@ import React from 'react'; // styles import { makeStyles } from '@material-ui/core'; -import { red, green } from '@material-ui/core/colors'; const useStyles = makeStyles(theme => ({ lineNumberCell: { @@ -33,7 +32,7 @@ const useStyles = makeStyles(theme => ({ textAlign: 'center', color: 'white', // need to enforce this color since it needs to stand out against colored background paddingLeft: theme.spacing(1), - paddingRight: `${theme.spacing(1)}`, + paddingRight: theme.spacing(1), }, countRoundedRectangle: { borderRadius: '45px', @@ -42,10 +41,10 @@ const useStyles = makeStyles(theme => ({ width: '50px', }, hitCountRoundedRectangle: { - backgroundColor: green[500], + backgroundColor: `${theme.palette.success.main}`, }, notHitCountRoundedRectangle: { - backgroundColor: `${red[500]}`, + backgroundColor: `${theme.palette.error.main}`, }, codeLine: { paddingLeft: `${theme.spacing(1)}`, @@ -53,10 +52,10 @@ const useStyles = makeStyles(theme => ({ fontSize: '90%', }, hitCodeLine: { - backgroundColor: `${green[100]}`, + backgroundColor: `${theme.palette.success.main}`, }, notHitCodeLine: { - backgroundColor: `${red[100]}`, + backgroundColor: `${theme.palette.error.main}`, }, })); From fd2fe42176520b1b519d9fa80f98bc234b5d6d4a Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 15:20:14 -0400 Subject: [PATCH 149/462] FileContent: remove unnecessary styling on paper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../code-coverage/src/components/FileExplorer/FileContent.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index 0d7f495daf..afaff61340 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -36,7 +36,6 @@ const useStyles = makeStyles(theme => ({ margin: 'auto', top: '2em', width: '80%', - backgroundColor: theme.palette.background.paper, border: '2px solid #000', boxShadow: theme.shadows[5], padding: theme.spacing(2, 4, 3), From bf7a3aee587e10cb689412cc6cd0248d76169d63 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 15:54:26 -0400 Subject: [PATCH 150/462] may not be necessary to set source-location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage-backend/README.md | 2 +- plugins/code-coverage/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md index 3229dc940f..157b5e8ddb 100644 --- a/plugins/code-coverage-backend/README.md +++ b/plugins/code-coverage-backend/README.md @@ -16,7 +16,7 @@ There's a feature to only include files that are in VCS in the coverage report, backstage.io/code-coverage: scm-only ``` -Note: This requires the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) to be set. +Note: It may be required to set the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location), however this should generally not be needed. ## API diff --git a/plugins/code-coverage/README.md b/plugins/code-coverage/README.md index b93ad7a091..c271b9ff36 100644 --- a/plugins/code-coverage/README.md +++ b/plugins/code-coverage/README.md @@ -16,4 +16,4 @@ There's a feature to only include files that are in VCS in the coverage report, backstage.io/code-coverage: scm-only ``` -Note: This requires the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) to be set. +Note: It may be required to set the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location), however this should generally not be needed. From 12a45d22adf4d9eff2856e4ee99000e8f8c4cc46 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Mon, 19 Apr 2021 16:31:25 -0400 Subject: [PATCH 151/462] fix some tsc issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage/dev/index.tsx | 4 ++-- plugins/code-coverage/src/api.ts | 1 - plugins/code-coverage/src/dev/index.tsx | 5 +++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/code-coverage/dev/index.tsx b/plugins/code-coverage/dev/index.tsx index 9eabafb976..69ff4bcda2 100644 --- a/plugins/code-coverage/dev/index.tsx +++ b/plugins/code-coverage/dev/index.tsx @@ -15,12 +15,12 @@ */ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { codeCoveragePlugin, CodeCoveragePage } from '../src/plugin'; +import { codeCoveragePlugin, EntityCodeCoverageContent } from '../src/plugin'; createDevApp() .registerPlugin(codeCoveragePlugin) .addPage({ - element: <CodeCoveragePage />, + element: <EntityCodeCoverageContent />, title: 'Root Page', }) .render(); diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index 2fa2dab05a..d168f50d95 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -15,7 +15,6 @@ */ import { createApiRef, DiscoveryApi } from '@backstage/core'; -import { Config } from '@backstage/config'; import { EntityName, stringifyEntityRef } from '@backstage/catalog-model'; import { JsonCodeCoverage, diff --git a/plugins/code-coverage/src/dev/index.tsx b/plugins/code-coverage/src/dev/index.tsx index 5c944b097a..4bbcdf07c5 100644 --- a/plugins/code-coverage/src/dev/index.tsx +++ b/plugins/code-coverage/src/dev/index.tsx @@ -17,12 +17,13 @@ import { createDevApp } from '@backstage/dev-utils'; import { codeCoveragePlugin } from '../plugin'; import { codeCoverageApiRef, CodeCoverageRestApi } from '../api'; +import { discoveryApiRef } from '@backstage/core-api'; createDevApp() .registerPlugin(codeCoveragePlugin) .registerApi({ api: codeCoverageApiRef, - deps: {}, - factory: () => new CodeCoverageRestApi('http://localhost:3000'), + deps: { discoveryApi: discoveryApiRef }, + factory: ({ discoveryApi }) => new CodeCoverageRestApi(discoveryApi), }) .render(); From eb35e81128a641db4872a3cced572df8582dd8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Tue, 20 Apr 2021 14:19:23 +0200 Subject: [PATCH 152/462] update express-promise-router to the repo standard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage-backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 79de777dfa..8bcce8784d 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -29,7 +29,7 @@ "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "express": "^4.17.1", - "express-promise-router": "^3.0.3", + "express-promise-router": "^4.1.0", "express-xml-bodyparser": "^0.3.0", "knex": "^0.95.1", "uuid": "^8.3.2", From 9ed45248b918c5c6209d1a219c5c6ea45e905f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Tue, 20 Apr 2021 14:34:26 +0200 Subject: [PATCH 153/462] update vocab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .github/styles/vocab.txt | 3 +++ plugins/code-coverage-backend/README.md | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 5a778b5ea3..a12f638a74 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -10,6 +10,7 @@ Chai Changesets Chanwit Cloudformation +Cobertura Codecov Codehilite Config @@ -34,6 +35,7 @@ Hackathons Heroku Hostname Iain +JaCoCo JavaScript Kaewkasi Knex @@ -78,6 +80,7 @@ Tolerations WWW Weaveworks Webpack +XML Zalando Zhou abc diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md index 157b5e8ddb..8d1491ef14 100644 --- a/plugins/code-coverage-backend/README.md +++ b/plugins/code-coverage-backend/README.md @@ -20,9 +20,9 @@ Note: It may be required to set the [`backstage.io/source-location` annotation]( ## API -### Adding cobertura report +### Adding a Cobertura report -POST a cobertura xml to `/report` +POST a Cobertura XML file to `/report` Example: @@ -38,9 +38,9 @@ Example: } ``` -### Adding jacoco report +### Adding a JaCoCo report -POST a jacoco xml to `/report` +POST a JaCoCo XML file to `/report` Example: From 22a9a88b46c591cef3304020dd0d05b2bf348989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Tue, 20 Apr 2021 14:49:17 +0200 Subject: [PATCH 154/462] move to devdependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/code-coverage/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index eabd961f4b..a4a9cc5584 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -33,7 +33,6 @@ "@material-ui/icons": "^4.9.1", "@material-ui/styles": "^4.11.0", "@material-ui/lab": "4.0.0-alpha.57", - "@types/highlightjs": "^10.1.0", "highlight.js": "^10.6.0", "react": "^16.13.1", "react-dom": "^16.13.1", @@ -48,6 +47,7 @@ "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", + "@types/highlightjs": "^10.1.0", "@types/jest": "^26.0.7", "@types/node": "^12.0.0", "@types/recharts": "^1.8.15", From 7f521339b992636b8ed1e87a55db41a2ceeee5ca Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Tue, 20 Apr 2021 10:50:10 -0400 Subject: [PATCH 155/462] fix test fixture Signed-off-by: alde <r.dybeck@gmail.com> --- .../code-coverage-backend/src/service/CoverageUtils.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts b/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts index 5a5cffbced..4a96e67338 100644 --- a/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts +++ b/plugins/code-coverage-backend/src/service/CoverageUtils.test.ts @@ -305,7 +305,8 @@ describe('CodeCoverageUtils', () => { namespace: 'test', annotations: { 'backstage.io/code-coverage': 'scm-only', - 'backstage.io/source-location': 'https://github.com/example/test/', + 'backstage.io/source-location': + 'url:https://github.com/example/test/', }, }, apiVersion: 'backstage.io/v1alpha1', From 50bd7ce58ace0673668f5b07e11961cd661708f2 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Tue, 20 Apr 2021 11:48:23 -0400 Subject: [PATCH 156/462] align dependency versions Signed-off-by: alde <r.dybeck@gmail.com> --- plugins/code-coverage/package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index a4a9cc5584..974e93e430 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -24,15 +24,14 @@ "@backstage/config": "^0.1.3", "@backstage/core": "^0.7.5", "@backstage/core-api": "^0.2.12", - "@backstage/dev-utils": "^0.1.11", "@backstage/errors": "^0.1.0", "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/plugin-code-coverage-backend": "^0.1.0", - "@backstage/theme": "^0.2.3", + "@backstage/theme": "^0.2.5", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/styles": "^4.11.0", - "@material-ui/lab": "4.0.0-alpha.57", + "@material-ui/lab": "4.0.0-alpha.45", "highlight.js": "^10.6.0", "react": "^16.13.1", "react-dom": "^16.13.1", @@ -42,14 +41,15 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.8", + "@backstage/dev-utils": "^0.1.13", + "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", - "@testing-library/react": "^10.4.1", + "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.0.7", "@types/highlightjs": "^10.1.0", "@types/jest": "^26.0.7", - "@types/node": "^12.0.0", + "@types/node": "^14.14.32", "@types/recharts": "^1.8.15", "cross-fetch": "^3.0.6", "msw": "^0.21.2" From 5fa7f679339f8f04e58b40a39e5fd7a663619a72 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Tue, 20 Apr 2021 12:15:49 -0400 Subject: [PATCH 157/462] remove src/dev/ folder Signed-off-by: alde <r.dybeck@gmail.com> --- plugins/code-coverage/src/dev/index.tsx | 29 ------------------------- 1 file changed, 29 deletions(-) delete mode 100644 plugins/code-coverage/src/dev/index.tsx diff --git a/plugins/code-coverage/src/dev/index.tsx b/plugins/code-coverage/src/dev/index.tsx deleted file mode 100644 index 4bbcdf07c5..0000000000 --- a/plugins/code-coverage/src/dev/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createDevApp } from '@backstage/dev-utils'; -import { codeCoveragePlugin } from '../plugin'; -import { codeCoverageApiRef, CodeCoverageRestApi } from '../api'; -import { discoveryApiRef } from '@backstage/core-api'; - -createDevApp() - .registerPlugin(codeCoveragePlugin) - .registerApi({ - api: codeCoverageApiRef, - deps: { discoveryApi: discoveryApiRef }, - factory: ({ discoveryApi }) => new CodeCoverageRestApi(discoveryApi), - }) - .render(); From 87a82498b9bc506ef9ef03f84c23a5b9dd45cb7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 21 Apr 2021 12:45:31 +0200 Subject: [PATCH 158/462] final fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../well-known-annotations.md | 6 +- plugins/code-coverage-backend/README.md | 16 +- .../migrations/20210302_init.js | 25 +++- plugins/code-coverage-backend/package.json | 13 +- plugins/code-coverage-backend/src/index.ts | 2 - .../src/service/CodeCoverageDatabase.test.ts | 14 +- .../src/service/CodeCoverageDatabase.ts | 22 ++- .../src/service/CoverageUtils.ts | 6 +- .../src/service/converter/Converter.ts | 2 +- .../src/service/converter/cobertura.ts | 4 +- .../src/service/converter/jacoco.ts | 6 +- .../src/service/router.ts | 9 +- .../src/service/standaloneServer.ts | 20 ++- .../{jsoncoverage-types.ts => types.ts} | 0 plugins/code-coverage/README.md | 12 +- plugins/code-coverage/package.json | 10 +- plugins/code-coverage/src/api.ts | 29 +--- .../CoverageHistoryChart.tsx | 31 ++-- .../{CoverageRow.tsx => CodeRow.tsx} | 8 +- .../components/FileExplorer/FileContent.tsx | 15 +- .../components/FileExplorer/FileExplorer.tsx | 10 +- plugins/code-coverage/src/types.ts | 71 +++++++++ yarn.lock | 138 +----------------- 23 files changed, 205 insertions(+), 264 deletions(-) rename plugins/code-coverage-backend/src/service/{jsoncoverage-types.ts => types.ts} (100%) rename plugins/code-coverage/src/components/FileExplorer/{CoverageRow.tsx => CodeRow.tsx} (98%) create mode 100644 plugins/code-coverage/src/types.ts diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 5cfe8f39ef..67b92bd941 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -283,9 +283,9 @@ metadata: ``` The value of this annotation controls the code-coverage backstage plugin. If set -to smc-only the plugin will only take into account files stored in source -control (e.g. ignoring generated code). If set to any other non-false:y value -all files covered by a coverage report will be taken into account. +to `scm-only`, the plugin will only take into account files stored in source +control (e.g. ignoring generated code). If set to `enabled`, all files covered +by a coverage report will be taken into account. ## Deprecated Annotations diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md index 8d1491ef14..101bee3e3f 100644 --- a/plugins/code-coverage-backend/README.md +++ b/plugins/code-coverage-backend/README.md @@ -1,19 +1,23 @@ -# code-coverage +# code-coverage-backend -This is the backend part of the code-coverage plugin. It takes care of processing various coverage formats and standardizing them into a single json format, used by the frontend. +This is the backend part of the `code-coverage` plugin. It takes care of processing various coverage formats and standardizing them into a single json format, used by the frontend. ## Configuring your entity In order to use this plugin, you must set the `backstage.io/code-coverage` annotation. ```yaml -backstage.io/code-coverage: enabled +metadata: + annotations: + backstage.io/code-coverage: enabled ``` There's a feature to only include files that are in VCS in the coverage report, this is helpful to not count generated files for example. To enable this set the `backstage.io/code-coverage` annotation to `scm-only`. ```yaml -backstage.io/code-coverage: scm-only +metadata: + annotations: + backstage.io/code-coverage: scm-only ``` Note: It may be required to set the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location), however this should generally not be needed. @@ -31,7 +35,7 @@ Example: { "links": [ { - "href": "http://localhost:7000/api/code-coverage/Component/default/entity-name", + "href": "http://localhost:7000/api/code-coverage/report?entity=component:default/entity-name", "rel": "coverage" } ] @@ -49,7 +53,7 @@ Example: { "links": [ { - "href": "http://localhost:7000/api/code-coverage/Component/default/entity-name", + "href": "http://localhost:7000/api/code-coverage/report?entity=component:default/entity-name", "rel": "coverage" } ] diff --git a/plugins/code-coverage-backend/migrations/20210302_init.js b/plugins/code-coverage-backend/migrations/20210302_init.js index b156a9d08d..538f658948 100644 --- a/plugins/code-coverage-backend/migrations/20210302_init.js +++ b/plugins/code-coverage-backend/migrations/20210302_init.js @@ -20,14 +20,23 @@ * @param {import('knex').Knex} knex */ exports.up = async function up(knex) { + // Note for the reader: the knex increments types automatically make it a + // primary column, whether you like it or not. That's why the id column is + // not marked as primary as one might have expected; it's only used for + // lookups by ID. Because, SQLite and MySQL don't return RETURNING on + // inserts ... so we want a manually generated key for lookups (an uuid), + // and also an index for ordering guarantees :) await knex.schema.createTable('code_coverage', table => { table.comment('The table of code coverage'); table - .uuid('id') - .primary() + .bigIncrements('index') .notNullable() - .comment('The ID of the code coverage'); - table.text('entity').notNullable().comment('entity string reference'); + .comment('An insert counter to ensure ordering'); + table.uuid('id').notNullable().comment('The ID of the code coverage'); + table + .text('entity') + .notNullable() + .comment('The entity ref that this code coverage applies to'); table .text('coverage') .notNullable() @@ -37,6 +46,9 @@ exports.up = async function up(knex) { .defaultTo(knex.fn.now()) .notNullable() .comment('The timestamp when this entry was created'); + table.index('index', 'code_coverage_index_idx'); + table.index('id', 'code_coverage_id_idx'); + table.index('entity', 'code_coverage_entity_idx'); }); }; @@ -44,5 +56,10 @@ exports.up = async function up(knex) { * @param {import('knex').Knex} knex */ exports.down = async function down(knex) { + await knex.schema.alterTable('code_coverage', table => { + table.dropIndex([], 'code_coverage_index_idx'); + table.dropIndex([], 'code_coverage_id_idx'); + table.dropIndex([], 'code_coverage_entity_idx'); + }); await knex.schema.dropTable('code_coverage'); }; diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 8bcce8784d..1e7903b016 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -19,13 +19,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.5.4", - "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.2", - "@backstage/config": "^0.1.3", + "@backstage/backend-common": "^0.6.2", + "@backstage/catalog-client": "^0.3.10", + "@backstage/catalog-model": "^0.7.7", + "@backstage/config": "^0.1.4", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.0", - "@backstage/plugin-catalog-backend": "^0.6.5", + "@backstage/integration": "^0.5.1", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "express": "^4.17.1", @@ -37,7 +36,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.2", + "@backstage/cli": "^0.6.8", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", "msw": "^0.21.2", diff --git a/plugins/code-coverage-backend/src/index.ts b/plugins/code-coverage-backend/src/index.ts index 12de31b541..7612c392a2 100644 --- a/plugins/code-coverage-backend/src/index.ts +++ b/plugins/code-coverage-backend/src/index.ts @@ -15,5 +15,3 @@ */ export * from './service/router'; - -export * from './service/jsoncoverage-types'; diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts index 108146287d..688eeb4ba2 100644 --- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts @@ -13,17 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - getVoidLogger, - SingleConnectionDatabaseManager, -} from '@backstage/backend-common'; +import { SingleConnectionDatabaseManager } from '@backstage/backend-common'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { CodeCoverageDatabase, CodeCoverageStore, } from './CodeCoverageDatabase'; -import { JsonCodeCoverage } from './jsoncoverage-types'; +import { JsonCodeCoverage } from './types'; const db = SingleConnectionDatabaseManager.fromConfig( new ConfigReader({ @@ -103,10 +100,9 @@ let database: CodeCoverageStore; describe('CodeCoverageDatabase', () => { beforeAll(async () => { const client = await db.getClient(); - database = await CodeCoverageDatabase.create(client, getVoidLogger()); - database.insertCodeCoverage(coverage[0]); - await new Promise(r => setTimeout(r, 1000)); - database.insertCodeCoverage(coverage[1]); + database = await CodeCoverageDatabase.create(client); + await database.insertCodeCoverage(coverage[0]); + await database.insertCodeCoverage(coverage[1]); }); describe('insertCodeCoverage', () => { diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts index cb83c2f606..390fd815f1 100644 --- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts @@ -18,15 +18,15 @@ import { NotFoundError } from '@backstage/errors'; import { parseEntityName, stringifyEntityRef } from '@backstage/catalog-model'; import { Knex } from 'knex'; import { v4 as uuid } from 'uuid'; -import { Logger } from 'winston'; import { aggregateCoverage } from './CoverageUtils'; -import { JsonCodeCoverage, JsonCoverageHistory } from './jsoncoverage-types'; +import { JsonCodeCoverage, JsonCoverageHistory } from './types'; export type RawDbCoverageRow = { id: string; entity: string; coverage: string; }; + export interface CodeCoverageStore { insertCodeCoverage( coverage: JsonCodeCoverage, @@ -39,44 +39,49 @@ const migrationsDir = resolvePackagePath( '@backstage/plugin-code-coverage-backend', 'migrations', ); + export class CodeCoverageDatabase implements CodeCoverageStore { - static async create(knex: Knex, logger: Logger): Promise<CodeCoverageStore> { + static async create(knex: Knex): Promise<CodeCoverageStore> { await knex.migrate.latest({ directory: migrationsDir, }); - return new CodeCoverageDatabase(knex, logger); + return new CodeCoverageDatabase(knex); } - constructor(private readonly db: Knex, private readonly logger: Logger) {} + constructor(private readonly db: Knex) {} async insertCodeCoverage( coverage: JsonCodeCoverage, ): Promise<{ codeCoverageId: string }> { const codeCoverageId = uuid(); - this.logger.error(JSON.stringify(coverage.entity)); const entity = stringifyEntityRef({ kind: coverage.entity.kind, namespace: coverage.entity.namespace, name: coverage.entity.name, }); + await this.db<RawDbCoverageRow>('code_coverage').insert({ id: codeCoverageId, entity: entity, coverage: JSON.stringify(coverage), }); + return { codeCoverageId }; } + async getCodeCoverage(entity: string): Promise<JsonCodeCoverage> { const [result] = await this.db<RawDbCoverageRow>('code_coverage') .where({ entity: entity }) - .orderBy('created_at', 'desc') + .orderBy('index', 'desc') .limit(1) .select(); + if (!result) { throw new NotFoundError( `No coverage for entity '${JSON.stringify(entity)}' found`, ); } + try { return JSON.parse(result.coverage); } catch (error) { @@ -90,7 +95,7 @@ export class CodeCoverageDatabase implements CodeCoverageStore { ): Promise<JsonCoverageHistory> { const res = await this.db<RawDbCoverageRow>('code_coverage') .where({ entity: entity }) - .orderBy('created_at', 'desc') + .orderBy('index', 'desc') .limit(limit) .select(); @@ -99,6 +104,7 @@ export class CodeCoverageDatabase implements CodeCoverageStore { .map(c => aggregateCoverage(c)); const entityName = parseEntityName(entity); + return { entity: { name: entityName.name, diff --git a/plugins/code-coverage-backend/src/service/CoverageUtils.ts b/plugins/code-coverage-backend/src/service/CoverageUtils.ts index 4850ac9b1b..f41a1d05a0 100644 --- a/plugins/code-coverage-backend/src/service/CoverageUtils.ts +++ b/plugins/code-coverage-backend/src/service/CoverageUtils.ts @@ -22,11 +22,7 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { ScmIntegration, ScmIntegrations } from '@backstage/integration'; -import { - AggregateCoverage, - FileEntry, - JsonCodeCoverage, -} from './jsoncoverage-types'; +import { AggregateCoverage, FileEntry, JsonCodeCoverage } from './types'; export const calculatePercentage = ( available: number, diff --git a/plugins/code-coverage-backend/src/service/converter/Converter.ts b/plugins/code-coverage-backend/src/service/converter/Converter.ts index 20c6920c99..43d9855e61 100644 --- a/plugins/code-coverage-backend/src/service/converter/Converter.ts +++ b/plugins/code-coverage-backend/src/service/converter/Converter.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { FileEntry } from '../jsoncoverage-types'; +import { FileEntry } from '../types'; export interface Converter { convert(xml: unknown, scmFiles: Array<string>): Array<FileEntry>; diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.ts index fd3cfe9c01..02ac187387 100644 --- a/plugins/code-coverage-backend/src/service/converter/cobertura.ts +++ b/plugins/code-coverage-backend/src/service/converter/cobertura.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BranchHit, FileEntry } from '../jsoncoverage-types'; +import { BranchHit, FileEntry } from '../types'; import { CoberturaXML, InnerClass, LineHit } from './types'; import { Logger } from 'winston'; import { Converter } from './Converter'; @@ -63,7 +63,7 @@ export class Cobertura implements Converter { }); const currentFile = scmFiles.find(f => f.endsWith(packageAndFilename)); - this.logger.info(`matched ${packageAndFilename} to ${currentFile}`); + this.logger.debug(`matched ${packageAndFilename} to ${currentFile}`); if ( scmFiles.length === 0 || (Object.keys(lineHits).length > 0 && currentFile) diff --git a/plugins/code-coverage-backend/src/service/converter/jacoco.ts b/plugins/code-coverage-backend/src/service/converter/jacoco.ts index 8dfcf0cb51..4c554fec91 100644 --- a/plugins/code-coverage-backend/src/service/converter/jacoco.ts +++ b/plugins/code-coverage-backend/src/service/converter/jacoco.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BranchHit, FileEntry } from '../jsoncoverage-types'; +import { BranchHit, FileEntry } from '../types'; import { JacocoSourceFile, JacocoXML } from './types'; import { Logger } from 'winston'; import { Converter } from './Converter'; @@ -35,7 +35,7 @@ export class Jacoco implements Converter { * Converts jacoco into shared json coverage format * * @param xml jacoco xml object - * @param scmFiles list of files that are commited to SCM + * @param scmFiles list of files that are committed to SCM */ convert(xml: JacocoXML, scmFiles: Array<string>): Array<FileEntry> { const jscov: Array<FileEntry> = []; @@ -64,7 +64,7 @@ export class Jacoco implements Converter { const packageAndFilename = `${packageName}/${fileName}`; const currentFile = scmFiles.find(f => f.endsWith(packageAndFilename)); - this.logger.info(`matched ${packageAndFilename} to ${currentFile}`); + this.logger.debug(`matched ${packageAndFilename} to ${currentFile}`); if (Object.keys(lineHits).length > 0 && currentFile) { jscov.push({ filename: currentFile, diff --git a/plugins/code-coverage-backend/src/service/router.ts b/plugins/code-coverage-backend/src/service/router.ts index f2e34cd07a..78aeab313c 100644 --- a/plugins/code-coverage-backend/src/service/router.ts +++ b/plugins/code-coverage-backend/src/service/router.ts @@ -58,7 +58,6 @@ export const makeRouter = async ( const codeCoverageDatabase = await CodeCoverageDatabase.create( await database.getClient(), - logger, ); const codecovUrl = await discovery.getExternalBaseUrl('code-coverage'); const catalogApi = new CatalogClient({ discoveryApi: discovery }); @@ -147,8 +146,8 @@ export const makeRouter = async ( const scmTree = await urlReader.readTree(sourceLocation.target); const scmFile = (await scmTree.files()).find(f => f.path === path); if (!scmFile) { - res.status(400).json({ - message: "couldn't find file in SCM", + res.status(404).json({ + message: "Couldn't find file in SCM", file: path, scm: vcs.title, }); @@ -157,7 +156,7 @@ export const makeRouter = async ( const content = await scmFile?.content(); if (!content) { res.status(400).json({ - message: "couldn't process content of file in SCM", + message: "Couldn't process content of file in SCM", file: path, scm: vcs.title, }); @@ -187,7 +186,7 @@ export const makeRouter = async ( } else if (coverageType === 'cobertura') { converter = new Cobertura(logger); } else { - throw new NotFoundError(`unsupported coverage type '${coverageType}`); + throw new InputError(`Unsupported coverage type '${coverageType}`); } const { diff --git a/plugins/code-coverage-backend/src/service/standaloneServer.ts b/plugins/code-coverage-backend/src/service/standaloneServer.ts index 8a3c4eaea1..2fb9627936 100644 --- a/plugins/code-coverage-backend/src/service/standaloneServer.ts +++ b/plugins/code-coverage-backend/src/service/standaloneServer.ts @@ -22,9 +22,9 @@ import { useHotMemoize, } from '@backstage/backend-common'; import { Server } from 'http'; +import knexFactory from 'knex'; import { Logger } from 'winston'; import { createRouter } from './router'; -import { DatabaseManager } from '@backstage/plugin-catalog-backend'; export interface ServerOptions { port: number; @@ -38,13 +38,23 @@ export async function startStandaloneServer( const logger = options.logger.child({ service: 'code-coverage-backend' }); const config = await loadBackendConfig({ logger, argv: process.argv }); - const db = useHotMemoize(module, () => - DatabaseManager.createInMemoryDatabaseConnection(), - ); + const db = useHotMemoize(module, () => { + const knex = knexFactory({ + client: 'sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }); + + knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { + resource.run('PRAGMA foreign_keys = ON', () => {}); + }); + + return knex; + }); logger.debug('Starting application server...'); const router = await createRouter({ - database: { getClient: () => db }, + database: { getClient: async () => db }, config, discovery: SingleHostDiscovery.fromConfig(config), urlReader: UrlReaders.default({ logger, config }), diff --git a/plugins/code-coverage-backend/src/service/jsoncoverage-types.ts b/plugins/code-coverage-backend/src/service/types.ts similarity index 100% rename from plugins/code-coverage-backend/src/service/jsoncoverage-types.ts rename to plugins/code-coverage-backend/src/service/types.ts diff --git a/plugins/code-coverage/README.md b/plugins/code-coverage/README.md index c271b9ff36..8903668507 100644 --- a/plugins/code-coverage/README.md +++ b/plugins/code-coverage/README.md @@ -1,19 +1,23 @@ # code-coverage -This is the frontend part of the code-coverage plugin. It takes care of processing various coverage formats and standardizing them into a single json format, used by the frontend. +This is the frontend part of the code-coverage plugin. It displays code coverage summaries for your entities. ## Configuring your entity -In order to use this plugin, you must set the `backstage.io/code-coverage` annotation. +In order to use this plugin, you must set the `backstage.io/code-coverage` annotation on entities for which coverage ingestion has been enabled. ```yaml -backstage.io/code-coverage: enabled +metadata: + annotations: + backstage.io/code-coverage: enabled ``` There's a feature to only include files that are in VCS in the coverage report, this is helpful to not count generated files for example. To enable this set the `backstage.io/code-coverage` annotation to `scm-only`. ```yaml -backstage.io/code-coverage: scm-only +metadata: + annotations: + backstage.io/code-coverage: scm-only ``` Note: It may be required to set the [`backstage.io/source-location` annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location), however this should generally not be needed. diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 974e93e430..1d02da3dea 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -20,13 +20,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.2", - "@backstage/config": "^0.1.3", + "@backstage/catalog-model": "^0.7.7", + "@backstage/config": "^0.1.4", "@backstage/core": "^0.7.5", - "@backstage/core-api": "^0.2.12", - "@backstage/errors": "^0.1.0", - "@backstage/plugin-catalog-react": "^0.1.0", - "@backstage/plugin-code-coverage-backend": "^0.1.0", + "@backstage/errors": "^0.1.1", + "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.5", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index d168f50d95..6331f8020f 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -14,27 +14,10 @@ * limitations under the License. */ -import { createApiRef, DiscoveryApi } from '@backstage/core'; import { EntityName, stringifyEntityRef } from '@backstage/catalog-model'; -import { - JsonCodeCoverage, - JsonCoverageHistory, -} from '@backstage/plugin-code-coverage-backend'; +import { createApiRef, DiscoveryApi } from '@backstage/core'; import { ResponseError } from '@backstage/errors'; - -export class FetchError extends Error { - get name(): string { - return this.constructor.name; - } - - static async forResponse(resp: Response): Promise<FetchError> { - return new FetchError( - `Request failed with status code ${ - resp.status - }.\nReason: ${await resp.text()}`, - ); - } -} +import { JsonCodeCoverage, JsonCoverageHistory } from './types'; export type CodeCoverageApi = { discovery: DiscoveryApi; @@ -79,7 +62,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { async getCoverageForEntity( entityName: EntityName, ): Promise<JsonCodeCoverage> { - const entity = encodeURI(stringifyEntityRef(entityName)); + const entity = encodeURIComponent(stringifyEntityRef(entityName)); return (await this.fetch<JsonCodeCoverage>( `/report?entity=${entity}`, )) as JsonCodeCoverage; @@ -89,7 +72,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { entityName: EntityName, filePath: string, ): Promise<string> { - const entity = encodeURI(stringifyEntityRef(entityName)); + const entity = encodeURIComponent(stringifyEntityRef(entityName)); return await this.fetch<string>( `/file-content?entity=${entity}&path=${encodeURI(filePath)}`, ); @@ -99,11 +82,11 @@ export class CodeCoverageRestApi implements CodeCoverageApi { entityName: EntityName, limit?: number, ): Promise<JsonCoverageHistory> { - const entity = encodeURI(stringifyEntityRef(entityName)); + const entity = encodeURIComponent(stringifyEntityRef(entityName)); const hasValidLimit = limit && limit > 0; return (await this.fetch<JsonCoverageHistory>( `/history?entity=${entity}${ - hasValidLimit ? `&limit=${encodeURI(`${limit}`)}` : '' + hasValidLimit ? `&limit=${encodeURIComponent(String(limit))}` : '' }`, )) as JsonCoverageHistory; } diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index f9927a17d3..7bb4648f6f 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -14,7 +14,9 @@ * limitations under the License. */ -import React from 'react'; +import { Progress, ResponseErrorPanel, useApi } from '@backstage/core'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { BackstageTheme } from '@backstage/theme'; import { Box, Card, @@ -23,27 +25,24 @@ import { makeStyles, Typography, } from '@material-ui/core'; +import TrendingDownIcon from '@material-ui/icons/TrendingDown'; +import TrendingFlatIcon from '@material-ui/icons/TrendingFlat'; +import TrendingUpIcon from '@material-ui/icons/TrendingUp'; +import { Alert } from '@material-ui/lab'; +import { ClassNameMap } from '@material-ui/styles'; +import React from 'react'; +import { useAsync } from 'react-use'; import { - LineChart, - XAxis, - YAxis, - Tooltip, + CartesianGrid, Legend, Line, - CartesianGrid, + LineChart, ResponsiveContainer, + Tooltip, + XAxis, + YAxis, } from 'recharts'; -import { useAsync } from 'react-use'; -import { useApi } from '@backstage/core-api'; -import { useEntity } from '@backstage/plugin-catalog-react'; import { codeCoverageApiRef } from '../../api'; -import { Progress, ResponseErrorPanel } from '@backstage/core'; -import { Alert } from '@material-ui/lab'; -import TrendingDownIcon from '@material-ui/icons/TrendingDown'; -import TrendingUpIcon from '@material-ui/icons/TrendingUp'; -import TrendingFlatIcon from '@material-ui/icons/TrendingFlat'; -import { BackstageTheme } from '@backstage/theme'; -import { ClassNameMap } from '@material-ui/styles'; type Coverage = 'line' | 'branch'; diff --git a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx b/plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx similarity index 98% rename from plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx rename to plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx index 8b9da9d9e8..bd982b0f6b 100644 --- a/plugins/code-coverage/src/components/FileExplorer/CoverageRow.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/CodeRow.tsx @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; -// styles +import React from 'react'; import { makeStyles } from '@material-ui/core'; const useStyles = makeStyles(theme => ({ @@ -64,7 +63,8 @@ type CodeRowProps = { lineContent: string; lineHits?: number | null; }; -const CodeRow = ({ + +export const CodeRow = ({ lineNumber, lineContent, lineHits = null, @@ -98,5 +98,3 @@ const CodeRow = ({ </tr> ); }; - -export default CodeRow; diff --git a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx index afaff61340..b43874123d 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileContent.tsx @@ -14,17 +14,16 @@ * limitations under the License. */ -import React from 'react'; -import { useApi } from '@backstage/core-api'; +import { Progress, ResponseErrorPanel, useApi } from '@backstage/core'; import { useEntity } from '@backstage/plugin-catalog-react'; +import { makeStyles, Paper } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; import { useAsync } from 'react-use'; import { codeCoverageApiRef } from '../../api'; -import { Progress, ResponseErrorPanel } from '@backstage/core'; -import { Alert } from '@material-ui/lab'; -import { makeStyles, Paper } from '@material-ui/core'; +import { FileEntry } from '../../types'; +import { CodeRow } from './CodeRow'; import { highlightLines } from './Highlighter'; -import CoverageRow from './CoverageRow'; -import { FileEntry } from '@backstage/plugin-code-coverage-backend'; type Props = { filename: string; @@ -61,7 +60,7 @@ const FormattedLines = ({ {highlightedLines.map((lineContent, idx) => { const line = idx + 1; return ( - <CoverageRow + <CodeRow key={line} lineNumber={line} lineContent={lineContent} diff --git a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx index 704edcdf15..b49b78c5dc 100644 --- a/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx +++ b/plugins/code-coverage/src/components/FileExplorer/FileExplorer.tsx @@ -14,14 +14,14 @@ * limitations under the License. */ -import { useApi } from '@backstage/core-api'; -import { useEntity } from '@backstage/plugin-catalog-react'; import { Progress, ResponseErrorPanel, Table, TableColumn, + useApi, } from '@backstage/core'; +import { useEntity } from '@backstage/plugin-catalog-react'; import { Box, Card, @@ -30,13 +30,13 @@ import { Modal, Tooltip, } from '@material-ui/core'; +import DescriptionIcon from '@material-ui/icons/Description'; +import { Alert } from '@material-ui/lab'; import React, { Fragment, useEffect, useState } from 'react'; import { useAsync } from 'react-use'; import { codeCoverageApiRef } from '../../api'; -import DescriptionIcon from '@material-ui/icons/Description'; +import { FileEntry } from '../../types'; import { FileContent } from './FileContent'; -import { Alert } from '@material-ui/lab'; -import { FileEntry } from '@backstage/plugin-code-coverage-backend'; type FileStructureObject = Record<string, any>; diff --git a/plugins/code-coverage/src/types.ts b/plugins/code-coverage/src/types.ts new file mode 100644 index 0000000000..34fcf57968 --- /dev/null +++ b/plugins/code-coverage/src/types.ts @@ -0,0 +1,71 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { EntityName } from '@backstage/catalog-model'; + +export type JsonCodeCoverage = { + metadata: CoverageMetadata; + entity: EntityName; + files: Array<FileEntry>; +}; + +export type JsonCoverageHistory = { + entity: EntityName; + history: Array<AggregateCoverage>; +}; + +export type CoverageHistory = { + line: { + available: number; + covered: number; + }; + branch: BranchHit; +}; + +export type CoverageMetadata = { + vcs: { + type: string; + location: string; + }; + generationTime: number; +}; + +export type BranchHit = { + covered: number; + missed: number; + available: number; +}; + +export type FileEntry = { + filename: string; + lineHits: Record<number, number>; + branchHits: Record<number, BranchHit>; +}; + +export type AggregateCoverage = { + timestamp: number; + line: { + available: number; + covered: number; + missed: number; + percentage: number; + }; + branch: { + available: number; + covered: number; + missed: number; + percentage: number; + }; +}; diff --git a/yarn.lock b/yarn.lock index 79f7d85b38..f614a7713a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,7 +1616,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.13.10" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== @@ -1679,95 +1679,6 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@backstage/backend-common@^0.5.4": - version "0.5.6" - resolved "https://registry.npmjs.org/@backstage/backend-common/-/backend-common-0.5.6.tgz#e49840eaa6738f6697319ccdfff04ce40cc54b72" - integrity sha512-BzKlcTZLAVDpH87fi2TCWIFO9DfVdaPIIZ8gZSorCuLLErG4X7CS/zQiujJZ/zD5HGtO2QB57fuRkwjBMhJhhw== - dependencies: - "@backstage/cli-common" "^0.1.1" - "@backstage/config" "^0.1.2" - "@backstage/config-loader" "^0.5.1" - "@backstage/integration" "^0.5.1" - "@octokit/rest" "^18.0.12" - "@types/cors" "^2.8.6" - "@types/dockerode" "^3.2.1" - "@types/express" "^4.17.6" - archiver "^5.0.2" - compression "^1.7.4" - concat-stream "^2.0.0" - cors "^2.8.5" - cross-fetch "^3.0.6" - dockerode "^3.2.1" - express "^4.17.1" - express-promise-router "^3.0.3" - fs-extra "^9.0.1" - git-url-parse "^11.4.4" - helmet "^4.0.0" - isomorphic-git "^1.8.0" - knex "^0.95.1" - lodash "^4.17.15" - logform "^2.1.1" - minimatch "^3.0.4" - minimist "^1.2.5" - morgan "^1.10.0" - selfsigned "^1.10.7" - stoppable "^1.1.0" - tar "^6.0.5" - unzipper "^0.10.11" - winston "^3.2.1" - -"@backstage/config-loader@^0.5.1": - version "0.5.1" - resolved "https://registry.npmjs.org/@backstage/config-loader/-/config-loader-0.5.1.tgz#a80f2047e209d2f41b17ad715c632ab142385b39" - integrity sha512-PmwXERs5BIf77sUIg3Fhp/elkR6ELj0czmpUgP4cuEdtazi0WcmdjCUC2DjgsKJWvYggsL1o372QKHh/M5AMTQ== - dependencies: - "@backstage/cli-common" "^0.1.1" - "@backstage/config" "^0.1.1" - ajv "^7.0.3" - fs-extra "^9.0.0" - json-schema "^0.2.5" - json-schema-merge-allof "^0.7.0" - typescript-json-schema "^0.47.0" - yaml "^1.9.2" - yup "^0.29.3" - -"@backstage/plugin-catalog-backend@^0.6.5": - version "0.6.7" - resolved "https://registry.npmjs.org/@backstage/plugin-catalog-backend/-/plugin-catalog-backend-0.6.7.tgz#97d0ed6db6aeb04e09ed0fee05e76bacf66cc179" - integrity sha512-Ey9PXyUjmi8IxQNSXBhF6Sl2SmZ/iXCFHXnffH8XCdBFTZS8HDRE2tSOlIIU4XQKd6lJVuAGTekas2DkaS9/lA== - dependencies: - "@azure/msal-node" "^1.0.0-beta.3" - "@backstage/backend-common" "^0.6.0" - "@backstage/catalog-model" "^0.7.4" - "@backstage/config" "^0.1.4" - "@backstage/errors" "^0.1.1" - "@backstage/integration" "^0.5.1" - "@backstage/plugin-search-backend-node" "^0.1.2" - "@backstage/search-common" "^0.1.1" - "@octokit/graphql" "^4.5.8" - "@types/express" "^4.17.6" - "@types/ldapjs" "^1.0.9" - aws-sdk "^2.840.0" - codeowners-utils "^1.0.2" - core-js "^3.6.5" - cross-fetch "^3.0.6" - express "^4.17.1" - express-promise-router "^4.1.0" - fs-extra "^9.0.0" - git-url-parse "^11.4.4" - glob "^7.1.6" - knex "^0.95.1" - ldapjs "^2.2.0" - lodash "^4.17.15" - morgan "^1.10.0" - p-limit "^3.0.2" - qs "^6.9.4" - uuid "^8.0.0" - winston "^3.2.1" - yaml "^1.9.2" - yn "^4.0.0" - yup "^0.29.3" - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -5609,20 +5520,6 @@ lz-string "^1.4.4" pretty-format "^26.6.2" -"@testing-library/dom@^7.22.3": - version "7.30.3" - resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-7.30.3.tgz#779ea9bbb92d63302461800a388a5a890ac22519" - integrity sha512-7JhIg2MW6WPwyikH2iL3o7z+FTVgSOd2jqCwTAHqK7Qal2gRRYiUQyURAxtbK9VXm/UTyG9bRihv8C5Tznr2zw== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^4.2.0" - aria-query "^4.2.2" - chalk "^4.1.0" - dom-accessibility-api "^0.5.4" - lz-string "^1.4.4" - pretty-format "^26.6.2" - "@testing-library/jest-dom@^5.10.1": version "5.11.9" resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.11.9.tgz#e6b3cd687021f89f261bd53cbe367041fbd3e975" @@ -5653,14 +5550,6 @@ "@babel/runtime" "^7.5.4" "@types/testing-library__react-hooks" "^3.4.0" -"@testing-library/react@^10.4.1": - version "10.4.9" - resolved "https://registry.npmjs.org/@testing-library/react/-/react-10.4.9.tgz#9faa29c6a1a217bf8bbb96a28bd29d7a847ca150" - integrity sha512-pHZKkqUy0tmiD81afs8xfiuseXfU/N7rAX3iKjeZYje86t9VaB0LrxYVa+OOsvkrveX5jCK3IjajVn2MbePvqA== - dependencies: - "@babel/runtime" "^7.10.3" - "@testing-library/dom" "^7.22.3" - "@testing-library/react@^11.2.5": version "11.2.6" resolved "https://registry.npmjs.org/@testing-library/react/-/react-11.2.6.tgz#586a23adc63615985d85be0c903f374dab19200b" @@ -6439,11 +6328,6 @@ resolved "https://registry.npmjs.org/@types/node/-/node-10.17.35.tgz#58058f29b870e6ae57b20e4f6e928f02b7129f56" integrity sha512-gXx7jAWpMddu0f7a+L+txMplp3FnHl53OhQIF9puXKq3hDGY/GjH+MF04oWnV/adPSCrbtHumDCFwzq2VhltWA== -"@types/node@^12.0.0": - version "12.20.10" - resolved "https://registry.npmjs.org/@types/node/-/node-12.20.10.tgz#4dcb8a85a8f1211acafb88d72fafc7e3d2685583" - integrity sha512-TxCmnSSppKBBOzYzPR2BR25YlX5Oay8z2XGwFBInuA/Co0V9xJhLlW4kjbxKtgeNo3NOMbQP1A5Rc03y+XecPw== - "@types/node@^12.7.1": version "12.12.58" resolved "https://registry.npmjs.org/@types/node/-/node-12.12.58.tgz#46dae9b2b9ee5992818c8f7cee01ff4ce03ab44c" @@ -12975,15 +12859,6 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" -express-promise-router@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/express-promise-router/-/express-promise-router-3.0.3.tgz#5e6d22a5a3f013d71833172fe8d7ab780c3f6b70" - integrity sha1-Xm0ipaPwE9cYMxcv6NereAw/a3A= - dependencies: - is-promise "^2.1.0" - lodash.flattendeep "^4.0.0" - methods "^1.0.0" - express-promise-router@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/express-promise-router/-/express-promise-router-4.1.0.tgz#79160e145c27610ba411bceb0552a36f11dbab4f" @@ -25778,17 +25653,6 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript-json-schema@^0.47.0: - version "0.47.0" - resolved "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.47.0.tgz#84dde5460b127c6774da81bf70b23c7e04857b13" - integrity sha512-A6NVwSOTSsNDHfaqDcDeKwwyXEeKqBHoAr20jcetnYj4e8C6zVFofAVhAuwsBXCRYiWEE/lyHrcxpsSpbIk0Mg== - dependencies: - "@types/json-schema" "^7.0.6" - glob "^7.1.6" - json-stable-stringify "^1.0.1" - typescript "^4.1.3" - yargs "^16.2.0" - typescript-json-schema@^0.49.0: version "0.49.0" resolved "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.49.0.tgz#442f6347ca85fb0d9811f217fb0d6537b68734b3" From 87c4f59deaab876d159661250319f859feb83890 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Wed, 21 Apr 2021 15:18:49 +0200 Subject: [PATCH 159/462] Add low german greeting Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/new-shirts-move.md | 5 +++++ .../CatalogPage/utils/locales/goodAfternoon.locales.json | 1 + .../CatalogPage/utils/locales/goodEvening.locales.json | 1 + .../CatalogPage/utils/locales/goodMorning.locales.json | 1 + 4 files changed, 8 insertions(+) create mode 100644 .changeset/new-shirts-move.md diff --git a/.changeset/new-shirts-move.md b/.changeset/new-shirts-move.md new file mode 100644 index 0000000000..3896c85bbb --- /dev/null +++ b/.changeset/new-shirts-move.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Add low german greeting diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json index 4d48666666..1c5f5fd2b0 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json @@ -68,6 +68,7 @@ "Latvian": "Labdien", "Limburgish": "Gojemiddig", "Lithuanian": "Laba diena", + "Low German": "Moin", "Lozi": "Ki musihali", "Lule Sámi": "Buorre biejvve", "Luxembourgish": "Gudde Mëtteg", diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json index 36d48eaf39..b8ec898a56 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json @@ -56,6 +56,7 @@ "Kurdish": "Evarbash", "Latvian": "Labvakar", "Lithuanian": "Labas vakaras", + "Low German": "Moin", "Luganda": "Osiibye otya nno", "Luo": "Oimore", "Luxembourgish": "Gudden Owend", diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json index febbc32c49..27ac91daaa 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json @@ -32,6 +32,7 @@ "Kazakh": "Kayırlı tan", "Kurdish": "Beyanî baş", "Lithuanian": "Labas rytas", + "Low German": "Moin", "Macedonian": "Добро утро", "Malay": "Selamat pagi", "Maltese": "Bonġu", From 5fe62f124e05e16298659cd9990db3bfc7d54aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Tue, 20 Apr 2021 20:19:35 +0200 Subject: [PATCH 160/462] Fix the schema / code mismatch in LDAP `set` config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/light-fireants-flow.md | 5 +++++ .../ingestion/processors/ldap/config.test.ts | 14 +++++++------- .../src/ingestion/processors/ldap/config.ts | 17 +++++++---------- .../src/ingestion/processors/ldap/read.ts | 6 +++--- 4 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 .changeset/light-fireants-flow.md diff --git a/.changeset/light-fireants-flow.md b/.changeset/light-fireants-flow.md new file mode 100644 index 0000000000..a8f7b09278 --- /dev/null +++ b/.changeset/light-fireants-flow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Fix the schema / code mismatch in LDAP `set` config diff --git a/plugins/catalog-backend/src/ingestion/processors/ldap/config.test.ts b/plugins/catalog-backend/src/ingestion/processors/ldap/config.test.ts index aac9a091b8..607581e153 100644 --- a/plugins/catalog-backend/src/ingestion/processors/ldap/config.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/ldap/config.test.ts @@ -88,7 +88,7 @@ describe('readLdapConfig', () => { filter: 'f', paged: true, }, - set: [{ path: 'p', value: 'v' }], + set: { p: 'v' }, map: { rdn: 'u', name: 'v', @@ -107,7 +107,7 @@ describe('readLdapConfig', () => { filter: 'f', paged: true, }, - set: [{ path: 'p', value: 'v' }], + set: { p: 'v' }, map: { rdn: 'u', name: 'v', @@ -136,7 +136,7 @@ describe('readLdapConfig', () => { filter: 'f', paged: true, }, - set: [{ path: 'p', value: 'v' }], + set: { p: 'v' }, map: { rdn: 'u', name: 'v', @@ -155,7 +155,7 @@ describe('readLdapConfig', () => { filter: 'f', paged: true, }, - set: [{ path: 'p', value: 'v' }], + set: { p: 'v' }, map: { rdn: 'u', name: 'v', @@ -182,9 +182,9 @@ describe('readLdapConfig', () => { dn: 'udn', options: { filter: ` - (| - (cn=foo bar) - (cn=bar) + (| + (cn=foo bar) + (cn=bar) ) `, }, diff --git a/plugins/catalog-backend/src/ingestion/processors/ldap/config.ts b/plugins/catalog-backend/src/ingestion/processors/ldap/config.ts index 625282ca05..aca02e6e10 100644 --- a/plugins/catalog-backend/src/ingestion/processors/ldap/config.ts +++ b/plugins/catalog-backend/src/ingestion/processors/ldap/config.ts @@ -57,7 +57,7 @@ export type UserConfig = { // default is scope "one" and attributes "*" and "+". options: SearchOptions; // JSON paths (on a.b.c form) and hard coded values to set on those paths - set?: { path: string; value: JsonValue }[]; + set?: { [path: string]: JsonValue }; // Mappings from well known entity fields, to LDAP attribute names map: { // The name of the attribute that holds the relative distinguished name of @@ -94,7 +94,7 @@ export type GroupConfig = { // Only the scope, filter, attributes, and paged fields are supported. options: SearchOptions; // JSON paths (on a.b.c form) and hard coded values to set on those paths - set?: { path: string; value: JsonValue }[]; + set?: { [path: string]: JsonValue }; // Mappings from well known entity fields, to LDAP attribute names map: { // The name of the attribute that holds the relative distinguished name of @@ -189,15 +189,12 @@ export function readLdapConfig(config: Config): LdapProviderConfig[] { } function readSetConfig( - c: Config[] | undefined, - ): { path: string; value: JsonValue }[] | undefined { + c: Config | undefined, + ): { [path: string]: JsonValue } | undefined { if (!c) { return undefined; } - return c.map(entry => ({ - path: entry.getString('path'), - value: entry.get('value'), - })); + return Object.fromEntries(c.keys().map(path => [path, c.get(path)])); } function readUserMapConfig( @@ -244,7 +241,7 @@ export function readLdapConfig(config: Config): LdapProviderConfig[] { return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), - set: readSetConfig(c.getOptionalConfigArray('set')), + set: readSetConfig(c.getOptionalConfig('set')), map: readUserMapConfig(c.getOptionalConfig('map')), }; } @@ -255,7 +252,7 @@ export function readLdapConfig(config: Config): LdapProviderConfig[] { return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), - set: readSetConfig(c.getOptionalConfigArray('set')), + set: readSetConfig(c.getOptionalConfig('set')), map: readGroupMapConfig(c.getOptionalConfig('map')), }; } diff --git a/plugins/catalog-backend/src/ingestion/processors/ldap/read.ts b/plugins/catalog-backend/src/ingestion/processors/ldap/read.ts index 3162fbd01c..68542b5b30 100644 --- a/plugins/catalog-backend/src/ingestion/processors/ldap/read.ts +++ b/plugins/catalog-backend/src/ingestion/processors/ldap/read.ts @@ -15,6 +15,7 @@ */ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import { SearchEntry } from 'ldapjs'; import lodashSet from 'lodash/set'; import { buildOrgHierarchy } from '../util/org'; import { LdapClient } from './client'; @@ -25,7 +26,6 @@ import { LDAP_UUID_ANNOTATION, } from './constants'; import { LdapVendor } from './vendors'; -import { SearchEntry } from 'ldapjs'; /** * Reads users out of an LDAP provider. @@ -63,7 +63,7 @@ export async function readLdapUsers( }; if (set) { - for (const { path, value } of set) { + for (const [path, value] of Object.entries(set)) { lodashSet(entity, path, value); } } @@ -142,7 +142,7 @@ export async function readLdapGroups( }; if (set) { - for (const { path, value } of set) { + for (const [path, value] of Object.entries(set)) { lodashSet(entity, path, value); } } From d0addca8602ad42133415786693765d88e900317 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Wed, 21 Apr 2021 13:14:46 -0400 Subject: [PATCH 161/462] [code-coverage] fix so tests work in windows Use path.resolve, and trim end of scmFiles Signed-off-by: alde <r.dybeck@gmail.com> --- .../src/service/converter/cobertura.test.ts | 22 ++++++++++++++++--- .../src/service/converter/cobertura.ts | 4 +++- .../src/service/converter/jacoco.test.ts | 13 ++++++++--- .../src/service/converter/jacoco.ts | 4 +++- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts index 72d4018f94..0e67d35d7a 100644 --- a/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts +++ b/plugins/code-coverage-backend/src/service/converter/cobertura.test.ts @@ -15,6 +15,7 @@ */ import { parseString } from 'xml2js'; import fs from 'fs'; +import path from 'path'; import { Cobertura } from './cobertura'; import { CoberturaXML } from './types'; import { getVoidLogger } from '@backstage/backend-common'; @@ -27,7 +28,12 @@ describe('convert cobertura', () => { let fixture: CoberturaXML; parseString( fs.readFileSync( - `${__dirname}/../__fixtures__/cobertura-testdata-${idx}.xml`, + path.resolve( + __dirname, + '..', + '__fixtures__', + `cobertura-testdata-${idx}.xml`, + ), ), (_e, r) => { fixture = r; @@ -36,13 +42,23 @@ describe('convert cobertura', () => { const expected = JSON.parse( fs .readFileSync( - `${__dirname}/../__fixtures__/cobertura-jsoncoverage-files-${idx}.json`, + path.resolve( + __dirname, + '..', + '__fixtures__', + `cobertura-jsoncoverage-files-${idx}.json`, + ), ) .toString(), ); const scmFiles = fs .readFileSync( - `${__dirname}/../__fixtures__/cobertura-sourcefiles-${idx}.txt`, + path.resolve( + __dirname, + '..', + '__fixtures__', + `cobertura-sourcefiles-${idx}.txt`, + ), ) .toString() .split('\n'); diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.ts index 02ac187387..fcaea839ee 100644 --- a/plugins/code-coverage-backend/src/service/converter/cobertura.ts +++ b/plugins/code-coverage-backend/src/service/converter/cobertura.ts @@ -62,7 +62,9 @@ export class Cobertura implements Converter { } }); - const currentFile = scmFiles.find(f => f.endsWith(packageAndFilename)); + const currentFile = scmFiles + .map(f => f.trimEnd()) + .find(f => f.endsWith(packageAndFilename)); this.logger.debug(`matched ${packageAndFilename} to ${currentFile}`); if ( scmFiles.length === 0 || diff --git a/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts b/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts index 48202748da..0507cf3a98 100644 --- a/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts +++ b/plugins/code-coverage-backend/src/service/converter/jacoco.test.ts @@ -15,6 +15,7 @@ */ import { parseString } from 'xml2js'; import fs from 'fs'; +import path from 'path'; import { Jacoco } from './jacoco'; import { JacocoXML } from './types'; import { getVoidLogger } from '@backstage/backend-common'; @@ -25,7 +26,9 @@ describe('convert jacoco', () => { const converter = new Jacoco(getVoidLogger()); let fixture: JacocoXML; parseString( - fs.readFileSync(`${__dirname}/../__fixtures__/jacoco-testdata-1.xml`), + fs.readFileSync( + path.resolve(`${__dirname}/../__fixtures__/jacoco-testdata-1.xml`), + ), (_e, r) => { fixture = r; }, @@ -33,12 +36,16 @@ describe('convert jacoco', () => { const expected = JSON.parse( fs .readFileSync( - `${__dirname}/../__fixtures__/jacoco-jsoncoverage-files-1.json`, + path.resolve( + `${__dirname}/../__fixtures__/jacoco-jsoncoverage-files-1.json`, + ), ) .toString(), ); const scmFiles = fs - .readFileSync(`${__dirname}/../__fixtures__/jacoco-sourcefiles-1.txt`) + .readFileSync( + path.resolve(`${__dirname}/../__fixtures__/jacoco-sourcefiles-1.txt`), + ) .toString() .split('\n'); diff --git a/plugins/code-coverage-backend/src/service/converter/jacoco.ts b/plugins/code-coverage-backend/src/service/converter/jacoco.ts index 4c554fec91..e4a41f8bc4 100644 --- a/plugins/code-coverage-backend/src/service/converter/jacoco.ts +++ b/plugins/code-coverage-backend/src/service/converter/jacoco.ts @@ -63,7 +63,9 @@ export class Jacoco implements Converter { }); const packageAndFilename = `${packageName}/${fileName}`; - const currentFile = scmFiles.find(f => f.endsWith(packageAndFilename)); + const currentFile = scmFiles + .map(f => f.trimEnd()) + .find(f => f.endsWith(packageAndFilename)); this.logger.debug(`matched ${packageAndFilename} to ${currentFile}`); if (Object.keys(lineHits).length > 0 && currentFile) { jscov.push({ From 55b2fc0c0f02c46a7be0122769f97a5f3cdfa240 Mon Sep 17 00:00:00 2001 From: alde <r.dybeck@gmail.com> Date: Wed, 21 Apr 2021 14:59:56 -0400 Subject: [PATCH 162/462] create changeset Signed-off-by: alde <r.dybeck@gmail.com> --- .changeset/rotten-cups-bow.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/rotten-cups-bow.md diff --git a/.changeset/rotten-cups-bow.md b/.changeset/rotten-cups-bow.md new file mode 100644 index 0000000000..967681171d --- /dev/null +++ b/.changeset/rotten-cups-bow.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-code-coverage': patch +'@backstage/plugin-code-coverage-backend': patch +--- + +Update tests to function in windows From 938b266b863271f87d416d60b0360b228c25d7de Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Wed, 21 Apr 2021 15:32:36 -0600 Subject: [PATCH 163/462] Template `spec.type` is not optional Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- .../software-catalog/descriptor-format.md | 19 ++++--------------- .../kinds/Template.v1alpha1.schema.json | 2 +- .../schema/kinds/Template.v1beta2.schema.json | 2 +- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index f4e1f86dd8..d3b14dd888 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -639,22 +639,11 @@ A list of strings that can be associated with the template, e.g. This list will also be used in the frontend to display to the user so you can potentially search and group templates by these tags. -### `spec.type` [optional] +### `spec.type` [required] -The type of component as a string, e.g. `website`. This field is optional but -recommended. - -The software catalog accepts any type value, but an organization should take -great care to establish a proper taxonomy for these. Tools including Backstage -itself may read this field and behave differently depending on its value. For -example, a website type component may present tooling in the Backstage interface -that is specific to just websites. - -The current set of well-known and common values for this field is: - -- `service` - a backend service, typically exposing an API -- `website` - a website -- `library` - a software library, such as an npm module or a Java library +The type of component created by the template, e.g. `website`. This is used for +filtering templates, and should ideally match the Component +[spec.type](#spectype-required) created by the template. ### `spec.parameters` [required] diff --git a/packages/catalog-model/src/schema/kinds/Template.v1alpha1.schema.json b/packages/catalog-model/src/schema/kinds/Template.v1alpha1.schema.json index 5bb83d116b..53109ac7ee 100644 --- a/packages/catalog-model/src/schema/kinds/Template.v1alpha1.schema.json +++ b/packages/catalog-model/src/schema/kinds/Template.v1alpha1.schema.json @@ -66,7 +66,7 @@ "properties": { "type": { "type": "string", - "description": "The type of component. This field is optional but recommended. The software catalog accepts any type value, but an organization should take great care to establish a proper taxonomy for these. Tools including Backstage itself may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Backstage interface that is specific to just websites.", + "description": "The type of component created by the template. The software catalog accepts any type value, but an organization should take great care to establish a proper taxonomy for these. Tools including Backstage itself may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Backstage interface that is specific to just websites.", "examples": ["service", "website", "library"], "minLength": 1 }, diff --git a/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json b/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json index ba3ccb9d1d..1e0b7d0ded 100644 --- a/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json +++ b/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json @@ -85,7 +85,7 @@ "properties": { "type": { "type": "string", - "description": "The type of component. This field is optional but recommended. The software catalog accepts any type value, but an organization should take great care to establish a proper taxonomy for these. Tools including Backstage itself may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Backstage interface that is specific to just websites.", + "description": "The type of component created by the template. The software catalog accepts any type value, but an organization should take great care to establish a proper taxonomy for these. Tools including Backstage itself may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Backstage interface that is specific to just websites.", "examples": ["service", "website", "library"], "minLength": 1 }, From b9028d0f0c36726a738fd83269274136d409c86d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 04:32:34 +0000 Subject: [PATCH 164/462] chore(deps-dev): bump @types/jest from 26.0.15 to 26.0.22 Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.15 to 26.0.22. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 46 +++++----------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index f614a7713a..dfa07a5397 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2955,17 +2955,6 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@jest/types@^26.6.1": - version "26.6.1" - resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.1.tgz#2638890e8031c0bc8b4681e0357ed986e2f866c5" - integrity sha512-ywHavIKNpAVrStiRY5wiyehvcktpijpItvGiK72RAn5ctqmzvPk8OvKnvHeBqa1XdQr959CTWAJMqxI8BTibyg== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -6102,9 +6091,9 @@ "@types/jest" "*" "@types/jest@*", "@types/jest@^26.0.7": - version "26.0.15" - resolved "https://registry.npmjs.org/@types/jest/-/jest-26.0.15.tgz#12e02c0372ad0548e07b9f4e19132b834cb1effe" - integrity sha512-s2VMReFXRg9XXxV+CW9e5Nz8fH2K1aEhwgjUqPPbQd7g95T0laAcvLv032EhFHIa5GHsZ8W7iJEQVaJq6k3Gog== + version "26.0.22" + resolved "https://registry.npmjs.org/@types/jest/-/jest-26.0.22.tgz#8308a1debdf1b807aa47be2838acdcd91e88fbe6" + integrity sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" @@ -11513,11 +11502,6 @@ diff-sequences@^24.9.0: resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== -diff-sequences@^26.5.0: - version "26.5.0" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.5.0.tgz#ef766cf09d43ed40406611f11c6d8d9dd8b2fefd" - integrity sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q== - diff-sequences@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" @@ -16241,17 +16225,7 @@ jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-diff@^26.0.0: - version "26.6.1" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.1.tgz#38aa194979f454619bb39bdee299fb64ede5300c" - integrity sha512-BBNy/zin2m4kG5In126O8chOBxLLS/XMTuuM2+YhgyHk87ewPzKTuTJcqj3lOWOi03NNgrl+DkMeV/exdvG9gg== - dependencies: - chalk "^4.0.0" - diff-sequences "^26.5.0" - jest-get-type "^26.3.0" - pretty-format "^26.6.1" - -jest-diff@^26.6.2: +jest-diff@^26.0.0, jest-diff@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== @@ -21320,17 +21294,7 @@ pretty-format@^24.9.0: ansi-styles "^3.2.0" react-is "^16.8.4" -pretty-format@^26.0.0, pretty-format@^26.6.1: - version "26.6.1" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.1.tgz#af9a2f63493a856acddeeb11ba6bcf61989660a8" - integrity sha512-MeqqsP5PYcRBbGMvwzsyBdmAJ4EFX7pWFyl7x4+dMVg5pE0ZDdBIvEH2ergvIO+Gvwv1wh64YuOY9y5LuyY/GA== - dependencies: - "@jest/types" "^26.6.1" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^17.0.1" - -pretty-format@^26.6.2: +pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== From 0d9d875bc91a1e7673a9a1714959cc95ae3f6528 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 04:33:43 +0000 Subject: [PATCH 165/462] chore(deps-dev): bump @graphql-codegen/typescript from 1.21.1 to 1.22.0 Bumps [@graphql-codegen/typescript](https://github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/plugins/typescript/typescript) from 1.21.1 to 1.22.0. - [Release notes](https://github.com/dotansimha/graphql-code-generator/releases) - [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/plugins/typescript/typescript/CHANGELOG.md) - [Commits](https://github.com/dotansimha/graphql-code-generator/commits/@graphql-codegen/typescript@1.22.0/packages/plugins/typescript/typescript) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 92 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index f614a7713a..376441c31b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2330,27 +2330,16 @@ "@graphql-tools/utils" "^6" tslib "~2.0.1" -"@graphql-codegen/plugin-helpers@^1.18.2", "@graphql-codegen/plugin-helpers@^1.18.3": - version "1.18.3" - resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.3.tgz#607a8bc16d80b30d59cd07d70de2ba803b57bc4a" - integrity sha512-+LVxWFlcZW+FB32CyvkdaMN/tIMajO42pCg0Cy8Z8ZZtGutXW1w6UggrvrEUzMZc9GHZQe49q+w7QQxeooaIlA== +"@graphql-codegen/plugin-helpers@^1.18.2", "@graphql-codegen/plugin-helpers@^1.18.4", "@graphql-codegen/plugin-helpers@^1.18.5": + version "1.18.5" + resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.5.tgz#e1d875cfb6a2f7bf4b4318135f7fee6e1200f3b0" + integrity sha512-xY8dWdU4+mm+253esLYcKQIgWZEgI3spKPmMRQ+oAxlrCn9oIcdhhiMqNxa9rHS20xpZtlAjozxHulrqjFLuyA== dependencies: "@graphql-tools/utils" "^7.0.0" common-tags "1.8.0" import-from "3.0.0" lodash "~4.17.20" - tslib "~2.1.0" - -"@graphql-codegen/plugin-helpers@^1.18.4": - version "1.18.4" - resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.4.tgz#0adc4c0f88386a50b7a69d358080b6ee54fc3b16" - integrity sha512-dpfhUmn9GOS8ByoOPIN3V4Nn9HX7sl9NR7Hf26TgN6Clg7cQvkT6XjHdS2e56Q3kWrxZT1zJ1sEa67D3tj9ZtQ== - dependencies: - "@graphql-tools/utils" "^7.0.0" - common-tags "1.8.0" - import-from "3.0.0" - lodash "~4.17.20" - tslib "~2.1.0" + tslib "~2.2.0" "@graphql-codegen/typescript-resolvers@^1.17.7": version "1.18.2" @@ -2365,30 +2354,30 @@ tslib "~2.1.0" "@graphql-codegen/typescript@^1.17.7", "@graphql-codegen/typescript@^1.21.0": - version "1.21.1" - resolved "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-1.21.1.tgz#9bce3254b8ef30a6bf64e57ba3991f9be7a19b53" - integrity sha512-JF6Vsu5HSv3dAoS2ca3PFLUN0qVxotex/+BgWw/6SKhtd83MUPnzJ/RU3lACg4vuNTCWeQSeGvg8x5qrw9Go9w== + version "1.22.0" + resolved "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-1.22.0.tgz#d05be3a971e5d75a076a43e123b6330f4366a6ab" + integrity sha512-YzN/3MBYHrP110m8JgUWQIHt7Ivi3JXiq0RT5XNx/F9mVOSbZz6Ezbaji8YJA3y04Gl2f6ZgtdGazWANUvcOcg== dependencies: - "@graphql-codegen/plugin-helpers" "^1.18.3" - "@graphql-codegen/visitor-plugin-common" "^1.19.0" + "@graphql-codegen/plugin-helpers" "^1.18.5" + "@graphql-codegen/visitor-plugin-common" "^1.20.0" auto-bind "~4.0.0" - tslib "~2.1.0" + tslib "~2.2.0" -"@graphql-codegen/visitor-plugin-common@^1.18.3", "@graphql-codegen/visitor-plugin-common@^1.19.0": - version "1.19.0" - resolved "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.19.0.tgz#e302dd1ba55cf220079c40fa840a355dcf81526d" - integrity sha512-Vsh9FwB90SBLnSr4KTFY8cuwjC//JBVyqn4k4usBZHFLWLkPwWzdkUKABFg6ET2gnL2L1rSU/gM30eEBrLRXFA== +"@graphql-codegen/visitor-plugin-common@^1.18.3", "@graphql-codegen/visitor-plugin-common@^1.20.0": + version "1.20.0" + resolved "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.20.0.tgz#38d829eab7370c79aa5229190788f94adcae8f76" + integrity sha512-AYrpy8NA3DpvhDLqYGerQRv44S+YAMPKtwT8x9GNVjzP0gVfmqi3gG1bDWbP5sm6kOZKvDC0kTxGePuBSZerxw== dependencies: - "@graphql-codegen/plugin-helpers" "^1.18.3" + "@graphql-codegen/plugin-helpers" "^1.18.5" "@graphql-tools/optimize" "^1.0.1" "@graphql-tools/relay-operation-optimizer" "^6" array.prototype.flatmap "^1.2.4" auto-bind "~4.0.0" - change-case-all "^1.0.12" + change-case-all "1.0.14" dependency-graph "^0.11.0" graphql-tag "^2.11.0" parse-filepath "^1.0.2" - tslib "~2.1.0" + tslib "~2.2.0" "@graphql-modules/core@^0.7.17": version "0.7.17" @@ -9406,7 +9395,7 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -change-case-all@1.0.12, change-case-all@^1.0.12: +change-case-all@1.0.12: version "1.0.12" resolved "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.12.tgz#ae3e0faf5e610e8e25c5d5eaa4a6d5c2f1d68797" integrity sha512-zdQus7R0lkprF99lrWUC5bFj6Nog4Xt4YCEjQ/vM4vbc6b5JHFBQMxRPAjfx+HJH8WxMzH0E+lQ8yQJLgmPCBg== @@ -9422,7 +9411,23 @@ change-case-all@1.0.12, change-case-all@^1.0.12: upper-case "^2.0.1" upper-case-first "^2.0.1" -change-case@^4.1.1: +change-case-all@1.0.14: + version "1.0.14" + resolved "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.14.tgz#bac04da08ad143278d0ac3dda7eccd39280bfba1" + integrity sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA== + dependencies: + change-case "^4.1.2" + is-lower-case "^2.0.2" + is-upper-case "^2.0.2" + lower-case "^2.0.2" + lower-case-first "^2.0.2" + sponge-case "^1.0.1" + swap-case "^2.0.2" + title-case "^3.0.3" + upper-case "^2.0.2" + upper-case-first "^2.0.2" + +change-case@^4.1.1, change-case@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== @@ -15715,7 +15720,7 @@ is-lambda@^1.0.1: resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= -is-lower-case@^2.0.1: +is-lower-case@^2.0.1, is-lower-case@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz#1c0884d3012c841556243483aa5d522f47396d2a" integrity sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ== @@ -15975,7 +15980,7 @@ is-unicode-supported@^0.1.0: resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-upper-case@^2.0.1: +is-upper-case@^2.0.1, is-upper-case@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649" integrity sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ== @@ -17880,7 +17885,7 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lower-case-first@^2.0.1: +lower-case-first@^2.0.1, lower-case-first@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz#64c2324a2250bf7c37c5901e76a5b5309301160b" integrity sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg== @@ -24062,7 +24067,7 @@ split@^1.0.0: dependencies: through "2" -sponge-case@^1.0.0: +sponge-case@^1.0.0, sponge-case@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz#260833b86453883d974f84854cdb63aecc5aef4c" integrity sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA== @@ -24811,7 +24816,7 @@ swagger-ui-react@^3.37.2: xml-but-prettier "^1.0.1" zenscroll "^4.0.2" -swap-case@^2.0.1: +swap-case@^2.0.1, swap-case@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz#671aedb3c9c137e2985ef51c51f9e98445bf70d9" integrity sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw== @@ -25193,7 +25198,7 @@ tinycolor2@^1.4.1: resolved "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= -title-case@^3.0.2: +title-case@^3.0.2, title-case@^3.0.3: version "3.0.3" resolved "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz#bc689b46f02e411f1d1e1d081f7c3deca0489982" integrity sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA== @@ -25509,16 +25514,21 @@ tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== +tslib@^2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@~2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== tslib@~2.0.0, tslib@~2.0.1: version "2.0.3" resolved "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + tsutils@^3.17.1: version "3.17.1" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" From 49574a8a3e7365a3c1474b787685d5956b1730cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Thu, 22 Apr 2021 09:15:36 +0200 Subject: [PATCH 166/462] Fix some spleling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/great-years-battle.md | 14 ++++++++++++++ plugins/config-schema/dev/example-schema.json | 8 ++++---- plugins/rollbar-backend/config.d.ts | 2 +- plugins/scaffolder-backend/config.d.ts | 6 +++--- .../scaffolder/actions/builtin/publish/azure.ts | 2 +- .../actions/builtin/publish/bitbucket.ts | 4 ++-- .../scaffolder/actions/builtin/publish/github.ts | 6 +++--- .../scaffolder/actions/builtin/publish/gitlab.ts | 4 ++-- 8 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 .changeset/great-years-battle.md diff --git a/.changeset/great-years-battle.md b/.changeset/great-years-battle.md new file mode 100644 index 0000000000..a2d61be11a --- /dev/null +++ b/.changeset/great-years-battle.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-rollbar-backend': patch +'@backstage/plugin-scaffolder-backend': minor +--- + +Fix some `spleling`. + +The `scaffolder-backend` has a configuration schema change that may be breaking +in rare circumstances. Due to a typo in the schema, the +`scaffolder.github.visibility`, `scaffolder.gitlab.visibility`, and +`scaffolder.bitbucket.visibility` did not get proper validation that the value +is one of the supported strings (`public`, `internal` (not available for +Bitbucket), and `private`). If you had a value that was not one of these three, +you may have to adjust your config. diff --git a/plugins/config-schema/dev/example-schema.json b/plugins/config-schema/dev/example-schema.json index d1e577ff6f..ac5c2ad347 100644 --- a/plugins/config-schema/dev/example-schema.json +++ b/plugins/config-schema/dev/example-schema.json @@ -1247,7 +1247,7 @@ "required": ["accountToken"], "properties": { "accountToken": { - "description": "The autentication token for accessing the Rollbar API", + "description": "The authentication token for accessing the Rollbar API", "type": "string" }, "organization": { @@ -1320,7 +1320,7 @@ "type": "string" }, "properties": { - "visiblity": { + "visibility": { "description": "The visibility to set on created repositories.", "enum": ["internal", "private", "public"], "type": "string" @@ -1337,7 +1337,7 @@ "type": "string" } }, - "visiblity": { + "visibility": { "description": "The visibility to set on created repositories.", "enum": ["internal", "private", "public"], "type": "string" @@ -1369,7 +1369,7 @@ "type": "string" } }, - "visiblity": { + "visibility": { "description": "The visibility to set on created repositories.", "enum": ["private", "public"], "type": "string" diff --git a/plugins/rollbar-backend/config.d.ts b/plugins/rollbar-backend/config.d.ts index 473b27a506..bb48f38cf2 100644 --- a/plugins/rollbar-backend/config.d.ts +++ b/plugins/rollbar-backend/config.d.ts @@ -18,7 +18,7 @@ export interface Config { /** Configuration options for the rollbar-backend plugin */ rollbar?: { /** - * The autentication token for accessing the Rollbar API + * The authentication token for accessing the Rollbar API * @see https://explorer.docs.rollbar.com/#section/Authentication */ accountToken: string; diff --git a/plugins/scaffolder-backend/config.d.ts b/plugins/scaffolder-backend/config.d.ts index 3b31b4f951..aefa6154ca 100644 --- a/plugins/scaffolder-backend/config.d.ts +++ b/plugins/scaffolder-backend/config.d.ts @@ -22,14 +22,14 @@ export interface Config { /** * The visibility to set on created repositories. */ - visiblity?: 'public' | 'internal' | 'private'; + visibility?: 'public' | 'internal' | 'private'; }; gitlab?: { api: { [key: string]: string }; /** * The visibility to set on created repositories. */ - visiblity?: 'public' | 'internal' | 'private'; + visibility?: 'public' | 'internal' | 'private'; }; azure?: { baseUrl: string; @@ -40,7 +40,7 @@ export interface Config { /** * The visibility to set on created repositories. */ - visiblity?: 'public' | 'private'; + visibility?: 'public' | 'private'; }; }; } diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts index e1a064b3e6..36f5341bbb 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts @@ -50,7 +50,7 @@ export function createPublishAzureAction(options: { }, sourcePath: { title: - 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the respository.', + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.', type: 'string', }, }, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts index 13f639d745..243e515b19 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.ts @@ -184,13 +184,13 @@ export function createPublishBitbucketAction(options: { type: 'string', }, repoVisibility: { - title: 'Repository Visiblity', + title: 'Repository Visibility', type: 'string', enum: ['private', 'public'], }, sourcePath: { title: - 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the respository.', + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.', type: 'string', }, }, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index e58f2c68aa..3ae43c5763 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -67,13 +67,13 @@ export function createPublishGithubAction(options: { type: 'string', }, repoVisibility: { - title: 'Repository Visiblity', + title: 'Repository Visibility', type: 'string', enum: ['private', 'public', 'internal'], }, sourcePath: { title: - 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the respository.', + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.', type: 'string', }, collaborators: { @@ -180,7 +180,7 @@ export function createPublishGithubAction(options: { repo, permission: 'admin', }); - // no need to add access if it's the person who own's the personal account + // No need to add access if it's the person who owns the personal account } else if (access && access !== owner) { await client.repos.addCollaborator({ owner, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts index 37074d6f57..0605f88983 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.ts @@ -44,13 +44,13 @@ export function createPublishGitlabAction(options: { type: 'string', }, repoVisibility: { - title: 'Repository Visiblity', + title: 'Repository Visibility', type: 'string', enum: ['private', 'public', 'internal'], }, sourcePath: { title: - 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the respository.', + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.', type: 'string', }, }, From d8cc7e67a3b078d3659ce444cdaba6447cb354aa Mon Sep 17 00:00:00 2001 From: Jussi Hallila <jussi@hallila.com> Date: Fri, 19 Feb 2021 09:47:00 +0100 Subject: [PATCH 167/462] Exposing Material-UI extension point from tab components on HeaderTabs so additional information can be added to them Signed-off-by: Jussi Hallila <jussi@hallila.com> --- .changeset/eighty-crews-rhyme.md | 5 +++ .../components/TabbedLayout/RoutedTabs.tsx | 7 +++- .../components/TabbedLayout/TabbedLayout.tsx | 6 ++-- .../core/src/components/TabbedLayout/types.ts | 4 +++ .../src/layout/HeaderTabs/HeaderTabs.test.tsx | 32 +++++++++++++++++++ .../core/src/layout/HeaderTabs/HeaderTabs.tsx | 4 ++- 6 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 .changeset/eighty-crews-rhyme.md diff --git a/.changeset/eighty-crews-rhyme.md b/.changeset/eighty-crews-rhyme.md new file mode 100644 index 0000000000..5a8379acb6 --- /dev/null +++ b/.changeset/eighty-crews-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/core': patch +--- + +Exposing Material UI extension point for tabs to be able to add additional information to them diff --git a/packages/core/src/components/TabbedLayout/RoutedTabs.tsx b/packages/core/src/components/TabbedLayout/RoutedTabs.tsx index b17c8afb3b..6b7b39329b 100644 --- a/packages/core/src/components/TabbedLayout/RoutedTabs.tsx +++ b/packages/core/src/components/TabbedLayout/RoutedTabs.tsx @@ -48,7 +48,12 @@ export const RoutedTabs = ({ routes }: { routes: SubRoute[] }) => { const navigate = useNavigate(); const { index, route, element } = useSelectedSubRoute(routes); const headerTabs = useMemo( - () => routes.map(t => ({ id: t.path, label: t.title })), + () => + routes.map(t => ({ + id: t.path, + label: t.title, + tabProps: t.tabProps, + })), [routes], ); diff --git a/packages/core/src/components/TabbedLayout/TabbedLayout.tsx b/packages/core/src/components/TabbedLayout/TabbedLayout.tsx index f181ee5980..5a1b190d00 100644 --- a/packages/core/src/components/TabbedLayout/TabbedLayout.tsx +++ b/packages/core/src/components/TabbedLayout/TabbedLayout.tsx @@ -23,11 +23,13 @@ import React, { ReactNode, } from 'react'; import { RoutedTabs } from './RoutedTabs'; +import { TabProps } from '@material-ui/core'; type SubRoute = { path: string; title: string; children: JSX.Element; + tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>; }; const Route: (props: SubRoute) => null = () => null; @@ -60,8 +62,8 @@ export function createSubRoutesFromChildren( throw new Error('Child of TabbedLayout must be an TabbedLayout.Route'); } - const { path, title, children } = child.props; - return [{ path, title, children }]; + const { path, title, children, tabProps } = child.props; + return [{ path, title, children, tabProps }]; }); } diff --git a/packages/core/src/components/TabbedLayout/types.ts b/packages/core/src/components/TabbedLayout/types.ts index 29ade88dc0..24ee011933 100644 --- a/packages/core/src/components/TabbedLayout/types.ts +++ b/packages/core/src/components/TabbedLayout/types.ts @@ -14,8 +14,12 @@ * limitations under the License. */ +import { TabProps } from '@material-ui/core'; +import * as React from 'react'; + export type SubRoute = { path: string; title: string; children: JSX.Element; + tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>; }; diff --git a/packages/core/src/layout/HeaderTabs/HeaderTabs.test.tsx b/packages/core/src/layout/HeaderTabs/HeaderTabs.test.tsx index 81d2123049..9a5093f6e9 100644 --- a/packages/core/src/layout/HeaderTabs/HeaderTabs.test.tsx +++ b/packages/core/src/layout/HeaderTabs/HeaderTabs.test.tsx @@ -17,6 +17,7 @@ import React from 'react'; import { renderInTestApp } from '@backstage/test-utils'; import { HeaderTabs } from './'; +import { Badge, makeStyles } from '@material-ui/core'; const mockTabs = [ { id: 'overview', label: 'Overview' }, @@ -46,4 +47,35 @@ describe('<HeaderTabs />', () => { 'true', ); }); + it('should render extension component to tab if one present', async () => { + const useStyles = makeStyles(() => ({ + badge: { + margin: '20px 20px 0 0', + }, + })); + + const TextualBadge = React.forwardRef<HTMLSpanElement>((props, ref) => ( + <Badge + classes={useStyles()} + color="secondary" + badgeContent="three new alarms" + > + <span ref={ref} {...props}> + {props.children} + </span> + </Badge> + )); + const iconTab = [ + { + id: 'icon-tab', + label: 'Alarms', + tabProps: { component: TextualBadge }, + }, + ]; + + const rendered = await renderInTestApp(<HeaderTabs tabs={iconTab} />); + + expect(rendered.getByText('Alarms')).toBeInTheDocument(); + expect(rendered.getByText('three new alarms')).toBeInTheDocument(); + }); }); diff --git a/packages/core/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core/src/layout/HeaderTabs/HeaderTabs.tsx index 718a103f00..1fd4a18ba3 100644 --- a/packages/core/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core/src/layout/HeaderTabs/HeaderTabs.tsx @@ -18,7 +18,7 @@ // This is just a temporary solution to implementing tabs for now import React, { useState, useEffect } from 'react'; -import { makeStyles, Tabs, Tab as TabUI } from '@material-ui/core'; +import { makeStyles, Tabs, Tab as TabUI, TabProps } from '@material-ui/core'; const useStyles = makeStyles(theme => ({ tabsWrapper: { @@ -41,6 +41,7 @@ const useStyles = makeStyles(theme => ({ export type Tab = { id: string; label: string; + tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>; }; type HeaderTabsProps = { @@ -82,6 +83,7 @@ export const HeaderTabs = ({ > {tabs.map((tab, index) => ( <TabUI + {...tab.tabProps} label={tab.label} key={tab.id} value={index} From 6eaecbd81d1a9e2ea61f2b8b101c2fd4aedee95a Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 13:21:33 +0200 Subject: [PATCH 168/462] Fix owner references to guest user If the user guest is used as an example value of the owner field, we should make sure to specify it as user:guest instead as the default is group. Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/thirty-humans-knock.md | 5 +++++ .../components/EmptyState/MissingAnnotationEmptyState.tsx | 2 +- .../src/ingestion/processors/util/parse.test.ts | 4 ++-- plugins/github-actions/README.md | 2 +- plugins/github-actions/examples/sample.yaml | 2 +- .../examples/dice-roller/catalog-info.yaml | 2 +- .../sample-templates/pull-request/template/catalog-info.yaml | 2 +- 7 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 .changeset/thirty-humans-knock.md diff --git a/.changeset/thirty-humans-knock.md b/.changeset/thirty-humans-knock.md new file mode 100644 index 0000000000..47545af282 --- /dev/null +++ b/.changeset/thirty-humans-knock.md @@ -0,0 +1,5 @@ +--- +'@backstage/core': patch +--- + +Improve owner example value in `MissingAnnotationEmptyState`. diff --git a/packages/core/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core/src/components/EmptyState/MissingAnnotationEmptyState.tsx index 377373a06d..6c04b34a90 100644 --- a/packages/core/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -30,7 +30,7 @@ metadata: spec: type: website lifecycle: production - owner: guest`; + owner: user:guest`; type Props = { annotation: string; diff --git a/plugins/catalog-backend/src/ingestion/processors/util/parse.test.ts b/plugins/catalog-backend/src/ingestion/processors/util/parse.test.ts index 4d6f67de22..1d8e139fb3 100644 --- a/plugins/catalog-backend/src/ingestion/processors/util/parse.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/util/parse.test.ts @@ -38,7 +38,7 @@ describe('parseEntityYaml', () => { spec: type: website lifecycle: production - owner: guest + owner: user:guest `, 'utf8', ), @@ -60,7 +60,7 @@ describe('parseEntityYaml', () => { spec: { type: 'website', lifecycle: 'production', - owner: 'guest', + owner: 'user:guest', }, }), ]); diff --git a/plugins/github-actions/README.md b/plugins/github-actions/README.md index d47144351e..e1569f16ce 100644 --- a/plugins/github-actions/README.md +++ b/plugins/github-actions/README.md @@ -30,7 +30,7 @@ TBD spec: type: website lifecycle: production - owner: guest + owner: user:guest ``` ### Standalone app requirements diff --git a/plugins/github-actions/examples/sample.yaml b/plugins/github-actions/examples/sample.yaml index a765bd395d..5b347388f7 100644 --- a/plugins/github-actions/examples/sample.yaml +++ b/plugins/github-actions/examples/sample.yaml @@ -9,4 +9,4 @@ metadata: spec: type: website lifecycle: production - owner: guest + owner: user:guest diff --git a/plugins/kubernetes-backend/examples/dice-roller/catalog-info.yaml b/plugins/kubernetes-backend/examples/dice-roller/catalog-info.yaml index a944232224..059b719563 100644 --- a/plugins/kubernetes-backend/examples/dice-roller/catalog-info.yaml +++ b/plugins/kubernetes-backend/examples/dice-roller/catalog-info.yaml @@ -10,4 +10,4 @@ metadata: spec: type: service lifecycle: production - owner: guest + owner: user:guest diff --git a/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml b/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml index dd1e0ebd09..04f055bd46 100644 --- a/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml +++ b/plugins/scaffolder-backend/sample-templates/pull-request/template/catalog-info.yaml @@ -5,4 +5,4 @@ metadata: spec: type: website lifecycle: experimental - owner: guest + owner: user:guest From 23afdba96f4ca6539cbd22ba487eb25ed599eed6 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 13:25:55 +0200 Subject: [PATCH 169/462] Use `EntityRefLink` in header and use relations to reference the owner of the document Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/lovely-wombats-relate.md | 6 +++ .../reader/components/TechDocsPageHeader.tsx | 51 +++++++++---------- 2 files changed, 31 insertions(+), 26 deletions(-) create mode 100644 .changeset/lovely-wombats-relate.md diff --git a/.changeset/lovely-wombats-relate.md b/.changeset/lovely-wombats-relate.md new file mode 100644 index 0000000000..33ed205c89 --- /dev/null +++ b/.changeset/lovely-wombats-relate.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Use `EntityRefLink` in header and use relations to reference the owner of the +document. diff --git a/plugins/techdocs/src/reader/components/TechDocsPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsPageHeader.tsx index 1d4321001d..10df7bff78 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPageHeader.tsx @@ -14,14 +14,18 @@ * limitations under the License. */ +import { EntityName, RELATION_OWNED_BY } from '@backstage/catalog-model'; +import { Header, HeaderLabel, useRouteRef } from '@backstage/core'; +import { + EntityRefLink, + EntityRefLinks, + getEntityRelations, +} from '@backstage/plugin-catalog-react'; +import CodeIcon from '@material-ui/icons/Code'; import React from 'react'; import { AsyncState } from 'react-use/lib/useAsync'; -import CodeIcon from '@material-ui/icons/Code'; -import { EntityName, parseEntityName } from '@backstage/catalog-model'; -import { Header, HeaderLabel, Link, useRouteRef } from '@backstage/core'; -import { TechDocsMetadata } from '../../types'; -import { EntityRefLink, entityRouteRef } from '@backstage/plugin-catalog-react'; import { rootRouteRef } from '../../plugin'; +import { TechDocsMetadata } from '../../types'; type TechDocsPageHeaderProps = { entityId: EntityName; @@ -50,15 +54,12 @@ export const TechDocsPageHeader = ({ const { locationMetadata, - spec: { owner, lifecycle }, + spec: { lifecycle }, } = entityMetadataValues || { spec: {} }; - const componentLink = useRouteRef(entityRouteRef); - - let ownerEntity; - if (owner) { - ownerEntity = parseEntityName(owner, { defaultKind: 'group' }); - } + const ownedByRelations = entityMetadataValues + ? getEntityRelations(entityMetadataValues, RELATION_OWNED_BY) + : []; const docsRootLink = useRouteRef(rootRouteRef)(); @@ -67,27 +68,25 @@ export const TechDocsPageHeader = ({ <HeaderLabel label="Component" value={ - <Link style={{ color: '#fff' }} to={componentLink(entityId)}> - {name} - </Link> + <EntityRefLink + color="inherit" + entityRef={entityId} + defaultKind="Component" + /> } /> - {owner ? ( + {ownedByRelations.length > 0 && ( <HeaderLabel label="Owner" value={ - ownerEntity ? ( - <EntityRefLink - style={{ color: '#fff' }} - entityRef={ownerEntity} - defaultKind="group" - /> - ) : ( - owner - ) + <EntityRefLinks + color="inherit" + entityRefs={ownedByRelations} + defaultKind="group" + /> } /> - ) : null} + )} {lifecycle ? <HeaderLabel label="Lifecycle" value={lifecycle} /> : null} {locationMetadata && locationMetadata.type !== 'dir' && From b9b2b4b7666d37ba650edcd4f4d518207d524151 Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Thu, 22 Apr 2021 15:03:10 +0200 Subject: [PATCH 170/462] [Search] Lunr search engine support (#5290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add lunr package Signed-off-by: Emma Indal <emma.indahl@gmail.com> * add search translator type and search engine interface Signed-off-by: Emma Indal <emma.indahl@gmail.com> * (wip) add support for lunr search engine Signed-off-by: Emma Indal <emma.indahl@gmail.com> * lunr search engine support Signed-off-by: Emma Indal <emma.indahl@gmail.com> * clean up todo comments Signed-off-by: Emma Indal <emma.indahl@gmail.com> * typing and cleanups Signed-off-by: Emma Indal <emma.indahl@gmail.com> * move lunr type package from dev deps to deps Signed-off-by: Emma Indal <emma.indahl@gmail.com> * check if documents exist to index Signed-off-by: Emma Indal <emma.indahl@gmail.com> * test fixup Signed-off-by: Emma Indal <emma.indahl@gmail.com> * changeset Signed-off-by: Emma Indal <emma.indahl@gmail.com> * move LunrSearchEngine.ts to /engines and add tests Signed-off-by: Emma Indal <emma.indahl@gmail.com> * update imports Signed-off-by: Emma Indal <emma.indahl@gmail.com> * update error message Signed-off-by: Emma Indal <emma.indahl@gmail.com> * add comment to index rotation Signed-off-by: Emma Indal <emma.indahl@gmail.com> * Update plugins/search-backend-node/src/types.ts Signed-off-by: Fredrik Adelöw freben@gmail.com Co-authored-by: Fredrik Adelöw <freben@gmail.com> Signed-off-by: Emma Indal <emma.indahl@gmail.com> * Update plugins/search-backend-node/src/engines/LunrSearchEngine.ts Signed-off-by: Emma Indal <emma.indahl@gmail.com> Co-authored-by: Fredrik Adelöw <freben@gmail.com> * Update plugins/search-backend-node/src/engines/LunrSearchEngine.ts Signed-off-by: Emma Indal <emma.indahl@gmail.com> Co-authored-by: Fredrik Adelöw <freben@gmail.com> * fix imports Signed-off-by: Emma Indal <emma.indahl@gmail.com> * use type assertion to specify more specific ConcreteLunrQuery type Signed-off-by: Emma Indal <emma.indahl@gmail.com> * fix imports Signed-off-by: Emma Indal <emma.indahl@gmail.com> * consistent naming Signed-off-by: Emma Indal <emma.indahl@gmail.com> * change search engine to be parameter of constructor in indexBuilder Signed-off-by: Emma Indal <emma.indahl@gmail.com> * make engine required in router options and pass it through in createRouter used in standalone server Signed-off-by: Emma Indal <emma.indahl@gmail.com> * fix tests Signed-off-by: Emma Indal <emma.indahl@gmail.com> * delete import Signed-off-by: Emma Indal <emma.indahl@gmail.com> * add types to SearchQuery interface to make it possible to scope to specific index + test Signed-off-by: Emma Indal <emma.indahl@gmail.com> * clean up tests Signed-off-by: Emma Indal <emma.indahl@gmail.com> * handle case when a filter is added on a field that does not exist on all documents + test Signed-off-by: Emma Indal <emma.indahl@gmail.com> Co-authored-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/dry-carrots-impress.md | 6 + packages/backend/src/plugins/search.ts | 9 +- packages/search-common/src/types.ts | 1 + plugins/search-backend-node/package.json | 4 +- .../search-backend-node/src/IndexBuilder.ts | 19 +- .../src/engines/LunrSearchEngine.test.ts | 325 ++++++++++++++++++ .../src/engines/LunrSearchEngine.ts | 134 ++++++++ .../search-backend-node/src/engines/index.ts | 17 + plugins/search-backend-node/src/index.test.ts | 9 +- plugins/search-backend-node/src/index.ts | 2 + plugins/search-backend-node/src/types.ts | 25 +- plugins/search-backend/package.json | 1 + .../search-backend/src/service/router.test.ts | 10 +- plugins/search-backend/src/service/router.ts | 16 +- .../src/service/standaloneServer.ts | 10 + yarn.lock | 10 + 16 files changed, 582 insertions(+), 16 deletions(-) create mode 100644 .changeset/dry-carrots-impress.md create mode 100644 plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts create mode 100644 plugins/search-backend-node/src/engines/LunrSearchEngine.ts create mode 100644 plugins/search-backend-node/src/engines/index.ts diff --git a/.changeset/dry-carrots-impress.md b/.changeset/dry-carrots-impress.md new file mode 100644 index 0000000000..aa057beb58 --- /dev/null +++ b/.changeset/dry-carrots-impress.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-search-backend': patch +'@backstage/plugin-search-backend-node': patch +--- + +Lunr Search Engine support diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts index 7bd473756d..a980661c85 100644 --- a/packages/backend/src/plugins/search.ts +++ b/packages/backend/src/plugins/search.ts @@ -15,7 +15,10 @@ */ import { useHotCleanup } from '@backstage/backend-common'; import { createRouter } from '@backstage/plugin-search-backend'; -import { IndexBuilder } from '@backstage/plugin-search-backend-node'; +import { + IndexBuilder, + LunrSearchEngine, +} from '@backstage/plugin-search-backend-node'; import { PluginEnvironment } from '../types'; import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend'; @@ -23,7 +26,8 @@ export default async function createPlugin({ logger, discovery, }: PluginEnvironment) { - const indexBuilder = new IndexBuilder({ logger }); + const searchEngine = new LunrSearchEngine({ logger }); + const indexBuilder = new IndexBuilder({ logger, searchEngine }); indexBuilder.addCollator({ type: 'software-catalog', @@ -38,6 +42,7 @@ export default async function createPlugin({ useHotCleanup(module, () => clearInterval(timerId)); return await createRouter({ + engine: indexBuilder.getSearchEngine(), logger, }); } diff --git a/packages/search-common/src/types.ts b/packages/search-common/src/types.ts index ad784c3b36..daa5823424 100644 --- a/packages/search-common/src/types.ts +++ b/packages/search-common/src/types.ts @@ -18,6 +18,7 @@ import { JsonObject } from '@backstage/config'; export interface SearchQuery { term: string; filters?: JsonObject; + types?: string[]; pageCursor: string; } diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index ab260ada5b..2d1803f4c4 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -20,7 +20,9 @@ }, "dependencies": { "@backstage/search-common": "^0.1.1", - "winston": "^3.2.1" + "winston": "^3.2.1", + "lunr": "^2.3.9", + "@types/lunr": "^2.3.3" }, "devDependencies": { "@backstage/backend-common": "^0.6.0", diff --git a/plugins/search-backend-node/src/IndexBuilder.ts b/plugins/search-backend-node/src/IndexBuilder.ts index 43bf84a59d..0f5a287037 100644 --- a/plugins/search-backend-node/src/IndexBuilder.ts +++ b/plugins/search-backend-node/src/IndexBuilder.ts @@ -16,9 +16,11 @@ import { DocumentCollator, DocumentDecorator } from '@backstage/search-common'; import { Logger } from 'winston'; + import { RegisterCollatorParameters, RegisterDecoratorParameters, + SearchEngine, } from './types'; interface CollatorEnvelope { @@ -27,18 +29,25 @@ interface CollatorEnvelope { } type IndexBuilderOptions = { + searchEngine: SearchEngine; logger: Logger; }; export class IndexBuilder { private collators: Record<string, CollatorEnvelope>; private decorators: Record<string, DocumentDecorator[]>; + private searchEngine: SearchEngine; private logger: Logger; - constructor({ logger }: IndexBuilderOptions) { + constructor({ logger, searchEngine }: IndexBuilderOptions) { this.collators = {}; this.decorators = {}; this.logger = logger; + this.searchEngine = searchEngine; + } + + getSearchEngine(): SearchEngine { + return this.searchEngine; } /** @@ -106,7 +115,13 @@ export class IndexBuilder { documents = await decorators[i].execute(documents); } - // TODO: push documents to a configured search engine. + if (!documents || documents.length === 0) { + this.logger.info(`No documents for type "${type}" to index`); + return; + } + + // pushing documents to index to a configured search engine. + this.searchEngine.index(type, documents); }), ); } diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts new file mode 100644 index 0000000000..6c348235e0 --- /dev/null +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts @@ -0,0 +1,325 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { LunrSearchEngine } from './LunrSearchEngine'; +import { SearchEngine } from '../types'; + +describe('LunrSearchEngine', () => { + let testLunrSearchEngine: SearchEngine; + + beforeEach(() => { + testLunrSearchEngine = new LunrSearchEngine({ logger: getVoidLogger() }); + }); + + describe('translator', () => { + it('query translator invoked', async () => { + const translatorSpy = jest.spyOn(testLunrSearchEngine, 'translator'); + + // Translate query and ensure the translator was invoked. + await testLunrSearchEngine.translator({ + term: 'testTerm', + filters: {}, + pageCursor: '', + }); + + expect(translatorSpy).toHaveBeenCalled(); + expect(translatorSpy).toHaveBeenCalledWith({ + term: 'testTerm', + filters: {}, + pageCursor: '', + }); + }); + + it('should return translated query', async () => { + const mockedTranslatedQuery = await testLunrSearchEngine.translator({ + term: 'testTerm', + filters: {}, + pageCursor: '', + }); + + expect(mockedTranslatedQuery).toMatchObject({ + documentTypes: ['*'], + lunrQueryString: 'testTerm', + }); + }); + + it('should return translated query with 1 filter', async () => { + const mockedTranslatedQuery = await testLunrSearchEngine.translator({ + term: 'testTerm', + filters: { kind: 'testKind' }, + pageCursor: '', + }); + + expect(mockedTranslatedQuery).toMatchObject({ + documentTypes: ['*'], + lunrQueryString: 'testTerm +kind:testKind', + }); + }); + + it('should return translated query with multiple filters', async () => { + const mockedTranslatedQuery = await testLunrSearchEngine.translator({ + term: 'testTerm', + filters: { kind: 'testKind', namespace: 'testNameSpace' }, + pageCursor: '', + }); + + expect(mockedTranslatedQuery).toMatchObject({ + documentTypes: ['*'], + lunrQueryString: 'testTerm +kind:testKind +namespace:testNameSpace', + }); + }); + }); + + describe('query', () => { + it('should perform search query', async () => { + const querySpy = jest.spyOn(testLunrSearchEngine, 'query'); + + // Perform search query and ensure the query func was invoked. + const mockedSearchResult = await testLunrSearchEngine.query({ + term: 'testTerm', + filters: {}, + pageCursor: '', + }); + + expect(querySpy).toHaveBeenCalled(); + expect(querySpy).toHaveBeenCalledWith({ + term: 'testTerm', + filters: {}, + pageCursor: '', + }); + + // Should return 0 results as nothing is indexed here + expect(mockedSearchResult).toMatchObject({ results: [] }); + }); + + it('should perform search query and return 0 results on no match', async () => { + const mockDocuments = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location', + }, + ]; + + // Mock indexing of 1 document + testLunrSearchEngine.index('test-index', mockDocuments); + + // Perform search query + const mockedSearchResult = await testLunrSearchEngine.query({ + term: 'testTerm', + filters: {}, + pageCursor: '', + }); + + // Should return 0 results as we are mocking the indexing of 1 document but with no match on the fields + expect(mockedSearchResult).toMatchObject({ results: [] }); + }); + + it('should perform search query and return search results on match', async () => { + const mockDocuments = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location', + }, + ]; + + // Mock indexing of 1 document + testLunrSearchEngine.index('test-index', mockDocuments); + + // Perform search query + const mockedSearchResult = await testLunrSearchEngine.query({ + term: 'testTitle', + filters: {}, + pageCursor: '', + }); + + // Should return 1 result as we are mocking the indexing of 1 document with match on the title field + expect(mockedSearchResult).toMatchObject({ + results: [ + { + document: { + title: 'testTitle', + text: 'testText', + location: 'test/location', + }, + }, + ], + }); + }); + + it('should perform search query and return search results on match with filters', async () => { + const mockDocuments = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location', + }, + { + title: 'testTitle', + text: 'testText', + location: 'test/location2', + }, + ]; + + // Mock indexing of 2 documents + testLunrSearchEngine.index('test-index', mockDocuments); + + // Perform search query + const mockedSearchResult = await testLunrSearchEngine.query({ + term: 'testTitle', + filters: { location: 'test/location2' }, + pageCursor: '', + }); + + // Should return 1 of 2 results as we are + // 1. Mocking the indexing of 2 documents + // 2. Matching on the location field with the filter { location: 'test/location2' } + expect(mockedSearchResult).toMatchObject({ + results: [ + { + document: { + title: 'testTitle', + text: 'testText', + location: 'test/location2', + }, + }, + ], + }); + }); + + it('should perform search query and return search results on match with filter and not fail on missing field', async () => { + const mockDocuments = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location', + }, + ]; + + const mockDocuments2 = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location2', + extraField: 'testExtraField', + }, + ]; + + // Mock 2 indices with 1 document each + testLunrSearchEngine.index('test-index', mockDocuments); + testLunrSearchEngine.index('test-index-2', mockDocuments2); + // Perform search query scoped to "test-index-2" with a filter on the field "extraField" + const mockedSearchResult = await testLunrSearchEngine.query({ + term: 'testTitle', + pageCursor: '', + filters: { extraField: 'testExtraField' }, + }); + + expect(mockedSearchResult).toMatchObject({ + results: [ + { + document: { + title: 'testTitle', + text: 'testText', + location: 'test/location2', + extraField: 'testExtraField', + }, + }, + ], + }); + }); + + it('should perform search query and return search results on match, scoped to specific index', async () => { + const mockDocuments = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location', + }, + { + title: 'testTitle', + text: 'testText', + location: 'test/location2', + }, + ]; + + const mockDocuments2 = [ + { + title: 'testTitle', + text: 'testText', + location: 'test/location3', + }, + { + title: 'testTitle', + text: 'testText', + location: 'test/location4', + }, + ]; + + // Mock 2 indices with 2 documents each + testLunrSearchEngine.index('test-index', mockDocuments); + testLunrSearchEngine.index('test-index-2', mockDocuments2); + + // Perform search query scoped to "test-index-2" + const mockedSearchResult = await testLunrSearchEngine.query({ + term: 'testTitle', + types: ['test-index-2'], + pageCursor: '', + }); + + expect(mockedSearchResult).toMatchObject({ + results: [ + { + document: { + location: 'test/location3', + text: 'testText', + title: 'testTitle', + }, + }, + { + document: { + location: 'test/location4', + text: 'testText', + title: 'testTitle', + }, + }, + ], + }); + }); + }); + + describe('index', () => { + it('should index document', async () => { + const indexSpy = jest.spyOn(testLunrSearchEngine, 'index'); + const mockDocuments = [ + { + title: 'testTerm', + text: 'testText', + location: 'test/location', + }, + ]; + + // call index func and ensure the index func was invoked. + testLunrSearchEngine.index('test-index', mockDocuments); + expect(indexSpy).toHaveBeenCalled(); + expect(indexSpy).toHaveBeenCalledWith('test-index', [ + { title: 'testTerm', text: 'testText', location: 'test/location' }, + ]); + }); + }); +}); diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts new file mode 100644 index 0000000000..cc8c5bb982 --- /dev/null +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts @@ -0,0 +1,134 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + SearchQuery, + IndexableDocument, + SearchResultSet, +} from '@backstage/search-common'; +import lunr from 'lunr'; +import { Logger } from 'winston'; +import { SearchEngine, QueryTranslator } from '../types'; + +type ConcreteLunrQuery = { + lunrQueryString: string; + documentTypes: string[]; +}; + +export class LunrSearchEngine implements SearchEngine { + protected lunrIndices: Record<string, lunr.Index> = {}; + protected docStore: Record<string, IndexableDocument>; + protected logger: Logger; + + constructor({ logger }: { logger: Logger }) { + this.logger = logger; + this.docStore = {}; + } + + translator: QueryTranslator = ({ + term, + filters, + types, + }: SearchQuery): ConcreteLunrQuery => { + let lunrQueryFilters; + if (filters) { + lunrQueryFilters = Object.entries(filters) + .map(([key, value]) => ` +${key}:${value}`) + .join(''); + } + + return { + lunrQueryString: `${term}${lunrQueryFilters || ''}`, + documentTypes: types || ['*'], + }; + }; + + index(type: string, documents: IndexableDocument[]): void { + const lunrBuilder = new lunr.Builder(); + // Make this lunr index aware of all relevant fields. + Object.keys(documents[0]).forEach(field => { + lunrBuilder.field(field); + }); + + // Set "location" field as reference field + lunrBuilder.ref('location'); + + documents.forEach((document: IndexableDocument) => { + // Add document to Lunar index + lunrBuilder.add(document); + // Store documents in memory to be able to look up document using the ref during query time + // This is not how you should implement your SearchEngine implementation! Do not copy! + this.docStore[document.location] = document; + }); + + // "Rotate" the index by simply overwriting any existing index of the same name. + this.lunrIndices[type] = lunrBuilder.build(); + } + + query(query: SearchQuery): Promise<SearchResultSet> { + const { lunrQueryString, documentTypes } = this.translator( + query, + ) as ConcreteLunrQuery; + + const results: lunr.Index.Result[] = []; + + if (documentTypes.length === 1 && documentTypes[0] === '*') { + // Iterate over all this.lunrIndex values. + Object.values(this.lunrIndices).forEach(i => { + try { + results.push(...i.search(lunrQueryString)); + } catch (err) { + // if a field does not exist on a index, we can see that as a no-match + if ( + err instanceof lunr.QueryParseError && + err.message.startsWith('unrecognised field') + ) + return; + } + }); + } else { + // Iterate over the filtered list of this.lunrIndex keys. + Object.keys(this.lunrIndices) + .filter(d => documentTypes.includes(d)) + .forEach(d => { + try { + results.push(...this.lunrIndices[d].search(lunrQueryString)); + } catch (err) { + // if a field does not exist on a index, we can see that as a no-match + if ( + err instanceof lunr.QueryParseError && + err.message.startsWith('unrecognised field') + ) + return; + } + }); + } + + // Sort results. + results.sort((doc1, doc2) => { + return doc2.score - doc1.score; + }); + + // Translate results into SearchResultSet + const resultSet: SearchResultSet = { + results: results.map(d => { + return { document: this.docStore[d.ref] }; + }), + }; + + return Promise.resolve(resultSet); + } +} diff --git a/plugins/search-backend-node/src/engines/index.ts b/plugins/search-backend-node/src/engines/index.ts new file mode 100644 index 0000000000..ed7079ef62 --- /dev/null +++ b/plugins/search-backend-node/src/engines/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { LunrSearchEngine } from './LunrSearchEngine'; diff --git a/plugins/search-backend-node/src/index.test.ts b/plugins/search-backend-node/src/index.test.ts index 0941f23540..0c66db372a 100644 --- a/plugins/search-backend-node/src/index.test.ts +++ b/plugins/search-backend-node/src/index.test.ts @@ -21,6 +21,7 @@ import { IndexableDocument, } from '@backstage/search-common'; import { IndexBuilder } from './IndexBuilder'; +import { LunrSearchEngine, SearchEngine } from './index'; class TestDocumentCollator implements DocumentCollator { async execute() { @@ -35,12 +36,18 @@ class TestDocumentDecorator implements DocumentDecorator { } describe('IndexBuilder', () => { + let testSearchEngine: SearchEngine; let testIndexBuilder: IndexBuilder; let testCollator: DocumentCollator; let testDecorator: DocumentDecorator; beforeEach(() => { - testIndexBuilder = new IndexBuilder({ logger: getVoidLogger() }); + const logger = getVoidLogger(); + testSearchEngine = new LunrSearchEngine({ logger }); + testIndexBuilder = new IndexBuilder({ + logger, + searchEngine: testSearchEngine, + }); testCollator = new TestDocumentCollator(); testDecorator = new TestDocumentDecorator(); }); diff --git a/plugins/search-backend-node/src/index.ts b/plugins/search-backend-node/src/index.ts index 924dfbc9dc..a3a0eb855e 100644 --- a/plugins/search-backend-node/src/index.ts +++ b/plugins/search-backend-node/src/index.ts @@ -15,3 +15,5 @@ */ export { IndexBuilder } from './IndexBuilder'; +export { LunrSearchEngine } from './engines'; +export type { SearchEngine } from './types'; diff --git a/plugins/search-backend-node/src/types.ts b/plugins/search-backend-node/src/types.ts index e55faccfb4..4abfa77fb1 100644 --- a/plugins/search-backend-node/src/types.ts +++ b/plugins/search-backend-node/src/types.ts @@ -14,7 +14,13 @@ * limitations under the License. */ -import { DocumentCollator, DocumentDecorator } from '@backstage/search-common'; +import { + DocumentCollator, + DocumentDecorator, + IndexableDocument, + SearchQuery, + SearchResultSet, +} from '@backstage/search-common'; /** * Parameters required to register a collator. @@ -51,3 +57,20 @@ export interface RegisterDecoratorParameters { */ types?: string[]; } + +/** + * A type of function responsible for translating an abstract search query into + * a concrete query relevant to a particular search engine. + */ +export type QueryTranslator = (query: SearchQuery) => unknown; + +/** + * Interface that must be implemented by specific search engines, responsible + * for performing indexing and querying and translating abstract queries into + * concrete, search engine-specific queries. + */ +export interface SearchEngine { + translator: QueryTranslator; + index(type: string, documents: IndexableDocument[]): void; + query(query: SearchQuery): Promise<SearchResultSet>; +} diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index a7d588b4b1..82b72e9506 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -21,6 +21,7 @@ "dependencies": { "@backstage/backend-common": "^0.6.0", "@backstage/search-common": "^0.1.1", + "@backstage/plugin-search-backend-node": "^0.1.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index ba7032eb93..9b7cf83ba5 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -15,6 +15,10 @@ */ import { getVoidLogger } from '@backstage/backend-common'; +import { + IndexBuilder, + LunrSearchEngine, +} from '@backstage/plugin-search-backend-node'; import express from 'express'; import request from 'supertest'; @@ -24,8 +28,12 @@ describe('createRouter', () => { let app: express.Express; beforeAll(async () => { + const logger = getVoidLogger(); + const searchEngine = new LunrSearchEngine({ logger }); + const indexBuilder = new IndexBuilder({ logger, searchEngine }); const router = await createRouter({ - logger: getVoidLogger(), + engine: indexBuilder.getSearchEngine(), + logger, }); app = express().use(router); }); diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 1a0c67bdb8..6b757fee16 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -18,23 +18,24 @@ import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; import { SearchQuery, SearchResultSet } from '@backstage/search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; type RouterOptions = { + engine: SearchEngine; logger: Logger; }; export async function createRouter({ + engine, logger, }: RouterOptions): Promise<express.Router> { const router = Router(); - router.get( '/query', async ( req: express.Request<any, unknown, unknown, SearchQuery>, res: express.Response<SearchResultSet>, ) => { - // TODO: Actually transform req.params into search engine specific query. const { term, filters = {}, pageCursor = '' } = req.query; logger.info( `Search request received: ${term}, ${JSON.stringify( @@ -43,13 +44,12 @@ export async function createRouter({ ); try { - // TODO: Actually query search engine. - // TODO: And actually transform results into frontend-readable result - res.send({ - results: [], - }); + const results = await engine?.query(req.query); + res.send(results); } catch (err) { - throw new Error(`There was a problem performing the search query.`); + throw new Error( + `There was a problem performing the search query. ${err}`, + ); } }, ); diff --git a/plugins/search-backend/src/service/standaloneServer.ts b/plugins/search-backend/src/service/standaloneServer.ts index b0c53a6adc..df42e3dda2 100644 --- a/plugins/search-backend/src/service/standaloneServer.ts +++ b/plugins/search-backend/src/service/standaloneServer.ts @@ -18,6 +18,10 @@ import { createServiceBuilder } from '@backstage/backend-common'; import { Server } from 'http'; import { Logger } from 'winston'; import { createRouter } from './router'; +import { + LunrSearchEngine, + IndexBuilder, +} from '@backstage/plugin-search-backend-node'; export interface ServerOptions { port: number; @@ -29,8 +33,14 @@ export async function startStandaloneServer( options: ServerOptions, ): Promise<Server> { const logger = options.logger.child({ service: 'search-backend' }); + const searchEngine = new LunrSearchEngine({ logger }); + const indexBuilder = new IndexBuilder({ logger, searchEngine }); logger.debug('Starting application server...'); + + // TODO: stub out some documents/indices? + const router = await createRouter({ + engine: indexBuilder.getSearchEngine(), logger, }); diff --git a/yarn.lock b/yarn.lock index dfa07a5397..df07058f48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6210,6 +6210,11 @@ resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w== +"@types/lunr@^2.3.3": + version "2.3.3" + resolved "https://registry.npmjs.org/@types/lunr/-/lunr-2.3.3.tgz#ec985618fd2712c010f8edab4f1ae7784ad7c583" + integrity sha512-09sXZZVsB3Ib41U0fC+O1O+4UOZT1bl/e+/QubPxpqDWHNEchvx/DEb1KJMOwq6K3MTNzZFoNSzVdR++o1DVnw== + "@types/luxon@^1.25.0": version "1.26.0" resolved "https://registry.npmjs.org/@types/luxon/-/luxon-1.26.0.tgz#8e783986370ad3bb9f885d93eb1a91caeecaed36" @@ -17927,6 +17932,11 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + luxon@1.25.0, luxon@^1.25.0: version "1.25.0" resolved "https://registry.npmjs.org/luxon/-/luxon-1.25.0.tgz#d86219e90bc0102c0eb299d65b2f5e95efe1fe72" From 034998d53756690a2ada42a1a78d79174e52480c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 13:19:35 +0000 Subject: [PATCH 171/462] Version Packages --- .changeset/chatty-parents-search.md | 5 --- .changeset/dry-carrots-impress.md | 6 --- .changeset/dry-elephants-doubt.md | 5 --- .changeset/eight-plums-hide.md | 5 --- .changeset/eighty-crews-rhyme.md | 5 --- .changeset/fair-carrots-tell.md | 5 --- .changeset/flat-paws-rule.md | 6 --- .changeset/fluffy-suns-repair.md | 5 --- .changeset/fresh-cheetahs-rush.md | 5 --- .changeset/giant-onions-obey.md | 5 --- .changeset/good-glasses-build.md | 6 --- .changeset/gorgeous-pumas-cover.md | 5 --- .changeset/great-years-battle.md | 14 ------ .changeset/grumpy-games-shop.md | 5 --- .changeset/healthy-stingrays-shout.md | 5 --- .changeset/light-fireants-flow.md | 5 --- .changeset/light-horses-hammer.md | 5 --- .changeset/moody-pigs-repeat.md | 5 --- .changeset/new-shirts-move.md | 5 --- .changeset/quiet-badgers-cheer.md | 11 ----- .changeset/real-apples-visit.md | 5 --- .changeset/rotten-cups-bow.md | 6 --- .changeset/rude-items-bow.md | 5 --- .changeset/six-turtles-sip.md | 6 --- .changeset/sour-plums-enjoy.md | 7 --- .changeset/stale-carpets-poke.md | 30 ------------- .changeset/stale-chefs-retire.md | 5 --- .changeset/strong-houses-lick.md | 6 --- .changeset/techdocs-eight-camels-hear.md | 7 --- .changeset/techdocs-swift-mugs-invent.md | 5 --- .changeset/tiny-ears-love.md | 5 --- .changeset/unlucky-starfishes-vanish.md | 6 --- packages/app/CHANGELOG.md | 31 +++++++++++++ packages/app/package.json | 18 ++++---- packages/backend-common/CHANGELOG.md | 8 ++++ packages/backend-common/package.json | 4 +- packages/backend/CHANGELOG.md | 24 ++++++++++ packages/backend/package.json | 22 ++++----- packages/cli/CHANGELOG.md | 8 ++++ packages/cli/package.json | 8 ++-- packages/core-api/CHANGELOG.md | 9 ++++ packages/core-api/package.json | 6 +-- packages/core/CHANGELOG.md | 17 +++++++ packages/core/package.json | 8 ++-- packages/create-app/CHANGELOG.md | 52 ++++++++++++++++++++++ packages/create-app/package.json | 2 +- packages/theme/CHANGELOG.md | 6 +++ packages/theme/package.json | 4 +- plugins/api-docs/package.json | 6 +-- plugins/badges/package.json | 6 +-- plugins/bitrise/package.json | 6 +-- plugins/catalog-backend/CHANGELOG.md | 50 +++++++++++++++++++++ plugins/catalog-backend/package.json | 10 ++--- plugins/catalog-import/CHANGELOG.md | 16 +++++++ plugins/catalog-import/package.json | 8 ++-- plugins/catalog/CHANGELOG.md | 17 +++++++ plugins/catalog/package.json | 8 ++-- plugins/circleci/package.json | 6 +-- plugins/cloudbuild/package.json | 6 +-- plugins/code-coverage-backend/CHANGELOG.md | 10 +++++ plugins/code-coverage-backend/package.json | 6 +-- plugins/code-coverage/CHANGELOG.md | 17 +++++++ plugins/code-coverage/package.json | 8 ++-- plugins/config-schema/package.json | 6 +-- plugins/cost-insights/package.json | 6 +-- plugins/explore/package.json | 6 +-- plugins/fossa/CHANGELOG.md | 17 +++++++ plugins/fossa/package.json | 8 ++-- plugins/gcp-projects/package.json | 6 +-- plugins/github-actions/package.json | 6 +-- plugins/github-deployments/CHANGELOG.md | 16 +++++++ plugins/github-deployments/package.json | 8 ++-- plugins/gitops-profiles/package.json | 6 +-- plugins/graphiql/package.json | 6 +-- plugins/jenkins/package.json | 6 +-- plugins/kafka/package.json | 6 +-- plugins/kubernetes-backend/CHANGELOG.md | 9 ++++ plugins/kubernetes-backend/package.json | 6 +-- plugins/kubernetes/package.json | 6 +-- plugins/lighthouse/package.json | 6 +-- plugins/newrelic/package.json | 6 +-- plugins/org/package.json | 6 +-- plugins/pagerduty/package.json | 6 +-- plugins/register-component/package.json | 6 +-- plugins/rollbar-backend/CHANGELOG.md | 18 ++++++++ plugins/rollbar-backend/package.json | 6 +-- plugins/rollbar/package.json | 6 +-- plugins/scaffolder-backend/CHANGELOG.md | 21 +++++++++ plugins/scaffolder-backend/package.json | 6 +-- plugins/scaffolder/CHANGELOG.md | 17 +++++++ plugins/scaffolder/package.json | 8 ++-- plugins/search-backend-node/CHANGELOG.md | 6 +++ plugins/search-backend-node/package.json | 6 +-- plugins/search-backend/CHANGELOG.md | 11 +++++ plugins/search-backend/package.json | 8 ++-- plugins/search/package.json | 6 +-- plugins/sentry/package.json | 6 +-- plugins/sonarqube/package.json | 6 +-- plugins/splunk-on-call/package.json | 6 +-- plugins/tech-radar/package.json | 6 +-- plugins/techdocs/CHANGELOG.md | 22 +++++++++ plugins/techdocs/package.json | 8 ++-- plugins/todo/package.json | 6 +-- plugins/user-settings/package.json | 6 +-- plugins/welcome/CHANGELOG.md | 16 +++++++ plugins/welcome/package.json | 8 ++-- 106 files changed, 594 insertions(+), 387 deletions(-) delete mode 100644 .changeset/chatty-parents-search.md delete mode 100644 .changeset/dry-carrots-impress.md delete mode 100644 .changeset/dry-elephants-doubt.md delete mode 100644 .changeset/eight-plums-hide.md delete mode 100644 .changeset/eighty-crews-rhyme.md delete mode 100644 .changeset/fair-carrots-tell.md delete mode 100644 .changeset/flat-paws-rule.md delete mode 100644 .changeset/fluffy-suns-repair.md delete mode 100644 .changeset/fresh-cheetahs-rush.md delete mode 100644 .changeset/giant-onions-obey.md delete mode 100644 .changeset/good-glasses-build.md delete mode 100644 .changeset/gorgeous-pumas-cover.md delete mode 100644 .changeset/great-years-battle.md delete mode 100644 .changeset/grumpy-games-shop.md delete mode 100644 .changeset/healthy-stingrays-shout.md delete mode 100644 .changeset/light-fireants-flow.md delete mode 100644 .changeset/light-horses-hammer.md delete mode 100644 .changeset/moody-pigs-repeat.md delete mode 100644 .changeset/new-shirts-move.md delete mode 100644 .changeset/quiet-badgers-cheer.md delete mode 100644 .changeset/real-apples-visit.md delete mode 100644 .changeset/rotten-cups-bow.md delete mode 100644 .changeset/rude-items-bow.md delete mode 100644 .changeset/six-turtles-sip.md delete mode 100644 .changeset/sour-plums-enjoy.md delete mode 100644 .changeset/stale-carpets-poke.md delete mode 100644 .changeset/stale-chefs-retire.md delete mode 100644 .changeset/strong-houses-lick.md delete mode 100644 .changeset/techdocs-eight-camels-hear.md delete mode 100644 .changeset/techdocs-swift-mugs-invent.md delete mode 100644 .changeset/tiny-ears-love.md delete mode 100644 .changeset/unlucky-starfishes-vanish.md create mode 100644 plugins/code-coverage-backend/CHANGELOG.md create mode 100644 plugins/code-coverage/CHANGELOG.md diff --git a/.changeset/chatty-parents-search.md b/.changeset/chatty-parents-search.md deleted file mode 100644 index d9b1222d8f..0000000000 --- a/.changeset/chatty-parents-search.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Sort the table filter options by name. diff --git a/.changeset/dry-carrots-impress.md b/.changeset/dry-carrots-impress.md deleted file mode 100644 index aa057beb58..0000000000 --- a/.changeset/dry-carrots-impress.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-search-backend': patch -'@backstage/plugin-search-backend-node': patch ---- - -Lunr Search Engine support diff --git a/.changeset/dry-elephants-doubt.md b/.changeset/dry-elephants-doubt.md deleted file mode 100644 index 7a9ccc9892..0000000000 --- a/.changeset/dry-elephants-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-deployments': patch ---- - -Adds extraColumns field to GitHub Deployments card diff --git a/.changeset/eight-plums-hide.md b/.changeset/eight-plums-hide.md deleted file mode 100644 index d1f8bcecfe..0000000000 --- a/.changeset/eight-plums-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Forward user token to scaffolder task for subsequent api requests diff --git a/.changeset/eighty-crews-rhyme.md b/.changeset/eighty-crews-rhyme.md deleted file mode 100644 index 5a8379acb6..0000000000 --- a/.changeset/eighty-crews-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Exposing Material UI extension point for tabs to be able to add additional information to them diff --git a/.changeset/fair-carrots-tell.md b/.changeset/fair-carrots-tell.md deleted file mode 100644 index 62dce5c3ce..0000000000 --- a/.changeset/fair-carrots-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Add `config:docs` command that opens up reference documentation for the local configuration schema in a browser. diff --git a/.changeset/flat-paws-rule.md b/.changeset/flat-paws-rule.md deleted file mode 100644 index af7725793e..0000000000 --- a/.changeset/flat-paws-rule.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core': patch -'@backstage/plugin-scaffolder': patch ---- - -Adding Headings for Accessibility on the Scaffolder Plugin diff --git a/.changeset/fluffy-suns-repair.md b/.changeset/fluffy-suns-repair.md deleted file mode 100644 index 6f45905219..0000000000 --- a/.changeset/fluffy-suns-repair.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Respect top-level UI schema keys in scaffolder forms. Allows more advanced RJSF features such as explicit field ordering. diff --git a/.changeset/fresh-cheetahs-rush.md b/.changeset/fresh-cheetahs-rush.md deleted file mode 100644 index fe8a9caafb..0000000000 --- a/.changeset/fresh-cheetahs-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -No longer add newly created plugins to `plugins.ts` in the app, as it is no longer needed. diff --git a/.changeset/giant-onions-obey.md b/.changeset/giant-onions-obey.md deleted file mode 100644 index fbf9faa0a3..0000000000 --- a/.changeset/giant-onions-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-import': patch ---- - -allow import from HTTP repositories diff --git a/.changeset/good-glasses-build.md b/.changeset/good-glasses-build.md deleted file mode 100644 index 3d506d3e43..0000000000 --- a/.changeset/good-glasses-build.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-api': patch -'@backstage/core': patch ---- - -Add support for discovering plugins through the app element tree, removing the need to register them explicitly. diff --git a/.changeset/gorgeous-pumas-cover.md b/.changeset/gorgeous-pumas-cover.md deleted file mode 100644 index c4c9facac4..0000000000 --- a/.changeset/gorgeous-pumas-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-welcome': patch ---- - -Australian Greeting diff --git a/.changeset/great-years-battle.md b/.changeset/great-years-battle.md deleted file mode 100644 index a2d61be11a..0000000000 --- a/.changeset/great-years-battle.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-rollbar-backend': patch -'@backstage/plugin-scaffolder-backend': minor ---- - -Fix some `spleling`. - -The `scaffolder-backend` has a configuration schema change that may be breaking -in rare circumstances. Due to a typo in the schema, the -`scaffolder.github.visibility`, `scaffolder.gitlab.visibility`, and -`scaffolder.bitbucket.visibility` did not get proper validation that the value -is one of the supported strings (`public`, `internal` (not available for -Bitbucket), and `private`). If you had a value that was not one of these three, -you may have to adjust your config. diff --git a/.changeset/grumpy-games-shop.md b/.changeset/grumpy-games-shop.md deleted file mode 100644 index 7426786f89..0000000000 --- a/.changeset/grumpy-games-shop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -remove use of deprecated type HelmetOptions diff --git a/.changeset/healthy-stingrays-shout.md b/.changeset/healthy-stingrays-shout.md deleted file mode 100644 index c3ce59ce1f..0000000000 --- a/.changeset/healthy-stingrays-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -SystemDiagramCard UI improvements diff --git a/.changeset/light-fireants-flow.md b/.changeset/light-fireants-flow.md deleted file mode 100644 index a8f7b09278..0000000000 --- a/.changeset/light-fireants-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': minor ---- - -Fix the schema / code mismatch in LDAP `set` config diff --git a/.changeset/light-horses-hammer.md b/.changeset/light-horses-hammer.md deleted file mode 100644 index 0d421c7056..0000000000 --- a/.changeset/light-horses-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/theme': patch ---- - -Replace the link color in dark theme diff --git a/.changeset/moody-pigs-repeat.md b/.changeset/moody-pigs-repeat.md deleted file mode 100644 index 396fa80281..0000000000 --- a/.changeset/moody-pigs-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Exported SignInProviderConfig to strongly type SignInPage providers diff --git a/.changeset/new-shirts-move.md b/.changeset/new-shirts-move.md deleted file mode 100644 index 3896c85bbb..0000000000 --- a/.changeset/new-shirts-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Add low german greeting diff --git a/.changeset/quiet-badgers-cheer.md b/.changeset/quiet-badgers-cheer.md deleted file mode 100644 index e22bf9492c..0000000000 --- a/.changeset/quiet-badgers-cheer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Removed `plugins.ts` from the app, as plugins are now discovered through the react tree. - -To apply this change to an existing app, simply delete `packages/app/src/plugins.ts` along with the import and usage in `packages/app/src/App.tsx`. - -Note that there are a few plugins that require explicit registration, in which case you would need to keep them in `plugins.ts`. The set of plugins that need explicit registration is any plugin that doesn't have a component extension that gets rendered as part of the app element tree. An example of such a plugin in the main Backstage repo is `@backstage/plugin-badges`. In the case of the badges plugin this is because there is not yet a component-based API for adding context menu items to the entity layout. - -If you have plugins that still rely on route registration through the `register` method of `createPlugin`, these need to be kept in `plugins.ts` as well. However, it is recommended to migrate these to export an extensions component instead. diff --git a/.changeset/real-apples-visit.md b/.changeset/real-apples-visit.md deleted file mode 100644 index b5165f633b..0000000000 --- a/.changeset/real-apples-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -GithubDiscoveryProcessor now excludes archived repositories so they won't be added to Backstage. diff --git a/.changeset/rotten-cups-bow.md b/.changeset/rotten-cups-bow.md deleted file mode 100644 index 967681171d..0000000000 --- a/.changeset/rotten-cups-bow.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-code-coverage-backend': patch ---- - -Update tests to function in windows diff --git a/.changeset/rude-items-bow.md b/.changeset/rude-items-bow.md deleted file mode 100644 index 69b76d821e..0000000000 --- a/.changeset/rude-items-bow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Kubernetes client TLS verification is now configurable and defaults to true diff --git a/.changeset/six-turtles-sip.md b/.changeset/six-turtles-sip.md deleted file mode 100644 index e71b04e64d..0000000000 --- a/.changeset/six-turtles-sip.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Support configuration of file storage for SQLite databases. Every plugin has its -own database file at the specified path. diff --git a/.changeset/sour-plums-enjoy.md b/.changeset/sour-plums-enjoy.md deleted file mode 100644 index ef68166255..0000000000 --- a/.changeset/sour-plums-enjoy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Fix system diagram card to be on the system page - -To apply the same fix to an existing application, in `EntityPage.tsx` simply move the `<EntityLayout.route>` for the `/diagram` path from the `groupPage` down into the `systemPage` element. diff --git a/.changeset/stale-carpets-poke.md b/.changeset/stale-carpets-poke.md deleted file mode 100644 index 4f39e57b71..0000000000 --- a/.changeset/stale-carpets-poke.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Externalize repository processing for BitbucketDiscoveryProcessor. - -Add an extension point where you can customize how a matched Bitbucket repository should -be processed. This can for example be used if you want to generate the catalog-info.yaml -automatically based on other files in a repository, while taking advantage of the -build-in repository crawling functionality. - -`BitbucketDiscoveryProcessor.fromConfig` now takes an optional parameter `options.parser` where -you can customize the logic for each repository found. The default parser has the same -behaviour as before, where it emits an optional location for the matched repository -and lets the other processors take care of further processing. - -```typescript -const customRepositoryParser: BitbucketRepositoryParser = async function* customRepositoryParser({ - client, - repository, -}) { - // Custom logic for interpret the matching repository. - // See defaultRepositoryParser for an example -}; - -const processor = BitbucketDiscoveryProcessor.fromConfig(env.config, { - parser: customRepositoryParser, - logger: env.logger, -}); -``` diff --git a/.changeset/stale-chefs-retire.md b/.changeset/stale-chefs-retire.md deleted file mode 100644 index e43c20062a..0000000000 --- a/.changeset/stale-chefs-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Adding close button on support menu diff --git a/.changeset/strong-houses-lick.md b/.changeset/strong-houses-lick.md deleted file mode 100644 index 9739bdfda1..0000000000 --- a/.changeset/strong-houses-lick.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-api': patch -'@backstage/core': patch ---- - -Fixed a potentially confusing error being thrown about misuse of routable extensions where the error was actually something different. diff --git a/.changeset/techdocs-eight-camels-hear.md b/.changeset/techdocs-eight-camels-hear.md deleted file mode 100644 index 8f2479f6bd..0000000000 --- a/.changeset/techdocs-eight-camels-hear.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -Add feedback link icon in Techdocs Reader that directs to GitLab or GitHub repo issue page with pre-filled title and source link. -For link to appear, requires `repo_url` and `edit_uri` to be filled in mkdocs.yml, as per https://www.mkdocs.org/user-guide/configuration. An `edit_uri` will need to be specified for self-hosted GitLab/GitHub instances with a different host name. -To identify issue URL format as GitHub or GitLab, the host name of source in `repo_url` is checked if it contains `gitlab` or `github`. Alternately this is determined by matching to `host` values from `integrations` in app-config.yaml. diff --git a/.changeset/techdocs-swift-mugs-invent.md b/.changeset/techdocs-swift-mugs-invent.md deleted file mode 100644 index 912089fb3c..0000000000 --- a/.changeset/techdocs-swift-mugs-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Add a test id to the shadow root element of the Reader to access it easily in e2e tests diff --git a/.changeset/tiny-ears-love.md b/.changeset/tiny-ears-love.md deleted file mode 100644 index 9c3d1613a5..0000000000 --- a/.changeset/tiny-ears-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added support for Datadog rum events diff --git a/.changeset/unlucky-starfishes-vanish.md b/.changeset/unlucky-starfishes-vanish.md deleted file mode 100644 index 3bb341bee9..0000000000 --- a/.changeset/unlucky-starfishes-vanish.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-fossa': patch ---- - -Add a `FossaPage` that shows the license compliance status of all components in the catalog. -See the projects `Readme` on how to use it. diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 81a7f66f4c..7262b2ae29 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,36 @@ # example-app +## 0.2.25 + +### Patch Changes + +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [4e5c94249] +- Updated dependencies [99fbef232] +- Updated dependencies [cb0206b2b] +- Updated dependencies [1373f4f12] +- Updated dependencies [29a7e4be8] +- Updated dependencies [ab07d77f6] +- Updated dependencies [96728a2af] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [87c4f59de] +- Updated dependencies [55b2fc0c0] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] +- Updated dependencies [ac6025f63] +- Updated dependencies [e292e393f] +- Updated dependencies [479b29124] + - @backstage/core@0.7.6 + - @backstage/cli@0.6.9 + - @backstage/plugin-scaffolder@0.9.1 + - @backstage/plugin-catalog-import@0.5.3 + - @backstage/plugin-catalog@0.5.5 + - @backstage/theme@0.2.6 + - @backstage/plugin-code-coverage@0.1.2 + - @backstage/plugin-techdocs@0.8.0 + ## 0.2.24 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 95e14766c3..ba9af03310 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,21 +1,21 @@ { "name": "example-app", - "version": "0.2.24", + "version": "0.2.25", "private": true, "bundled": true, "dependencies": { "@backstage/catalog-model": "^0.7.7", - "@backstage/cli": "^0.6.8", - "@backstage/core": "^0.7.5", + "@backstage/cli": "^0.6.9", + "@backstage/core": "^0.7.6", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-api-docs": "^0.4.11", "@backstage/plugin-badges": "^0.2.0", - "@backstage/plugin-catalog": "^0.5.4", - "@backstage/plugin-catalog-import": "^0.5.2", + "@backstage/plugin-catalog": "^0.5.5", + "@backstage/plugin-catalog-import": "^0.5.3", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/plugin-circleci": "^0.2.12", "@backstage/plugin-cloudbuild": "^0.2.13", - "@backstage/plugin-code-coverage": "^0.1.0", + "@backstage/plugin-code-coverage": "^0.1.2", "@backstage/plugin-cost-insights": "^0.8.4", "@backstage/plugin-explore": "^0.3.2", "@backstage/plugin-gcp-projects": "^0.2.5", @@ -29,14 +29,14 @@ "@backstage/plugin-org": "^0.3.12", "@backstage/plugin-pagerduty": "0.3.2", "@backstage/plugin-rollbar": "^0.3.3", - "@backstage/plugin-scaffolder": "^0.9.0", + "@backstage/plugin-scaffolder": "^0.9.1", "@backstage/plugin-search": "^0.3.4", "@backstage/plugin-sentry": "^0.3.8", "@backstage/plugin-tech-radar": "^0.3.9", - "@backstage/plugin-techdocs": "^0.7.2", + "@backstage/plugin-techdocs": "^0.8.0", "@backstage/plugin-todo": "^0.1.0", "@backstage/plugin-user-settings": "^0.2.8", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@octokit/rest": "^18.0.12", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index c194f7e666..68fab7d861 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/backend-common +## 0.6.3 + +### Patch Changes + +- d367f63b5: remove use of deprecated type HelmetOptions +- b42531cfe: Support configuration of file storage for SQLite databases. Every plugin has its + own database file at the specified path. + ## 0.6.2 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 41fa657818..998ac475d9 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.6.2", + "version": "0.6.3", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -73,7 +73,7 @@ } }, "devDependencies": { - "@backstage/cli": "^0.6.7", + "@backstage/cli": "^0.6.9", "@backstage/test-utils": "^0.1.10", "@types/archiver": "^5.1.0", "@types/compression": "^1.7.0", diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 6585ea2723..ee04e2bb6b 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,29 @@ # example-backend +## 0.2.25 + +### Patch Changes + +- Updated dependencies [b9b2b4b76] +- Updated dependencies [84c54474d] +- Updated dependencies [49574a8a3] +- Updated dependencies [d367f63b5] +- Updated dependencies [5fe62f124] +- Updated dependencies [09b5fcf2e] +- Updated dependencies [55b2fc0c0] +- Updated dependencies [c42cd1daa] +- Updated dependencies [b42531cfe] +- Updated dependencies [c2306f898] + - @backstage/plugin-search-backend@0.1.3 + - @backstage/plugin-search-backend-node@0.1.3 + - @backstage/plugin-scaffolder-backend@0.10.0 + - @backstage/plugin-rollbar-backend@0.1.9 + - @backstage/backend-common@0.6.3 + - @backstage/plugin-catalog-backend@0.8.0 + - @backstage/plugin-code-coverage-backend@0.1.2 + - @backstage/plugin-kubernetes-backend@0.3.5 + - example-app@0.2.25 + ## 0.2.22 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 984b8b60a5..440ceca8e5 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.22", + "version": "0.2.25", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -27,30 +27,30 @@ "migrate:create": "knex migrate:make -x ts" }, "dependencies": { - "@backstage/backend-common": "^0.6.1", + "@backstage/backend-common": "^0.6.3", "@backstage/catalog-client": "^0.3.9", "@backstage/catalog-model": "^0.7.5", "@backstage/config": "^0.1.4", "@backstage/plugin-app-backend": "^0.3.10", "@backstage/plugin-auth-backend": "^0.3.7", "@backstage/plugin-badges-backend": "^0.1.1", - "@backstage/plugin-catalog-backend": "^0.7.0", - "@backstage/plugin-code-coverage-backend": "^0.1.0", + "@backstage/plugin-catalog-backend": "^0.8.0", + "@backstage/plugin-code-coverage-backend": "^0.1.2", "@backstage/plugin-graphql-backend": "^0.1.6", - "@backstage/plugin-kubernetes-backend": "^0.3.3", + "@backstage/plugin-kubernetes-backend": "^0.3.5", "@backstage/plugin-kafka-backend": "^0.2.3", "@backstage/plugin-proxy-backend": "^0.2.6", - "@backstage/plugin-rollbar-backend": "^0.1.8", - "@backstage/plugin-scaffolder-backend": "^0.9.4", - "@backstage/plugin-search-backend": "^0.1.2", - "@backstage/plugin-search-backend-node": "^0.1.2", + "@backstage/plugin-rollbar-backend": "^0.1.9", + "@backstage/plugin-scaffolder-backend": "^0.10.0", + "@backstage/plugin-search-backend": "^0.1.3", + "@backstage/plugin-search-backend-node": "^0.1.3", "@backstage/plugin-techdocs-backend": "^0.7.0", "@backstage/plugin-todo-backend": "^0.1.3", "@gitbeaker/node": "^28.0.2", "@octokit/rest": "^18.0.12", "azure-devops-node-api": "^10.1.1", "dockerode": "^3.2.1", - "example-app": "^0.2.21", + "example-app": "^0.2.25", "express": "^4.17.1", "express-promise-router": "^4.1.0", "knex": "^0.95.1", @@ -60,7 +60,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.6", + "@backstage/cli": "^0.6.9", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5" diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a1381495ff..af452b3c9d 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/cli +## 0.6.9 + +### Patch Changes + +- 4e5c94249: Add `config:docs` command that opens up reference documentation for the local configuration schema in a browser. +- 1373f4f12: No longer add newly created plugins to `plugins.ts` in the app, as it is no longer needed. +- 479b29124: Added support for Datadog rum events + ## 0.6.8 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 251b2ab076..cd61193efe 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.6.8", + "version": "0.6.9", "private": false, "publishConfig": { "access": "public" @@ -116,12 +116,12 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-common": "^0.6.2", + "@backstage/backend-common": "^0.6.3", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@types/diff": "^5.0.0", "@types/express": "^4.17.6", "@types/fs-extra": "^9.0.1", diff --git a/packages/core-api/CHANGELOG.md b/packages/core-api/CHANGELOG.md index 609940b8db..fab82a77e5 100644 --- a/packages/core-api/CHANGELOG.md +++ b/packages/core-api/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/core-api +## 0.2.17 + +### Patch Changes + +- ab07d77f6: Add support for discovering plugins through the app element tree, removing the need to register them explicitly. +- 50ce875a0: Fixed a potentially confusing error being thrown about misuse of routable extensions where the error was actually something different. +- Updated dependencies [931b21a12] + - @backstage/theme@0.2.6 + ## 0.2.16 ### Patch Changes diff --git a/packages/core-api/package.json b/packages/core-api/package.json index 33e5ac146d..a55df67343 100644 --- a/packages/core-api/package.json +++ b/packages/core-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-api", "description": "Internal Core API used by Backstage plugins and apps", - "version": "0.2.16", + "version": "0.2.17", "private": false, "publishConfig": { "access": "public", @@ -30,7 +30,7 @@ }, "dependencies": { "@backstage/config": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@types/react": "^16.9", @@ -42,7 +42,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.7", + "@backstage/cli": "^0.6.9", "@backstage/test-utils": "^0.1.10", "@backstage/test-utils-core": "^0.1.1", "@testing-library/jest-dom": "^5.10.1", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 7f691a2787..1b556ac1c3 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/core +## 0.7.6 + +### Patch Changes + +- 94da20976: Sort the table filter options by name. +- d8cc7e67a: Exposing Material UI extension point for tabs to be able to add additional information to them +- 99fbef232: Adding Headings for Accessibility on the Scaffolder Plugin +- ab07d77f6: Add support for discovering plugins through the app element tree, removing the need to register them explicitly. +- 937ed39ce: Exported SignInProviderConfig to strongly type SignInPage providers +- 9a9e7a42f: Adding close button on support menu +- 50ce875a0: Fixed a potentially confusing error being thrown about misuse of routable extensions where the error was actually something different. +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [50ce875a0] + - @backstage/core-api@0.2.17 + - @backstage/theme@0.2.6 + ## 0.7.5 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 7b1898a19d..344ea10398 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core", "description": "Core API used by Backstage plugins and apps", - "version": "0.7.5", + "version": "0.7.6", "private": false, "publishConfig": { "access": "public", @@ -30,9 +30,9 @@ }, "dependencies": { "@backstage/config": "^0.1.4", - "@backstage/core-api": "^0.2.16", + "@backstage/core-api": "^0.2.17", "@backstage/errors": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -69,7 +69,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 5975b78e06..bd35768e68 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/create-app +## 1.0.0 + +### Patch Changes + +- ee22773e9: Removed `plugins.ts` from the app, as plugins are now discovered through the react tree. + + To apply this change to an existing app, simply delete `packages/app/src/plugins.ts` along with the import and usage in `packages/app/src/App.tsx`. + + Note that there are a few plugins that require explicit registration, in which case you would need to keep them in `plugins.ts`. The set of plugins that need explicit registration is any plugin that doesn't have a component extension that gets rendered as part of the app element tree. An example of such a plugin in the main Backstage repo is `@backstage/plugin-badges`. In the case of the badges plugin this is because there is not yet a component-based API for adding context menu items to the entity layout. + + If you have plugins that still rely on route registration through the `register` method of `createPlugin`, these need to be kept in `plugins.ts` as well. However, it is recommended to migrate these to export an extensions component instead. + +- 670acd88e: Fix system diagram card to be on the system page + + To apply the same fix to an existing application, in `EntityPage.tsx` simply move the `<EntityLayout.route>` for the `/diagram` path from the `groupPage` down into the `systemPage` element. + +- Updated dependencies [94da20976] +- Updated dependencies [84c54474d] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [4e5c94249] +- Updated dependencies [99fbef232] +- Updated dependencies [cb0206b2b] +- Updated dependencies [1373f4f12] +- Updated dependencies [29a7e4be8] +- Updated dependencies [ab07d77f6] +- Updated dependencies [49574a8a3] +- Updated dependencies [d367f63b5] +- Updated dependencies [96728a2af] +- Updated dependencies [5fe62f124] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [87c4f59de] +- Updated dependencies [09b5fcf2e] +- Updated dependencies [b42531cfe] +- Updated dependencies [c2306f898] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] +- Updated dependencies [ac6025f63] +- Updated dependencies [e292e393f] +- Updated dependencies [479b29124] + - @backstage/core@0.7.6 + - @backstage/plugin-scaffolder-backend@0.10.0 + - @backstage/cli@0.6.9 + - @backstage/plugin-scaffolder@0.9.1 + - @backstage/plugin-catalog-import@0.5.3 + - @backstage/plugin-rollbar-backend@0.1.9 + - @backstage/backend-common@0.6.3 + - @backstage/plugin-catalog@0.5.5 + - @backstage/plugin-catalog-backend@0.8.0 + - @backstage/theme@0.2.6 + - @backstage/plugin-techdocs@0.8.0 + ## 0.3.18 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index ea3d3548b8..2b30eafa2b 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "0.3.18", + "version": "1.0.0", "private": false, "publishConfig": { "access": "public" diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index 9ce3c75802..22964d6b25 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/theme +## 0.2.6 + +### Patch Changes + +- 931b21a12: Replace the link color in dark theme + ## 0.2.5 ### Patch Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index b10e01ca1b..87821b6751 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.2.5", + "version": "0.2.6", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ "@material-ui/core": "^4.11.0" }, "devDependencies": { - "@backstage/cli": "^0.6.6" + "@backstage/cli": "^0.6.9" }, "files": [ "dist" diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 13f27c321b..51df09ba80 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -31,9 +31,9 @@ "dependencies": { "@asyncapi/react-component": "^0.22.3", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-icons/font": "^1.0.2", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -49,7 +49,7 @@ "swagger-ui-react": "^3.37.2" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 0d59e271b0..9f0c49af7e 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -21,10 +21,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,7 +34,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 16a02ae42a..83911cdfc4 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.2", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -37,7 +37,7 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 94e9960e35..28efc1c5d3 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,55 @@ # @backstage/plugin-catalog-backend +## 0.8.0 + +### Minor Changes + +- 5fe62f124: Fix the schema / code mismatch in LDAP `set` config + +### Patch Changes + +- 09b5fcf2e: GithubDiscoveryProcessor now excludes archived repositories so they won't be added to Backstage. +- c2306f898: Externalize repository processing for BitbucketDiscoveryProcessor. + + Add an extension point where you can customize how a matched Bitbucket repository should + be processed. This can for example be used if you want to generate the catalog-info.yaml + automatically based on other files in a repository, while taking advantage of the + build-in repository crawling functionality. + + `BitbucketDiscoveryProcessor.fromConfig` now takes an optional parameter `options.parser` where + you can customize the logic for each repository found. The default parser has the same + behaviour as before, where it emits an optional location for the matched repository + and lets the other processors take care of further processing. + + ```typescript + const customRepositoryParser: BitbucketRepositoryParser = async function* customRepositoryParser({ + client, + repository, + }) { + // Custom logic for interpret the matching repository. + // See defaultRepositoryParser for an example + }; + + const processor = BitbucketDiscoveryProcessor.fromConfig(env.config, { + parser: customRepositoryParser, + logger: env.logger, + }); + ``` + +- Updated dependencies [94da20976] +- Updated dependencies [b9b2b4b76] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [d367f63b5] +- Updated dependencies [937ed39ce] +- Updated dependencies [b42531cfe] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/plugin-search-backend-node@0.1.3 + - @backstage/backend-common@0.6.3 + ## 0.7.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 5125e9703e..9afb537637 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "0.7.1", + "version": "0.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,13 +30,13 @@ }, "dependencies": { "@azure/msal-node": "^1.0.0-beta.3", - "@backstage/backend-common": "^0.6.1", + "@backstage/backend-common": "^0.6.3", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.3", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", - "@backstage/plugin-search-backend-node": "^0.1.2", + "@backstage/plugin-search-backend-node": "^0.1.3", "@backstage/search-common": "^0.1.1", "@octokit/graphql": "^4.5.8", "@types/express": "^4.17.6", @@ -65,7 +65,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/test-utils": "^0.1.9", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 5fd93562d6..8c189a5f9b 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-import +## 0.5.3 + +### Patch Changes + +- 29a7e4be8: allow import from HTTP repositories +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.5.2 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 6af4b02bd0..9ba32d830c 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.5.2", + "version": "0.5.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,11 +32,11 @@ "dependencies": { "@backstage/catalog-model": "^0.7.6", "@backstage/catalog-client": "^0.3.9", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/integration": "^0.5.0", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -53,7 +53,7 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index eccfa953a4..35e000f130 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog +## 0.5.5 + +### Patch Changes + +- 96728a2af: SystemDiagramCard UI improvements +- 87c4f59de: Add low german greeting +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.5.4 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 8561ae3188..b6b306c260 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "0.5.4", + "version": "0.5.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,12 +32,12 @@ "dependencies": { "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -53,7 +53,7 @@ "swr": "^0.3.0" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@microsoft/microsoft-graph-types": "^1.25.0", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 5eb91d08bb..5c05c0ee6f 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -50,7 +50,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 75e877ccb6..6ad0b8bfa9 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -32,8 +32,8 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md new file mode 100644 index 0000000000..cfc08db5c4 --- /dev/null +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -0,0 +1,10 @@ +# @backstage/plugin-code-coverage-backend + +## 0.1.2 + +### Patch Changes + +- 55b2fc0c0: Update tests to function in windows +- Updated dependencies [d367f63b5] +- Updated dependencies [b42531cfe] + - @backstage/backend-common@0.6.3 diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 1e7903b016..3fc238ce61 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-coverage-backend", - "version": "0.1.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,7 +19,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.2", + "@backstage/backend-common": "^0.6.3", "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", @@ -36,7 +36,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", "msw": "^0.21.2", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md new file mode 100644 index 0000000000..4a55b7f0f5 --- /dev/null +++ b/plugins/code-coverage/CHANGELOG.md @@ -0,0 +1,17 @@ +# @backstage/plugin-code-coverage + +## 0.1.2 + +### Patch Changes + +- 55b2fc0c0: Update tests to function in windows +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 1d02da3dea..1adc94fff7 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-coverage", - "version": "0.1.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/styles": "^4.11.0", @@ -39,7 +39,7 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 2db05d549a..55f785a7a4 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,7 +34,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index bec5db9fe0..c68fdde509 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -31,8 +31,8 @@ }, "dependencies": { "@backstage/config": "^0.1.3", - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -55,7 +55,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 7765760906..7c2eb5c90d 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -31,10 +31,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/plugin-explore-react": "^0.0.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -45,7 +45,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index 001b926c6d..fe916804d2 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-fossa +## 0.2.5 + +### Patch Changes + +- 40d1e11cf: Add a `FossaPage` that shows the license compliance status of all components in the catalog. + See the projects `Readme` on how to use it. +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.2.4 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 2f656c476a..23f9cfde74 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-fossa", - "version": "0.2.4", + "version": "0.2.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,10 +32,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index fecf9bdf22..509576cf2b 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 3dba840b8b..6a95803d6f 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -34,9 +34,9 @@ "dependencies": { "@backstage/catalog-model": "^0.7.5", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/integration": "^0.5.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -50,7 +50,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 9369ef87f9..e7f849ef2e 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-github-deployments +## 0.1.3 + +### Patch Changes + +- 60d0a1a2e: Adds extraColumns field to GitHub Deployments card +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.1.2 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index c5571b6e1f..12a36c160e 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-deployments", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,7 +34,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index d3a0d0df66..ae614fe504 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -42,7 +42,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 4ebedffd74..4aa26587ad 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -43,7 +43,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index c736eb0b5b..edee4bc2ee 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 644c074b81..a7295469d6 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -33,7 +33,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 379f0dd872..8bcac8a60b 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes-backend +## 0.3.5 + +### Patch Changes + +- c42cd1daa: Kubernetes client TLS verification is now configurable and defaults to true +- Updated dependencies [d367f63b5] +- Updated dependencies [b42531cfe] + - @backstage/backend-common@0.6.3 + ## 0.3.4 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 79864b7b48..7a8b16bc8a 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.3.4", + "version": "0.3.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.1", + "@backstage/backend-common": "^0.6.3", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", "@google-cloud/container": "^2.2.0", @@ -52,7 +52,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@types/aws4": "^1.5.1", "supertest": "^6.1.3" }, diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index df00c0801f..03013e1480 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -33,10 +33,10 @@ "dependencies": { "@backstage/catalog-model": "^0.7.4", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/plugin-kubernetes-backend": "^0.3.2", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@kubernetes/client-node": "^0.14.0", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -50,7 +50,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index eb7d69d77d..45980df00c 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -33,9 +33,9 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -46,7 +46,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 82952c7452..0951d972c2 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/org/package.json b/plugins/org/package.json index 0a9917cb7d..5bed02e9c8 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -21,10 +21,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/core-api": "^0.2.16", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -35,7 +35,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 44e8cb5b7f..c0e3afec34 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -46,7 +46,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index a8cfcc894a..2870ef79f1 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -45,7 +45,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index a64fa25a81..8e20e93555 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-rollbar-backend +## 0.1.9 + +### Patch Changes + +- 49574a8a3: Fix some `spleling`. + + The `scaffolder-backend` has a configuration schema change that may be breaking + in rare circumstances. Due to a typo in the schema, the + `scaffolder.github.visibility`, `scaffolder.gitlab.visibility`, and + `scaffolder.bitbucket.visibility` did not get proper validation that the value + is one of the supported strings (`public`, `internal` (not available for + Bitbucket), and `private`). If you had a value that was not one of these three, + you may have to adjust your config. + +- Updated dependencies [d367f63b5] +- Updated dependencies [b42531cfe] + - @backstage/backend-common@0.6.3 + ## 0.1.8 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 489c12139d..05b02b2c39 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-rollbar-backend", - "version": "0.1.8", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.0", + "@backstage/backend-common": "^0.6.3", "@backstage/config": "^0.1.4", "@types/express": "^4.17.6", "axios": "^0.21.1", @@ -47,7 +47,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.5", + "@backstage/cli": "^0.6.9", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 6d0e49b1ae..6d654866af 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 2c45bdc611..cb1855e041 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-scaffolder-backend +## 0.10.0 + +### Minor Changes + +- 49574a8a3: Fix some `spleling`. + + The `scaffolder-backend` has a configuration schema change that may be breaking + in rare circumstances. Due to a typo in the schema, the + `scaffolder.github.visibility`, `scaffolder.gitlab.visibility`, and + `scaffolder.bitbucket.visibility` did not get proper validation that the value + is one of the supported strings (`public`, `internal` (not available for + Bitbucket), and `private`). If you had a value that was not one of these three, + you may have to adjust your config. + +### Patch Changes + +- 84c54474d: Forward user token to scaffolder task for subsequent api requests +- Updated dependencies [d367f63b5] +- Updated dependencies [b42531cfe] + - @backstage/backend-common@0.6.3 + ## 0.9.6 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 2c65d91604..729ef58d99 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "0.9.6", + "version": "0.10.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.2", + "@backstage/backend-common": "^0.6.3", "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", @@ -67,7 +67,7 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/test-utils": "^0.1.10", "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index b7a8cbb89c..fee76f8775 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-scaffolder +## 0.9.1 + +### Patch Changes + +- 99fbef232: Adding Headings for Accessibility on the Scaffolder Plugin +- cb0206b2b: Respect top-level UI schema keys in scaffolder forms. Allows more advanced RJSF features such as explicit field ordering. +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.9.0 ### Minor Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 10785a4db7..4d4563df2f 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "0.9.0", + "version": "0.9.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -60,7 +60,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 8718488b21..e7a9d9aa0a 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-search-backend-node +## 0.1.3 + +### Patch Changes + +- b9b2b4b76: Lunr Search Engine support + ## 0.1.2 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 2d1803f4c4..b5d13af01c 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,8 +25,8 @@ "@types/lunr": "^2.3.3" }, "devDependencies": { - "@backstage/backend-common": "^0.6.0", - "@backstage/cli": "^0.6.6" + "@backstage/backend-common": "^0.6.3", + "@backstage/cli": "^0.6.9" }, "files": [ "dist" diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index b6a8d9fd18..9313e2e83a 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-search-backend +## 0.1.3 + +### Patch Changes + +- b9b2b4b76: Lunr Search Engine support +- Updated dependencies [b9b2b4b76] +- Updated dependencies [d367f63b5] +- Updated dependencies [b42531cfe] + - @backstage/plugin-search-backend-node@0.1.3 + - @backstage/backend-common@0.6.3 + ## 0.1.2 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 82b72e9506..a94fed35b9 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,9 +19,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.0", + "@backstage/backend-common": "^0.6.3", "@backstage/search-common": "^0.1.1", - "@backstage/plugin-search-backend-node": "^0.1.2", + "@backstage/plugin-search-backend-node": "^0.1.3", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -29,7 +29,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.6", + "@backstage/cli": "^0.6.9", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/search/package.json b/plugins/search/package.json index 13019c7f32..c7ab201efe 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -29,11 +29,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/catalog-model": "^0.7.3", "@backstage/plugin-catalog-react": "^0.1.2", "@backstage/search-common": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -44,7 +44,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index dee05a8c2d..9908af2e24 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -46,7 +46,7 @@ "timeago.js": "^4.0.2" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index d48f59febe..97243bb930 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -34,8 +34,8 @@ "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 990d0acb27..ecaf21f8eb 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.4", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -45,7 +45,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index e927ed938a..5a1c2e2095 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -30,8 +30,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -43,7 +43,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 3924a56df3..4f89cd9844 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-techdocs +## 0.8.0 + +### Minor Changes + +- ac6025f63: Add feedback link icon in Techdocs Reader that directs to GitLab or GitHub repo issue page with pre-filled title and source link. + For link to appear, requires `repo_url` and `edit_uri` to be filled in mkdocs.yml, as per https://www.mkdocs.org/user-guide/configuration. An `edit_uri` will need to be specified for self-hosted GitLab/GitHub instances with a different host name. + To identify issue URL format as GitHub or GitLab, the host name of source in `repo_url` is checked if it contains `gitlab` or `github`. Alternately this is determined by matching to `host` values from `integrations` in app-config.yaml. + +### Patch Changes + +- e292e393f: Add a test id to the shadow root element of the Reader to access it easily in e2e tests +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.7.2 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 88b3b6a1df..025a419f59 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "0.7.2", + "version": "0.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ "dependencies": { "@backstage/config": "^0.1.4", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/test-utils": "^0.1.9", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@backstage/errors": "^0.1.1", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -49,7 +49,7 @@ "sanitize-html": "^2.3.2" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 5a80f068cc..7339e568c3 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -27,10 +27,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.5", + "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.5", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -39,7 +39,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 6055f31b8a..d410dc103e 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/welcome/CHANGELOG.md b/plugins/welcome/CHANGELOG.md index 68b8c358c2..cf907b5b4f 100644 --- a/plugins/welcome/CHANGELOG.md +++ b/plugins/welcome/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-welcome +## 0.2.7 + +### Patch Changes + +- f85851837: Australian Greeting +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + ## 0.2.6 ### Patch Changes diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index aa7a746016..b276b86835 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-welcome", - "version": "0.2.6", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -30,8 +30,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.7.5", - "@backstage/theme": "^0.2.5", + "@backstage/core": "^0.7.6", + "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.9", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", From f218637d0859edd6d1bbce4f8050b5c73c430723 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 22 Apr 2021 13:43:17 +0200 Subject: [PATCH 172/462] create-app: release version 0.3.19 Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/create-app/CHANGELOG.md | 2 +- packages/create-app/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index bd35768e68..c821a3ab81 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,6 +1,6 @@ # @backstage/create-app -## 1.0.0 +## 0.3.19 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 2b30eafa2b..5cf6cdd78e 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "1.0.0", + "version": "0.3.19", "private": false, "publishConfig": { "access": "public" From 6fbd7beca5bd67cc7721c942e7180aecb60ba273 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 15:50:24 +0200 Subject: [PATCH 173/462] Rename changeset Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- ...lovely-wombats-relate.md => techdocs-lovely-wombats-relate.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changeset/{lovely-wombats-relate.md => techdocs-lovely-wombats-relate.md} (100%) diff --git a/.changeset/lovely-wombats-relate.md b/.changeset/techdocs-lovely-wombats-relate.md similarity index 100% rename from .changeset/lovely-wombats-relate.md rename to .changeset/techdocs-lovely-wombats-relate.md From dcd54c7cd12ec1c48ce44e8a2f7c9e4c0d300d07 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 16:07:13 +0200 Subject: [PATCH 174/462] Use `RouteRef` to generate path to search page Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/sixty-dragons-retire.md | 5 +++++ .../src/components/SidebarSearch/SidebarSearch.tsx | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/sixty-dragons-retire.md diff --git a/.changeset/sixty-dragons-retire.md b/.changeset/sixty-dragons-retire.md new file mode 100644 index 0000000000..62965c6e88 --- /dev/null +++ b/.changeset/sixty-dragons-retire.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search': patch +--- + +Use `RouteRef` to generate path to search page. diff --git a/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx b/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx index 7e72e83b02..b422c33e02 100644 --- a/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx +++ b/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx @@ -13,22 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useCallback } from 'react'; +import { SidebarSearchField, useRouteRef } from '@backstage/core'; import qs from 'qs'; +import React, { useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; -import { SidebarSearchField } from '@backstage/core'; +import { rootRouteRef } from '../../plugin'; export const SidebarSearch = () => { + const searchRoute = useRouteRef(rootRouteRef); const navigate = useNavigate(); const handleSearch = useCallback( (query: string): void => { const queryString = qs.stringify({ query }, { addQueryPrefix: true }); - // TODO: Here the url to the search plugin is hardcoded. We need a way to query the route in the future. - // Maybe an API that I can just call from other places? - navigate(`/search${queryString}`); + navigate(`${searchRoute()}${queryString}`); }, - [navigate], + [navigate, searchRoute], ); return <SidebarSearchField onSearch={handleSearch} to="/search" />; From 546172674279917bfa49ce621207925e760a6da5 Mon Sep 17 00:00:00 2001 From: jrusso1020 <jrusso@brex.com> Date: Thu, 22 Apr 2021 09:08:46 -0600 Subject: [PATCH 175/462] [Fixes 5420] Update component example in documentation Currently the entity component example towards the top of the page has metadata.labels.system set https://github.com/backstage/backstage/blame/master/docs/features/software-catalog/descriptor-format.md#L47 but further down on the page it's spec.system https://github.com/backstage/backstage/blame/master/docs/features/software-catalog/descriptor-format.md#L423. This updates them to both use the correct spec.system key/value, as well as add an example label to get a sense for what labels look like as well Signed-off-by: jrusso1020 <jrusso@brex.com> --- docs/features/software-catalog/descriptor-format.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index d3b14dd888..2506e2e9c1 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -44,7 +44,7 @@ metadata: name: artist-web description: The place to be, for great artists labels: - system: public-websites + backstage.io/custom: ValueStuff annotations: example.com/service-discovery: artistweb circleci.com/project-slug: github/example-org/artist-website @@ -58,6 +58,7 @@ spec: type: website lifecycle: production owner: artist-relations-team + system: public-websites ``` This is the same entity as returned in JSON from the software catalog API: @@ -76,7 +77,7 @@ This is the same entity as returned in JSON from the software catalog API: "etag": "ZjU2MWRkZWUtMmMxZS00YTZiLWFmMWMtOTE1NGNiZDdlYzNk", "generation": 1, "labels": { - "system": "public-websites" + "backstage.io/custom": "ValueStuff" }, "links": [{ "url": "https://admin.example-org.com", @@ -90,7 +91,8 @@ This is the same entity as returned in JSON from the software catalog API: "spec": { "lifecycle": "production", "owner": "artist-relations-team", - "type": "website" + "type": "website", + "system": "public-websites" } } ``` From 8bd92cff3f0c9c5d794252bb51dda4859829d8bf Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Thu, 22 Apr 2021 17:30:08 +0200 Subject: [PATCH 176/462] Update nginx deployment to use 1.19 features - There is no need to override the `CMD` on the base image to get the custom scripts to run. This can be done simply by adding the custom configuration script to the `/docker-entrypoint.d` folder. See https://github.com/nginxinc/docker-nginx/blob/master/mainline/debian/docker-entrypoint.sh. - With the above change made, we can now also reap the benefit of support for `envsubst` having been added in 1.19 - as long as the config is placed in the folder `/etc/nginx/templates/`. See https://github.com/docker-library/docs/tree/master/nginx#using-environment-variables-in-nginx-configuration-new-in-119 and https://github.com/nginxinc/docker-nginx/blob/master/mainline/debian/20-envsubst-on-templates.sh for more info. Signed-off-by: Brian Fox <brianhfox@gmail.com> --- contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild | 5 ++--- contrib/docker/frontend-with-nginx/Dockerfile.hostbuild | 6 +++--- .../docker/{run.sh => inject-config.sh} | 8 -------- 3 files changed, 5 insertions(+), 14 deletions(-) rename contrib/docker/frontend-with-nginx/docker/{run.sh => inject-config.sh} (80%) diff --git a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild index dda9779eb0..41f931544f 100644 --- a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild +++ b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild @@ -51,9 +51,8 @@ FROM nginx:mainline RUN apt-get update && apt-get -y install jq && rm -rf /var/lib/apt/lists/* COPY --from=build /app/packages/app/dist /usr/share/nginx/html -COPY docker/default.conf.template /etc/nginx/conf.d/default.conf.template -COPY docker/run.sh /usr/local/bin/run.sh +COPY docker/default.conf.template /etc/nginx/templates/default.conf.template -CMD run.sh +COPY docker/inject-config.sh /docker-entrypoint.d/40-inject-config.sh ENV PORT 80 diff --git a/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild b/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild index 6e5912dd67..1e0134017f 100644 --- a/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild +++ b/contrib/docker/frontend-with-nginx/Dockerfile.hostbuild @@ -33,9 +33,9 @@ FROM nginx:mainline RUN apt-get update && apt-get -y install jq && rm -rf /var/lib/apt/lists/* COPY packages/app/dist /usr/share/nginx/html -COPY docker/default.conf.template /etc/nginx/conf.d/default.conf.template -COPY docker/run.sh /usr/local/bin/run.sh +COPY docker/default.conf.template /etc/nginx/templates/default.conf.template -CMD run.sh +COPY docker/inject-config.sh /docker-entrypoint.d/40-inject-config.sh ENV PORT 80 + diff --git a/contrib/docker/frontend-with-nginx/docker/run.sh b/contrib/docker/frontend-with-nginx/docker/inject-config.sh similarity index 80% rename from contrib/docker/frontend-with-nginx/docker/run.sh rename to contrib/docker/frontend-with-nginx/docker/inject-config.sh index fdb1742a07..a0cea96ff3 100755 --- a/contrib/docker/frontend-with-nginx/docker/run.sh +++ b/contrib/docker/frontend-with-nginx/docker/inject-config.sh @@ -2,13 +2,6 @@ set -Eeuo pipefail -# Run nginx as root -sed -i 's/user nginx.*$//' /etc/nginx/nginx.conf - -# Write selected env vars to nginx config -envsubst '$PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf - -# Inject runtime config into the client function inject_config() { # Read runtime config from env in the same way as the @backstage/config-loader package local config @@ -41,4 +34,3 @@ function inject_config() { inject_config -exec nginx -g 'daemon off;' From c6a5acfc2a84ed0ef3269cc4958276604286caf7 Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Thu, 22 Apr 2021 17:46:21 +0200 Subject: [PATCH 177/462] Fix typo - Service should be only be enabled when backend is enabled Signed-off-by: Brian Fox <brianhfox@gmail.com> --- .../backstage/templates/service.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/kubernetes/basic_kubernetes_example_with_helm/backstage/templates/service.yaml b/contrib/kubernetes/basic_kubernetes_example_with_helm/backstage/templates/service.yaml index 77a113ae5c..e74bfe0b8d 100644 --- a/contrib/kubernetes/basic_kubernetes_example_with_helm/backstage/templates/service.yaml +++ b/contrib/kubernetes/basic_kubernetes_example_with_helm/backstage/templates/service.yaml @@ -16,7 +16,7 @@ spec: app.kubernetes.io/name: {{ include "backstage.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} -{{- if .Values.app.enabled }} +{{- if .Values.backend.enabled }} --- apiVersion: v1 kind: Service From 610619dba09e0c82be7abde8c16ae54456cc77d2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 15 Apr 2021 19:45:40 +0200 Subject: [PATCH 178/462] docs: update install step in plugin architecture docs Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/overview/architecture-overview.md | 48 +++++++++++++++----------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index f2f2bc72c8..fab5698014 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -67,33 +67,41 @@ is available at ### Installing plugins -Plugins are typically loaded by the UI in your Backstage applications -`plugins.ts` file. For example, -[here](https://github.com/backstage/backstage/blob/master/packages/app/src/plugins.ts) -is that file in the Backstage sample app. +Plugins are typically installed as React components in your Backstage +application. For example, +[here](https://github.com/backstage/backstage/blob/master/packages/app/src/App.tsx) +is a file that imports many full-page plugins in the Backstage sample app. -Plugins can be enabled, and passed configuration in `apis.ts`. For example, -[here](https://github.com/backstage/backstage/blob/master/packages/app/src/apis.ts) -is that file in the Backstage sample app. - -This is how the Lighthouse plugin would be enabled in a typical Backstage -application: +An example of one of these plugin components is the `CatalogIndexPage`, which is +a full-page view that allows you to browse entities in the Backstage catalog. It +is installed in the app by importing it and adding it as an element like this: ```tsx -import { ApiHolder, ApiRegistry } from '@backstage/core'; -import { - lighthouseApiRef, - LighthouseRestApi, -} from '@backstage/plugin-lighthouse'; +import { CatalogIndexPage } from '@backstage/plugin-catalog'; -const builder = ApiRegistry.builder(); +... -export const lighthouseApi = new LighthouseRestApi(/* URL of the lighthouse microservice! */); -builder.add(lighthouseApiRef, lighthouseApi); - -export default builder.build() as ApiHolder; +const routes = ( + <FlatRoutes> + ... + <Route path="/catalog" element={<CatalogIndexPage />} /> + ... + </FlatRoutes> +); ``` +Note that we use `"/catalog"` as our path to this plugin page, but we can choose +any route we want for the page, as long as it doesn't collide with the routes +that we choose for the other plugins in the app. + +These components that are exported from plugins are referred to as "Plugin +Extension Components", or "Extensions Components". They are regular React +components, but in addition to being able to be rendered by React, they also +contain various pieces of metadata that is used to write together the entire +app. Extensions components are created using `create*Extension` methods, which +you can read more about in the +[composability documentation](../plugins/composability.md). + As of this moment, there is no config based install procedure for plugins. Some code changes are required. From c614ede9a5b56232d2b8cb655bcc9a903d4ac9a7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 15 Apr 2021 20:12:33 +0200 Subject: [PATCH 179/462] docs: update plugin installation docs Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/gentle-days-return.md | 21 ++++++ docs/features/kubernetes/installation.md | 12 +--- .../features/software-catalog/installation.md | 10 +-- .../software-templates/installation.md | 10 +-- docs/features/techdocs/getting-started.md | 10 +-- .../configure-app-with-plugins.md | 9 +-- docs/plugins/structure-of-a-plugin.md | 3 +- plugins/api-docs/README.md | 14 +--- plugins/bitrise/README.md | 6 -- plugins/catalog-import/README.md | 10 +-- plugins/circleci/README.md | 30 ++++----- plugins/cost-insights/README.md | 14 ++-- plugins/explore/README.md | 10 +-- plugins/fossa/README.md | 16 ++--- plugins/github-actions/README.md | 24 +++++-- plugins/github-deployments/README.md | 12 +--- plugins/graphiql/README.md | 13 ++-- plugins/jenkins/README.md | 19 ++++-- plugins/lighthouse/README.md | 19 ++---- .../lighthouse/src/components/Intro/index.tsx | 11 +-- plugins/pagerduty/README.md | 6 -- plugins/register-component/README.md | 67 +++---------------- plugins/rollbar/README.md | 32 ++++----- plugins/sentry/README.md | 40 +++++------ plugins/sonarqube/README.md | 17 ++--- 25 files changed, 152 insertions(+), 283 deletions(-) create mode 100644 .changeset/gentle-days-return.md diff --git a/.changeset/gentle-days-return.md b/.changeset/gentle-days-return.md new file mode 100644 index 0000000000..96552173bd --- /dev/null +++ b/.changeset/gentle-days-return.md @@ -0,0 +1,21 @@ +--- +'@backstage/plugin-api-docs': patch +'@backstage/plugin-bitrise': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-fossa': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-github-deployments': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-jenkins': patch +'@backstage/plugin-lighthouse': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-register-component': patch +'@backstage/plugin-rollbar': patch +'@backstage/plugin-sentry': patch +'@backstage/plugin-sonarqube': patch +--- + +Updated README to have up-to-date install instructions. diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index fed24c58d6..10968b427c 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -23,16 +23,8 @@ cd packages/app yarn add @backstage/plugin-kubernetes ``` -Once the package has been installed, you need to import the plugin in your app. -Add the following to `packages/app/src/plugins.ts`: - -`plugins.ts`: - -```typescript -export { plugin as Kubernetes } from '@backstage/plugin-kubernetes'; -``` - -Now, add the "Kubernetes" tab to the catalog entity page. In +Once the package has been installed, you need to import the plugin in your app +by adding the "Kubernetes" tab to the catalog entity page. In `packages/app/src/components/catalog/EntityPage.tsx`, you'll add a router to get to the tab, and add the tab itself. diff --git a/docs/features/software-catalog/installation.md b/docs/features/software-catalog/installation.md index ff8dfbda68..df473f886f 100644 --- a/docs/features/software-catalog/installation.md +++ b/docs/features/software-catalog/installation.md @@ -24,14 +24,8 @@ yarn add @backstage/plugin-catalog ### Adding the Plugin to your `packages/app` -Add the following entry to the head of your `packages/app/src/plugins.ts`: - -```ts -export { catalogPlugin } from '@backstage/plugin-catalog'; -``` - -Next we need to install the two pages that the catalog plugin provides. You can -choose any name for these routes, but we recommend the following: +Add the two pages that the catalog plugin provides to your app. You can choose +any name for these routes, but we recommend the following: ```tsx // packages/app/src/App.tsx diff --git a/docs/features/software-templates/installation.md b/docs/features/software-templates/installation.md index 105b7e5f96..0abaab0aed 100644 --- a/docs/features/software-templates/installation.md +++ b/docs/features/software-templates/installation.md @@ -26,14 +26,8 @@ yarn add @backstage/plugin-scaffolder ### Adding the Plugin to your `packages/app` -Add the following entry to the head of your `packages/app/src/plugins.ts`: - -```ts -export { scaffolderPlugin } from '@backstage/plugin-scaffolder'; -``` - -Next we need to install the root page that the Scaffolder plugin provides. You -can choose any path for the route, but we recommend the following: +Add the root page that the Scaffolder plugin provides to your app. You can +choose any path for the route, but we recommend the following: ```tsx import { ScaffolderPage } from '@backstage/plugin-scaffolder'; diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index a96e881849..934e91bd26 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -29,14 +29,8 @@ yarn add @backstage/plugin-techdocs Once the package has been installed, you need to import the plugin in your app. -Add the following to `packages/app/src/plugins.ts`: - -```typescript -export { plugin as TechDocs } from '@backstage/plugin-techdocs'; -``` - -Now we can add a route for the TechDocs page. In `packages/app/src/App.tsx`, -import TechDocsPage and add the following to `FlatRoutes`: +In `packages/app/src/App.tsx`, import TechDocsPage and add the following to +`FlatRoutes`: ```tsx import { TechDocsPage } from '@backstage/plugin-techdocs'; diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index b2f3a37d90..746b4bd940 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -27,14 +27,7 @@ package.json. Backstage Apps are set up as monorepos with [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). Since CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`. -2. Add the plugin itself to the App: - -```js -// packages/app/src/plugins.ts -export { plugin as CircleCi } from '@backstage/plugin-circleci'; -``` - -3. Register the plugin in the entity pages: +2. Add the `EntityCircleCIContent` extension to the entity pages in the app: ```diff // packages/app/src/components/catalog/EntityPage.tsx diff --git a/docs/plugins/structure-of-a-plugin.md b/docs/plugins/structure-of-a-plugin.md index 2aacd02cf2..f81e3794e5 100644 --- a/docs/plugins/structure-of-a-plugin.md +++ b/docs/plugins/structure-of-a-plugin.md @@ -100,8 +100,7 @@ There are three things needed for a Backstage app to start making use of a plugin. 1. Add plugin as dependency in `app/package.json` -2. `import` plugin in `app/src/plugins.ts` -3. Import and use one or more plugin extensions, for example in +2. Import and use one or more plugin extensions, for example in `app/src/App.tsx`. Luckily these three steps happen automatically when you create a plugin with the diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index 4e71e87275..3d44eaaa29 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -33,17 +33,7 @@ To link that a component provides or consumes an API, see the [`providesApis`](h yarn add @backstage/plugin-api-docs ``` -2. Add the plugin to the app: - -```ts -// packages/app/src/plugins.ts - -export { apiDocsPlugin } from '@backstage/plugin-api-docs'; -``` - -<Route path="/api-docs" element={<ApiExplorerPage />} /> - -3. Register the `ApiExplorerPage` at the `/api-docs` path: +2. Add the `ApiExplorerPage` extensions to the app: ```tsx // packages/app/src/App.tsx @@ -53,7 +43,7 @@ import { ApiExplorerPage } from '@backstage/plugin-api-docs'; <Route path="/api-docs" element={<ApiExplorerPage />} />; ``` -4. Add one of the provided widgets to the EntityPage: +3. Add one of the provided widgets to the EntityPage: ```tsx // packages/app/src/components/catalog/EntityPage.tsx diff --git a/plugins/bitrise/README.md b/plugins/bitrise/README.md index 59d85b0a98..ae3917d78a 100644 --- a/plugins/bitrise/README.md +++ b/plugins/bitrise/README.md @@ -11,12 +11,6 @@ Welcome to the Bitrise plugin! $ yarn add @backstage/plugin-bitrise ``` -Then make sure to export the plugin in your app's [`plugins.ts`](https://github.com/backstage/backstage/blob/master/packages/app/src/plugins.ts) to enable the plugin: - -```js -export { bitrisePlugin } from '@backstage/plugin-bitrise'; -``` - Bitrise Plugin exposes an "Entity Tab Content" component `EntityBitriseContent`. You can include it in the [`EntityPage.tsx`](https://github.com/backstage/backstage/blob/master/packages/app/src/components/catalog/EntityPage.tsx)`: ```tsx diff --git a/plugins/catalog-import/README.md b/plugins/catalog-import/README.md index 97371ce0e7..90190e4356 100644 --- a/plugins/catalog-import/README.md +++ b/plugins/catalog-import/README.md @@ -23,15 +23,7 @@ Some features are not yet available for all supported Git providers. yarn add @backstage/plugin-catalog-import ``` -2. Add the plugin to the app: - -```ts -// packages/app/src/plugins.ts - -export { catalogImportPlugin } from '@backstage/plugin-catalog-import'; -``` - -3. Register the `CatalogImportPage` at the `/catalog-import` path: +2. Add the `CatalogImportPage` extensions to the app: ```tsx // packages/app/src/App.tsx diff --git a/plugins/circleci/README.md b/plugins/circleci/README.md index d30e950aa9..868ae6e26a 100644 --- a/plugins/circleci/README.md +++ b/plugins/circleci/README.md @@ -13,26 +13,22 @@ Website: [https://circleci.com/](https://circleci.com/) yarn add @backstage/plugin-circleci ``` -2. Add plugin itself: +2. Add the `EntityCircleCIContent` extension to the entity page in the app: -```js -// packages/app/src/plugins.ts -export { plugin as Circleci } from '@backstage/plugin-circleci'; -``` - -3. Register the plugin router: - -```jsx +```tsx // packages/app/src/components/catalog/EntityPage.tsx +import { EntityCircleCIContent } from '@backstage/plugin-circleci'; -import { Router as CircleCIRouter } from '@backstage/plugin-circleci'; - -// Then somewhere inside <EntityPageLayout> -<EntityPageLayout.Content - path="/ci-cd/*" - title="CI/CD" - element={<CircleCIRouter />} -/>; +// ... +const serviceEntityPage = ( + <EntityPageLayout> + ... + <EntityLayout.Route path="/circle-ci" title="Circle CI"> + <EntityCircleCIContent /> + </EntityLayout.Route> + ... + </EntityPageLayout> +); ``` 4. Add proxy config: diff --git a/plugins/cost-insights/README.md b/plugins/cost-insights/README.md index bbd047be14..f737c022f3 100644 --- a/plugins/cost-insights/README.md +++ b/plugins/cost-insights/README.md @@ -51,11 +51,17 @@ export const apis = [ ]; ``` -4. Add cost-insights to your Backstage plugins. +4. Add the `CostInsightsPage` extension to your `App.tsx`: -```ts -// packages/app/src/plugins.ts -export { plugin as CostInsights } from '@backstage/plugin-cost-insights'; +```tsx +// packages/app/src/App.tsx +import { CostInsightsPage } from '@backstage/plugin-cost-insights'; + +<FlatRoutes> + ... + <Route path="/cost-insights" element={<CostInsightsPage />} /> + ... +</FlatRoutes>; ``` 5. Add Cost Insights to your app Sidebar. diff --git a/plugins/explore/README.md b/plugins/explore/README.md index b236af14dc..fea1333e34 100644 --- a/plugins/explore/README.md +++ b/plugins/explore/README.md @@ -5,13 +5,7 @@ This plugin helps to visualize the domains and tools in your ecosystem. ## Getting started -To install the plugin, include the following import your `plugins.ts`: - -```typescript -export { explorePlugin } from '@backstage/plugin-explore'; -``` - -Register and bind the route in `App.tsx`: +To install the plugin, add and bind the route in `App.tsx`: ```typescript import { ExplorePage, explorePlugin } from '@backstage/plugin-explore'; @@ -30,7 +24,7 @@ bindRoutes({ bind }) { <Route path="/explore" element={<ExplorePage />} /> ``` -Add a link to the sidebar in `Root.tsx`: +And add a link to the sidebar in `Root.tsx`: ```typescript import LayersIcon from '@material-ui/icons/Layers'; diff --git a/plugins/fossa/README.md b/plugins/fossa/README.md index 049a1c25cb..11f3e90e1c 100644 --- a/plugins/fossa/README.md +++ b/plugins/fossa/README.md @@ -14,15 +14,7 @@ The FOSSA Plugin displays code statistics from [FOSSA](https://fossa.com/). yarn add @backstage/plugin-fossa ``` -2. Add plugin to the app: - -```js -// packages/app/src/plugins.ts - -export { fossaPlugin } from '@backstage/plugin-fossa'; -``` - -3. Add the `EntityFossaCard` to the EntityPage: +2. Add the `EntityFossaCard` to the EntityPage: ```jsx // packages/app/src/components/catalog/EntityPage.tsx @@ -40,7 +32,7 @@ const OverviewContent = ({ entity }: { entity: Entity }) => ( ); ``` -4. Add the proxy config: +3. Add the proxy config: ```yaml # app-config.yaml @@ -57,9 +49,9 @@ fossa: organizationId: <your-fossa-organization-id> ``` -5. Get an api-token and provide `FOSSA_AUTH_HEADER` as env variable (https://app.fossa.com/account/settings/integrations/api_tokens) +4. Get an api-token and provide `FOSSA_AUTH_HEADER` as env variable (https://app.fossa.com/account/settings/integrations/api_tokens) -6. Add the `fossa.io/project-name` annotation to your catalog-info.yaml file: +5. Add the `fossa.io/project-name` annotation to your catalog-info.yaml file: ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/github-actions/README.md b/plugins/github-actions/README.md index d47144351e..328ef6054d 100644 --- a/plugins/github-actions/README.md +++ b/plugins/github-actions/README.md @@ -35,17 +35,29 @@ TBD ### Standalone app requirements -If you didn't clone this repo you have to do some extra work. - -1. Add plugin API to your Backstage instance: +1. Install the plugin dependency in your Backstage app package: ```bash +cd packages/app yarn add @backstage/plugin-github-actions ``` -```js -// packages/app/src/plugins.ts -export { plugin as GithubActions } from '@backstage/plugin-github-actions'; +2. Add to the app `EntityPage` component: + +```tsx +// packages/app/src/components/catalog/EntityPage.tsx +import { EntityGithubActionsContent } from '@backstage/plugin-github-actions'; + +// ... +const serviceEntityPage = ( + <EntityPageLayout> + ... + <EntityLayout.Route path="/github-actions" title="GitHub Actions"> + <EntityGithubActionsContent /> + </EntityLayout.Route> + ... + </EntityPageLayout> +); ``` 2. Run the app with `yarn start` and the backend with `yarn --cwd packages/backend start`, navigate to `/github-actions/`. diff --git a/plugins/github-deployments/README.md b/plugins/github-deployments/README.md index 174d1bc8c7..1bb8846105 100644 --- a/plugins/github-deployments/README.md +++ b/plugins/github-deployments/README.md @@ -18,15 +18,7 @@ The GitHub Deployments Plugin displays recent deployments from GitHub. yarn add @backstage/plugin-github-deployments ``` -2. Add the plugin to the app - -```typescript -// packages/app/src/plugins.ts - -export { githubDeploymentsPlugin as GithubDeploymentsPlugin } from '@backstage/plugin-github-deployments'; -``` - -3. Add the `EntityGithubDeploymentsCard` to the EntityPage: +2. Add the `EntityGithubDeploymentsCard` to the EntityPage: ```typescript // packages/app/src/components/catalog/EntityPage.tsx @@ -44,7 +36,7 @@ const OverviewContent = () => ( ); ``` -4. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file: +3. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file: ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/graphiql/README.md b/plugins/graphiql/README.md index c75d8b71e3..39372890d1 100644 --- a/plugins/graphiql/README.md +++ b/plugins/graphiql/README.md @@ -16,18 +16,13 @@ cd packages/app yarn add @backstage/plugin-graphiql ``` -```diff -# in packages/app/src/plugins.ts -+export { plugin as GraphiQL } from '@backstage/plugin-graphiql'; -``` - ```diff # in packages/app/src/App.tsx -+import { Router as GraphiQLRouter } from '@backstage/plugin-graphiql'; ++import { GraphiQLPage } from '@backstage/plugin-graphiql'; - const AppRoutes = () => ( - <Routes> -+ <Route path="/graphiql" element={<GraphiQLRouter />} /> + const routes = ( + <FlatRoutes> ++ <Route path="/graphiql" element={<GraphiQLPage />} /> ``` ### Adding GraphQL endpoints diff --git a/plugins/jenkins/README.md b/plugins/jenkins/README.md index b3bc21b7d5..f406393190 100644 --- a/plugins/jenkins/README.md +++ b/plugins/jenkins/README.md @@ -14,11 +14,22 @@ Website: [https://jenkins.io/](https://jenkins.io/) yarn add @backstage/plugin-jenkins ``` -2. Add plugin: +2. Add the `EntityJenkinsContent` extension to the entity page in the app: -```js -// packages/app/src/plugins.ts -export { plugin as Jenkins } from '@backstage/plugin-jenkins'; +```tsx +// packages/app/src/components/catalog/EntityPage.tsx +import { EntityJenkinsContent } from '@backstage/plugin-circleci'; + +// ... +const serviceEntityPage = ( + <EntityPageLayout> + ... + <EntityLayout.Route path="/jenkins" title="Jenkins"> + <EntityJenkinsContent /> + </EntityLayout.Route> + ... + </EntityPageLayout> +); ``` 3. Add proxy configuration to `app-config.yaml` diff --git a/plugins/lighthouse/README.md b/plugins/lighthouse/README.md index 149172b7e8..028547ea3e 100644 --- a/plugins/lighthouse/README.md +++ b/plugins/lighthouse/README.md @@ -31,26 +31,17 @@ When you have an instance running that Backstage can hook into, first install th $ yarn add @backstage/plugin-lighthouse ``` -Then make sure to export the plugin in -your app's [`plugins.ts`](https://github.com/backstage/backstage/blob/master/packages/app/src/plugins.ts) -to enable the plugin: - -```js -export { plugin as LighthousePlugin } from '@backstage/plugin-lighthouse'; -``` - -Modify your app routes in `App.tsx` to include the Router component exported from the plugin, for example: +Modify your app routes in `App.tsx` to include the `LighthousePage` component exported from the plugin, for example: ```tsx // At the top imports -import { Router as LighthouseRouter } from '@backstage/plugin-lighthouse'; +import { LighthousePage } from '@backstage/plugin-lighthouse'; -// Inside App component -<Routes> +<FlatRoutes> // ... - <Route path="/lighthouse/*" element={<LighthouseRouter />} /> + <Route path="/lighthouse" element={<LighthousePage />} /> // ... -</Routes>; +</FlatRoutes>; ``` Then configure the `lighthouse-audit-service` URL in your [`app-config.yaml`](https://github.com/backstage/backstage/blob/master/app-config.yaml). diff --git a/plugins/lighthouse/src/components/Intro/index.tsx b/plugins/lighthouse/src/components/Intro/index.tsx index 25ffccabbd..a89518a5ed 100644 --- a/plugins/lighthouse/src/components/Intro/index.tsx +++ b/plugins/lighthouse/src/components/Intro/index.tsx @@ -49,19 +49,12 @@ When you have an instance running that Backstage can hook into, first install th $ yarn add @backstage/plugin-lighthouse \`\`\` -Then make sure to export the plugin in your app's [\`plugins.ts\`](https://github.com/backstage/backstage/blob/master/packages/app/src/plugins.ts) to enable the plugin: +Modify your app routes in \`App.tsx\` to include the \`LighthousePage\` component exported from the plugin, for example: -\`\`\`js -export { plugin as LighthousePlugin } from '@backstage/plugin-lighthouse'; -\`\`\` - -Modify your app routes in \`App.tsx\` or \`App.jsx\` to include the Router component exported from the plugin, for example: - -\`\`\`js +\`\`\`tsx // At the top imports import { LighthousePage } from '@backstage/plugin-lighthouse'; -// Inside App component <FlatRoutes> // ... <Route path="/lighthouse" element={<LighthousePage />} /> diff --git a/plugins/pagerduty/README.md b/plugins/pagerduty/README.md index 9d8023b9fe..36f380fdd5 100644 --- a/plugins/pagerduty/README.md +++ b/plugins/pagerduty/README.md @@ -22,12 +22,6 @@ Install the plugin: yarn add @backstage/plugin-pagerduty ``` -Add it to the app in `plugins.ts`: - -```ts -export { plugin as Pagerduty } from '@backstage/plugin-pagerduty'; -``` - Add it to the `EntityPage.tsx`: ```ts diff --git a/plugins/register-component/README.md b/plugins/register-component/README.md index 0abf27590f..9c5304385e 100644 --- a/plugins/register-component/README.md +++ b/plugins/register-component/README.md @@ -16,69 +16,24 @@ When installed it is accessible on [localhost:3000/register-component](localhost ## Standalone setup -0. Install plugin and its dependency `plugin-catalog` +1. Install plugin and its dependency `plugin-catalog` ```bash -yarn add @backstage/plugin-register-component -W -yarn add @backstage/plugin-catalog -W +cd packages/app +yarn add @backstage/plugin-register-component ``` -1. Add dependencies to the active plugins list +2. Add the `RegisterComponentPage` extension to your `App.tsx`: -```typescript -// packages/app/src/plugins.ts -export { plugin as RegisterComponent } from '@backstage/plugin-register-component'; -export { plugin as CatalogPlugin } from '@backstage/plugin-catalog'; -``` - -2. Create `packages/app/src/apis.ts` and register all the needed plugins - -```typescript -import { - alertApiRef, - AlertApiForwarder, - ApiRegistry, - ConfigApi, - errorApiRef, - ErrorApiForwarder, - ErrorAlerter, -} from '@backstage/core'; - -import { catalogApiRef, CatalogClient } from '@backstage/plugin-catalog'; - -export const apis = (config: ConfigApi) => { - const backendUrl = config.getString('backend.baseUrl'); - - const builder = ApiRegistry.builder(); - - const alertApi = builder.add(alertApiRef, new AlertApiForwarder()); - const errorApi = builder.add( - errorApiRef, - new ErrorAlerter(alertApi, new ErrorApiForwarder()), - ); - - builder.add( - catalogApiRef, - new CatalogClient({ - apiOrigin: backendUrl, - basePath: '/catalog', - }), - ); - - return builder.build(); -}; -``` - -3. Pass `apis` to createApp - -```typescript +```tsx // packages/app/src/App.tsx -import { apis } from './apis'; +import { RegisterComponentPage } from '@backstage/plugin-cost-insights'; -const app = createApp({ - apis, - plugins: Object.values(plugins), -}); +<FlatRoutes> + ... + <Route path="/register-component" element={<RegisterComponentPage />} /> + ... +</FlatRoutes>; ``` ## Running diff --git a/plugins/rollbar/README.md b/plugins/rollbar/README.md index 993b93d3a0..584bd7d6bc 100644 --- a/plugins/rollbar/README.md +++ b/plugins/rollbar/README.md @@ -12,33 +12,25 @@ Website: [https://rollbar.com/](https://rollbar.com/) yarn add @backstage/plugin-rollbar ``` -3. Add plugin to the list of plugins: +3. Add to the app `EntityPage` component: -```ts -// packages/app/src/plugins.ts -export { plugin as Rollbar } from '@backstage/plugin-rollbar'; -``` - -4. Add to the app `EntityPage` component: - -```ts +```tsx // packages/app/src/components/catalog/EntityPage.tsx -import { Router as RollbarRouter } from '@backstage/plugin-rollbar'; +import { EntityRollbarContent } from '@backstage/plugin-rollbar'; // ... -const ServiceEntityPage = ({ entity }: { entity: Entity }) => ( +const serviceEntityPage = ( <EntityPageLayout> - // ... - <EntityPageLayout.Content - path="/rollbar" - title="Errors" - element={<RollbarRouter entity={entity} />} - /> + ... + <EntityLayout.Route path="/rollbar" title="Rollbar"> + <EntityRollbarContent /> + </EntityLayout.Route> + ... </EntityPageLayout> ); ``` -5. Setup the `app.config.yaml` and account token environment variable +4. Setup the `app.config.yaml` and account token environment variable ```yaml # app.config.yaml @@ -48,7 +40,7 @@ rollbar: accountToken: ${ROLLBAR_ACCOUNT_TOKEN} ``` -6. Annotate entities with the rollbar project slug +5. Annotate entities with the rollbar project slug ```yaml # pump-station-catalog-component.yaml @@ -60,7 +52,7 @@ metadata: rollbar.com/project-slug: project-name ``` -7. Run app with `yarn start` and navigate to `/rollbar` or a catalog entity +6. Run app with `yarn start` and navigate to `/rollbar` or a catalog entity ## Features diff --git a/plugins/sentry/README.md b/plugins/sentry/README.md index 52cef9cbe6..9bdb2dc16d 100644 --- a/plugins/sentry/README.md +++ b/plugins/sentry/README.md @@ -14,53 +14,43 @@ The Sentry Plugin displays issues from [Sentry](https://sentry.io). yarn add @backstage/plugin-sentry ``` -2. Add plugin to the app: - -```js -// packages/app/src/plugins.ts - -export { plugin as Sentry } from '@backstage/plugin-sentry'; -``` - -3. Add the `SentryIssuesWidget` to the EntityPage: +2. Add the `EntitySentryCard` to the EntityPage: ```jsx // packages/app/src/components/catalog/EntityPage.tsx -import { SentryIssuesWidget } from '@backstage/plugin-sentry'; +import { EntitySentryCard } from '@backstage/plugin-sentry'; -const OverviewContent = ({ entity }: { entity: Entity }) => ( +const overviewContent = ( <Grid container spacing={3} alignItems="stretch"> // ... <Grid item xs={12} sm={6} md={4}> - <SentryIssuesWidget entity={entity} /> + <EntitySentryCard /> </Grid> // ... </Grid> ); ``` -> You can also import a `Router` if you want to have a dedicated sentry page: +> You can also import the full-page `EntitySentryContent` extension if you want to have a dedicated sentry page: > > ```tsx > // packages/app/src/components/catalog/EntityPage.tsx > -> import { Router as SentryRouter } from '@backstage/plugin-sentry'; +> import { EntitySentryContent } from '@backstage/plugin-sentry'; > -> const ServiceEntityPage = ({ entity }: { entity: Entity }) => ( -> <EntityPageLayout> +> const serviceEntityPage = ( +> <EntityLayout> > // ... -> <EntityPageLayout.Content -> path="/sentry" -> title="Sentry" -> element={<SentryRouter entity={entity} />} -> /> +> <EntityLayout.Route path="/sentry" title="Sentry"> +> <EntitySentryContent /> +> </EntityLayout.Route> > // ... -> </EntityPageLayout> +> </EntityLayout> > ); > ``` -4. Add the proxy config: +3. Add the proxy config: ```yaml # app-config.yaml @@ -76,9 +66,9 @@ sentry: organization: <your-organization> ``` -5. Create a new internal integration with the permissions `Issues & Events: Read` (https://docs.sentry.io/product/integrations/integration-platform/) and provide it as `SENTRY_TOKEN` as env variable. +4. Create a new internal integration with the permissions `Issues & Events: Read` (https://docs.sentry.io/product/integrations/integration-platform/) and provide it as `SENTRY_TOKEN` as env variable. -6. Add the `sentry.io/project-slug` annotation to your catalog-info.yaml file: +5. Add the `sentry.io/project-slug` annotation to your catalog-info.yaml file: ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/sonarqube/README.md b/plugins/sonarqube/README.md index 7c745edf90..5c12832e57 100644 --- a/plugins/sonarqube/README.md +++ b/plugins/sonarqube/README.md @@ -13,14 +13,7 @@ The SonarQube Plugin displays code statistics from [SonarCloud](https://sonarclo yarn add @backstage/plugin-sonarqube ``` -2. Add plugin to the app: - -```js -// packages/app/src/plugins.ts -export { plugin as SonarQube } from '@backstage/plugin-sonarqube'; -``` - -3. Add the `EntitySonarQubeCard` to the EntityPage: +2. Add the `EntitySonarQubeCard` to the EntityPage: ```diff // packages/app/src/components/catalog/EntityPage.tsx @@ -40,7 +33,7 @@ export { plugin as SonarQube } from '@backstage/plugin-sonarqube'; ); ``` -4. Add the proxy config: +3. Add the proxy config: Provide a method for your Backstage backend to get to your SonarQube API end point. Add configuration to your `app-config.yaml` file depending on the product you use. @@ -77,16 +70,16 @@ sonarQube: baseUrl: https://your.sonarqube.instance.com ``` -5. Get and provide `SONARQUBE_AUTH` as an env variable (https://sonarcloud.io/account/security or https://docs.sonarqube.org/latest/user-guide/user-token/) +4. Get and provide `SONARQUBE_AUTH` as an env variable (https://sonarcloud.io/account/security or https://docs.sonarqube.org/latest/user-guide/user-token/) -6. Run the following commands in the root folder of the project to install and compile the changes. +5. Run the following commands in the root folder of the project to install and compile the changes. ```yaml yarn install yarn tsc ``` -7. Add the `sonarqube.org/project-key` annotation to the `catalog-info.yaml` file of the target repo for which code quality analysis is needed. +6. Add the `sonarqube.org/project-key` annotation to the `catalog-info.yaml` file of the target repo for which code quality analysis is needed. ```yaml apiVersion: backstage.io/v1alpha1 From 8e067f00bec02b3666b063cf2f0b8a96ce08f9f6 Mon Sep 17 00:00:00 2001 From: azhurbilo <artemzhurbilo@gmail.com> Date: Thu, 22 Apr 2021 20:22:45 +0300 Subject: [PATCH 180/462] add ability to disable some helm lighthouse resources Signed-off-by: azhurbilo <artemzhurbilo@gmail.com> --- .../backstage/templates/lighthouse-config.yaml | 4 +++- ... => postgresql-password-backend-secret.yaml} | 0 .../postgresql-password-lighthouse-secret.yaml | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) rename contrib/chart/backstage/templates/{postgresql-password-secret.yaml => postgresql-password-backend-secret.yaml} (100%) create mode 100644 contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml diff --git a/contrib/chart/backstage/templates/lighthouse-config.yaml b/contrib/chart/backstage/templates/lighthouse-config.yaml index fdf4bd8b06..7b8cad42dc 100644 --- a/contrib/chart/backstage/templates/lighthouse-config.yaml +++ b/contrib/chart/backstage/templates/lighthouse-config.yaml @@ -1,3 +1,4 @@ +{{- if .Values.lighthouse.enabled }} apiVersion: v1 kind: ConfigMap metadata: @@ -7,4 +8,5 @@ data: PGUSER: {{ include "lighthouse.postgresql.user" . | quote }} PGPORT: {{ include "lighthouse.postgresql.port" . | quote }} PGHOST: {{ include "lighthouse.postgresql.host" . | quote }} - PGPATH_TO_CA: {{ include "backstage.lighthouse.postgresCaFilename" . | quote }} \ No newline at end of file + PGPATH_TO_CA: {{ include "backstage.lighthouse.postgresCaFilename" . | quote }} +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/postgresql-password-secret.yaml b/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml similarity index 100% rename from contrib/chart/backstage/templates/postgresql-password-secret.yaml rename to contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml diff --git a/contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml b/contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml new file mode 100644 index 0000000000..e7374e70db --- /dev/null +++ b/contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml @@ -0,0 +1,17 @@ +{{- if .Values.lighthouse.enabled }} +{{- if not .Values.postgresql.enabled }} +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "lighthouse.postgresql.passwordSecret" . }} + labels: + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" +data: + postgresql-password: {{ .Values.lighthouse.database.connection.password | b64enc }} +{{- end }} +{{- end }} From 041575f25741c5924ec83e3cc9a967a93ab11122 Mon Sep 17 00:00:00 2001 From: azhurbilo <artemzhurbilo@gmail.com> Date: Thu, 22 Apr 2021 20:51:37 +0300 Subject: [PATCH 181/462] ability to change components service type Signed-off-by: azhurbilo <artemzhurbilo@gmail.com> --- contrib/chart/backstage/templates/backend-deployment.yaml | 6 +++++- contrib/chart/backstage/templates/frontend-deployment.yaml | 2 +- .../chart/backstage/templates/lighthouse-deployment.yaml | 2 +- contrib/chart/backstage/values.yaml | 3 +++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/contrib/chart/backstage/templates/backend-deployment.yaml b/contrib/chart/backstage/templates/backend-deployment.yaml index 144fc93e62..7009a22de0 100644 --- a/contrib/chart/backstage/templates/backend-deployment.yaml +++ b/contrib/chart/backstage/templates/backend-deployment.yaml @@ -49,16 +49,20 @@ spec: name: {{ include "backend.postgresql.passwordSecret" .}} key: postgresql-password volumeMounts: + {{- if .Values.postgresql.enabled }} - name: postgres-ca mountPath: {{ include "backstage.backend.postgresCaDir" . }} + {{- end }} - name: app-config mountPath: {{ printf "/usr/src/app/%s" (include "backstage.appConfigFilename" .) }} subPath: {{ include "backstage.appConfigFilename" . }} volumes: + {{- if .Values.postgresql.enabled }} - name: postgres-ca configMap: name: {{ include "backstage.fullname" . }}-postgres-ca + {{- end }} - name: app-config configMap: name: {{ include "backstage.fullname" . }}-app-config @@ -83,5 +87,5 @@ spec: app: backstage component: backend - type: ClusterIP + type: {{ .Values.backend.serviceType }} {{- end }} diff --git a/contrib/chart/backstage/templates/frontend-deployment.yaml b/contrib/chart/backstage/templates/frontend-deployment.yaml index 9c674cc160..f74cf0a1e9 100644 --- a/contrib/chart/backstage/templates/frontend-deployment.yaml +++ b/contrib/chart/backstage/templates/frontend-deployment.yaml @@ -62,5 +62,5 @@ spec: app: backstage component: frontend - type: ClusterIP + type: {{ .Values.frontend.serviceType }} {{- end }} diff --git a/contrib/chart/backstage/templates/lighthouse-deployment.yaml b/contrib/chart/backstage/templates/lighthouse-deployment.yaml index d6e1ce19dd..6104d4e73c 100644 --- a/contrib/chart/backstage/templates/lighthouse-deployment.yaml +++ b/contrib/chart/backstage/templates/lighthouse-deployment.yaml @@ -78,5 +78,5 @@ spec: app: backstage component: lighthouse-audit-service - type: ClusterIP + type: {{ .Values.lighthouse.serviceType }} {{- end }} diff --git a/contrib/chart/backstage/values.yaml b/contrib/chart/backstage/values.yaml index bd80bc22b6..e21148b04b 100644 --- a/contrib/chart/backstage/values.yaml +++ b/contrib/chart/backstage/values.yaml @@ -10,6 +10,7 @@ frontend: tag: test1 pullPolicy: IfNotPresent containerPort: 80 + serviceType: ClusterIP resources: requests: memory: 128Mi @@ -26,6 +27,7 @@ backend: tag: test1 pullPolicy: IfNotPresent containerPort: 7000 + serviceType: ClusterIP resources: requests: memory: 512Mi @@ -40,6 +42,7 @@ lighthouse: tag: latest pullPolicy: IfNotPresent containerPort: 3003 + serviceType: ClusterIP resources: requests: memory: 128Mi From 349c15d9f713c2a3c34bd8a9df7343b94ce3bb87 Mon Sep 17 00:00:00 2001 From: Ryan Vazquez <ryanv@spotify.com> Date: Thu, 22 Apr 2021 15:01:40 -0400 Subject: [PATCH 182/462] make ratio optional Signed-off-by: Ryan Vazquez <ryanv@spotify.com> --- .../components/CostGrowth/CostGrowth.test.tsx | 6 + .../src/components/CostGrowth/CostGrowth.tsx | 61 +++++-- .../CostGrowth/CostGrowthIndicator.test.tsx | 9 +- .../CostGrowth/CostGrowthIndicator.tsx | 34 ++-- .../CostOverviewLegend.test.tsx | 153 ++++++++++++++++++ .../CostOverviewCard/CostOverviewLegend.tsx | 27 ++-- .../ProductEntityTable.tsx | 36 +++-- .../ProductInsightsChart.tsx | 33 ++-- .../cost-insights/src/testUtils/mockData.ts | 5 - .../cost-insights/src/testUtils/testUtils.ts | 12 +- .../src/types/ChangeStatistic.ts | 4 +- plugins/cost-insights/src/utils/assert.ts | 2 +- .../cost-insights/src/utils/change.test.ts | 16 +- plugins/cost-insights/src/utils/change.ts | 41 +++-- plugins/cost-insights/src/utils/formatters.ts | 10 +- 15 files changed, 336 insertions(+), 113 deletions(-) create mode 100644 plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.test.tsx diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowth.test.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowth.test.tsx index f8c06845c9..7133ae81e3 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowth.test.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowth.test.tsx @@ -46,6 +46,7 @@ describe.each` engineerCost | ratio | amount | expected ${200_000} | ${0} | ${0} | ${'Negligible'} ${200_000} | ${0} | ${8_333} | ${'Negligible'} + ${200_000} | ${undefined} | ${10_000} | ${`~1 ${engineers.unit}`} ${200_000} | ${0.000000001} | ${8_334} | ${`0% or ~1 ${engineers.unit}`} ${200_000} | ${-0.000000001} | ${10_000} | ${`0% or ~1 ${engineers.unit}`} ${200_000} | ${-0.8} | ${10_000} | ${`80% or ~1 ${engineers.unit}`} @@ -65,6 +66,9 @@ describe.each` engineerCost | ratio | amount | expected ${200_000} | ${0} | ${0} | ${'Negligible'} ${200_000} | ${0} | ${8_333} | ${'Negligible'} + ${200_000} | ${undefined} | ${-1_000} | ${'Negligible'} + ${200_000} | ${undefined} | ${1_000} | ${'Negligible'} + ${200_000} | ${undefined} | ${10_000} | ${'~$10,000'} ${200_000} | ${0.000000001} | ${8_334} | ${'0% or ~$8,334'} ${200_000} | ${-0.000000001} | ${10_000} | ${'0% or ~$10,000'} ${200_000} | ${-0.8} | ${10_000} | ${'80% or ~$10,000'} @@ -84,6 +88,8 @@ describe.each` engineerCost | ratio | amount | expected ${200_000} | ${0} | ${0} | ${'Negligible'} ${200_000} | ${0} | ${8_333} | ${'Negligible'} + ${200_000} | ${undefined} | ${1_000} | ${'Negligible'} + ${200_000} | ${undefined} | ${10_000} | ${`~2,857 ${carbon.unit}s`} ${200_000} | ${0.000000001} | ${8_334} | ${`0% or ~2,381 ${carbon.unit}s`} ${200_000} | ${-0.000000001} | ${10_000} | ${`0% or ~2,857 ${carbon.unit}s`} ${200_000} | ${-0.8} | ${10_000} | ${`80% or ~2,857 ${carbon.unit}s`} diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx index 01a0874636..196f8bec44 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowth.tsx @@ -29,6 +29,7 @@ import { useCostGrowthStyles as useStyles } from '../../utils/styles'; import { formatPercent, formatCurrency } from '../../utils/formatters'; import { indefiniteArticleOf } from '../../utils/grammar'; import { useConfig, useCurrency } from '../../hooks'; +import { notEmpty } from '../../utils/assert'; export type CostGrowthProps = { change: ChangeStatistic; @@ -42,31 +43,65 @@ export const CostGrowth = ({ change, duration }: CostGrowthProps) => { // Only display costs in absolute values const amount = Math.abs(change.amount); - const ratio = Math.abs(change.ratio); + const ratio = Math.abs(change.ratio ?? NaN); const rate = rateOf(engineerCost, duration); const engineers = amount / rate; const converted = amount / (currency.rate ?? rate); + // If a ratio cannot be calculated, don't format. + const growth = notEmpty(change.ratio) + ? growthOf({ ratio: change.ratio, amount: engineers }) + : null; // Determine if growth is significant enough to highlight - const growth = growthOf(change.ratio, engineers); const classes = classnames({ [styles.excess]: growth === GrowthType.Excess, [styles.savings]: growth === GrowthType.Savings, }); - const percent = formatPercent(ratio); - - let cost = `${percent} or ~${formatCurrency(converted, currency.unit)}`; - // Always display the converted value but use the cost in engineers - // to determine negligibility, as costs should be time-period aware if (engineers < EngineerThreshold) { - cost = 'Negligible'; - } else if (currency.kind === CurrencyType.USD) { - cost = `${percent} or ~${currency.prefix}${formatCurrency(converted)}`; - } else if (amount < 1) { - cost = `less than ${indefiniteArticleOf(['a', 'an'], currency.unit)}`; + return <span className={classes}>Negligible</span>; } - return <span className={classes}>{cost}</span>; + if (currency.kind === CurrencyType.USD) { + // Do not display percentage if ratio cannot be calculated + if (isNaN(ratio)) { + return ( + <span className={classes}> + ~{currency.prefix} + {formatCurrency(converted)} + </span> + ); + } + + return ( + <span className={classes}> + {formatPercent(ratio)} or ~{currency.prefix} + {formatCurrency(converted)} + </span> + ); + } + + if (amount < 1) { + return ( + <span className={classes}> + less than {indefiniteArticleOf(['a', 'an'], currency.unit)} + </span> + ); + } + + // Do not display percentage if ratio cannot be calculated + if (isNaN(ratio)) { + return ( + <span className={classes}> + ~{formatCurrency(converted, currency.unit)} + </span> + ); + } + + return ( + <span className={classes}> + {formatPercent(ratio)} or ~{formatCurrency(converted, currency.unit)} + </span> + ); }; diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.test.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.test.tsx index 8be5e238cc..6dc6f2cc93 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.test.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.test.tsx @@ -21,8 +21,6 @@ import { ChangeThreshold, EngineerThreshold } from '../../types'; describe.each` ratio | amount | ariaLabel - ${-0.1} | ${undefined} | ${'savings'} - ${0.01} | ${undefined} | ${'excess'} ${ChangeThreshold.lower} | ${EngineerThreshold} | ${'savings'} ${ChangeThreshold.lower - 0.01} | ${EngineerThreshold} | ${'savings'} ${ChangeThreshold.lower - 0.01} | ${EngineerThreshold + 0.1} | ${'savings'} @@ -32,7 +30,7 @@ describe.each` `('growthOf', ({ ratio, amount, ariaLabel }) => { it(`should display the correct indicator for ${ariaLabel}`, async () => { const { getByLabelText } = await renderInTestApp( - <CostGrowthIndicator ratio={ratio} amount={amount} />, + <CostGrowthIndicator change={{ ratio, amount }} />, ); expect(getByLabelText(ariaLabel)).toBeInTheDocument(); }); @@ -40,7 +38,8 @@ describe.each` describe.each` ratio | amount - ${0} | ${undefined} + ${undefined} | ${0} + ${0} | ${0} ${ChangeThreshold.lower} | ${0} ${ChangeThreshold.lower + 0.01} | ${EngineerThreshold} ${ChangeThreshold.lower + 0.01} | ${EngineerThreshold + 0.1} @@ -49,7 +48,7 @@ describe.each` `('growthOf', ({ ratio, amount }) => { it('should display the correct indicator for negligible growth', async () => { const { queryByLabelText } = await renderInTestApp( - <CostGrowthIndicator ratio={ratio} amount={amount} />, + <CostGrowthIndicator change={{ ratio, amount }} />, ); expect(queryByLabelText('savings')).not.toBeInTheDocument(); expect(queryByLabelText('excess')).not.toBeInTheDocument(); diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx index e220fdb8e7..a1c200c6b3 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx @@ -20,49 +20,33 @@ import { Typography, TypographyProps } from '@material-ui/core'; import { default as ArrowDropUp } from '@material-ui/icons/ArrowDropUp'; import { default as ArrowDropDown } from '@material-ui/icons/ArrowDropDown'; import { growthOf } from '../../utils/change'; -import { GrowthType } from '../../types'; +import { ChangeStatistic, GrowthType, Maybe } from '../../types'; import { useCostGrowthStyles as useStyles } from '../../utils/styles'; export type CostGrowthIndicatorProps = TypographyProps & { - ratio: number; - amount?: number; - formatter?: (amount: number) => string; + change: ChangeStatistic; + formatter?: (change: ChangeStatistic) => Maybe<string>; }; export const CostGrowthIndicator = ({ - ratio, - amount, + change, formatter, className, ...props }: CostGrowthIndicatorProps) => { const classes = useStyles(); - const growth = growthOf(ratio, amount); + const growth = growthOf(change); const classNames = classnames(classes.indicator, className, { - [classes.savings]: growth === GrowthType.Savings, [classes.excess]: growth === GrowthType.Excess, + [classes.savings]: growth === GrowthType.Savings, }); - // Display cost as a factor of engineer cost growth and percentage growth - if (typeof amount === 'number') { - return ( - <Typography className={classNames} component="span" {...props}> - {formatter ? formatter(amount) : amount} - {growth === GrowthType.Savings && ( - <ArrowDropDown aria-label="savings" /> - )} - {growth === GrowthType.Excess && <ArrowDropUp aria-label="excess" />} - </Typography> - ); - } - - // Display cost as a factor of percent change return ( <Typography className={classNames} component="span" {...props}> - {formatter ? formatter(ratio) : ratio} - {ratio < 0 && <ArrowDropDown aria-label="savings" />} - {ratio > 0 && <ArrowDropUp aria-label="excess" />} + {formatter ? formatter(change) : change.ratio} + {growth === GrowthType.Excess && <ArrowDropUp aria-label="excess" />} + {growth === GrowthType.Savings && <ArrowDropDown aria-label="savings" />} </Typography> ); }; diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.test.tsx new file mode 100644 index 0000000000..112081fed4 --- /dev/null +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.test.tsx @@ -0,0 +1,153 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { render } from '@testing-library/react'; +import { wrapInTestApp } from '@backstage/test-utils'; +import { CostOverviewLegend } from './CostOverviewLegend'; +import { + MockBillingDateProvider, + MockConfigProvider, + MockFilterProvider, + MockCurrencyProvider, +} from '../../testUtils'; + +function renderInTestApp(children: JSX.Element) { + return render( + wrapInTestApp( + <MockConfigProvider> + <MockCurrencyProvider> + <MockBillingDateProvider> + <MockFilterProvider>{children}</MockFilterProvider> + </MockBillingDateProvider> + </MockCurrencyProvider> + </MockConfigProvider>, + ), + ); +} + +describe('<CostOverviewLegend />', () => { + it('displays the legend without exploding', async () => { + const { findByText } = renderInTestApp( + <CostOverviewLegend + metric={{ + kind: 'msc', + name: 'MSC', + default: false, + }} + metricData={{ + id: 'msc', + format: 'number', + aggregation: [], + change: { + ratio: 0, + amount: 0, + }, + }} + dailyCostData={{ + id: 'mock-id', + aggregation: [], + change: { + amount: 0, + }, + }} + />, + ); + + expect(await findByText('Cost Trend')).toBeInTheDocument(); + expect(await findByText('MSC Trend')).toBeInTheDocument(); + }); + + it('does not display metric legend if metric data is not provided', async () => { + const { findByText, queryByText } = renderInTestApp( + <CostOverviewLegend + metric={{ + kind: 'msc', + name: 'MSC', + default: false, + }} + metricData={null} + dailyCostData={{ + id: 'mock-id', + aggregation: [], + change: { + amount: 0, + }, + }} + />, + ); + + expect(await findByText('Cost Trend')).toBeInTheDocument(); + expect(queryByText('MSC Trend')).not.toBeInTheDocument(); + }); +}); + +describe.each` + ratio | amount | title | expected + ${undefined} | ${1_000} | ${'∞'} | ${'Your Excess'} + ${undefined} | ${-1_000} | ${'-∞'} | ${'Your Savings'} +`('<CostOverviewLegend />', ({ ratio, amount, title, expected }) => { + it('displays the correct legend if ratio cannot be calculated and costs are within time period', async () => { + const { findByText, findAllByText } = renderInTestApp( + <CostOverviewLegend + metric={{ + kind: 'msc', + name: 'MSC', + default: false, + }} + metricData={{ + id: 'msc', + format: 'number', + change: { + ratio: ratio, + amount: amount, + }, + aggregation: [ + { + date: '2020-01-01', + amount: 0, + }, + { + date: '2020-07-01', // within default P90D period + amount: amount, + }, + ], + }} + dailyCostData={{ + id: 'mock-id', + change: { + ratio, + amount, + }, + aggregation: [ + { + date: '2020-01-01', + amount: 0, + }, + { + date: '2020-07-01', // within default P90D period + amount: amount, + }, + ], + }} + />, + ); + + expect(await findByText('Cost Trend')).toBeInTheDocument(); + expect(await findByText('MSC Trend')).toBeInTheDocument(); + expect(await findAllByText(title).then(res => res.length)).toBe(2); + expect(await findByText(expected)).toBeInTheDocument(); + }); +}); diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx index ebba5173a9..0033ba4f14 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx @@ -25,11 +25,13 @@ import { Metric, } from '../../types'; import { useLastCompleteBillingDate, useFilters } from '../../hooks'; -import { getComparedChange } from '../../utils/change'; +import { getComparedChange, choose } from '../../utils/change'; import { mapFiltersToProps } from './selector'; -import { formatPercent } from '../../utils/formatters'; +import { formatChange } from '../../utils/formatters'; import { CostGrowth } from '../CostGrowth'; +import { notEmpty } from '../../utils/assert'; + type CostOverviewLegendProps = { metric: Maybe<Metric>; metricData: Maybe<MetricData>; @@ -42,9 +44,8 @@ export const CostOverviewLegend = ({ metricData, }: PropsWithChildren<CostOverviewLegendProps>) => { const theme = useTheme<CostInsightsTheme>(); - - const lastCompleteBillingDate = useLastCompleteBillingDate(); const { duration } = useFilters(mapFiltersToProps); + const lastCompleteBillingDate = useLastCompleteBillingDate(); const comparedChange = metricData ? getComparedChange( @@ -57,23 +58,25 @@ export const CostOverviewLegend = ({ return ( <Box display="flex" flexDirection="row"> - <Box mr={2}> - <LegendItem title="Cost Trend" markerColor={theme.palette.blue}> - {formatPercent(dailyCostData.change!.ratio)} - </LegendItem> - </Box> - {metric && metricData && comparedChange && ( + {dailyCostData.change && ( + <Box mr={2}> + <LegendItem title="Cost Trend" markerColor={theme.palette.blue}> + {formatChange(dailyCostData.change)} + </LegendItem> + </Box> + )} + {metricData && metric && comparedChange && ( <> <Box mr={2}> <LegendItem title={`${metric.name} Trend`} markerColor={theme.palette.magenta} > - {formatPercent(metricData.change.ratio)} + {formatChange(metricData.change)} </LegendItem> </Box> <LegendItem - title={comparedChange.ratio <= 0 ? 'Your Savings' : 'Your Excess'} + title={choose(['Your Savings', 'Your Excess'], comparedChange)} > <CostGrowth change={comparedChange} duration={duration} /> </LegendItem> diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx index 45576bda65..a8211fbbed 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx @@ -18,10 +18,11 @@ import React from 'react'; import classnames from 'classnames'; import { Table, TableColumn } from '@backstage/core'; import { Typography } from '@material-ui/core'; -import { costFormatter, formatPercent } from '../../utils/formatters'; +import { costFormatter, formatChange } from '../../utils/formatters'; import { useEntityDialogStyles as useStyles } from '../../utils/styles'; import { CostGrowthIndicator } from '../CostGrowth'; -import { BarChartOptions, Entity } from '../../types'; +import { BarChartOptions, ChangeStatistic, Entity } from '../../types'; +import { isUndefined } from '../../utils/assert'; export type ProductEntityTableOptions = Partial< Pick<BarChartOptions, 'previousName' | 'currentName'> @@ -32,7 +33,7 @@ type RowData = { label: string; previous: number; current: number; - ratio: number; + change: ChangeStatistic; }; function createRenderer(col: keyof RowData, classes: Record<string, string>) { @@ -41,7 +42,7 @@ function createRenderer(col: keyof RowData, classes: Record<string, string>) { const rowStyles = classnames(classes.row, { [classes.rowTotal]: row.id === 'total', [classes.colFirst]: col === 'label', - [classes.colLast]: col === 'ratio', + [classes.colLast]: col === 'change', }); switch (col) { @@ -52,12 +53,12 @@ function createRenderer(col: keyof RowData, classes: Record<string, string>) { {costFormatter.format(row[col])} </Typography> ); - case 'ratio': + case 'change': return ( <CostGrowthIndicator className={rowStyles} - ratio={row.ratio} - formatter={amount => formatPercent(Math.abs(amount))} + change={row.change} + formatter={formatChange} /> ); default: @@ -75,10 +76,15 @@ function createSorter(field?: keyof Omit<RowData, 'id'>) { if (a.id === 'total') return 1; if (b.id === 'total') return 1; if (field === 'label') return a.label.localeCompare(b.label); + if (field === 'change') { + if (formatChange(a[field]) === '∞' || formatChange(b[field]) === '-∞') + return 1; + if (formatChange(a[field]) === '-∞' || formatChange(b[field]) === '∞') + return -1; + return a[field].ratio! - b[field].ratio!; + } - return field - ? a[field] - b[field] - : b.previous + b.current - (a.previous + a.current); + return b.previous + b.current - (a.previous + a.current); }; } @@ -134,11 +140,11 @@ export const ProductEntityTable = ({ customSort: createSorter('current'), }, { - field: 'ratio', + field: 'change', title: <Typography className={lastColClasses}>Change</Typography>, align: 'right', - render: createRenderer('ratio', classes), - customSort: createSorter('ratio'), + render: createRenderer('change', classes), + customSort: createSorter('change'), }, ]; @@ -148,14 +154,14 @@ export const ProductEntityTable = ({ label: e.id || 'Unknown', previous: e.aggregation[0], current: e.aggregation[1], - ratio: e.change.ratio, + change: e.change, })) .concat({ id: 'total', label: 'Total', previous: entity.aggregation[0], current: entity.aggregation[1], - ratio: entity.change.ratio, + change: entity.change, }) .sort(createSorter()); diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx index ace2766277..07fea77d9d 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsChart.tsx @@ -40,7 +40,7 @@ import { findAnyKey, assertAlways, } from '../../utils/assert'; -import { formatPeriod, formatPercent } from '../../utils/formatters'; +import { formatPeriod, formatChange } from '../../utils/formatters'; import { titleOf, tooltipItemOf, @@ -54,6 +54,7 @@ import { useBarChartLayoutStyles as useLayoutStyles, } from '../../utils/styles'; import { Duration, Entity, Maybe } from '../../types'; +import { choose } from '../../utils/change'; export type ProductInsightsChartProps = { billingDate: string; @@ -86,7 +87,6 @@ export const ProductInsightsChart = ({ return breakdowns.length > 0; }, [entities, activeLabel]); - const legendTitle = `Cost ${entity.change.ratio <= 0 ? 'Savings' : 'Growth'}`; const costStart = entity.aggregation[0]; const costEnd = entity.aggregation[1]; const resources = entities.map(resourceOf); @@ -136,7 +136,6 @@ export const ProductInsightsChart = ({ const items = payload.map(tooltipItemOf).filter(notEmpty); const activeEntity = findAlways(entities, e => e.id === id); - const ratio = activeEntity.change.ratio; const breakdowns = Object.keys(activeEntity.entities); if (breakdowns.length) { @@ -148,11 +147,13 @@ export const ProductInsightsChart = ({ title={title} subtitle={subtitle} topRight={ - <CostGrowthIndicator - className={classes.indicator} - ratio={ratio} - formatter={formatPercent} - /> + !!activeEntity.change.ratio && ( + <CostGrowthIndicator + formatter={formatChange} + change={activeEntity.change} + className={classes.indicator} + /> + ) } actions={ <Box className={classes.actions}> @@ -173,11 +174,13 @@ export const ProductInsightsChart = ({ <BarChartTooltip title={title} topRight={ - <CostGrowthIndicator - className={classes.indicator} - ratio={ratio} - formatter={formatPercent} - /> + !!activeEntity.change.ratio && ( + <CostGrowthIndicator + formatter={formatChange} + change={activeEntity.change} + className={classes.indicator} + /> + ) } content={ id @@ -197,7 +200,9 @@ export const ProductInsightsChart = ({ return ( <Box className={layoutClasses.wrapper}> <BarChartLegend costStart={costStart} costEnd={costEnd} options={options}> - <LegendItem title={legendTitle}> + <LegendItem + title={choose(['Cost Savings', 'Cost Excess'], entity.change)} + > <CostGrowth change={entity.change} duration={duration} /> </LegendItem> </BarChartLegend> diff --git a/plugins/cost-insights/src/testUtils/mockData.ts b/plugins/cost-insights/src/testUtils/mockData.ts index 5149da278d..27bb07d0e1 100644 --- a/plugins/cost-insights/src/testUtils/mockData.ts +++ b/plugins/cost-insights/src/testUtils/mockData.ts @@ -294,7 +294,6 @@ export const MockBigQueryInsights: Entity = { id: 'dataset-c', aggregation: [0, 10_000], change: { - ratio: 10_000, amount: 10_000, }, entities: {}, @@ -415,7 +414,6 @@ export const MockCloudDataflowInsights: Entity = { id: 'pipeline-c', aggregation: [0, 10_000], change: { - ratio: 10_000, amount: 10_000, }, entities: {}, @@ -503,7 +501,6 @@ export const MockCloudStorageInsights: Entity = { id: 'Mock SKU C', aggregation: [2_000, 0], change: { - ratio: -1, amount: -2000, }, entities: {}, @@ -515,7 +512,6 @@ export const MockCloudStorageInsights: Entity = { id: 'bucket-c', aggregation: [0, 0], change: { - ratio: 0, amount: 0, }, entities: {}, @@ -655,7 +651,6 @@ export const MockComputeEngineInsights: Entity = { id: 'service-c', aggregation: [0, 10_000], change: { - ratio: 10_000, amount: 10_000, }, entities: {}, diff --git a/plugins/cost-insights/src/testUtils/testUtils.ts b/plugins/cost-insights/src/testUtils/testUtils.ts index 37913f635e..5077e05b75 100644 --- a/plugins/cost-insights/src/testUtils/testUtils.ts +++ b/plugins/cost-insights/src/testUtils/testUtils.ts @@ -93,10 +93,16 @@ export function changeOf(aggregation: DateAggregation[]): ChangeStatistic { const lastAmount = aggregation.length ? aggregation[aggregation.length - 1].amount : 0; - const ratio = - firstAmount !== 0 ? (lastAmount - firstAmount) / firstAmount : 0; + + // if either the first or last amounts are zero, the rate of increase/decrease is infinite + if (!firstAmount || !lastAmount) { + return { + amount: lastAmount - firstAmount, + }; + } + return { - ratio: ratio, + ratio: (lastAmount - firstAmount) / firstAmount, amount: lastAmount - firstAmount, }; } diff --git a/plugins/cost-insights/src/types/ChangeStatistic.ts b/plugins/cost-insights/src/types/ChangeStatistic.ts index a47640411a..70cd9fb9a2 100644 --- a/plugins/cost-insights/src/types/ChangeStatistic.ts +++ b/plugins/cost-insights/src/types/ChangeStatistic.ts @@ -16,7 +16,9 @@ export interface ChangeStatistic { // The ratio of change from one duration to another, expressed as: (newSum - oldSum) / oldSum - ratio: number; + // If a ratio cannot be calculated - such as when a new or old sum is zero, + // the ratio can be omitted and where applicable, ∞ or -∞ will display based on amount. + ratio?: number; // The actual USD change between time periods (can be negative if costs decreased) amount: number; } diff --git a/plugins/cost-insights/src/utils/assert.ts b/plugins/cost-insights/src/utils/assert.ts index 05ce65197b..5f9f0d01e1 100644 --- a/plugins/cost-insights/src/utils/assert.ts +++ b/plugins/cost-insights/src/utils/assert.ts @@ -20,7 +20,7 @@ export function notEmpty<TValue>( return !isNull(value) && !isUndefined(value); } -export function isUndefined(value: any): boolean { +export function isUndefined(value: any): value is undefined { return value === undefined; } diff --git a/plugins/cost-insights/src/utils/change.test.ts b/plugins/cost-insights/src/utils/change.test.ts index 7208e9bc4f..191ae589d6 100644 --- a/plugins/cost-insights/src/utils/change.test.ts +++ b/plugins/cost-insights/src/utils/change.test.ts @@ -32,23 +32,23 @@ const GrowthMap = { describe.each` ratio | amount | expected - ${0.0} | ${undefined} | ${GrowthType.Negligible} + ${undefined} | ${0} | ${GrowthType.Negligible} + ${0.0} | ${0} | ${GrowthType.Negligible} ${0.0} | ${EngineerThreshold} | ${GrowthType.Negligible} ${ChangeThreshold.lower} | ${0} | ${GrowthType.Negligible} - ${ChangeThreshold.lower + 0.01} | ${undefined} | ${GrowthType.Negligible} + ${ChangeThreshold.lower + 0.01} | ${0} | ${GrowthType.Negligible} ${ChangeThreshold.lower + 0.01} | ${EngineerThreshold} | ${GrowthType.Negligible} ${ChangeThreshold.lower + 0.01} | ${EngineerThreshold + 0.1} | ${GrowthType.Negligible} ${ChangeThreshold.lower - 0.01} | ${EngineerThreshold - 0.1} | ${GrowthType.Negligible} - ${ChangeThreshold.upper - 0.01} | ${undefined} | ${GrowthType.Negligible} + ${ChangeThreshold.lower - 0.01} | ${0} | ${GrowthType.Negligible} + ${ChangeThreshold.upper} | ${0} | ${GrowthType.Negligible} + ${ChangeThreshold.upper - 0.01} | ${0} | ${GrowthType.Negligible} ${ChangeThreshold.upper + 0.01} | ${EngineerThreshold - 0.1} | ${GrowthType.Negligible} - ${ChangeThreshold.lower} | ${undefined} | ${GrowthType.Savings} + ${ChangeThreshold.upper + 0.01} | ${0} | ${GrowthType.Negligible} ${ChangeThreshold.lower} | ${EngineerThreshold} | ${GrowthType.Savings} - ${ChangeThreshold.lower - 0.01} | ${undefined} | ${GrowthType.Savings} ${ChangeThreshold.lower - 0.01} | ${EngineerThreshold} | ${GrowthType.Savings} ${ChangeThreshold.lower - 0.01} | ${EngineerThreshold + 0.1} | ${GrowthType.Savings} - ${ChangeThreshold.upper} | ${undefined} | ${GrowthType.Excess} ${ChangeThreshold.upper} | ${EngineerThreshold} | ${GrowthType.Excess} - ${ChangeThreshold.upper + 0.01} | ${undefined} | ${GrowthType.Excess} ${ChangeThreshold.upper + 0.01} | ${EngineerThreshold} | ${GrowthType.Excess} ${ChangeThreshold.upper + 0.01} | ${EngineerThreshold + 0.1} | ${GrowthType.Excess} `( @@ -63,7 +63,7 @@ describe.each` expected: GrowthType; }) => { it(`should display ${GrowthMap[expected]}`, () => { - expect(growthOf(ratio, amount)).toBe(expected); + expect(growthOf({ ratio, amount })).toBe(expected); }); }, ); diff --git a/plugins/cost-insights/src/utils/change.ts b/plugins/cost-insights/src/utils/change.ts index 950fbfeb82..479818bdae 100644 --- a/plugins/cost-insights/src/utils/change.ts +++ b/plugins/cost-insights/src/utils/change.ts @@ -27,21 +27,26 @@ import { import dayjs, { OpUnitType } from 'dayjs'; import durationPlugin from 'dayjs/plugin/duration'; import { inclusiveStartDateOf } from './duration'; +import { notEmpty } from './assert'; dayjs.extend(durationPlugin); // Used for displaying status colors -export function growthOf(ratio: number, amount?: number) { - if (typeof amount === 'number') { - if (amount >= EngineerThreshold && ratio >= ChangeThreshold.upper) { +export function growthOf(change: ChangeStatistic): GrowthType { + const exceedsEngineerThreshold = Math.abs(change.amount) >= EngineerThreshold; + + if (notEmpty(change.ratio)) { + if (exceedsEngineerThreshold && change.ratio >= ChangeThreshold.upper) { return GrowthType.Excess; } - if (amount >= EngineerThreshold && ratio <= ChangeThreshold.lower) { + + if (exceedsEngineerThreshold && change.ratio <= ChangeThreshold.lower) { return GrowthType.Savings; } } else { - if (ratio >= ChangeThreshold.upper) return GrowthType.Excess; - if (ratio <= ChangeThreshold.lower) return GrowthType.Savings; + if (exceedsEngineerThreshold && change.amount > 0) return GrowthType.Excess; + if (exceedsEngineerThreshold && change.amount < 0) + return GrowthType.Savings; } return GrowthType.Negligible; @@ -54,15 +59,24 @@ export function getComparedChange( duration: Duration, lastCompleteBillingDate: string, // YYYY-MM-DD, ): ChangeStatistic { - const ratio = dailyCost.change!.ratio - metricData.change.ratio; + const dailyCostRatio = dailyCost.change?.ratio; + const metricDataRatio = metricData.change?.ratio; const previousPeriodTotal = getPreviousPeriodTotalCost( dailyCost.aggregation, duration, lastCompleteBillingDate, ); + + // if either ratio cannot be calculated, no compared ratio can be calculated + if (!notEmpty(dailyCostRatio) || !notEmpty(metricDataRatio)) { + return { + amount: previousPeriodTotal, + }; + } + return { - ratio: ratio, - amount: previousPeriodTotal * ratio, + ratio: dailyCostRatio - metricDataRatio, + amount: previousPeriodTotal * (dailyCostRatio - metricDataRatio), }; } @@ -78,7 +92,6 @@ export function getPreviousPeriodTotalCost( ? [dayjsDuration.days(), 'day'] : [dayjsDuration.months(), 'month']; const nextPeriodStart = dayjs(startDate).add(amount, type); - // Add up costs that incurred before the start of the next period. return aggregation.reduce((acc, costByDate) => { return dayjs(costByDate.date).isBefore(nextPeriodStart) @@ -86,3 +99,11 @@ export function getPreviousPeriodTotalCost( : acc; }, 0); } + +export function choose<T>( + [savings, excess]: [T, T], + change: ChangeStatistic, +): T { + const isSavings = (change.ratio ?? change.amount) <= 0; + return isSavings ? savings : excess; +} diff --git a/plugins/cost-insights/src/utils/formatters.ts b/plugins/cost-insights/src/utils/formatters.ts index 8f2b94f997..75306d7392 100644 --- a/plugins/cost-insights/src/utils/formatters.ts +++ b/plugins/cost-insights/src/utils/formatters.ts @@ -16,8 +16,9 @@ import moment from 'moment'; import pluralize from 'pluralize'; -import { Duration } from '../types'; +import { ChangeStatistic, Duration } from '../types'; import { inclusiveEndDateOf, inclusiveStartDateOf } from '../utils/duration'; +import { notEmpty } from './assert'; export type Period = { periodStart: string; @@ -78,6 +79,13 @@ export function formatCurrency(amount: number, currency?: string): string { return currency ? `${numString} ${pluralize(currency, n)}` : numString; } +export function formatChange(change: ChangeStatistic): string { + if (notEmpty(change.ratio)) { + return formatPercent(Math.abs(change.ratio)); + } + return change.amount >= 0 ? '∞' : '-∞'; +} + export function formatPercent(n: number): string { // Number.toFixed shows scientific notation for extreme numbers if (isNaN(n) || Math.abs(n) < 0.01) { From 6f1b82b14175f85a76a7b91db9800ec8f6425d81 Mon Sep 17 00:00:00 2001 From: Ryan Vazquez <ryanv@spotify.com> Date: Thu, 22 Apr 2021 15:03:17 -0400 Subject: [PATCH 183/462] changeset Signed-off-by: Ryan Vazquez <ryanv@spotify.com> --- .changeset/cost-insights-five-baboons-attack.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cost-insights-five-baboons-attack.md diff --git a/.changeset/cost-insights-five-baboons-attack.md b/.changeset/cost-insights-five-baboons-attack.md new file mode 100644 index 0000000000..f2c070acb4 --- /dev/null +++ b/.changeset/cost-insights-five-baboons-attack.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': minor +--- + +make change ratio optional From c2abcf91acc397b9837eff29f0dffbcbdfb110da Mon Sep 17 00:00:00 2001 From: Ryan Vazquez <ryanv@spotify.com> Date: Thu, 22 Apr 2021 15:41:58 -0400 Subject: [PATCH 184/462] lint Signed-off-by: Ryan Vazquez <ryanv@spotify.com> --- .../src/components/CostOverviewCard/CostOverviewLegend.tsx | 2 -- .../src/components/ProductInsightsCard/ProductEntityTable.tsx | 1 - 2 files changed, 3 deletions(-) diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx index 0033ba4f14..ad8a065a6e 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewLegend.tsx @@ -30,8 +30,6 @@ import { mapFiltersToProps } from './selector'; import { formatChange } from '../../utils/formatters'; import { CostGrowth } from '../CostGrowth'; -import { notEmpty } from '../../utils/assert'; - type CostOverviewLegendProps = { metric: Maybe<Metric>; metricData: Maybe<MetricData>; diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx index a8211fbbed..f9bb44058b 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductEntityTable.tsx @@ -22,7 +22,6 @@ import { costFormatter, formatChange } from '../../utils/formatters'; import { useEntityDialogStyles as useStyles } from '../../utils/styles'; import { CostGrowthIndicator } from '../CostGrowth'; import { BarChartOptions, ChangeStatistic, Entity } from '../../types'; -import { isUndefined } from '../../utils/assert'; export type ProductEntityTableOptions = Partial< Pick<BarChartOptions, 'previousName' | 'currentName'> From 39bdaa0046f41c395d0e43f7b00d6d4239471b30 Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" <ftt.adrian.ke@grabtaxi.com> Date: Tue, 6 Apr 2021 17:18:38 +0800 Subject: [PATCH 185/462] Add TechDocs landing page customization and exported components Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- .changeset/techdocs-quiet-pens-prove.md | 5 + docs/features/techdocs/how-to-guides.md | 77 ++++++++ ...Content.test.tsx => DocsCardGrid.test.tsx} | 17 +- .../src/home/components/DocsCardGrid.tsx | 58 ++++++ ...nedContent.test.tsx => DocsTable.test.tsx} | 44 +---- .../{OwnedContent.tsx => DocsTable.tsx} | 68 +++---- .../src/home/components/OverviewContent.tsx | 73 -------- .../components/TechDocsCustomHome.test.tsx | 83 +++++++++ .../home/components/TechDocsCustomHome.tsx | 169 ++++++++++++++++++ .../src/home/components/TechDocsHome.test.tsx | 26 ++- .../src/home/components/TechDocsHome.tsx | 118 ++++-------- plugins/techdocs/src/index.ts | 5 + plugins/techdocs/src/plugin.ts | 39 ++++ 13 files changed, 538 insertions(+), 244 deletions(-) create mode 100644 .changeset/techdocs-quiet-pens-prove.md rename plugins/techdocs/src/home/components/{OverviewContent.test.tsx => DocsCardGrid.test.tsx} (77%) create mode 100644 plugins/techdocs/src/home/components/DocsCardGrid.tsx rename plugins/techdocs/src/home/components/{OwnedContent.test.tsx => DocsTable.test.tsx} (68%) rename plugins/techdocs/src/home/components/{OwnedContent.tsx => DocsTable.tsx} (67%) delete mode 100644 plugins/techdocs/src/home/components/OverviewContent.tsx create mode 100644 plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx create mode 100644 plugins/techdocs/src/home/components/TechDocsCustomHome.tsx diff --git a/.changeset/techdocs-quiet-pens-prove.md b/.changeset/techdocs-quiet-pens-prove.md new file mode 100644 index 0000000000..379c20e72a --- /dev/null +++ b/.changeset/techdocs-quiet-pens-prove.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Add customization and exportable components for TechDocs landing page diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 2cb769b0e3..a76905d6c5 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -82,3 +82,80 @@ Caveat: Currently TechDocs sites built using URL Reader will be cached for 30 minutes which means they will not be re-built if new changes are made within 30 minutes. This cache invalidation will be replaced by commit timestamp based implementation very soon. + +## How to use a custom TechDocs home page? + +### 1st way: TechDocsCustomHome with a custom configuration + +In your main App.tsx: + +``` +import { + TechDocsCustomHome, + WidgetType, + TechDocsReaderPage, +} from '@backstage/plugin-techdocs'; +import { Entity } from '@backstage/catalog-model'; + +const tabsConfig = [ + { + label: 'Custom Tab', + widgets: [ + { + title: 'Custom Documents Cards 1', + description: + 'Explore your internal technical ecosystem through documentation.', + // sets maximum height of widget, as CSS maxHeight attribute + widgetMaxHeight: '400px' + widgetType: 'DocsCardGrid' as WidgetType, + filterPredicate: (entity: Entity) => !!entity.metadata.annotations?.['customCardAnnotationOne']; + }, + { + title: 'Custom Documents Cards 2', + description: + 'Explore your internal technical ecosystem through documentation.', + widgetMaxHeight: '400px' + widgetType: 'DocsCardGrid' as WidgetType, + filterPredicate: (entity: Entity) => !!entity.metadata.annotations?.['customCardAnnotationTwo']; + }, + ], + }, + { + label: 'Overview', + widgets: [ + { + title: 'Overview', + description: + 'Explore your internal technical ecosystem through documentation.', + widgetType: 'DocsTable' as WidgetType, + filterPredicate: () => true, + }, + ], + }, +]; + +const routes = ( + <FlatRoutes> + <Route + path="/docs" + element={<TechDocsCustomHome tabsConfig={tabsConfig} />} + /> + <Route + path="/docs/:namespace/:kind/:name/*" + element={<TechDocsReaderPage />} + /> + </FlatRoutes> +``` + +An example of tabsConfig that corresponds to the default documentation home page +can be found at `plugins/techdocs/src/home/components/TechDocsHome.tsx`. + +### 2nd way: custom home page plugin + +A custom home page plugin can be built that uses the components extensions +DocsCardGrid and DocsTable, exported from @backstage/techdocs. They both take a +array of documentation entities ( have 'backstage.io/techdocs-ref' annotation ) +as an 'entities' attribute. + +For an reference to the React structure of the default home page, please refer +to `plugins/techdocs/src/home/components/TechDocsCustomHome.tsx`. diff --git a/plugins/techdocs/src/home/components/OverviewContent.test.tsx b/plugins/techdocs/src/home/components/DocsCardGrid.test.tsx similarity index 77% rename from plugins/techdocs/src/home/components/OverviewContent.test.tsx rename to plugins/techdocs/src/home/components/DocsCardGrid.test.tsx index ec67c346d7..1ddaa4c373 100644 --- a/plugins/techdocs/src/home/components/OverviewContent.test.tsx +++ b/plugins/techdocs/src/home/components/DocsCardGrid.test.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 Spotify AB + * Copyright 2021 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,13 @@ import { wrapInTestApp } from '@backstage/test-utils'; import { render } from '@testing-library/react'; import React from 'react'; -import { OverviewContent } from './OverviewContent'; +import { DocsCardGrid } from './DocsCardGrid'; -describe('TechDocs Overview Content', () => { - it('should render all TechDocs Documents', async () => { +describe('Entity Docs Card Grid', () => { + it('should render all entities passed ot it', async () => { const { findByText } = render( wrapInTestApp( - <OverviewContent + <DocsCardGrid entities={[ { apiVersion: 'version', @@ -49,13 +49,6 @@ describe('TechDocs Overview Content', () => { />, ), ); - - expect(await findByText('Overview')).toBeInTheDocument(); - expect( - await findByText( - /Explore your internal technical ecosystem through documentation./i, - ), - ).toBeInTheDocument(); expect(await findByText('testName')).toBeInTheDocument(); expect(await findByText('testName2')).toBeInTheDocument(); }); diff --git a/plugins/techdocs/src/home/components/DocsCardGrid.tsx b/plugins/techdocs/src/home/components/DocsCardGrid.tsx new file mode 100644 index 0000000000..47f747442c --- /dev/null +++ b/plugins/techdocs/src/home/components/DocsCardGrid.tsx @@ -0,0 +1,58 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { generatePath } from 'react-router-dom'; + +import { Entity } from '@backstage/catalog-model'; +import { Button, ItemCardGrid, ItemCardHeader } from '@backstage/core'; +import { Card, CardActions, CardContent, CardMedia } from '@material-ui/core'; + +import { rootDocsRouteRef } from '../../plugin'; + +export const DocsCardGrid = ({ + entities, +}: { + entities: Entity[] | undefined; +}) => { + if (!entities) return null; + return ( + <ItemCardGrid data-testid="docs-explore"> + {!entities?.length + ? null + : entities.map((entity, index: number) => ( + <Card key={index}> + <CardMedia> + <ItemCardHeader title={entity.metadata.name} /> + </CardMedia> + <CardContent>{entity.metadata.description}</CardContent> + <CardActions> + <Button + to={generatePath(rootDocsRouteRef.path, { + namespace: entity.metadata.namespace ?? 'default', + kind: entity.kind, + name: entity.metadata.name, + })} + color="primary" + > + Read Docs + </Button> + </CardActions> + </Card> + ))} + </ItemCardGrid> + ); +}; diff --git a/plugins/techdocs/src/home/components/OwnedContent.test.tsx b/plugins/techdocs/src/home/components/DocsTable.test.tsx similarity index 68% rename from plugins/techdocs/src/home/components/OwnedContent.test.tsx rename to plugins/techdocs/src/home/components/DocsTable.test.tsx index edccb0d3c6..8a7d8d9af1 100644 --- a/plugins/techdocs/src/home/components/OwnedContent.test.tsx +++ b/plugins/techdocs/src/home/components/DocsTable.test.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 Spotify AB + * Copyright 2021 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,37 +16,13 @@ import React from 'react'; import { render } from '@testing-library/react'; import { wrapInTestApp } from '@backstage/test-utils'; -import { OwnedContent } from './OwnedContent'; +import { DocsTable } from './DocsTable'; -jest.mock('../hooks', () => ({ - useOwnUser: () => { - return { - value: { - apiVersion: 'version', - kind: 'User', - metadata: { - name: 'owned', - namespace: 'default', - }, - relations: [ - { - target: { - kind: 'TestKind', - name: 'testName', - }, - type: 'ownerOf', - }, - ], - }, - }; - }, -})); - -describe('TechDocs Owned Content', () => { - it('should render TechDocs Owned Documents', async () => { - const { findByText, queryByText } = render( +describe('DocsTable test', () => { + it('should render documents passed', async () => { + const { findByText } = render( wrapInTestApp( - <OwnedContent + <DocsTable entities={[ { apiVersion: 'version', @@ -93,16 +69,12 @@ describe('TechDocs Owned Content', () => { ), ); - expect(await findByText('Owned documents')).toBeInTheDocument(); - expect(await findByText(/Access your documentation./i)).toBeInTheDocument(); expect(await findByText('testName')).toBeInTheDocument(); - expect(await queryByText('testName2')).not.toBeInTheDocument(); + expect(await findByText('testName2')).toBeInTheDocument(); }); it('should render empty state if no owned documents exist', async () => { - const { findByText } = render( - wrapInTestApp(<OwnedContent entities={[]} />), - ); + const { findByText } = render(wrapInTestApp(<DocsTable entities={[]} />)); expect(await findByText('No documents to show')).toBeInTheDocument(); }); diff --git a/plugins/techdocs/src/home/components/OwnedContent.tsx b/plugins/techdocs/src/home/components/DocsTable.tsx similarity index 67% rename from plugins/techdocs/src/home/components/OwnedContent.tsx rename to plugins/techdocs/src/home/components/DocsTable.tsx index f962147345..341ff852be 100644 --- a/plugins/techdocs/src/home/components/OwnedContent.tsx +++ b/plugins/techdocs/src/home/components/DocsTable.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 Spotify AB + * Copyright 2021 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,46 +20,34 @@ import { generatePath } from 'react-router-dom'; import { IconButton, Tooltip } from '@material-ui/core'; import ShareIcon from '@material-ui/icons/Share'; -import { - Content, - ContentHeader, - SupportButton, - Table, - EmptyState, - Button, - SubvalueCell, - Link, -} from '@backstage/core'; +import { Table, EmptyState, Button, SubvalueCell, Link } from '@backstage/core'; import { Entity } from '@backstage/catalog-model'; -import { isOwnerOf } from '@backstage/plugin-catalog-react'; import { rootDocsRouteRef } from '../../plugin'; -import { useOwnUser } from '../hooks'; -export const OwnedContent = ({ +export const DocsTable = ({ entities, + title, }: { entities: Entity[] | undefined; + title?: string | undefined; }) => { const [, copyToClipboard] = useCopyToClipboard(); - const { value: user } = useOwnUser(); - if (!entities || !user) return null; + if (!entities) return null; - const ownedDocuments = entities - .filter((entity: Entity) => isOwnerOf(user, entity)) - .map(entity => { - return { + const documents = entities.map(entity => { + return { + name: entity.metadata.name, + description: entity.metadata.description, + owner: entity?.spec?.owner, + type: entity?.spec?.type, + docsUrl: generatePath(rootDocsRouteRef.path, { + namespace: entity.metadata.namespace ?? 'default', + kind: entity.kind, name: entity.metadata.name, - description: entity.metadata.description, - owner: entity?.spec?.owner, - type: entity?.spec?.type, - docsUrl: generatePath(rootDocsRouteRef.path, { - namespace: entity.metadata.namespace ?? 'default', - kind: entity.kind, - name: entity.metadata.name, - }), - }; - }); + }), + }; + }); const columns = [ { @@ -99,19 +87,17 @@ export const OwnedContent = ({ ]; return ( - <Content> - <ContentHeader - title="Owned documents" - description="Access your documentation." - > - <SupportButton>Discover documentation you own.</SupportButton> - </ContentHeader> - {ownedDocuments && ownedDocuments.length > 0 ? ( + <> + {documents && documents.length > 0 ? ( <Table options={{ paging: true, pageSize: 20, search: true }} - data={ownedDocuments} + data={documents} columns={columns} - title={`Owned (${ownedDocuments.length})`} + title={ + title + ? `${title} (${documents.length})` + : `All (${documents.length})` + } /> ) : ( <EmptyState @@ -130,6 +116,6 @@ export const OwnedContent = ({ } /> )} - </Content> + </> ); }; diff --git a/plugins/techdocs/src/home/components/OverviewContent.tsx b/plugins/techdocs/src/home/components/OverviewContent.tsx deleted file mode 100644 index e0030691f5..0000000000 --- a/plugins/techdocs/src/home/components/OverviewContent.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { generatePath } from 'react-router-dom'; - -import { Entity } from '@backstage/catalog-model'; -import { - Button, - Content, - ContentHeader, - SupportButton, - ItemCardGrid, - ItemCardHeader, -} from '@backstage/core'; -import { Card, CardActions, CardContent, CardMedia } from '@material-ui/core'; - -import { rootDocsRouteRef } from '../../plugin'; - -export const OverviewContent = ({ - entities, -}: { - entities: Entity[] | undefined; -}) => { - if (!entities) return null; - return ( - <Content> - <ContentHeader - title="Overview" - description="Explore your internal technical ecosystem through documentation." - > - <SupportButton>Discover documentation in your ecosystem.</SupportButton> - </ContentHeader> - <ItemCardGrid data-testid="docs-explore"> - {!entities?.length - ? null - : entities.map((entity, index: number) => ( - <Card key={index}> - <CardMedia> - <ItemCardHeader title={entity.metadata.name} /> - </CardMedia> - <CardContent>{entity.metadata.description}</CardContent> - <CardActions> - <Button - to={generatePath(rootDocsRouteRef.path, { - namespace: entity.metadata.namespace ?? 'default', - kind: entity.kind, - name: entity.metadata.name, - })} - color="primary" - > - Read Docs - </Button> - </CardActions> - </Card> - ))} - </ItemCardGrid> - </Content> - ); -}; diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx new file mode 100644 index 0000000000..a7f4d90240 --- /dev/null +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx @@ -0,0 +1,83 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import { screen } from '@testing-library/react'; +import React from 'react'; +import { TechDocsCustomHome, WidgetType } from './TechDocsCustomHome'; + +describe('TechDocsCustomHome', () => { + const catalogApi: Partial<CatalogApi> = { + getEntities: async () => ({ items: [] }), + }; + + const apiRegistry = ApiRegistry.with(catalogApiRef, catalogApi); + + it('should render a TechDocs home page', async () => { + const tabsConfig = [ + { + label: 'First Tab', + widgets: [ + { + title: 'First Tab', + description: 'First Tab Description', + widgetType: 'DocsCardGrid' as WidgetType, + filterPredicate: () => true, + }, + ], + }, + { + label: 'Second Tab ', + widgets: [ + { + title: 'Second Tab', + description: 'Second Tab Description', + widgetType: 'DocsTable' as WidgetType, + filterPredicate: () => true, + }, + ], + }, + ]; + + await renderInTestApp( + <ApiProvider apis={apiRegistry}> + <TechDocsCustomHome tabsConfig={tabsConfig} /> + </ApiProvider>, + ); + + // Header + expect(await screen.findByText('Documentation')).toBeInTheDocument(); + expect( + await screen.findByText(/Documentation available in Backstage/i), + ).toBeInTheDocument(); + + // Explore Content + expect(await screen.findByTestId('docs-explore')).toBeDefined(); + + // Tabs + expect(await screen.findAllByText('First Tab')).toHaveLength(2); + expect(await screen.findByText('Second Tab')).toBeInTheDocument(); + expect( + await screen.findByText('First Tab Description'), + ).toBeInTheDocument(); + (await screen.findByText('Second Tab')).click(); + expect( + await screen.findByText('Second Tab Description'), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx new file mode 100644 index 0000000000..37a9dadddb --- /dev/null +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx @@ -0,0 +1,169 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useState } from 'react'; +import { useAsync } from 'react-use'; +import { makeStyles } from '@material-ui/core'; + +import { catalogApiRef, CatalogApi } from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; +import { + CodeSnippet, + Content, + ConfigApi, + configApiRef, + Header, + HeaderTabs, + Page, + Progress, + useApi, + WarningPanel, + SupportButton, + ContentHeader, +} from '@backstage/core'; +import { DocsTable } from './DocsTable'; +import { DocsCardGrid } from './DocsCardGrid'; + +const widgets = { + DocsTable: DocsTable, + DocsCardGrid: DocsCardGrid, +}; + +export type WidgetType = 'DocsCardGrid' | 'DocsTable'; + +export interface WidgetConfig { + title: string; + description: string; + widgetType: WidgetType; + widgetMaxHeight?: string; + filterPredicate: (entity: Entity) => boolean; +} + +export interface TabConfig { + label: string; + widgets: WidgetConfig[]; +} + +export type TabsConfig = TabConfig[]; + +const CustomWidget = ({ + config, + entities, + index, +}: { + config: WidgetConfig; + entities: Entity[]; + index: number; +}) => { + const useStyles = makeStyles({ + widgetContainer: { + maxHeight: config.widgetMaxHeight || 'inherit', + marginBottom: '2rem', + overflow: 'auto', + }, + }); + const classes = useStyles(); + const Widget = widgets[config.widgetType]; + const shownEntities = entities.filter(config.filterPredicate); + return ( + <> + <ContentHeader title={config.title} description={config.description}> + {index === 0 ? ( + <SupportButton> + Discover documentation in your ecosystem. + </SupportButton> + ) : null} + </ContentHeader> + <div className={classes.widgetContainer}> + <Widget entities={shownEntities} /> + </div> + </> + ); +}; + +export const TechDocsCustomHome = ({ + tabsConfig, +}: { + tabsConfig: TabsConfig; +}) => { + const [selectedTab, setSelectedTab] = useState<number>(0); + const catalogApi: CatalogApi = useApi(catalogApiRef); + const configApi: ConfigApi = useApi(configApiRef); + + const { value: entities, loading, error } = useAsync(async () => { + const response = await catalogApi.getEntities(); + return response.items.filter((entity: Entity) => { + return !!entity.metadata.annotations?.['backstage.io/techdocs-ref']; + }); + }); + + const generatedSubtitle = `Documentation available in ${ + configApi.getOptionalString('organization.name') ?? 'Backstage' + }`; + + const currentTabConfig = tabsConfig[selectedTab]; + + if (loading) { + return ( + <Page themeId="documentation"> + <Header title="Documentation" subtitle={generatedSubtitle} /> + <Content> + <Progress /> + </Content> + </Page> + ); + } + + if (error) { + return ( + <Page themeId="documentation"> + <Header title="Documentation" subtitle={generatedSubtitle} /> + <Content> + <WarningPanel + severity="error" + title="Could not load available documentation." + > + <CodeSnippet language="text" text={error.toString()} /> + </WarningPanel> + </Content> + </Page> + ); + } + + return ( + <Page themeId="documentation"> + <Header title="Documentation" subtitle={generatedSubtitle} /> + <HeaderTabs + selectedIndex={selectedTab} + onChange={index => setSelectedTab(index)} + tabs={tabsConfig.map(({ label }, index) => ({ + id: index.toString(), + label, + }))} + /> + <Content> + {currentTabConfig.widgets.map((config, index) => ( + <CustomWidget + key={index} + config={config} + entities={!!entities ? entities : []} + index={index} + /> + ))} + </Content> + </Page> + ); +}; diff --git a/plugins/techdocs/src/home/components/TechDocsHome.test.tsx b/plugins/techdocs/src/home/components/TechDocsHome.test.tsx index 8067767d39..566ed3bd0b 100644 --- a/plugins/techdocs/src/home/components/TechDocsHome.test.tsx +++ b/plugins/techdocs/src/home/components/TechDocsHome.test.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 Spotify AB + * Copyright 2021 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,30 @@ import { screen } from '@testing-library/react'; import React from 'react'; import { TechDocsHome } from './TechDocsHome'; +jest.mock('../hooks', () => ({ + useOwnUser: () => { + return { + value: { + apiVersion: 'version', + kind: 'User', + metadata: { + name: 'owned', + namespace: 'default', + }, + relations: [ + { + target: { + kind: 'TestKind', + name: 'testName', + }, + type: 'ownerOf', + }, + ], + }, + }; + }, +})); + describe('TechDocs Home', () => { const catalogApi: Partial<CatalogApi> = { getEntities: async () => ({ items: [] }), diff --git a/plugins/techdocs/src/home/components/TechDocsHome.tsx b/plugins/techdocs/src/home/components/TechDocsHome.tsx index 5e9e25e7a0..904c759b11 100644 --- a/plugins/techdocs/src/home/components/TechDocsHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsHome.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 Spotify AB + * Copyright 2021 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,88 +14,44 @@ * limitations under the License. */ -import React, { useState } from 'react'; -import { useAsync } from 'react-use'; - -import { catalogApiRef, CatalogApi } from '@backstage/plugin-catalog-react'; +import React from 'react'; import { Entity } from '@backstage/catalog-model'; -import { - CodeSnippet, - ConfigApi, - configApiRef, - Content, - Header, - HeaderTabs, - Page, - Progress, - useApi, - WarningPanel, -} from '@backstage/core'; - -import { OverviewContent } from './OverviewContent'; -import { OwnedContent } from './OwnedContent'; +import { useOwnUser } from '../hooks'; +import { isOwnerOf } from '@backstage/plugin-catalog-react'; +import { WidgetType, TechDocsCustomHome } from './TechDocsCustomHome'; export const TechDocsHome = () => { - const [selectedTab, setSelectedTab] = useState<number>(0); - const catalogApi: CatalogApi = useApi(catalogApiRef); - const configApi: ConfigApi = useApi(configApiRef); + const { value: user } = useOwnUser(); - const tabs = [{ label: 'Overview' }, { label: 'Owned Documents' }]; - - const { value, loading, error } = useAsync(async () => { - const response = await catalogApi.getEntities(); - return response.items.filter((entity: Entity) => { - return !!entity.metadata.annotations?.['backstage.io/techdocs-ref']; - }); - }); - - const generatedSubtitle = `Documentation available in ${ - configApi.getOptionalString('organization.name') ?? 'Backstage' - }`; - - if (loading) { - return ( - <Page themeId="documentation"> - <Header title="Documentation" subtitle={generatedSubtitle} /> - <Content> - <Progress /> - </Content> - </Page> - ); - } - - if (error) { - return ( - <Page themeId="documentation"> - <Header title="Documentation" subtitle={generatedSubtitle} /> - <Content> - <WarningPanel - severity="error" - title="Could not load available documentation." - > - <CodeSnippet language="text" text={error.toString()} /> - </WarningPanel> - </Content> - </Page> - ); - } - - return ( - <Page themeId="documentation"> - <Header title="Documentation" subtitle={generatedSubtitle} /> - <HeaderTabs - selectedIndex={selectedTab} - onChange={index => setSelectedTab(index)} - tabs={tabs.map(({ label }, index) => ({ - id: index.toString(), - label, - }))} - /> - {selectedTab === 0 ? ( - <OverviewContent entities={value} /> - ) : ( - <OwnedContent entities={value} /> - )} - </Page> - ); + const tabsConfig = [ + { + label: 'Overview', + widgets: [ + { + title: 'Overview', + description: + 'Explore your internal technical ecosystem through documentation.', + widgetType: 'DocsCardGrid' as WidgetType, + filterPredicate: () => true, + }, + ], + }, + { + label: 'Owned', + widgets: [ + { + title: 'Owned documents', + description: 'Access your documentation.', + widgetType: 'DocsTable' as WidgetType, + filterPredicate: (entity: Entity) => { + if (!user) { + return false; + } + return isOwnerOf(user, entity); + }, + }, + ], + }, + ]; + return <TechDocsCustomHome tabsConfig={tabsConfig} />; }; diff --git a/plugins/techdocs/src/index.ts b/plugins/techdocs/src/index.ts index 30c143e31f..f72938e385 100644 --- a/plugins/techdocs/src/index.ts +++ b/plugins/techdocs/src/index.ts @@ -19,7 +19,12 @@ export { techdocsPlugin as plugin, TechdocsPage, EntityTechdocsContent, + DocsCardGrid, + DocsTable, + TechDocsCustomHome, + TechDocsReaderPage, } from './plugin'; export { Router, EmbeddedDocsRouter } from './Router'; export * from './reader'; export * from './api'; +export type { WidgetType } from './home/components/TechDocsCustomHome'; diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index a945ca1494..d9b38a2c76 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -37,6 +37,7 @@ import { discoveryApiRef, identityApiRef, createRoutableExtension, + createComponentExtension, } from '@backstage/core'; import { techdocsStorageApiRef, @@ -111,3 +112,41 @@ export const EntityTechdocsContent = techdocsPlugin.provide( mountPoint: rootCatalogDocsRouteRef, }), ); + +// takes a list of entities and renders documentation cards +export const DocsCardGrid = techdocsPlugin.provide( + createComponentExtension({ + component: { + lazy: () => + import('./home/components/DocsCardGrid').then(m => m.DocsCardGrid), + }, + }), +); + +// takes a list of entities and renders table listing documentation +export const DocsTable = techdocsPlugin.provide( + createComponentExtension({ + component: { + lazy: () => import('./home/components/DocsTable').then(m => m.DocsTable), + }, + }), +); + +// takes a custom tabs config object and renders a documentation landing page +export const TechDocsCustomHome = techdocsPlugin.provide( + createRoutableExtension({ + component: () => + import('./home/components/TechDocsCustomHome').then( + m => m.TechDocsCustomHome, + ), + mountPoint: rootRouteRef, + }), +); + +export const TechDocsReaderPage = techdocsPlugin.provide( + createRoutableExtension({ + component: () => + import('./reader/components/TechDocsPage').then(m => m.TechDocsPage), + mountPoint: rootDocsRouteRef, + }), +); From 10579c3d0daf824ae2aa41a63e280039e50e14b4 Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Mon, 19 Apr 2021 15:17:50 +0800 Subject: [PATCH 186/462] Update docs/features/techdocs/how-to-guides.md Co-authored-by: Himanshu Mishra <himanshu@orkohunter.net> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index a76905d6c5..2b3fd08f76 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -89,7 +89,7 @@ implementation very soon. In your main App.tsx: -``` +```tsx import { TechDocsCustomHome, WidgetType, From 74c91998bfd295d2422a3b63327344bdf739ba8d Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Mon, 19 Apr 2021 15:17:55 +0800 Subject: [PATCH 187/462] Update docs/features/techdocs/how-to-guides.md Co-authored-by: Himanshu Mishra <himanshu@orkohunter.net> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 2b3fd08f76..f387379e06 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -150,7 +150,7 @@ const routes = ( An example of tabsConfig that corresponds to the default documentation home page can be found at `plugins/techdocs/src/home/components/TechDocsHome.tsx`. -### 2nd way: custom home page plugin +### 2nd way: Custom home page plugin A custom home page plugin can be built that uses the components extensions DocsCardGrid and DocsTable, exported from @backstage/techdocs. They both take a From 6db5564af60c4a704c476daad80e8aa8a13fdf62 Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Mon, 19 Apr 2021 15:18:01 +0800 Subject: [PATCH 188/462] Update docs/features/techdocs/how-to-guides.md Co-authored-by: Himanshu Mishra <himanshu@orkohunter.net> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index f387379e06..e1dbe8b494 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -157,5 +157,5 @@ DocsCardGrid and DocsTable, exported from @backstage/techdocs. They both take a array of documentation entities ( have 'backstage.io/techdocs-ref' annotation ) as an 'entities' attribute. -For an reference to the React structure of the default home page, please refer +For a reference to the React structure of the default home page, please refer to `plugins/techdocs/src/home/components/TechDocsCustomHome.tsx`. From 9f7d5662e3002356c06abe40dbfade36473a239c Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" <ftt.adrian.ke@grabtaxi.com> Date: Mon, 19 Apr 2021 16:24:59 +0800 Subject: [PATCH 189/462] update how-to-guides.md Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index e1dbe8b494..1da925ae5a 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -154,8 +154,8 @@ can be found at `plugins/techdocs/src/home/components/TechDocsHome.tsx`. A custom home page plugin can be built that uses the components extensions DocsCardGrid and DocsTable, exported from @backstage/techdocs. They both take a -array of documentation entities ( have 'backstage.io/techdocs-ref' annotation ) -as an 'entities' attribute. +array of documentation entities ( i.e.have a 'backstage.io/techdocs-ref' +annotation ) as an 'entities' attribute. -For a reference to the React structure of the default home page, please refer -to `plugins/techdocs/src/home/components/TechDocsCustomHome.tsx`. +For a reference to the React structure of the default home page, please refer to +`plugins/techdocs/src/home/components/TechDocsCustomHome.tsx`. From cb321bae90356b4eaa8609144e99ae082b2d939a Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" <ftt.adrian.ke@grabtaxi.com> Date: Thu, 22 Apr 2021 11:53:30 +0800 Subject: [PATCH 190/462] change naming from widget to panel Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 18 ++++++----- .../src/home/components/DocsTable.tsx | 6 +++- .../components/TechDocsCustomHome.test.tsx | 10 +++---- .../home/components/TechDocsCustomHome.tsx | 30 +++++++++---------- .../src/home/components/TechDocsHome.tsx | 11 +++---- plugins/techdocs/src/index.ts | 2 +- 6 files changed, 43 insertions(+), 34 deletions(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 1da925ae5a..682051dd83 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -92,7 +92,7 @@ In your main App.tsx: ```tsx import { TechDocsCustomHome, - WidgetType, + PanelType, TechDocsReaderPage, } from '@backstage/plugin-techdocs'; import { Entity } from '@backstage/catalog-model'; @@ -105,17 +105,17 @@ const tabsConfig = [ title: 'Custom Documents Cards 1', description: 'Explore your internal technical ecosystem through documentation.', - // sets maximum height of widget, as CSS maxHeight attribute - widgetMaxHeight: '400px' - widgetType: 'DocsCardGrid' as WidgetType, + panelType: 'DocsCardGrid' as PanelType, + // optional, is applied to a container of the panel (excludes header of panel) + panelCSS: { maxHeight: '400px' }, filterPredicate: (entity: Entity) => !!entity.metadata.annotations?.['customCardAnnotationOne']; }, { title: 'Custom Documents Cards 2', description: 'Explore your internal technical ecosystem through documentation.', - widgetMaxHeight: '400px' - widgetType: 'DocsCardGrid' as WidgetType, + panelType: 'DocsCardGrid' as PanelType, + panelCSS: { maxHeight: '400px' }, filterPredicate: (entity: Entity) => !!entity.metadata.annotations?.['customCardAnnotationTwo']; }, ], @@ -127,7 +127,7 @@ const tabsConfig = [ title: 'Overview', description: 'Explore your internal technical ecosystem through documentation.', - widgetType: 'DocsTable' as WidgetType, + panelType: 'DocsTable' as PanelType, filterPredicate: () => true, }, ], @@ -150,6 +150,10 @@ const routes = ( An example of tabsConfig that corresponds to the default documentation home page can be found at `plugins/techdocs/src/home/components/TechDocsHome.tsx`. +Currently `panelType` has DocsCardGrid and DocsTable available. We currently +recommend that DocsCardGrid can be optionally vertically stacked by setting a +maxHeight using `panelCSS`, and DocsTable to be in a tab by itself. + ### 2nd way: Custom home page plugin A custom home page plugin can be built that uses the components extensions diff --git a/plugins/techdocs/src/home/components/DocsTable.tsx b/plugins/techdocs/src/home/components/DocsTable.tsx index 341ff852be..cb0a3b4329 100644 --- a/plugins/techdocs/src/home/components/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/DocsTable.tsx @@ -90,7 +90,11 @@ export const DocsTable = ({ <> {documents && documents.length > 0 ? ( <Table - options={{ paging: true, pageSize: 20, search: true }} + options={{ + paging: true, + pageSize: 20, + search: true, + }} data={documents} columns={columns} title={ diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx index a7f4d90240..9ee32fef13 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx @@ -19,7 +19,7 @@ import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; import { renderInTestApp } from '@backstage/test-utils'; import { screen } from '@testing-library/react'; import React from 'react'; -import { TechDocsCustomHome, WidgetType } from './TechDocsCustomHome'; +import { TechDocsCustomHome, PanelType } from './TechDocsCustomHome'; describe('TechDocsCustomHome', () => { const catalogApi: Partial<CatalogApi> = { @@ -32,22 +32,22 @@ describe('TechDocsCustomHome', () => { const tabsConfig = [ { label: 'First Tab', - widgets: [ + panels: [ { title: 'First Tab', description: 'First Tab Description', - widgetType: 'DocsCardGrid' as WidgetType, + panelType: 'DocsCardGrid' as PanelType, filterPredicate: () => true, }, ], }, { label: 'Second Tab ', - widgets: [ + panels: [ { title: 'Second Tab', description: 'Second Tab Description', - widgetType: 'DocsTable' as WidgetType, + panelType: 'DocsTable' as PanelType, filterPredicate: () => true, }, ], diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx index 37a9dadddb..ffcb02451b 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx @@ -37,46 +37,46 @@ import { import { DocsTable } from './DocsTable'; import { DocsCardGrid } from './DocsCardGrid'; -const widgets = { +const panels = { DocsTable: DocsTable, DocsCardGrid: DocsCardGrid, }; -export type WidgetType = 'DocsCardGrid' | 'DocsTable'; +export type PanelType = 'DocsCardGrid' | 'DocsTable'; -export interface WidgetConfig { +export interface PanelConfig { title: string; description: string; - widgetType: WidgetType; - widgetMaxHeight?: string; + panelType: PanelType; + panelCSS?: {}; filterPredicate: (entity: Entity) => boolean; } export interface TabConfig { label: string; - widgets: WidgetConfig[]; + panels: PanelConfig[]; } export type TabsConfig = TabConfig[]; -const CustomWidget = ({ +const CustomPanel = ({ config, entities, index, }: { - config: WidgetConfig; + config: PanelConfig; entities: Entity[]; index: number; }) => { const useStyles = makeStyles({ - widgetContainer: { - maxHeight: config.widgetMaxHeight || 'inherit', + panelContainer: { marginBottom: '2rem', overflow: 'auto', + ...(config.panelCSS ? config.panelCSS : {}), }, }); const classes = useStyles(); - const Widget = widgets[config.widgetType]; + const Panel = panels[config.panelType]; const shownEntities = entities.filter(config.filterPredicate); return ( <> @@ -87,8 +87,8 @@ const CustomWidget = ({ </SupportButton> ) : null} </ContentHeader> - <div className={classes.widgetContainer}> - <Widget entities={shownEntities} /> + <div className={classes.panelContainer}> + <Panel entities={shownEntities} /> </div> </> ); @@ -155,8 +155,8 @@ export const TechDocsCustomHome = ({ }))} /> <Content> - {currentTabConfig.widgets.map((config, index) => ( - <CustomWidget + {currentTabConfig.panels.map((config, index) => ( + <CustomPanel key={index} config={config} entities={!!entities ? entities : []} diff --git a/plugins/techdocs/src/home/components/TechDocsHome.tsx b/plugins/techdocs/src/home/components/TechDocsHome.tsx index 904c759b11..a9641391e2 100644 --- a/plugins/techdocs/src/home/components/TechDocsHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsHome.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { Entity } from '@backstage/catalog-model'; import { useOwnUser } from '../hooks'; import { isOwnerOf } from '@backstage/plugin-catalog-react'; -import { WidgetType, TechDocsCustomHome } from './TechDocsCustomHome'; +import { PanelType, TechDocsCustomHome } from './TechDocsCustomHome'; export const TechDocsHome = () => { const { value: user } = useOwnUser(); @@ -26,23 +26,24 @@ export const TechDocsHome = () => { const tabsConfig = [ { label: 'Overview', - widgets: [ + panels: [ { title: 'Overview', description: 'Explore your internal technical ecosystem through documentation.', - widgetType: 'DocsCardGrid' as WidgetType, + panelType: 'DocsCardGrid' as PanelType, filterPredicate: () => true, }, ], }, { label: 'Owned', - widgets: [ + panels: [ { title: 'Owned documents', description: 'Access your documentation.', - widgetType: 'DocsTable' as WidgetType, + panelType: 'DocsTable' as PanelType, + paneCSS: { maxHeight: '200px' }, filterPredicate: (entity: Entity) => { if (!user) { return false; diff --git a/plugins/techdocs/src/index.ts b/plugins/techdocs/src/index.ts index f72938e385..b33b91e2c5 100644 --- a/plugins/techdocs/src/index.ts +++ b/plugins/techdocs/src/index.ts @@ -27,4 +27,4 @@ export { export { Router, EmbeddedDocsRouter } from './Router'; export * from './reader'; export * from './api'; -export type { WidgetType } from './home/components/TechDocsCustomHome'; +export type { PanelType } from './home/components/TechDocsCustomHome'; From f5dab83b5972ae9c317a51a7b77ccf1c788b788e Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Fri, 23 Apr 2021 11:00:08 +0800 Subject: [PATCH 191/462] Update docs/features/techdocs/how-to-guides.md Signed-off-by: Eric Peterson <ericpeterson@spotify.com> Co-authored-by: Eric Peterson <iamEAP@users.noreply.github.com> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 682051dd83..1b19f12b8a 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -100,7 +100,7 @@ import { Entity } from '@backstage/catalog-model'; const tabsConfig = [ { label: 'Custom Tab', - widgets: [ + panels: [ { title: 'Custom Documents Cards 1', description: From 7a3b3b2be6bec8bbc733313e56cc0d396be2c16d Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Fri, 23 Apr 2021 11:00:17 +0800 Subject: [PATCH 192/462] Update docs/features/techdocs/how-to-guides.md Signed-off-by: Eric Peterson <ericpeterson@spotify.com> Co-authored-by: Eric Peterson <iamEAP@users.noreply.github.com> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 1b19f12b8a..384656ea38 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -122,7 +122,7 @@ const tabsConfig = [ }, { label: 'Overview', - widgets: [ + panels: [ { title: 'Overview', description: From 64ade20227f269f26ad3d4ffa1c20fcf6d223c77 Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Fri, 23 Apr 2021 11:00:30 +0800 Subject: [PATCH 193/462] Update plugins/techdocs/src/home/components/TechDocsHome.tsx Signed-off-by: Eric Peterson <ericpeterson@spotify.com> Co-authored-by: Eric Peterson <iamEAP@users.noreply.github.com> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- plugins/techdocs/src/home/components/TechDocsHome.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/techdocs/src/home/components/TechDocsHome.tsx b/plugins/techdocs/src/home/components/TechDocsHome.tsx index a9641391e2..ef2749015a 100644 --- a/plugins/techdocs/src/home/components/TechDocsHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsHome.tsx @@ -43,7 +43,6 @@ export const TechDocsHome = () => { title: 'Owned documents', description: 'Access your documentation.', panelType: 'DocsTable' as PanelType, - paneCSS: { maxHeight: '200px' }, filterPredicate: (entity: Entity) => { if (!user) { return false; From 4666ddb275465dc499d9b9c30d2dbb3546233d4b Mon Sep 17 00:00:00 2001 From: Adrian Ke Chongyang <14866712+adrianke77@users.noreply.github.com> Date: Fri, 23 Apr 2021 11:00:37 +0800 Subject: [PATCH 194/462] Update plugins/techdocs/src/home/components/TechDocsHome.tsx Signed-off-by: Eric Peterson <ericpeterson@spotify.com> Co-authored-by: Eric Peterson <iamEAP@users.noreply.github.com> Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- plugins/techdocs/src/home/components/TechDocsHome.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs/src/home/components/TechDocsHome.tsx b/plugins/techdocs/src/home/components/TechDocsHome.tsx index ef2749015a..72f59d5446 100644 --- a/plugins/techdocs/src/home/components/TechDocsHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsHome.tsx @@ -37,7 +37,7 @@ export const TechDocsHome = () => { ], }, { - label: 'Owned', + label: 'Owned Documents', panels: [ { title: 'Owned documents', From 7dd94b075056ea9118047d4c66e0285f23e9139c Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" <ftt.adrian.ke@grabtaxi.com> Date: Fri, 23 Apr 2021 11:20:46 +0800 Subject: [PATCH 195/462] add CSSProperties type for panelCSS Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- plugins/techdocs/package.json | 1 + plugins/techdocs/src/home/components/TechDocsCustomHome.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 88b3b6a1df..775e57d00f 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -41,6 +41,7 @@ "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", + "@material-ui/styles": "^4.10.0", "react": "^16.13.1", "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx index ffcb02451b..7230adb29b 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx @@ -17,7 +17,7 @@ import React, { useState } from 'react'; import { useAsync } from 'react-use'; import { makeStyles } from '@material-ui/core'; - +import { CSSProperties } from '@material-ui/styles'; import { catalogApiRef, CatalogApi } from '@backstage/plugin-catalog-react'; import { Entity } from '@backstage/catalog-model'; import { @@ -48,7 +48,7 @@ export interface PanelConfig { title: string; description: string; panelType: PanelType; - panelCSS?: {}; + panelCSS?: CSSProperties; filterPredicate: (entity: Entity) => boolean; } From 813a4a04f55752bf273c2dac304f1d1dbd2152f8 Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" <ftt.adrian.ke@grabtaxi.com> Date: Fri, 23 Apr 2021 11:38:09 +0800 Subject: [PATCH 196/462] fix DocsTable rendering of EmptyState Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- docs/features/techdocs/how-to-guides.md | 6 +++--- plugins/techdocs/src/home/components/TechDocsCustomHome.tsx | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 384656ea38..6c64e83a76 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -87,7 +87,7 @@ implementation very soon. ### 1st way: TechDocsCustomHome with a custom configuration -In your main App.tsx: +As an example, in your main App.tsx: ```tsx import { @@ -107,7 +107,7 @@ const tabsConfig = [ 'Explore your internal technical ecosystem through documentation.', panelType: 'DocsCardGrid' as PanelType, // optional, is applied to a container of the panel (excludes header of panel) - panelCSS: { maxHeight: '400px' }, + panelCSS: { maxHeight: '400px', overflow:'auto' }, filterPredicate: (entity: Entity) => !!entity.metadata.annotations?.['customCardAnnotationOne']; }, { @@ -115,7 +115,7 @@ const tabsConfig = [ description: 'Explore your internal technical ecosystem through documentation.', panelType: 'DocsCardGrid' as PanelType, - panelCSS: { maxHeight: '400px' }, + panelCSS: { maxHeight: '400px', overflow:'auto' }, filterPredicate: (entity: Entity) => !!entity.metadata.annotations?.['customCardAnnotationTwo']; }, ], diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx index 7230adb29b..ff9f1bf101 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx @@ -71,7 +71,6 @@ const CustomPanel = ({ const useStyles = makeStyles({ panelContainer: { marginBottom: '2rem', - overflow: 'auto', ...(config.panelCSS ? config.panelCSS : {}), }, }); From e363f6103ef99b73a5945dd95eee9bc9b344f11b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Apr 2021 04:14:11 +0000 Subject: [PATCH 197/462] chore(deps): bump serialize-error from 8.0.1 to 8.1.0 Bumps [serialize-error](https://github.com/sindresorhus/serialize-error) from 8.0.1 to 8.1.0. - [Release notes](https://github.com/sindresorhus/serialize-error/releases) - [Commits](https://github.com/sindresorhus/serialize-error/compare/v8.0.1...v8.1.0) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index df07058f48..ba1b3bfe73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23454,9 +23454,9 @@ serialize-error@^2.1.0: integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= serialize-error@^8.0.1: - version "8.0.1" - resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-8.0.1.tgz#7a67f8ecbbf28973b5a954a2852ff9f4eef52d99" - integrity sha512-r5o60rWFS+8/b49DNAbB+GXZA0SpDpuWE758JxDKgRTga05r3U5lwyksE91dYKDhXSmnu36RALj615E6Aj5pSg== + version "8.1.0" + resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" + integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ== dependencies: type-fest "^0.20.2" From 0b95bc1c6bf96530ff716926bb5a1e5141363d32 Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Fri, 23 Apr 2021 09:57:39 +0200 Subject: [PATCH 198/462] Align techdocs navigation with microsite Signed-off-by: Brian Fox <brianhfox@gmail.com> --- mkdocs.yml | 153 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 57 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 031fb56059..7826b3221d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,114 +7,153 @@ plugins: nav: - Overview: - What is Backstage?: 'overview/what-is-backstage.md' - - Backstage architecture: 'overview/architecture-overview.md' - - Roadmap: 'overview/roadmap.md' + - Architecture overview: 'overview/architecture-overview.md' + - Project Roadmap: 'overview/roadmap.md' - Vision: 'overview/vision.md' - - The Spotify story: 'overview/background.md' + - The Spotify Story: 'overview/background.md' - Strategies for adopting: 'overview/adopting.md' + - Stability Index: 'overview/stability-index.md' - Logo assets: 'overview/logos.md' - - Getting started: + - Getting Started: - Getting Started: 'getting-started/index.md' + - Create an App: 'getting-started/create-an-app.md' - Running Backstage locally: 'getting-started/running-backstage-locally.md' + - App configuration: + - Configuring App with plugins: 'getting-started/configure-app-with-plugins.md' + - Customize the look-and-feel of your App: 'getting-started/app-custom-theme.md' + - Keeping Backstage Updated: 'getting-started/keeping-backstage-updated.md' + - Key Concepts: 'getting-started/concepts.md' - Contributors: 'getting-started/contributors.md' - - Demo deployment: https://backstage-demo.roadie.io - - Production deployments: - - Create an App: 'getting-started/create-an-app.md' - - App configuration: - - Configuring App with plugins: 'getting-started/configure-app-with-plugins.md' - - Customize the look-and-feel of your App: 'getting-started/app-custom-theme.md' - - Deployment scenarios: - - Docker: 'getting-started/deployment-docker.md' - - Kubernetes: 'getting-started/deployment-k8s.md' - - Kubernetes and Helm: 'getting-started/deployment-helm.md' - - Other: 'getting-started/deployment-other.md' - - Features: + - CLI: + - Overview: 'cli/index.md' + - Commands: 'cli/commands.md' + - Core Features: - Software Catalog: - Overview: 'features/software-catalog/index.md' - - Installation: 'features/software-catalog/installation.md' - - Configuration: 'features/software-catalog/configuration.md' - - System model: 'features/software-catalog/system-model.md' + - Installing in your Backstage App: 'features/software-catalog/installation.md' + - Catalog Configuration: 'features/software-catalog/configuration.md' + - System Model: 'features/software-catalog/system-model.md' - YAML File Format: 'features/software-catalog/descriptor-format.md' - Entity References: 'features/software-catalog/references.md' - Well-known Annotations: 'features/software-catalog/well-known-annotations.md' + - Well-known Relations: 'features/software-catalog/well-known-relations.md' - Extending the model: 'features/software-catalog/extending-the-model.md' - External integrations: 'features/software-catalog/external-integrations.md' - API: 'features/software-catalog/api.md' - - Software creation templates: + - Kubernetes: + - Overview: 'features/kubernetes/index.md' + - Installation: 'features/kubernetes/installation.md' + - Configuration: 'features/kubernetes/configuration.md' + - Troubleshooting: 'features/kubernetes/troubleshooting.md' + - Software Templates: - Overview: 'features/software-templates/index.md' - - Installation: 'features/software-templates/installation.md' - - Adding templates: 'features/software-templates/adding-templates.md' - - Extending the Scaffolder: - - Overview: 'features/software-templates/extending/index.md' - - Create your own Templater: 'features/software-templates/extending/create-your-own-templater.md' - - Create your own Publisher: 'features/software-templates/extending/create-your-own-publisher.md' - - Create your own Preparer: 'features/software-templates/extending/create-your-own-preparer.md' + - Installing in your Backstage App: 'features/software-templates/installation.md' + - Adding your own Templates: 'features/software-templates/adding-templates.md' + - Writing Templates: 'features/software-templates/writing-templates.md' + - Builtin Actions: 'features/software-templates/builtin-actions.md' + - Writing Custom Actions: 'features/software-templates/writing-custom-actions.md' + - Writing Templates (Legacy): 'features/software-templates/legacy.md' - Backstage Search: - Overview: 'features/search/README.md' - - Architecture: 'features/search/architecture.md' + - Search Architecture: 'features/search/architecture.md' - TechDocs: - Overview: 'features/techdocs/README.md' - Getting Started: 'features/techdocs/getting-started.md' - Concepts: 'features/techdocs/concepts.md' - TechDocs Architecture: 'features/techdocs/architecture.md' - Creating and Publishing Documentation: 'features/techdocs/creating-and-publishing.md' - - Configuration: 'features/techdocs/configuration.md' + - TechDocs Configuration Options: 'features/techdocs/configuration.md' - Using Cloud Storage: 'features/techdocs/using-cloud-storage.md' + - Configuring CI/CD to generate and publish TechDocs sites: 'features/techdocs/configuring-ci-cd.md' - HOW TO guides: 'features/techdocs/how-to-guides.md' - Troubleshooting: 'features/techdocs/troubleshooting.md' - FAQ: 'features/techdocs/FAQ.md' - - Kubernetes: - - Overview: 'features/kubernetes/index.md' - Integrations: + - Overview: 'integrations/index.md' + - Azure DevOps: + - Locations: 'integrations/azure/locations.md' + - Bitbucket: + - Locations: 'integrations/bitbucket/locations.md' + - Discovery: 'integrations/bitbucket/discovery.md' + - Datadog: + - Installation: 'integrations/datadog-rum/installation.md' - GitHub: + - Locations: 'integrations/github/locations.md' + - Discovery: 'integrations/github/discovery.md' - Org Data: 'integrations/github/org.md' - - LDAP: - - Org Data: 'integrations/ldap/org.md' + - GitLab: + - Locations: 'integrations/gitlab/locations.md' - Google Analytics: - Installation: 'integrations/google-analytics/installation.md' + - Google GCS: + - Locations: 'integrations/google-cloud-storage/locations.md' + - LDAP: + - Org Data: 'integrations/ldap/org.md' - Plugins: - - Overview: 'plugins/index.md' + - Intro to plugins: 'plugins/index.md' - Existing plugins: 'plugins/existing-plugins.md' - - Creating a new plugin: 'plugins/create-a-plugin.md' - - Developing a plugin: 'plugins/plugin-development.md' + - Create a Backstage Plugin: 'plugins/create-a-plugin.md' + - Plugin Development: 'plugins/plugin-development.md' - Structure of a plugin: 'plugins/structure-of-a-plugin.md' + - Plugin Development: 'plugins/plugin-development.md' + - Integrate into the Service Catalog: 'plugins/integrating-plugin-into-service-catalog.md' - Composability System Migration: 'plugins/composability.md' - Backends and APIs: - Proxying: 'plugins/proxying.md' - - Backstage backend plugin: 'plugins/backend-plugin.md' + - Backend plugin: 'plugins/backend-plugin.md' - Call existing API: 'plugins/call-existing-api.md' + - GitHub Apps for Backend Authentication: 'plugins/github-apps.md' - Testing: - - Overview: 'plugins/testing.md' + - Testing with Jest: 'plugins/testing.md' - Publishing: - - Open source and npm: 'plugins/publishing.md' - - Private/internal (non-open source): 'plugins/publish-private.md' + - Publishing: 'plugins/publishing.md' + - Publish private: 'plugins/publish-private.md' + - Add to Marketplace: 'plugins/add-to-marketplace.md' - Observability: 'plugins/observability.md' - Configuration: - - Overview: 'conf/index.md' - - Reading Configuration: 'conf/reading.md' - - Writing Configuration: 'conf/writing.md' - - Defining Configuration: 'conf/defining.md' + - Static Configuration in Backstage: 'conf/index.md' + - Reading Backstage Configuration: 'conf/reading.md' + - Writing Backstage Configuration: 'conf/writing.md' + - Defining Configuration for your Plugin: 'conf/defining.md' - Authentication and identity: - - Overview: 'auth/index.md' - - Add auth provider: 'auth/add-auth-provider.md' + - Adding Authentication: 'auth/index.md' + - Included providers: + - Auth0: 'auth/auth0/provider.md' + - Azure: 'auth/microsoft/provider.md' + - GitHub: 'auth/github/provider.md' + - GitLab: 'auth/gitlab/provider.md' + - Google: 'auth/google/provider.md' + - Okta: 'auth/okta/provider.md' + - OneLogin: 'auth/onelogin/provider.md' + - Adding authentication providers: 'auth/add-auth-provider.md' + - Using authentication and identity: 'auth/using-auth.md' - Auth backend: 'auth/auth-backend.md' - - Auth backend class structure: 'auth/auth-backend-classes.md' - - OAuth: 'auth/oauth.md' + - OAuth and OpenID Connect: 'auth/oauth.md' + - Auth backend classes: 'auth/auth-backend-classes.md' - Glossary: 'auth/glossary.md' + - Deployment: + - Deploying Backstage: 'deployment/index.md' + - Docker: 'deployment/docker.md' + - Kubernetes: 'deployment/k8s.md' + - Helm: 'deployment/helm.md' + - Heroku: 'deployment/heroku.md' - Designing for Backstage: - - Backstage Design Language System (DLS): 'dls/design.md' - - Storybook -- reusable UI components: 'http://backstage.io/storybook' + - Design: 'dls/design.md' - Contributing to Storybook: 'dls/contributing-to-storybook.md' - - Figma resources: 'dls/figma.md' + - Figma: 'dls/figma.md' - API references: - - TypeScript APIs: - - Utilities: 'api/utility-apis.md' + - TypeScript API: + - Utility APIs: 'api/utility-apis.md' + - reference/utility-apis/README: 'reference/utility-apis/README.md' - createPlugin: 'reference/createPlugin.md' - - createPlugin-feature-flags: 'reference/createPlugin-feature-flags.md' + - createPlugin -feature flags: 'reference/createPlugin-feature-flags.md' - Backend APIs: - Backend: 'api/backend.md' - Tutorials: - - Overview: 'tutorials/index.md' + - Future developer journey: 'tutorials/journey.md' + - Monorepo App Setup With Authentication: 'tutorials/quickstart-app-auth.md' + - Adding Custom Plugin to Existing Monorepo App: 'tutorials/quickstart-app-plugin.md' + - Switching Backstage from SQLite to PostgreSQL: 'tutorials/switching-sqlite-postgres.md' - Architecture Decision Records (ADRs): - Overview: 'architecture-decisions/index.md' - ADR001 - Architecture Decision Record (ADR) log: 'architecture-decisions/adr001-add-adr-log.md' @@ -129,7 +168,7 @@ nav: - ADR010 - Luxon Date Library: 'architecture-decisions/adr010-luxon-date-library.md' - ADR011 - Plugin Package Structure: 'architecture-decisions/adr011-plugin-package-structure.md' - Support: - - 'support/support.md' - - 'support/project-structure.md' + - Support and community: 'support/support.md' + - Backstage Project Structure: 'support/project-structure.md' - Glossary: glossary.md - FAQ: FAQ.md From a3a171ccd2a1db14fcd22dae6daeca5de53ea193 Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Fri, 23 Apr 2021 09:31:00 +0200 Subject: [PATCH 199/462] Microsite nav - Alphabetic order please Signed-off-by: Brian Fox <brianhfox@gmail.com> --- microsite/sidebars.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/microsite/sidebars.json b/microsite/sidebars.json index e2a57bd426..c7b049a53e 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -135,13 +135,13 @@ }, { "type": "subcategory", - "label": "LDAP", - "ids": ["integrations/ldap/org"] + "label": "Google GCS", + "ids": ["integrations/google-cloud-storage/locations"] }, { "type": "subcategory", - "label": "Google GCS", - "ids": ["integrations/google-cloud-storage/locations"] + "label": "LDAP", + "ids": ["integrations/ldap/org"] } ], "Plugins": [ From 5652f4eee5b94c5522cb69cf4d643bfd57ffa441 Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Fri, 23 Apr 2021 09:31:35 +0200 Subject: [PATCH 200/462] Fix broken link in Software Templates -> Installation Signed-off-by: Brian Fox <brianhfox@gmail.com> --- docs/features/software-templates/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-templates/installation.md b/docs/features/software-templates/installation.md index 105b7e5f96..7d42c71af9 100644 --- a/docs/features/software-templates/installation.md +++ b/docs/features/software-templates/installation.md @@ -265,7 +265,7 @@ the templates at [localhost:3000/create](http://localhost:3000/create) now! Software Templates use [Cookiecutter](https://github.com/cookiecutter/cookiecutter) as templating library. By default it will use the -[spotify/backstage-cookiecutter](<[spotify/backstage-cookiecutter](https://github.com/backstage/backstage/blob/37e35b910afc7d1270855aed0ec4718aba366c91/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile)>) +[spotify/backstage-cookiecutter](https://github.com/backstage/backstage/blob/37e35b910afc7d1270855aed0ec4718aba366c91/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile) docker image. If you are running backstage from a Docker container and you want to avoid From f09f6a166bd1acd9b2026af18ef827d51a3ca893 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 12:41:53 +0200 Subject: [PATCH 201/462] Use interface and not implementation in ApiRef<T> Closes #4404 Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/swift-waves-sleep.md | 12 + plugins/techdocs/dev/api.ts | 8 +- plugins/techdocs/src/api.ts | 236 +---------------- .../src/{api.test.ts => client.test.ts} | 8 +- plugins/techdocs/src/client.ts | 244 ++++++++++++++++++ plugins/techdocs/src/index.ts | 17 +- plugins/techdocs/src/plugin.ts | 22 +- plugins/techdocs/src/types.ts | 4 + 8 files changed, 296 insertions(+), 255 deletions(-) create mode 100644 .changeset/swift-waves-sleep.md rename plugins/techdocs/src/{api.test.ts => client.test.ts} (87%) create mode 100644 plugins/techdocs/src/client.ts diff --git a/.changeset/swift-waves-sleep.md b/.changeset/swift-waves-sleep.md new file mode 100644 index 0000000000..831ecc0001 --- /dev/null +++ b/.changeset/swift-waves-sleep.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Make `techdocsStorageApiRef` and `techdocsApiRef` use interfaces instead of the +actual implementation classes. + +This renames the classes `TechDocsApi` to `TechDocsClient` and `TechDocsStorageApi` +to `TechDocsStorageClient` and renames the interfaces `TechDocs` to `TechDocsApi` +and `TechDocsStorage` to `TechDocsStorageApi` to comply the pattern elsewhere in +the project. This also fixes the types returned by some methods on those +interfaces. diff --git a/plugins/techdocs/dev/api.ts b/plugins/techdocs/dev/api.ts index 7acf3c7032..e764bf82bb 100644 --- a/plugins/techdocs/dev/api.ts +++ b/plugins/techdocs/dev/api.ts @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { DiscoveryApi, IdentityApi } from '@backstage/core'; -import { Config } from '@backstage/config'; import { EntityName } from '@backstage/catalog-model'; -import { TechDocsStorage } from '../src/api'; +import { Config } from '@backstage/config'; +import { DiscoveryApi, IdentityApi } from '@backstage/core'; import { NotFoundError } from '@backstage/errors'; +import { TechDocsStorageApi } from '../src/api'; -export class TechDocsDevStorageApi implements TechDocsStorage { +export class TechDocsDevStorageApi implements TechDocsStorageApi { public configApi: Config; public discoveryApi: DiscoveryApi; public identityApi: IdentityApi; diff --git a/plugins/techdocs/src/api.ts b/plugins/techdocs/src/api.ts index 0be530cc08..204cc1b5a8 100644 --- a/plugins/techdocs/src/api.ts +++ b/plugins/techdocs/src/api.ts @@ -14,11 +14,9 @@ * limitations under the License. */ -import { createApiRef, DiscoveryApi, IdentityApi } from '@backstage/core'; -import { Config } from '@backstage/config'; import { EntityName } from '@backstage/catalog-model'; -import { TechDocsMetadata } from './types'; -import { NotFoundError } from '@backstage/errors'; +import { createApiRef } from '@backstage/core'; +import { TechDocsEntityMetadata, TechDocsMetadata } from './types'; export const techdocsStorageApiRef = createApiRef<TechDocsStorageApi>({ id: 'plugin.techdocs.storageservice', @@ -30,7 +28,10 @@ export const techdocsApiRef = createApiRef<TechDocsApi>({ description: 'Used to make requests towards techdocs API', }); -export interface TechDocsStorage { +export interface TechDocsStorageApi { + getApiOrigin(): Promise<string>; + getStorageUrl(): Promise<string>; + getBuilder(): Promise<string>; getEntityDocs(entityId: EntityName, path: string): Promise<string>; syncEntityDocs(entityId: EntityName): Promise<boolean>; getBaseUrl( @@ -40,227 +41,8 @@ export interface TechDocsStorage { ): Promise<string>; } -export interface TechDocs { +export interface TechDocsApi { + getApiOrigin(): Promise<string>; getTechDocsMetadata(entityId: EntityName): Promise<TechDocsMetadata>; - getEntityMetadata(entityId: EntityName): Promise<string>; -} - -/** - * API to talk to techdocs-backend. - * - * @property {string} apiOrigin Set to techdocs.requestUrl as the URL for techdocs-backend API - */ -export class TechDocsApi implements TechDocs { - public configApi: Config; - public discoveryApi: DiscoveryApi; - public identityApi: IdentityApi; - - constructor({ - configApi, - discoveryApi, - identityApi, - }: { - configApi: Config; - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }) { - this.configApi = configApi; - this.discoveryApi = discoveryApi; - this.identityApi = identityApi; - } - - async getApiOrigin() { - return ( - this.configApi.getOptionalString('techdocs.requestUrl') ?? - (await this.discoveryApi.getBaseUrl('techdocs')) - ); - } - - /** - * Retrieve TechDocs metadata. - * - * When docs are built, we generate a techdocs_metadata.json and store it along with the generated - * static files. It includes necessary data about the docs site. This method requests techdocs-backend - * which retrieves the TechDocs metadata. - * - * @param {EntityName} entityId Object containing entity data like name, namespace, etc. - */ - async getTechDocsMetadata(entityId: EntityName) { - const { kind, namespace, name } = entityId; - - const apiOrigin = await this.getApiOrigin(); - const requestUrl = `${apiOrigin}/metadata/techdocs/${namespace}/${kind}/${name}`; - const token = await this.identityApi.getIdToken(); - - const request = await fetch(`${requestUrl}`, { - headers: token ? { Authorization: `Bearer ${token}` } : {}, - }); - const res = await request.json(); - - return res; - } - - /** - * Retrieve metadata about an entity. - * - * This method requests techdocs-backend which uses the catalog APIs to respond with filtered - * information required here. - * - * @param {EntityName} entityId Object containing entity data like name, namespace, etc. - */ - async getEntityMetadata(entityId: EntityName) { - const { kind, namespace, name } = entityId; - - const apiOrigin = await this.getApiOrigin(); - const requestUrl = `${apiOrigin}/metadata/entity/${namespace}/${kind}/${name}`; - const token = await this.identityApi.getIdToken(); - - const request = await fetch(`${requestUrl}`, { - headers: token ? { Authorization: `Bearer ${token}` } : {}, - }); - const res = await request.json(); - - return res; - } -} - -/** - * API which talks to TechDocs storage to fetch files to render. - * - * @property {string} apiOrigin Set to techdocs.requestUrl as the URL for techdocs-backend API - */ -export class TechDocsStorageApi implements TechDocsStorage { - public configApi: Config; - public discoveryApi: DiscoveryApi; - public identityApi: IdentityApi; - - constructor({ - configApi, - discoveryApi, - identityApi, - }: { - configApi: Config; - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }) { - this.configApi = configApi; - this.discoveryApi = discoveryApi; - this.identityApi = identityApi; - } - - async getApiOrigin() { - return ( - this.configApi.getOptionalString('techdocs.requestUrl') ?? - (await this.discoveryApi.getBaseUrl('techdocs')) - ); - } - - async getStorageUrl() { - return ( - this.configApi.getOptionalString('techdocs.storageUrl') ?? - `${await this.discoveryApi.getBaseUrl('techdocs')}/static/docs` - ); - } - - async getBuilder() { - return this.configApi.getString('techdocs.builder'); - } - - /** - * Fetch HTML content as text for an individual docs page in an entity's docs site. - * - * @param {EntityName} entityId Object containing entity data like name, namespace, etc. - * @param {string} path The unique path to an individual docs page e.g. overview/what-is-new - * @returns {string} HTML content of the docs page as string - * @throws {Error} Throws error when the page is not found. - */ - async getEntityDocs(entityId: EntityName, path: string) { - const { kind, namespace, name } = entityId; - - const storageUrl = await this.getStorageUrl(); - const url = `${storageUrl}/${namespace}/${kind}/${name}/${path}`; - const token = await this.identityApi.getIdToken(); - - const request = await fetch( - `${url.endsWith('/') ? url : `${url}/`}index.html`, - { - headers: token ? { Authorization: `Bearer ${token}` } : {}, - }, - ); - - let errorMessage = ''; - switch (request.status) { - case 404: - errorMessage = 'Page not found. '; - // path is empty for the home page of an entity's docs site - if (!path) { - errorMessage += - 'This could be because there is no index.md file in the root of the docs directory of this repository.'; - } - throw new NotFoundError(errorMessage); - case 500: - errorMessage = - 'Could not generate documentation or an error in the TechDocs backend. '; - throw new Error(errorMessage); - default: - // Do nothing - break; - } - - return request.text(); - } - - /** - * Check if docs are on the latest version and trigger rebuild if not - * - * @param {EntityName} entityId Object containing entity data like name, namespace, etc. - * @returns {boolean} Whether documents are currently synchronized to newest version - * @throws {Error} Throws error on error from sync endpoint in Techdocs Backend - */ - async syncEntityDocs(entityId: EntityName) { - const { kind, namespace, name } = entityId; - - const apiOrigin = await this.getApiOrigin(); - const url = `${apiOrigin}/sync/${namespace}/${kind}/${name}`; - const token = await this.identityApi.getIdToken(); - let request; - let attempts: number = 0; - // retry if request times out, up to 5 times - // can happen due to docs taking too long to generate - while (!request || (request.status === 408 && attempts < 5)) { - attempts++; - request = await fetch(url, { - headers: token ? { Authorization: `Bearer ${token}` } : {}, - }); - } - - switch (request.status) { - case 404: - throw new NotFoundError((await request.json()).error); - case 200: - case 201: - case 304: - return true; - // for timeout and misc errors, handle without error to allow viewing older docs - // if older docs not available, - // Reader will show 404 error coming from getEntityDocs - case 408: - default: - return false; - } - } - - async getBaseUrl( - oldBaseUrl: string, - entityId: EntityName, - path: string, - ): Promise<string> { - const { kind, namespace, name } = entityId; - - const apiOrigin = await this.getApiOrigin(); - return new URL( - oldBaseUrl, - `${apiOrigin}/static/docs/${namespace}/${kind}/${name}/${path}`, - ).toString(); - } + getEntityMetadata(entityId: EntityName): Promise<TechDocsEntityMetadata>; } diff --git a/plugins/techdocs/src/api.test.ts b/plugins/techdocs/src/client.test.ts similarity index 87% rename from plugins/techdocs/src/api.test.ts rename to plugins/techdocs/src/client.test.ts index 2260cc7d39..e8fc8f042f 100644 --- a/plugins/techdocs/src/api.test.ts +++ b/plugins/techdocs/src/client.test.ts @@ -15,7 +15,7 @@ */ import { Config } from '@backstage/config'; import { UrlPatternDiscovery } from '@backstage/core'; -import { TechDocsStorageApi } from './api'; +import { TechDocsStorageClient } from './client'; const mockEntity = { kind: 'Component', @@ -23,7 +23,7 @@ const mockEntity = { name: 'test-component', }; -describe('TechDocsStorageApi', () => { +describe('TechDocsStorageClient', () => { const mockBaseUrl = 'http://backstage:9191/api/techdocs'; const configApi = { getOptionalString: () => 'http://backstage:9191/api/techdocs', @@ -32,7 +32,7 @@ describe('TechDocsStorageApi', () => { it('should return correct base url based on defined storage', async () => { // @ts-ignore Partial<Config> not assignable to Config. - const storageApi = new TechDocsStorageApi({ configApi, discoveryApi }); + const storageApi = new TechDocsStorageClient({ configApi, discoveryApi }); await expect( storageApi.getBaseUrl('test.js', mockEntity, ''), @@ -43,7 +43,7 @@ describe('TechDocsStorageApi', () => { it('should return base url with correct entity structure', async () => { // @ts-ignore Partial<Config> not assignable to Config. - const storageApi = new TechDocsStorageApi({ configApi, discoveryApi }); + const storageApi = new TechDocsStorageClient({ configApi, discoveryApi }); await expect( storageApi.getBaseUrl('test/', mockEntity, ''), diff --git a/plugins/techdocs/src/client.ts b/plugins/techdocs/src/client.ts new file mode 100644 index 0000000000..245cfb0154 --- /dev/null +++ b/plugins/techdocs/src/client.ts @@ -0,0 +1,244 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EntityName } from '@backstage/catalog-model'; +import { Config } from '@backstage/config'; +import { DiscoveryApi, IdentityApi } from '@backstage/core'; +import { NotFoundError } from '@backstage/errors'; +import { TechDocsApi, TechDocsStorageApi } from './api'; +import { TechDocsEntityMetadata, TechDocsMetadata } from './types'; + +/** + * API to talk to techdocs-backend. + * + * @property {string} apiOrigin Set to techdocs.requestUrl as the URL for techdocs-backend API + */ +export class TechDocsClient implements TechDocsApi { + public configApi: Config; + public discoveryApi: DiscoveryApi; + public identityApi: IdentityApi; + + constructor({ + configApi, + discoveryApi, + identityApi, + }: { + configApi: Config; + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + }) { + this.configApi = configApi; + this.discoveryApi = discoveryApi; + this.identityApi = identityApi; + } + + async getApiOrigin(): Promise<string> { + return ( + this.configApi.getOptionalString('techdocs.requestUrl') ?? + (await this.discoveryApi.getBaseUrl('techdocs')) + ); + } + + /** + * Retrieve TechDocs metadata. + * + * When docs are built, we generate a techdocs_metadata.json and store it along with the generated + * static files. It includes necessary data about the docs site. This method requests techdocs-backend + * which retrieves the TechDocs metadata. + * + * @param {EntityName} entityId Object containing entity data like name, namespace, etc. + */ + async getTechDocsMetadata(entityId: EntityName): Promise<TechDocsMetadata> { + const { kind, namespace, name } = entityId; + + const apiOrigin = await this.getApiOrigin(); + const requestUrl = `${apiOrigin}/metadata/techdocs/${namespace}/${kind}/${name}`; + const token = await this.identityApi.getIdToken(); + + const request = await fetch(`${requestUrl}`, { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }); + const res = await request.json(); + + return res; + } + + /** + * Retrieve metadata about an entity. + * + * This method requests techdocs-backend which uses the catalog APIs to respond with filtered + * information required here. + * + * @param {EntityName} entityId Object containing entity data like name, namespace, etc. + */ + async getEntityMetadata( + entityId: EntityName, + ): Promise<TechDocsEntityMetadata> { + const { kind, namespace, name } = entityId; + + const apiOrigin = await this.getApiOrigin(); + const requestUrl = `${apiOrigin}/metadata/entity/${namespace}/${kind}/${name}`; + const token = await this.identityApi.getIdToken(); + + const request = await fetch(`${requestUrl}`, { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }); + const res = await request.json(); + + return res; + } +} + +/** + * API which talks to TechDocs storage to fetch files to render. + * + * @property {string} apiOrigin Set to techdocs.requestUrl as the URL for techdocs-backend API + */ +export class TechDocsStorageClient implements TechDocsStorageApi { + public configApi: Config; + public discoveryApi: DiscoveryApi; + public identityApi: IdentityApi; + + constructor({ + configApi, + discoveryApi, + identityApi, + }: { + configApi: Config; + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + }) { + this.configApi = configApi; + this.discoveryApi = discoveryApi; + this.identityApi = identityApi; + } + + async getApiOrigin(): Promise<string> { + return ( + this.configApi.getOptionalString('techdocs.requestUrl') ?? + (await this.discoveryApi.getBaseUrl('techdocs')) + ); + } + + async getStorageUrl(): Promise<string> { + return ( + this.configApi.getOptionalString('techdocs.storageUrl') ?? + `${await this.discoveryApi.getBaseUrl('techdocs')}/static/docs` + ); + } + + async getBuilder(): Promise<string> { + return this.configApi.getString('techdocs.builder'); + } + + /** + * Fetch HTML content as text for an individual docs page in an entity's docs site. + * + * @param {EntityName} entityId Object containing entity data like name, namespace, etc. + * @param {string} path The unique path to an individual docs page e.g. overview/what-is-new + * @returns {string} HTML content of the docs page as string + * @throws {Error} Throws error when the page is not found. + */ + async getEntityDocs(entityId: EntityName, path: string): Promise<string> { + const { kind, namespace, name } = entityId; + + const storageUrl = await this.getStorageUrl(); + const url = `${storageUrl}/${namespace}/${kind}/${name}/${path}`; + const token = await this.identityApi.getIdToken(); + + const request = await fetch( + `${url.endsWith('/') ? url : `${url}/`}index.html`, + { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }, + ); + + let errorMessage = ''; + switch (request.status) { + case 404: + errorMessage = 'Page not found. '; + // path is empty for the home page of an entity's docs site + if (!path) { + errorMessage += + 'This could be because there is no index.md file in the root of the docs directory of this repository.'; + } + throw new NotFoundError(errorMessage); + case 500: + errorMessage = + 'Could not generate documentation or an error in the TechDocs backend. '; + throw new Error(errorMessage); + default: + // Do nothing + break; + } + + return request.text(); + } + + /** + * Check if docs are on the latest version and trigger rebuild if not + * + * @param {EntityName} entityId Object containing entity data like name, namespace, etc. + * @returns {boolean} Whether documents are currently synchronized to newest version + * @throws {Error} Throws error on error from sync endpoint in Techdocs Backend + */ + async syncEntityDocs(entityId: EntityName): Promise<boolean> { + const { kind, namespace, name } = entityId; + + const apiOrigin = await this.getApiOrigin(); + const url = `${apiOrigin}/sync/${namespace}/${kind}/${name}`; + const token = await this.identityApi.getIdToken(); + let request; + let attempts: number = 0; + // retry if request times out, up to 5 times + // can happen due to docs taking too long to generate + while (!request || (request.status === 408 && attempts < 5)) { + attempts++; + request = await fetch(url, { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }); + } + + switch (request.status) { + case 404: + throw new NotFoundError((await request.json()).error); + case 200: + case 201: + case 304: + return true; + // for timeout and misc errors, handle without error to allow viewing older docs + // if older docs not available, + // Reader will show 404 error coming from getEntityDocs + case 408: + default: + return false; + } + } + + async getBaseUrl( + oldBaseUrl: string, + entityId: EntityName, + path: string, + ): Promise<string> { + const { kind, namespace, name } = entityId; + + const apiOrigin = await this.getApiOrigin(); + return new URL( + oldBaseUrl, + `${apiOrigin}/static/docs/${namespace}/${kind}/${name}/${path}`, + ).toString(); + } +} diff --git a/plugins/techdocs/src/index.ts b/plugins/techdocs/src/index.ts index b33b91e2c5..3bdf8bfec1 100644 --- a/plugins/techdocs/src/index.ts +++ b/plugins/techdocs/src/index.ts @@ -14,17 +14,20 @@ * limitations under the License. */ +export * from './api'; +export { techdocsApiRef, techdocsStorageApiRef } from './api'; +export type { TechDocsApi, TechDocsStorageApi } from './api'; +export { TechDocsClient, TechDocsStorageClient } from './client'; +export type { PanelType } from './home/components/TechDocsCustomHome'; export { - techdocsPlugin, - techdocsPlugin as plugin, - TechdocsPage, - EntityTechdocsContent, DocsCardGrid, DocsTable, + EntityTechdocsContent, TechDocsCustomHome, + TechdocsPage, + techdocsPlugin as plugin, + techdocsPlugin, TechDocsReaderPage, } from './plugin'; -export { Router, EmbeddedDocsRouter } from './Router'; export * from './reader'; -export * from './api'; -export type { PanelType } from './home/components/TechDocsCustomHome'; +export { EmbeddedDocsRouter, Router } from './Router'; diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index d9b38a2c76..97dd6f2150 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -30,21 +30,17 @@ */ import { - createPlugin, - createRouteRef, - createApiFactory, configApiRef, + createApiFactory, + createComponentExtension, + createPlugin, + createRoutableExtension, + createRouteRef, discoveryApiRef, identityApiRef, - createRoutableExtension, - createComponentExtension, } from '@backstage/core'; -import { - techdocsStorageApiRef, - TechDocsStorageApi, - techdocsApiRef, - TechDocsApi, -} from './api'; +import { techdocsApiRef, techdocsStorageApiRef } from './api'; +import { TechDocsClient, TechDocsStorageClient } from './client'; export const rootRouteRef = createRouteRef({ path: '', @@ -72,7 +68,7 @@ export const techdocsPlugin = createPlugin({ identityApi: identityApiRef, }, factory: ({ configApi, discoveryApi, identityApi }) => - new TechDocsStorageApi({ + new TechDocsStorageClient({ configApi, discoveryApi, identityApi, @@ -86,7 +82,7 @@ export const techdocsPlugin = createPlugin({ identityApi: identityApiRef, }, factory: ({ configApi, discoveryApi, identityApi }) => - new TechDocsApi({ + new TechDocsClient({ configApi, discoveryApi, identityApi, diff --git a/plugins/techdocs/src/types.ts b/plugins/techdocs/src/types.ts index 36cc4e187b..fb068bee09 100644 --- a/plugins/techdocs/src/types.ts +++ b/plugins/techdocs/src/types.ts @@ -14,7 +14,11 @@ * limitations under the License. */ +import { Entity, Location } from '@backstage/catalog-model'; + export type TechDocsMetadata = { site_name: string; site_description: string; }; + +export type TechDocsEntityMetadata = Entity & { locationMetadata?: Location }; From bf905d9bdeba84c81d7e84e4b506867e662c10ce Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 12:43:28 +0200 Subject: [PATCH 202/462] Comment out datadog configuration Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- app-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index ac59874878..3c4f2d7ea5 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -2,9 +2,9 @@ app: title: Backstage Example App baseUrl: http://localhost:3000 googleAnalyticsTrackingId: # UA-000000-0 - datadogRum: - clientToken: '123456789' - applicationId: qwerty + #datadogRum: + # clientToken: '123456789' + # applicationId: qwerty # site: # datadoghq.eu default = datadoghq.com # env: # optional From a3048a3b7fcebea0394489c1c09ff2e814336bd4 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 13:08:20 +0200 Subject: [PATCH 203/462] Fix some remaining typing issues Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .../src/reader/components/TechDocsPage.test.tsx | 15 +++++++++++++-- .../src/reader/components/TechDocsPage.tsx | 8 ++++---- .../src/reader/transformers/addBaseUrl.test.ts | 7 +++++-- .../src/reader/transformers/addBaseUrl.ts | 4 ++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx index 4b578bef38..52ddd3794e 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx @@ -51,8 +51,19 @@ describe('<TechDocsPage />', () => { }); const techdocsApi: Partial<TechDocsApi> = { - getEntityMetadata: () => Promise.resolve([]), - getTechDocsMetadata: () => Promise.resolve([]), + getEntityMetadata: () => + Promise.resolve({ + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'backstage', + }, + }), + getTechDocsMetadata: () => + Promise.resolve({ + site_name: 'string', + site_description: 'string', + }), }; const techdocsStorageApi: Partial<TechDocsStorageApi> = { getEntityDocs: (): Promise<string> => Promise.resolve('String'), diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.tsx index f2635c0dfb..c15f3a6a44 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.tsx @@ -14,13 +14,13 @@ * limitations under the License. */ +import { Content, Page, useApi } from '@backstage/core'; import React, { useState } from 'react'; import { useParams } from 'react-router-dom'; -import { Content, Page, useApi } from '@backstage/core'; -import { Reader } from './Reader'; import { useAsync } from 'react-use'; -import { TechDocsPageHeader } from './TechDocsPageHeader'; import { techdocsApiRef } from '../../api'; +import { Reader } from './Reader'; +import { TechDocsPageHeader } from './TechDocsPageHeader'; export const TechDocsPage = () => { const [documentReady, setDocumentReady] = useState<boolean>(false); @@ -33,7 +33,7 @@ export const TechDocsPage = () => { return techdocsApi.getTechDocsMetadata({ kind, namespace, name }); } - return Promise.resolve({ loading: true }); + return Promise.resolve(undefined); }, [kind, namespace, name, techdocsApi, documentReady]); const entityMetadataRequest = useAsync(() => { diff --git a/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts b/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts index 5ba86e42ca..4311de5dae 100644 --- a/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts +++ b/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts @@ -16,14 +16,17 @@ import { createTestShadowDom } from '../../test-utils'; import { addBaseUrl } from '../transformers'; -import { TechDocsStorage } from '../../api'; +import { TechDocsStorageApi } from '../../api'; const DOC_STORAGE_URL = 'https://example-host.storage.googleapis.com'; -const techdocsStorageApi: TechDocsStorage = { +const techdocsStorageApi: TechDocsStorageApi = { getBaseUrl: jest.fn(() => Promise.resolve(DOC_STORAGE_URL)), getEntityDocs: () => new Promise(resolve => resolve('yes!')), syncEntityDocs: () => new Promise(resolve => resolve(true)), + getApiOrigin: jest.fn(), + getBuilder: jest.fn(), + getStorageUrl: jest.fn(), }; const fixture = ` diff --git a/plugins/techdocs/src/reader/transformers/addBaseUrl.ts b/plugins/techdocs/src/reader/transformers/addBaseUrl.ts index 2872ad36cc..17070dcfe0 100644 --- a/plugins/techdocs/src/reader/transformers/addBaseUrl.ts +++ b/plugins/techdocs/src/reader/transformers/addBaseUrl.ts @@ -15,10 +15,10 @@ */ import { EntityName } from '@backstage/catalog-model'; import type { Transformer } from './index'; -import { TechDocsStorage } from '../../api'; +import { TechDocsStorageApi } from '../../api'; type AddBaseUrlOptions = { - techdocsStorageApi: TechDocsStorage; + techdocsStorageApi: TechDocsStorageApi; entityId: EntityName; path: string; }; From 21fddf45244e9a335411627fdbc68cac9250a9b7 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 22 Apr 2021 15:51:55 +0200 Subject: [PATCH 204/462] Rename changeset Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .../{swift-waves-sleep.md => techdocs-swift-waves-sleep.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changeset/{swift-waves-sleep.md => techdocs-swift-waves-sleep.md} (100%) diff --git a/.changeset/swift-waves-sleep.md b/.changeset/techdocs-swift-waves-sleep.md similarity index 100% rename from .changeset/swift-waves-sleep.md rename to .changeset/techdocs-swift-waves-sleep.md From 92cc589201170b05689d0c310132e3448b8b9602 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Fri, 23 Apr 2021 13:16:10 +0200 Subject: [PATCH 205/462] Remove duplicate @backstage/test-utils dependency Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- plugins/techdocs/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index e526f028d5..7bde151663 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -35,7 +35,6 @@ "@backstage/catalog-model": "^0.7.7", "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/test-utils": "^0.1.9", "@backstage/theme": "^0.2.6", "@backstage/errors": "^0.1.1", "@material-ui/core": "^4.11.0", From 38f076c0dffccfa0619de77451326fcc4f6fc4ff Mon Sep 17 00:00:00 2001 From: Eric Peterson <ericpeterson@spotify.com> Date: Fri, 23 Apr 2021 14:34:33 +0200 Subject: [PATCH 206/462] Tweak search code ownership. Signed-off-by: Eric Peterson <ericpeterson@spotify.com> --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 803ebd6445..b07519824b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,6 +16,8 @@ /plugins/search-* @backstage/techdocs-core /plugins/techdocs @backstage/techdocs-core /plugins/techdocs-backend @backstage/techdocs-core +/packages/search-common @backstage/techdocs-core /packages/techdocs-common @backstage/techdocs-core /.changeset/cost-insights-* @backstage/silver-lining +/.changeset/search-* @backstage/techdocs-core /.changeset/techdocs-* @backstage/techdocs-core From cdda9c671d500c26a58759d276d3cd9b4591a6ac Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Fri, 23 Apr 2021 15:03:32 +0200 Subject: [PATCH 207/462] move refresh loop to builder and use configured refreshInterval Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- packages/backend/src/plugins/search.ts | 7 +--- .../search-backend-node/src/IndexBuilder.ts | 37 ++++++++++--------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts index a980661c85..da7ee193b4 100644 --- a/packages/backend/src/plugins/search.ts +++ b/packages/backend/src/plugins/search.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useHotCleanup } from '@backstage/backend-common'; import { createRouter } from '@backstage/plugin-search-backend'; import { IndexBuilder, @@ -35,11 +34,7 @@ export default async function createPlugin({ collator: new DefaultCatalogCollator(discovery), }); - // TODO: Move refresh loop logic into the builder. - const timerId = setInterval(() => { - indexBuilder.build(); - }, 60000); - useHotCleanup(module, () => clearInterval(timerId)); + indexBuilder.build(); return await createRouter({ engine: indexBuilder.getSearchEngine(), diff --git a/plugins/search-backend-node/src/IndexBuilder.ts b/plugins/search-backend-node/src/IndexBuilder.ts index 0f5a287037..199cb7f923 100644 --- a/plugins/search-backend-node/src/IndexBuilder.ts +++ b/plugins/search-backend-node/src/IndexBuilder.ts @@ -100,28 +100,31 @@ export class IndexBuilder { async build() { return Promise.all( Object.keys(this.collators).map(async type => { - const decorators: DocumentDecorator[] = ( - this.decorators['*'] || [] - ).concat(this.decorators[type] || []); + setInterval(async () => { + const decorators: DocumentDecorator[] = ( + this.decorators['*'] || [] + ).concat(this.decorators[type] || []); - this.logger.info( - `Collating documents for ${type} via ${this.collators[type].collate.constructor.name}`, - ); - let documents = await this.collators[type].collate.execute(); - for (let i = 0; i < decorators.length; i++) { this.logger.info( - `Decorating ${type} documents via ${decorators[i].constructor.name}`, + `Collating documents for ${type} via ${this.collators[type].collate.constructor.name}`, ); - documents = await decorators[i].execute(documents); - } + let documents = await this.collators[type].collate.execute(); + for (let i = 0; i < decorators.length; i++) { + this.logger.info( + `Decorating ${type} documents via ${decorators[i].constructor.name}`, + ); + documents = await decorators[i].execute(documents); + } - if (!documents || documents.length === 0) { - this.logger.info(`No documents for type "${type}" to index`); - return; - } + if (!documents || documents.length === 0) { + this.logger.info(`No documents for type "${type}" to index`); + return; + } - // pushing documents to index to a configured search engine. - this.searchEngine.index(type, documents); + // pushing documents to index to a configured search engine. + this.searchEngine.index(type, documents); + // refreshInterval configured in seconds, setInterval want milliseconds + }, this.collators[type].refreshInterval * 1000); }), ); } From f5ba99d61c5acc77b2bc7b6cc0dad0d2a6796993 Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Fri, 23 Apr 2021 15:07:12 +0200 Subject: [PATCH 208/462] add changeset Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- .changeset/odd-ads-invite.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/odd-ads-invite.md diff --git a/.changeset/odd-ads-invite.md b/.changeset/odd-ads-invite.md new file mode 100644 index 0000000000..d487df47d3 --- /dev/null +++ b/.changeset/odd-ads-invite.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-node': patch +--- + +Moved refresh loop to builder and use configured refreshInterval for each collator From 23769512a393445391f020b676ee5941ffbedcd6 Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Fri, 23 Apr 2021 15:03:30 +0200 Subject: [PATCH 209/462] Support anyOf schemas in the scaffolder template Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- .changeset/tough-planes-jump.md | 5 + .../MultistepJsonForm/schema.test.ts | 120 ++++++++++++++++++ .../components/MultistepJsonForm/schema.ts | 35 +++-- 3 files changed, 146 insertions(+), 14 deletions(-) create mode 100644 .changeset/tough-planes-jump.md diff --git a/.changeset/tough-planes-jump.md b/.changeset/tough-planes-jump.md new file mode 100644 index 0000000000..a30315e9e4 --- /dev/null +++ b/.changeset/tough-planes-jump.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Support anyOf schemas in the scaffolder template diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts index b83725c2bb..edfde0ea90 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts @@ -70,4 +70,124 @@ describe('transformSchemaToProps', () => { uiSchema: expectedUiSchema, }); }); + + it('transforms schema with anyOf fields', () => { + const inputSchema = { + type: 'object', + anyOf: [ + { + properties: { + field3: { + type: 'string', + default: 'Value 1', + 'ui:readonly': true, + }, + }, + }, + { + properties: { + field3: { + type: 'string', + default: 'Value 2', + 'ui:readonly': true, + }, + }, + }, + ], + properties: { + field1: { + type: 'object', + anyOf: [ + { + properties: { + field3: { + type: 'string', + default: 'Value 1', + 'ui:readonly': true, + }, + }, + }, + { + properties: { + field3: { + type: 'string', + default: 'Value 2', + 'ui:readonly': true, + }, + }, + }, + ], + }, + field2: { + type: 'string', + 'ui:derp': 'xerp', + }, + }, + }; + const expectedSchema = { + type: 'object', + anyOf: [ + { + properties: { + field3: { + type: 'string', + default: 'Value 1', + }, + }, + }, + { + properties: { + field3: { + type: 'string', + default: 'Value 2', + }, + }, + }, + ], + properties: { + field1: { + type: 'object', + anyOf: [ + { + properties: { + field3: { + type: 'string', + default: 'Value 1', + }, + }, + }, + { + properties: { + field3: { + type: 'string', + default: 'Value 2', + }, + }, + }, + ], + }, + field2: { + type: 'string', + }, + }, + }; + const expectedUiSchema = { + field3: { + 'ui:readonly': true, + }, + field1: { + field3: { + 'ui:readonly': true, + }, + }, + field2: { + 'ui:derp': 'xerp', + }, + }; + + expect(transformSchemaToProps(inputSchema)).toEqual({ + schema: expectedSchema, + uiSchema: expectedUiSchema, + }); + }); }); diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts index e591589bd8..c189bbf1a7 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts @@ -26,7 +26,7 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { return; } - const { properties } = schema; + const { properties, anyOf } = schema; for (const propName in schema) { if (!schema.hasOwnProperty(propName)) { @@ -39,22 +39,29 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { } } - if (!isObject(properties)) { - return; + if (isObject(properties)) { + for (const propName in properties) { + if (!properties.hasOwnProperty(propName)) { + continue; + } + + const schemaNode = properties[propName]; + if (!isObject(schemaNode)) { + continue; + } + const innerUiSchema = {}; + uiSchema[propName] = innerUiSchema; + extractUiSchema(schemaNode, innerUiSchema); + } } - for (const propName in properties) { - if (!properties.hasOwnProperty(propName)) { - continue; + if (Array.isArray(anyOf)) { + for (const schemaNode of anyOf) { + if (!isObject(schemaNode)) { + continue; + } + extractUiSchema(schemaNode, uiSchema); } - - const schemaNode = properties[propName]; - if (!isObject(schemaNode)) { - continue; - } - const innerUiSchema = {}; - uiSchema[propName] = innerUiSchema; - extractUiSchema(schemaNode, innerUiSchema); } } From 6f015b7689694bdbe2e90709b93b675cc66d9715 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 23 Apr 2021 19:38:51 +0200 Subject: [PATCH 210/462] e2e: added read tree tests to add github, gitlab and azure read URLs Signed-off-by: blam <ben@blam.sh> --- cypress/cypress.json | 2 +- cypress/src/integration/integrations.ts | 64 +++++++++++++++++-------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/cypress/cypress.json b/cypress/cypress.json index 59f7516c47..ebbbe59901 100644 --- a/cypress/cypress.json +++ b/cypress/cypress.json @@ -1,5 +1,5 @@ { - "baseUrl": "http://localhost:3000", + "baseUrl": "http://localhost:7000", "integrationFolder": "./src/integration", "supportFile": "./src/support", "fixturesFolder": "./src/fixures", diff --git a/cypress/src/integration/integrations.ts b/cypress/src/integration/integrations.ts index 839159d34e..5ee077502a 100644 --- a/cypress/src/integration/integrations.ts +++ b/cypress/src/integration/integrations.ts @@ -18,33 +18,59 @@ import 'os'; describe('Integrations', () => { describe('ReadTree', () => { - // it('should work for azure', () => { - // cy.loginAsGuest(); - - // cy.visit('/catalog-import'); - - // cy.get('input[name=url]').type( - // 'https://dev.azure.com/backstage-verification/_git/test-repo?path=%2Fnested%2F*', - // ); - - // cy.contains('Analyze').click(); - // }); - it('should work for github', () => { cy.loginAsGuest(); - cy.visit('/catalog-import'); - - cy.get('input[name=url]').type( - 'https://github.com/backstage-verification/test-repo', - ); - cy.request('/api/catalog/locations', { + cy.request('POST', '/api/catalog/locations', { target: 'https://github.com/backstage-verification/test-repo/blob/main/**/*', type: 'url', }); - cy.contains('Analyze').click(); + cy.visit('/catalog'); + cy.contains('All').click(); + cy.get('table').should('contain', 'github-repo'); + cy.get('table').should('contain', 'github-repo-nested'); + }); + + // it('should work for azure', () => { + // cy.loginAsGuest(); + + // cy.request('POST', '/api/catalog/locations', { + // target: + // 'https://dev.azure.com/backstage-verification/_git/test-repo?path=*', + // type: 'url', + // }); + // }); + + it('should work for gitlab', () => { + cy.loginAsGuest(); + + cy.request('POST', '/api/catalog/locations', { + target: + 'https://gitlab.com/backstage-verification/test-repo/-/tree/master/**/*', + type: 'url', + }); + + cy.visit('/catalog'); + cy.contains('All').click(); + cy.get('table').should('contain', 'gitlab-repo'); + cy.get('table').should('contain', 'gitlab-repo-nested'); + }); + + it('should work for bitbucket', () => { + cy.loginAsGuest(); + + cy.request('POST', '/api/catalog/locations', { + target: + 'https://bitbucket.org/backstage-verification/test-repo/src/master/**/*', + type: 'url', + }); + + cy.visit('/catalog'); + cy.contains('All').click(); + cy.get('table').should('contain', 'bitbucket-repo'); + cy.get('table').should('contain', 'bitbucket-repo-nested'); }); }); }); From 3b3bc4d120feb4d51656451b9f4830e8f10c2068 Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Fri, 23 Apr 2021 12:13:13 -0600 Subject: [PATCH 211/462] Add healthcheck to k8s doc Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- docs/deployment/k8s.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/deployment/k8s.md b/docs/deployment/k8s.md index 9dbf447740..81f7150a53 100644 --- a/docs/deployment/k8s.md +++ b/docs/deployment/k8s.md @@ -357,6 +357,14 @@ spec: name: postgres-secrets - secretRef: name: backstage-secrets + readinessProbe: + httpGet: + port: 7000 + path: /healthcheck + livenessProbe: + httpGet: + port: 7000 + path: /healthcheck ``` For production deployments, the `image` reference will usually be a full URL to From ba86f0290d7715e7c1189600fbab7d7f1b92bcc8 Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Fri, 23 Apr 2021 12:34:46 -0600 Subject: [PATCH 212/462] Comment health checks with note Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- docs/deployment/k8s.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/deployment/k8s.md b/docs/deployment/k8s.md index 81f7150a53..2c52e0e308 100644 --- a/docs/deployment/k8s.md +++ b/docs/deployment/k8s.md @@ -357,14 +357,16 @@ spec: name: postgres-secrets - secretRef: name: backstage-secrets - readinessProbe: - httpGet: - port: 7000 - path: /healthcheck - livenessProbe: - httpGet: - port: 7000 - path: /healthcheck +# Uncomment if health checks are enabled in your app: +# https://backstage.io/docs/plugins/observability#health-checks +# readinessProbe: +# httpGet: +# port: 7000 +# path: /healthcheck +# livenessProbe: +# httpGet: +# port: 7000 +# path: /healthcheck ``` For production deployments, the `image` reference will usually be a full URL to From e0c9ed759d9e6ef12ce8b04a1fe53ae77b4796f0 Mon Sep 17 00:00:00 2001 From: Phil Kuang <pkuang@factset.com> Date: Fri, 23 Apr 2021 16:18:07 -0400 Subject: [PATCH 213/462] feat(EntityLayout): add 'if' prop to Route component Signed-off-by: Phil Kuang <pkuang@factset.com> --- .changeset/small-ways-hunt.md | 6 ++ .../core/src/components/TabbedLayout/index.ts | 1 + plugins/catalog/package.json | 1 + .../EntityLayout/EntityLayout.test.tsx | 35 ++++++++++ .../components/EntityLayout/EntityLayout.tsx | 67 +++++++++++++++++-- 5 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 .changeset/small-ways-hunt.md diff --git a/.changeset/small-ways-hunt.md b/.changeset/small-ways-hunt.md new file mode 100644 index 0000000000..f0b8dc88cc --- /dev/null +++ b/.changeset/small-ways-hunt.md @@ -0,0 +1,6 @@ +--- +'@backstage/core': patch +'@backstage/plugin-catalog': patch +--- + +Add `if` prop to `EntityLayout.Route` to conditionally render tabs diff --git a/packages/core/src/components/TabbedLayout/index.ts b/packages/core/src/components/TabbedLayout/index.ts index 744b56959e..fe72b199ec 100644 --- a/packages/core/src/components/TabbedLayout/index.ts +++ b/packages/core/src/components/TabbedLayout/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { TabbedLayout } from './TabbedLayout'; +export { RoutedTabs } from './RoutedTabs'; diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index b6b306c260..d87ca5b7d9 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -33,6 +33,7 @@ "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", "@backstage/core": "^0.7.6", + "@backstage/core-api": "^0.2.17", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx index 7356ccc27b..c5b51b8334 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.test.tsx @@ -101,4 +101,39 @@ describe('EntityLayout', () => { expect(rendered.getByText('tabbed-test-title-2')).toBeInTheDocument(); expect(rendered.queryByText('tabbed-test-content-2')).toBeInTheDocument(); }); + + it('should conditionally render tabs', async () => { + const shouldRenderTab = (e: Entity) => e.metadata.name === 'my-entity'; + const shouldNotRenderTab = (e: Entity) => e.metadata.name === 'some-entity'; + + const rendered = await renderInTestApp( + <ApiProvider apis={mockApis}> + <EntityContext.Provider value={mockEntityData}> + <EntityLayout> + <EntityLayout.Route path="/" title="tabbed-test-title"> + <div>tabbed-test-content</div> + </EntityLayout.Route> + <EntityLayout.Route + path="/some-other-path" + title="tabbed-test-title-2" + if={shouldNotRenderTab} + > + <div>tabbed-test-content-2</div> + </EntityLayout.Route> + <EntityLayout.Route + path="/some-other-other-path" + title="tabbed-test-title-3" + if={shouldRenderTab} + > + <div>tabbed-test-content-3</div> + </EntityLayout.Route> + </EntityLayout> + </EntityContext.Provider> + </ApiProvider>, + ); + + expect(rendered.queryByText('tabbed-test-title')).toBeInTheDocument(); + expect(rendered.queryByText('tabbed-test-title-2')).not.toBeInTheDocument(); + expect(rendered.queryByText('tabbed-test-title-3')).toBeInTheDocument(); + }); }); diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx index 6a9fa38e73..e3a8a89b71 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx @@ -26,7 +26,7 @@ import { IconComponent, Page, Progress, - TabbedLayout, + RoutedTabs, } from '@backstage/core'; import { EntityContext, @@ -34,14 +34,70 @@ import { getEntityRelations, useEntityCompoundName, } from '@backstage/plugin-catalog-react'; -import { Box } from '@material-ui/core'; +import { attachComponentData } from '@backstage/core-api'; +import { Box, TabProps } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; -import { default as React, useContext, useState } from 'react'; +import { + default as React, + Children, + Fragment, + isValidElement, + useContext, + useState, +} from 'react'; import { useNavigate } from 'react-router'; import { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu'; import { FavouriteEntity } from '../FavouriteEntity/FavouriteEntity'; import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEntityDialog'; +type SubRoute = { + path: string; + title: string; + children: JSX.Element; + if?: (entity: Entity) => boolean; + tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>; +}; + +const Route: (props: SubRoute) => null = () => null; + +// This causes all mount points that are discovered within this route to use the path of the route itself +attachComponentData(Route, 'core.gatherMountPoints', true); + +function createSubRoutesFromChildren( + childrenProps: React.ReactNode, + entity: Entity | undefined, +): SubRoute[] { + // Directly comparing child.type with Route will not work with in + // combination with react-hot-loader in storybook + // https://github.com/gaearon/react-hot-loader/issues/304 + const routeType = ( + <Route path="" title=""> + <div /> + </Route> + ).type; + + return Children.toArray(childrenProps).flatMap(child => { + if (!isValidElement(child)) { + return []; + } + + if (child.type === Fragment) { + return createSubRoutesFromChildren(child.props.children, entity); + } + + if (child.type !== routeType) { + throw new Error('Child of EntityLayout must be an EntityLayout.Route'); + } + + const { path, title, children, if: condition, tabProps } = child.props; + if (condition && entity && !condition(entity)) { + return []; + } + + return [{ path, title, children, tabProps }]; + }); +} + const EntityLayoutTitle = ({ entity, title, @@ -139,6 +195,7 @@ export const EntityLayout = ({ const { kind, namespace, name } = useEntityCompoundName(); const { entity, loading, error } = useContext(EntityContext); + const routes = createSubRoutesFromChildren(children, entity); const { headerTitle, headerType } = headerProps( kind, namespace, @@ -175,7 +232,7 @@ export const EntityLayout = ({ {loading && <Progress />} - {entity && <TabbedLayout>{children}</TabbedLayout>} + {entity && <RoutedTabs routes={routes} />} {error && ( <Content> @@ -192,4 +249,4 @@ export const EntityLayout = ({ ); }; -EntityLayout.Route = TabbedLayout.Route; +EntityLayout.Route = Route; From d47c2628b7c35fb35376727d1cafbf3ef2266aab Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Sat, 24 Apr 2021 06:51:24 +0200 Subject: [PATCH 214/462] fix: include migrations in code-coverage-backend plugin Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- .changeset/pink-islands-help.md | 5 +++++ plugins/code-coverage-backend/package.json | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/pink-islands-help.md diff --git a/.changeset/pink-islands-help.md b/.changeset/pink-islands-help.md new file mode 100644 index 0000000000..c7672f484f --- /dev/null +++ b/.changeset/pink-islands-help.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-code-coverage-backend': patch +--- + +Include migrations diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 3fc238ce61..3ae76e3fe0 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -44,6 +44,7 @@ "xml2js": "^0.4.23" }, "files": [ - "dist" + "dist", + "migrations/**/*.{js,d.ts}" ] } From f940c3837802434cc7ae45f522a2782357eb5412 Mon Sep 17 00:00:00 2001 From: Taras <tarasm@gmail.com> Date: Sat, 24 Apr 2021 11:23:56 -0400 Subject: [PATCH 215/462] Prevent uncaught exception in download of Techdocs Azure Blob Storage publisher Signed-off-by: Taras <tarasm@gmail.com> --- .../techdocs-common/src/stages/publish/azureBlobStorage.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/techdocs-common/src/stages/publish/azureBlobStorage.ts b/packages/techdocs-common/src/stages/publish/azureBlobStorage.ts index 1a823c3d19..f6567abe49 100644 --- a/packages/techdocs-common/src/stages/publish/azureBlobStorage.ts +++ b/packages/techdocs-common/src/stages/publish/azureBlobStorage.ts @@ -221,7 +221,8 @@ export class AzureBlobStoragePublish implements PublisherBase { .on('end', () => { resolve(Buffer.concat(fileStreamChunks)); }); - }); + }) + .catch(reject); }); } From f4af06ebe339f2aeccce5a84b140b453f643033c Mon Sep 17 00:00:00 2001 From: Taras <tarasm@gmail.com> Date: Sat, 24 Apr 2021 11:34:41 -0400 Subject: [PATCH 216/462] Add changeset Signed-off-by: Taras <tarasm@gmail.com> --- .changeset/six-rocks-allow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/six-rocks-allow.md diff --git a/.changeset/six-rocks-allow.md b/.changeset/six-rocks-allow.md new file mode 100644 index 0000000000..f207654f45 --- /dev/null +++ b/.changeset/six-rocks-allow.md @@ -0,0 +1,5 @@ +--- +'@backstage/techdocs-common': patch +--- + +Gracefully handle HTTP request failures in download method of AzureBlobStorage publisher. From 15cbe6815611d15d9d993ff18a2c7491515f26a1 Mon Sep 17 00:00:00 2001 From: "Chongyang Adrian, Ke" <ftt.adrian.ke@grabtaxi.com> Date: Mon, 26 Apr 2021 11:59:51 +0800 Subject: [PATCH 217/462] fix techdocs landing page table wrong copied link Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com> --- .changeset/techdocs-mean-humans-hammer.md | 5 +++++ plugins/techdocs/src/home/components/DocsTable.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/techdocs-mean-humans-hammer.md diff --git a/.changeset/techdocs-mean-humans-hammer.md b/.changeset/techdocs-mean-humans-hammer.md new file mode 100644 index 0000000000..7697650250 --- /dev/null +++ b/.changeset/techdocs-mean-humans-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fix TechDocs landing page table wrong copied link diff --git a/plugins/techdocs/src/home/components/DocsTable.tsx b/plugins/techdocs/src/home/components/DocsTable.tsx index cb0a3b4329..5b4a337dea 100644 --- a/plugins/techdocs/src/home/components/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/DocsTable.tsx @@ -76,7 +76,7 @@ export const DocsTable = ({ <Tooltip title="Click to copy documentation link to clipboard"> <IconButton onClick={() => - copyToClipboard(`${window.location.origin}/${row.docsUrl}`) + copyToClipboard(`${window.location.href}/${row.docsUrl}`) } > <ShareIcon /> From 7e5b73d73341c872f4ec1182748a59a0a11b0b13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Apr 2021 04:34:56 +0000 Subject: [PATCH 218/462] chore(deps-dev): bump @types/supertest from 2.0.10 to 2.0.11 Bumps [@types/supertest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest) from 2.0.10 to 2.0.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/supertest) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index ba1b3bfe73..056f7257db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6727,9 +6727,9 @@ "@types/node" "*" "@types/supertest@^2.0.8": - version "2.0.10" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.10.tgz#630d79b4d82c73e043e43ff777a9ca98d457cab7" - integrity sha512-Xt8TbEyZTnD5Xulw95GLMOkmjGICrOQyJ2jqgkSjAUR3mm7pAIzSR0NFBaMcwlzVvlpCjNwbATcWWwjNiZiFrQ== + version "2.0.11" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.11.tgz#2e70f69f220bc77b4f660d72c2e1a4231f44a77d" + integrity sha512-uci4Esokrw9qGb9bvhhSVEjd6rkny/dk5PK/Qz4yxKiyppEI+dOPlNrZBahE3i+PoKFYyDxChVXZ/ysS/nrm1Q== dependencies: "@types/superagent" "*" From 43db3d6892115eded93b3e5a655889658554c0a6 Mon Sep 17 00:00:00 2001 From: Martina Iglesias Fernandez <martina@roadie.io> Date: Fri, 23 Apr 2021 19:02:01 +0200 Subject: [PATCH 219/462] [docker] Fix error in docker build Before: ``` Step 7/8 : RUN tar xzf bundle.tar.gz && rm bundle.tar.gz ---> Running in 91107ee4a847 tar (child): bundle.tar.gz: Cannot open: No such file or directory tar (child): Error is not recoverable: exiting now tar: Child returned status 2 tar: Error is not recoverable: exiting now ``` Signed-off-by: Martina Iglesias Fernandez <martina@roadie.io> --- packages/backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index 02aab45609..31231a3a4a 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -22,7 +22,7 @@ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)" # Then copy the rest of the backend bundle, along with any other files we might want. -ADD packages/backend/dist/bundle.tar.gz app-config.yaml ./ +COPY packages/backend/dist/bundle.tar.gz app-config.yaml ./ RUN tar xzf bundle.tar.gz && rm bundle.tar.gz CMD ["node", "packages/backend", "--config", "app-config.yaml"] From 8c0184a1c8858e1bc1673438ae44e0f4b94f019e Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 13:37:27 +0200 Subject: [PATCH 220/462] use timers in tests Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- plugins/search-backend-node/src/index.test.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/plugins/search-backend-node/src/index.test.ts b/plugins/search-backend-node/src/index.test.ts index 0c66db372a..86233425e7 100644 --- a/plugins/search-backend-node/src/index.test.ts +++ b/plugins/search-backend-node/src/index.test.ts @@ -54,29 +54,32 @@ describe('IndexBuilder', () => { describe('addCollator', () => { it('adds a collator', async () => { + jest.useFakeTimers(); const collatorSpy = jest.spyOn(testCollator, 'execute'); // Add a collator. testIndexBuilder.addCollator({ type: 'anything', - defaultRefreshIntervalSeconds: 600, + defaultRefreshIntervalSeconds: 6, collator: testCollator, }); // Build the index and ensure the collator was invoked. await testIndexBuilder.build(); + jest.advanceTimersByTime(6000); expect(collatorSpy).toHaveBeenCalled(); }); }); describe('addDecorator', () => { it('adds a decorator', async () => { + jest.useFakeTimers(); const decoratorSpy = jest.spyOn(testDecorator, 'execute'); // Add a collator. testIndexBuilder.addCollator({ type: 'anything', - defaultRefreshIntervalSeconds: 600, + defaultRefreshIntervalSeconds: 6, collator: testCollator, }); @@ -87,10 +90,14 @@ describe('IndexBuilder', () => { // Build the index and ensure the decorator was invoked. await testIndexBuilder.build(); + jest.advanceTimersByTime(6000); + // wait for async decorator execution + await Promise.resolve(); expect(decoratorSpy).toHaveBeenCalled(); }); it('adds a type-specific decorator', async () => { + jest.useFakeTimers(); const expectedType = 'an-expected-type'; const docFixture = { title: 'Test', @@ -105,7 +112,7 @@ describe('IndexBuilder', () => { // Add a collator. testIndexBuilder.addCollator({ type: expectedType, - defaultRefreshIntervalSeconds: 600, + defaultRefreshIntervalSeconds: 6, collator: testCollator, }); @@ -117,6 +124,9 @@ describe('IndexBuilder', () => { // Build the index and ensure the decorator was invoked. await testIndexBuilder.build(); + jest.advanceTimersByTime(6000); + // wait for async decorator execution + await Promise.resolve(); expect(decoratorSpy).toHaveBeenCalled(); expect(decoratorSpy).toHaveBeenCalledWith([docFixture]); }); @@ -136,7 +146,7 @@ describe('IndexBuilder', () => { // Add a collator. testIndexBuilder.addCollator({ type: expectedType, - defaultRefreshIntervalSeconds: 600, + defaultRefreshIntervalSeconds: 6, collator: testCollator, }); @@ -148,6 +158,7 @@ describe('IndexBuilder', () => { // Build the index and ensure the decorator was not invoked. await testIndexBuilder.build(); + jest.advanceTimersByTime(6000); expect(decoratorSpy).not.toHaveBeenCalled(); }); }); From 1c2d8436ab1af5c5424d78b8c5ac04647b3e24fe Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 13:38:15 +0200 Subject: [PATCH 221/462] change log severity from info to debug Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- plugins/search-backend-node/src/IndexBuilder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/search-backend-node/src/IndexBuilder.ts b/plugins/search-backend-node/src/IndexBuilder.ts index 199cb7f923..0fc881c262 100644 --- a/plugins/search-backend-node/src/IndexBuilder.ts +++ b/plugins/search-backend-node/src/IndexBuilder.ts @@ -105,19 +105,19 @@ export class IndexBuilder { this.decorators['*'] || [] ).concat(this.decorators[type] || []); - this.logger.info( + this.logger.debug( `Collating documents for ${type} via ${this.collators[type].collate.constructor.name}`, ); let documents = await this.collators[type].collate.execute(); for (let i = 0; i < decorators.length; i++) { - this.logger.info( + this.logger.debug( `Decorating ${type} documents via ${decorators[i].constructor.name}`, ); documents = await decorators[i].execute(documents); } if (!documents || documents.length === 0) { - this.logger.info(`No documents for type "${type}" to index`); + this.logger.debug(`No documents for type "${type}" to index`); return; } From d0b69236542f8cf31043c1f48facc74783c428d5 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Mon, 26 Apr 2021 14:05:04 +0200 Subject: [PATCH 222/462] Adjust changeset Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/techdocs-swift-waves-sleep.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/techdocs-swift-waves-sleep.md b/.changeset/techdocs-swift-waves-sleep.md index 831ecc0001..79d10931cd 100644 --- a/.changeset/techdocs-swift-waves-sleep.md +++ b/.changeset/techdocs-swift-waves-sleep.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-techdocs': patch +'@backstage/plugin-techdocs': minor --- Make `techdocsStorageApiRef` and `techdocsApiRef` use interfaces instead of the From a3f090b2f391d47c9a36e8aeb53041798a9e02ac Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 21 Apr 2021 19:58:02 +0200 Subject: [PATCH 223/462] catalog-backend: WIP EntityProvider mutation interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: blam <ben@blam.sh> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../next/DefaultCatalogProcessingEngine.ts | 15 ++-- .../src/next/DefaultLocationStore.ts | 68 ++++++++++--------- .../src/next/NextCatalogBuilder.ts | 3 +- plugins/catalog-backend/src/next/types.ts | 21 +++--- 4 files changed, 55 insertions(+), 52 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 934ab3a1cc..b423b61041 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -19,6 +19,8 @@ import { CatalogProcessingEngine, EntityProvider, EntityMessage, + EntityProviderConnection, + EntityProviderMutation, ProcessingStateManager, CatalogProcessingOrchestrator, } from './types'; @@ -27,8 +29,13 @@ import { Logger } from 'winston'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { Stitcher } from './Stitcher'; +class Connection implements EntityProviderConnection { + constructor(private readonly stateManager: ProcessingStateManager) {} + + async applyMutation(mutation: EntityProviderMutation): Promise<void> {} +} + export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { - private subscriptions: Subscription[] = []; private running: boolean = false; constructor( @@ -41,11 +48,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - const id = 'databaseProvider'; - const subscription = provider - .entityChange$() - .subscribe({ next: m => this.onNext(id, m) }); - this.subscriptions.push(subscription); + provider.connect(new Connection(this.stateManager)); } this.running = true; diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index b21fe9da02..a6b4adcca4 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -16,24 +16,29 @@ import { LocationSpec, Location } from '@backstage/catalog-model'; import { Database } from '../database'; -import { LocationStore } from './types'; +import { + LocationStore, + EntityProvider, + EntityProviderConnection, +} from './types'; import { v4 as uuidv4 } from 'uuid'; +import { locationSpecToLocationEntity } from './util'; import { ConflictError } from '@backstage/errors'; -import { Observable } from '@backstage/core'; -import ObservableImpl from 'zen-observable'; export type LocationMessage = | { all: Location[] } | { added: Location[]; removed: Location[] }; -export class DefaultLocationStore implements LocationStore { - private subscribers = new Set< - ZenObservable.SubscriptionObserver<LocationMessage> - >(); +export class DefaultLocationStore implements LocationStore, EntityProvider { + private _connection: EntityProviderConnection | undefined; constructor(private readonly db: Database) {} createLocation(spec: LocationSpec): Promise<Location> { + if (!this.connection) { + throw new Error('location store is not initialized'); + } + return this.db.transaction(async tx => { // TODO: id should really be type and target combined and not a uuid. @@ -55,7 +60,11 @@ export class DefaultLocationStore implements LocationStore { target: spec.target, }); - this.notifyAddition(location); + await this.connection.applyMutation({ + type: 'delta', + added: [locationSpecToLocationEntity(location)], + removed: [], + }); return location; }); @@ -75,40 +84,33 @@ export class DefaultLocationStore implements LocationStore { } deleteLocation(id: string): Promise<void> { + if (!this.connection) { + throw new Error('location store is not initialized'); + } + return this.db.transaction(async tx => { const location = await this.db.location(id); if (!location) { throw new ConflictError(`No location found with id: ${id}`); } await this.db.removeLocation(tx, id); - this.notifyDeletion(location); - }); - } - - private notifyAddition(location: Location) { - for (const subscriber of this.subscribers) { - subscriber.next({ - added: [location], - removed: [], - }); - } - } - - private notifyDeletion(location: Location) { - for (const subscriber of this.subscribers) { - subscriber.next({ + await this.connection.applyMutation({ + type: 'delta', added: [], - removed: [location], + removed: [locationSpecToLocationEntity(location)], }); - } + }); } - location$(): Observable<LocationMessage> { - return new ObservableImpl<LocationMessage>(subscriber => { - this.subscribers.add(subscriber); - return () => { - this.subscribers.delete(subscriber); - }; - }); + private get connection(): EntityProviderConnection { + if (!this._connection) { + throw new Error('location store is not initialized'); + } + + return this._connection; + } + + async connect(connection: EntityProviderConnection): Promise<void> { + this._connection = connection; } } diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index c3e0a6bd9c..1796847164 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -272,11 +272,10 @@ export class NextCatalogBuilder { const entitiesCatalog = new NextEntitiesCatalog(dbClient); const locationStore = new DefaultLocationStore(db); - const dbLocationProvider = new DatabaseLocationProvider(locationStore); const stitcher = new Stitcher(dbClient, logger); const processingEngine = new DefaultCatalogProcessingEngine( logger, - [dbLocationProvider], // entityproviders + [locationStore], // entityproviders stateManager, orchestrator, stitcher, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 0aeb290224..c3854d631f 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity, EntityName, @@ -21,7 +22,6 @@ import { EntityRelationSpec, } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; -import { Observable } from '@backstage/core'; // << nooo export interface LocationEntity { apiVersion: 'backstage.io/v1alpha1'; @@ -45,20 +45,11 @@ export interface LocationService { deleteLocation(id: string): Promise<void>; } -export type EntityMessage = - | { all: Entity[] } - | { added: Entity[]; removed: EntityName[] }; - export interface LocationStore { - // extends EntityProvider createLocation(spec: LocationSpec): Promise<Location>; listLocations(): Promise<Location[]>; getLocation(id: string): Promise<Location>; deleteLocation(id: string): Promise<void>; - - location$(): Observable< - { all: Location[] } | { added: Location[]; removed: Location[] } - >; } export interface CatalogProcessingEngine { @@ -66,8 +57,16 @@ export interface CatalogProcessingEngine { stop(): Promise<void>; } +export type EntityProviderMutation = + | { type: 'full'; entities: Iterable<Entity> } + | { type: 'delta'; added: Iterable<Entity>; removed: Iterable<Entity> }; + +export interface EntityProviderConnection { + applyMutation(mutation: EntityProviderMutation): Promise<void>; +} + export interface EntityProvider { - entityChange$(): Observable<EntityMessage>; + connect(connection: EntityProviderConnection): Promise<void>; } export type EntityProcessingRequest = { From 92a4a4832beccc622f83473328555f03d094bba7 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 22 Apr 2021 19:41:40 +0200 Subject: [PATCH 224/462] chore: worked on some more of the new catalog migration with fixing deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Signed-off-by: blam <ben@blam.sh> --- .../20210302150147_refresh_state.js | 33 ++-- .../next/DefaultCatalogProcessingEngine.ts | 38 +++- .../src/next/DefaultLocationStore.ts | 4 - .../src/next/DefaultProcessingStateManager.ts | 13 +- .../src/next/database/DatabaseManager.ts | 114 +++++++++++ .../DefaultProcessingDatabase.test.ts | 31 +++ .../database/DefaultProcessingDatabase.ts | 180 +++++++++++++++++- .../src/next/database/types.ts | 17 ++ plugins/catalog-backend/src/next/types.ts | 21 +- 9 files changed, 405 insertions(+), 46 deletions(-) create mode 100644 plugins/catalog-backend/src/next/database/DatabaseManager.ts create mode 100644 plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 6abab6270b..14c75b2530 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -59,13 +59,14 @@ exports.up = async function up(knex) { .notNullable() .comment('JSON array containing all errors related to entity'); table - .dateTime('next_update_at') + .dateTime('next_update_at') // TOOD: timezone or change to epoch-millis or similar .notNullable() .comment('Timestamp of when entity should be updated'); table - .dateTime('last_discovery_at') + .dateTime('last_discovery_at') // TOOD: timezone or change to epoch-millis or similar .notNullable() .comment('The last timestamp of which this entity was discovered'); + table.index('entity_id', 'refresh_state_entity_id_idx'); table.index('entity_ref', 'refresh_state_entity_ref_idx'); table.index('next_update_at', 'refresh_state_next_update_at_idx'); }); @@ -94,38 +95,35 @@ exports.up = async function up(knex) { 'Holds edges between refresh state rows. Every time when an entity is processed and emits another entity, an edge will be stored to represent that fact. This is used to detect orphans and ultimately deletions.', ); table - .text('source_special_key') + .text('source_key') .nullable() .comment( 'When the reference source is not an entity, this is an opaque identifier for that source.', ); table - .text('source_entity_id') + .text('source_entity_ref') .nullable() - .references('entity_id') + .references('entity_ref') .inTable('refresh_state') .onDelete('CASCADE') .comment( - 'When the reference source is an entity, this is the ID of the source entity.', + 'When the reference source is an entity, this is the EntityRef of the source entity.', ); table - .text('target_entity_id') + .text('target_entity_ref') .notNullable() - .references('entity_id') + .references('entity_ref') .inTable('refresh_state') .onDelete('CASCADE') - .comment('The ID of the target entity.'); + .comment('The EntityRef of the target entity.'); + table.index('source_key', 'refresh_state_references_source_key_idx'); table.index( - 'source_special_key', - 'refresh_state_references_source_special_key_idx', + 'source_entity_ref', + 'refresh_state_references_source_entity_ref_idx', ); table.index( - 'source_entity_id', - 'refresh_state_references_source_entity_id_idx', - ); - table.index( - 'target_entity_id', - 'refresh_state_references_target_entity_id_idx', + 'target_entity_ref', + 'refresh_state_references_target_entity_ref_idx', ); }); @@ -165,6 +163,7 @@ exports.down = async function down(knex) { table.dropIndex([], 'refresh_state_references_target_entity_id_idx'); }); await knex.schema.alterTable('refresh_state', table => { + table.dropIndex([], 'refresh_state_entity_id_idx'); table.dropIndex([], 'refresh_state_entity_ref_idx'); table.dropIndex([], 'refresh_state_next_update_at_idx'); }); diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index b423b61041..7f49bf832d 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -30,9 +30,31 @@ import { stringifyEntityRef } from '@backstage/catalog-model'; import { Stitcher } from './Stitcher'; class Connection implements EntityProviderConnection { - constructor(private readonly stateManager: ProcessingStateManager) {} + constructor( + private readonly config: { + stateManager: ProcessingStateManager; + id: string; + }, + ) {} - async applyMutation(mutation: EntityProviderMutation): Promise<void> {} + async applyMutation(mutation: EntityProviderMutation): Promise<void> { + if (mutation.type === 'full') { + await this.config.stateManager.replaceProcessingItems({ + id: this.config.id, + type: 'full', + items: mutation.entities, + }); + + return; + } + + await this.config.stateManager.replaceProcessingItems({ + id: this.config.id, + type: 'delta', + added: mutation.added, + removed: mutation.removed, + }); + } } export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { @@ -48,7 +70,9 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - provider.connect(new Connection(this.stateManager)); + // TODO: this ID should be some form of identifier for the EntityProvider + const id = 'databaseProvider'; + provider.connect(new Connection({ stateManager: this.stateManager, id })); } this.running = true; @@ -57,12 +81,12 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { const { id, entity, - state: intialState, + state: initialState, } = await this.stateManager.getNextProcessingItem(); const result = await this.orchestrator.process({ entity, - state: intialState, + state: initialState, }); for (const error of result.errors) { @@ -95,10 +119,6 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async stop() { this.running = false; - - for (const subscription of this.subscriptions) { - subscription.unsubscribe(); - } } private async onNext(id: string, message: EntityMessage) { diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index a6b4adcca4..dff424b1a9 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -35,10 +35,6 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { constructor(private readonly db: Database) {} createLocation(spec: LocationSpec): Promise<Location> { - if (!this.connection) { - throw new Error('location store is not initialized'); - } - return this.db.transaction(async tx => { // TODO: id should really be type and target combined and not a uuid. diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index 91090bc139..d2765c3101 100644 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -17,14 +17,23 @@ import { ProcessingDatabase, RefreshStateItem } from './database/types'; import { AddProcessingItemRequest, - ProccessingItem, + ProcessingItem, ProcessingItemResult, ProcessingStateManager, + ReplaceProcessingItemsRequest, } from './types'; export class DefaultProcessingStateManager implements ProcessingStateManager { constructor(private readonly db: ProcessingDatabase) {} + replaceProcessingItems( + request: ReplaceProcessingItemsRequest, + ): Promise<void> { + return this.db.transaction(async tx => { + await this.db.replaceUnprocessedEntities(tx, request); + }); + } + async setProcessingItemResult(result: ProcessingItemResult) { return this.db.transaction(async tx => { await this.db.updateProcessedEntity(tx, { @@ -44,7 +53,7 @@ export class DefaultProcessingStateManager implements ProcessingStateManager { }); } - async getNextProcessingItem(): Promise<ProccessingItem> { + async getNextProcessingItem(): Promise<ProcessingItem> { const entities = await new Promise<RefreshStateItem[]>(resolve => this.popFromQueue(resolve), ); diff --git a/plugins/catalog-backend/src/next/database/DatabaseManager.ts b/plugins/catalog-backend/src/next/database/DatabaseManager.ts new file mode 100644 index 0000000000..4c9e45950f --- /dev/null +++ b/plugins/catalog-backend/src/next/database/DatabaseManager.ts @@ -0,0 +1,114 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger, resolvePackagePath } from '@backstage/backend-common'; +import knexFactory, { Knex } from 'knex'; +import { v4 as uuidv4 } from 'uuid'; +import { Logger } from 'winston'; +import { CommonDatabase } from '../../database/CommonDatabase'; +import { Database } from '../../database/types'; +import fs from 'fs-extra'; + +export type CreateDatabaseOptions = { + logger: Logger; +}; + +const defaultOptions: CreateDatabaseOptions = { + logger: getVoidLogger(), +}; + +export class DatabaseManager { + public static async createDatabase( + knex: Knex, + options: Partial<CreateDatabaseOptions> = {}, + ): Promise<Database> { + const allMigrations = resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrations', + ); + + const migrationsDir = resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrationsv2', + ); + await fs.copy(allMigrations, migrationsDir); + + await knex.migrate.latest({ + directory: migrationsDir, + }); + const { logger } = { ...defaultOptions, ...options }; + return new CommonDatabase(knex, logger); + } + + public static async createInMemoryDatabase(): Promise<Database> { + const knex = await this.createInMemoryDatabaseConnection(); + return await this.createDatabase(knex); + } + + public static async createInMemoryDatabaseConnection(): Promise<Knex> { + const knex = knexFactory({ + client: 'sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }); + + knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { + resource.run('PRAGMA foreign_keys = ON', () => {}); + }); + + return knex; + } + + public static async createTestDatabase(): Promise<Database> { + const knex = await this.createTestDatabaseConnection(); + return await this.createDatabase(knex); + } + + public static async createTestDatabaseConnection(): Promise<Knex> { + const config: Knex.Config<any> = { + /* + client: 'pg', + connection: { + host: 'localhost', + user: 'postgres', + password: 'postgres', + }, + */ + client: 'sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }; + + let knex = knexFactory(config); + if (typeof config.connection !== 'string') { + const tempDbName = `d${uuidv4().replace(/-/g, '')}`; + await knex.raw(`CREATE DATABASE ${tempDbName};`); + knex = knexFactory({ + ...config, + connection: { + ...config.connection, + database: tempDbName, + }, + }); + } + + knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { + resource.run('PRAGMA foreign_keys = ON', () => {}); + }); + + return knex; + } +} diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts new file mode 100644 index 0000000000..fd2e9e6750 --- /dev/null +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// import { DefaultProcessingDatabase } from './DefaultProcessingDatabase'; +import { DatabaseManager } from './DatabaseManager'; +import { Knex } from 'knex'; + +describe('Default Processing Database', () => { + let db: Knex | undefined; + + beforeEach(async () => { + db = await DatabaseManager.createTestDatabaseConnection(); + await DatabaseManager.createDatabase(db); + }); + + it('should write some stuff', async () => { + await db('refresh_state_referencess').select(); + }); +}); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index cf2d4e121c..b799bd6284 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -15,6 +15,7 @@ */ import { ConflictError, NotFoundError } from '@backstage/errors'; +import { stringifyEntityRef, Entity } from '@backstage/catalog-model'; import { Knex } from 'knex'; import { Transaction } from '../../database'; import lodash from 'lodash'; @@ -24,20 +25,21 @@ import { AddUnprocessedEntitiesOptions, UpdateProcessedEntityOptions, GetProcessableEntitiesResult, + ReplaceUnprocessedEntitiesOptions, } from './types'; import type { Logger } from 'winston'; -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; + import { v4 as uuid } from 'uuid'; export type DbRefreshStateRow = { entity_id: string; entity_ref: string; unprocessed_entity: string; - processed_entity: string; - cache: string; + processed_entity?: string; + cache?: string; next_update_at: string; last_discovery_at: string; // remove? - errors: string; + errors?: string; }; export type DbRelationsRow = { @@ -47,10 +49,10 @@ export type DbRelationsRow = { type: string; }; -export type DbRefreshStateReferences = { - source_special_key?: string; - source_entity_id?: string; - target_entity_id: string; +export type DbRefreshStateReferencesRow = { + source_key?: string; + source_entity_ref?: string; + target_entity_ref: string; }; // The number of items that are sent per batch to the database layer, when @@ -128,6 +130,164 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ); } + async replaceUnprocessedEntities( + txOpaque: Transaction, + options: ReplaceUnprocessedEntitiesOptions, + ): Promise<void> { + const tx = txOpaque as Knex.Transaction; + const entityIds = new Array<string>(); + + if (options.type === 'full') { + const oldRefs = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .where({ source_key: options.sourceKey }) + .select('target_entity_ref') + .then(rows => rows.map(r => r.target_entity_ref)); + + const items = options.items.map(entity => ({ + entity, + ref: stringifyEntityRef(entity), + id: uuid(), + })); + + const oldRefsSet = new Set(oldRefs); + const newRefsSet = new Set(items.map(item => item.ref)); + const toAdd = items.filter(item => !oldRefsSet.has(item.ref)); + const toRemove = oldRefs.filter(ref => !newRefsSet.has(ref)); + + if (toRemove.length) { + // TODO(freben): Batch split, to not hit variable limits? + + // get all refs where source = any of the toRemove + // delete all state rows matching any of the toRemove + // revisit the targets of all of those refs + // verify if they have references, otherwise delete from refresh_state + + const current = [...toRemove]; + while (true) { + + tx.withRecursive('r', function refs() { + return tx.select({ }) + .from({ r1: 'refresh_state_references' }) + .where({ source_key: options.sourceKey }) + .whereIn('target_entity_ref', toRemove) + .unionAll(function recurse() { + return tx.select({ }) + .from({ r2: 'refresh_state_references' }) + .whereNotExists() + }) + }) + .select().from('refs'); + + const nextLayerToRemove = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .whereIn('source_entity_ref', toRemove) + .leftOuterJoin('refresh_state_references AS b', function f() { + + }) + + .whereNotNull('b.source_target_ref') + .select('target_entity_ref'); + + await tx<DbRefreshStateRow>('refresh_state') + .whereIn('entity_ref', toRemove) + .delete(); + + const refsThatStillHaveASourcePointingAtThe = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .whereIn('target_entity_ref', nextLayerTargetRefs) + .groupBy('target_entity_ref') + .select('target_entity_ref'); + + } + + + + + if (toAdd.length) { + const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(item => ({ + entity_id: item.id, + entity_ref: item.ref, + unprocessed_entity: JSON.stringify(item.entity), + errors: '', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + })); + const stateReferences: DbRefreshStateReferencesRow[] = toAdd.map( + item => ({ + source_key: options.sourceKey, + target_entity_ref: item.ref, + }), + ); + // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense + await tx.batchInsert('refresh_state', state, BATCH_SIZE); + await tx.batchInsert('refresh_state_references', stateReferences, BATCH_SIZE); + } + + + for (const entity of options.items) { + const entityRef = stringifyEntityRef(entity); + await tx<DbRefreshStateRow>('refresh_state') + .insert({ + entity_id: uuid(), + entity_ref: entityRef, + unprocessed_entity: JSON.stringify(entity), + errors: '', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + }) + .onConflict('entity_ref') + .merge(['unprocessed_entity', 'last_discovery_at']); + + const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( + 'refresh_state', + ).where({ entity_ref: entityRef }); + entityIds.push(entityId); + } + const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( + entityId => ({ + source_key: options.sourceKey, + target_entityRef: entityRef, + }), + ); + await tx.batchInsert( + 'refresh_state_references', + referenceRows, + BATCH_SIZE, + ); + return; + } + + for (const entity of options.removed) { + const entityRef = stringifyEntityRef(entity); + const [result] = await tx<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: entityRef }) + .select('entity_id'); + + if (!result) { + this.logger.info( + `Unable to delete entity '${entityRef}', entity does not exist in refresh state`, + ); + continue; + } + + const referenceResults = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + // todo correct key? + .where({ source_entity_id: result.entity_id }) + .select(); + + await tx<DbRefreshStateReferencesRow>('refresh_state_references') + // todo correct key? + .where({ source_entity_id: result.entity_id }) + .delete(); + } + } + async addUnprocessedEntities( txOpaque: Transaction, options: AddUnprocessedEntitiesOptions, @@ -160,11 +320,11 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ? { source_special_key: options.id } : { source_entity_id: options.id }; // copied from update refs - await tx<DbRefreshStateReferences>('refresh_state_references') + await tx<DbRefreshStateReferencesRow>('refresh_state_references') .where(key) .delete(); - const referenceRows: DbRefreshStateReferences[] = entityIds.map( + const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( entityId => ({ ...key, target_entity_id: entityId, diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index 22e9e90c8e..b926676887 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -50,6 +50,19 @@ export type GetProcessableEntitiesResult = { items: RefreshStateItem[]; }; +export type ReplaceUnprocessedEntitiesOptions = + | { + sourceKey: string; + items: Entity[]; + type: 'full'; + } + | { + sourceKey: string; + added: Entity[]; + removed: Entity[]; + type: 'delta'; + }; + export interface ProcessingDatabase { transaction<T>(fn: (tx: Transaction) => Promise<T>): Promise<T>; @@ -58,6 +71,10 @@ export interface ProcessingDatabase { options: AddUnprocessedEntitiesOptions, ): Promise<void>; + replaceUnprocessedEntities( + txOpaque: Transaction, + options: ReplaceUnprocessedEntitiesOptions, + ): Promise<void>; getProcessableEntities( txOpaque: Transaction, request: { processBatchSize: number }, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index c3854d631f..f8b4de1c41 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -58,8 +58,8 @@ export interface CatalogProcessingEngine { } export type EntityProviderMutation = - | { type: 'full'; entities: Iterable<Entity> } - | { type: 'delta'; added: Iterable<Entity>; removed: Iterable<Entity> }; + | { type: 'full'; entities: Entity[] } + | { type: 'delta'; added: Entity[]; removed: Entity[] }; export interface EntityProviderConnection { applyMutation(mutation: EntityProviderMutation): Promise<void>; @@ -108,14 +108,27 @@ export type AddProcessingItemRequest = { entities: Entity[]; }; -export type ProccessingItem = { +export type ProcessingItem = { id: string; entity: Entity; state: Map<string, JsonObject>; }; +export type ReplaceProcessingItemsRequest = + | { + id: string; + items: Entity[]; + type: 'full'; + } + | { + id: string; + added: Entity[]; + removed: Entity[]; + type: 'delta'; + }; export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise<void>; - getNextProcessingItem(): Promise<ProccessingItem>; + getNextProcessingItem(): Promise<ProcessingItem>; addProcessingItems(request: AddProcessingItemRequest): Promise<void>; + replaceProcessingItems(request: ReplaceProcessingItemsRequest): Promise<void>; } From f62db5992f7b9ba66dbcb291a9d88ab1264aca07 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 23 Apr 2021 15:05:04 +0200 Subject: [PATCH 225/462] feat: added support for full sync replace with an awesome sql statement courtesy of @freben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Signed-off-by: blam <ben@blam.sh> --- .../20210302150147_refresh_state.js | 3 + .../DefaultProcessingDatabase.test.ts | 271 +++++++++++++++++- .../database/DefaultProcessingDatabase.ts | 220 +++++++------- 3 files changed, 390 insertions(+), 104 deletions(-) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 14c75b2530..2afeda02c0 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -94,6 +94,9 @@ exports.up = async function up(knex) { table.comment( 'Holds edges between refresh state rows. Every time when an entity is processed and emits another entity, an edge will be stored to represent that fact. This is used to detect orphans and ultimately deletions.', ); + table + .increments('id') + .comment('Primary key to distinguish unique lines from each other'); table .text('source_key') .nullable() diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index fd2e9e6750..ee04a2baf8 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -16,16 +16,283 @@ // import { DefaultProcessingDatabase } from './DefaultProcessingDatabase'; import { DatabaseManager } from './DatabaseManager'; import { Knex } from 'knex'; +import { + DbRefreshStateReferencesRow, + DbRefreshStateRow, + DefaultProcessingDatabase, +} from './DefaultProcessingDatabase'; + +import { Entity } from '@backstage/catalog-model'; +import * as uuid from 'uuid'; +import { getVoidLogger } from '@backstage/backend-common'; describe('Default Processing Database', () => { let db: Knex | undefined; + let processingDatabase: DefaultProcessingDatabase | undefined; + + const logger = getVoidLogger(); beforeEach(async () => { db = await DatabaseManager.createTestDatabaseConnection(); await DatabaseManager.createDatabase(db); + + processingDatabase = new DefaultProcessingDatabase(db!, logger); }); - it('should write some stuff', async () => { - await db('refresh_state_referencess').select(); + describe('replaceUnprocessedEntities', () => { + const insertRefRow = async (ref: DbRefreshStateReferencesRow) => { + return db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).insert(ref); + }; + + const insertRefreshStateRow = async (ref: DbRefreshStateRow) => { + await db!<DbRefreshStateRow>('refresh_state').insert(ref); + }; + + const createLocations = async (entityRefs: string[]) => { + for (const ref of entityRefs) { + await insertRefreshStateRow({ + entity_id: uuid.v4(), + entity_ref: ref, + unprocessed_entity: '{}', + processed_entity: '{}', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + } + }; + + it('replaces all existing state correctly for simple dependency chains', async () => { + /* + config -> location:default/root -> location:default/root-1 -> location:default/root-2 + database -> location:default/second -> location:default/root-2 + */ + await createLocations([ + 'location:default/root', + 'location:default/root-1', + 'location:default/root-2', + 'location:default/second', + ]); + + await insertRefRow({ + source_key: 'config', + target_entity_ref: 'location:default/root', + }); + + await insertRefRow({ + source_key: 'database', + target_entity_ref: 'location:default/second', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root', + target_entity_ref: 'location:default/root-1', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root-1', + target_entity_ref: 'location:default/root-2', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/second', + target_entity_ref: 'location:default/root-2', + }); + + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'full', + sourceKey: 'config', + items: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + for (const ref of ['location:default/root', 'location:default/root-1']) { + expect(currentRefreshState.some(t => t.entity_ref === ref)).toBeFalsy(); + } + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root' && + t.target_entity_ref === 'location:default/root-1', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root-1' && + t.target_entity_ref === 'location:default/root-2', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.target_entity_ref === 'location:default/root-1' && + t.source_key === 'config', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.target_entity_ref === 'location:default/new-root' && + t.source_key === 'config', + ), + ).toBeTruthy(); + }); + + it('should work for more complex chains', async () => { + /* + config -> location:default/root -> location:default/root-1 -> location:default/root-2 + config -> location:default/root -> location:default/root-1a -> location:default/root-2 + */ + await createLocations([ + 'location:default/root', + 'location:default/root-1', + 'location:default/root-2', + 'location:default/root-1a', + ]); + + await insertRefRow({ + source_key: 'config', + target_entity_ref: 'location:default/root', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root', + target_entity_ref: 'location:default/root-1', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root', + target_entity_ref: 'location:default/root-1a', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root-1', + target_entity_ref: 'location:default/root-2', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root-1a', + target_entity_ref: 'location:default/root-2', + }); + + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'full', + sourceKey: 'config', + items: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + const deletedRefs = [ + 'location:default/root', + 'location:default/root-1', + 'location:default/root-1a', + 'location:default/root-2', + ]; + + for (const ref of deletedRefs) { + expect(currentRefreshState.some(t => t.entity_ref === ref)).toBeFalsy(); + } + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'config' && + t.target_entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'config' && + t.target_entity_ref === 'location:default/root', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root' && + t.target_entity_ref === 'location:default/root-1', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root' && + t.target_entity_ref === 'location:default/root-1a', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root-1' && + t.target_entity_ref === 'location:default/root-2', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root-1a' && + t.target_entity_ref === 'location:default/root-2', + ), + ).toBeFalsy(); + }); }); }); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index b799bd6284..f0c5443651 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -135,7 +135,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { options: ReplaceUnprocessedEntitiesOptions, ): Promise<void> { const tx = txOpaque as Knex.Transaction; - const entityIds = new Array<string>(); if (options.type === 'full') { const oldRefs = await tx<DbRefreshStateReferencesRow>( @@ -158,55 +157,95 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { if (toRemove.length) { // TODO(freben): Batch split, to not hit variable limits? - - // get all refs where source = any of the toRemove - // delete all state rows matching any of the toRemove - // revisit the targets of all of those refs - // verify if they have references, otherwise delete from refresh_state - - const current = [...toRemove]; - while (true) { - - tx.withRecursive('r', function refs() { - return tx.select({ }) - .from({ r1: 'refresh_state_references' }) - .where({ source_key: options.sourceKey }) - .whereIn('target_entity_ref', toRemove) - .unionAll(function recurse() { - return tx.select({ }) - .from({ r2: 'refresh_state_references' }) - .whereNotExists() - }) + /* + WITH RECURSIVE + -- All the refs that can be reached from each individual root + root_reach(id, entity_ref) AS ( + -- Start with all roots + SELECT id, target_entity_ref + FROM refresh_state_references + WHERE source_key IS NOT NULL + UNION + -- For each match, select all children + SELECT root_reach.id, target_entity_ref + FROM refresh_state_references, root_reach + WHERE source_entity_ref = root_reach.entity_ref + ) + -- Start out with our own matching row (see the WHERE that + -- matches on source_key and target_entity_ref below) + SELECT us.entity_ref + FROM refresh_state_references + -- Expand the entire tree that emanates from that row + JOIN root_reach AS us + ON us.id = refresh_state_references.id + -- Expand with all roots that target the same node but + -- aren't ourselves + LEFT OUTER JOIN root_reach AS them + ON them.entity_ref = us.entity_ref + AND them.id != us.id + -- Keep only the matches that had no other rooots + WHERE refresh_state_references.source_key = "R1" + AND refresh_state_references.target_entity_ref = "A" + AND them.id IS NULL; + */ + const removedCount = await tx<DbRefreshStateRow>('refresh_state') + .whereIn('entity_ref', function orphanedEntityRefs(orphans) { + return ( + orphans + // All the refs that can be reached from each individual root + .withRecursive('root_reach', function rootReach(outer) { + // Start with all roots + return outer + .select({ id: 'id', entity_ref: 'target_entity_ref' }) + .from('refresh_state_references') + .whereNotNull('source_key') + .union(function recurse(inner) { + return ( + inner + // For each match, select all children + .select({ + id: 'root_reach.id', + entity_ref: + 'refresh_state_references.target_entity_ref', + }) + .from('refresh_state_references') + .crossJoin('root_reach', { + 'root_reach.entity_ref': + 'refresh_state_references.source_entity_ref', + }) + ); + }); + }) + .select('us.entity_ref') + // Start out with our own matching row + .from('refresh_state_references') + .where('source_key', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + // Expand the entire tree that emanates from that row + .leftJoin({ us: 'root_reach' }, function us() { + this.on('us.id', '=', 'refresh_state_references.id'); + }) + // Expand with all roots that target the same node but aren't ourselves + .leftOuterJoin({ them: 'root_reach' }, function them() { + this.on('them.entity_ref', '=', 'us.entity_ref'); + this.andOn('them.id', '!=', 'us.id'); + }) + // Keep only the matches that had no other rooots + .whereNull('them.id') + ); }) - .select().from('refs'); + .delete(); - const nextLayerToRemove = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .whereIn('source_entity_ref', toRemove) - .leftOuterJoin('refresh_state_references AS b', function f() { - - }) - - .whereNotNull('b.source_target_ref') - .select('target_entity_ref'); - - await tx<DbRefreshStateRow>('refresh_state') - .whereIn('entity_ref', toRemove) - .delete(); - - const refsThatStillHaveASourcePointingAtThe = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .whereIn('target_entity_ref', nextLayerTargetRefs) - .groupBy('target_entity_ref') - .select('target_entity_ref'); + await tx<DbRefreshStateReferencesRow>('refresh_state_references') + .where('source_key', '=', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + .delete(); + console.log( + `REMOVED, ${removedCount} entities: ${JSON.stringify(toRemove)}`, + ); } - - - if (toAdd.length) { const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(item => ({ entity_id: item.id, @@ -224,67 +263,44 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ); // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense await tx.batchInsert('refresh_state', state, BATCH_SIZE); - await tx.batchInsert('refresh_state_references', stateReferences, BATCH_SIZE); - } - - - for (const entity of options.items) { - const entityRef = stringifyEntityRef(entity); - await tx<DbRefreshStateRow>('refresh_state') - .insert({ - entity_id: uuid(), - entity_ref: entityRef, - unprocessed_entity: JSON.stringify(entity), - errors: '', - next_update_at: tx.fn.now(), - last_discovery_at: tx.fn.now(), - }) - .onConflict('entity_ref') - .merge(['unprocessed_entity', 'last_discovery_at']); - - const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( - 'refresh_state', - ).where({ entity_ref: entityRef }); - entityIds.push(entityId); - } - const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( - entityId => ({ - source_key: options.sourceKey, - target_entityRef: entityRef, - }), - ); - await tx.batchInsert( - 'refresh_state_references', - referenceRows, - BATCH_SIZE, - ); - return; - } - - for (const entity of options.removed) { - const entityRef = stringifyEntityRef(entity); - const [result] = await tx<DbRefreshStateRow>('refresh_state') - .where({ entity_ref: entityRef }) - .select('entity_id'); - - if (!result) { - this.logger.info( - `Unable to delete entity '${entityRef}', entity does not exist in refresh state`, + await tx.batchInsert( + 'refresh_state_references', + stateReferences, + BATCH_SIZE, ); - continue; } - const referenceResults = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - // todo correct key? - .where({ source_entity_id: result.entity_id }) - .select(); + // for (const entity of options.items) { + // const entityRef = stringifyEntityRef(entity); + // await tx<DbRefreshStateRow>('refresh_state') + // .insert({ + // entity_id: uuid(), + // entity_ref: entityRef, + // unprocessed_entity: JSON.stringify(entity), + // errors: '', + // next_update_at: tx.fn.now(), + // last_discovery_at: tx.fn.now(), + // }) + // .onConflict('entity_ref') + // .merge(['unprocessed_entity', 'last_discovery_at']); - await tx<DbRefreshStateReferencesRow>('refresh_state_references') - // todo correct key? - .where({ source_entity_id: result.entity_id }) - .delete(); + // const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( + // 'refresh_state', + // ).where({ entity_ref: entityRef }); + // entityIds.push(entityId); + // } + // const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( + // entityId => ({ + // source_key: options.sourceKey, + // target_entityRef: entityRef, + // }), + // ); + // await tx.batchInsert( + // 'refresh_state_references', + // referenceRows, + // BATCH_SIZE, + // ); + // return; } } From 6e545108e7418ee0bd9f57678f59f1a14e27f9be Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 23 Apr 2021 16:01:36 +0200 Subject: [PATCH 226/462] feat: support delta and full sync with the same code and simplify things MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Signed-off-by: blam <ben@blam.sh> --- .../DefaultProcessingDatabase.test.ts | 89 +++++++ .../database/DefaultProcessingDatabase.ts | 242 ++++++++---------- 2 files changed, 201 insertions(+), 130 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index ee04a2baf8..c4784c081d 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -294,5 +294,94 @@ describe('Default Processing Database', () => { ), ).toBeFalsy(); }); + + it('should add new locations using the delta options', async () => { + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'delta', + sourceKey: 'lols', + removed: [], + added: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'lols' && + t.target_entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + }); + + it('should remove old locations using the delta options', async () => { + await createLocations(['location:default/new-root']); + + await insertRefRow({ + source_key: 'lols', + target_entity_ref: 'location:default/new-root', + }); + + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'delta', + sourceKey: 'lols', + added: [], + removed: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'lols' && + t.target_entity_ref === 'location:default/new-root', + ), + ).toBeFalsy(); + }); }); }); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index f0c5443651..a80325d469 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -130,34 +130,48 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ); } + private async createDelta( + tx: Knex.Transaction, + options: ReplaceUnprocessedEntitiesOptions, + ): Promise<{ toAdd: Entity[]; toRemove: string[] }> { + if (options.type === 'delta') { + return { + toAdd: options.added, + toRemove: options.removed.map(e => stringifyEntityRef(e)), + }; + } + + const oldRefs = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .where({ source_key: options.sourceKey }) + .select('target_entity_ref') + .then(rows => rows.map(r => r.target_entity_ref)); + + const items = options.items.map(entity => ({ + entity, + ref: stringifyEntityRef(entity), + })); + + const oldRefsSet = new Set(oldRefs); + const newRefsSet = new Set(items.map(item => item.ref)); + const toAdd = items.filter(item => !oldRefsSet.has(item.ref)); + const toRemove = oldRefs.filter(ref => !newRefsSet.has(ref)); + + return { toAdd: toAdd.map(({ entity }) => entity), toRemove }; + } + async replaceUnprocessedEntities( txOpaque: Transaction, options: ReplaceUnprocessedEntitiesOptions, ): Promise<void> { const tx = txOpaque as Knex.Transaction; - if (options.type === 'full') { - const oldRefs = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .where({ source_key: options.sourceKey }) - .select('target_entity_ref') - .then(rows => rows.map(r => r.target_entity_ref)); + const { toAdd, toRemove } = await this.createDelta(tx, options); - const items = options.items.map(entity => ({ - entity, - ref: stringifyEntityRef(entity), - id: uuid(), - })); - - const oldRefsSet = new Set(oldRefs); - const newRefsSet = new Set(items.map(item => item.ref)); - const toAdd = items.filter(item => !oldRefsSet.has(item.ref)); - const toRemove = oldRefs.filter(ref => !newRefsSet.has(ref)); - - if (toRemove.length) { - // TODO(freben): Batch split, to not hit variable limits? - /* + if (toRemove.length) { + // TODO(freben): Batch split, to not hit variable limits? + /* WITH RECURSIVE -- All the refs that can be reached from each individual root root_reach(id, entity_ref) AS ( @@ -188,119 +202,87 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { AND refresh_state_references.target_entity_ref = "A" AND them.id IS NULL; */ - const removedCount = await tx<DbRefreshStateRow>('refresh_state') - .whereIn('entity_ref', function orphanedEntityRefs(orphans) { - return ( - orphans - // All the refs that can be reached from each individual root - .withRecursive('root_reach', function rootReach(outer) { - // Start with all roots - return outer - .select({ id: 'id', entity_ref: 'target_entity_ref' }) - .from('refresh_state_references') - .whereNotNull('source_key') - .union(function recurse(inner) { - return ( - inner - // For each match, select all children - .select({ - id: 'root_reach.id', - entity_ref: - 'refresh_state_references.target_entity_ref', - }) - .from('refresh_state_references') - .crossJoin('root_reach', { - 'root_reach.entity_ref': - 'refresh_state_references.source_entity_ref', - }) - ); - }); - }) - .select('us.entity_ref') - // Start out with our own matching row - .from('refresh_state_references') - .where('source_key', options.sourceKey) - .whereIn('target_entity_ref', toRemove) - // Expand the entire tree that emanates from that row - .leftJoin({ us: 'root_reach' }, function us() { - this.on('us.id', '=', 'refresh_state_references.id'); - }) - // Expand with all roots that target the same node but aren't ourselves - .leftOuterJoin({ them: 'root_reach' }, function them() { - this.on('them.entity_ref', '=', 'us.entity_ref'); - this.andOn('them.id', '!=', 'us.id'); - }) - // Keep only the matches that had no other rooots - .whereNull('them.id') - ); - }) - .delete(); + const removedCount = await tx<DbRefreshStateRow>('refresh_state') + .whereIn('entity_ref', function orphanedEntityRefs(orphans) { + return ( + orphans + // All the refs that can be reached from each individual root + .withRecursive('root_reach', function rootReach(outer) { + // Start with all roots + return outer + .select({ id: 'id', entity_ref: 'target_entity_ref' }) + .from('refresh_state_references') + .whereNotNull('source_key') + .union(function recurse(inner) { + return ( + inner + // For each match, select all children + .select({ + id: 'root_reach.id', + entity_ref: + 'refresh_state_references.target_entity_ref', + }) + .from('refresh_state_references') + .crossJoin('root_reach', { + 'root_reach.entity_ref': + 'refresh_state_references.source_entity_ref', + }) + ); + }); + }) + .select('us.entity_ref') + // Start out with our own matching row + .from('refresh_state_references') + .where('source_key', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + // Expand the entire tree that emanates from that row + .leftJoin({ us: 'root_reach' }, function us() { + this.on('us.id', '=', 'refresh_state_references.id'); + }) + // Expand with all roots that target the same node but aren't ourselves + .leftOuterJoin({ them: 'root_reach' }, function them() { + this.on('them.entity_ref', '=', 'us.entity_ref'); + this.andOn('them.id', '!=', 'us.id'); + }) + // Keep only the matches that had no other rooots + .whereNull('them.id') + ); + }) + .delete(); - await tx<DbRefreshStateReferencesRow>('refresh_state_references') - .where('source_key', '=', options.sourceKey) - .whereIn('target_entity_ref', toRemove) - .delete(); + await tx<DbRefreshStateReferencesRow>('refresh_state_references') + .where('source_key', '=', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + .delete(); - console.log( - `REMOVED, ${removedCount} entities: ${JSON.stringify(toRemove)}`, - ); - } + this.logger.debug( + `removed, ${removedCount} entities: ${JSON.stringify(toRemove)}`, + ); + } - if (toAdd.length) { - const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(item => ({ - entity_id: item.id, - entity_ref: item.ref, - unprocessed_entity: JSON.stringify(item.entity), - errors: '', - next_update_at: tx.fn.now(), - last_discovery_at: tx.fn.now(), - })); - const stateReferences: DbRefreshStateReferencesRow[] = toAdd.map( - item => ({ - source_key: options.sourceKey, - target_entity_ref: item.ref, - }), - ); - // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense - await tx.batchInsert('refresh_state', state, BATCH_SIZE); - await tx.batchInsert( - 'refresh_state_references', - stateReferences, - BATCH_SIZE, - ); - } + if (toAdd.length) { + const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(entity => ({ + entity_id: uuid(), + entity_ref: stringifyEntityRef(entity), + unprocessed_entity: JSON.stringify(entity), + errors: '', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + })); - // for (const entity of options.items) { - // const entityRef = stringifyEntityRef(entity); - // await tx<DbRefreshStateRow>('refresh_state') - // .insert({ - // entity_id: uuid(), - // entity_ref: entityRef, - // unprocessed_entity: JSON.stringify(entity), - // errors: '', - // next_update_at: tx.fn.now(), - // last_discovery_at: tx.fn.now(), - // }) - // .onConflict('entity_ref') - // .merge(['unprocessed_entity', 'last_discovery_at']); - - // const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( - // 'refresh_state', - // ).where({ entity_ref: entityRef }); - // entityIds.push(entityId); - // } - // const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( - // entityId => ({ - // source_key: options.sourceKey, - // target_entityRef: entityRef, - // }), - // ); - // await tx.batchInsert( - // 'refresh_state_references', - // referenceRows, - // BATCH_SIZE, - // ); - // return; + const stateReferences: DbRefreshStateReferencesRow[] = toAdd.map( + entity => ({ + source_key: options.sourceKey, + target_entity_ref: stringifyEntityRef(entity), + }), + ); + // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense + await tx.batchInsert('refresh_state', state, BATCH_SIZE); + await tx.batchInsert( + 'refresh_state_references', + stateReferences, + BATCH_SIZE, + ); } } From b8e80eab23b8e4aadd79b75de16a42839c6e4c45 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 10:14:45 +0200 Subject: [PATCH 227/462] catalog-backend: Remove obervables Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/package.json | 4 +- .../src/next/DatabaseLocationProvider.ts | 71 ------------------- .../next/DefaultCatalogProcessingEngine.ts | 27 +------ .../src/next/DefaultLocationStore.ts | 4 -- plugins/catalog-backend/src/next/types.ts | 5 +- 5 files changed, 5 insertions(+), 106 deletions(-) delete mode 100644 plugins/catalog-backend/src/next/DatabaseLocationProvider.ts diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 9afb537637..5f70ec60e1 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -33,7 +33,6 @@ "@backstage/backend-common": "^0.6.3", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/plugin-search-backend-node": "^0.1.3", @@ -61,8 +60,7 @@ "winston": "^3.2.1", "yaml": "^1.9.2", "yn": "^4.0.0", - "yup": "^0.29.3", - "zen-observable": "^0.8.15" + "yup": "^0.29.3" }, "devDependencies": { "@backstage/cli": "^0.6.9", diff --git a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts b/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts deleted file mode 100644 index eaf5a78556..0000000000 --- a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2021 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Observable } from '@backstage/core'; -import { ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -import { EntityProvider, LocationStore, EntityMessage } from './types'; -import ObservableImpl from 'zen-observable'; -import { - locationSpecToLocationEntity, - locationSpecToMetadataName, -} from './util'; - -export class DatabaseLocationProvider implements EntityProvider { - private subscribers = new Set< - ZenObservable.SubscriptionObserver<EntityMessage> - >(); - - constructor(private readonly store: LocationStore) { - store.location$().subscribe({ - next: locations => { - if ('all' in locations) { - this.notify({ - all: locations.all.map(l => locationSpecToLocationEntity(l)), - }); - } else { - this.notify({ - added: locations.added.map(l => locationSpecToLocationEntity(l)), - removed: locations.removed.map(l => ({ - kind: 'Location', - namespace: ENTITY_DEFAULT_NAMESPACE, - name: locationSpecToMetadataName(l), - })), - }); - } - }, - }); - } - - private notify(message: EntityMessage) { - for (const subscriber of this.subscribers) { - subscriber.next(message); - } - } - - entityChange$(): Observable<EntityMessage> { - return new ObservableImpl(subscriber => { - this.store.listLocations().then(locations => { - subscriber.next({ - all: locations.map(l => locationSpecToLocationEntity(l)), - }); - this.subscribers.add(subscriber); - }); - return () => { - this.subscribers.delete(subscriber); - }; - }); - } -} diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 7f49bf832d..b71b2c1045 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -14,11 +14,9 @@ * limitations under the License. */ -import { Subscription } from '@backstage/core'; import { CatalogProcessingEngine, EntityProvider, - EntityMessage, EntityProviderConnection, EntityProviderMutation, ProcessingStateManager, @@ -40,7 +38,7 @@ class Connection implements EntityProviderConnection { async applyMutation(mutation: EntityProviderMutation): Promise<void> { if (mutation.type === 'full') { await this.config.stateManager.replaceProcessingItems({ - id: this.config.id, + sourceKey: this.config.id, type: 'full', items: mutation.entities, }); @@ -49,7 +47,7 @@ class Connection implements EntityProviderConnection { } await this.config.stateManager.replaceProcessingItems({ - id: this.config.id, + sourceKey: this.config.id, type: 'delta', added: mutation.added, removed: mutation.removed, @@ -120,25 +118,4 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async stop() { this.running = false; } - - private async onNext(id: string, message: EntityMessage) { - if ('all' in message) { - // TODO unhandled rejection - await this.stateManager.addProcessingItems({ - id, - type: 'provider', - entities: message.all, - }); - } - - if ('added' in message) { - await this.stateManager.addProcessingItems({ - id, - type: 'provider', - entities: message.added, - }); - - // TODO deletions of message.removed - } - } } diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index dff424b1a9..21206f0a7b 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -25,10 +25,6 @@ import { v4 as uuidv4 } from 'uuid'; import { locationSpecToLocationEntity } from './util'; import { ConflictError } from '@backstage/errors'; -export type LocationMessage = - | { all: Location[] } - | { added: Location[]; removed: Location[] }; - export class DefaultLocationStore implements LocationStore, EntityProvider { private _connection: EntityProviderConnection | undefined; diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index f8b4de1c41..a39ab9a8ff 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -16,7 +16,6 @@ import { Entity, - EntityName, LocationSpec, Location, EntityRelationSpec, @@ -116,12 +115,12 @@ export type ProcessingItem = { export type ReplaceProcessingItemsRequest = | { - id: string; + sourceKey: string; items: Entity[]; type: 'full'; } | { - id: string; + sourceKey: string; added: Entity[]; removed: Entity[]; type: 'delta'; From 464863419888171a95d805f3d51cc44bd8950de8 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 13:56:32 +0200 Subject: [PATCH 228/462] Refactor deferredEntities processing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultLocationStore.ts | 8 + .../src/next/DefaultProcessingStateManager.ts | 39 ++- .../src/next/NextCatalogBuilder.ts | 1 - plugins/catalog-backend/src/next/Stitcher.ts | 4 +- .../DefaultProcessingDatabase.test.ts | 83 ++++-- .../database/DefaultProcessingDatabase.ts | 236 ++++++++++-------- .../src/next/database/types.ts | 7 +- 7 files changed, 222 insertions(+), 156 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index 21206f0a7b..40870cff7b 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -104,5 +104,13 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; + const locations = await this.db.locations(); + const entities = locations.map(location => { + return locationSpecToLocationEntity(location); + }); + await this.connection.applyMutation({ + type: 'full', + entities, + }); } } diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index d2765c3101..0003b7a7cf 100644 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -49,35 +49,28 @@ export class DefaultProcessingStateManager implements ProcessingStateManager { async addProcessingItems(request: AddProcessingItemRequest) { return this.db.transaction(async tx => { - await this.db.addUnprocessedEntities(tx, request); + // await this.db.addUnprocessedEntities(tx, request); }); } async getNextProcessingItem(): Promise<ProcessingItem> { - const entities = await new Promise<RefreshStateItem[]>(resolve => - this.popFromQueue(resolve), - ); - const { id, state, unprocessedEntity } = entities[0]; - return { - id, - entity: unprocessedEntity, - state, - }; - } - - async popFromQueue(resolve: (rows: RefreshStateItem[]) => void) { - const entities = await this.db.transaction(async tx => { - return this.db.getProcessableEntities(tx, { - processBatchSize: 1, + for (;;) { + const { items } = await this.db.transaction(async tx => { + return this.db.getProcessableEntities(tx, { + processBatchSize: 1, + }); }); - }); - // No entities require refresh, wait and try again. - if (!entities.items.length) { - setTimeout(() => this.popFromQueue(resolve), 1000); - return; + if (items.length) { + const { id, state, unprocessedEntity } = items[0]; + return { + id, + entity: unprocessedEntity, + state, + }; + } + + await new Promise<void>(resolve => setTimeout(resolve, 1000)); } - - resolve(entities.items); } } diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 1796847164..d720bd331a 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -67,7 +67,6 @@ import { LocationAnalyzer } from '../ingestion/types'; import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; -import { DatabaseLocationProvider } from '../next/DatabaseLocationProvider'; import { DefaultLocationStore } from './DefaultLocationStore'; import { DefaultProcessingStateManager } from './DefaultProcessingStateManager'; import { CatalogProcessingEngine } from '../next/types'; diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 3e5e3ac24b..f53b7c6fad 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -76,8 +76,8 @@ export class Stitcher { const [reference_count_result] = await tx<DbRefreshStateReferences>( 'refresh_state_references', ) - .where({ target_entity_id: entity.metadata.uid }) - .count({ reference_count: 'target_entity_id' }); + .where({ target_entity_ref: entityRef }) + .count({ reference_count: 'target_entity_ref' }); if (Number(reference_count_result.reference_count) === 0) { this.logger.debug(`${entityRef} is orphan`); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index c4784c081d..14990a2a79 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -27,27 +27,26 @@ import * as uuid from 'uuid'; import { getVoidLogger } from '@backstage/backend-common'; describe('Default Processing Database', () => { - let db: Knex | undefined; - let processingDatabase: DefaultProcessingDatabase | undefined; - + let db: Knex; + let processingDatabase: DefaultProcessingDatabase; const logger = getVoidLogger(); beforeEach(async () => { db = await DatabaseManager.createTestDatabaseConnection(); await DatabaseManager.createDatabase(db); - processingDatabase = new DefaultProcessingDatabase(db!, logger); + processingDatabase = new DefaultProcessingDatabase(db, logger); }); describe('replaceUnprocessedEntities', () => { const insertRefRow = async (ref: DbRefreshStateReferencesRow) => { - return db!<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ).insert(ref); + return db<DbRefreshStateReferencesRow>('refresh_state_references').insert( + ref, + ); }; const insertRefreshStateRow = async (ref: DbRefreshStateRow) => { - await db!<DbRefreshStateRow>('refresh_state').insert(ref); + await db<DbRefreshStateRow>('refresh_state').insert(ref); }; const createLocations = async (entityRefs: string[]) => { @@ -101,8 +100,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/root-2', }); - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'full', sourceKey: 'config', items: [ @@ -117,11 +116,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); @@ -205,8 +204,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/root-2', }); - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'full', sourceKey: 'config', items: [ @@ -221,11 +220,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); @@ -296,8 +295,8 @@ describe('Default Processing Database', () => { }); it('should add new locations using the delta options', async () => { - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'delta', sourceKey: 'lols', removed: [], @@ -313,11 +312,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); @@ -336,6 +335,42 @@ describe('Default Processing Database', () => { ).toBeTruthy(); }); + it('should not remove locations that are referenced elsewhere', async () => { + /* + config-1 -> location:default/root + config-2 -> location:default/root + */ + await createLocations(['location:default/root']); + + await insertRefRow({ + source_key: 'config-1', + target_entity_ref: 'location:default/root', + }); + await insertRefRow({ + source_key: 'config-2', + target_entity_ref: 'location:default/root', + }); + + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { + type: 'full', + sourceKey: 'config-1', + items: [], + }); + }); + + const currentRefRowState = await db<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + expect(currentRefRowState).toEqual({ + source_key: 'config-2', + target_entity_ref: 'location:default/root', + }); + + // TODO: assert that root wasn't removed + }); + it('should remove old locations using the delta options', async () => { await createLocations(['location:default/new-root']); @@ -344,8 +379,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/new-root', }); - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'delta', sourceKey: 'lols', added: [], @@ -361,11 +396,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index a80325d469..dc5e6036f5 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -26,10 +26,12 @@ import { UpdateProcessedEntityOptions, GetProcessableEntitiesResult, ReplaceUnprocessedEntitiesOptions, + RefreshStateItem, } from './types'; import type { Logger } from 'winston'; import { v4 as uuid } from 'uuid'; +import { JsonObject } from '@backstage/config'; export type DbRefreshStateRow = { entity_id: string; @@ -88,7 +90,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { errors, }) .where('entity_id', id); - if (refreshResult === 0) { throw new NotFoundError(`Processing state not found for ${id}`); } @@ -96,8 +97,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { // Schedule all deferred entities for future processing. await this.addUnprocessedEntities(tx, { entities: deferredEntities, - id, - type: 'entity', + entityRef: stringifyEntityRef(processedEntity), }); // Update fragments @@ -172,80 +172,104 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { if (toRemove.length) { // TODO(freben): Batch split, to not hit variable limits? /* - WITH RECURSIVE - -- All the refs that can be reached from each individual root - root_reach(id, entity_ref) AS ( - -- Start with all roots - SELECT id, target_entity_ref - FROM refresh_state_references - WHERE source_key IS NOT NULL - UNION - -- For each match, select all children - SELECT root_reach.id, target_entity_ref - FROM refresh_state_references, root_reach - WHERE source_entity_ref = root_reach.entity_ref - ) - -- Start out with our own matching row (see the WHERE that - -- matches on source_key and target_entity_ref below) - SELECT us.entity_ref - FROM refresh_state_references - -- Expand the entire tree that emanates from that row - JOIN root_reach AS us - ON us.id = refresh_state_references.id - -- Expand with all roots that target the same node but - -- aren't ourselves - LEFT OUTER JOIN root_reach AS them - ON them.entity_ref = us.entity_ref - AND them.id != us.id - -- Keep only the matches that had no other rooots - WHERE refresh_state_references.source_key = "R1" - AND refresh_state_references.target_entity_ref = "A" - AND them.id IS NULL; - */ + WITH RECURSIVE + -- All the nodes that can be reached downwards from our root + descendants(root_id, entity_ref) AS ( + SELECT id, target_entity_ref + FROM refresh_state_references + WHERE source_key = "R1" AND target_entity_ref = "A" + UNION + SELECT descendants.root_id, target_entity_ref + FROM descendants + JOIN refresh_state_references ON source_entity_ref = descendants.entity_ref + ), + -- All the nodes that can be reached upwards from the descendants + ancestors(root_id, via_entity_ref, to_entity_ref) AS ( + SELECT NULL, entity_ref, entity_ref + FROM descendants + UNION + SELECT + CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END, + source_entity_ref, + ancestors.to_entity_ref + FROM ancestors + JOIN refresh_state_references ON target_entity_ref = ancestors.via_entity_ref + ) + -- Start out with all of the descendants + SELECT descendants.entity_ref + FROM descendants + -- Expand with all ancestors that point to those, but aren't the current root + LEFT OUTER JOIN ancestors + ON ancestors.to_entity_ref = descendants.entity_ref + AND ancestors.root_id IS NOT NULL + AND ancestors.root_id != descendants.root_id + -- Exclude all lines that had such a foreign ancestor + WHERE ancestors.root_id IS NULL; + */ const removedCount = await tx<DbRefreshStateRow>('refresh_state') .whereIn('entity_ref', function orphanedEntityRefs(orphans) { return ( orphans - // All the refs that can be reached from each individual root - .withRecursive('root_reach', function rootReach(outer) { - // Start with all roots + // All the nodes that can be reached downwards from our root + .withRecursive('descendants', function descendants(outer) { return outer - .select({ id: 'id', entity_ref: 'target_entity_ref' }) + .select({ root_id: 'id', entity_ref: 'target_entity_ref' }) .from('refresh_state_references') - .whereNotNull('source_key') - .union(function recurse(inner) { - return ( - inner - // For each match, select all children - .select({ - id: 'root_reach.id', - entity_ref: - 'refresh_state_references.target_entity_ref', - }) - .from('refresh_state_references') - .crossJoin('root_reach', { - 'root_reach.entity_ref': - 'refresh_state_references.source_entity_ref', - }) - ); + .where('source_key', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + .union(function recursive(inner) { + return inner + .select({ + root_id: 'descendants.root_id', + entity_ref: + 'refresh_state_references.target_entity_ref', + }) + .from('descendants') + .join('refresh_state_references', { + 'descendants.entity_ref': + 'refresh_state_references.source_entity_ref', + }); }); }) - .select('us.entity_ref') - // Start out with our own matching row - .from('refresh_state_references') - .where('source_key', options.sourceKey) - .whereIn('target_entity_ref', toRemove) - // Expand the entire tree that emanates from that row - .leftJoin({ us: 'root_reach' }, function us() { - this.on('us.id', '=', 'refresh_state_references.id'); + // All the nodes that can be reached upwards from the descendants + .withRecursive('ancestors', function ancestors(outer) { + return outer + .select({ + root_id: tx.raw('NULL', []), + via_entity_ref: 'entity_ref', + to_entity_ref: 'entity_ref', + }) + .from('descendants') + .union(function recursive(inner) { + return inner + .select({ + root_id: tx.raw( + 'CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END', + [], + ), + via_entity_ref: 'source_entity_ref', + to_entity_ref: 'ancestors.to_entity_ref', + }) + .from('ancestors') + .join('refresh_state_references', { + target_entity_ref: 'ancestors.via_entity_ref', + }); + }); }) - // Expand with all roots that target the same node but aren't ourselves - .leftOuterJoin({ them: 'root_reach' }, function them() { - this.on('them.entity_ref', '=', 'us.entity_ref'); - this.andOn('them.id', '!=', 'us.id'); + // Start out with all of the descendants + .select('descendants.entity_ref') + .from('descendants') + // Expand with all ancestors that point to those, but aren't the current root + .leftOuterJoin('ancestors', function keepaliveRoots() { + this.on( + 'ancestors.to_entity_ref', + '=', + 'descendants.entity_ref', + ); + this.andOnNotNull('ancestors.root_id'); + this.andOn('ancestors.root_id', '!=', 'descendants.root_id'); }) - // Keep only the matches that had no other rooots - .whereNull('them.id') + .whereNull('ancestors.root_id') ); }) .delete(); @@ -291,44 +315,45 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { options: AddUnprocessedEntitiesOptions, ): Promise<void> { const tx = txOpaque as Knex.Transaction; - const entityIds = new Array<string>(); - for (const entity of options.entities) { - const entityRef = stringifyEntityRef(entity); - await tx<DbRefreshStateRow>('refresh_state') - .insert({ + const stateRows = options.entities.map( + entity => + ({ entity_id: uuid(), - entity_ref: entityRef, + entity_ref: stringifyEntityRef(entity), unprocessed_entity: JSON.stringify(entity), errors: '', next_update_at: tx.fn.now(), last_discovery_at: tx.fn.now(), - }) + } as Knex.DbRecord<DbRefreshStateRow>), + ); + const stateReferenceRows = stateRows.map( + stateRow => + ({ + source_entity_ref: options.entityRef, + target_entity_ref: stateRow.entity_ref, + } as Knex.DbRecord<DbRefreshStateReferencesRow>), + ); + + // Upsert all of the unprocessed entities into the refresh_state table, by + // their entity ref. + // TODO(freben): Can this be batched somehow? + for (const row of stateRows) { + await tx<DbRefreshStateRow>('refresh_state') + .insert(row) .onConflict('entity_ref') .merge(['unprocessed_entity', 'last_discovery_at']); - - const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( - 'refresh_state', - ).where({ entity_ref: entityRef }); - entityIds.push(entityId); } - const key = - options.type === 'provider' - ? { source_special_key: options.id } - : { source_entity_id: options.id }; - // copied from update refs + // Replace all references for the originating entity before creating new ones await tx<DbRefreshStateReferencesRow>('refresh_state_references') - .where(key) + .where({ source_entity_ref: options.entityRef }) .delete(); - - const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( - entityId => ({ - ...key, - target_entity_id: entityId, - }), + await tx.batchInsert( + 'refresh_state_references', + stateReferenceRows, + BATCH_SIZE, ); - await tx.batchInsert('refresh_state_references', referenceRows, BATCH_SIZE); } async getProcessableEntities( @@ -356,16 +381,23 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { }); return { - items: items.map(i => ({ - id: i.entity_id, - entityRef: i.entity_ref, - unprocessedEntity: JSON.parse(i.unprocessed_entity) as Entity, - processedEntity: JSON.parse(i.processed_entity) as Entity, - nextUpdateAt: i.next_update_at, - lastDiscoveryAt: i.last_discovery_at, - state: JSON.parse(i.cache), - errors: i.errors, - })), + items: items.map( + i => + ({ + id: i.entity_id, + entityRef: i.entity_ref, + unprocessedEntity: JSON.parse(i.unprocessed_entity) as Entity, + processedEntity: i.processed_entity + ? (JSON.parse(i.processed_entity) as Entity) + : undefined, + nextUpdateAt: i.next_update_at, + lastDiscoveryAt: i.last_discovery_at, + state: i.cache + ? JSON.parse(i.cache) + : new Map<string, JsonObject>(), + errors: i.errors, + } as RefreshStateItem), + ), }; } diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index b926676887..d7a1dcd20b 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -19,8 +19,7 @@ import { JsonObject } from '@backstage/config'; import { Transaction } from '../../database/types'; export type AddUnprocessedEntitiesOptions = { - type: 'entity' | 'provider'; - id: string; + entityRef: string; entities: Entity[]; }; @@ -39,11 +38,11 @@ export type RefreshStateItem = { id: string; entityRef: string; unprocessedEntity: Entity; - processedEntity: Entity; + processedEntity?: Entity; nextUpdateAt: string; lastDiscoveryAt: string; // remove? state: Map<string, JsonObject>; - errors: string; + errors?: string; }; export type GetProcessableEntitiesResult = { From f22ac8403507761e188e28ae25bb49433c694d2d Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 14:02:41 +0200 Subject: [PATCH 229/462] Remove addProcessingItems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/Stitcher.ts | 4 ++-- plugins/catalog-backend/src/next/types.ts | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index f53b7c6fad..57f5ae9167 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -19,7 +19,7 @@ import { Logger } from 'winston'; import { Transaction } from '../database'; import { ConflictError } from '@backstage/errors'; import { - DbRefreshStateReferences, + DbRefreshStateReferencesRow, DbRefreshStateRow, DbRelationsRow, } from './database/DefaultProcessingDatabase'; @@ -73,7 +73,7 @@ export class Stitcher { return; } - const [reference_count_result] = await tx<DbRefreshStateReferences>( + const [reference_count_result] = await tx<DbRefreshStateReferencesRow>( 'refresh_state_references', ) .where({ target_entity_ref: entityRef }) diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index a39ab9a8ff..ef3bab797b 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -101,12 +101,6 @@ export type ProcessingItemResult = { deferredEntities: Entity[]; }; -export type AddProcessingItemRequest = { - type: 'entity' | 'provider'; - id: string; - entities: Entity[]; -}; - export type ProcessingItem = { id: string; entity: Entity; @@ -128,6 +122,5 @@ export type ReplaceProcessingItemsRequest = export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise<void>; getNextProcessingItem(): Promise<ProcessingItem>; - addProcessingItems(request: AddProcessingItemRequest): Promise<void>; replaceProcessingItems(request: ReplaceProcessingItemsRequest): Promise<void>; } From d77f5fea4406de005f25d052a90423f494d8bfcb Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 14:12:57 +0200 Subject: [PATCH 230/462] Add moar tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index 14990a2a79..f67b8603db 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -359,16 +359,26 @@ describe('Default Processing Database', () => { }); }); + const currentRefreshState = await db<DbRefreshStateRow>( + 'refresh_state', + ).select(); + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); - expect(currentRefRowState).toEqual({ - source_key: 'config-2', - target_entity_ref: 'location:default/root', - }); + expect(currentRefRowState).toEqual([ + expect.objectContaining({ + source_key: 'config-2', + target_entity_ref: 'location:default/root', + }), + ]); - // TODO: assert that root wasn't removed + expect(currentRefreshState).toEqual([ + expect.objectContaining({ + entity_ref: 'location:default/root', + }), + ]); }); it('should remove old locations using the delta options', async () => { From c1156a4b4748dfe9661ca9727e11184065d35d87 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 14:15:29 +0200 Subject: [PATCH 231/462] Remove dead code Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultProcessingStateManager.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index 0003b7a7cf..9c1d20ae9c 100644 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -14,9 +14,8 @@ * limitations under the License. */ -import { ProcessingDatabase, RefreshStateItem } from './database/types'; +import { ProcessingDatabase } from './database/types'; import { - AddProcessingItemRequest, ProcessingItem, ProcessingItemResult, ProcessingStateManager, @@ -47,12 +46,6 @@ export class DefaultProcessingStateManager implements ProcessingStateManager { }); } - async addProcessingItems(request: AddProcessingItemRequest) { - return this.db.transaction(async tx => { - // await this.db.addUnprocessedEntities(tx, request); - }); - } - async getNextProcessingItem(): Promise<ProcessingItem> { for (;;) { const { items } = await this.db.transaction(async tx => { From e0f43ae45391149d1d7bba5e91689d4690c0dde3 Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Mon, 26 Apr 2021 09:21:09 -0400 Subject: [PATCH 232/462] Clarify token exposure Signed-off-by: Adam Harvey <adaharve@cisco.com> --- .github/workflows/chromatic-storybook-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/chromatic-storybook-test.yml b/.github/workflows/chromatic-storybook-test.yml index bb14e1c38b..89df848c76 100644 --- a/.github/workflows/chromatic-storybook-test.yml +++ b/.github/workflows/chromatic-storybook-test.yml @@ -48,5 +48,7 @@ jobs: - uses: chromaui/action@v1 with: token: ${{ secrets.GITHUB_TOKEN }} + # projetToken intentionally shared to allow collaborators to run Chromatic on forks + # https://www.chromatic.com/docs/custom-ci-provider#run-chromatic-on-external-forks-of-open-source-projects projectToken: 9tzak77m9nj storybookBuildDir: 'packages/storybook/dist' From 656e1d82b281f4f3a9518e27d1bfe014393c2c91 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 15:38:31 +0200 Subject: [PATCH 233/462] Add all migration files to migrationsv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../migrationsv2/20200511113813_init.js | 133 ++++++++++ ...0200520140700_location_update_log_table.js | 43 ++++ ...7114117_location_update_log_latest_view.js | 45 ++++ .../migrationsv2/20200702153613_entities.js | 236 ++++++++++++++++++ ..._location_update_log_latest_deduplicate.js | 44 ++++ ...904_location_update_log_duplication_fix.js | 87 +++++++ .../20200807120600_entitySearch.js | 41 +++ .../20200809202832_add_bootstrap_location.js | 42 ++++ .../20200923104503_case_insensitivity.js | 32 +++ .../20201005122705_add_entity_full_name.js | 60 +++++ .../20201006130744_entity_data_column.js | 66 +++++ ...6203131_entity_remove_redundant_columns.js | 50 ++++ .../20201007201501_index_entity_search.js | 37 +++ .../20201019130742_add_relations_table.js | 54 ++++ .../20201123205611_relations_table_uniq.js | 93 +++++++ .../migrationsv2/20201210185851_fk_index.js | 45 ++++ .../20201230103504_update_log_varchar.js | 73 ++++++ .../20210209121210_locations_fk_index.js | 45 ++++ .../src/next/database/DatabaseManager.ts | 15 -- 19 files changed, 1226 insertions(+), 15 deletions(-) create mode 100644 plugins/catalog-backend/migrationsv2/20200511113813_init.js create mode 100644 plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js create mode 100644 plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js create mode 100644 plugins/catalog-backend/migrationsv2/20200702153613_entities.js create mode 100644 plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js create mode 100644 plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js create mode 100644 plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js create mode 100644 plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js create mode 100644 plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js create mode 100644 plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js create mode 100644 plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js create mode 100644 plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js create mode 100644 plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js create mode 100644 plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js create mode 100644 plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js create mode 100644 plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js create mode 100644 plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js create mode 100644 plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js diff --git a/plugins/catalog-backend/migrationsv2/20200511113813_init.js b/plugins/catalog-backend/migrationsv2/20200511113813_init.js new file mode 100644 index 0000000000..7f3d75e35c --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200511113813_init.js @@ -0,0 +1,133 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + return ( + knex.schema + // + // locations + // + .createTable('locations', table => { + table.comment( + 'Registered locations that shall be contiuously scanned for catalog item updates', + ); + table + .uuid('id') + .primary() + .notNullable() + .comment('Auto-generated ID of the location'); + table.string('type').notNullable().comment('The type of location'); + table + .string('target') + .notNullable() + .comment('The actual target of the location'); + }) + // + // entities + // + .createTable('entities', table => { + table.comment('All entities currently stored in the catalog'); + table.uuid('id').primary().comment('Auto-generated ID of the entity'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .nullable() + .comment('The location that originated the entity'); + table + .string('etag') + .notNullable() + .comment( + 'An opaque string that changes for each update operation to any part of the entity, including metadata.', + ); + table + .string('generation') + .notNullable() + .unsigned() + .comment( + 'A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes.', + ); + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table + .string('kind') + .notNullable() + .comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + table + .string('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .string('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + }) + .alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + }) + // + // entities_search + // + .createTable('entities_search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + }) + ); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + return knex.schema + .dropTable('entities_search') + .alterTable('entities', table => { + table.dropUnique([], 'entities_unique_name'); + }) + .dropTable('entities') + .dropTable('locations'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js b/plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js new file mode 100644 index 0000000000..d8093fc9b4 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + return knex.schema.createTable('location_update_log', table => { + table.uuid('id').primary(); + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + return knex.schema.dropTableIfExists('location_update_log'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js b/plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js new file mode 100644 index 0000000000..a0f0f33a65 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Get list sorted by created_at timestamp in descending order + // Grouped by location_id + return knex.schema.raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + ORDER BY created_at DESC; + `); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + return knex.schema.raw(`DROP VIEW location_update_log_latest;`); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200702153613_entities.js b/plugins/catalog-backend/migrationsv2/20200702153613_entities.js new file mode 100644 index 0000000000..0f1c204f9b --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200702153613_entities.js @@ -0,0 +1,236 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // SQLite does not support FK and PK + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.dropForeign(['entity_id']); + }); + await knex.schema.alterTable('entities', table => { + table.dropPrimary('entities_pkey'); + }); + } + await knex.schema.alterTable('entities', table => { + table.dropUnique([], 'entities_unique_name'); + }); + // Setup temporary tables + await knex.schema.renameTable('entities_search', 'tmp_entities_search'); + await knex.schema.renameTable('entities', 'tmp_entities'); + + // + // entities + // + await knex.schema + .createTable('entities', table => { + table.comment('All entities currently stored in the catalog'); + table.uuid('id').primary().comment('Auto-generated ID of the entity'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .nullable() + .comment('The location that originated the entity'); + table + .string('etag') + .notNullable() + .comment( + 'An opaque string that changes for each update operation to any part of the entity, including metadata.', + ); + table + .string('generation') + .notNullable() + .unsigned() + .comment( + 'A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes.', + ); + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table + .string('kind') + .notNullable() + .comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + table + .text('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .text('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + }) + .alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + }); + + await knex.schema.raw(`INSERT INTO entities SELECT * FROM tmp_entities`); + + // + // entities_search + // + await knex.schema.createTable('entities_search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + }); + await knex.schema.raw( + `INSERT INTO entities_search SELECT * FROM tmp_entities_search`, + ); + + // Clean up + await knex.schema.dropTable('tmp_entities'); + return knex.schema.dropTable('tmp_entities_search'); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + // SQLite does not support FK and PK + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.dropForeign(['entity_id']); + }); + await knex.schema.alterTable('entities', table => { + table.dropPrimary('entities_pkey'); + }); + } + await knex.schema.alterTable('entities', table => { + table.dropUnique([], 'entities_unique_name'); + }); + + // Setup temporary tables + await knex.schema.renameTable('entities_search', 'tmp_entities_search'); + await knex.schema.renameTable('entities', 'tmp_entities'); + + // + // entities + // + await knex.schema + .createTable('entities', table => { + table.comment('All entities currently stored in the catalog'); + table.uuid('id').primary().comment('Auto-generated ID of the entity'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .nullable() + .comment('The location that originated the entity'); + table + .string('etag') + .notNullable() + .comment( + 'An opaque string that changes for each update operation to any part of the entity, including metadata.', + ); + table + .string('generation') + .notNullable() + .unsigned() + .comment( + 'A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes.', + ); + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table + .string('kind') + .notNullable() + .comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + table + .string('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .string('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + }) + .alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + }); + + await knex.schema.raw(`INSERT INTO entities SELECT * FROM tmp_entities`); + + // + // entities_search + // + await knex.schema.createTable('entities_search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + }); + await knex.schema.raw( + `INSERT INTO entities_search SELECT * FROM tmp_entities_search`, + ); + + // Clean up + await knex.schema.dropTable('tmp_entities'); + return knex.schema.dropTable('tmp_entities_search'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js b/plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js new file mode 100644 index 0000000000..87b41a80fc --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js @@ -0,0 +1,44 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = function up(knex) { + return knex.schema.raw(`DROP VIEW location_update_log_latest;`).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; +`); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = function down(knex) { + knex.schema.raw(`DROP VIEW location_update_log_latest;`); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js b/plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js new file mode 100644 index 0000000000..de2b194cff --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js @@ -0,0 +1,87 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = function up(knex) { + return knex.schema + .raw('DROP VIEW location_update_log_latest;') + .dropTable('location_update_log') + .createTable('location_update_log', table => { + table.bigIncrements('id').primary(); // instead of uuid, so we can MAX it + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = function down(knex) { + return knex.schema + .raw('DROP VIEW location_update_log_latest;') + .dropTable('location_update_log') + .createTable('location_update_log', table => { + table.uuid('id').primary(); + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js b/plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js new file mode 100644 index 0000000000..45226e53b4 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js @@ -0,0 +1,41 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Sqlite does not support alter column. + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.text('value').nullable().alter(); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + // Sqlite does not support alter column. + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.string('value').nullable().alter(); + }); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js b/plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js new file mode 100644 index 0000000000..a90813fe85 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Adds a single 'bootstrap' location that can be used to trigger work in processors. + // This is primarily here to fulfill foreign key constraints. + await knex('locations').insert({ + id: require('uuid').v4(), + type: 'bootstrap', + target: 'bootstrap', + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex('locations') + .where({ + type: 'bootstrap', + target: 'bootstrap', + }) + .del(); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js b/plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js new file mode 100644 index 0000000000..ea5ba9e58d --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js @@ -0,0 +1,32 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex('entities') + .where({ namespace: null }) + .update({ namespace: 'default' }); + await knex('entities_search').update({ + key: knex.raw('LOWER(key)'), + value: knex.raw('LOWER(value)'), + }); +}; + +exports.down = async function down() {}; diff --git a/plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js b/plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js new file mode 100644 index 0000000000..aae1861658 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js @@ -0,0 +1,60 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table.text('full_name').nullable(); + }); + + await knex('entities').update({ + full_name: knex.raw( + "LOWER(kind) || ':' || LOWER(COALESCE(namespace, 'default')) || '/' || LOWER(name)", + ), + }); + + // SQLite does not support alter column + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.text('full_name').notNullable().alter(); + }); + } + + await knex.schema.alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['full_name'], 'entities_unique_full_name'); + table.dropUnique([], 'entities_unique_name'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.dropUnique([], 'entities_unique_full_name'); + table.unique(['kind', 'namespace', 'name'], 'entities_unique_name'); + }); + + await knex.schema.alterTable('entities_search', table => { + table.dropColumn('full_name'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js b/plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js new file mode 100644 index 0000000000..a8964efbf6 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table + .text('data') + .nullable() + .comment('The entire JSON data blob of the entity'); + }); + + await knex('entities').update({ + // apiVersion and kind should not contain any JSON unsafe chars, and both + // metadata and spec are already valid serialized JSON + data: knex.raw( + `'{"apiVersion":"' || api_version || '","kind":"' || kind || '","metadata":' || metadata || COALESCE(',"spec":' || spec, '') || '}'`, + ), + }); + + await knex.schema.alterTable('entities', table => { + table.dropColumn('metadata'); + table.dropColumn('spec'); + }); + + // SQLite does not support ALTER COLUMN. + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.text('data').notNullable().alter(); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + table + .text('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .text('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + table.dropColumn('data'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js b/plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js new file mode 100644 index 0000000000..f40df5f73e --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js @@ -0,0 +1,50 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table.dropColumn('api_version'); + table.dropColumn('kind'); + table.dropColumn('name'); + table.dropColumn('namespace'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table.string('kind').notNullable().comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js b/plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js new file mode 100644 index 0000000000..77bf0529eb --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities_search', table => { + table.index(['key'], 'entities_search_key'); + table.index(['value'], 'entities_search_value'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities_search', table => { + table.dropIndex('', 'entities_search_key'); + table.dropIndex('', 'entities_search_value'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js b/plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js new file mode 100644 index 0000000000..85e729f814 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.createTable('entities_relations', table => { + table.comment('All relations between entities in the catalog'); + table + .uuid('originating_entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .string('source_full_name') + .notNullable() + .comment('The full name of the source entity of the relation'); + table + .string('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .string('target_full_name') + .notNullable() + .comment('The full name of the target entity of the relation'); + + table.primary(['source_full_name', 'type', 'target_full_name']); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.dropTable('entities_relations'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js b/plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js new file mode 100644 index 0000000000..9e8198b5eb --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js @@ -0,0 +1,93 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client === 'sqlite3') { + // sqlite doesn't support dropPrimary so we recreate it properly instead + await knex.schema.dropTable('entities_relations'); + await knex.schema.createTable('entities_relations', table => { + table.comment('All relations between entities in the catalog'); + table + .uuid('originating_entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .string('source_full_name') + .notNullable() + .comment('The full name of the source entity of the relation'); + table + .string('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .string('target_full_name') + .notNullable() + .comment('The full name of the target entity of the relation'); + table.index('source_full_name', 'source_full_name_idx'); + }); + } else { + await knex.schema.alterTable('entities_relations', table => { + table.dropPrimary(); + table.index('source_full_name', 'source_full_name_idx'); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client === 'sqlite3') { + await knex.schema.dropTable('entities_relations'); + await knex.schema.createTable('entities_relations', table => { + table.comment('All relations between entities in the catalog'); + table + .uuid('originating_entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .string('source_full_name') + .notNullable() + .comment('The full name of the source entity of the relation'); + table + .string('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .string('target_full_name') + .notNullable() + .comment('The full name of the target entity of the relation'); + + table.primary(['source_full_name', 'type', 'target_full_name']); + }); + } else { + await knex.schema.alterTable('entities_relations', table => { + table.dropIndex([], 'source_full_name_idx'); + table.primary(['source_full_name', 'type', 'target_full_name']); + }); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js b/plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js new file mode 100644 index 0000000000..abb26cd5fc --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_relations', table => { + table.index('originating_entity_id', 'originating_entity_id_idx'); + }); + await knex.schema.alterTable('entities_search', table => { + table.index('entity_id', 'entity_id_idx'); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_relations', table => { + table.dropIndex([], 'originating_entity_id_idx'); + }); + await knex.schema.alterTable('entities_relations', table => { + table.dropIndex([], 'entity_id_idx'); + }); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js b/plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js new file mode 100644 index 0000000000..d924b0414a --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js @@ -0,0 +1,73 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client !== 'sqlite3') { + // We actually just want to widen columns, but can't do that while a + // view is dependent on them - so we just reconstruct it exactly as it was + await knex.schema + .raw('DROP VIEW location_update_log_latest;') + .alterTable('location_update_log', table => { + table.text('message').alter(); + table.text('entity_name').nullable().alter(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema + .raw('DROP VIEW location_update_log_latest;') + .alterTable('location_update_log', table => { + table.string('message').alter(); + table.string('entity_name').nullable().alter(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js b/plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js new file mode 100644 index 0000000000..ccfb1faffb --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.index('location_id', 'entity_location_id_idx'); + }); + await knex.schema.alterTable('location_update_log', table => { + table.index('location_id', 'update_log_location_id_idx'); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.dropIndex([], 'entity_location_id_idx'); + }); + await knex.schema.alterTable('location_update_log', table => { + table.dropIndex([], 'update_log_location_id_idx'); + }); + } +}; diff --git a/plugins/catalog-backend/src/next/database/DatabaseManager.ts b/plugins/catalog-backend/src/next/database/DatabaseManager.ts index 4c9e45950f..f660f73ecb 100644 --- a/plugins/catalog-backend/src/next/database/DatabaseManager.ts +++ b/plugins/catalog-backend/src/next/database/DatabaseManager.ts @@ -20,7 +20,6 @@ import { v4 as uuidv4 } from 'uuid'; import { Logger } from 'winston'; import { CommonDatabase } from '../../database/CommonDatabase'; import { Database } from '../../database/types'; -import fs from 'fs-extra'; export type CreateDatabaseOptions = { logger: Logger; @@ -35,16 +34,10 @@ export class DatabaseManager { knex: Knex, options: Partial<CreateDatabaseOptions> = {}, ): Promise<Database> { - const allMigrations = resolvePackagePath( - '@backstage/plugin-catalog-backend', - 'migrations', - ); - const migrationsDir = resolvePackagePath( '@backstage/plugin-catalog-backend', 'migrationsv2', ); - await fs.copy(allMigrations, migrationsDir); await knex.migrate.latest({ directory: migrationsDir, @@ -79,14 +72,6 @@ export class DatabaseManager { public static async createTestDatabaseConnection(): Promise<Knex> { const config: Knex.Config<any> = { - /* - client: 'pg', - connection: { - host: 'localhost', - user: 'postgres', - password: 'postgres', - }, - */ client: 'sqlite3', connection: ':memory:', useNullAsDefault: true, From fae7eb02965c17534168b0c85580ea5367e05477 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 15:43:22 +0200 Subject: [PATCH 234/462] Add configLocationProvider and provider identifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/ConfigLocationProvider.ts | 49 +++++++++++++++++++ .../next/DefaultCatalogProcessingEngine.ts | 9 ++-- .../src/next/DefaultLocationStore.ts | 4 ++ .../src/next/NextCatalogBuilder.ts | 7 +-- plugins/catalog-backend/src/next/types.ts | 1 + 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 plugins/catalog-backend/src/next/ConfigLocationProvider.ts diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts new file mode 100644 index 0000000000..5b93fcfd98 --- /dev/null +++ b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EntityProviderConnection, EntityProvider } from './types'; +import path from 'path'; +import { Config } from '@backstage/config'; +import { locationSpecToLocationEntity } from './util'; + +export class ConfigLocationProvider implements EntityProvider { + private connection: EntityProviderConnection | undefined; + + constructor(private readonly config: Config) {} + + getProviderName(): string { + return 'ConfigLocationProvider'; + } + + async connect(connection: EntityProviderConnection): Promise<void> { + this.connection = connection; + + const locationConfigs = + this.config.getOptionalConfigArray('catalog.locations') ?? []; + + const entities = locationConfigs.map(location => + locationSpecToLocationEntity({ + type: location.getString('type'), + target: path.resolve(location.getString('target')), + }), + ); + + await this.connection.applyMutation({ + type: 'full', + entities, + }); + } +} diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index b71b2c1045..1934b0aea7 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -68,9 +68,12 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - // TODO: this ID should be some form of identifier for the EntityProvider - const id = 'databaseProvider'; - provider.connect(new Connection({ stateManager: this.stateManager, id })); + provider.connect( + new Connection({ + stateManager: this.stateManager, + id: provider.getProviderName(), + }), + ); } this.running = true; diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index 40870cff7b..a56e5d1585 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -30,6 +30,10 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { constructor(private readonly db: Database) {} + getProviderName(): string { + return 'DefaultLocationStore'; + } + createLocation(spec: LocationSpec): Promise<Location> { return this.db.transaction(async tx => { // TODO: id should really be type and target combined and not a uuid. diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index d720bd331a..0699a13f58 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -50,6 +50,7 @@ import { GithubDiscoveryProcessor, GithubOrgReaderProcessor, LdapOrgReaderProcessor, + LocationEntityProcessor, MicrosoftGraphOrgReaderProcessor, PlaceholderProcessor, PlaceholderResolver, @@ -73,6 +74,7 @@ import { CatalogProcessingEngine } from '../next/types'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; import { CommonDatabase } from '../database/CommonDatabase'; +import { ConfigLocationProvider } from './ConfigLocationProvider'; export type CatalogEnvironment = { logger: Logger; @@ -272,9 +274,10 @@ export class NextCatalogBuilder { const locationStore = new DefaultLocationStore(db); const stitcher = new Stitcher(dbClient, logger); + const configLocationProvider = new ConfigLocationProvider(config); const processingEngine = new DefaultCatalogProcessingEngine( logger, - [locationStore], // entityproviders + [locationStore, configLocationProvider], stateManager, orchestrator, stitcher, @@ -322,7 +325,6 @@ export class NextCatalogBuilder { // These are always there no matter what const processors: CatalogProcessor[] = [ - StaticLocationProcessor.fromConfig(config), new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }), new BuiltinKindsEntityProcessor(), ]; @@ -338,7 +340,6 @@ export class NextCatalogBuilder { MicrosoftGraphOrgReaderProcessor.fromConfig(config, { logger }), new UrlReaderProcessor({ reader, logger }), CodeOwnersProcessor.fromConfig(config, { logger, reader }), - // new LocationEntityProcessor({ integrations }), new AnnotateLocationEntityProcessor({ integrations }), ); } diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index ef3bab797b..e0616fb336 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -65,6 +65,7 @@ export interface EntityProviderConnection { } export interface EntityProvider { + getProviderName(): string; connect(connection: EntityProviderConnection): Promise<void>; } From 19a4dd7103b806122fede7bdf2a8952204f81f84 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 26 Apr 2021 16:00:09 +0200 Subject: [PATCH 235/462] plugins: removed unused swr dependency Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/rare-parrots-share.md | 6 ++++++ plugins/catalog/package.json | 3 +-- plugins/scaffolder/package.json | 1 - yarn.lock | 7 ------- 4 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 .changeset/rare-parrots-share.md diff --git a/.changeset/rare-parrots-share.md b/.changeset/rare-parrots-share.md new file mode 100644 index 0000000000..917ec5a18e --- /dev/null +++ b/.changeset/rare-parrots-share.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog': patch +'@backstage/plugin-scaffolder': patch +--- + +Removed unused `swr` dependency. diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index b6b306c260..965a0b327b 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -49,8 +49,7 @@ "react-helmet": "6.1.0", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", - "swr": "^0.3.0" + "react-use": "^15.3.3" }, "devDependencies": { "@backstage/cli": "^0.6.9", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 4d4563df2f..2b4feecb7b 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -55,7 +55,6 @@ "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", "react-use": "^15.3.3", - "swr": "^0.3.0", "use-immer": "^0.5.1", "zen-observable": "^0.8.15" }, diff --git a/yarn.lock b/yarn.lock index ba1b3bfe73..f2c2bee93c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24792,13 +24792,6 @@ swap-case@^2.0.1: dependencies: tslib "^2.0.3" -swr@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/swr/-/swr-0.3.0.tgz#69602953dd50ab07fe60c920fd63199256645675" - integrity sha512-3p0p5TWH0qiaKAph5wBkMwqe2WjNseITfjmdVoNzjqRZGn/gnpRi6whMDjhMVb/vp/yyDtKWPlyjid8QZH+UhA== - dependencies: - fast-deep-equal "2.0.1" - symbol-observable@1.2.0, symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" From da489d2cd3a29f30749829e804ff8f9668153e0f Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 16:38:34 +0200 Subject: [PATCH 236/462] add new Scheduler Class Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- plugins/search-backend-node/src/Scheduler.ts | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 plugins/search-backend-node/src/Scheduler.ts diff --git a/plugins/search-backend-node/src/Scheduler.ts b/plugins/search-backend-node/src/Scheduler.ts new file mode 100644 index 0000000000..e54a837cee --- /dev/null +++ b/plugins/search-backend-node/src/Scheduler.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Logger } from 'winston'; + +type TaskEnvelope = { + task: Function; + interval: number; +}; + +/** + * TODO: coordination, error handling + */ + +export class Scheduler { + private logger: Logger; + private schedule: TaskEnvelope[]; + private intervalTimeouts: NodeJS.Timeout[] = []; + + constructor({ logger }: { logger: Logger }) { + this.logger = logger; + this.schedule = []; + } + + /** + * Adds each task and interval to the schedule + * + */ + addToSchedule(task: Function, interval: number) { + if (this.intervalTimeouts.length) { + throw new Error( + 'Cannot add task to schedule that has already been started.', + ); + } + this.schedule.push({ task, interval }); + } + + /** + * Starts the scheduling process for each task + */ + start() { + this.logger.info('Starting all scheduled search tasks.'); + this.schedule.forEach(({ task, interval }) => { + this.intervalTimeouts.push( + setInterval(() => { + task(); + }, interval), + ); + }); + } + + /** + * Stop all scheduled tasks. + */ + stop() { + this.logger.info('Stopping all scheduled search tasks.'); + this.intervalTimeouts.forEach(timeout => { + clearInterval(timeout); + }); + this.intervalTimeouts = []; + } +} From 0b9eac3a819e3185c98a339124871f85fb2383e8 Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 16:39:33 +0200 Subject: [PATCH 237/462] refactor build method in indexBuilder Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- .../search-backend-node/src/IndexBuilder.ts | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/plugins/search-backend-node/src/IndexBuilder.ts b/plugins/search-backend-node/src/IndexBuilder.ts index 0fc881c262..768dee5b67 100644 --- a/plugins/search-backend-node/src/IndexBuilder.ts +++ b/plugins/search-backend-node/src/IndexBuilder.ts @@ -16,7 +16,7 @@ import { DocumentCollator, DocumentDecorator } from '@backstage/search-common'; import { Logger } from 'winston'; - +import { Scheduler } from './index'; import { RegisterCollatorParameters, RegisterDecoratorParameters, @@ -92,40 +92,42 @@ export class IndexBuilder { } /** - * Starts the process of executing collators and decorators and building the - * search index. - * - * TODO: But like with coordination, timing, error handling, and what have you. + * Compiles collators and decorators into tasks, which are added to a + * scheduler returned to the caller. */ - async build() { - return Promise.all( - Object.keys(this.collators).map(async type => { - setInterval(async () => { - const decorators: DocumentDecorator[] = ( - this.decorators['*'] || [] - ).concat(this.decorators[type] || []); + async build(): Promise<{ scheduler: Scheduler }> { + const scheduler = new Scheduler({ logger: this.logger }); + Object.keys(this.collators).map(type => { + scheduler.addToSchedule(async () => { + // Collate, Decorate, Index. + const decorators: DocumentDecorator[] = ( + this.decorators['*'] || [] + ).concat(this.decorators[type] || []); + + this.logger.debug( + `Collating documents for ${type} via ${this.collators[type].collate.constructor.name}`, + ); + let documents = await this.collators[type].collate.execute(); + for (let i = 0; i < decorators.length; i++) { this.logger.debug( - `Collating documents for ${type} via ${this.collators[type].collate.constructor.name}`, + `Decorating ${type} documents via ${decorators[i].constructor.name}`, ); - let documents = await this.collators[type].collate.execute(); - for (let i = 0; i < decorators.length; i++) { - this.logger.debug( - `Decorating ${type} documents via ${decorators[i].constructor.name}`, - ); - documents = await decorators[i].execute(documents); - } + documents = await decorators[i].execute(documents); + } - if (!documents || documents.length === 0) { - this.logger.debug(`No documents for type "${type}" to index`); - return; - } + if (!documents || documents.length === 0) { + this.logger.debug(`No documents for type "${type}" to index`); + return; + } - // pushing documents to index to a configured search engine. - this.searchEngine.index(type, documents); - // refreshInterval configured in seconds, setInterval want milliseconds - }, this.collators[type].refreshInterval * 1000); - }), - ); + // pushing documents to index to a configured search engine. + this.searchEngine.index(type, documents); + }, this.collators[type].refreshInterval * 1000); + }); + + return { + scheduler, + }; } } From 9dff1a9839704af0ae722372a728b504ebe27bec Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 16:43:58 +0200 Subject: [PATCH 238/462] use scheduler and fix tests Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- packages/backend/src/plugins/search.ts | 5 ++++- plugins/search-backend-node/src/index.test.ts | 15 ++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts index da7ee193b4..03c7d44a18 100644 --- a/packages/backend/src/plugins/search.ts +++ b/packages/backend/src/plugins/search.ts @@ -34,7 +34,10 @@ export default async function createPlugin({ collator: new DefaultCatalogCollator(discovery), }); - indexBuilder.build(); + const { scheduler } = await indexBuilder.build(); + + scheduler.start(); + useHotCleanup(module, () => scheduler.stop()); return await createRouter({ engine: indexBuilder.getSearchEngine(), diff --git a/plugins/search-backend-node/src/index.test.ts b/plugins/search-backend-node/src/index.test.ts index 86233425e7..e1dc511b97 100644 --- a/plugins/search-backend-node/src/index.test.ts +++ b/plugins/search-backend-node/src/index.test.ts @@ -65,7 +65,8 @@ describe('IndexBuilder', () => { }); // Build the index and ensure the collator was invoked. - await testIndexBuilder.build(); + const { scheduler } = await testIndexBuilder.build(); + scheduler.start(); jest.advanceTimersByTime(6000); expect(collatorSpy).toHaveBeenCalled(); }); @@ -89,7 +90,8 @@ describe('IndexBuilder', () => { }); // Build the index and ensure the decorator was invoked. - await testIndexBuilder.build(); + const { scheduler } = await testIndexBuilder.build(); + scheduler.start(); jest.advanceTimersByTime(6000); // wait for async decorator execution await Promise.resolve(); @@ -123,7 +125,8 @@ describe('IndexBuilder', () => { }); // Build the index and ensure the decorator was invoked. - await testIndexBuilder.build(); + const { scheduler } = await testIndexBuilder.build(); + scheduler.start(); jest.advanceTimersByTime(6000); // wait for async decorator execution await Promise.resolve(); @@ -138,7 +141,7 @@ describe('IndexBuilder', () => { text: 'Test text.', location: '/test/location', }; - jest + const collatorSpy = jest .spyOn(testCollator, 'execute') .mockImplementation(async () => [docFixture]); const decoratorSpy = jest.spyOn(testDecorator, 'execute'); @@ -157,8 +160,10 @@ describe('IndexBuilder', () => { }); // Build the index and ensure the decorator was not invoked. - await testIndexBuilder.build(); + const { scheduler } = await testIndexBuilder.build(); + scheduler.start(); jest.advanceTimersByTime(6000); + expect(collatorSpy).toHaveBeenCalled(); expect(decoratorSpy).not.toHaveBeenCalled(); }); }); From 50b15bfeb3495f623f0bce521ad9e5d5b383951d Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 16:44:32 +0200 Subject: [PATCH 239/462] imports and exports Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- packages/backend/src/plugins/search.ts | 1 + plugins/search-backend-node/src/index.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts index 03c7d44a18..dcd48aaf40 100644 --- a/packages/backend/src/plugins/search.ts +++ b/packages/backend/src/plugins/search.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { useHotCleanup } from '@backstage/backend-common'; import { createRouter } from '@backstage/plugin-search-backend'; import { IndexBuilder, diff --git a/plugins/search-backend-node/src/index.ts b/plugins/search-backend-node/src/index.ts index a3a0eb855e..7ee75e3d59 100644 --- a/plugins/search-backend-node/src/index.ts +++ b/plugins/search-backend-node/src/index.ts @@ -15,5 +15,6 @@ */ export { IndexBuilder } from './IndexBuilder'; +export { Scheduler } from './Scheduler'; export { LunrSearchEngine } from './engines'; export type { SearchEngine } from './types'; From fafd8043649dd7432bde654eaee11cf58539544f Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 16:49:32 +0200 Subject: [PATCH 240/462] update changeset Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- .changeset/odd-ads-invite.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/odd-ads-invite.md b/.changeset/odd-ads-invite.md index d487df47d3..0dde3d0c1f 100644 --- a/.changeset/odd-ads-invite.md +++ b/.changeset/odd-ads-invite.md @@ -2,4 +2,4 @@ '@backstage/plugin-search-backend-node': patch --- -Moved refresh loop to builder and use configured refreshInterval for each collator +Introduced Scheduler which is responsible for adding new tasks to a schedule together with it's interval timer as well as starting and stopping the scheduler processes. From e00ba124546a742639973fd26edb39635dff5351 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 16:53:44 +0200 Subject: [PATCH 241/462] chore: remove unused imports Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/NextCatalogBuilder.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 0699a13f58..24b763a098 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -50,11 +50,9 @@ import { GithubDiscoveryProcessor, GithubOrgReaderProcessor, LdapOrgReaderProcessor, - LocationEntityProcessor, MicrosoftGraphOrgReaderProcessor, PlaceholderProcessor, PlaceholderResolver, - StaticLocationProcessor, UrlReaderProcessor, } from '../ingestion'; import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer'; From 17915e29b31acb6ebfbacee71db655888ae5602e Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Mon, 26 Apr 2021 16:53:28 +0200 Subject: [PATCH 242/462] Rework state management to avoid rendering multiple while navigating between pages Closes #5184 Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/techdocs-young-walls-decide.md | 5 ++ .../techdocs/src/reader/components/Reader.tsx | 38 ++++++------- .../src/reader/components/TechDocsPage.tsx | 6 +-- .../src/reader/components/useRawPage.ts | 54 +++++++++++++++++++ 4 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 .changeset/techdocs-young-walls-decide.md create mode 100644 plugins/techdocs/src/reader/components/useRawPage.ts diff --git a/.changeset/techdocs-young-walls-decide.md b/.changeset/techdocs-young-walls-decide.md new file mode 100644 index 0000000000..8dc0373234 --- /dev/null +++ b/.changeset/techdocs-young-walls-decide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Rework state management to avoid rendering multiple while navigating between pages. diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index ff4f47dca0..6e5e0b5920 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { EntityName } from '@backstage/catalog-model'; -import { useApi, configApiRef } from '@backstage/core'; +import { configApiRef, useApi } from '@backstage/core'; import { BackstageTheme } from '@backstage/theme'; import { useTheme } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; @@ -24,6 +24,7 @@ import { useAsync } from 'react-use'; import { techdocsStorageApiRef } from '../../api'; import transformer, { addBaseUrl, + addGitFeedbackLink, addLinkClickListener, injectCss, onCssReady, @@ -31,10 +32,10 @@ import transformer, { rewriteDocLinks, sanitizeDOM, simplifyMkdocsFooter, - addGitFeedbackLink, } from '../transformers'; import { TechDocsNotFound } from './TechDocsNotFound'; import TechDocsProgressBar from './TechDocsProgressBar'; +import { useRawPage } from './useRawPage'; type Props = { entityId: EntityName; @@ -69,20 +70,20 @@ export const Reader = ({ entityId, onReady }: Props) => { }); } return techdocsStorageApi.syncEntityDocs({ kind, namespace, name }); - }); + }, [techdocsStorageApi, kind, namespace, name]); const { value: rawPage, loading: docLoading, error: docLoadError, - } = useAsync(async () => { - // do not automatically load same page again if URL has not changed, - // happens when generating new docs finishes - if (newerDocsExist && path === loadedPath) { - return null; + retry, + } = useRawPage(path, kind, namespace, name); + + useEffect(() => { + if (isSynced && newerDocsExist && path !== loadedPath) { + retry(); } - return techdocsStorageApi.getEntityDocs({ kind, namespace, name }, path); - }, [techdocsStorageApi, kind, namespace, name, path, isSynced]); + }); useEffect(() => { const updateSidebarPosition = () => { @@ -134,12 +135,12 @@ export const Reader = ({ entityId, onReady }: Props) => { onReady(); } // Pre-render - const transformedElement = transformer(rawPage as string, [ + const transformedElement = transformer(rawPage.content, [ sanitizeDOM(), addBaseUrl({ techdocsStorageApi, - entityId: entityId, - path, + entityId: rawPage.entityId, + path: rawPage.path, }), rewriteDocLinks(), removeMkdocsHeader(), @@ -304,16 +305,15 @@ export const Reader = ({ entityId, onReady }: Props) => { ]); }, [ rawPage, - entityId, navigate, onReady, shadowDomRef, - path, techdocsStorageApi, - theme, - kind, - namespace, - name, + theme.typography.fontFamily, + theme.palette.text.primary, + theme.palette.primary.main, + theme.palette.background.paper, + theme.palette.background.default, newerDocsExist, isSynced, configApi, diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.tsx index c15f3a6a44..338088be4d 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.tsx @@ -15,7 +15,7 @@ */ import { Content, Page, useApi } from '@backstage/core'; -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { useParams } from 'react-router-dom'; import { useAsync } from 'react-use'; import { techdocsApiRef } from '../../api'; @@ -40,9 +40,9 @@ export const TechDocsPage = () => { return techdocsApi.getEntityMetadata({ kind, namespace, name }); }, [kind, namespace, name, techdocsApi]); - const onReady = () => { + const onReady = useCallback(() => { setDocumentReady(true); - }; + }, [setDocumentReady]); return ( <Page themeId="documentation"> diff --git a/plugins/techdocs/src/reader/components/useRawPage.ts b/plugins/techdocs/src/reader/components/useRawPage.ts new file mode 100644 index 0000000000..1bc23d2a45 --- /dev/null +++ b/plugins/techdocs/src/reader/components/useRawPage.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { EntityName } from '@backstage/catalog-model'; +import { useApi } from '@backstage/core'; +import { useAsyncRetry } from 'react-use'; +import { AsyncState } from 'react-use/lib/useAsync'; +import { techdocsStorageApiRef } from '../../api'; + +export type RawPage = { + content: string; + path: string; + entityId: EntityName; +}; + +export function useRawPage( + path: string, + kind: string, + namespace: string, + name: string, +): AsyncState<RawPage> & { + retry(): void; +} { + const techdocsStorageApi = useApi(techdocsStorageApiRef); + + return useAsyncRetry(async () => { + const content = await techdocsStorageApi.getEntityDocs( + { kind, namespace, name }, + path, + ); + + return { + content, + path, + entityId: { + kind, + name, + namespace, + }, + }; + }, [techdocsStorageApi, kind, namespace, name, path]); +} From cb8c848a38d2e100288b46ba767258e83f5d9b15 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Mon, 26 Apr 2021 17:16:59 +0200 Subject: [PATCH 243/462] Disable color transitions on links to avoid issues in dark mode Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/techdocs-red-donkeys-share.md | 5 +++++ plugins/techdocs/src/reader/components/Reader.tsx | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 .changeset/techdocs-red-donkeys-share.md diff --git a/.changeset/techdocs-red-donkeys-share.md b/.changeset/techdocs-red-donkeys-share.md new file mode 100644 index 0000000000..29d932d0b8 --- /dev/null +++ b/.changeset/techdocs-red-donkeys-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Disable color transitions on links to avoid issues in dark mode. diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index ff4f47dca0..14fcb43700 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -197,10 +197,21 @@ export const Reader = ({ entityId, onReady }: Props) => { } .md-nav--primary > .md-nav__title [for="none"] { padding-top: 0; - } + } } `, }), + injectCss({ + // Disable CSS animations on link colors as they lead to issues in dark + // mode. The dark mode color theme is applied later and theirfore there + // is always an animation from light to dark mode when navigation + // between pages. + css: ` + .md-nav__link, .md-typeset a, .md-typeset a::before, .md-typeset .headerlink { + transition: none; + } + `, + }), injectCss({ // Admonitions and others are using SVG masks to define icons. These // masks are defined as CSS variables. From e1e757569fbb2f3b9b30ab48229ec2ef97cc0c7f Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Mon, 26 Apr 2021 17:32:54 +0200 Subject: [PATCH 244/462] prefix changeset with search Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- .changeset/{odd-ads-invite.md => search-odd-ads-invite.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changeset/{odd-ads-invite.md => search-odd-ads-invite.md} (100%) diff --git a/.changeset/odd-ads-invite.md b/.changeset/search-odd-ads-invite.md similarity index 100% rename from .changeset/odd-ads-invite.md rename to .changeset/search-odd-ads-invite.md From 24c24f384a327632f92767406ac6b8eb7aae46d6 Mon Sep 17 00:00:00 2001 From: Brenda Sukh <brendasukh@gmail.com> Date: Mon, 26 Apr 2021 14:14:22 -0400 Subject: [PATCH 245/462] Add stability index for cost insights Signed-off-by: Brenda Sukh <brendasukh@gmail.com> --- docs/overview/stability-index.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/overview/stability-index.md b/docs/overview/stability-index.md index 4172e4d1b7..6882f3d6c2 100644 --- a/docs/overview/stability-index.md +++ b/docs/overview/stability-index.md @@ -153,6 +153,13 @@ re-exported from @backstage/core, and this package should not be used directly. Stability: See @backstage/core +### `cost-insights` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/cost-insights) + +A frontend plugin that allows users to visualize, understand and optimize your +team's cloud costs. + +Stability: `1` + ### `create-app` [GitHub](https://github.com/backstage/backstage/tree/master/packages/create-app/) The CLI used to scaffold new Backstage projects. @@ -359,7 +366,7 @@ https://github.com/backstage/backstage/issues/2771. ### `tech-radar` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/tech-radar/) -Visualize the your company's official guidelines of different areas of software +Visualize your company's official guidelines of different areas of software development. Stability: `0` From f639a09f835f8c1e0485a6a936a7115dadb6152f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 17:40:43 +0200 Subject: [PATCH 246/462] root: add api-extractor dependency and friends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gustaf Räntilä <g.rantila@gmail.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- package.json | 6 ++ yarn.lock | 162 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 159 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index d87b98fbdb..b946019c0a 100644 --- a/package.json +++ b/package.json @@ -39,10 +39,16 @@ "**/@roadiehq/**/@backstage/core": "*", "**/@roadiehq/**/@backstage/plugin-catalog": "*", "**/@roadiehq/**/@backstage/catalog-model": "*", + "**/@microsoft/api-extractor/typescript": "^4.0.3", "graphql-language-service-interface": "2.8.2", "graphql-language-service-parser": "1.9.0" }, "version": "1.0.0", + "dependencies": { + "@microsoft/api-extractor": "7.13.2-pr1916.0", + "@microsoft/api-documenter": "^7.12.16", + "@microsoft/api-extractor-model": "^7.12.5" + }, "devDependencies": { "@changesets/cli": "^2.14.0", "@octokit/openapi-types": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index f2c2bee93c..98c3af5d2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3820,11 +3820,54 @@ dependencies: "@types/whatwg-streams" "^0.0.7" +"@microsoft/api-documenter@^7.12.16": + version "7.12.21" + resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.12.21.tgz#cdafcd4575d42e55eb8ca338a3a5fb868f9d5872" + integrity sha512-XZQKnMppgkTHeGh92fQ7kidT2Bxr3o775Mo9gP21+kTQs3LnvukHmSnFwBTHTXpvOq1wnkbT430dRvxdayWECQ== + dependencies: + "@microsoft/api-extractor-model" "7.12.5" + "@microsoft/tsdoc" "0.12.24" + "@rushstack/node-core-library" "3.36.2" + "@rushstack/ts-command-line" "4.7.10" + colors "~1.2.1" + js-yaml "~3.13.1" + resolve "~1.17.0" + +"@microsoft/api-extractor-model@7.12.5", "@microsoft/api-extractor-model@^7.12.5", "@microsoft/api-extractor-model@workspace:*": + version "7.12.5" + resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.12.5.tgz#28d2804865ceba9cd89ab4f05cff99d16fa6c9b8" + integrity sha512-oeHZW83JWjIVoCDvdwI5nsZGPxThbq4gZTLAYNeJGZE/mKEO0iayMPGmI3EllJBjwQsFvNVU+O/HGULhB2to/g== + dependencies: + "@microsoft/tsdoc" "0.12.24" + "@rushstack/node-core-library" "3.36.2" + +"@microsoft/api-extractor@7.13.2-pr1916.0": + version "7.13.2-pr1916.0" + resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.13.2-pr1916.0.tgz#2e10cb928ea81b56cd5f63264da11f1f9b9310a5" + integrity sha512-0/HajL+NUixuNGMfFZbHmKJn5VEqiF45q2FXhu8UrggutdJ+9M6wZ++fejUHfxlC/WhQVrVVRtf4xvVM3oIW+A== + dependencies: + "@microsoft/api-extractor-model" "workspace:*" + "@microsoft/tsdoc" "0.12.24" + "@rushstack/node-core-library" "workspace:*" + "@rushstack/rig-package" "workspace:*" + "@rushstack/ts-command-line" "workspace:*" + colors "~1.2.1" + lodash "~4.17.15" + resolve "~1.17.0" + semver "~7.3.0" + source-map "~0.6.1" + typescript "~4.1.3" + "@microsoft/microsoft-graph-types@^1.25.0": version "1.25.0" resolved "https://registry.npmjs.org/@microsoft/microsoft-graph-types/-/microsoft-graph-types-1.25.0.tgz#1f543ebc029a115dd1d48a1ae99d7ddd5ee9af57" integrity sha512-RsuA+ROaU3voWzG9TVBkRKxmLatteRGduFDi5p0k3FUHho49rm9SvrA7DUyYbSXLy2xXRx9AnjKM9klYBeKEiQ== +"@microsoft/tsdoc@0.12.24": + version "0.12.24" + resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz#30728e34ebc90351dd3aff4e18d038eed2c3e098" + integrity sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg== + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -4368,6 +4411,39 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@rushstack/node-core-library@3.36.2", "@rushstack/node-core-library@workspace:*": + version "3.36.2" + resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.2.tgz#ba00d313577f9b06d5aafaa29da0d94e594874c0" + integrity sha512-5J8xSY/PuCKR+yfxS497l0PP43kBUeD86S4eS3RzrmMle04J4522MWal8mk1T1EIDpYpgi8qScannU9oVxoStA== + dependencies: + "@types/node" "10.17.13" + colors "~1.2.1" + fs-extra "~7.0.1" + import-lazy "~4.0.0" + jju "~1.4.0" + resolve "~1.17.0" + semver "~7.3.0" + timsort "~0.3.0" + z-schema "~3.18.3" + +"@rushstack/rig-package@workspace:*": + version "0.2.12" + resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz#c434d62b28e0418a040938226f8913971d0424c7" + integrity sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ== + dependencies: + resolve "~1.17.0" + strip-json-comments "~3.1.1" + +"@rushstack/ts-command-line@4.7.10", "@rushstack/ts-command-line@workspace:*": + version "4.7.10" + resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.10.tgz#a2ec6efb1945b79b496671ce90eb1be4f1397d31" + integrity sha512-8t042g8eerypNOEcdpxwRA3uCmz0duMo21rG4Z2mdz7JxJeylDmzjlU3wDdef2t3P1Z61JCdZB6fbm1Mh0zi7w== + dependencies: + "@types/argparse" "1.0.38" + argparse "~1.0.9" + colors "~1.2.1" + string-argv "~0.3.1" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -5578,6 +5654,11 @@ dependencies: "@types/glob" "*" +"@types/argparse@1.0.38": + version "1.0.38" + resolved "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" + integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== + "@types/aria-query@^4.2.0": version "4.2.0" resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" @@ -6317,6 +6398,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-14.14.32.tgz#90c5c4a8d72bbbfe53033f122341343249183448" integrity sha512-/Ctrftx/zp4m8JOujM5ZhwzlWLx22nbQJiVqz8/zE15gOeEW+uly3FSX4fGFpcfEvFzXcMCJwq9lGVWgyARXhg== +"@types/node@10.17.13": + version "10.17.13" + resolved "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz#ccebcdb990bd6139cd16e84c39dc2fb1023ca90c" + integrity sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg== + "@types/node@^10.1.0", "@types/node@^10.12.0": version "10.17.35" resolved "https://registry.npmjs.org/@types/node/-/node-10.17.35.tgz#58058f29b870e6ae57b20e4f6e928f02b7129f56" @@ -7813,7 +7899,7 @@ arg@^4.1.0: resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== -argparse@^1.0.10, argparse@^1.0.7: +argparse@^1.0.10, argparse@^1.0.7, argparse@~1.0.9: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== @@ -9903,6 +9989,11 @@ colors@^1.1.2, colors@^1.2.1: resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== +colors@~1.2.1: + version "1.2.5" + resolved "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc" + integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg== + colorspace@1.1.x: version "1.1.2" resolved "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" @@ -9951,7 +10042,7 @@ commander@2.3.0: resolved "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= -commander@^2.19.0, commander@^2.20.0, commander@^2.20.3, commander@~2.20.3: +commander@^2.19.0, commander@^2.20.0, commander@^2.20.3, commander@^2.7.1, commander@~2.20.3: version "2.20.3" resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -13552,7 +13643,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^7.0.1: +fs-extra@^7.0.1, fs-extra@~7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== @@ -15200,6 +15291,11 @@ import-lazy@^2.1.0: resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= +import-lazy@~4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + import-local@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" @@ -16602,6 +16698,11 @@ jest@^26.0.1: import-local "^3.0.2" jest-cli "^26.6.3" +jju@~1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" + integrity sha1-o6vicYryQaKykE+EpiWXDzia4yo= + jmespath@0.15.0: version "0.15.0" resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" @@ -16682,6 +16783,14 @@ js-yaml@^4.0.0: dependencies: argparse "^2.0.1" +js-yaml@~3.13.1: + version "3.13.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -17672,7 +17781,7 @@ lodash.flattendeep@^4.0.0: resolved "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= -lodash.get@^4: +lodash.get@^4, lodash.get@^4.0.0: version "4.4.2" resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= @@ -17687,6 +17796,11 @@ lodash.isboolean@^3.0.3: resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" @@ -17772,7 +17886,7 @@ lodash@4.17.15: resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -lodash@4.x, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@~4.17.20, lodash@~4.17.4: +lodash@4.x, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@~4.17.15, lodash@~4.17.20, lodash@~4.17.4: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -22990,6 +23104,13 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17 is-core-module "^2.2.0" path-parse "^1.0.6" +resolve@~1.17.0: + version "1.17.0" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + responselike@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -23420,6 +23541,13 @@ semver@~5.3.0: resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= +semver@~7.3.0: + version "7.3.5" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -24300,7 +24428,7 @@ strict-uri-encode@^2.0.0: resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= -string-argv@0.3.1: +string-argv@0.3.1, string-argv@~0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== @@ -24526,7 +24654,7 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -25130,7 +25258,7 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" -timsort@^0.3.0: +timsort@^0.3.0, timsort@~0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= @@ -25632,7 +25760,7 @@ typescript-json-schema@^0.49.0: typescript "^4.1.3" yargs "^16.2.0" -typescript@^4.0.3, typescript@^4.1.3: +typescript@^4.0.3, typescript@^4.1.3, typescript@~4.1.3: version "4.2.3" resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== @@ -26198,6 +26326,11 @@ validate.io-number@^1.0.3: resolved "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz#f63ffeda248bf28a67a8d48e0e3b461a1665baf8" integrity sha1-9j/+2iSL8opnqNSODjtGGhZluvg= +validator@^8.0.0: + version "8.2.0" + resolved "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz#3c1237290e37092355344fef78c231249dab77b9" + integrity sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -27112,6 +27245,17 @@ yup@^0.29.3: synchronous-promise "^2.0.13" toposort "^2.0.2" +z-schema@~3.18.3: + version "3.18.4" + resolved "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz#ea8132b279533ee60be2485a02f7e3e42541a9a2" + integrity sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw== + dependencies: + lodash.get "^4.0.0" + lodash.isequal "^4.0.0" + validator "^8.0.0" + optionalDependencies: + commander "^2.7.1" + zen-observable-ts@^0.8.21: version "0.8.21" resolved "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d" From 482256023b82bdb07afb48e900cf082c12d7a081 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 17:57:18 +0200 Subject: [PATCH 247/462] scripts: add api-extractor script that generates API reports and documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gustaf Räntilä <g.rantila@gmail.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- package.json | 2 + scripts/api-extractor.ts | 264 +++++++++++++++++++++++++++++++++++++++ scripts/tsconfig.json | 6 + 3 files changed, 272 insertions(+) create mode 100644 scripts/api-extractor.ts create mode 100644 scripts/tsconfig.json diff --git a/package.json b/package.json index b946019c0a..f1faad5de7 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "start": "yarn workspace example-app start", "start-backend": "yarn workspace example-backend start", "build": "lerna run build", + "build:api-reports": "tsc && ts-node -T -P scripts/tsconfig.json scripts/api-extractor.ts", + "build:api-docs": "yarn build:api-reports --docs", "tsc": "tsc", "tsc:full": "tsc --skipLibCheck false --incremental false", "clean": "backstage-cli clean && lerna run clean", diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts new file mode 100644 index 0000000000..1cab49750f --- /dev/null +++ b/scripts/api-extractor.ts @@ -0,0 +1,264 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eslint-disable import/no-extraneous-dependencies */ + +// eslint-disable-next-line no-restricted-imports +import { resolve as resolvePath, join as joinPath, dirname } from 'path'; +import fs from 'fs-extra'; +import { + Extractor, + ExtractorConfig, + CompilerState, + ExtractorLogLevel, +} from '@microsoft/api-extractor'; +import { ApiPackage, ApiModel } from '@microsoft/api-extractor-model'; +import { MarkdownDocumenter } from '@microsoft/api-documenter/lib/documenters/MarkdownDocumenter'; + +const tmpDir = resolvePath(__dirname, '../node_modules/.cache/api-extractor'); + +/** + * Yup + */ +const { + PackageJsonLookup, +} = require('@rushstack/node-core-library/lib/PackageJsonLookup'); + +const old = PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor; +PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor = function tryGetPackageJsonFilePathForPatch( + path: string, +) { + if ( + path.includes('@material-ui') && + !dirname(path).endsWith('@material-ui') + ) { + return undefined; + } + return old.call(this, path); +}; + +const DOCUMENTED_PACKAGES = [ + 'packages/backend-common', + 'packages/catalog-client', + 'packages/catalog-model', + 'packages/cli-common', + 'packages/config', + 'packages/config-loader', + // 'packages/core', + // 'packages/core-api', + 'packages/dev-utils', + 'packages/errors', + 'packages/integration', + 'packages/integration-react', + 'packages/search-common', + 'packages/techdocs-common', + 'packages/test-utils', + 'packages/test-utils-core', + 'packages/theme', +]; + +interface ApiExtractionOptions { + packageDirs: string[]; + outputDir: string; + isLocalBuild: boolean; +} +async function runApiExtraction({ + packageDirs, + outputDir, + isLocalBuild, +}: ApiExtractionOptions) { + await fs.remove(outputDir); + + const entryPoints = packageDirs.map(packageDir => { + return resolvePath(__dirname, `../dist-types/${packageDir}/src/index.d.ts`); + }); + + let compilerState: CompilerState | undefined = undefined; + + for (const packageDir of packageDirs) { + console.log(`## Processing ${packageDir}`); + const projectFolder = resolvePath(__dirname, '..', packageDir); + const packagePath = resolvePath(__dirname, `../${packageDir}/package.json`); + + const extractorConfig = ExtractorConfig.prepare({ + configObject: { + mainEntryPointFilePath: resolvePath( + __dirname, + '../dist-types/packages/<unscopedPackageName>/src/index.d.ts', + ), + bundledPackages: [], + + compiler: { + tsconfigFilePath: resolvePath(__dirname, '../tsconfig.json'), + }, + + apiReport: { + enabled: true, + reportFileName: 'api-report.md', + reportFolder: projectFolder, + reportTempFolder: resolvePath(outputDir, '<unscopedPackageName>'), + }, + + docModel: { + enabled: true, + apiJsonFilePath: resolvePath( + outputDir, + '<unscopedPackageName>.api.json', + ), + }, + + dtsRollup: { + enabled: false, + }, + + tsdocMetadata: { + enabled: false, + }, + + messages: { + compilerMessageReporting: { + default: { + logLevel: 'warning' as ExtractorLogLevel.Warning, + addToApiReportFile: true, + }, + }, + extractorMessageReporting: { + default: { + logLevel: 'warning' as ExtractorLogLevel.Warning, + addToApiReportFile: true, + }, + }, + tsdocMessageReporting: { + default: { + logLevel: 'warning' as ExtractorLogLevel.Warning, + addToApiReportFile: true, + }, + }, + }, + + newlineKind: 'lf', + + projectFolder, + }, + configObjectFullPath: projectFolder, + packageJsonFullPath: packagePath, + }); + + if (!compilerState) { + compilerState = CompilerState.create(extractorConfig, { + additionalEntryPoints: entryPoints, + }); + } + + // Message verbosity can't be configured, so just skip the check instead + (Extractor as any)._checkCompilerCompatibility = () => {}; + + // Invoke API Extractor + const extractorResult = Extractor.invoke(extractorConfig, { + localBuild: isLocalBuild, + showVerboseMessages: false, + showDiagnostics: false, + compilerState, + }); + + if (!extractorResult.succeeded) { + throw new Error( + `API Extractor completed with ${extractorResult.errorCount} errors` + + ` and ${extractorResult.warningCount} warnings`, + ); + } + } +} + +function isComponentMember(member: any) { + // React components are annotated with @components, and we want to skip those + return Boolean(member.docComment.match(/\n\s*\**\s*@component/m)); +} + +async function buildDocs({ + inputDir, + outputDir, +}: { + inputDir: string; + outputDir: string; +}) { + const parseFile = async (filename: string): Promise<any> => { + console.log(`Reading ${filename}`); + return fs.readJson(resolvePath(inputDir, filename)); + }; + + const filenames = await fs.readdir(inputDir); + const serializedPackages = await Promise.all( + filenames + .filter(filename => filename.match(/\.api\.json$/i)) + .map(parseFile), + ); + + const newModel = new ApiModel(); + for (const serialized of serializedPackages) { + serialized.members[0].members = serialized.members[0].members.filter( + member => !isComponentMember(member), + ); + + const pkg = ApiPackage.deserialize( + serialized, + serialized.metadata, + ) as ApiPackage; + newModel.addMember(pkg); + } + + await fs.remove(outputDir); + await fs.ensureDir(outputDir); + + const documenter = new MarkdownDocumenter({ + apiModel: newModel, + documenterConfig: { + outputTarget: 'markdown', + newlineKind: '\n', + // De ba dålig kod + configFilePath: '', + configFile: {}, + } as any, + outputFolder: outputDir, + }); + + documenter.generateFiles(); +} + +async function main() { + const isCiBuild = process.argv.includes('--ci'); + const isDocsBuild = process.argv.includes('--docs'); + + console.log('# Generating package API reports'); + await runApiExtraction({ + packageDirs: DOCUMENTED_PACKAGES, + outputDir: tmpDir, + isLocalBuild: !isCiBuild, + }); + + if (isDocsBuild) { + console.log('# Generating package documentation'); + await buildDocs({ + inputDir: tmpDir, + outputDir: resolvePath(__dirname, '..', 'docs/reference'), + }); + } +} + +main().catch(error => { + console.error(error.stack || String(error)); + process.exit(1); +}); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 0000000000..c8d842173c --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "CommonJS" + } +} From 26dee60729efac52a53500086f5c0c4649d747e7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 18:13:00 +0200 Subject: [PATCH 248/462] scripts/api-extractor: better feedback for api-report mismatches Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- scripts/api-extractor.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 1cab49750f..e232170e9d 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -171,6 +171,28 @@ async function runApiExtraction({ localBuild: isLocalBuild, showVerboseMessages: false, showDiagnostics: false, + messageCallback(message) { + if ( + message.text.includes( + 'You have changed the public API signature for this project.', + ) + ) { + console.log(''); + console.log( + '*************************************************************************************', + ); + console.log( + '* You have uncommitted changes to the public API of a package. *', + ); + console.log( + '* To solve this, run `yarn build:api-reports` and commit all api-report.md changes. *', + ); + console.log( + '*************************************************************************************', + ); + console.log(''); + } + }, compilerState, }); From fecf70ae1aa2747e81a5c28ef3dcf8728505ee32 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 18:23:23 +0200 Subject: [PATCH 249/462] workflows: validate api reports in CI Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .github/workflows/ci.yml | 3 +++ package.json | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2337a70e2c..0a6d0f8589 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,9 @@ jobs: - name: type checking and declarations run: yarn tsc:full + - name: check api reports + run: yarn build:api-reports:only --ci + - name: build changed packages if: ${{ steps.yarn-lock.outcome == 'success' }} run: yarn lerna -- run build --since origin/master --include-dependencies diff --git a/package.json b/package.json index f1faad5de7..b0f79031de 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "start": "yarn workspace example-app start", "start-backend": "yarn workspace example-backend start", "build": "lerna run build", - "build:api-reports": "tsc && ts-node -T -P scripts/tsconfig.json scripts/api-extractor.ts", + "build:api-reports": "tsc && yarn build:api-reports:only", + "build:api-reports:only": "ts-node -T -P scripts/tsconfig.json scripts/api-extractor.ts", "build:api-docs": "yarn build:api-reports --docs", "tsc": "tsc", "tsc:full": "tsc --skipLibCheck false --incremental false", From a904d8ba5e82d0d8e60eba9b438f7970596e673d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 18:39:21 +0200 Subject: [PATCH 250/462] packages: add api-reports for all included packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gustaf Räntilä <g.rantila@gmail.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .prettierignore | 1 + packages/backend-common/api-report.md | 469 +++++++++++++ packages/catalog-client/api-report.md | 105 +++ packages/catalog-model/api-report.md | 811 +++++++++++++++++++++++ packages/cli-common/api-report.md | 35 + packages/config-loader/api-report.md | 72 ++ packages/config/api-report.md | 112 ++++ packages/dev-utils/api-report.md | 39 ++ packages/errors/api-report.md | 125 ++++ packages/integration-react/api-report.md | 32 + packages/integration/api-report.md | 414 ++++++++++++ packages/search-common/api-report.md | 70 ++ packages/techdocs-common/api-report.md | 259 ++++++++ packages/test-utils-core/api-report.md | 113 ++++ packages/test-utils/api-report.md | 109 +++ packages/theme/api-report.md | 130 ++++ 16 files changed, 2896 insertions(+) create mode 100644 packages/backend-common/api-report.md create mode 100644 packages/catalog-client/api-report.md create mode 100644 packages/catalog-model/api-report.md create mode 100644 packages/cli-common/api-report.md create mode 100644 packages/config-loader/api-report.md create mode 100644 packages/config/api-report.md create mode 100644 packages/dev-utils/api-report.md create mode 100644 packages/errors/api-report.md create mode 100644 packages/integration-react/api-report.md create mode 100644 packages/integration/api-report.md create mode 100644 packages/search-common/api-report.md create mode 100644 packages/techdocs-common/api-report.md create mode 100644 packages/test-utils-core/api-report.md create mode 100644 packages/test-utils/api-report.md create mode 100644 packages/theme/api-report.md diff --git a/.prettierignore b/.prettierignore index c4e675a5d7..e60d54a466 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,6 +4,7 @@ microsite coverage *.hbs templates +api-report.md plugins/scaffolder-backend/sample-templates .vscode dist-types diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md new file mode 100644 index 0000000000..bdef061eda --- /dev/null +++ b/packages/backend-common/api-report.md @@ -0,0 +1,469 @@ +## API Report File for "@backstage/backend-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { AzureIntegration } from '@backstage/integration'; +import { BitbucketIntegration } from '@backstage/integration'; +import { Config } from '@backstage/config'; +import { ConfigReader } from '@backstage/config'; +import cors from 'cors'; +import Docker from 'dockerode'; +import { ErrorRequestHandler } from 'express'; +import express from 'express'; +import { Format } from 'logform'; +import { GithubCredentialsProvider } from '@backstage/integration'; +import { GitHubIntegration } from '@backstage/integration'; +import { GitLabIntegration } from '@backstage/integration'; +import * as http from 'http'; +import { Knex } from 'knex'; +import { Logger } from 'winston'; +import { MergeResult } from 'isomorphic-git'; +import { PushResult } from 'isomorphic-git'; +import { Readable } from 'stream'; +import { ReadCommitResult } from 'isomorphic-git'; +import { RequestHandler } from 'express'; +import { Router } from 'express'; +import { Server } from 'http'; +import * as winston from 'winston'; +import { Writable } from 'stream'; + +// Warning: (ae-missing-release-tag) "AzureUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class AzureUrlReader implements UrlReader { + constructor(integration: AzureIntegration, deps: { + treeResponseFactory: ReadTreeResponseFactory; + }); + // Warning: (ae-forgotten-export) The symbol "ReaderFactory" needs to be exported by the entry point index.d.ts + // + // (undocumented) + static factory: ReaderFactory; + // (undocumented) + read(url: string): Promise<Buffer>; + // Warning: (ae-forgotten-export) The symbol "ReadTreeOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>; + // Warning: (ae-forgotten-export) The symbol "SearchOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + search(url: string, options?: SearchOptions): Promise<SearchResponse>; + // (undocumented) + toString(): string; +} + +// Warning: (ae-missing-release-tag) "BitbucketUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class BitbucketUrlReader implements UrlReader { + constructor(integration: BitbucketIntegration, deps: { + treeResponseFactory: ReadTreeResponseFactory; + }); + // (undocumented) + static factory: ReaderFactory; + // (undocumented) + read(url: string): Promise<Buffer>; + // (undocumented) + readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>; + // (undocumented) + search(url: string, options?: SearchOptions): Promise<SearchResponse>; + // (undocumented) + toString(): string; +} + +// Warning: (ae-missing-release-tag) "coloredFormat" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const coloredFormat: Format; + +// Warning: (ae-missing-release-tag) "createDatabase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public @deprecated +export const createDatabase: typeof createDatabaseClient; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "createDatabaseClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function createDatabaseClient(dbConfig: Config, overrides?: Partial<Knex.Config>): Knex<any, unknown[]>; + +// Warning: (ae-missing-release-tag) "createRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function createRootLogger(options?: winston.LoggerOptions, env?: NodeJS.ProcessEnv): winston.Logger; + +// Warning: (ae-forgotten-export) The symbol "ServiceBuilderImpl" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "createServiceBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function createServiceBuilder(_module: NodeModule): ServiceBuilderImpl; + +// Warning: (ae-forgotten-export) The symbol "StatusCheckRouterOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "createStatusCheckRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function createStatusCheckRouter(options: StatusCheckRouterOptions): Promise<express.Router>; + +// Warning: (ae-missing-release-tag) "ensureDatabaseExists" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function ensureDatabaseExists(dbConfig: Config, ...databases: Array<string>): Promise<void>; + +// Warning: (ae-missing-release-tag) "errorHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function errorHandler(options?: ErrorHandlerOptions): ErrorRequestHandler; + +// Warning: (ae-missing-release-tag) "ErrorHandlerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ErrorHandlerOptions = { + showStackTraces?: boolean; + logger?: Logger; + logClientErrors?: boolean; +}; + +// Warning: (ae-missing-release-tag) "getRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function getRootLogger(): winston.Logger; + +// Warning: (ae-missing-release-tag) "getVoidLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getVoidLogger(): winston.Logger; + +// Warning: (ae-missing-release-tag) "Git" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Git { + // (undocumented) + add({ dir, filepath, }: { + dir: string; + filepath: string; + }): Promise<void>; + // (undocumented) + addRemote({ dir, url, remote, }: { + dir: string; + remote: string; + url: string; + }): Promise<void>; + // (undocumented) + clone({ url, dir, ref, }: { + url: string; + dir: string; + ref?: string; + }): Promise<void>; + // (undocumented) + commit({ dir, message, author, committer, }: { + dir: string; + message: string; + author: { + name: string; + email: string; + }; + committer: { + name: string; + email: string; + }; + }): Promise<string>; + // (undocumented) + currentBranch({ dir, fullName, }: { + dir: string; + fullName?: boolean; + }): Promise<string | undefined>; + // (undocumented) + fetch({ dir, remote, }: { + dir: string; + remote?: string; + }): Promise<void>; + // (undocumented) + static fromAuth: ({ username, password, logger, }: { + username?: string | undefined; + password?: string | undefined; + logger?: Logger | undefined; + }) => Git; + // (undocumented) + init({ dir }: { + dir: string; + }): Promise<void>; + // (undocumented) + merge({ dir, theirs, ours, author, committer, }: { + dir: string; + theirs: string; + ours?: string; + author: { + name: string; + email: string; + }; + committer: { + name: string; + email: string; + }; + }): Promise<MergeResult>; + // (undocumented) + push({ dir, remote }: { + dir: string; + remote: string; + }): Promise<PushResult>; + // (undocumented) + readCommit({ dir, sha, }: { + dir: string; + sha: string; + }): Promise<ReadCommitResult>; + // (undocumented) + resolveRef({ dir, ref, }: { + dir: string; + ref: string; + }): Promise<string>; +} + +// Warning: (ae-missing-release-tag) "GithubUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class GithubUrlReader implements UrlReader { + constructor(integration: GitHubIntegration, deps: { + treeResponseFactory: ReadTreeResponseFactory; + credentialsProvider: GithubCredentialsProvider; + }); + // (undocumented) + static factory: ReaderFactory; + // (undocumented) + read(url: string): Promise<Buffer>; + // (undocumented) + readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>; + // (undocumented) + search(url: string, options?: SearchOptions): Promise<SearchResponse>; + // (undocumented) + toString(): string; +} + +// Warning: (ae-missing-release-tag) "GitlabUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class GitlabUrlReader implements UrlReader { + constructor(integration: GitLabIntegration, deps: { + treeResponseFactory: ReadTreeResponseFactory; + }); + // (undocumented) + static factory: ReaderFactory; + // (undocumented) + read(url: string): Promise<Buffer>; + // (undocumented) + readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>; + // (undocumented) + search(url: string, options?: SearchOptions): Promise<SearchResponse>; + // (undocumented) + toString(): string; +} + +// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "loadBackendConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function loadBackendConfig(options: Options): Promise<Config>; + +// Warning: (ae-missing-release-tag) "notFoundHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function notFoundHandler(): RequestHandler; + +// Warning: (ae-missing-release-tag) "PluginDatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface PluginDatabaseManager { + getClient(): Promise<Knex>; +} + +// Warning: (ae-missing-release-tag) "PluginEndpointDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PluginEndpointDiscovery = { + getBaseUrl(pluginId: string): Promise<string>; + getExternalBaseUrl(pluginId: string): Promise<string>; +}; + +// Warning: (ae-missing-release-tag) "ReadTreeResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ReadTreeResponse = { + files(): Promise<ReadTreeResponseFile[]>; + archive(): Promise<NodeJS.ReadableStream>; + dir(options?: ReadTreeResponseDirOptions): Promise<string>; + etag: string; +}; + +// Warning: (ae-missing-release-tag) "ReadTreeResponseFile" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ReadTreeResponseFile = { + path: string; + content(): Promise<Buffer>; +}; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "requestLoggingHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function requestLoggingHandler(logger?: Logger): RequestHandler; + +// Warning: (ae-missing-release-tag) "resolvePackagePath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function resolvePackagePath(name: string, ...paths: string[]): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (ae-forgotten-export) The symbol "RunDockerContainerOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "runDockerContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const runDockerContainer: ({ imageName, args, logStream, dockerClient, mountDirs, workingDir, envVars, createOptions, }: RunDockerContainerOptions) => Promise<{ + error: any; + statusCode: any; +}>; + +// Warning: (ae-missing-release-tag) "SearchResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type SearchResponse = { + files: SearchResponseFile[]; + etag: string; +}; + +// Warning: (ae-missing-release-tag) "SearchResponseFile" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type SearchResponseFile = { + url: string; + content(): Promise<Buffer>; +}; + +// Warning: (ae-missing-release-tag) "ServiceBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ServiceBuilder = { + loadConfig(config: ConfigReader): ServiceBuilder; + setPort(port: number): ServiceBuilder; + setHost(host: string): ServiceBuilder; + setLogger(logger: Logger): ServiceBuilder; + enableCors(options: cors.CorsOptions): ServiceBuilder; + setHttpsSettings(settings: HttpsSettings): ServiceBuilder; + addRouter(root: string, router: Router | RequestHandler): ServiceBuilder; + start(): Promise<Server>; +}; + +// Warning: (ae-missing-release-tag) "setRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function setRootLogger(newLogger: winston.Logger): void; + +// Warning: (ae-missing-release-tag) "SingleConnectionDatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class SingleConnectionDatabaseManager { + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + forPlugin(pluginId: string): PluginDatabaseManager; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + static fromConfig(config: Config): SingleConnectionDatabaseManager; + } + +// Warning: (ae-missing-release-tag) "SingleHostDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class SingleHostDiscovery implements PluginEndpointDiscovery { + static fromConfig(config: Config, options?: { + basePath?: string; + }): SingleHostDiscovery; + // (undocumented) + getBaseUrl(pluginId: string): Promise<string>; + // (undocumented) + getExternalBaseUrl(pluginId: string): Promise<string>; + } + +// Warning: (ae-missing-release-tag) "StatusCheck" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type StatusCheck = () => Promise<any>; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "statusCheckHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function statusCheckHandler(options?: StatusCheckHandlerOptions): Promise<RequestHandler>; + +// Warning: (ae-missing-release-tag) "StatusCheckHandlerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface StatusCheckHandlerOptions { + statusCheck?: StatusCheck; +} + +// Warning: (ae-missing-release-tag) "UrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type UrlReader = { + read(url: string): Promise<Buffer>; + readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>; + search(url: string, options?: SearchOptions): Promise<SearchResponse>; +}; + +// Warning: (ae-missing-release-tag) "UrlReaders" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class UrlReaders { + // Warning: (ae-forgotten-export) The symbol "CreateOptions" needs to be exported by the entry point index.d.ts + static create({ logger, config, factories }: CreateOptions): UrlReader; + static default({ logger, config, factories }: CreateOptions): UrlReader; +} + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "useHotCleanup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function useHotCleanup(_module: NodeModule, cancelEffect: () => void): void; + +// Warning: (tsdoc-undefined-tag) The TSDoc tag "@warning" is not defined in this configuration +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "useHotMemoize" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T; + + +// Warnings were encountered during analysis: +// +// src/middleware/errorHandler.ts:47:24 - (tsdoc-malformed-html-name) Invalid HTML element: A space is not allowed here +// src/reading/AzureUrlReader.ts:53:30 - (ae-forgotten-export) The symbol "ReadTreeResponseFactory" needs to be exported by the entry point index.d.ts +// src/reading/types.ts:87:3 - (ae-forgotten-export) The symbol "ReadTreeResponseDirOptions" needs to be exported by the entry point index.d.ts +// src/service/types.ts:28:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:39:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:48:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:57:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:67:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:76:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:78:3 - (ae-forgotten-export) The symbol "HttpsSettings" needs to be exported by the entry point index.d.ts +// src/service/types.ts:83:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/service/types.ts:84:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md new file mode 100644 index 0000000000..fe12d3a62c --- /dev/null +++ b/packages/catalog-client/api-report.md @@ -0,0 +1,105 @@ +## API Report File for "@backstage/catalog-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Entity } from '@backstage/catalog-model'; +import { EntityName } from '@backstage/catalog-model'; +import { Location as Location_2 } from '@backstage/catalog-model'; + +// Warning: (ae-missing-release-tag) "AddLocationRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AddLocationRequest = { + type?: string; + target: string; + dryRun?: boolean; + presence?: 'optional' | 'required'; +}; + +// Warning: (ae-missing-release-tag) "AddLocationResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AddLocationResponse = { + location: Location_2; + entities: Entity[]; +}; + +// Warning: (ae-missing-release-tag) "CatalogApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface CatalogApi { + // (undocumented) + addLocation(location: AddLocationRequest, options?: CatalogRequestOptions): Promise<AddLocationResponse>; + // Warning: (ae-forgotten-export) The symbol "CatalogRequestOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + getEntities(request?: CatalogEntitiesRequest, options?: CatalogRequestOptions): Promise<CatalogListResponse<Entity>>; + // (undocumented) + getEntityByName(name: EntityName, options?: CatalogRequestOptions): Promise<Entity | undefined>; + // (undocumented) + getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + // (undocumented) + getLocationById(id: String, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + // (undocumented) + getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + // (undocumented) + removeEntityByUid(uid: string, options?: CatalogRequestOptions): Promise<void>; + // (undocumented) + removeLocationById(id: string, options?: CatalogRequestOptions): Promise<void>; +} + +// Warning: (ae-missing-release-tag) "CatalogClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class CatalogClient implements CatalogApi { + constructor(options: { + discoveryApi: DiscoveryApi; + }); + // (undocumented) + addLocation({ type, target, dryRun, presence }: AddLocationRequest, options?: CatalogRequestOptions): Promise<AddLocationResponse>; + // (undocumented) + getEntities(request?: CatalogEntitiesRequest, options?: CatalogRequestOptions): Promise<CatalogListResponse<Entity>>; + // (undocumented) + getEntityByName(compoundName: EntityName, options?: CatalogRequestOptions): Promise<Entity | undefined>; + // (undocumented) + getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + // (undocumented) + getLocationById(id: String, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + // (undocumented) + getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + // (undocumented) + removeEntityByUid(uid: string, options?: CatalogRequestOptions): Promise<void>; + // (undocumented) + removeLocationById(id: string, options?: CatalogRequestOptions): Promise<void>; + } + +// Warning: (ae-missing-release-tag) "CatalogEntitiesRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type CatalogEntitiesRequest = { + filter?: Record<string, string | string[]> | undefined; + fields?: string[] | undefined; +}; + +// Warning: (ae-missing-release-tag) "CatalogListResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type CatalogListResponse<T> = { + items: T[]; +}; + + +// Warnings were encountered during analysis: +// +// src/CatalogClient.ts:40:26 - (ae-forgotten-export) The symbol "DiscoveryApi" needs to be exported by the entry point index.d.ts +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md new file mode 100644 index 0000000000..b3e3303589 --- /dev/null +++ b/packages/catalog-model/api-report.md @@ -0,0 +1,811 @@ +## API Report File for "@backstage/catalog-model" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { JsonObject } from '@backstage/config'; +import { JSONSchema7 } from 'json-schema'; +import { JsonValue } from '@backstage/config'; +import * as yup from 'yup'; + +// Warning: (ae-missing-release-tag) "analyzeLocationSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const analyzeLocationSchema: yup.ObjectSchema<{ + location: LocationSpec; +}, object>; + +// Warning: (ae-missing-release-tag) "ApiEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface ApiEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND; + // (undocumented) + spec: { + type: string; + lifecycle: string; + owner: string; + definition: string; + system?: string; + }; +} + +export { ApiEntityV1alpha1 as ApiEntity } + +export { ApiEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "apiEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const apiEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "CommonValidatorFunctions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class CommonValidatorFunctions { + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + static isJsonSafe(value: unknown): boolean; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool + static isValidDnsLabel(value: unknown): boolean; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool + static isValidDnsSubdomain(value: unknown): boolean; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + static isValidPrefixAndOrSuffix(value: unknown, separator: string, isValidPrefix: (value: string) => boolean, isValidSuffix: (value: string) => boolean): boolean; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + static isValidString(value: unknown): boolean; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + static isValidUrl(value: unknown): boolean; +} + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-forgotten-export) The symbol "EntityRefContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "compareEntityToRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function compareEntityToRef(entity: Entity, ref: EntityRef | EntityName, context?: EntityRefContext): boolean; + +// Warning: (ae-missing-release-tag) "ComponentEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface ComponentEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_2[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_2; + // (undocumented) + spec: { + type: string; + lifecycle: string; + owner: string; + subcomponentOf?: string; + providesApis?: string[]; + consumesApis?: string[]; + system?: string; + }; +} + +export { ComponentEntityV1alpha1 as ComponentEntity } + +export { ComponentEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "componentEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const componentEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "DefaultNamespaceEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class DefaultNamespaceEntityPolicy implements EntityPolicy { + constructor(namespace?: string); + // (undocumented) + enforce(entity: Entity): Promise<Entity>; + } + +// Warning: (ae-missing-release-tag) "DomainEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface DomainEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_3[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_3; + // (undocumented) + spec: { + owner: string; + }; +} + +export { DomainEntityV1alpha1 as DomainEntity } + +export { DomainEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "domainEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const domainEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "EDIT_URL_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const EDIT_URL_ANNOTATION = "backstage.io/edit-url"; + +// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool +// Warning: (ae-missing-release-tag) "Entity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type Entity = { + apiVersion: string; + kind: string; + metadata: EntityMeta; + spec?: JsonObject; + relations?: EntityRelation[]; +}; + +// Warning: (ae-missing-release-tag) "ENTITY_DEFAULT_NAMESPACE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const ENTITY_DEFAULT_NAMESPACE = "default"; + +// Warning: (ae-missing-release-tag) "ENTITY_META_GENERATED_FIELDS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const ENTITY_META_GENERATED_FIELDS: readonly ["uid", "etag", "generation"]; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "entityHasChanges" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function entityHasChanges(previous: Entity, next: Entity): boolean; + +// Warning: (ae-missing-release-tag) "EntityLink" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityLink = { + url: string; + title?: string; + icon?: string; +}; + +// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool +// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool +// Warning: (ae-missing-release-tag) "EntityMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityMeta = JsonObject & { + uid?: string; + etag?: string; + generation?: number; + name: string; + namespace?: string; + description?: string; + labels?: Record<string, string>; + annotations?: Record<string, string>; + tags?: string[]; + links?: EntityLink[]; +}; + +// Warning: (ae-missing-release-tag) "EntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityName = { + kind: string; + namespace: string; + name: string; +}; + +// Warning: (ae-missing-release-tag) "EntityPolicies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const EntityPolicies: { + allOf(policies: EntityPolicy[]): AllEntityPolicies; + oneOf(policies: EntityPolicy[]): AnyEntityPolicy; +}; + +// Warning: (ae-missing-release-tag) "EntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityPolicy = { + enforce(entity: Entity): Promise<Entity | undefined>; +}; + +// Warning: (ae-missing-release-tag) "EntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityRef = string | { + kind?: string; + namespace?: string; + name: string; +}; + +// Warning: (ae-missing-release-tag) "EntityRelation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityRelation = { + type: string; + target: EntityName; +}; + +// Warning: (ae-missing-release-tag) "EntityRelationSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EntityRelationSpec = { + source: EntityName; + type: string; + target: EntityName; +}; + +// Warning: (ae-missing-release-tag) "FieldFormatEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class FieldFormatEntityPolicy implements EntityPolicy { + constructor(validators?: Validators); + // (undocumented) + enforce(entity: Entity): Promise<Entity>; + } + +// Warning: (ae-missing-release-tag) "generateEntityEtag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function generateEntityEtag(): string; + +// Warning: (ae-missing-release-tag) "generateEntityUid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function generateEntityUid(): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "generateUpdatedEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function generateUpdatedEntity(previous: Entity, next: Entity): Entity; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getEntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getEntityName(entity: Entity): EntityName; + +// Warning: (ae-missing-release-tag) "GroupEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface GroupEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_4[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_4; + // (undocumented) + spec: { + type: string; + profile?: { + displayName?: string; + email?: string; + picture?: string; + }; + parent?: string; + children: string[]; + members?: string[]; + }; +} + +export { GroupEntityV1alpha1 as GroupEntity } + +export { GroupEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "groupEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const groupEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "JSONSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type JSONSchema = JSONSchema7 & { + [key in string]?: JsonValue; +}; + +// Warning: (ae-missing-release-tag) "KindValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type KindValidator = { + check(entity: Entity): Promise<boolean>; +}; + +// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool +// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool +// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool +// Warning: (ae-missing-release-tag) "KubernetesValidatorFunctions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class KubernetesValidatorFunctions { + // (undocumented) + static isValidAnnotationKey(value: unknown): boolean; + // (undocumented) + static isValidAnnotationValue(value: unknown): boolean; + // (undocumented) + static isValidApiVersion(value: unknown): boolean; + // (undocumented) + static isValidKind(value: unknown): boolean; + // (undocumented) + static isValidLabelKey(value: unknown): boolean; + // (undocumented) + static isValidLabelValue(value: unknown): boolean; + // (undocumented) + static isValidNamespace(value: unknown): boolean; + // (undocumented) + static isValidObjectName(value: unknown): boolean; +} + +// Warning: (ae-missing-release-tag) "Location" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +type Location_2 = { + id: string; +} & LocationSpec; + +export { Location_2 as Location } + +// Warning: (ae-missing-release-tag) "LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const LOCATION_ANNOTATION = "backstage.io/managed-by-location"; + +// Warning: (ae-missing-release-tag) "LocationEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface LocationEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_5[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_5; + // (undocumented) + spec: { + type?: string; + target?: string; + targets?: string[]; + }; +} + +export { LocationEntityV1alpha1 as LocationEntity } + +export { LocationEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "locationEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const locationEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "locationSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const locationSchema: yup.ObjectSchema<Location_2, object>; + +// Warning: (ae-missing-release-tag) "LocationSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LocationSpec = { + type: string; + target: string; + presence?: 'optional' | 'required'; +}; + +// Warning: (ae-missing-release-tag) "locationSpecSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const locationSpecSchema: yup.ObjectSchema<LocationSpec, object>; + +// Warning: (ae-missing-release-tag) "makeValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function makeValidator(overrides?: Partial<Validators>): Validators; + +// Warning: (ae-missing-release-tag) "NoForeignRootFieldsEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class NoForeignRootFieldsEntityPolicy implements EntityPolicy { + constructor(knownFields?: string[]); + // (undocumented) + enforce(entity: Entity): Promise<Entity>; + } + +// Warning: (ae-missing-release-tag) "ORIGIN_LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const ORIGIN_LOCATION_ANNOTATION = "backstage.io/managed-by-origin-location"; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "parseEntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function parseEntityName(ref: EntityRef, context?: EntityRefContext): EntityName; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function parseEntityRef(ref: EntityRef, context?: { + defaultKind: string; + defaultNamespace: string; +}): { + kind: string; + namespace: string; + name: string; +}; + +// @public (undocumented) +export function parseEntityRef(ref: EntityRef, context?: { + defaultKind: string; +}): { + kind: string; + namespace?: string; + name: string; +}; + +// @public (undocumented) +export function parseEntityRef(ref: EntityRef, context?: { + defaultNamespace: string; +}): { + kind?: string; + namespace: string; + name: string; +}; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (ae-missing-release-tag) "parseLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function parseLocationReference(ref: string): { + type: string; + target: string; +}; + +// Warning: (ae-missing-release-tag) "RELATION_API_CONSUMED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_API_CONSUMED_BY = "apiConsumedBy"; + +// Warning: (ae-missing-release-tag) "RELATION_API_PROVIDED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_API_PROVIDED_BY = "apiProvidedBy"; + +// Warning: (ae-missing-release-tag) "RELATION_CHILD_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_CHILD_OF = "childOf"; + +// Warning: (ae-missing-release-tag) "RELATION_CONSUMES_API" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const RELATION_CONSUMES_API = "consumesApi"; + +// Warning: (ae-missing-release-tag) "RELATION_DEPENDENCY_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_DEPENDENCY_OF = "dependencyOf"; + +// Warning: (ae-missing-release-tag) "RELATION_DEPENDS_ON" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const RELATION_DEPENDS_ON = "dependsOn"; + +// Warning: (ae-missing-release-tag) "RELATION_HAS_MEMBER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_HAS_MEMBER = "hasMember"; + +// Warning: (ae-missing-release-tag) "RELATION_HAS_PART" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_HAS_PART = "hasPart"; + +// Warning: (ae-missing-release-tag) "RELATION_MEMBER_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const RELATION_MEMBER_OF = "memberOf"; + +// Warning: (ae-missing-release-tag) "RELATION_OWNED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const RELATION_OWNED_BY = "ownedBy"; + +// Warning: (ae-missing-release-tag) "RELATION_OWNER_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_OWNER_OF = "ownerOf"; + +// Warning: (ae-missing-release-tag) "RELATION_PARENT_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const RELATION_PARENT_OF = "parentOf"; + +// Warning: (ae-missing-release-tag) "RELATION_PART_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const RELATION_PART_OF = "partOf"; + +// Warning: (ae-missing-release-tag) "RELATION_PROVIDES_API" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const RELATION_PROVIDES_API = "providesApi"; + +// Warning: (ae-missing-release-tag) "ResourceEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface ResourceEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_6[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_6; + // (undocumented) + spec: { + type: string; + owner: string; + system?: string; + }; +} + +export { ResourceEntityV1alpha1 as ResourceEntity } + +export { ResourceEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "resourceEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const resourceEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "schemaValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public @deprecated (undocumented) +export function schemaValidator(kind: string, apiVersion: readonly string[], schema: yup.Schema<any>): KindValidator; + +// Warning: (ae-missing-release-tag) "SchemaValidEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class SchemaValidEntityPolicy implements EntityPolicy { + // (undocumented) + enforce(entity: Entity): Promise<Entity>; + } + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "serializeEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public @deprecated +export function serializeEntityRef(ref: Entity | { + kind?: string; + namespace?: string; + name: string; +}): EntityRef; + +// Warning: (ae-missing-release-tag) "SOURCE_LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const SOURCE_LOCATION_ANNOTATION = "backstage.io/source-location"; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "stringifyEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function stringifyEntityRef(ref: Entity | { + kind: string; + namespace?: string; + name: string; +}): string; + +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "stringifyLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function stringifyLocationReference(ref: { + type: string; + target: string; +}): string; + +// Warning: (ae-missing-release-tag) "SystemEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface SystemEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_7[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_7; + // (undocumented) + spec: { + owner: string; + domain?: string; + }; +} + +export { SystemEntityV1alpha1 as SystemEntity } + +export { SystemEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "systemEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const systemEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "TemplateEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface TemplateEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_8[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_8; + // (undocumented) + spec: { + type: string; + templater: string; + path?: string; + schema: JSONSchema; + }; +} + +export { TemplateEntityV1alpha1 as TemplateEntity } + +export { TemplateEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "templateEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const templateEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "TemplateEntityV1beta2" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface TemplateEntityV1beta2 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_9[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_9; + // (undocumented) + metadata: EntityMeta & { + title?: string; + }; + // (undocumented) + spec: { + type: string; + parameters?: JsonObject | JsonObject[]; + steps: Array<{ + id?: string; + name?: string; + action: string; + parameters?: JsonObject; + }>; + output?: { + [name: string]: string; + }; + }; +} + +// Warning: (ae-missing-release-tag) "templateEntityV1beta2Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const templateEntityV1beta2Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "UserEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +interface UserEntityV1alpha1 extends Entity { + // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + apiVersion: typeof API_VERSION_10[number]; + // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kind: typeof KIND_10; + // (undocumented) + spec: { + profile?: { + displayName?: string; + email?: string; + picture?: string; + }; + memberOf: string[]; + }; +} + +export { UserEntityV1alpha1 as UserEntity } + +export { UserEntityV1alpha1 } + +// Warning: (ae-missing-release-tag) "userEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const userEntityV1alpha1Validator: KindValidator; + +// Warning: (ae-missing-release-tag) "Validators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Validators = { + isValidApiVersion(value: unknown): boolean; + isValidKind(value: unknown): boolean; + isValidEntityName(value: unknown): boolean; + isValidNamespace(value: unknown): boolean; + isValidLabelKey(value: unknown): boolean; + isValidLabelValue(value: unknown): boolean; + isValidAnnotationKey(value: unknown): boolean; + isValidAnnotationValue(value: unknown): boolean; + isValidTag(value: unknown): boolean; +}; + +// Warning: (ae-missing-release-tag) "VIEW_URL_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const VIEW_URL_ANNOTATION = "backstage.io/view-url"; + + +// Warnings were encountered during analysis: +// +// src/EntityPolicies.ts:55:28 - (ae-forgotten-export) The symbol "AllEntityPolicies" needs to be exported by the entry point index.d.ts +// src/EntityPolicies.ts:57:3 - (ae-forgotten-export) The symbol "AnyEntityPolicy" needs to be exported by the entry point index.d.ts +// src/entity/policies/types.ts:27:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/kinds/types.ts:26:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/cli-common/api-report.md b/packages/cli-common/api-report.md new file mode 100644 index 0000000000..81d494e4ef --- /dev/null +++ b/packages/cli-common/api-report.md @@ -0,0 +1,35 @@ +## API Report File for "@backstage/cli-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +// Warning: (ae-missing-release-tag) "findPaths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function findPaths(searchDir: string): Paths; + +// Warning: (ae-missing-release-tag) "Paths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Paths = { + ownDir: string; + ownRoot: string; + targetDir: string; + targetRoot: string; + resolveOwn: ResolveFunc; + resolveOwnRoot: ResolveFunc; + resolveTarget: ResolveFunc; + resolveTargetRoot: ResolveFunc; +}; + +// Warnings were encountered during analysis: +// +// src/paths.ts:38:3 - (ae-forgotten-export) The symbol "ResolveFunc" needs to be exported by the entry point index.d.ts +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md new file mode 100644 index 0000000000..0c011aea65 --- /dev/null +++ b/packages/config-loader/api-report.md @@ -0,0 +1,72 @@ +## API Report File for "@backstage/config-loader" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { AppConfig } from '@backstage/config'; +import { JsonObject } from '@backstage/config'; +import { JSONSchema7 } from 'json-schema'; + +// Warning: (ae-missing-release-tag) "ConfigSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ConfigSchema = { + process(appConfigs: AppConfig[], options?: ConfigProcessingOptions): AppConfig[]; + serialize(): JsonObject; +}; + +// Warning: (ae-forgotten-export) The symbol "CONFIG_VISIBILITIES" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ConfigVisibility" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ConfigVisibility = typeof CONFIG_VISIBILITIES[number]; + +// Warning: (ae-missing-release-tag) "loadConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function loadConfig(options: LoadConfigOptions): Promise<AppConfig[]>; + +// Warning: (ae-missing-release-tag) "LoadConfigOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LoadConfigOptions = { + configRoot: string; + configPaths: string[]; + env?: string; + experimentalEnvFunc?: EnvFunc; +}; + +// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "loadConfigSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function loadConfigSchema(options: Options): Promise<ConfigSchema>; + +// Warning: (ae-missing-release-tag) "mergeConfigSchemas" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function mergeConfigSchemas(schemas: JSONSchema7[]): JSONSchema7; + +// Warning: (ae-missing-release-tag) "readEnvConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readEnvConfig(env: { + [name: string]: string | undefined; +}): AppConfig[]; + + +// Warnings were encountered during analysis: +// +// src/lib/schema/types.ts:105:3 - (ae-forgotten-export) The symbol "ConfigProcessingOptions" needs to be exported by the entry point index.d.ts +// src/loader.ts:42:6 - (tsdoc-unsupported-tag) The TSDoc tag "@experimental" is not supported by this tool +// src/loader.ts:44:3 - (ae-forgotten-export) The symbol "EnvFunc" needs to be exported by the entry point index.d.ts +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/config/api-report.md b/packages/config/api-report.md new file mode 100644 index 0000000000..8ff881a34b --- /dev/null +++ b/packages/config/api-report.md @@ -0,0 +1,112 @@ +## API Report File for "@backstage/config" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// Warning: (ae-missing-release-tag) "AppConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AppConfig = { + context: string; + data: JsonObject; +}; + +// Warning: (ae-missing-release-tag) "Config" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Config = { + has(key: string): boolean; + keys(): string[]; + get<T = JsonValue>(key?: string): T; + getOptional<T = JsonValue>(key?: string): T | undefined; + getConfig(key: string): Config; + getOptionalConfig(key: string): Config | undefined; + getConfigArray(key: string): Config[]; + getOptionalConfigArray(key: string): Config[] | undefined; + getNumber(key: string): number; + getOptionalNumber(key: string): number | undefined; + getBoolean(key: string): boolean; + getOptionalBoolean(key: string): boolean | undefined; + getString(key: string): string; + getOptionalString(key: string): string | undefined; + getStringArray(key: string): string[]; + getOptionalStringArray(key: string): string[] | undefined; +}; + +// Warning: (ae-missing-release-tag) "ConfigReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ConfigReader implements Config { + constructor(data: JsonObject | undefined, context?: string, fallback?: ConfigReader | undefined, prefix?: string); + // (undocumented) + static fromConfigs(configs: AppConfig[]): ConfigReader; + // (undocumented) + get<T = JsonValue>(key?: string): T; + // (undocumented) + getBoolean(key: string): boolean; + // (undocumented) + getConfig(key: string): ConfigReader; + // (undocumented) + getConfigArray(key: string): ConfigReader[]; + // (undocumented) + getNumber(key: string): number; + // (undocumented) + getOptional<T = JsonValue>(key?: string): T | undefined; + // (undocumented) + getOptionalBoolean(key: string): boolean | undefined; + // (undocumented) + getOptionalConfig(key: string): ConfigReader | undefined; + // (undocumented) + getOptionalConfigArray(key: string): ConfigReader[] | undefined; + // (undocumented) + getOptionalNumber(key: string): number | undefined; + // (undocumented) + getOptionalString(key: string): string | undefined; + // (undocumented) + getOptionalStringArray(key: string): string[] | undefined; + // (undocumented) + getString(key: string): string; + // (undocumented) + getStringArray(key: string): string[]; + // (undocumented) + has(key: string): boolean; + // (undocumented) + keys(): string[]; + } + +// Warning: (ae-missing-release-tag) "JsonArray" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface JsonArray extends Array<JsonValue> { +} + +// Warning: (ae-missing-release-tag) "JsonObject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type JsonObject = { + [key in string]?: JsonValue; +}; + +// Warning: (ae-missing-release-tag) "JsonPrimitive" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type JsonPrimitive = number | string | boolean | null; + +// Warning: (ae-missing-release-tag) "JsonValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type JsonValue = JsonObject | JsonArray | JsonPrimitive; + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md new file mode 100644 index 0000000000..41c793e189 --- /dev/null +++ b/packages/dev-utils/api-report.md @@ -0,0 +1,39 @@ +## API Report File for "@backstage/dev-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ApiFactory } from '@backstage/core'; +import { ComponentType } from 'react'; +import { createPlugin } from '@backstage/core'; +import { Entity } from '@backstage/catalog-model'; +import { GridProps } from '@material-ui/core'; +import { IconComponent } from '@backstage/core'; +import { ReactNode } from 'react'; + +// Warning: (ae-forgotten-export) The symbol "DevAppBuilder" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "createDevApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function createDevApp(): DevAppBuilder; + +// Warning: (ae-missing-release-tag) "EntityGridItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const EntityGridItem: ({ entity, classes, ...rest }: Omit<GridProps<"div", {}>, "container" | "item"> & { + entity: Entity; +}) => JSX.Element; + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/errors/api-report.md b/packages/errors/api-report.md new file mode 100644 index 0000000000..2a4b482463 --- /dev/null +++ b/packages/errors/api-report.md @@ -0,0 +1,125 @@ +## API Report File for "@backstage/errors" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { JsonObject } from '@backstage/config'; + +// Warning: (ae-missing-release-tag) "AuthenticationError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class AuthenticationError extends CustomErrorBase { +} + +// Warning: (ae-missing-release-tag) "ConflictError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class ConflictError extends CustomErrorBase { +} + +// Warning: (ae-missing-release-tag) "CustomErrorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class CustomErrorBase extends Error { + constructor(message?: string, cause?: Error); + // (undocumented) + readonly cause?: Error; +} + +// Warning: (ae-missing-release-tag) "deserializeError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function deserializeError<T extends Error = Error>(data: SerializedError): T; + +// Warning: (ae-missing-release-tag) "ErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ErrorResponse = { + error: SerializedError; + request?: { + method: string; + url: string; + }; + response: { + statusCode: number; + }; +}; + +// Warning: (ae-missing-release-tag) "InputError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class InputError extends CustomErrorBase { +} + +// Warning: (ae-missing-release-tag) "NotAllowedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class NotAllowedError extends CustomErrorBase { +} + +// Warning: (ae-missing-release-tag) "NotFoundError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class NotFoundError extends CustomErrorBase { +} + +// Warning: (ae-missing-release-tag) "NotModifiedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class NotModifiedError extends CustomErrorBase { +} + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "parseErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function parseErrorResponse(response: Response): Promise<ErrorResponse>; + +// Warning: (ae-missing-release-tag) "ResponseError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class ResponseError extends Error { + constructor(props: { + message: string; + response: Response; + data: ErrorResponse; + cause: Error; + }); + readonly cause: Error; + readonly data: ErrorResponse; + static fromResponse(response: Response): Promise<ResponseError>; + readonly response: Response; +} + +// Warning: (ae-missing-release-tag) "SerializedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type SerializedError = JsonObject & { + name: string; + message: string; + stack?: string; + code?: string; +}; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// Warning: (ae-missing-release-tag) "serializeError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function serializeError(error: Error, options?: { + includeStack?: boolean; +}): SerializedError; + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/integration-react/api-report.md b/packages/integration-react/api-report.md new file mode 100644 index 0000000000..aa12687415 --- /dev/null +++ b/packages/integration-react/api-report.md @@ -0,0 +1,32 @@ +## API Report File for "@backstage/integration-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ApiRef } from '@backstage/core'; +import { Config } from '@backstage/config'; +import { ScmIntegrationRegistry } from '@backstage/integration'; + +// Warning: (ae-missing-release-tag) "ScmIntegrationsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ScmIntegrationsApi { + // (undocumented) + static fromConfig(config: Config): ScmIntegrationRegistry; +} + +// Warning: (ae-missing-release-tag) "scmIntegrationsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const scmIntegrationsApiRef: ApiRef<ScmIntegrationRegistry>; + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md new file mode 100644 index 0000000000..8782abaf1a --- /dev/null +++ b/packages/integration/api-report.md @@ -0,0 +1,414 @@ +## API Report File for "@backstage/integration" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Config } from '@backstage/config'; + +// Warning: (ae-missing-release-tag) "AzureIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class AzureIntegration implements ScmIntegration { + constructor(integrationConfig: AzureIntegrationConfig); + // (undocumented) + get config(): AzureIntegrationConfig; + // Warning: (ae-forgotten-export) The symbol "ScmIntegrationsFactory" needs to be exported by the entry point index.d.ts + // + // (undocumented) + static factory: ScmIntegrationsFactory<AzureIntegration>; + // (undocumented) + resolveEditUrl(url: string): string; + // (undocumented) + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; + // (undocumented) + get title(): string; + // (undocumented) + get type(): string; +} + +// Warning: (ae-missing-release-tag) "AzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type AzureIntegrationConfig = { + host: string; + token?: string; +}; + +// Warning: (ae-missing-release-tag) "BitbucketIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class BitbucketIntegration implements ScmIntegration { + constructor(integrationConfig: BitbucketIntegrationConfig); + // (undocumented) + get config(): BitbucketIntegrationConfig; + // (undocumented) + static factory: ScmIntegrationsFactory<BitbucketIntegration>; + // (undocumented) + resolveEditUrl(url: string): string; + // (undocumented) + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; + // (undocumented) + get title(): string; + // (undocumented) + get type(): string; +} + +// Warning: (ae-missing-release-tag) "BitbucketIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type BitbucketIntegrationConfig = { + host: string; + apiBaseUrl?: string; + token?: string; + username?: string; + appPassword?: string; +}; + +// Warning: (ae-missing-release-tag) "defaultScmResolveUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function defaultScmResolveUrl(options: { + url: string; + base: string; + lineNumber?: number; +}): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getAzureCommitsUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getAzureCommitsUrl(url: string): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getAzureDownloadUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getAzureDownloadUrl(url: string): string; + +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getAzureFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getAzureFileFetchUrl(url: string): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getAzureRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getAzureRequestOptions(config: AzureIntegrationConfig, additionalHeaders?: Record<string, string>): RequestInit; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getBitbucketDefaultBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getBitbucketDefaultBranch(url: string, config: BitbucketIntegrationConfig): Promise<string>; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getBitbucketDownloadUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getBitbucketDownloadUrl(url: string, config: BitbucketIntegrationConfig): Promise<string>; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getBitbucketFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getBitbucketFileFetchUrl(url: string, config: BitbucketIntegrationConfig): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getBitbucketRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getBitbucketRequestOptions(config: BitbucketIntegrationConfig): RequestInit; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getGitHubFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getGitHubFileFetchUrl(url: string, config: GitHubIntegrationConfig): string; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getGitHubRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getGitHubRequestOptions(config: GitHubIntegrationConfig): RequestInit; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getGitLabFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getGitLabFileFetchUrl(url: string, config: GitLabIntegrationConfig): Promise<string>; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "getGitLabRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function getGitLabRequestOptions(config: GitLabIntegrationConfig): RequestInit; + +// Warning: (ae-missing-release-tag) "GithubCredentialsProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class GithubCredentialsProvider { + // (undocumented) + static create(config: GitHubIntegrationConfig): GithubCredentialsProvider; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag + // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag + // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" + // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" + // Warning: (tsdoc-undefined-tag) The TSDoc tag "@type" is not defined in this configuration + // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag + // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag + // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" + // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" + // Warning: (ae-forgotten-export) The symbol "GithubCredentials" needs to be exported by the entry point index.d.ts + getCredentials(opts: { + url: string; + }): Promise<GithubCredentials>; + } + +// Warning: (ae-missing-release-tag) "GitHubIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class GitHubIntegration implements ScmIntegration { + constructor(integrationConfig: GitHubIntegrationConfig); + // (undocumented) + get config(): GitHubIntegrationConfig; + // (undocumented) + static factory: ScmIntegrationsFactory<GitHubIntegration>; + // (undocumented) + resolveEditUrl(url: string): string; + // (undocumented) + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; + // (undocumented) + get title(): string; + // (undocumented) + get type(): string; +} + +// Warning: (ae-missing-release-tag) "GitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type GitHubIntegrationConfig = { + host: string; + apiBaseUrl?: string; + rawBaseUrl?: string; + token?: string; + apps?: GithubAppConfig[]; +}; + +// Warning: (ae-missing-release-tag) "GitLabIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class GitLabIntegration implements ScmIntegration { + constructor(integrationConfig: GitLabIntegrationConfig); + // (undocumented) + get config(): GitLabIntegrationConfig; + // (undocumented) + static factory: ScmIntegrationsFactory<GitLabIntegration>; + // (undocumented) + resolveEditUrl(url: string): string; + // (undocumented) + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; + // (undocumented) + get title(): string; + // (undocumented) + get type(): string; +} + +// Warning: (ae-missing-release-tag) "GitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type GitLabIntegrationConfig = { + host: string; + apiBaseUrl: string; + token?: string; + baseUrl: string; +}; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readAzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readAzureIntegrationConfig(config: Config): AzureIntegrationConfig; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readAzureIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readAzureIntegrationConfigs(configs: Config[]): AzureIntegrationConfig[]; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readBitbucketIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readBitbucketIntegrationConfig(config: Config): BitbucketIntegrationConfig; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readBitbucketIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readBitbucketIntegrationConfigs(configs: Config[]): BitbucketIntegrationConfig[]; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readGitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readGitHubIntegrationConfig(config: Config): GitHubIntegrationConfig; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readGitHubIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readGitHubIntegrationConfigs(configs: Config[]): GitHubIntegrationConfig[]; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readGitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readGitLabIntegrationConfig(config: Config): GitLabIntegrationConfig; + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "readGitLabIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function readGitLabIntegrationConfigs(configs: Config[]): GitLabIntegrationConfig[]; + +// Warning: (ae-missing-release-tag) "ScmIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ScmIntegration { + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + resolveEditUrl(url: string): string; + // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters + // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters + // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; + title: string; + type: string; +} + +// Warning: (ae-missing-release-tag) "ScmIntegrationRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ScmIntegrationRegistry extends ScmIntegrationsGroup<ScmIntegration> { + // (undocumented) + azure: ScmIntegrationsGroup<AzureIntegration>; + // (undocumented) + bitbucket: ScmIntegrationsGroup<BitbucketIntegration>; + // (undocumented) + github: ScmIntegrationsGroup<GitHubIntegration>; + // (undocumented) + gitlab: ScmIntegrationsGroup<GitLabIntegration>; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + resolveEditUrl(url: string): string; + // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters + // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters + // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; +} + +// Warning: (ae-missing-release-tag) "ScmIntegrations" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ScmIntegrations implements ScmIntegrationRegistry { + // Warning: (ae-forgotten-export) The symbol "IntegrationsByType" needs to be exported by the entry point index.d.ts + constructor(integrationsByType: IntegrationsByType); + // (undocumented) + get azure(): ScmIntegrationsGroup<AzureIntegration>; + // (undocumented) + get bitbucket(): ScmIntegrationsGroup<BitbucketIntegration>; + // (undocumented) + byHost(host: string): ScmIntegration | undefined; + // (undocumented) + byUrl(url: string | URL): ScmIntegration | undefined; + // (undocumented) + static fromConfig(config: Config): ScmIntegrations; + // (undocumented) + get github(): ScmIntegrationsGroup<GitHubIntegration>; + // (undocumented) + get gitlab(): ScmIntegrationsGroup<GitLabIntegration>; + // (undocumented) + list(): ScmIntegration[]; + // (undocumented) + resolveEditUrl(url: string): string; + // (undocumented) + resolveUrl(options: { + url: string; + base: string; + lineNumber?: number; + }): string; +} + +// Warning: (ae-missing-release-tag) "ScmIntegrationsGroup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ScmIntegrationsGroup<T extends ScmIntegration> { + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + byHost(host: string): T | undefined; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + byUrl(url: string | URL): T | undefined; + list(): T[]; +} + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. +// src/github/config.ts:67:3 - (ae-forgotten-export) The symbol "GithubAppConfig" needs to be exported by the entry point index.d.ts +// src/gitlab/config.ts:51:66 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// src/gitlab/config.ts:51:61 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/search-common/api-report.md b/packages/search-common/api-report.md new file mode 100644 index 0000000000..3911059177 --- /dev/null +++ b/packages/search-common/api-report.md @@ -0,0 +1,70 @@ +## API Report File for "@backstage/search-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { JsonObject } from '@backstage/config'; + +// Warning: (ae-missing-release-tag) "DocumentCollator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface DocumentCollator { + // (undocumented) + execute(): Promise<IndexableDocument[]>; +} + +// Warning: (ae-missing-release-tag) "DocumentDecorator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface DocumentDecorator { + // (undocumented) + execute(documents: IndexableDocument[]): Promise<IndexableDocument[]>; +} + +// Warning: (ae-missing-release-tag) "IndexableDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface IndexableDocument { + location: string; + text: string; + title: string; +} + +// Warning: (ae-missing-release-tag) "SearchQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SearchQuery { + // (undocumented) + filters?: JsonObject; + // (undocumented) + pageCursor: string; + // (undocumented) + term: string; +} + +// Warning: (ae-missing-release-tag) "SearchResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SearchResult { + // (undocumented) + document: IndexableDocument; +} + +// Warning: (ae-missing-release-tag) "SearchResultSet" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SearchResultSet { + // (undocumented) + results: SearchResult[]; +} + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md new file mode 100644 index 0000000000..df1bea443c --- /dev/null +++ b/packages/techdocs-common/api-report.md @@ -0,0 +1,259 @@ +## API Report File for "@backstage/techdocs-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { AzureIntegrationConfig } from '@backstage/integration'; +import { Config } from '@backstage/config'; +import Docker from 'dockerode'; +import { Entity } from '@backstage/catalog-model'; +import { EntityName } from '@backstage/catalog-model'; +import express from 'express'; +import { GitHubIntegrationConfig } from '@backstage/integration'; +import { GitLabIntegrationConfig } from '@backstage/integration'; +import { Logger } from 'winston'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; +import { Writable } from 'stream'; + +// Warning: (ae-missing-release-tag) "checkoutGitRepository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const checkoutGitRepository: (repoUrl: string, config: Config, logger: Logger) => Promise<string>; + +// Warning: (ae-missing-release-tag) "CommonGitPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class CommonGitPreparer implements PreparerBase { + constructor(config: Config, logger: Logger); + // Warning: (ae-forgotten-export) The symbol "PreparerResponse" needs to be exported by the entry point index.d.ts + // + // (undocumented) + prepare(entity: Entity, options?: { + etag?: string; + }): Promise<PreparerResponse>; +} + +// Warning: (ae-missing-release-tag) "DirectoryPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class DirectoryPreparer implements PreparerBase { + constructor(config: Config, logger: Logger, reader: UrlReader); + // (undocumented) + prepare(entity: Entity): Promise<PreparerResponse>; + } + +// Warning: (ae-missing-release-tag) "GeneratorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type GeneratorBase = { + run(opts: GeneratorRunOptions): Promise<void>; +}; + +// Warning: (ae-missing-release-tag) "GeneratorBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type GeneratorBuilder = { + register(protocol: SupportedGeneratorKey, generator: GeneratorBase): void; + get(entity: Entity): GeneratorBase; +}; + +// Warning: (ae-missing-release-tag) "Generators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Generators implements GeneratorBuilder { + // (undocumented) + static fromConfig(config: Config, { logger }: { + logger: Logger; + }): Promise<GeneratorBuilder>; + // (undocumented) + get(entity: Entity): GeneratorBase; + // (undocumented) + register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase): void; +} + +// Warning: (ae-missing-release-tag) "getAzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getAzureIntegrationConfig: (config: Config, host: string) => AzureIntegrationConfig; + +// Warning: (ae-missing-release-tag) "getDefaultBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getDefaultBranch: (repositoryUrl: string, config: Config) => Promise<string>; + +// Warning: (ae-missing-release-tag) "getDocFilesFromRepository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getDocFilesFromRepository: (reader: UrlReader, entity: Entity, opts?: { + etag?: string | undefined; + logger?: Logger | undefined; +} | undefined) => Promise<PreparerResponse>; + +// Warning: (ae-missing-release-tag) "getGitHost" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function getGitHost(url: string): string; + +// Warning: (ae-missing-release-tag) "getGitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getGitHubIntegrationConfig: (config: Config, host: string) => GitHubIntegrationConfig; + +// Warning: (ae-missing-release-tag) "getGitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getGitLabIntegrationConfig: (config: Config, host: string) => GitLabIntegrationConfig; + +// Warning: (ae-missing-release-tag) "getGitRepositoryTempFolder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getGitRepositoryTempFolder: (repositoryUrl: string, config: Config) => Promise<string>; + +// Warning: (ae-missing-release-tag) "getGitRepoType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function getGitRepoType(url: string): string; + +// Warning: (ae-missing-release-tag) "getLastCommitTimestamp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getLastCommitTimestamp: (repositoryLocation: string, logger: Logger) => Promise<number>; + +// Warning: (ae-missing-release-tag) "getLocationForEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getLocationForEntity: (entity: Entity) => ParsedLocationAnnotation; + +// Warning: (ae-missing-release-tag) "getTokenForGitRepo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const getTokenForGitRepo: (repositoryUrl: string, config: Config) => Promise<string | undefined>; + +// Warning: (ae-missing-release-tag) "ParsedLocationAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ParsedLocationAnnotation = { + type: RemoteProtocol; + target: string; +}; + +// Warning: (ae-missing-release-tag) "parseReferenceAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const parseReferenceAnnotation: (annotationName: string, entity: Entity) => ParsedLocationAnnotation; + +// Warning: (ae-missing-release-tag) "PreparerBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PreparerBase = { + prepare(entity: Entity, options?: { + logger?: Logger; + etag?: string; + }): Promise<PreparerResponse>; +}; + +// Warning: (ae-missing-release-tag) "PreparerBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PreparerBuilder = { + register(protocol: RemoteProtocol, preparer: PreparerBase): void; + get(entity: Entity): PreparerBase; +}; + +// Warning: (ae-missing-release-tag) "Preparers" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Preparers implements PreparerBuilder { + // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + static fromConfig(config: Config, { logger, reader }: factoryOptions): Promise<PreparerBuilder>; + // (undocumented) + get(entity: Entity): PreparerBase; + // (undocumented) + register(protocol: RemoteProtocol, preparer: PreparerBase): void; +} + +// Warning: (ae-missing-release-tag) "Publisher" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class Publisher { + // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + static fromConfig(config: Config, { logger, discovery }: factoryOptions_2): Promise<PublisherBase>; +} + +// Warning: (ae-missing-release-tag) "PublisherBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface PublisherBase { + docsRouter(): express.Handler; + fetchTechDocsMetadata(entityName: EntityName): Promise<TechDocsMetadata>; + hasDocsBeenGenerated(entityName: Entity): Promise<boolean>; + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen + // Warning: (ae-forgotten-export) The symbol "PublishRequest" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "PublishResponse" needs to be exported by the entry point index.d.ts + publish(request: PublishRequest): Promise<PublishResponse>; +} + +// Warning: (ae-missing-release-tag) "PublisherType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PublisherType = 'local' | 'googleGcs' | 'awsS3' | 'azureBlobStorage' | 'openStackSwift'; + +// Warning: (ae-missing-release-tag) "RemoteProtocol" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type RemoteProtocol = 'url' | 'dir' | 'github' | 'gitlab' | 'file' | 'azure/api'; + +// Warning: (ae-missing-release-tag) "TechdocsGenerator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class TechdocsGenerator implements GeneratorBase { + constructor(logger: Logger, config: Config); + // (undocumented) + run({ inputDir, outputDir, dockerClient, parsedLocationAnnotation, etag, }: GeneratorRunOptions): Promise<void>; +} + +// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// Warning: (ae-missing-release-tag) "TechDocsMetadata" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type TechDocsMetadata = { + site_name: string; + site_description: string; + etag: string; +}; + +// Warning: (ae-missing-release-tag) "UrlPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class UrlPreparer implements PreparerBase { + constructor(reader: UrlReader, logger: Logger); + // (undocumented) + prepare(entity: Entity, options?: { + etag?: string; + }): Promise<PreparerResponse>; + } + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. +// src/stages/generate/types.ts:42:3 - (ae-forgotten-export) The symbol "GeneratorRunOptions" needs to be exported by the entry point index.d.ts +// src/stages/generate/types.ts:54:3 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts +// src/stages/prepare/types.ts:35:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/stages/prepare/types.ts:36:6 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters +// src/stages/prepare/types.ts:38:31 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// src/stages/prepare/types.ts:38:14 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/test-utils-core/api-report.md b/packages/test-utils-core/api-report.md new file mode 100644 index 0000000000..a462be7aca --- /dev/null +++ b/packages/test-utils-core/api-report.md @@ -0,0 +1,113 @@ +## API Report File for "@backstage/test-utils-core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ReactElement } from 'react'; +import { RenderResult } from '@testing-library/react'; + +// Warning: (ae-missing-release-tag) "AsyncLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AsyncLogCollector = () => Promise<void>; + +// Warning: (ae-missing-release-tag) "CollectedLogs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type CollectedLogs<T extends LogFuncs> = { + [key in T]: string[]; +}; + +// Warning: (ae-missing-release-tag) "Keyboard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Keyboard { + constructor(target: any, { debug }?: { + debug?: boolean | undefined; + }); + // (undocumented) + click(): Promise<void>; + // (undocumented) + debug: boolean; + // (undocumented) + document: any; + // (undocumented) + enter(value: any): Promise<void>; + // (undocumented) + escape(): Promise<void>; + // (undocumented) + get focused(): any; + // (undocumented) + static fromReadableInput(input: any): any; + // (undocumented) + _log(message: any, ...args: any[]): void; + // (undocumented) + _pretty(element: any): string; + // (undocumented) + send(chars: any): Promise<void>; + // (undocumented) + _sendKey(key: any, charCode: any, action: any): Promise<void>; + // (undocumented) + tab(): Promise<void>; + // (undocumented) + static toReadableInput(chars: any): any; + // (undocumented) + toString(): string; + // (undocumented) + static type(target: any, input: any): Promise<void>; + // (undocumented) + type(input: any): Promise<void>; + // (undocumented) + static typeDebug(target: any, input: any): Promise<void>; +} + +// Warning: (ae-missing-release-tag) "LogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LogCollector = AsyncLogCollector | SyncLogCollector; + +// Warning: (ae-missing-release-tag) "LogFuncs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type LogFuncs = 'log' | 'warn' | 'error'; + +// Warning: (ae-missing-release-tag) "renderWithEffects" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function renderWithEffects(nodes: ReactElement): Promise<RenderResult>; + +// Warning: (ae-missing-release-tag) "SyncLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type SyncLogCollector = () => void; + +// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function withLogCollector(callback: AsyncLogCollector): Promise<CollectedLogs<LogFuncs>>; + +// @public (undocumented) +export function withLogCollector(callback: SyncLogCollector): CollectedLogs<LogFuncs>; + +// @public (undocumented) +export function withLogCollector<T extends LogFuncs>(logsToCollect: T[], callback: AsyncLogCollector): Promise<CollectedLogs<T>>; + +// @public (undocumented) +export function withLogCollector<T extends LogFuncs>(logsToCollect: T[], callback: SyncLogCollector): CollectedLogs<T>; + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md new file mode 100644 index 0000000000..9e72a070f7 --- /dev/null +++ b/packages/test-utils/api-report.md @@ -0,0 +1,109 @@ +## API Report File for "@backstage/test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ComponentType } from 'react'; +import { ErrorApi } from '@backstage/core-api'; +import { ErrorContext } from '@backstage/core-api'; +import { ExternalRouteRef } from '@backstage/core-api'; +import { Observable } from '@backstage/core-api'; +import { ReactElement } from 'react'; +import { ReactNode } from 'react'; +import { RenderResult } from '@testing-library/react'; +import { RouteRef } from '@backstage/core-api'; +import { StorageApi } from '@backstage/core-api'; +import { StorageValueChange } from '@backstage/core-api'; + +// Warning: (ae-forgotten-export) The symbol "Breakpoint" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "mockBreakpoint" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function mockBreakpoint(initialBreakpoint?: Breakpoint): { + set(breakpoint: Breakpoint): void; + remove(): void; +}; + +// Warning: (ae-missing-release-tag) "MockErrorApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class MockErrorApi implements ErrorApi { + // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts + constructor(options?: Options); + // (undocumented) + error$(): Observable<{ + error: Error; + context?: ErrorContext; + }>; + // Warning: (ae-forgotten-export) The symbol "ErrorWithContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + getErrors(): ErrorWithContext[]; + // (undocumented) + post(error: Error, context?: ErrorContext): void; + // (undocumented) + waitForError(pattern: RegExp, timeoutMs?: number): Promise<ErrorWithContext>; +} + +// Warning: (ae-missing-release-tag) "MockStorageApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class MockStorageApi implements StorageApi { + // (undocumented) + static create(data?: MockStorageBucket): MockStorageApi; + // (undocumented) + forBucket(name: string): StorageApi; + // (undocumented) + get<T>(key: string): T | undefined; + // (undocumented) + observe$<T>(key: string): Observable<StorageValueChange<T>>; + // (undocumented) + remove(key: string): Promise<void>; + // (undocumented) + set<T>(key: string, data: T): Promise<void>; + } + +// Warning: (ae-missing-release-tag) "MockStorageBucket" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type MockStorageBucket = { + [key: string]: any; +}; + +// Warning: (ae-missing-release-tag) "msw" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const msw: { + setupDefaultHandlers: (worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; + }) => void; +}; + +// Warning: (ae-forgotten-export) The symbol "TestAppOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "renderInTestApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function renderInTestApp(Component: ComponentType | ReactNode, options?: TestAppOptions): Promise<RenderResult>; + +// Warning: (ae-missing-release-tag) "wrapInTestApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function wrapInTestApp(Component: ComponentType | ReactNode, options?: TestAppOptions): ReactElement; + + +export * from "@backstage/test-utils-core"; + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md new file mode 100644 index 0000000000..87656beb2c --- /dev/null +++ b/packages/theme/api-report.md @@ -0,0 +1,130 @@ +## API Report File for "@backstage/theme" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Overrides } from '@material-ui/core/styles/overrides'; +import { Palette } from '@material-ui/core/styles/createPalette'; +import { PaletteOptions } from '@material-ui/core/styles/createPalette'; +import { Theme } from '@material-ui/core'; +import { ThemeOptions } from '@material-ui/core'; + +// Warning: (ae-forgotten-export) The symbol "PaletteAdditions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "BackstagePalette" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type BackstagePalette = Palette & PaletteAdditions; + +// Warning: (ae-missing-release-tag) "BackstagePaletteOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type BackstagePaletteOptions = PaletteOptions & PaletteAdditions; + +// Warning: (ae-missing-release-tag) "BackstageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface BackstageTheme extends Theme { + // (undocumented) + getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme; + // (undocumented) + page: PageTheme; + // (undocumented) + palette: BackstagePalette; +} + +// Warning: (ae-missing-release-tag) "BackstageThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface BackstageThemeOptions extends ThemeOptions { + // (undocumented) + getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme; + // (undocumented) + page: PageTheme; + // (undocumented) + palette: BackstagePaletteOptions; +} + +// Warning: (ae-missing-release-tag) "colorVariants" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const colorVariants: Record<string, string[]>; + +// Warning: (ae-missing-release-tag) "createTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function createTheme(options: SimpleThemeOptions): BackstageTheme; + +// Warning: (ae-missing-release-tag) "createThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function createThemeOptions(options: SimpleThemeOptions): BackstageThemeOptions; + +// Warning: (ae-missing-release-tag) "createThemeOverrides" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function createThemeOverrides(theme: BackstageTheme): Overrides; + +// Warning: (ae-missing-release-tag) "darkTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const darkTheme: BackstageTheme; + +// Warning: (ae-missing-release-tag) "genPageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function genPageTheme(colors: string[], shape: string): PageTheme; + +// Warning: (ae-missing-release-tag) "lightTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const lightTheme: BackstageTheme; + +// Warning: (ae-missing-release-tag) "PageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PageTheme = { + colors: string[]; + shape: string; + backgroundImage: string; +}; + +// Warning: (ae-missing-release-tag) "pageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const pageTheme: Record<string, PageTheme>; + +// Warning: (ae-missing-release-tag) "PageThemeSelector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PageThemeSelector = { + themeId: string; +}; + +// Warning: (ae-missing-release-tag) "shapes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const shapes: Record<string, string>; + +// Warning: (ae-missing-release-tag) "SimpleThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type SimpleThemeOptions = { + palette: BackstagePaletteOptions; + defaultPageTheme: string; + pageTheme?: Record<string, PageTheme>; + fontFamily?: string; +}; + + +// Warnings were encountered during analysis: +// +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. +// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. + +// (No @packageDocumentation comment for this package) + +``` From d3c54f9663a890bc9cadad2db7d071e2d8c461ac Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 19:23:00 +0200 Subject: [PATCH 251/462] scripts/api-extractor: log instructions after run is complete to avoid race Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- scripts/api-extractor.ts | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index e232170e9d..6eca3b0de3 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -166,6 +166,8 @@ async function runApiExtraction({ // Message verbosity can't be configured, so just skip the check instead (Extractor as any)._checkCompilerCompatibility = () => {}; + let shouldLogInstructions = false; + // Invoke API Extractor const extractorResult = Extractor.invoke(extractorConfig, { localBuild: isLocalBuild, @@ -177,26 +179,29 @@ async function runApiExtraction({ 'You have changed the public API signature for this project.', ) ) { - console.log(''); - console.log( - '*************************************************************************************', - ); - console.log( - '* You have uncommitted changes to the public API of a package. *', - ); - console.log( - '* To solve this, run `yarn build:api-reports` and commit all api-report.md changes. *', - ); - console.log( - '*************************************************************************************', - ); - console.log(''); + shouldLogInstructions = true; } }, compilerState, }); if (!extractorResult.succeeded) { + if (shouldLogInstructions) { + console.log(''); + console.log( + '*************************************************************************************', + ); + console.log( + '* You have uncommitted changes to the public API of a package. *', + ); + console.log( + '* To solve this, run `yarn build:api-reports` and commit all api-report.md changes. *', + ); + console.log( + '*************************************************************************************', + ); + console.log(''); + } throw new Error( `API Extractor completed with ${extractorResult.errorCount} errors` + ` and ${extractorResult.warningCount} warnings`, From 0eda63fe9da28397288d7d52be4d8dfd0e98591b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 20:12:52 +0200 Subject: [PATCH 252/462] scripts/api-extractor: disable inline compilation warnings Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/backend-common/api-report.md | 5 --- packages/catalog-client/api-report.md | 5 --- packages/catalog-model/api-report.md | 5 --- packages/cli-common/api-report.md | 24 ++++++------- packages/config-loader/api-report.md | 5 --- packages/config/api-report.md | 8 ----- packages/dev-utils/api-report.md | 8 ----- packages/errors/api-report.md | 8 ----- packages/integration-react/api-report.md | 13 +++---- packages/integration/api-report.md | 5 --- packages/search-common/api-report.md | 43 +++++++++++------------- packages/techdocs-common/api-report.md | 5 --- packages/test-utils-core/api-report.md | 8 ----- packages/test-utils/api-report.md | 8 ----- packages/theme/api-report.md | 8 ----- scripts/api-extractor.ts | 3 +- 16 files changed, 36 insertions(+), 125 deletions(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index bdef061eda..79a7ca1a5c 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -458,11 +458,6 @@ export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T; // src/service/types.ts:78:3 - (ae-forgotten-export) The symbol "HttpsSettings" needs to be exported by the entry point index.d.ts // src/service/types.ts:83:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/service/types.ts:84:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index fe12d3a62c..467cf752af 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -94,11 +94,6 @@ export type CatalogListResponse<T> = { // Warnings were encountered during analysis: // // src/CatalogClient.ts:40:26 - (ae-forgotten-export) The symbol "DiscoveryApi" needs to be exported by the entry point index.d.ts -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index b3e3303589..7aa98e52c7 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -800,11 +800,6 @@ export const VIEW_URL_ANNOTATION = "backstage.io/view-url"; // src/EntityPolicies.ts:57:3 - (ae-forgotten-export) The symbol "AnyEntityPolicy" needs to be exported by the entry point index.d.ts // src/entity/policies/types.ts:27:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/kinds/types.ts:26:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) diff --git a/packages/cli-common/api-report.md b/packages/cli-common/api-report.md index 81d494e4ef..f4df3562b8 100644 --- a/packages/cli-common/api-report.md +++ b/packages/cli-common/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts + // Warning: (ae-missing-release-tag) "findPaths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -12,24 +13,21 @@ export function findPaths(searchDir: string): Paths; // // @public (undocumented) export type Paths = { - ownDir: string; - ownRoot: string; - targetDir: string; - targetRoot: string; - resolveOwn: ResolveFunc; - resolveOwnRoot: ResolveFunc; - resolveTarget: ResolveFunc; - resolveTargetRoot: ResolveFunc; + ownDir: string; + ownRoot: string; + targetDir: string; + targetRoot: string; + resolveOwn: ResolveFunc; + resolveOwnRoot: ResolveFunc; + resolveTarget: ResolveFunc; + resolveTargetRoot: ResolveFunc; }; + // Warnings were encountered during analysis: // // src/paths.ts:38:3 - (ae-forgotten-export) The symbol "ResolveFunc" needs to be exported by the entry point index.d.ts -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) + ``` diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index 0c011aea65..ffa599df2b 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -61,11 +61,6 @@ export function readEnvConfig(env: { // src/lib/schema/types.ts:105:3 - (ae-forgotten-export) The symbol "ConfigProcessingOptions" needs to be exported by the entry point index.d.ts // src/loader.ts:42:6 - (tsdoc-unsupported-tag) The TSDoc tag "@experimental" is not supported by this tool // src/loader.ts:44:3 - (ae-forgotten-export) The symbol "EnvFunc" needs to be exported by the entry point index.d.ts -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) diff --git a/packages/config/api-report.md b/packages/config/api-report.md index 8ff881a34b..4e0da777ec 100644 --- a/packages/config/api-report.md +++ b/packages/config/api-report.md @@ -99,14 +99,6 @@ export type JsonPrimitive = number | string | boolean | null; export type JsonValue = JsonObject | JsonArray | JsonPrimitive; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md index 41c793e189..841f9c19b2 100644 --- a/packages/dev-utils/api-report.md +++ b/packages/dev-utils/api-report.md @@ -26,14 +26,6 @@ export const EntityGridItem: ({ entity, classes, ...rest }: Omit<GridProps<"div" }) => JSX.Element; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/errors/api-report.md b/packages/errors/api-report.md index 2a4b482463..18861fdc84 100644 --- a/packages/errors/api-report.md +++ b/packages/errors/api-report.md @@ -112,14 +112,6 @@ export function serializeError(error: Error, options?: { }): SerializedError; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/integration-react/api-report.md b/packages/integration-react/api-report.md index aa12687415..8dcc02a443 100644 --- a/packages/integration-react/api-report.md +++ b/packages/integration-react/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts + import { ApiRef } from '@backstage/core'; import { Config } from '@backstage/config'; import { ScmIntegrationRegistry } from '@backstage/integration'; @@ -11,8 +12,8 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; // // @public (undocumented) export class ScmIntegrationsApi { - // (undocumented) - static fromConfig(config: Config): ScmIntegrationRegistry; + // (undocumented) + static fromConfig(config: Config): ScmIntegrationRegistry; } // Warning: (ae-missing-release-tag) "scmIntegrationsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -20,13 +21,7 @@ export class ScmIntegrationsApi { // @public (undocumented) export const scmIntegrationsApiRef: ApiRef<ScmIntegrationRegistry>; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) + ``` diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md index 8782abaf1a..6d85bf4a51 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/api-report.md @@ -400,11 +400,6 @@ export interface ScmIntegrationsGroup<T extends ScmIntegration> { // Warnings were encountered during analysis: // -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // src/github/config.ts:67:3 - (ae-forgotten-export) The symbol "GithubAppConfig" needs to be exported by the entry point index.d.ts // src/gitlab/config.ts:51:66 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag // src/gitlab/config.ts:51:61 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" diff --git a/packages/search-common/api-report.md b/packages/search-common/api-report.md index 3911059177..ed53275017 100644 --- a/packages/search-common/api-report.md +++ b/packages/search-common/api-report.md @@ -3,68 +3,63 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts + import { JsonObject } from '@backstage/config'; // Warning: (ae-missing-release-tag) "DocumentCollator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export interface DocumentCollator { - // (undocumented) - execute(): Promise<IndexableDocument[]>; + // (undocumented) + execute(): Promise<IndexableDocument[]>; } // Warning: (ae-missing-release-tag) "DocumentDecorator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export interface DocumentDecorator { - // (undocumented) - execute(documents: IndexableDocument[]): Promise<IndexableDocument[]>; + // (undocumented) + execute(documents: IndexableDocument[]): Promise<IndexableDocument[]>; } // Warning: (ae-missing-release-tag) "IndexableDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export interface IndexableDocument { - location: string; - text: string; - title: string; + location: string; + text: string; + title: string; } // Warning: (ae-missing-release-tag) "SearchQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface SearchQuery { - // (undocumented) - filters?: JsonObject; - // (undocumented) - pageCursor: string; - // (undocumented) - term: string; + // (undocumented) + filters?: JsonObject; + // (undocumented) + pageCursor: string; + // (undocumented) + term: string; } // Warning: (ae-missing-release-tag) "SearchResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface SearchResult { - // (undocumented) - document: IndexableDocument; + // (undocumented) + document: IndexableDocument; } // Warning: (ae-missing-release-tag) "SearchResultSet" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface SearchResultSet { - // (undocumented) - results: SearchResult[]; + // (undocumented) + results: SearchResult[]; } -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // (No @packageDocumentation comment for this package) + ``` diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index df1bea443c..aa6c9da2f8 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -242,11 +242,6 @@ export class UrlPreparer implements PreparerBase { // Warnings were encountered during analysis: // -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. // src/stages/generate/types.ts:42:3 - (ae-forgotten-export) The symbol "GeneratorRunOptions" needs to be exported by the entry point index.d.ts // src/stages/generate/types.ts:54:3 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts // src/stages/prepare/types.ts:35:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen diff --git a/packages/test-utils-core/api-report.md b/packages/test-utils-core/api-report.md index a462be7aca..bda058ad23 100644 --- a/packages/test-utils-core/api-report.md +++ b/packages/test-utils-core/api-report.md @@ -100,14 +100,6 @@ export function withLogCollector<T extends LogFuncs>(logsToCollect: T[], callbac export function withLogCollector<T extends LogFuncs>(logsToCollect: T[], callback: SyncLogCollector): CollectedLogs<T>; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index 9e72a070f7..f62b1e6dec 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -96,14 +96,6 @@ export function wrapInTestApp(Component: ComponentType | ReactNode, options?: Te export * from "@backstage/test-utils-core"; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md index 87656beb2c..adfbcee346 100644 --- a/packages/theme/api-report.md +++ b/packages/theme/api-report.md @@ -117,14 +117,6 @@ export type SimpleThemeOptions = { }; -// Warnings were encountered during analysis: -// -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:18:31 - (TS2307) Cannot find module './assets/missingAnnotation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:19:27 - (TS2307) Cannot find module './assets/noInformation.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:20:29 - (TS2307) Cannot find module './assets/createComponent.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/components/EmptyState/EmptyStateImage.tsx:21:21 - (TS2307) Cannot find module './assets/noBuild.svg' or its corresponding type declarations. -// /Users/patriko/dev/backstage/packages/core/src/layout/ErrorPage/MicDrop.tsx:19:27 - (TS2307) Cannot find module './mic-drop.svg' or its corresponding type declarations. - // (No @packageDocumentation comment for this package) ``` diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 6eca3b0de3..6095b1f15f 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -132,7 +132,8 @@ async function runApiExtraction({ compilerMessageReporting: { default: { logLevel: 'warning' as ExtractorLogLevel.Warning, - addToApiReportFile: true, + // These contain absolute file paths, so can't be included in the report + // addToApiReportFile: true, }, }, extractorMessageReporting: { From 6768b397bd644ae5e9d5ec35e0ee4c82bb64c79a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 7 Apr 2021 22:41:35 +0200 Subject: [PATCH 253/462] scripts/api-extractor: silence compiler warnings Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- scripts/api-extractor.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 6095b1f15f..2391832f3e 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -131,7 +131,8 @@ async function runApiExtraction({ messages: { compilerMessageReporting: { default: { - logLevel: 'warning' as ExtractorLogLevel.Warning, + // Silence compiler warnings, as these will prevent the CI build to work + logLevel: 'none' as ExtractorLogLevel.None, // These contain absolute file paths, so can't be included in the report // addToApiReportFile: true, }, From c04a465330dbc35543b224aa4562265c59a287a4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 14 Apr 2021 18:40:04 +0200 Subject: [PATCH 254/462] scripts/api-extractor: figure out the conflicting file in CI and print the contents Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- scripts/api-extractor.ts | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 2391832f3e..4135c52701 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -17,7 +17,11 @@ /* eslint-disable import/no-extraneous-dependencies */ // eslint-disable-next-line no-restricted-imports -import { resolve as resolvePath, join as joinPath, dirname } from 'path'; +import { + resolve as resolvePath, + relative as relativePath, + dirname, +} from 'path'; import fs from 'fs-extra'; import { Extractor, @@ -169,6 +173,7 @@ async function runApiExtraction({ (Extractor as any)._checkCompilerCompatibility = () => {}; let shouldLogInstructions = false; + let conflictingFile: undefined | string = undefined; // Invoke API Extractor const extractorResult = Extractor.invoke(extractorConfig, { @@ -182,6 +187,12 @@ async function runApiExtraction({ ) ) { shouldLogInstructions = true; + const match = message.text.match( + /Please copy the file "(.*)" to "api-report\.md"/, + ); + if (match) { + conflictingFile = match[1]; + } } }, compilerState, @@ -203,7 +214,23 @@ async function runApiExtraction({ '*************************************************************************************', ); console.log(''); + + if (conflictingFile) { + console.log(''); + console.log( + `The conflicting file is ${relativePath( + tmpDir, + conflictingFile, + )}, with the following content:`, + ); + console.log(''); + + const content = await fs.readFile(conflictingFile, 'utf8'); + console.log(content); + console.log(''); + } } + throw new Error( `API Extractor completed with ${extractorResult.errorCount} errors` + ` and ${extractorResult.warningCount} warnings`, From 658de01647c9fbd3e206ccc3d6c9673b8c9e90ba Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 14 Apr 2021 20:00:37 +0200 Subject: [PATCH 255/462] scripts/api-extractor: disable all inline warnings Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/backend-common/api-report.md | 123 ----------- packages/catalog-client/api-report.md | 22 +- packages/catalog-model/api-report.md | 251 +---------------------- packages/cli-common/api-report.md | 8 - packages/config-loader/api-report.md | 22 -- packages/config/api-report.md | 14 -- packages/dev-utils/api-report.md | 5 - packages/errors/api-report.md | 29 --- packages/integration-react/api-report.md | 4 - packages/integration/api-report.md | 148 +------------ packages/search-common/api-report.md | 12 -- packages/techdocs-common/api-report.md | 77 ------- packages/test-utils-core/api-report.md | 19 -- packages/test-utils/api-report.md | 19 -- packages/theme/api-report.md | 33 --- scripts/api-extractor.ts | 10 +- 16 files changed, 24 insertions(+), 772 deletions(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 79a7ca1a5c..58b9aa36d9 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -29,33 +29,23 @@ import { Server } from 'http'; import * as winston from 'winston'; import { Writable } from 'stream'; -// Warning: (ae-missing-release-tag) "AzureUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class AzureUrlReader implements UrlReader { constructor(integration: AzureIntegration, deps: { treeResponseFactory: ReadTreeResponseFactory; }); - // Warning: (ae-forgotten-export) The symbol "ReaderFactory" needs to be exported by the entry point index.d.ts - // // (undocumented) static factory: ReaderFactory; // (undocumented) read(url: string): Promise<Buffer>; - // Warning: (ae-forgotten-export) The symbol "ReadTreeOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>; - // Warning: (ae-forgotten-export) The symbol "SearchOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) search(url: string, options?: SearchOptions): Promise<SearchResponse>; // (undocumented) toString(): string; } -// Warning: (ae-missing-release-tag) "BitbucketUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class BitbucketUrlReader implements UrlReader { constructor(integration: BitbucketIntegration, deps: { @@ -73,52 +63,30 @@ export class BitbucketUrlReader implements UrlReader { toString(): string; } -// Warning: (ae-missing-release-tag) "coloredFormat" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const coloredFormat: Format; -// Warning: (ae-missing-release-tag) "createDatabase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public @deprecated export const createDatabase: typeof createDatabaseClient; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "createDatabaseClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function createDatabaseClient(dbConfig: Config, overrides?: Partial<Knex.Config>): Knex<any, unknown[]>; -// Warning: (ae-missing-release-tag) "createRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createRootLogger(options?: winston.LoggerOptions, env?: NodeJS.ProcessEnv): winston.Logger; -// Warning: (ae-forgotten-export) The symbol "ServiceBuilderImpl" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createServiceBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function createServiceBuilder(_module: NodeModule): ServiceBuilderImpl; -// Warning: (ae-forgotten-export) The symbol "StatusCheckRouterOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createStatusCheckRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createStatusCheckRouter(options: StatusCheckRouterOptions): Promise<express.Router>; -// Warning: (ae-missing-release-tag) "ensureDatabaseExists" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function ensureDatabaseExists(dbConfig: Config, ...databases: Array<string>): Promise<void>; -// Warning: (ae-missing-release-tag) "errorHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function errorHandler(options?: ErrorHandlerOptions): ErrorRequestHandler; -// Warning: (ae-missing-release-tag) "ErrorHandlerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type ErrorHandlerOptions = { showStackTraces?: boolean; @@ -126,18 +94,12 @@ export type ErrorHandlerOptions = { logClientErrors?: boolean; }; -// Warning: (ae-missing-release-tag) "getRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function getRootLogger(): winston.Logger; -// Warning: (ae-missing-release-tag) "getVoidLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getVoidLogger(): winston.Logger; -// Warning: (ae-missing-release-tag) "Git" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class Git { // (undocumented) @@ -221,8 +183,6 @@ export class Git { }): Promise<string>; } -// Warning: (ae-missing-release-tag) "GithubUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class GithubUrlReader implements UrlReader { constructor(integration: GitHubIntegration, deps: { @@ -241,8 +201,6 @@ export class GithubUrlReader implements UrlReader { toString(): string; } -// Warning: (ae-missing-release-tag) "GitlabUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class GitlabUrlReader implements UrlReader { constructor(integration: GitLabIntegration, deps: { @@ -260,34 +218,23 @@ export class GitlabUrlReader implements UrlReader { toString(): string; } -// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "loadBackendConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function loadBackendConfig(options: Options): Promise<Config>; -// Warning: (ae-missing-release-tag) "notFoundHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function notFoundHandler(): RequestHandler; -// Warning: (ae-missing-release-tag) "PluginDatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface PluginDatabaseManager { getClient(): Promise<Knex>; } -// Warning: (ae-missing-release-tag) "PluginEndpointDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type PluginEndpointDiscovery = { getBaseUrl(pluginId: string): Promise<string>; getExternalBaseUrl(pluginId: string): Promise<string>; }; -// Warning: (ae-missing-release-tag) "ReadTreeResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type ReadTreeResponse = { files(): Promise<ReadTreeResponseFile[]>; @@ -296,62 +243,36 @@ export type ReadTreeResponse = { etag: string; }; -// Warning: (ae-missing-release-tag) "ReadTreeResponseFile" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ReadTreeResponseFile = { path: string; content(): Promise<Buffer>; }; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "requestLoggingHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function requestLoggingHandler(logger?: Logger): RequestHandler; -// Warning: (ae-missing-release-tag) "resolvePackagePath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function resolvePackagePath(name: string, ...paths: string[]): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (ae-forgotten-export) The symbol "RunDockerContainerOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "runDockerContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const runDockerContainer: ({ imageName, args, logStream, dockerClient, mountDirs, workingDir, envVars, createOptions, }: RunDockerContainerOptions) => Promise<{ error: any; statusCode: any; }>; -// Warning: (ae-missing-release-tag) "SearchResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type SearchResponse = { files: SearchResponseFile[]; etag: string; }; -// Warning: (ae-missing-release-tag) "SearchResponseFile" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type SearchResponseFile = { url: string; content(): Promise<Buffer>; }; -// Warning: (ae-missing-release-tag) "ServiceBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type ServiceBuilder = { loadConfig(config: ConfigReader): ServiceBuilder; @@ -364,23 +285,15 @@ export type ServiceBuilder = { start(): Promise<Server>; }; -// Warning: (ae-missing-release-tag) "setRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function setRootLogger(newLogger: winston.Logger): void; -// Warning: (ae-missing-release-tag) "SingleConnectionDatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class SingleConnectionDatabaseManager { - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen forPlugin(pluginId: string): PluginDatabaseManager; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen static fromConfig(config: Config): SingleConnectionDatabaseManager; } -// Warning: (ae-missing-release-tag) "SingleHostDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class SingleHostDiscovery implements PluginEndpointDiscovery { static fromConfig(config: Config, options?: { @@ -392,26 +305,17 @@ export class SingleHostDiscovery implements PluginEndpointDiscovery { getExternalBaseUrl(pluginId: string): Promise<string>; } -// Warning: (ae-missing-release-tag) "StatusCheck" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type StatusCheck = () => Promise<any>; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "statusCheckHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function statusCheckHandler(options?: StatusCheckHandlerOptions): Promise<RequestHandler>; -// Warning: (ae-missing-release-tag) "StatusCheckHandlerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface StatusCheckHandlerOptions { statusCheck?: StatusCheck; } -// Warning: (ae-missing-release-tag) "UrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type UrlReader = { read(url: string): Promise<Buffer>; @@ -419,46 +323,19 @@ export type UrlReader = { search(url: string, options?: SearchOptions): Promise<SearchResponse>; }; -// Warning: (ae-missing-release-tag) "UrlReaders" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class UrlReaders { - // Warning: (ae-forgotten-export) The symbol "CreateOptions" needs to be exported by the entry point index.d.ts static create({ logger, config, factories }: CreateOptions): UrlReader; static default({ logger, config, factories }: CreateOptions): UrlReader; } -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "useHotCleanup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function useHotCleanup(_module: NodeModule, cancelEffect: () => void): void; -// Warning: (tsdoc-undefined-tag) The TSDoc tag "@warning" is not defined in this configuration -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "useHotMemoize" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T; -// Warnings were encountered during analysis: -// -// src/middleware/errorHandler.ts:47:24 - (tsdoc-malformed-html-name) Invalid HTML element: A space is not allowed here -// src/reading/AzureUrlReader.ts:53:30 - (ae-forgotten-export) The symbol "ReadTreeResponseFactory" needs to be exported by the entry point index.d.ts -// src/reading/types.ts:87:3 - (ae-forgotten-export) The symbol "ReadTreeResponseDirOptions" needs to be exported by the entry point index.d.ts -// src/service/types.ts:28:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:39:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:48:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:57:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:67:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:76:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:78:3 - (ae-forgotten-export) The symbol "HttpsSettings" needs to be exported by the entry point index.d.ts -// src/service/types.ts:83:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/service/types.ts:84:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index 467cf752af..a17a6cdc10 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -8,8 +8,6 @@ import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; import { Location as Location_2 } from '@backstage/catalog-model'; -// Warning: (ae-missing-release-tag) "AddLocationRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AddLocationRequest = { type?: string; @@ -18,22 +16,16 @@ export type AddLocationRequest = { presence?: 'optional' | 'required'; }; -// Warning: (ae-missing-release-tag) "AddLocationResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AddLocationResponse = { location: Location_2; entities: Entity[]; }; -// Warning: (ae-missing-release-tag) "CatalogApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface CatalogApi { // (undocumented) addLocation(location: AddLocationRequest, options?: CatalogRequestOptions): Promise<AddLocationResponse>; - // Warning: (ae-forgotten-export) The symbol "CatalogRequestOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) getEntities(request?: CatalogEntitiesRequest, options?: CatalogRequestOptions): Promise<CatalogListResponse<Entity>>; // (undocumented) @@ -41,7 +33,7 @@ export interface CatalogApi { // (undocumented) getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; // (undocumented) - getLocationById(id: String, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + getLocationById(id: string, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; // (undocumented) getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; // (undocumented) @@ -50,8 +42,6 @@ export interface CatalogApi { removeLocationById(id: string, options?: CatalogRequestOptions): Promise<void>; } -// Warning: (ae-missing-release-tag) "CatalogClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class CatalogClient implements CatalogApi { constructor(options: { @@ -66,7 +56,7 @@ export class CatalogClient implements CatalogApi { // (undocumented) getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; // (undocumented) - getLocationById(id: String, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; + getLocationById(id: string, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; // (undocumented) getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>; // (undocumented) @@ -75,26 +65,18 @@ export class CatalogClient implements CatalogApi { removeLocationById(id: string, options?: CatalogRequestOptions): Promise<void>; } -// Warning: (ae-missing-release-tag) "CatalogEntitiesRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CatalogEntitiesRequest = { filter?: Record<string, string | string[]> | undefined; fields?: string[] | undefined; }; -// Warning: (ae-missing-release-tag) "CatalogListResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CatalogListResponse<T> = { items: T[]; }; -// Warnings were encountered during analysis: -// -// src/CatalogClient.ts:40:26 - (ae-forgotten-export) The symbol "DiscoveryApi" needs to be exported by the entry point index.d.ts - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index 7aa98e52c7..c37c86b01f 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -9,23 +9,15 @@ import { JSONSchema7 } from 'json-schema'; import { JsonValue } from '@backstage/config'; import * as yup from 'yup'; -// Warning: (ae-missing-release-tag) "analyzeLocationSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const analyzeLocationSchema: yup.ObjectSchema<{ location: LocationSpec; }, object>; -// Warning: (ae-missing-release-tag) "ApiEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface ApiEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND; // (undocumented) @@ -42,53 +34,26 @@ export { ApiEntityV1alpha1 as ApiEntity } export { ApiEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "apiEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const apiEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "CommonValidatorFunctions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class CommonValidatorFunctions { - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen static isJsonSafe(value: unknown): boolean; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool static isValidDnsLabel(value: unknown): boolean; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool static isValidDnsSubdomain(value: unknown): boolean; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen static isValidPrefixAndOrSuffix(value: unknown, separator: string, isValidPrefix: (value: string) => boolean, isValidSuffix: (value: string) => boolean): boolean; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen static isValidString(value: unknown): boolean; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen static isValidUrl(value: unknown): boolean; } -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-forgotten-export) The symbol "EntityRefContext" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "compareEntityToRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function compareEntityToRef(entity: Entity, ref: EntityRef | EntityName, context?: EntityRefContext): boolean; -// Warning: (ae-missing-release-tag) "ComponentEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface ComponentEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_2[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_2; // (undocumented) @@ -99,6 +64,7 @@ interface ComponentEntityV1alpha1 extends Entity { subcomponentOf?: string; providesApis?: string[]; consumesApis?: string[]; + dependsOn?: string[]; system?: string; }; } @@ -107,13 +73,9 @@ export { ComponentEntityV1alpha1 as ComponentEntity } export { ComponentEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "componentEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const componentEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "DefaultNamespaceEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class DefaultNamespaceEntityPolicy implements EntityPolicy { constructor(namespace?: string); @@ -121,16 +83,10 @@ export class DefaultNamespaceEntityPolicy implements EntityPolicy { enforce(entity: Entity): Promise<Entity>; } -// Warning: (ae-missing-release-tag) "DomainEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface DomainEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_3[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_3; // (undocumented) @@ -143,19 +99,12 @@ export { DomainEntityV1alpha1 as DomainEntity } export { DomainEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "domainEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const domainEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "EDIT_URL_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const EDIT_URL_ANNOTATION = "backstage.io/edit-url"; -// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool -// Warning: (ae-missing-release-tag) "Entity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type Entity = { apiVersion: string; @@ -165,25 +114,15 @@ export type Entity = { relations?: EntityRelation[]; }; -// Warning: (ae-missing-release-tag) "ENTITY_DEFAULT_NAMESPACE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const ENTITY_DEFAULT_NAMESPACE = "default"; -// Warning: (ae-missing-release-tag) "ENTITY_META_GENERATED_FIELDS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const ENTITY_META_GENERATED_FIELDS: readonly ["uid", "etag", "generation"]; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "entityHasChanges" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function entityHasChanges(previous: Entity, next: Entity): boolean; -// Warning: (ae-missing-release-tag) "EntityLink" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityLink = { url: string; @@ -191,10 +130,6 @@ export type EntityLink = { icon?: string; }; -// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool -// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool -// Warning: (ae-missing-release-tag) "EntityMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityMeta = JsonObject & { uid?: string; @@ -209,8 +144,6 @@ export type EntityMeta = JsonObject & { links?: EntityLink[]; }; -// Warning: (ae-missing-release-tag) "EntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityName = { kind: string; @@ -218,23 +151,17 @@ export type EntityName = { name: string; }; -// Warning: (ae-missing-release-tag) "EntityPolicies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const EntityPolicies: { allOf(policies: EntityPolicy[]): AllEntityPolicies; oneOf(policies: EntityPolicy[]): AnyEntityPolicy; }; -// Warning: (ae-missing-release-tag) "EntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityPolicy = { enforce(entity: Entity): Promise<Entity | undefined>; }; -// Warning: (ae-missing-release-tag) "EntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityRef = string | { kind?: string; @@ -242,16 +169,12 @@ export type EntityRef = string | { name: string; }; -// Warning: (ae-missing-release-tag) "EntityRelation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityRelation = { type: string; target: EntityName; }; -// Warning: (ae-missing-release-tag) "EntityRelationSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type EntityRelationSpec = { source: EntityName; @@ -259,8 +182,6 @@ export type EntityRelationSpec = { target: EntityName; }; -// Warning: (ae-missing-release-tag) "FieldFormatEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class FieldFormatEntityPolicy implements EntityPolicy { constructor(validators?: Validators); @@ -268,39 +189,28 @@ export class FieldFormatEntityPolicy implements EntityPolicy { enforce(entity: Entity): Promise<Entity>; } -// Warning: (ae-missing-release-tag) "generateEntityEtag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function generateEntityEtag(): string; -// Warning: (ae-missing-release-tag) "generateEntityUid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function generateEntityUid(): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "generateUpdatedEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function generateUpdatedEntity(previous: Entity, next: Entity): Entity; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getEntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getEntityName(entity: Entity): EntityName; -// Warning: (ae-missing-release-tag) "GroupEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export function getEntitySourceLocation(entity: Entity): { + type: string; + target: string; +}; + // @public (undocumented) interface GroupEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_4[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_4; // (undocumented) @@ -321,30 +231,19 @@ export { GroupEntityV1alpha1 as GroupEntity } export { GroupEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "groupEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const groupEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "JSONSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type JSONSchema = JSONSchema7 & { [key in string]?: JsonValue; }; -// Warning: (ae-missing-release-tag) "KindValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type KindValidator = { check(entity: Entity): Promise<boolean>; }; -// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool -// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool -// Warning: (tsdoc-unsupported-tag) The TSDoc tag "@see" is not supported by this tool -// Warning: (ae-missing-release-tag) "KubernetesValidatorFunctions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class KubernetesValidatorFunctions { // (undocumented) @@ -365,8 +264,6 @@ export class KubernetesValidatorFunctions { static isValidObjectName(value: unknown): boolean; } -// Warning: (ae-missing-release-tag) "Location" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) type Location_2 = { id: string; @@ -374,21 +271,13 @@ type Location_2 = { export { Location_2 as Location } -// Warning: (ae-missing-release-tag) "LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const LOCATION_ANNOTATION = "backstage.io/managed-by-location"; -// Warning: (ae-missing-release-tag) "LocationEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface LocationEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_5[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_5; // (undocumented) @@ -403,18 +292,12 @@ export { LocationEntityV1alpha1 as LocationEntity } export { LocationEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "locationEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const locationEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "locationSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const locationSchema: yup.ObjectSchema<Location_2, object>; -// Warning: (ae-missing-release-tag) "LocationSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type LocationSpec = { type: string; @@ -422,18 +305,12 @@ export type LocationSpec = { presence?: 'optional' | 'required'; }; -// Warning: (ae-missing-release-tag) "locationSpecSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const locationSpecSchema: yup.ObjectSchema<LocationSpec, object>; -// Warning: (ae-missing-release-tag) "makeValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function makeValidator(overrides?: Partial<Validators>): Validators; -// Warning: (ae-missing-release-tag) "NoForeignRootFieldsEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class NoForeignRootFieldsEntityPolicy implements EntityPolicy { constructor(knownFields?: string[]); @@ -441,24 +318,12 @@ export class NoForeignRootFieldsEntityPolicy implements EntityPolicy { enforce(entity: Entity): Promise<Entity>; } -// Warning: (ae-missing-release-tag) "ORIGIN_LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const ORIGIN_LOCATION_ANNOTATION = "backstage.io/managed-by-origin-location"; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "parseEntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function parseEntityName(ref: EntityRef, context?: EntityRefContext): EntityName; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function parseEntityRef(ref: EntityRef, context?: { defaultKind: string; @@ -487,103 +352,65 @@ export function parseEntityRef(ref: EntityRef, context?: { name: string; }; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (ae-missing-release-tag) "parseLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function parseLocationReference(ref: string): { type: string; target: string; }; -// Warning: (ae-missing-release-tag) "RELATION_API_CONSUMED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_API_CONSUMED_BY = "apiConsumedBy"; -// Warning: (ae-missing-release-tag) "RELATION_API_PROVIDED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_API_PROVIDED_BY = "apiProvidedBy"; -// Warning: (ae-missing-release-tag) "RELATION_CHILD_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_CHILD_OF = "childOf"; -// Warning: (ae-missing-release-tag) "RELATION_CONSUMES_API" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const RELATION_CONSUMES_API = "consumesApi"; -// Warning: (ae-missing-release-tag) "RELATION_DEPENDENCY_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_DEPENDENCY_OF = "dependencyOf"; -// Warning: (ae-missing-release-tag) "RELATION_DEPENDS_ON" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const RELATION_DEPENDS_ON = "dependsOn"; -// Warning: (ae-missing-release-tag) "RELATION_HAS_MEMBER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_HAS_MEMBER = "hasMember"; -// Warning: (ae-missing-release-tag) "RELATION_HAS_PART" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_HAS_PART = "hasPart"; -// Warning: (ae-missing-release-tag) "RELATION_MEMBER_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const RELATION_MEMBER_OF = "memberOf"; -// Warning: (ae-missing-release-tag) "RELATION_OWNED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const RELATION_OWNED_BY = "ownedBy"; -// Warning: (ae-missing-release-tag) "RELATION_OWNER_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_OWNER_OF = "ownerOf"; -// Warning: (ae-missing-release-tag) "RELATION_PARENT_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const RELATION_PARENT_OF = "parentOf"; -// Warning: (ae-missing-release-tag) "RELATION_PART_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const RELATION_PART_OF = "partOf"; -// Warning: (ae-missing-release-tag) "RELATION_PROVIDES_API" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const RELATION_PROVIDES_API = "providesApi"; -// Warning: (ae-missing-release-tag) "ResourceEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface ResourceEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_6[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_6; // (undocumented) spec: { type: string; owner: string; + dependsOn?: string[]; system?: string; }; } @@ -592,27 +419,18 @@ export { ResourceEntityV1alpha1 as ResourceEntity } export { ResourceEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "resourceEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const resourceEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "schemaValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public @deprecated (undocumented) export function schemaValidator(kind: string, apiVersion: readonly string[], schema: yup.Schema<any>): KindValidator; -// Warning: (ae-missing-release-tag) "SchemaValidEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class SchemaValidEntityPolicy implements EntityPolicy { // (undocumented) enforce(entity: Entity): Promise<Entity>; } -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "serializeEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public @deprecated export function serializeEntityRef(ref: Entity | { kind?: string; @@ -620,14 +438,9 @@ export function serializeEntityRef(ref: Entity | { name: string; }): EntityRef; -// Warning: (ae-missing-release-tag) "SOURCE_LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const SOURCE_LOCATION_ANNOTATION = "backstage.io/source-location"; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "stringifyEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function stringifyEntityRef(ref: Entity | { kind: string; @@ -635,27 +448,16 @@ export function stringifyEntityRef(ref: Entity | { name: string; }): string; -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "stringifyLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function stringifyLocationReference(ref: { type: string; target: string; }): string; -// Warning: (ae-missing-release-tag) "SystemEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface SystemEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_7[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_7; // (undocumented) @@ -669,21 +471,13 @@ export { SystemEntityV1alpha1 as SystemEntity } export { SystemEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "systemEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const systemEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "TemplateEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface TemplateEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_8[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_8; // (undocumented) @@ -699,21 +493,13 @@ export { TemplateEntityV1alpha1 as TemplateEntity } export { TemplateEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "templateEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const templateEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "TemplateEntityV1beta2" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface TemplateEntityV1beta2 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_9[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_9; // (undocumented) @@ -736,21 +522,13 @@ export interface TemplateEntityV1beta2 extends Entity { }; } -// Warning: (ae-missing-release-tag) "templateEntityV1beta2Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const templateEntityV1beta2Validator: KindValidator; -// Warning: (ae-missing-release-tag) "UserEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) interface UserEntityV1alpha1 extends Entity { - // Warning: (ae-forgotten-export) The symbol "API_VERSION" needs to be exported by the entry point index.d.ts - // // (undocumented) apiVersion: typeof API_VERSION_10[number]; - // Warning: (ae-forgotten-export) The symbol "KIND" needs to be exported by the entry point index.d.ts - // // (undocumented) kind: typeof KIND_10; // (undocumented) @@ -768,13 +546,9 @@ export { UserEntityV1alpha1 as UserEntity } export { UserEntityV1alpha1 } -// Warning: (ae-missing-release-tag) "userEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const userEntityV1alpha1Validator: KindValidator; -// Warning: (ae-missing-release-tag) "Validators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type Validators = { isValidApiVersion(value: unknown): boolean; @@ -788,19 +562,10 @@ export type Validators = { isValidTag(value: unknown): boolean; }; -// Warning: (ae-missing-release-tag) "VIEW_URL_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const VIEW_URL_ANNOTATION = "backstage.io/view-url"; -// Warnings were encountered during analysis: -// -// src/EntityPolicies.ts:55:28 - (ae-forgotten-export) The symbol "AllEntityPolicies" needs to be exported by the entry point index.d.ts -// src/EntityPolicies.ts:57:3 - (ae-forgotten-export) The symbol "AnyEntityPolicy" needs to be exported by the entry point index.d.ts -// src/entity/policies/types.ts:27:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/kinds/types.ts:26:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/cli-common/api-report.md b/packages/cli-common/api-report.md index f4df3562b8..bcdc023c22 100644 --- a/packages/cli-common/api-report.md +++ b/packages/cli-common/api-report.md @@ -4,13 +4,9 @@ ```ts -// Warning: (ae-missing-release-tag) "findPaths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function findPaths(searchDir: string): Paths; -// Warning: (ae-missing-release-tag) "Paths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type Paths = { ownDir: string; @@ -24,10 +20,6 @@ export type Paths = { }; -// Warnings were encountered during analysis: -// -// src/paths.ts:38:3 - (ae-forgotten-export) The symbol "ResolveFunc" needs to be exported by the entry point index.d.ts - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index ffa599df2b..a09311b786 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -8,27 +8,18 @@ import { AppConfig } from '@backstage/config'; import { JsonObject } from '@backstage/config'; import { JSONSchema7 } from 'json-schema'; -// Warning: (ae-missing-release-tag) "ConfigSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ConfigSchema = { process(appConfigs: AppConfig[], options?: ConfigProcessingOptions): AppConfig[]; serialize(): JsonObject; }; -// Warning: (ae-forgotten-export) The symbol "CONFIG_VISIBILITIES" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ConfigVisibility" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ConfigVisibility = typeof CONFIG_VISIBILITIES[number]; -// Warning: (ae-missing-release-tag) "loadConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function loadConfig(options: LoadConfigOptions): Promise<AppConfig[]>; -// Warning: (ae-missing-release-tag) "LoadConfigOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type LoadConfigOptions = { configRoot: string; @@ -37,31 +28,18 @@ export type LoadConfigOptions = { experimentalEnvFunc?: EnvFunc; }; -// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "loadConfigSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function loadConfigSchema(options: Options): Promise<ConfigSchema>; -// Warning: (ae-missing-release-tag) "mergeConfigSchemas" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function mergeConfigSchemas(schemas: JSONSchema7[]): JSONSchema7; -// Warning: (ae-missing-release-tag) "readEnvConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readEnvConfig(env: { [name: string]: string | undefined; }): AppConfig[]; -// Warnings were encountered during analysis: -// -// src/lib/schema/types.ts:105:3 - (ae-forgotten-export) The symbol "ConfigProcessingOptions" needs to be exported by the entry point index.d.ts -// src/loader.ts:42:6 - (tsdoc-unsupported-tag) The TSDoc tag "@experimental" is not supported by this tool -// src/loader.ts:44:3 - (ae-forgotten-export) The symbol "EnvFunc" needs to be exported by the entry point index.d.ts - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/config/api-report.md b/packages/config/api-report.md index 4e0da777ec..be250778ec 100644 --- a/packages/config/api-report.md +++ b/packages/config/api-report.md @@ -4,16 +4,12 @@ ```ts -// Warning: (ae-missing-release-tag) "AppConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AppConfig = { context: string; data: JsonObject; }; -// Warning: (ae-missing-release-tag) "Config" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type Config = { has(key: string): boolean; @@ -34,8 +30,6 @@ export type Config = { getOptionalStringArray(key: string): string[] | undefined; }; -// Warning: (ae-missing-release-tag) "ConfigReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class ConfigReader implements Config { constructor(data: JsonObject | undefined, context?: string, fallback?: ConfigReader | undefined, prefix?: string); @@ -75,26 +69,18 @@ export class ConfigReader implements Config { keys(): string[]; } -// Warning: (ae-missing-release-tag) "JsonArray" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface JsonArray extends Array<JsonValue> { } -// Warning: (ae-missing-release-tag) "JsonObject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type JsonObject = { [key in string]?: JsonValue; }; -// Warning: (ae-missing-release-tag) "JsonPrimitive" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type JsonPrimitive = number | string | boolean | null; -// Warning: (ae-missing-release-tag) "JsonValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type JsonValue = JsonObject | JsonArray | JsonPrimitive; diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md index 841f9c19b2..d3e6447cd5 100644 --- a/packages/dev-utils/api-report.md +++ b/packages/dev-utils/api-report.md @@ -12,14 +12,9 @@ import { GridProps } from '@material-ui/core'; import { IconComponent } from '@backstage/core'; import { ReactNode } from 'react'; -// Warning: (ae-forgotten-export) The symbol "DevAppBuilder" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createDevApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function createDevApp(): DevAppBuilder; -// Warning: (ae-missing-release-tag) "EntityGridItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const EntityGridItem: ({ entity, classes, ...rest }: Omit<GridProps<"div", {}>, "container" | "item"> & { entity: Entity; diff --git a/packages/errors/api-report.md b/packages/errors/api-report.md index 18861fdc84..cb24cba80f 100644 --- a/packages/errors/api-report.md +++ b/packages/errors/api-report.md @@ -6,20 +6,14 @@ import { JsonObject } from '@backstage/config'; -// Warning: (ae-missing-release-tag) "AuthenticationError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class AuthenticationError extends CustomErrorBase { } -// Warning: (ae-missing-release-tag) "ConflictError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class ConflictError extends CustomErrorBase { } -// Warning: (ae-missing-release-tag) "CustomErrorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class CustomErrorBase extends Error { constructor(message?: string, cause?: Error); @@ -27,13 +21,9 @@ export class CustomErrorBase extends Error { readonly cause?: Error; } -// Warning: (ae-missing-release-tag) "deserializeError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function deserializeError<T extends Error = Error>(data: SerializedError): T; -// Warning: (ae-missing-release-tag) "ErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ErrorResponse = { error: SerializedError; @@ -46,38 +36,25 @@ export type ErrorResponse = { }; }; -// Warning: (ae-missing-release-tag) "InputError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class InputError extends CustomErrorBase { } -// Warning: (ae-missing-release-tag) "NotAllowedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class NotAllowedError extends CustomErrorBase { } -// Warning: (ae-missing-release-tag) "NotFoundError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class NotFoundError extends CustomErrorBase { } -// Warning: (ae-missing-release-tag) "NotModifiedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class NotModifiedError extends CustomErrorBase { } -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "parseErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function parseErrorResponse(response: Response): Promise<ErrorResponse>; -// Warning: (ae-missing-release-tag) "ResponseError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class ResponseError extends Error { constructor(props: { @@ -92,8 +69,6 @@ export class ResponseError extends Error { readonly response: Response; } -// Warning: (ae-missing-release-tag) "SerializedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type SerializedError = JsonObject & { name: string; @@ -102,10 +77,6 @@ export type SerializedError = JsonObject & { code?: string; }; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// Warning: (ae-missing-release-tag) "serializeError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function serializeError(error: Error, options?: { includeStack?: boolean; diff --git a/packages/integration-react/api-report.md b/packages/integration-react/api-report.md index 8dcc02a443..7c37ab0392 100644 --- a/packages/integration-react/api-report.md +++ b/packages/integration-react/api-report.md @@ -8,16 +8,12 @@ import { ApiRef } from '@backstage/core'; import { Config } from '@backstage/config'; import { ScmIntegrationRegistry } from '@backstage/integration'; -// Warning: (ae-missing-release-tag) "ScmIntegrationsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class ScmIntegrationsApi { // (undocumented) static fromConfig(config: Config): ScmIntegrationRegistry; } -// Warning: (ae-missing-release-tag) "scmIntegrationsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const scmIntegrationsApiRef: ApiRef<ScmIntegrationRegistry>; diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md index 6d85bf4a51..5387eb12db 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/api-report.md @@ -6,15 +6,11 @@ import { Config } from '@backstage/config'; -// Warning: (ae-missing-release-tag) "AzureIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class AzureIntegration implements ScmIntegration { constructor(integrationConfig: AzureIntegrationConfig); // (undocumented) get config(): AzureIntegrationConfig; - // Warning: (ae-forgotten-export) The symbol "ScmIntegrationsFactory" needs to be exported by the entry point index.d.ts - // // (undocumented) static factory: ScmIntegrationsFactory<AzureIntegration>; // (undocumented) @@ -31,16 +27,12 @@ export class AzureIntegration implements ScmIntegration { get type(): string; } -// Warning: (ae-missing-release-tag) "AzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AzureIntegrationConfig = { host: string; token?: string; }; -// Warning: (ae-missing-release-tag) "BitbucketIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class BitbucketIntegration implements ScmIntegration { constructor(integrationConfig: BitbucketIntegrationConfig); @@ -62,8 +54,6 @@ export class BitbucketIntegration implements ScmIntegration { get type(): string; } -// Warning: (ae-missing-release-tag) "BitbucketIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type BitbucketIntegrationConfig = { host: string; @@ -73,8 +63,6 @@ export type BitbucketIntegrationConfig = { appPassword?: string; }; -// Warning: (ae-missing-release-tag) "defaultScmResolveUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function defaultScmResolveUrl(options: { url: string; @@ -82,123 +70,51 @@ export function defaultScmResolveUrl(options: { lineNumber?: number; }): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getAzureCommitsUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getAzureCommitsUrl(url: string): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getAzureDownloadUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getAzureDownloadUrl(url: string): string; -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getAzureFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getAzureFileFetchUrl(url: string): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getAzureRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getAzureRequestOptions(config: AzureIntegrationConfig, additionalHeaders?: Record<string, string>): RequestInit; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getBitbucketDefaultBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getBitbucketDefaultBranch(url: string, config: BitbucketIntegrationConfig): Promise<string>; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getBitbucketDownloadUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getBitbucketDownloadUrl(url: string, config: BitbucketIntegrationConfig): Promise<string>; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getBitbucketFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getBitbucketFileFetchUrl(url: string, config: BitbucketIntegrationConfig): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getBitbucketRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getBitbucketRequestOptions(config: BitbucketIntegrationConfig): RequestInit; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getGitHubFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getGitHubFileFetchUrl(url: string, config: GitHubIntegrationConfig): string; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getGitHubRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getGitHubRequestOptions(config: GitHubIntegrationConfig): RequestInit; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getGitLabFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getGitLabFileFetchUrl(url: string, config: GitLabIntegrationConfig): Promise<string>; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "getGitLabRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function getGitLabRequestOptions(config: GitLabIntegrationConfig): RequestInit; -// Warning: (ae-missing-release-tag) "GithubCredentialsProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class GithubCredentialsProvider { // (undocumented) static create(config: GitHubIntegrationConfig): GithubCredentialsProvider; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag - // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag - // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" - // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" - // Warning: (tsdoc-undefined-tag) The TSDoc tag "@type" is not defined in this configuration - // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag - // Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag - // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" - // Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" - // Warning: (ae-forgotten-export) The symbol "GithubCredentials" needs to be exported by the entry point index.d.ts getCredentials(opts: { url: string; }): Promise<GithubCredentials>; } -// Warning: (ae-missing-release-tag) "GitHubIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class GitHubIntegration implements ScmIntegration { constructor(integrationConfig: GitHubIntegrationConfig); @@ -220,8 +136,6 @@ export class GitHubIntegration implements ScmIntegration { get type(): string; } -// Warning: (ae-missing-release-tag) "GitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type GitHubIntegrationConfig = { host: string; @@ -231,8 +145,6 @@ export type GitHubIntegrationConfig = { apps?: GithubAppConfig[]; }; -// Warning: (ae-missing-release-tag) "GitLabIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class GitLabIntegration implements ScmIntegration { constructor(integrationConfig: GitLabIntegrationConfig); @@ -254,8 +166,6 @@ export class GitLabIntegration implements ScmIntegration { get type(): string; } -// Warning: (ae-missing-release-tag) "GitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type GitLabIntegrationConfig = { host: string; @@ -264,63 +174,42 @@ export type GitLabIntegrationConfig = { baseUrl: string; }; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readAzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export type GoogleGcsIntegrationConfig = { + clientEmail?: string; + privateKey?: string; +}; + // @public export function readAzureIntegrationConfig(config: Config): AzureIntegrationConfig; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readAzureIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readAzureIntegrationConfigs(configs: Config[]): AzureIntegrationConfig[]; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readBitbucketIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readBitbucketIntegrationConfig(config: Config): BitbucketIntegrationConfig; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readBitbucketIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readBitbucketIntegrationConfigs(configs: Config[]): BitbucketIntegrationConfig[]; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readGitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readGitHubIntegrationConfig(config: Config): GitHubIntegrationConfig; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readGitHubIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readGitHubIntegrationConfigs(configs: Config[]): GitHubIntegrationConfig[]; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readGitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readGitLabIntegrationConfig(config: Config): GitLabIntegrationConfig; -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "readGitLabIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function readGitLabIntegrationConfigs(configs: Config[]): GitLabIntegrationConfig[]; -// Warning: (ae-missing-release-tag) "ScmIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export function readGoogleGcsIntegrationConfig(config: Config): GoogleGcsIntegrationConfig; + // @public export interface ScmIntegration { - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen resolveEditUrl(url: string): string; - // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters - // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters - // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters resolveUrl(options: { url: string; base: string; @@ -330,8 +219,6 @@ export interface ScmIntegration { type: string; } -// Warning: (ae-missing-release-tag) "ScmIntegrationRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface ScmIntegrationRegistry extends ScmIntegrationsGroup<ScmIntegration> { // (undocumented) @@ -342,11 +229,7 @@ export interface ScmIntegrationRegistry extends ScmIntegrationsGroup<ScmIntegrat github: ScmIntegrationsGroup<GitHubIntegration>; // (undocumented) gitlab: ScmIntegrationsGroup<GitLabIntegration>; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen resolveEditUrl(url: string): string; - // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters - // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters - // Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters resolveUrl(options: { url: string; base: string; @@ -354,11 +237,8 @@ export interface ScmIntegrationRegistry extends ScmIntegrationsGroup<ScmIntegrat }): string; } -// Warning: (ae-missing-release-tag) "ScmIntegrations" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class ScmIntegrations implements ScmIntegrationRegistry { - // Warning: (ae-forgotten-export) The symbol "IntegrationsByType" needs to be exported by the entry point index.d.ts constructor(integrationsByType: IntegrationsByType); // (undocumented) get azure(): ScmIntegrationsGroup<AzureIntegration>; @@ -386,24 +266,14 @@ export class ScmIntegrations implements ScmIntegrationRegistry { }): string; } -// Warning: (ae-missing-release-tag) "ScmIntegrationsGroup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface ScmIntegrationsGroup<T extends ScmIntegration> { - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen byHost(host: string): T | undefined; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen byUrl(url: string | URL): T | undefined; list(): T[]; } -// Warnings were encountered during analysis: -// -// src/github/config.ts:67:3 - (ae-forgotten-export) The symbol "GithubAppConfig" needs to be exported by the entry point index.d.ts -// src/gitlab/config.ts:51:66 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// src/gitlab/config.ts:51:61 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/search-common/api-report.md b/packages/search-common/api-report.md index ed53275017..70522f4ee4 100644 --- a/packages/search-common/api-report.md +++ b/packages/search-common/api-report.md @@ -6,24 +6,18 @@ import { JsonObject } from '@backstage/config'; -// Warning: (ae-missing-release-tag) "DocumentCollator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface DocumentCollator { // (undocumented) execute(): Promise<IndexableDocument[]>; } -// Warning: (ae-missing-release-tag) "DocumentDecorator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface DocumentDecorator { // (undocumented) execute(documents: IndexableDocument[]): Promise<IndexableDocument[]>; } -// Warning: (ae-missing-release-tag) "IndexableDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface IndexableDocument { location: string; @@ -31,8 +25,6 @@ export interface IndexableDocument { title: string; } -// Warning: (ae-missing-release-tag) "SearchQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface SearchQuery { // (undocumented) @@ -43,16 +35,12 @@ export interface SearchQuery { term: string; } -// Warning: (ae-missing-release-tag) "SearchResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface SearchResult { // (undocumented) document: IndexableDocument; } -// Warning: (ae-missing-release-tag) "SearchResultSet" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface SearchResultSet { // (undocumented) diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index aa6c9da2f8..c26f62e981 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -17,26 +17,18 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { UrlReader } from '@backstage/backend-common'; import { Writable } from 'stream'; -// Warning: (ae-missing-release-tag) "checkoutGitRepository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const checkoutGitRepository: (repoUrl: string, config: Config, logger: Logger) => Promise<string>; -// Warning: (ae-missing-release-tag) "CommonGitPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class CommonGitPreparer implements PreparerBase { constructor(config: Config, logger: Logger); - // Warning: (ae-forgotten-export) The symbol "PreparerResponse" needs to be exported by the entry point index.d.ts - // // (undocumented) prepare(entity: Entity, options?: { etag?: string; }): Promise<PreparerResponse>; } -// Warning: (ae-missing-release-tag) "DirectoryPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class DirectoryPreparer implements PreparerBase { constructor(config: Config, logger: Logger, reader: UrlReader); @@ -44,23 +36,17 @@ export class DirectoryPreparer implements PreparerBase { prepare(entity: Entity): Promise<PreparerResponse>; } -// Warning: (ae-missing-release-tag) "GeneratorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type GeneratorBase = { run(opts: GeneratorRunOptions): Promise<void>; }; -// Warning: (ae-missing-release-tag) "GeneratorBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type GeneratorBuilder = { register(protocol: SupportedGeneratorKey, generator: GeneratorBase): void; get(entity: Entity): GeneratorBase; }; -// Warning: (ae-missing-release-tag) "Generators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class Generators implements GeneratorBuilder { // (undocumented) @@ -73,79 +59,51 @@ export class Generators implements GeneratorBuilder { register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase): void; } -// Warning: (ae-missing-release-tag) "getAzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getAzureIntegrationConfig: (config: Config, host: string) => AzureIntegrationConfig; -// Warning: (ae-missing-release-tag) "getDefaultBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getDefaultBranch: (repositoryUrl: string, config: Config) => Promise<string>; -// Warning: (ae-missing-release-tag) "getDocFilesFromRepository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getDocFilesFromRepository: (reader: UrlReader, entity: Entity, opts?: { etag?: string | undefined; logger?: Logger | undefined; } | undefined) => Promise<PreparerResponse>; -// Warning: (ae-missing-release-tag) "getGitHost" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function getGitHost(url: string): string; -// Warning: (ae-missing-release-tag) "getGitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getGitHubIntegrationConfig: (config: Config, host: string) => GitHubIntegrationConfig; -// Warning: (ae-missing-release-tag) "getGitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getGitLabIntegrationConfig: (config: Config, host: string) => GitLabIntegrationConfig; -// Warning: (ae-missing-release-tag) "getGitRepositoryTempFolder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getGitRepositoryTempFolder: (repositoryUrl: string, config: Config) => Promise<string>; -// Warning: (ae-missing-release-tag) "getGitRepoType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function getGitRepoType(url: string): string; -// Warning: (ae-missing-release-tag) "getLastCommitTimestamp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getLastCommitTimestamp: (repositoryLocation: string, logger: Logger) => Promise<number>; -// Warning: (ae-missing-release-tag) "getLocationForEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getLocationForEntity: (entity: Entity) => ParsedLocationAnnotation; -// Warning: (ae-missing-release-tag) "getTokenForGitRepo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const getTokenForGitRepo: (repositoryUrl: string, config: Config) => Promise<string | undefined>; -// Warning: (ae-missing-release-tag) "ParsedLocationAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type ParsedLocationAnnotation = { type: RemoteProtocol; target: string; }; -// Warning: (ae-missing-release-tag) "parseReferenceAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const parseReferenceAnnotation: (annotationName: string, entity: Entity) => ParsedLocationAnnotation; -// Warning: (ae-missing-release-tag) "PreparerBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PreparerBase = { prepare(entity: Entity, options?: { @@ -154,20 +112,14 @@ export type PreparerBase = { }): Promise<PreparerResponse>; }; -// Warning: (ae-missing-release-tag) "PreparerBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PreparerBuilder = { register(protocol: RemoteProtocol, preparer: PreparerBase): void; get(entity: Entity): PreparerBase; }; -// Warning: (ae-missing-release-tag) "Preparers" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class Preparers implements PreparerBuilder { - // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) static fromConfig(config: Config, { logger, reader }: factoryOptions): Promise<PreparerBuilder>; // (undocumented) @@ -176,41 +128,26 @@ export class Preparers implements PreparerBuilder { register(protocol: RemoteProtocol, preparer: PreparerBase): void; } -// Warning: (ae-missing-release-tag) "Publisher" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class Publisher { - // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) static fromConfig(config: Config, { logger, discovery }: factoryOptions_2): Promise<PublisherBase>; } -// Warning: (ae-missing-release-tag) "PublisherBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface PublisherBase { docsRouter(): express.Handler; fetchTechDocsMetadata(entityName: EntityName): Promise<TechDocsMetadata>; hasDocsBeenGenerated(entityName: Entity): Promise<boolean>; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (ae-forgotten-export) The symbol "PublishRequest" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "PublishResponse" needs to be exported by the entry point index.d.ts publish(request: PublishRequest): Promise<PublishResponse>; } -// Warning: (ae-missing-release-tag) "PublisherType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type PublisherType = 'local' | 'googleGcs' | 'awsS3' | 'azureBlobStorage' | 'openStackSwift'; -// Warning: (ae-missing-release-tag) "RemoteProtocol" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type RemoteProtocol = 'url' | 'dir' | 'github' | 'gitlab' | 'file' | 'azure/api'; -// Warning: (ae-missing-release-tag) "TechdocsGenerator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class TechdocsGenerator implements GeneratorBase { constructor(logger: Logger, config: Config); @@ -218,9 +155,6 @@ export class TechdocsGenerator implements GeneratorBase { run({ inputDir, outputDir, dockerClient, parsedLocationAnnotation, etag, }: GeneratorRunOptions): Promise<void>; } -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "TechDocsMetadata" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type TechDocsMetadata = { site_name: string; @@ -228,8 +162,6 @@ export type TechDocsMetadata = { etag: string; }; -// Warning: (ae-missing-release-tag) "UrlPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class UrlPreparer implements PreparerBase { constructor(reader: UrlReader, logger: Logger); @@ -240,15 +172,6 @@ export class UrlPreparer implements PreparerBase { } -// Warnings were encountered during analysis: -// -// src/stages/generate/types.ts:42:3 - (ae-forgotten-export) The symbol "GeneratorRunOptions" needs to be exported by the entry point index.d.ts -// src/stages/generate/types.ts:54:3 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts -// src/stages/prepare/types.ts:35:6 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/stages/prepare/types.ts:36:6 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters -// src/stages/prepare/types.ts:38:31 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// src/stages/prepare/types.ts:38:14 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/test-utils-core/api-report.md b/packages/test-utils-core/api-report.md index bda058ad23..4b603b8e7b 100644 --- a/packages/test-utils-core/api-report.md +++ b/packages/test-utils-core/api-report.md @@ -7,20 +7,14 @@ import { ReactElement } from 'react'; import { RenderResult } from '@testing-library/react'; -// Warning: (ae-missing-release-tag) "AsyncLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AsyncLogCollector = () => Promise<void>; -// Warning: (ae-missing-release-tag) "CollectedLogs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CollectedLogs<T extends LogFuncs> = { [key in T]: string[]; }; -// Warning: (ae-missing-release-tag) "Keyboard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class Keyboard { constructor(target: any, { debug }?: { @@ -62,31 +56,18 @@ export class Keyboard { static typeDebug(target: any, input: any): Promise<void>; } -// Warning: (ae-missing-release-tag) "LogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type LogCollector = AsyncLogCollector | SyncLogCollector; -// Warning: (ae-missing-release-tag) "LogFuncs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type LogFuncs = 'log' | 'warn' | 'error'; -// Warning: (ae-missing-release-tag) "renderWithEffects" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function renderWithEffects(nodes: ReactElement): Promise<RenderResult>; -// Warning: (ae-missing-release-tag) "SyncLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type SyncLogCollector = () => void; -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function withLogCollector(callback: AsyncLogCollector): Promise<CollectedLogs<LogFuncs>>; diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index f62b1e6dec..dcac9b64a7 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -16,28 +16,20 @@ import { RouteRef } from '@backstage/core-api'; import { StorageApi } from '@backstage/core-api'; import { StorageValueChange } from '@backstage/core-api'; -// Warning: (ae-forgotten-export) The symbol "Breakpoint" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "mockBreakpoint" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function mockBreakpoint(initialBreakpoint?: Breakpoint): { set(breakpoint: Breakpoint): void; remove(): void; }; -// Warning: (ae-missing-release-tag) "MockErrorApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class MockErrorApi implements ErrorApi { - // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts constructor(options?: Options); // (undocumented) error$(): Observable<{ error: Error; context?: ErrorContext; }>; - // Warning: (ae-forgotten-export) The symbol "ErrorWithContext" needs to be exported by the entry point index.d.ts - // // (undocumented) getErrors(): ErrorWithContext[]; // (undocumented) @@ -46,8 +38,6 @@ export class MockErrorApi implements ErrorApi { waitForError(pattern: RegExp, timeoutMs?: number): Promise<ErrorWithContext>; } -// Warning: (ae-missing-release-tag) "MockStorageApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class MockStorageApi implements StorageApi { // (undocumented) @@ -64,15 +54,11 @@ export class MockStorageApi implements StorageApi { set<T>(key: string, data: T): Promise<void>; } -// Warning: (ae-missing-release-tag) "MockStorageBucket" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type MockStorageBucket = { [key: string]: any; }; -// Warning: (ae-missing-release-tag) "msw" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const msw: { setupDefaultHandlers: (worker: { @@ -82,14 +68,9 @@ export const msw: { }) => void; }; -// Warning: (ae-forgotten-export) The symbol "TestAppOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "renderInTestApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function renderInTestApp(Component: ComponentType | ReactNode, options?: TestAppOptions): Promise<RenderResult>; -// Warning: (ae-missing-release-tag) "wrapInTestApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function wrapInTestApp(Component: ComponentType | ReactNode, options?: TestAppOptions): ReactElement; diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md index adfbcee346..93d0957f5a 100644 --- a/packages/theme/api-report.md +++ b/packages/theme/api-report.md @@ -10,19 +10,12 @@ import { PaletteOptions } from '@material-ui/core/styles/createPalette'; import { Theme } from '@material-ui/core'; import { ThemeOptions } from '@material-ui/core'; -// Warning: (ae-forgotten-export) The symbol "PaletteAdditions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "BackstagePalette" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BackstagePalette = Palette & PaletteAdditions; -// Warning: (ae-missing-release-tag) "BackstagePaletteOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BackstagePaletteOptions = PaletteOptions & PaletteAdditions; -// Warning: (ae-missing-release-tag) "BackstageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface BackstageTheme extends Theme { // (undocumented) @@ -33,8 +26,6 @@ export interface BackstageTheme extends Theme { palette: BackstagePalette; } -// Warning: (ae-missing-release-tag) "BackstageThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface BackstageThemeOptions extends ThemeOptions { // (undocumented) @@ -45,43 +36,27 @@ export interface BackstageThemeOptions extends ThemeOptions { palette: BackstagePaletteOptions; } -// Warning: (ae-missing-release-tag) "colorVariants" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const colorVariants: Record<string, string[]>; -// Warning: (ae-missing-release-tag) "createTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createTheme(options: SimpleThemeOptions): BackstageTheme; -// Warning: (ae-missing-release-tag) "createThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createThemeOptions(options: SimpleThemeOptions): BackstageThemeOptions; -// Warning: (ae-missing-release-tag) "createThemeOverrides" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createThemeOverrides(theme: BackstageTheme): Overrides; -// Warning: (ae-missing-release-tag) "darkTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const darkTheme: BackstageTheme; -// Warning: (ae-missing-release-tag) "genPageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function genPageTheme(colors: string[], shape: string): PageTheme; -// Warning: (ae-missing-release-tag) "lightTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const lightTheme: BackstageTheme; -// Warning: (ae-missing-release-tag) "PageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PageTheme = { colors: string[]; @@ -89,25 +64,17 @@ export type PageTheme = { backgroundImage: string; }; -// Warning: (ae-missing-release-tag) "pageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const pageTheme: Record<string, PageTheme>; -// Warning: (ae-missing-release-tag) "PageThemeSelector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PageThemeSelector = { themeId: string; }; -// Warning: (ae-missing-release-tag) "shapes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const shapes: Record<string, string>; -// Warning: (ae-missing-release-tag) "SimpleThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type SimpleThemeOptions = { palette: BackstagePaletteOptions; diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 4135c52701..7bbf955f9a 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -133,9 +133,9 @@ async function runApiExtraction({ }, messages: { + // Silence warnings, as these will prevent the CI build to work compilerMessageReporting: { default: { - // Silence compiler warnings, as these will prevent the CI build to work logLevel: 'none' as ExtractorLogLevel.None, // These contain absolute file paths, so can't be included in the report // addToApiReportFile: true, @@ -143,14 +143,14 @@ async function runApiExtraction({ }, extractorMessageReporting: { default: { - logLevel: 'warning' as ExtractorLogLevel.Warning, - addToApiReportFile: true, + logLevel: 'none' as ExtractorLogLevel.Warning, + // addToApiReportFile: true, }, }, tsdocMessageReporting: { default: { - logLevel: 'warning' as ExtractorLogLevel.Warning, - addToApiReportFile: true, + logLevel: 'none' as ExtractorLogLevel.Warning, + // addToApiReportFile: true, }, }, }, From 70ac6d68c25d398435d0fb0f11d8f5067556598d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 22 Apr 2021 18:24:41 +0200 Subject: [PATCH 256/462] scripts/api-extractor: some more explanations Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- scripts/api-extractor.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 7bbf955f9a..7da9fac515 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -35,7 +35,13 @@ import { MarkdownDocumenter } from '@microsoft/api-documenter/lib/documenters/Ma const tmpDir = resolvePath(__dirname, '../node_modules/.cache/api-extractor'); /** - * Yup + * All of this monkey patching below is because MUI has these bare package.json file as a method + * for making TypeScript accept imports like `@material-ui/core/Button`, and improve tree-shaking + * by declaring them side effect free. + * + * The package.json lookup logic in api-extractor really doesn't like that though, as it enforces + * that the 'name' field exists in all package.json files that it discovers. This below is just + * making sure that we ignore those file package.json files instead of crashing. */ const { PackageJsonLookup, @@ -61,6 +67,7 @@ const DOCUMENTED_PACKAGES = [ 'packages/cli-common', 'packages/config', 'packages/config-loader', + // TODO(Rugvip): Enable these once `import * as ...` and `import()` PRs have landed, #1796 & #1916. // 'packages/core', // 'packages/core-api', 'packages/dev-utils', From 215b44de9c10a9b6d8f657ad42c91a15c3f41116 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 22 Apr 2021 18:29:22 +0200 Subject: [PATCH 257/462] scripts/api-extractor: fix comment Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- scripts/api-extractor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 7da9fac515..37dc4769fd 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -247,7 +247,7 @@ async function runApiExtraction({ } function isComponentMember(member: any) { - // React components are annotated with @components, and we want to skip those + // React components are annotated with @component, and we want to skip those return Boolean(member.docComment.match(/\n\s*\**\s*@component/m)); } From 9d3fb9a30aaeb8d9901ff76047a88b0eef722790 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 26 Apr 2021 20:51:12 +0200 Subject: [PATCH 258/462] scripts/api-extractor: sync API definitions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/search-common/api-report.md | 2 ++ packages/techdocs-common/api-report.md | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/search-common/api-report.md b/packages/search-common/api-report.md index 70522f4ee4..76bd937a1c 100644 --- a/packages/search-common/api-report.md +++ b/packages/search-common/api-report.md @@ -33,6 +33,8 @@ export interface SearchQuery { pageCursor: string; // (undocumented) term: string; + // (undocumented) + types?: string[]; } // @public (undocumented) diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index c26f62e981..a53fb9e681 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -138,6 +138,7 @@ export class Publisher { export interface PublisherBase { docsRouter(): express.Handler; fetchTechDocsMetadata(entityName: EntityName): Promise<TechDocsMetadata>; + getReadiness(): Promise<ReadinessResponse>; hasDocsBeenGenerated(entityName: Entity): Promise<boolean>; publish(request: PublishRequest): Promise<PublishResponse>; } From b74e3e1efc3739304e37435a58ea3f0f16478bfe Mon Sep 17 00:00:00 2001 From: Victor Perera <v-vperera@expediagroup.com> Date: Mon, 26 Apr 2021 18:53:11 -0500 Subject: [PATCH 259/462] Enable starred templates on scaffolder Signed-off-by: Victor Perera <v-vperera@expediagroup.com> --- .../FavouriteTemplate/FavouriteTemplate.tsx | 67 +++++++++++++++++++ .../ScaffolderPage/ScaffolderPage.tsx | 1 + .../components/TemplateCard/TemplateCard.tsx | 10 ++- 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx diff --git a/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx b/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx new file mode 100644 index 0000000000..99f6c21a1d --- /dev/null +++ b/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { ComponentProps } from 'react'; +import { useStarredEntities } from '@backstage/plugin-catalog-react'; +import { IconButton, makeStyles, Tooltip, withStyles } from '@material-ui/core'; +import StarBorder from '@material-ui/icons/StarBorder'; +import Star from '@material-ui/icons/Star'; +import { Entity } from '@backstage/catalog-model'; + +type Props = ComponentProps<typeof IconButton> & { entity: Entity }; + +const YellowStar = withStyles({ + root: { + color: '#f3ba37', + }, +})(Star); + +const useStyles = makeStyles(theme => ({ + starButton: { + position: 'absolute', + top: theme.spacing(0.5), + right: theme.spacing(0.5), + padding: '0.25rem', + }, +})); + +export const favouriteTemplateTooltip = (isStarred: boolean) => + isStarred ? 'Remove from favorites' : 'Add to favorites'; + +export const favouriteTemplateIcon = (isStarred: boolean) => + isStarred ? <YellowStar /> : <StarBorder style={{ color: 'white' }} />; + +/** + * IconButton for showing if a current entity is starred and adding/removing it from the favourite entities + * @param props MaterialUI IconButton props extended by required `entity` prop + */ +export const FavouriteTemplate = (props: Props) => { + const classes = useStyles(); + const { toggleStarredEntity, isStarredEntity } = useStarredEntities(); + const isStarred = isStarredEntity(props.entity); + return ( + <IconButton + color="inherit" + className={classes.starButton} + {...props} + onClick={() => toggleStarredEntity(props.entity)} + > + <Tooltip title={favouriteTemplateTooltip(isStarred)}> + {favouriteTemplateIcon(isStarred)} + </Tooltip> + </IconButton> + ); +}; diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index 68bf588d01..00b13853ec 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -61,6 +61,7 @@ const getTemplateCardProps = ( type: template.spec.type ?? '', description: template.metadata.description ?? '-', tags: (template.metadata?.tags as string[]) ?? [], + entityTemplate: template, }; }; diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index 2ba83fdaae..2e9cfe6470 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -28,8 +28,13 @@ import { import React from 'react'; import { generatePath } from 'react-router'; import { rootRouteRef } from '../../routes'; +import { Entity } from '@backstage/catalog-model'; +import { FavouriteTemplate } from '../FavouriteTemplate/FavouriteTemplate'; const useStyles = makeStyles({ + cardHeader: { + position: 'relative', + }, title: { backgroundImage: ({ backgroundImage }: any) => backgroundImage, }, @@ -48,6 +53,7 @@ export type TemplateCardProps = { title: string; type: string; name: string; + entityTemplate: Entity; }; export const TemplateCard = ({ @@ -56,6 +62,7 @@ export const TemplateCard = ({ title, type, name, + entityTemplate, }: TemplateCardProps) => { const backstageTheme = useTheme<BackstageTheme>(); const rootLink = useRouteRef(rootRouteRef); @@ -69,7 +76,8 @@ export const TemplateCard = ({ return ( <Card> - <CardMedia> + <CardMedia className={classes.cardHeader}> + <FavouriteTemplate entity={entityTemplate} /> <ItemCardHeader title={title} subtitle={type} From f6efa71ee7c7960bbc2b1a4b7e678f36b8076091 Mon Sep 17 00:00:00 2001 From: Victor Perera <v-vperera@expediagroup.com> Date: Mon, 26 Apr 2021 19:00:57 -0500 Subject: [PATCH 260/462] Adding Changeset Signed-off-by: Victor Perera <v-vperera@expediagroup.com> --- .changeset/long-ladybugs-promise.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/long-ladybugs-promise.md diff --git a/.changeset/long-ladybugs-promise.md b/.changeset/long-ladybugs-promise.md new file mode 100644 index 0000000000..7d683650c3 --- /dev/null +++ b/.changeset/long-ladybugs-promise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Enable starred templates on Scaffolder frontend From 111d30a8cb6fb91142d267ccc2e6eeb033915b2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Apr 2021 04:20:03 +0000 Subject: [PATCH 261/462] chore(deps-dev): bump @types/express-serve-static-core Bumps [@types/express-serve-static-core](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express-serve-static-core) from 4.17.18 to 4.17.19. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express-serve-static-core) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index f2c2bee93c..ce39d4425e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5875,7 +5875,16 @@ resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@4.17.18", "@types/express-serve-static-core@^4.17.5": +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.5": + version "4.17.19" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d" + integrity sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express-serve-static-core@4.17.18": version "4.17.18" resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40" integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== From 4c42ecca2d106c80f358655b7e0863be463049c6 Mon Sep 17 00:00:00 2001 From: Andrew Shirley <andrew@als-bi.com> Date: Mon, 19 Apr 2021 16:31:30 +0100 Subject: [PATCH 262/462] Wrap EmptyState in a Card This prevents it overflowing onto subsequent content Signed-off-by: Andrew Shirley <andrew@als-bi.com> --- .changeset/empty-lizards-doubt.md | 5 +++ .../Cards/RecentWorkflowRunsCard.tsx | 43 ++++++++++++------- 2 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 .changeset/empty-lizards-doubt.md diff --git a/.changeset/empty-lizards-doubt.md b/.changeset/empty-lizards-doubt.md new file mode 100644 index 0000000000..cfe1e128fc --- /dev/null +++ b/.changeset/empty-lizards-doubt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-github-actions': patch +--- + +Wrap EmptyState in Card diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx index 1126c2a2a0..a3605abb7e 100644 --- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx +++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx @@ -25,7 +25,14 @@ import { } from '@backstage/core'; import { readGitHubIntegrationConfigs } from '@backstage/integration'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { Button, Link } from '@material-ui/core'; +import { + Button, + Card, + CardContent, + CardHeader, + Divider, + Link, +} from '@material-ui/core'; import React, { useEffect } from 'react'; import { generatePath, Link as RouterLink } from 'react-router-dom'; import { GITHUB_ACTIONS_ANNOTATION } from '../useProjectName'; @@ -75,20 +82,26 @@ export const RecentWorkflowRunsCard = ({ const githubHost = hostname || 'github.com'; return !runs.length ? ( - <EmptyState - missing="data" - title="No Workflow Data" - description="This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow." - action={ - <Button - variant="contained" - color="primary" - href={`https://${githubHost}/${owner}/${repo}/actions/new`} - > - Create new Workflow - </Button> - } - /> + <Card> + <CardHeader title="Recent Workflow Runs" /> + <Divider /> + <CardContent> + <EmptyState + missing="data" + title="No Workflow Data" + description="This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow." + action={ + <Button + variant="contained" + color="primary" + href={`https://${githubHost}/${owner}/${repo}/actions/new`} + > + Create new Workflow + </Button> + } + /> + </CardContent> + </Card> ) : ( <InfoCard title="Recent Workflow Runs" From 50701f32cb87d6582135c21b9f0a04dcb3650e97 Mon Sep 17 00:00:00 2001 From: Andrew Shirley <andrew@als-bi.com> Date: Mon, 26 Apr 2021 17:31:43 +0100 Subject: [PATCH 263/462] Use InfoCard not Card Signed-off-by: Andrew Shirley <andrew@als-bi.com> --- .../Cards/RecentWorkflowRunsCard.tsx | 45 +++++++------------ 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx index a3605abb7e..97428088fc 100644 --- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx +++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx @@ -25,14 +25,7 @@ import { } from '@backstage/core'; import { readGitHubIntegrationConfigs } from '@backstage/integration'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { - Button, - Card, - CardContent, - CardHeader, - Divider, - Link, -} from '@material-ui/core'; +import { Button, Link } from '@material-ui/core'; import React, { useEffect } from 'react'; import { generatePath, Link as RouterLink } from 'react-router-dom'; import { GITHUB_ACTIONS_ANNOTATION } from '../useProjectName'; @@ -82,26 +75,22 @@ export const RecentWorkflowRunsCard = ({ const githubHost = hostname || 'github.com'; return !runs.length ? ( - <Card> - <CardHeader title="Recent Workflow Runs" /> - <Divider /> - <CardContent> - <EmptyState - missing="data" - title="No Workflow Data" - description="This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow." - action={ - <Button - variant="contained" - color="primary" - href={`https://${githubHost}/${owner}/${repo}/actions/new`} - > - Create new Workflow - </Button> - } - /> - </CardContent> - </Card> + <InfoCard title="Recent Workflow Runs" variant={variant}> + <EmptyState + missing="data" + title="No Workflow Data" + description="This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow." + action={ + <Button + variant="contained" + color="primary" + href={`https://${githubHost}/${owner}/${repo}/actions/new`} + > + Create new Workflow + </Button> + } + /> + </InfoCard> ) : ( <InfoCard title="Recent Workflow Runs" From 16a4ffb871f1643cd1f1eef964488f2b318da046 Mon Sep 17 00:00:00 2001 From: Andrew Shirley <andrew@als-bi.com> Date: Mon, 26 Apr 2021 18:04:06 +0100 Subject: [PATCH 264/462] Eliminate EmptyState usage Signed-off-by: Andrew Shirley <andrew@als-bi.com> --- .../Cards/RecentWorkflowRunsCard.tsx | 89 +++++++++---------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx index 97428088fc..f0366e5590 100644 --- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx +++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx @@ -16,21 +16,21 @@ import { Entity } from '@backstage/catalog-model'; import { configApiRef, - EmptyState, errorApiRef, InfoCard, InfoCardVariants, + Link, Table, useApi, } from '@backstage/core'; import { readGitHubIntegrationConfigs } from '@backstage/integration'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { Button, Link } from '@material-ui/core'; import React, { useEffect } from 'react'; import { generatePath, Link as RouterLink } from 'react-router-dom'; import { GITHUB_ACTIONS_ANNOTATION } from '../useProjectName'; import { useWorkflowRuns } from '../useWorkflowRuns'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; +import { Typography } from '@material-ui/core'; const firstLine = (message: string): string => message.split('\n')[0]; @@ -74,56 +74,53 @@ export const RecentWorkflowRunsCard = ({ const githubHost = hostname || 'github.com'; - return !runs.length ? ( - <InfoCard title="Recent Workflow Runs" variant={variant}> - <EmptyState - missing="data" - title="No Workflow Data" - description="This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow." - action={ - <Button - variant="contained" - color="primary" - href={`https://${githubHost}/${owner}/${repo}/actions/new`} - > - Create new Workflow - </Button> - } - /> - </InfoCard> - ) : ( + return ( <InfoCard title="Recent Workflow Runs" subheader={branch ? `Branch: ${branch}` : 'All Branches'} noPadding variant={variant} > - <Table - isLoading={loading} - options={{ - search: false, - paging: false, - padding: dense ? 'dense' : 'default', - toolbar: false, - }} - columns={[ - { - title: 'Commit Message', - field: 'message', - render: data => ( - <Link - component={RouterLink} - to={generatePath('./ci-cd/:id', { id: data.id! })} - > - {firstLine(data.message)} - </Link> - ), - }, - { title: 'Branch', field: 'source.branchName' }, - { title: 'Status', field: 'status', render: WorkflowRunStatus }, - ]} - data={runs} - /> + {!runs.length ? ( + <div style={{ textAlign: 'center' }}> + <Typography variant="body1"> + This component has GitHub Actions enabled, but no workflows were + found. + </Typography> + <Typography variant="body2"> + <Link to={`https://${githubHost}/${owner}/${repo}/actions/new`}> + Create a new workflow + </Link> + </Typography> + </div> + ) : ( + <Table + isLoading={loading} + options={{ + search: false, + paging: false, + padding: dense ? 'dense' : 'default', + toolbar: false, + }} + columns={[ + { + title: 'Commit Message', + field: 'message', + render: data => ( + <Link + component={RouterLink} + to={generatePath('./ci-cd/:id', { id: data.id! })} + > + {firstLine(data.message)} + </Link> + ), + }, + { title: 'Branch', field: 'source.branchName' }, + { title: 'Status', field: 'status', render: WorkflowRunStatus }, + ]} + data={runs} + /> + )} </InfoCard> ); }; From 266e46d3c3a4f73f5c27f50c4275be254b4ed9e9 Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Tue, 27 Apr 2021 11:07:08 +0200 Subject: [PATCH 265/462] switch from map to forEach Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- plugins/search-backend-node/src/IndexBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/search-backend-node/src/IndexBuilder.ts b/plugins/search-backend-node/src/IndexBuilder.ts index 768dee5b67..71d374e704 100644 --- a/plugins/search-backend-node/src/IndexBuilder.ts +++ b/plugins/search-backend-node/src/IndexBuilder.ts @@ -98,7 +98,7 @@ export class IndexBuilder { async build(): Promise<{ scheduler: Scheduler }> { const scheduler = new Scheduler({ logger: this.logger }); - Object.keys(this.collators).map(type => { + Object.keys(this.collators).forEach(type => { scheduler.addToSchedule(async () => { // Collate, Decorate, Index. const decorators: DocumentDecorator[] = ( From 4906a4c2210c38e1364bf69c882ab90df2fc7f3c Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Tue, 27 Apr 2021 11:07:55 +0200 Subject: [PATCH 266/462] rename test file to be more specific to IndexBuilder Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- .../src/{index.test.ts => IndexBuilder.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/search-backend-node/src/{index.test.ts => IndexBuilder.test.ts} (100%) diff --git a/plugins/search-backend-node/src/index.test.ts b/plugins/search-backend-node/src/IndexBuilder.test.ts similarity index 100% rename from plugins/search-backend-node/src/index.test.ts rename to plugins/search-backend-node/src/IndexBuilder.test.ts From 6c46febf6326a8a119529e2b37f2029178fa7a3e Mon Sep 17 00:00:00 2001 From: Emma Indal <emma.indahl@gmail.com> Date: Tue, 27 Apr 2021 11:08:37 +0200 Subject: [PATCH 267/462] Add tests for Scheduler Signed-off-by: Emma Indal <emma.indahl@gmail.com> --- .../search-backend-node/src/Scheduler.test.ts | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 plugins/search-backend-node/src/Scheduler.test.ts diff --git a/plugins/search-backend-node/src/Scheduler.test.ts b/plugins/search-backend-node/src/Scheduler.test.ts new file mode 100644 index 0000000000..43fdb7ea92 --- /dev/null +++ b/plugins/search-backend-node/src/Scheduler.test.ts @@ -0,0 +1,77 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { Scheduler } from './index'; + +describe('Scheduler', () => { + let testScheduler: Scheduler; + + beforeEach(() => { + const logger = getVoidLogger(); + testScheduler = new Scheduler({ + logger, + }); + }); + + describe('addToSchedule', () => { + it('should not add a task and interval to schedule, if already started', async () => { + jest.useFakeTimers(); + const mockTask1 = jest.fn(); + const mockTask2 = jest.fn(); + + // Add a task and interval to schedule + testScheduler.addToSchedule(mockTask1, 2); + + // Starts scheduling process + testScheduler.start(); + + // Throws Error if task and interval is added to a already started schedule + expect(() => testScheduler.addToSchedule(mockTask2, 2)).toThrowError(); + + jest.runOnlyPendingTimers(); + expect(mockTask1).toHaveBeenCalled(); + expect(mockTask2).not.toHaveBeenCalled(); + }); + + it('should be possible to add a task and interval to schedule, if already started, but stopped in between', async () => { + jest.useFakeTimers(); + const mockTask1 = jest.fn(); + const mockTask2 = jest.fn(); + + // Add a task and interval to schedule + testScheduler.addToSchedule(mockTask1, 2); + + // Starts scheduling process + testScheduler.start(); + + // Stop scheduling process + testScheduler.stop(); + + // Should't throw error, as it is stopped. + expect(() => + testScheduler.addToSchedule(mockTask2, 4), + ).not.toThrowError(); + + // Starts scheduling process + testScheduler.start(); + + jest.runOnlyPendingTimers(); + expect(mockTask1).toHaveBeenCalled(); + expect(mockTask2).toHaveBeenCalled(); + }); + }); +}); From 1a142ae8a42fb018e9c746f853e3d5c460dc544d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 26 Apr 2021 21:36:50 +0200 Subject: [PATCH 268/462] catalog: switch out time-based greeting for plain title Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/witty-lies-shave.md | 5 +++++ .../src/components/CatalogPage/CatalogLayout.tsx | 13 ++++--------- .../src}/utils/locales/goodAfternoon.locales.json | 0 .../src}/utils/locales/goodEvening.locales.json | 0 .../src}/utils/locales/goodMorning.locales.json | 0 .../CatalogPage => welcome/src}/utils/timeUtil.js | 0 .../src}/utils/timeUtil.test.js | 0 7 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 .changeset/witty-lies-shave.md rename plugins/{catalog/src/components/CatalogPage => welcome/src}/utils/locales/goodAfternoon.locales.json (100%) rename plugins/{catalog/src/components/CatalogPage => welcome/src}/utils/locales/goodEvening.locales.json (100%) rename plugins/{catalog/src/components/CatalogPage => welcome/src}/utils/locales/goodMorning.locales.json (100%) rename plugins/{catalog/src/components/CatalogPage => welcome/src}/utils/timeUtil.js (100%) rename plugins/{catalog/src/components/CatalogPage => welcome/src}/utils/timeUtil.test.js (100%) diff --git a/.changeset/witty-lies-shave.md b/.changeset/witty-lies-shave.md new file mode 100644 index 0000000000..4c0aeef80a --- /dev/null +++ b/.changeset/witty-lies-shave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Switch out the time-based personal greeting for a plain title on the catalog index page. diff --git a/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx b/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx index 298aeacfec..c038f3f08c 100644 --- a/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx +++ b/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx @@ -18,29 +18,24 @@ import { configApiRef, Header, HomepageTimer, - identityApiRef, Page, useApi, } from '@backstage/core'; import React from 'react'; -import { getTimeBasedGreeting } from './utils/timeUtil'; type Props = { children?: React.ReactNode; }; const CatalogLayout = ({ children }: Props) => { - const greeting = getTimeBasedGreeting(); - const profile = useApi(identityApiRef).getProfile(); - const userId = useApi(identityApiRef).getUserId(); - const orgName = useApi(configApiRef).getOptionalString('organization.name'); + const orgName = + useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; return ( <Page themeId="home"> <Header - title={`${greeting.greeting}, ${profile.displayName || userId}!`} - subtitle={`${orgName || 'Backstage'} Service Catalog`} - tooltip={greeting.language} + title={`${orgName} Catalog`} + subtitle={`Index of software components in ${orgName}`} pageTitleOverride="Home" > <HomepageTimer /> diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json b/plugins/welcome/src/utils/locales/goodAfternoon.locales.json similarity index 100% rename from plugins/catalog/src/components/CatalogPage/utils/locales/goodAfternoon.locales.json rename to plugins/welcome/src/utils/locales/goodAfternoon.locales.json diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json b/plugins/welcome/src/utils/locales/goodEvening.locales.json similarity index 100% rename from plugins/catalog/src/components/CatalogPage/utils/locales/goodEvening.locales.json rename to plugins/welcome/src/utils/locales/goodEvening.locales.json diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json b/plugins/welcome/src/utils/locales/goodMorning.locales.json similarity index 100% rename from plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json rename to plugins/welcome/src/utils/locales/goodMorning.locales.json diff --git a/plugins/catalog/src/components/CatalogPage/utils/timeUtil.js b/plugins/welcome/src/utils/timeUtil.js similarity index 100% rename from plugins/catalog/src/components/CatalogPage/utils/timeUtil.js rename to plugins/welcome/src/utils/timeUtil.js diff --git a/plugins/catalog/src/components/CatalogPage/utils/timeUtil.test.js b/plugins/welcome/src/utils/timeUtil.test.js similarity index 100% rename from plugins/catalog/src/components/CatalogPage/utils/timeUtil.test.js rename to plugins/welcome/src/utils/timeUtil.test.js From 8b43d5f8a231ba58be5cbbad0467834c13e23f6d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 26 Apr 2021 21:45:51 +0200 Subject: [PATCH 269/462] catalog: remove home page clocks Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/witty-lies-shave.md | 2 +- .../src/components/CatalogPage/CatalogLayout.tsx | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.changeset/witty-lies-shave.md b/.changeset/witty-lies-shave.md index 4c0aeef80a..68fd4b1137 100644 --- a/.changeset/witty-lies-shave.md +++ b/.changeset/witty-lies-shave.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog': patch --- -Switch out the time-based personal greeting for a plain title on the catalog index page. +Switch out the time-based personal greeting for a plain title on the catalog index page, and remove the clocks for different timezones. diff --git a/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx b/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx index c038f3f08c..e762efdee8 100644 --- a/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx +++ b/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx @@ -14,13 +14,7 @@ * limitations under the License. */ -import { - configApiRef, - Header, - HomepageTimer, - Page, - useApi, -} from '@backstage/core'; +import { configApiRef, Header, Page, useApi } from '@backstage/core'; import React from 'react'; type Props = { @@ -37,9 +31,7 @@ const CatalogLayout = ({ children }: Props) => { title={`${orgName} Catalog`} subtitle={`Index of software components in ${orgName}`} pageTitleOverride="Home" - > - <HomepageTimer /> - </Header> + /> {children} </Page> ); From f2a5ed93b68927475fbb6cb57c129f113e0d9a40 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 27 Apr 2021 12:25:28 +0200 Subject: [PATCH 270/462] catalog: tweak index page subtitle Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx b/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx index e762efdee8..a57b223afe 100644 --- a/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx +++ b/plugins/catalog/src/components/CatalogPage/CatalogLayout.tsx @@ -29,7 +29,7 @@ const CatalogLayout = ({ children }: Props) => { <Page themeId="home"> <Header title={`${orgName} Catalog`} - subtitle={`Index of software components in ${orgName}`} + subtitle={`Catalog of software components at ${orgName}`} pageTitleOverride="Home" /> {children} From 4bfff07eaec3b7255bc56c48acd0cf8b2210def9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 27 Apr 2021 12:27:06 +0200 Subject: [PATCH 271/462] e2e-test: update to search for new catalog index page title Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/e2e-test/src/commands/run.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index c055bcd21e..ebf4e6c835 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -335,7 +335,7 @@ async function testAppServe(pluginName: string, appDir: string) { try { const browser = new Browser(); - await waitForPageWithText(browser, '/', 'My Company Service Catalog'); + await waitForPageWithText(browser, '/', 'My Company Catalog'); await waitForPageWithText( browser, `/${pluginName}`, From 73f3f5d78d2388576c25b462a181fb3ddf2767c7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 27 Apr 2021 12:29:53 +0200 Subject: [PATCH 272/462] create-app: update app template to check for new catalog index page title Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/little-trees-fold.md | 5 +++++ .../default-app/packages/app/cypress/integration/app.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/little-trees-fold.md diff --git a/.changeset/little-trees-fold.md b/.changeset/little-trees-fold.md new file mode 100644 index 0000000000..4963dd5aa1 --- /dev/null +++ b/.changeset/little-trees-fold.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Updates the end to end test in the app to match the new catalog index page title. To apply this change to an existing app, update `packages/app/cypress/integration/app.js` to search for `"My Company Catalog"` instead of `"My Company Service Catalog"`. diff --git a/packages/create-app/templates/default-app/packages/app/cypress/integration/app.js b/packages/create-app/templates/default-app/packages/app/cypress/integration/app.js index efcd5b8d93..43fb2e32de 100644 --- a/packages/create-app/templates/default-app/packages/app/cypress/integration/app.js +++ b/packages/create-app/templates/default-app/packages/app/cypress/integration/app.js @@ -1,6 +1,6 @@ describe('App', () => { it('should render the catalog', () => { cy.visit('/'); - cy.contains('My Company Service Catalog'); + cy.contains('My Company Catalog'); }); }); From 6c38f5e92031b5574e20d8da28ffeedd89608177 Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Tue, 27 Apr 2021 10:55:57 +0200 Subject: [PATCH 273/462] tests(proxy-backend): align tests with default backend configuration The pathPrefix is not suffixed with `/` by default as noted at https://github.com/backstage/backstage/blob/df897a6126d1641d111b015c527cc8d40c47bd06/packages/backend-common/src/discovery/types.ts#L47 and seen in the implementation at https://github.com/backstage/backstage/blob/df897a6126d1641d111b015c527cc8d40c47bd06/packages/backend-common/src/discovery/SingleHostDiscovery.ts#L81. Currently the tests work in the opposite way - the pathPrefix is suffixed by / whereas the routes are **not** prefixed by /. This commit brings the tests in line with the default configuration prior to any further work. Signed-off-by: Brian Fox <brianhfox@gmail.com> --- .../proxy-backend/src/service/router.test.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts index 6c47043602..3a0a25f164 100644 --- a/plugins/proxy-backend/src/service/router.test.ts +++ b/plugins/proxy-backend/src/service/router.test.ts @@ -60,7 +60,7 @@ describe('buildMiddleware', () => { }); it('accepts strings', async () => { - buildMiddleware('/api/', logger, 'test', 'http://mocked'); + buildMiddleware('/proxy', logger, '/test', 'http://mocked'); expect(createProxyMiddleware).toHaveBeenCalledTimes(1); @@ -74,13 +74,13 @@ describe('buildMiddleware', () => { expect(filter('', { method: 'PATCH', headers: {} })).toBe(true); expect(filter('', { method: 'DELETE', headers: {} })).toBe(true); - expect(fullConfig.pathRewrite).toEqual({ '^/api/test/': '/' }); + expect(fullConfig.pathRewrite).toEqual({ '^/proxy/test/': '/' }); expect(fullConfig.changeOrigin).toBe(true); expect(fullConfig.logProvider!(logger)).toBe(logger); }); it('limits allowedMethods', async () => { - buildMiddleware('/api/', logger, 'test', { + buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', allowedMethods: ['GET', 'DELETE'], }); @@ -97,13 +97,13 @@ describe('buildMiddleware', () => { expect(filter('', { method: 'PATCH', headers: {} })).toBe(false); expect(filter('', { method: 'DELETE', headers: {} })).toBe(true); - expect(fullConfig.pathRewrite).toEqual({ '^/api/test/': '/' }); + expect(fullConfig.pathRewrite).toEqual({ '^/proxy/test/': '/' }); expect(fullConfig.changeOrigin).toBe(true); expect(fullConfig.logProvider!(logger)).toBe(logger); }); it('permits default headers', async () => { - buildMiddleware('/api/', logger, 'test', { + buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', }); @@ -143,7 +143,7 @@ describe('buildMiddleware', () => { }); it('permits default and configured headers', async () => { - buildMiddleware('/api/', logger, 'test', { + buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', headers: { Authorization: 'my-token', @@ -176,7 +176,7 @@ describe('buildMiddleware', () => { }); it('permits configured headers', async () => { - buildMiddleware('/api/', logger, 'test', { + buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', allowedHeaders: ['authorization', 'cookie'], }); @@ -208,7 +208,7 @@ describe('buildMiddleware', () => { }); it('responds default headers', async () => { - buildMiddleware('/api/', logger, 'test', { + buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', }); @@ -251,7 +251,7 @@ describe('buildMiddleware', () => { }); it('responds configured headers', async () => { - buildMiddleware('/api/', logger, 'test', { + buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', allowedHeaders: ['set-cookie'], }); @@ -282,10 +282,10 @@ describe('buildMiddleware', () => { it('rejects malformed target URLs', async () => { expect(() => - buildMiddleware('/api/', logger, 'test', 'backstage.io'), + buildMiddleware('/proxy', logger, '/test', 'backstage.io'), ).toThrowError(/Proxy target is not a valid URL/); expect(() => - buildMiddleware('/api/', logger, 'test', { target: 'backstage.io' }), + buildMiddleware('/proxy', logger, '/test', { target: 'backstage.io' }), ).toThrowError(/Proxy target is not a valid URL/); }); }); From cdb3426e56f49dd5dffba3c35eea383a416b1bf1 Mon Sep 17 00:00:00 2001 From: Brian Fox <brianhfox@gmail.com> Date: Tue, 27 Apr 2021 12:38:31 +0200 Subject: [PATCH 274/462] fix(proxy-backend): prefix routes with `/` if not present in config This commit ensures that the default `pathRewrite` configuration for a proxy element is more resilient to the combination of whether: - `route` is prefixed with `/` - `pathPrefix` on the plugin is suffixed with `/` (which at present it will never be - see comments). Signed-off-by: Brian Fox <brianhfox@gmail.com> --- .changeset/thick-cobras-switch.md | 5 +++ docs/plugins/proxying.md | 11 ++--- .../proxy-backend/src/service/router.test.ts | 42 ++++++++++++++++++- plugins/proxy-backend/src/service/router.ts | 16 ++++++- 4 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 .changeset/thick-cobras-switch.md diff --git a/.changeset/thick-cobras-switch.md b/.changeset/thick-cobras-switch.md new file mode 100644 index 0000000000..002c724421 --- /dev/null +++ b/.changeset/thick-cobras-switch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-proxy-backend': patch +--- + +Prefix proxy routes with `/` if not present in configuration diff --git a/docs/plugins/proxying.md b/docs/plugins/proxying.md index 50c56af7a6..3e20e37cad 100644 --- a/docs/plugins/proxying.md +++ b/docs/plugins/proxying.md @@ -36,7 +36,7 @@ Example: ```yaml # in app-config.yaml proxy: - '/simple-example': http://simple.example.com:8080 + simple-example: http://simple.example.com:8080 '/larger-example/v1': target: http://larger.example.com:8080/svc.v1 headers: @@ -46,10 +46,11 @@ proxy: ``` Each key under the proxy configuration entry is a route to match, below the -prefix that the proxy plugin is mounted on. It must start with a slash. For -example, if the backend mounts the proxy plugin as `/proxy`, the above -configuration will lead to the proxy acting on backend requests to -`/api/proxy/simple-example/...` and `/api/proxy/larger-example/v1/...`. +prefix that the proxy plugin is mounted on. If it does not start with a slash, +one will be prefixed automatically. For example, if the backend mounts the proxy +plugin as `/proxy`, the above configuration will lead to the proxy acting on +backend requests to `/api/proxy/simple-example/...` and +`/api/proxy/larger-example/v1/...`. The value inside each route is either a simple URL string, or an object on the format accepted by diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts index 3a0a25f164..571de96ac4 100644 --- a/plugins/proxy-backend/src/service/router.test.ts +++ b/plugins/proxy-backend/src/service/router.test.ts @@ -59,7 +59,7 @@ describe('buildMiddleware', () => { mockCreateProxyMiddleware.mockClear(); }); - it('accepts strings', async () => { + it('accepts strings prefixed by /', async () => { buildMiddleware('/proxy', logger, '/test', 'http://mocked'); expect(createProxyMiddleware).toHaveBeenCalledTimes(1); @@ -79,6 +79,46 @@ describe('buildMiddleware', () => { expect(fullConfig.logProvider!(logger)).toBe(logger); }); + it('accepts routes not prefixed with / when path is not suffixed with /', async () => { + buildMiddleware('/proxy', logger, 'test', 'http://mocked'); + + expect(createProxyMiddleware).toHaveBeenCalledTimes(1); + + const [filter, fullConfig] = mockCreateProxyMiddleware.mock.calls[0] as [ + (pathname: string, req: Partial<http.IncomingMessage>) => boolean, + ProxyMiddlewareConfig, + ]; + expect(filter('', { method: 'GET', headers: {} })).toBe(true); + expect(filter('', { method: 'POST', headers: {} })).toBe(true); + expect(filter('', { method: 'PUT', headers: {} })).toBe(true); + expect(filter('', { method: 'PATCH', headers: {} })).toBe(true); + expect(filter('', { method: 'DELETE', headers: {} })).toBe(true); + + expect(fullConfig.pathRewrite).toEqual({ '^/proxy/test/': '/' }); + expect(fullConfig.changeOrigin).toBe(true); + expect(fullConfig.logProvider!(logger)).toBe(logger); + }); + + it('accepts routes prefixed with / when path is suffixed with /', async () => { + buildMiddleware('/proxy/', logger, '/test', 'http://mocked'); + + expect(createProxyMiddleware).toHaveBeenCalledTimes(1); + + const [filter, fullConfig] = mockCreateProxyMiddleware.mock.calls[0] as [ + (pathname: string, req: Partial<http.IncomingMessage>) => boolean, + ProxyMiddlewareConfig, + ]; + expect(filter('', { method: 'GET', headers: {} })).toBe(true); + expect(filter('', { method: 'POST', headers: {} })).toBe(true); + expect(filter('', { method: 'PUT', headers: {} })).toBe(true); + expect(filter('', { method: 'PATCH', headers: {} })).toBe(true); + expect(filter('', { method: 'DELETE', headers: {} })).toBe(true); + + expect(fullConfig.pathRewrite).toEqual({ '^/proxy/test/': '/' }); + expect(fullConfig.changeOrigin).toBe(true); + expect(fullConfig.logProvider!(logger)).toBe(logger); + }); + it('limits allowedMethods', async () => { buildMiddleware('/proxy', logger, '/test', { target: 'http://mocked', diff --git a/plugins/proxy-backend/src/service/router.ts b/plugins/proxy-backend/src/service/router.ts index 5c306de966..71ed82c23b 100644 --- a/plugins/proxy-backend/src/service/router.ts +++ b/plugins/proxy-backend/src/service/router.ts @@ -77,10 +77,24 @@ export function buildMiddleware( `Proxy target is not a valid URL: ${fullConfig.target ?? ''}`, ); } + // Default is to do a path rewrite that strips out the proxy's path prefix // and the rest of the route. if (fullConfig.pathRewrite === undefined) { - const routeWithSlash = route.endsWith('/') ? route : `${route}/`; + let routeWithSlash = route.endsWith('/') ? route : `${route}/`; + + if (!pathPrefix.endsWith('/') && !routeWithSlash.startsWith('/')) { + // Need to insert a / between pathPrefix and routeWithSlash + routeWithSlash = `/${routeWithSlash}`; + } else if (pathPrefix.endsWith('/') && routeWithSlash.startsWith('/')) { + // Never expect this to happen at this point in time as + // pathPrefix is set using `getExternalBaseUrl` which "Returns the + // external HTTP base backend URL for a given plugin, + // **without a trailing slash.**". But in case this changes in future, we + // need to drop a / on either pathPrefix or routeWithSlash + routeWithSlash = routeWithSlash.substring(1); + } + fullConfig.pathRewrite = { [`^${pathPrefix}${routeWithSlash}`]: '/', }; From 8ce7d6e8f81d621c66e069c64cfe67f4e42fed3c Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 14:16:49 +0200 Subject: [PATCH 275/462] catalog-backend: Add ConfigLocationProvider tests Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/ConfigLocationProvider.test.ts | 67 +++++++++++++++++++ .../src/next/ConfigLocationProvider.ts | 14 ++-- 2 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts b/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts new file mode 100644 index 0000000000..9aaba13c48 --- /dev/null +++ b/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigLocationProvider } from './ConfigLocationProvider'; +import { EntityProviderConnection } from './types'; +import { ConfigReader } from '@backstage/config'; +import { resolvePackagePath } from '@backstage/backend-common'; +import path from 'path'; + +describe('Config Location Provider', () => { + it('should apply mutation with the correct paths in the config', async () => { + const mockConfig = new ConfigReader({ + catalog: { + locations: [ + { type: 'file', target: './lols.yaml' }, + { type: 'url', target: 'https://github.com/backstage/backstage' }, + ], + }, + }); + + const mockConnection = ({ + applyMutation: jest.fn(), + } as unknown) as EntityProviderConnection; + const locationProvider = new ConfigLocationProvider(mockConfig); + + await locationProvider.connect(mockConnection); + + expect(mockConnection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: path.join( + resolvePackagePath('@backstage/plugin-catalog-backend'), + './lols.yaml', + ), + type: 'file', + }, + }), + ]), + }); + expect(mockConnection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: 'https://github.com/backstage/backstage', + type: 'url', + }, + }), + ]), + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts index 5b93fcfd98..8a65487df1 100644 --- a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts +++ b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts @@ -34,12 +34,14 @@ export class ConfigLocationProvider implements EntityProvider { const locationConfigs = this.config.getOptionalConfigArray('catalog.locations') ?? []; - const entities = locationConfigs.map(location => - locationSpecToLocationEntity({ - type: location.getString('type'), - target: path.resolve(location.getString('target')), - }), - ); + const entities = locationConfigs.map(location => { + const type = location.getString('type'); + const target = location.getString('target'); + return locationSpecToLocationEntity({ + type, + target: type === 'file' ? path.resolve(target) : target, + }); + }); await this.connection.applyMutation({ type: 'full', From 07a7806c31847c459b3aaea8bad7d76bfe952c94 Mon Sep 17 00:00:00 2001 From: Anastasia Rodionova <argali96@gmail.com> Date: Thu, 22 Apr 2021 16:20:03 +0200 Subject: [PATCH 276/462] Filter returned fields in apis explorer Signed-off-by: Anastasia Rodionova <argali96@gmail.com> --- .changeset/kind-suns-melt.md | 5 +++++ .../components/ApiExplorerPage/ApiExplorerPage.tsx | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .changeset/kind-suns-melt.md diff --git a/.changeset/kind-suns-melt.md b/.changeset/kind-suns-melt.md new file mode 100644 index 0000000000..7cbec28fea --- /dev/null +++ b/.changeset/kind-suns-melt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Added fields filtering in get API entities to avoid the requesting of unused data diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx index 83d0bfc2ba..1ed47811ef 100644 --- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx +++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx @@ -34,7 +34,19 @@ export const ApiExplorerPage = () => { const createComponentLink = useRouteRef(createComponentRouteRef); const catalogApi = useApi(catalogApiRef); const { loading, error, value: catalogResponse } = useAsync(() => { - return catalogApi.getEntities({ filter: { kind: 'API' } }); + return catalogApi.getEntities({ + filter: { kind: 'API' }, + fields: [ + 'apiVersion', + 'kind', + 'metadata', + 'relations', + 'spec.lifecycle', + 'spec.owner', + 'spec.type', + 'spec.system', + ], + }); }, [catalogApi]); return ( From 74f74ccbdbb9932cbda2a88eb81a371bbb57a26f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 27 Apr 2021 17:16:16 +0200 Subject: [PATCH 277/462] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Co-authored-by: Fredrik Adelöw <freben@gmail.com> --- docs/features/techdocs/getting-started.md | 2 +- docs/overview/architecture-overview.md | 6 +++--- plugins/api-docs/README.md | 2 +- plugins/catalog-import/README.md | 2 +- plugins/rollbar/README.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index 934e91bd26..223b276d68 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -29,7 +29,7 @@ yarn add @backstage/plugin-techdocs Once the package has been installed, you need to import the plugin in your app. -In `packages/app/src/App.tsx`, import TechDocsPage and add the following to +In `packages/app/src/App.tsx`, import `TechDocsPage` and add the following to `FlatRoutes`: ```tsx diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index fab5698014..44bc1293f0 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -95,10 +95,10 @@ any route we want for the page, as long as it doesn't collide with the routes that we choose for the other plugins in the app. These components that are exported from plugins are referred to as "Plugin -Extension Components", or "Extensions Components". They are regular React +Extension Components", or "Extension Components". They are regular React components, but in addition to being able to be rendered by React, they also -contain various pieces of metadata that is used to write together the entire -app. Extensions components are created using `create*Extension` methods, which +contain various pieces of metadata that is used to wire together the entire +app. Extension components are created using `create*Extension` methods, which you can read more about in the [composability documentation](../plugins/composability.md). diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index 3d44eaaa29..dac4b6ff4d 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -33,7 +33,7 @@ To link that a component provides or consumes an API, see the [`providesApis`](h yarn add @backstage/plugin-api-docs ``` -2. Add the `ApiExplorerPage` extensions to the app: +2. Add the `ApiExplorerPage` extension to the app: ```tsx // packages/app/src/App.tsx diff --git a/plugins/catalog-import/README.md b/plugins/catalog-import/README.md index 90190e4356..5e773ad288 100644 --- a/plugins/catalog-import/README.md +++ b/plugins/catalog-import/README.md @@ -23,7 +23,7 @@ Some features are not yet available for all supported Git providers. yarn add @backstage/plugin-catalog-import ``` -2. Add the `CatalogImportPage` extensions to the app: +2. Add the `CatalogImportPage` extension to the app: ```tsx // packages/app/src/App.tsx diff --git a/plugins/rollbar/README.md b/plugins/rollbar/README.md index 584bd7d6bc..3a33fe223c 100644 --- a/plugins/rollbar/README.md +++ b/plugins/rollbar/README.md @@ -30,7 +30,7 @@ const serviceEntityPage = ( ); ``` -4. Setup the `app.config.yaml` and account token environment variable +4. Setup the `app-config.yaml` and account token environment variable ```yaml # app.config.yaml From 6b580d979b4d5aed9f9b167436c8b3a448af58b0 Mon Sep 17 00:00:00 2001 From: jrusso1020 <jrusso@brex.com> Date: Tue, 27 Apr 2021 09:16:41 -0600 Subject: [PATCH 278/462] addres feedback Signed-off-by: jrusso1020 <jrusso@brex.com> --- docs/features/software-catalog/descriptor-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 2506e2e9c1..0dba11fd62 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -44,7 +44,7 @@ metadata: name: artist-web description: The place to be, for great artists labels: - backstage.io/custom: ValueStuff + example.com/custom: custom_label_value annotations: example.com/service-discovery: artistweb circleci.com/project-slug: github/example-org/artist-website From d6ead26753337e84150e4aa7dececfbd4abbd086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Fri, 23 Apr 2021 16:50:06 +0200 Subject: [PATCH 279/462] Update the Bitrise plugin README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/bitrise/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/bitrise/README.md b/plugins/bitrise/README.md index ae3917d78a..411db3198e 100644 --- a/plugins/bitrise/README.md +++ b/plugins/bitrise/README.md @@ -8,30 +8,30 @@ Welcome to the Bitrise plugin! ## Installation ```sh +# The plugin must be added in the app package +$ cd packages/app $ yarn add @backstage/plugin-bitrise ``` -Bitrise Plugin exposes an "Entity Tab Content" component `EntityBitriseContent`. You can include it in the [`EntityPage.tsx`](https://github.com/backstage/backstage/blob/master/packages/app/src/components/catalog/EntityPage.tsx)`: +Bitrise Plugin exposes an entity tab component named `EntityBitriseContent`. You can include it in the +[`EntityPage.tsx`](https://github.com/backstage/backstage/blob/master/packages/app/src/components/catalog/EntityPage.tsx)`: ```tsx // At the top imports import { EntityBitriseContent } from '@backstage/plugin-bitrise'; -// Inside `WebsiteEntityPage` component -<EntityPageLayout.Content - path="/bitrise" - title="Bitrise" - element={ - <Grid container spacing={3}> - <Grid item xs={12}> - <EntityBitrisePage /> - </Grid> - </Grid> - } -/>; +// Farther down at the website declaration +const websiteEntityPage = ( + <EntityLayoutWrapper> + {/* Place the following section where you want the tab to appear */} + <EntityLayout.Route path="/bitrise" title="Bitrise"> + <EntityBitriseContent /> + </EntityLayout.Route> ``` -Now your plugin should be visible in the entity page, however in a state with a missing `bitrise.io/app` annotation. +Now your plugin should be visible as a tab at the top of the entity pages, +specifically for components that are of the type `website`. +However, it warns of a missing `bitrise.io/app` annotation. Add the annotation to your component [catalog-info.yaml](https://github.com/backstage/backstage/blob/master/catalog-info.yaml) as shown in the highlighted example below: From e5d4cd4dc8b4db1fa48ec059341c14c112e76c96 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 27 Apr 2021 17:30:34 +0200 Subject: [PATCH 280/462] docs: prettier Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/overview/architecture-overview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index 44bc1293f0..316f066614 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -97,9 +97,9 @@ that we choose for the other plugins in the app. These components that are exported from plugins are referred to as "Plugin Extension Components", or "Extension Components". They are regular React components, but in addition to being able to be rendered by React, they also -contain various pieces of metadata that is used to wire together the entire -app. Extension components are created using `create*Extension` methods, which -you can read more about in the +contain various pieces of metadata that is used to wire together the entire app. +Extension components are created using `create*Extension` methods, which you can +read more about in the [composability documentation](../plugins/composability.md). As of this moment, there is no config based install procedure for plugins. Some From 826bcc46b6afebaa915d5d0da0df2803d031e2a3 Mon Sep 17 00:00:00 2001 From: Victor Perera <v-vperera@expediagroup.com> Date: Tue, 27 Apr 2021 10:36:14 -0500 Subject: [PATCH 281/462] Issues/sugestions fixed Signed-off-by: Victor Perera victorcito001@hotmail.com Signed-off-by: Victor Perera <v-vperera@expediagroup.com> --- .../FavouriteTemplate/FavouriteTemplate.tsx | 15 ++++-- .../ScaffolderPage/ScaffolderPage.tsx | 18 +------ .../components/TemplateCard/TemplateCard.tsx | 50 ++++++++++++------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx b/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx index 99f6c21a1d..ae6057beff 100644 --- a/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx +++ b/plugins/scaffolder/src/components/FavouriteTemplate/FavouriteTemplate.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { ComponentProps } from 'react'; +import React, { ComponentProps, useMemo } from 'react'; import { useStarredEntities } from '@backstage/plugin-catalog-react'; import { IconButton, makeStyles, Tooltip, withStyles } from '@material-ui/core'; import StarBorder from '@material-ui/icons/StarBorder'; @@ -29,6 +29,12 @@ const YellowStar = withStyles({ }, })(Star); +const WhiteBorderStar = withStyles({ + root: { + color: '#ffffff', + }, +})(StarBorder); + const useStyles = makeStyles(theme => ({ starButton: { position: 'absolute', @@ -42,7 +48,7 @@ export const favouriteTemplateTooltip = (isStarred: boolean) => isStarred ? 'Remove from favorites' : 'Add to favorites'; export const favouriteTemplateIcon = (isStarred: boolean) => - isStarred ? <YellowStar /> : <StarBorder style={{ color: 'white' }} />; + isStarred ? <YellowStar /> : <WhiteBorderStar />; /** * IconButton for showing if a current entity is starred and adding/removing it from the favourite entities @@ -51,7 +57,10 @@ export const favouriteTemplateIcon = (isStarred: boolean) => export const FavouriteTemplate = (props: Props) => { const classes = useStyles(); const { toggleStarredEntity, isStarredEntity } = useStarredEntities(); - const isStarred = isStarredEntity(props.entity); + const isStarred = useMemo(() => isStarredEntity(props.entity), [ + isStarredEntity, + props.entity, + ]); return ( <IconButton color="inherit" diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index 00b13853ec..4a482402f8 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -39,7 +39,7 @@ import { ResultsFilter } from '../ResultsFilter/ResultsFilter'; import { ScaffolderFilter } from '../ScaffolderFilter'; import { ButtonGroup } from '../ScaffolderFilter/ScaffolderFilter'; import SearchToolbar from '../SearchToolbar/SearchToolbar'; -import { TemplateCard, TemplateCardProps } from '../TemplateCard'; +import { TemplateCard } from '../TemplateCard'; import { registerComponentRouteRef } from '../../routes'; const useStyles = makeStyles(theme => ({ @@ -51,20 +51,6 @@ const useStyles = makeStyles(theme => ({ }, })); -const getTemplateCardProps = ( - template: TemplateEntityV1alpha1, -): TemplateCardProps & { key: string } => { - return { - key: template.metadata.uid!, - name: template.metadata.name, - title: `${(template.metadata.title || template.metadata.name) ?? ''}`, - type: template.spec.type ?? '', - description: template.metadata.description ?? '-', - tags: (template.metadata?.tags as string[]) ?? [], - entityTemplate: template, - }; -}; - export const ScaffolderPageContents = () => { const styles = useStyles(); const { @@ -189,7 +175,7 @@ export const ScaffolderPageContents = () => { {matchingEntities && matchingEntities?.length > 0 && matchingEntities.map(template => ( - <TemplateCard {...getTemplateCardProps(template)} /> + <TemplateCard template={template} /> ))} </ItemCardGrid> </div> diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index 2e9cfe6470..8c64d981ad 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -28,7 +28,7 @@ import { import React from 'react'; import { generatePath } from 'react-router'; import { rootRouteRef } from '../../routes'; -import { Entity } from '@backstage/catalog-model'; +import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { FavouriteTemplate } from '../FavouriteTemplate/FavouriteTemplate'; const useStyles = makeStyles({ @@ -48,52 +48,66 @@ const useStyles = makeStyles({ }); export type TemplateCardProps = { + template: TemplateEntityV1alpha1; +}; + +type TemplateProps = { description: string; tags: string[]; title: string; type: string; name: string; - entityTemplate: Entity; }; -export const TemplateCard = ({ - description, - tags, - title, - type, - name, - entityTemplate, -}: TemplateCardProps) => { +const getTemplateCardProps = ( + template: TemplateEntityV1alpha1, +): TemplateProps & { key: string } => { + return { + key: template.metadata.uid!, + name: template.metadata.name, + title: `${(template.metadata.title || template.metadata.name) ?? ''}`, + type: template.spec.type ?? '', + description: template.metadata.description ?? '-', + tags: (template.metadata?.tags as string[]) ?? [], + }; +}; + +export const TemplateCard = ({ template }: TemplateCardProps) => { const backstageTheme = useTheme<BackstageTheme>(); const rootLink = useRouteRef(rootRouteRef); + const templateProps = getTemplateCardProps(template); - const themeId = pageTheme[type] ? type : 'other'; + const themeId = pageTheme[templateProps.type] ? templateProps.type : 'other'; const theme = backstageTheme.getPageTheme({ themeId }); const classes = useStyles({ backgroundImage: theme.backgroundImage }); const href = generatePath(`${rootLink()}/templates/:templateName`, { - templateName: name, + templateName: templateProps.name, }); return ( <Card> <CardMedia className={classes.cardHeader}> - <FavouriteTemplate entity={entityTemplate} /> + <FavouriteTemplate entity={template} /> <ItemCardHeader - title={title} - subtitle={type} + title={templateProps.title} + subtitle={templateProps.type} classes={{ root: classes.title }} /> </CardMedia> <CardContent> <Box> - {tags?.map(tag => ( + {templateProps.tags?.map(tag => ( <Chip size="small" label={tag} key={tag} /> ))} </Box> - <Box className={classes.description}>{description}</Box> + <Box className={classes.description}>{templateProps.description}</Box> </CardContent> <CardActions> - <Button color="primary" to={href} aria-label={`Choose ${title} `}> + <Button + color="primary" + to={href} + aria-label={`Choose ${templateProps.title} `} + > Choose </Button> </CardActions> From b219821a01c1eee7bf06c989d6db9ff1bdcdf6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20A=CC=8Ahsberg?= <mathias.ahsberg@resurs.se> Date: Tue, 27 Apr 2021 15:47:40 +0000 Subject: [PATCH 282/462] Expose BitbucketRepositoryParser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathias Åhsberg <mathias.ahsberg@resurs.se> --- .changeset/khaki-rice-accept.md | 5 +++++ plugins/catalog-backend/src/ingestion/processors/index.ts | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 .changeset/khaki-rice-accept.md diff --git a/.changeset/khaki-rice-accept.md b/.changeset/khaki-rice-accept.md new file mode 100644 index 0000000000..72f1c635ed --- /dev/null +++ b/.changeset/khaki-rice-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Expose `BitbucketRepositoryParser` introduced in [#5295](https://github.com/backstage/backstage/pull/5295) diff --git a/plugins/catalog-backend/src/ingestion/processors/index.ts b/plugins/catalog-backend/src/ingestion/processors/index.ts index 8aedc8889b..8d1a7967cd 100644 --- a/plugins/catalog-backend/src/ingestion/processors/index.ts +++ b/plugins/catalog-backend/src/ingestion/processors/index.ts @@ -35,3 +35,7 @@ export * from './types'; export { UrlReaderProcessor } from './UrlReaderProcessor'; export { parseEntityYaml } from './util/parse'; export { results }; + +export * from './bitbucket/types'; +export { BitbucketClient } from './bitbucket'; +export type { BitbucketRepositoryParser } from './bitbucket'; From 512889f3ca11f266786b0344900ef71ee432e4b9 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 18:28:55 +0200 Subject: [PATCH 283/462] WIP tests for DefaultProcessingDatabase Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index f67b8603db..a5c1e56cff 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -429,4 +429,66 @@ describe('Default Processing Database', () => { ).toBeFalsy(); }); }); + + describe('updateProcessedEntity', () => { + it('should throw if the entity does not exist', async () => { + await processingDatabase.transaction(async tx => { + await expect( + processingDatabase.updateProcessedEntity(tx, { + id: '9', + processedEntity: { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + deferredEntities: [], + relations: [], + }), + ).rejects.toThrow('Processing state not found for 9'); + }); + }); + + it('should update a processed entity', async () => { + await db<DbRefreshStateRow>('refresh_state').insert({ + entity_id: '123', + entity_ref: 'Component:default/wacka', + unprocessed_entity: '', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + + const deferredEntity = { + apiVersion: '1.0.0', + metadata: { + name: 'deferred', + }, + kind: 'Location', + } as Entity; + + await processingDatabase.transaction(async tx => { + await processingDatabase.updateProcessedEntity(tx, { + id: '123', + processedEntity: { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + deferredEntities: [deferredEntity], + relations: [], + }); + }); + + console.log( + await db<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: 'deferred' }) + .select(), + ); + expect(1).toBeDefined(); + }); + }); }); From 412f96edc10bccc1ccf0716f63dca1bc0dcd244b Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 18:30:00 +0200 Subject: [PATCH 284/462] Combine stitiching queries Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/Stitcher.ts | 118 ++++++++++++++----- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 57f5ae9167..04a8ab8cfc 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -26,6 +26,14 @@ import { import { Entity, parseEntityRef } from '@backstage/catalog-model'; import { createHash } from 'crypto'; import stableStringify from 'fast-json-stable-stringify'; +import { buildEntitySearch } from '../database/search'; +import { DbEntitiesSearchRow } from '../database/types'; + +// The number of items that are sent per batch to the database layer, when +// doing .batchInsert calls to knex. This needs to be low enough to not cause +// errors in the underlying engine due to exceeding query limits, but large +// enough to get the speed benefits. +const BATCH_SIZE = 50; export type DbFinalEntitiesRow = { entity_id: string; @@ -49,64 +57,114 @@ export class Stitcher { for (const entityRef of entityRefs) { await this.transaction(async txOpaque => { const tx = txOpaque as Knex.Transaction; - const [result] = await tx<DbRefreshStateRow>('refresh_state') - .select('entity_id', 'processed_entity') - .where({ entity_ref: entityRef }); - if (!result) { + const result: Array<{ + entityId: string; + processedEntity?: string; + errors: string; + incomingReferenceCount: string | number; + previousEtag?: string; + relationType?: string; + relationTarget?: string; + }> = await tx + .with('incoming_references', function incomingReferences(builder) { + return builder + .from('refresh_state_references') + .where({ target_entity_ref: entityRef }) + .count({ count: '*' }); + }) + .select({ + entityId: 'refresh_state.entity_id', + processedEntity: 'refresh_state.processed_entity', + errors: 'refresh_state.errors', + incomingReferenceCount: 'incoming_references.count', + previousEtag: 'final_entities.etag', + relationType: 'relations.type', + relationTarget: 'relations.target_entity_ref', + }) + .from('refresh_state') + .leftJoin('incoming_references', {}) + .leftOuterJoin('final_entities', { + 'final_entities.entity_id': 'refresh_state.entity_id', + }) + .leftOuterJoin('relations', { + 'relations.source_entity_ref': 'refresh_state.entity_ref', + }) + .where({ 'refresh_state.entity_ref': entityRef }); + + if (!result.length) { this.logger.debug( `Unable to stitch ${entityRef}, item does not exist in refresh state table`, ); return; - } else if (!result.processed_entity) { + } + + const { + entityId, + processedEntity, + errors, + incomingReferenceCount, + previousEtag, + } = result[0]; + + if (!processedEntity) { this.logger.debug( `Unable to stitch ${entityRef}, the entity has not yet been processed`, ); return; } - const entity: Entity = JSON.parse(result.processed_entity); + const entity = JSON.parse(processedEntity) as Entity; + const isOrphan = Number(incomingReferenceCount) === 0; - const entityId = entity?.metadata?.uid; - if (!entityId) { - this.logger.error(`missing ID in entity ${JSON.stringify(entity)}`); - return; - } - - const [reference_count_result] = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .where({ target_entity_ref: entityRef }) - .count({ reference_count: 'target_entity_ref' }); - - if (Number(reference_count_result.reference_count) === 0) { - this.logger.debug(`${entityRef} is orphan`); + if (isOrphan) { + this.logger.debug(`${entityRef} is an orphan`); entity.metadata.annotations = { ...entity.metadata.annotations, ['backstage.io/orphan']: 'true', }; } - const relationResults = await tx<DbRelationsRow>('relations') - .where({ source_entity_ref: entityRef }) - .select(); - - // TODO: entityRef is lower case and should be uppercase in the final result. - entity.relations = relationResults.map(relation => ({ - type: relation.type, - target: parseEntityRef(relation.target_entity_ref), - })); + // TODO: entityRef is lower case and should be uppercase in the final result + entity.relations = result + .filter(row => row.relationType) + .map(row => ({ + type: row.relationType!, + target: parseEntityRef(row.relationTarget!), + })); entity.metadata.generation = 1; + + // If the output entity was actually not changed, just abort const etag = generateEntityEtag(entity); + if (etag === previousEtag) { + console.log(`Skipped stitching of ${entityRef}, no changes`); + return; + } + entity.metadata.etag = etag; + await tx<DbFinalEntitiesRow>('final_entities') .insert({ - finalized_entity: JSON.stringify(entity), entity_id: entityId, + finalized_entity: JSON.stringify(entity), etag, }) .onConflict('entity_id') .merge(['finalized_entity', 'etag']); + + try { + const entries = buildEntitySearch(entityId, entity); + await tx<DbEntitiesSearchRow>('search') + .where({ entity_id: entityId }) + .delete(); + await tx.batchInsert('search', entries, BATCH_SIZE); + } catch (e) { + this.logger.debug( + `Failed to write search entries for ${entityId}`, + e, + ); + // intentionally ignored + } }); } } From 20346793a20e32299e88858c636985cd4836236d Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 18:30:22 +0200 Subject: [PATCH 285/462] Create search table Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../20210302150147_refresh_state.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 2afeda02c0..755a645894 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -154,6 +154,28 @@ exports.up = async function up(knex) { table.index('source_entity_ref', 'relations_source_entity_ref_idx'); table.index('originating_entity_id', 'relations_source_entity_id_idx'); }); + + await knex.schema.createTable('search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + table.index(['key'], 'search_key_idx'); + table.index(['value'], 'search_value_idx'); + }); }; /** @@ -177,6 +199,12 @@ exports.down = async function down(knex) { table.index('source_entity_ref', 'relations_source_entity_ref_idx'); table.index('originating_entity_id', 'relations_source_entity_id_idx'); }); + await knex.schema.alterTable('search', table => { + table.dropIndex([], 'search_key_idx'); + table.dropIndex([], 'search_value_idx'); + }); + + await knex.schema.dropTable('search'); await knex.schema.dropTable('final_entities'); await knex.schema.dropTable('relations'); await knex.schema.dropTable('references'); From a1783f3060bc306fd3e2261eee14491aa43c397b Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Tue, 27 Apr 2021 11:04:07 -0600 Subject: [PATCH 286/462] Add nebula-preview Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- .changeset/thin-coins-compete.md | 5 +++++ .../src/scaffolder/actions/builtin/publish/github.ts | 1 + .../src/scaffolder/stages/publish/github.ts | 1 + 3 files changed, 7 insertions(+) create mode 100644 .changeset/thin-coins-compete.md diff --git a/.changeset/thin-coins-compete.md b/.changeset/thin-coins-compete.md new file mode 100644 index 0000000000..36511ec1cb --- /dev/null +++ b/.changeset/thin-coins-compete.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Added the `nebula-preview` preview to `Octokit` for repository visibility. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index 3ae43c5763..66dfc1d655 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -149,6 +149,7 @@ export function createPublishGithubAction(options: { const client = new Octokit({ auth: token, baseUrl: integrationConfig.config.apiBaseUrl, + previews: ['nebula-preview'], }); const user = await client.users.getByUsername({ diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts index d0bfc89529..829856ec0c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/publish/github.ts @@ -72,6 +72,7 @@ export class GithubPublisher implements PublisherBase { const client = new Octokit({ auth: token, baseUrl: this.config.apiBaseUrl, + previews: ['nebula-preview'], }); const description = values.description as string; From 1a3ce09aee63fa19714f149d73b3985a960fc43c Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 27 Apr 2021 21:23:35 +0200 Subject: [PATCH 287/462] chore(tests): Added some more tests for DefaultLocationStore and fixing migration so it will run properly on PG Signed-off-by: blam <ben@blam.sh> --- .../20210302150147_refresh_state.js | 2 +- .../src/next/DefaultLocationStore.test.ts | 146 ++++++++++++++++++ .../src/next/DefaultLocationStore.ts | 26 ++-- 3 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 plugins/catalog-backend/src/next/DefaultLocationStore.test.ts diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 755a645894..bbaf4820cd 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -160,7 +160,7 @@ exports.up = async function up(knex) { 'Flattened key-values from the entities, used for quick filtering', ); table - .uuid('entity_id') + .text('entity_id') .references('entity_id') .inTable('refresh_state') .onDelete('CASCADE') diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts new file mode 100644 index 0000000000..be20179e9a --- /dev/null +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -0,0 +1,146 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { DatabaseManager } from './database/DatabaseManager'; +import { DefaultLocationStore } from './DefaultLocationStore'; +import { v4 } from 'uuid'; + +describe('Default Location Store', () => { + const createLocationStore = async () => { + const db = await DatabaseManager.createTestDatabase(); + const connection = { applyMutation: jest.fn() }; + const store = new DefaultLocationStore(db); + await store.connect(connection); + return { store, connection }; + }; + + it('should do a full sync with the locations on connect', async () => { + const { connection } = await createLocationStore(); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: [], + }); + }); + + describe('listLocations', () => { + it('lists empty locations when there is no locations', async () => { + const { store } = await createLocationStore(); + + expect(await store.listLocations()).toEqual([]); + }); + + it('lists locations that are added to the db', async () => { + const { store } = await createLocationStore(); + + await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + const listLocations = await store.listLocations(); + + expect(listLocations).toHaveLength(1); + expect(listLocations).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }), + ]), + ); + }); + }); + + describe('createLocation', () => { + it('throws when the location already exists', async () => { + const { store } = await createLocationStore(); + const spec = { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }; + await store.createLocation(spec); + + await expect(() => store.createLocation(spec)).rejects.toThrow( + new RegExp(`Location ${spec.type}:${spec.target} already exists`), + ); + }); + + it('calls apply mutation when adding a new location', async () => { + const { store, connection } = await createLocationStore(); + + await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + removed: [], + added: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), + }); + }); + }); + + describe('deleteLocation', () => { + it('throws if the location does not exist', async () => { + const { store } = await createLocationStore(); + + const id = v4(); + + await expect(() => store.deleteLocation(id)).rejects.toThrow( + new RegExp(`Found no location with ID ${id}`), + ); + }); + + it('calls apply mutation when adding a new location', async () => { + const { store, connection } = await createLocationStore(); + + const location = await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + await store.deleteLocation(location.id); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), + }); + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index a56e5d1585..28db3790b6 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -34,10 +34,8 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return 'DefaultLocationStore'; } - createLocation(spec: LocationSpec): Promise<Location> { + async createLocation(spec: LocationSpec): Promise<Location> { return this.db.transaction(async tx => { - // TODO: id should really be type and target combined and not a uuid. - // Attempt to find a previous location matching the spec const previousLocations = await this.listLocations(); const previousLocation = previousLocations.some( @@ -50,6 +48,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { ); } + // TODO: id should really be type and target combined and not a uuid. const location = await this.db.addLocation(tx, { id: uuidv4(), type: spec.type, @@ -68,11 +67,17 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async listLocations(): Promise<Location[]> { const dbLocations = await this.db.locations(); - return dbLocations.map(item => ({ - id: item.id, - target: item.target, - type: item.type, - })); + return ( + dbLocations + // TODO(blam): We should create a mutation to remove this location for everyone + // eventually when it's all done and dusted + .filter(({ type }) => type !== 'bootstrap') + .map(item => ({ + id: item.id, + target: item.target, + type: item.type, + })) + ); } getLocation(id: string): Promise<Location> { @@ -86,9 +91,6 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return this.db.transaction(async tx => { const location = await this.db.location(id); - if (!location) { - throw new ConflictError(`No location found with id: ${id}`); - } await this.db.removeLocation(tx, id); await this.connection.applyMutation({ type: 'delta', @@ -108,7 +110,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; - const locations = await this.db.locations(); + const locations = await this.listLocations(); const entities = locations.map(location => { return locationSpecToLocationEntity(location); }); From 0aff8985d1fd437cd26ded862912e3cdfce61f56 Mon Sep 17 00:00:00 2001 From: azhurbilo <artemzhurbilo@gmail.com> Date: Thu, 22 Apr 2021 21:31:42 +0300 Subject: [PATCH 288/462] ability to disable postgres CA mount Signed-off-by: azhurbilo <artemzhurbilo@gmail.com> --- contrib/chart/backstage/README.md | 10 ++++++++++ contrib/chart/backstage/templates/_helpers.tpl | 2 +- .../backstage/templates/backend-deployment.yaml | 4 ++-- .../templates/lighthouse-deployment.yaml | 4 ++++ .../postgresql-password-backend-secret.yaml | 15 --------------- contrib/chart/backstage/values.yaml | 2 ++ 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/contrib/chart/backstage/README.md b/contrib/chart/backstage/README.md index 7d04a2cf1e..40bb2666bc 100644 --- a/contrib/chart/backstage/README.md +++ b/contrib/chart/backstage/README.md @@ -129,6 +129,16 @@ For the CA, create a `configMap` named `<release name>-<chart name>-postgres-ca` kubectl create configmap my-company-backstage-postgres-ca --from-file=ca.crt" ``` +or disable CA mount + +```yaml +backend: + postgresCertMountEnabled: false + +lighthouse: + postgresCertMountEnabled: false +``` + > Where the release name contains the chart name "backstage" then only the release name will be used. Now install the helm chart: diff --git a/contrib/chart/backstage/templates/_helpers.tpl b/contrib/chart/backstage/templates/_helpers.tpl index 5d49ba6975..123d4dba5b 100644 --- a/contrib/chart/backstage/templates/_helpers.tpl +++ b/contrib/chart/backstage/templates/_helpers.tpl @@ -214,7 +214,7 @@ Postgres port for the backend {{- .Values.postgresql.service.port }} {{- else if .Values.appConfig.backend.database.connection.port -}} {{- .Values.appConfig.backend.database.connection.port }} -{{ else }} +{{- else -}} 5432 {{- end -}} {{- end -}} diff --git a/contrib/chart/backstage/templates/backend-deployment.yaml b/contrib/chart/backstage/templates/backend-deployment.yaml index 7009a22de0..4059ee3cc9 100644 --- a/contrib/chart/backstage/templates/backend-deployment.yaml +++ b/contrib/chart/backstage/templates/backend-deployment.yaml @@ -49,7 +49,7 @@ spec: name: {{ include "backend.postgresql.passwordSecret" .}} key: postgresql-password volumeMounts: - {{- if .Values.postgresql.enabled }} + {{- if .Values.backend.postgresCertMountEnabled }} - name: postgres-ca mountPath: {{ include "backstage.backend.postgresCaDir" . }} {{- end }} @@ -58,7 +58,7 @@ spec: subPath: {{ include "backstage.appConfigFilename" . }} volumes: - {{- if .Values.postgresql.enabled }} + {{- if .Values.backend.postgresCertMountEnabled }} - name: postgres-ca configMap: name: {{ include "backstage.fullname" . }}-postgres-ca diff --git a/contrib/chart/backstage/templates/lighthouse-deployment.yaml b/contrib/chart/backstage/templates/lighthouse-deployment.yaml index 6104d4e73c..849c48d7a6 100644 --- a/contrib/chart/backstage/templates/lighthouse-deployment.yaml +++ b/contrib/chart/backstage/templates/lighthouse-deployment.yaml @@ -51,14 +51,18 @@ spec: name: {{ include "lighthouse.postgresql.passwordSecret" . }} key: postgresql-password + {{- if .Values.lighthouse.postgresCertMountEnabled }} volumeMounts: - name: postgres-ca mountPath: {{ include "backstage.lighthouse.postgresCaDir" . }} + {{- end }} + {{- if .Values.lighthouse.postgresCertMountEnabled }} volumes: - name: postgres-ca configMap: name: {{ include "backstage.fullname" . }}-postgres-ca + {{- end }} {{- if .Values.global.nodeSelector }} nodeSelector: {{- toYaml .Values.global.nodeSelector | nindent 8 }} diff --git a/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml b/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml index e53369adb9..a71cef7b21 100644 --- a/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml +++ b/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml @@ -13,18 +13,3 @@ metadata: data: postgresql-password: {{ .Values.appConfig.backend.database.connection.password | b64enc }} {{- end }} -{{- if not .Values.postgresql.enabled }} ---- -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: {{ include "lighthouse.postgresql.passwordSecret" . }} - labels: - release: {{ .Release.Name }} - annotations: - "helm.sh/hook": "pre-install,pre-upgrade" - "helm.sh/hook-delete-policy": "before-hook-creation" -data: - postgresql-password: {{ .Values.lighthouse.database.connection.password | b64enc }} -{{- end }} diff --git a/contrib/chart/backstage/values.yaml b/contrib/chart/backstage/values.yaml index e21148b04b..645de91313 100644 --- a/contrib/chart/backstage/values.yaml +++ b/contrib/chart/backstage/values.yaml @@ -28,6 +28,7 @@ backend: pullPolicy: IfNotPresent containerPort: 7000 serviceType: ClusterIP + postgresCertMountEnabled: true resources: requests: memory: 512Mi @@ -43,6 +44,7 @@ lighthouse: pullPolicy: IfNotPresent containerPort: 3003 serviceType: ClusterIP + postgresCertMountEnabled: true resources: requests: memory: 128Mi From 0265764749ed726e6a040593489ecb4726e0911b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 04:19:31 +0000 Subject: [PATCH 289/462] chore(deps): bump eslint-plugin-jest from 24.1.5 to 24.3.6 Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 24.1.5 to 24.3.6. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v24.1.5...v24.3.6) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/yarn.lock b/yarn.lock index b21e2a9bf5..230ff83c19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12518,9 +12518,9 @@ eslint-plugin-import@^2.20.2: tsconfig-paths "^3.9.0" eslint-plugin-jest@^24.1.0: - version "24.1.5" - resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.1.5.tgz#1e866a9f0deac587d0a3d5d7cefe99815a580de2" - integrity sha512-FIP3lwC8EzEG+rOs1y96cOJmMVpdFNreoDJv29B5vIupVssRi8zrSY3QadogT0K3h1Y8TMxJ6ZSAzYUmFCp2hg== + version "24.3.6" + resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz#5f0ca019183c3188c5ad3af8e80b41de6c8e9173" + integrity sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg== dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" @@ -23538,7 +23538,7 @@ semver@7.0.0: resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: +semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@~7.3.0: version "7.3.5" resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -23555,13 +23555,6 @@ semver@~5.3.0: resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= -semver@~7.3.0: - version "7.3.5" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" From d49c94f2f7c5485da0aedff54ac2b4c5616a5795 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 04:22:54 +0000 Subject: [PATCH 290/462] chore(deps): bump core-js from 3.8.3 to 3.11.0 Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.8.3 to 3.11.0. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.11.0/packages/core-js) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/yarn.lock b/yarn.lock index b21e2a9bf5..19aff83248 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10451,9 +10451,9 @@ core-js-pure@^3.0.0, core-js-pure@^3.0.1: integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== core-js@3, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.5.0, core-js@^3.6.0, core-js@^3.6.5: - version "3.8.3" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0" - integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q== + version "3.11.0" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.11.0.tgz#05dac6aa70c0a4ad842261f8957b961d36eb8926" + integrity sha512-bd79DPpx+1Ilh9+30aT5O1sgpQd4Ttg8oqkqi51ZzhedMM1omD2e6IOF48Z/DzDCZ2svp49tN/3vneTK6ZBkXw== core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.10, core-js@^2.6.5: version "2.6.11" @@ -23538,7 +23538,7 @@ semver@7.0.0: resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: +semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@~7.3.0: version "7.3.5" resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -23555,13 +23555,6 @@ semver@~5.3.0: resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= -semver@~7.3.0: - version "7.3.5" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" From c04403f6195cfebd1e0b99e2525965d149a2a68c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 04:26:55 +0000 Subject: [PATCH 291/462] chore(deps): bump json-schema from 0.2.5 to 0.3.0 Bumps [json-schema](https://github.com/kriszyp/json-schema) from 0.2.5 to 0.3.0. - [Release notes](https://github.com/kriszyp/json-schema/releases) - [Commits](https://github.com/kriszyp/json-schema/compare/v0.2.5...v0.3.0) Signed-off-by: dependabot[bot] <support@github.com> --- packages/catalog-model/package.json | 2 +- packages/cli/package.json | 2 +- packages/config-loader/package.json | 2 +- plugins/scaffolder/package.json | 2 +- yarn.lock | 17 +++++------------ 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 64550b35d1..941877aec5 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -33,7 +33,7 @@ "@types/json-schema": "^7.0.5", "@types/yup": "^0.29.8", "ajv": "^7.0.3", - "json-schema": "^0.2.5", + "json-schema": "^0.3.0", "lodash": "^4.17.15", "uuid": "^8.0.0", "yup": "^0.29.3" diff --git a/packages/cli/package.json b/packages/cli/package.json index cd61193efe..1110efefe6 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -82,7 +82,7 @@ "inquirer": "^7.0.4", "jest": "^26.0.1", "jest-css-modules": "^2.1.0", - "json-schema": "^0.2.5", + "json-schema": "^0.3.0", "lodash": "^4.17.19", "mini-css-extract-plugin": "^0.9.0", "ora": "^5.3.0", diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 0a0a76c2d6..55d86314af 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -35,7 +35,7 @@ "@types/json-schema": "^7.0.6", "ajv": "^7.0.3", "fs-extra": "^9.0.0", - "json-schema": "^0.2.5", + "json-schema": "^0.3.0", "json-schema-merge-allof": "^0.7.0", "typescript-json-schema": "^0.49.0", "yaml": "^1.9.2", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 2b4feecb7b..8af5339a0f 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -44,7 +44,7 @@ "@rjsf/core": "^2.4.0", "@rjsf/material-ui": "^2.4.0", "classnames": "^2.2.6", - "json-schema": "^0.2.5", + "json-schema": "^0.3.0", "git-url-parse": "^11.4.4", "humanize-duration": "^3.25.1", "immer": "^9.0.1", diff --git a/yarn.lock b/yarn.lock index b21e2a9bf5..6076e21713 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16965,10 +16965,10 @@ json-schema@0.2.3: resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= -json-schema@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.5.tgz#97997f50972dd0500214e208c407efa4b5d7063b" - integrity sha512-gWJOWYFrhQ8j7pVm0EM8Slr+EPVq1Phf6lvzvD/WCeqkrx/f2xBI0xOsRRS9xCn3I4vKtP519dvs3TP09r24wQ== +json-schema@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.3.0.tgz#90a9c5054bd065422c00241851ce8d59475b701b" + integrity sha512-TYfxx36xfl52Rf1LU9HyWSLGPdYLL+SQ8/E/0yVyKG8wCCDaSrhPap0vEdlsZWRaS6tnKKLPGiEJGiREVC8kxQ== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -23538,7 +23538,7 @@ semver@7.0.0: resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: +semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@~7.3.0: version "7.3.5" resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -23555,13 +23555,6 @@ semver@~5.3.0: resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= -semver@~7.3.0: - version "7.3.5" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" From da546ce005ab90240a0fec4c2969826e7cfb1d38 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Wed, 28 Apr 2021 09:12:15 +0200 Subject: [PATCH 292/462] Support `gridItem` variant for `EntityLinksCard` This makes it similar to other cards. Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/small-snakes-shake.md | 5 +++++ .../src/components/EntityLinksCard/EntityLinksCard.tsx | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changeset/small-snakes-shake.md diff --git a/.changeset/small-snakes-shake.md b/.changeset/small-snakes-shake.md new file mode 100644 index 0000000000..6db9db3754 --- /dev/null +++ b/.changeset/small-snakes-shake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Support `gridItem` variant for `EntityLinksCard`. diff --git a/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx b/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx index f7e558e285..59de0a4587 100644 --- a/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx +++ b/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx @@ -27,9 +27,10 @@ type Props = { /** @deprecated The entity is now grabbed from context instead */ entity?: Entity; cols?: ColumnBreakpoints | number; + variant?: 'gridItem'; }; -export const EntityLinksCard = ({ cols = undefined }: Props) => { +export const EntityLinksCard = ({ cols = undefined, variant }: Props) => { const { entity } = useEntity(); const app = useApp(); @@ -39,7 +40,7 @@ export const EntityLinksCard = ({ cols = undefined }: Props) => { const links = entity?.metadata?.links; return ( - <InfoCard title="Links"> + <InfoCard title="Links" variant={variant}> {!links || links.length === 0 ? ( <EntityLinksEmptyState /> ) : ( From f7167e9aacd2ec721c1998896f12694c1f7b8917 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Wed, 28 Apr 2021 09:18:35 +0200 Subject: [PATCH 293/462] Update processed entity tests Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index a5c1e56cff..d76bd74260 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -19,10 +19,11 @@ import { Knex } from 'knex'; import { DbRefreshStateReferencesRow, DbRefreshStateRow, + DbRelationsRow, DefaultProcessingDatabase, } from './DefaultProcessingDatabase'; -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityRelationSpec } from '@backstage/catalog-model'; import * as uuid from 'uuid'; import { getVoidLogger } from '@backstage/backend-common'; @@ -452,8 +453,8 @@ describe('Default Processing Database', () => { it('should update a processed entity', async () => { await db<DbRefreshStateRow>('refresh_state').insert({ - entity_id: '123', - entity_ref: 'Component:default/wacka', + entity_id: '321', + entity_ref: 'location:default/new-root', unprocessed_entity: '', errors: '', next_update_at: 'now()', @@ -468,9 +469,23 @@ describe('Default Processing Database', () => { kind: 'Location', } as Entity; + const relation: EntityRelationSpec = { + source: { + kind: 'Component', + namespace: 'Default', + name: 'foo', + }, + target: { + kind: 'Component', + namespace: 'Default', + name: 'foo', + }, + type: 'url', + }; + await processingDatabase.transaction(async tx => { await processingDatabase.updateProcessedEntity(tx, { - id: '123', + id: '321', processedEntity: { apiVersion: '1.0.0', metadata: { @@ -479,16 +494,24 @@ describe('Default Processing Database', () => { kind: 'Location', } as Entity, deferredEntities: [deferredEntity], - relations: [], + relations: [relation], }); }); - console.log( - await db<DbRefreshStateRow>('refresh_state') - .where({ entity_ref: 'deferred' }) - .select(), - ); - expect(1).toBeDefined(); + const deferredResult = await db<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: 'location:default/deferred' }) + .select(); + expect(deferredResult.length).toBe(1); + + const [relations] = await db<DbRelationsRow>('relations') + .where({ originating_entity_id: '321' }) + .select(); + expect(relations).toEqual({ + originating_entity_id: '321', + source_entity_ref: 'component:default/foo', + type: 'url', + target_entity_ref: 'component:default/foo', + }); }); }); }); From 17b8da50a959a0c452a457f4207328d8ae1ca98a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 09:18:36 +0200 Subject: [PATCH 294/462] update the stitcher including search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../20210302150147_refresh_state.js | 7 +- .../catalog-backend/src/next/Stitcher.test.ts | 205 ++++++++++++++++++ plugins/catalog-backend/src/next/Stitcher.ts | 59 ++--- .../catalog-backend/src/next/search.test.ts | 160 ++++++++++++++ plugins/catalog-backend/src/next/search.ts | 191 ++++++++++++++++ plugins/catalog-backend/src/next/types.ts | 1 + 6 files changed, 592 insertions(+), 31 deletions(-) create mode 100644 plugins/catalog-backend/src/next/Stitcher.test.ts create mode 100644 plugins/catalog-backend/src/next/search.test.ts create mode 100644 plugins/catalog-backend/src/next/search.ts diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index bbaf4820cd..4d2c30f194 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -33,7 +33,6 @@ exports.up = async function up(knex) { ); table .text('entity_ref') - .unique() .notNullable() .comment('A reference to the entity that the refresh state is tied to'); table @@ -59,13 +58,14 @@ exports.up = async function up(knex) { .notNullable() .comment('JSON array containing all errors related to entity'); table - .dateTime('next_update_at') // TOOD: timezone or change to epoch-millis or similar + .dateTime('next_update_at') // TODO: timezone or change to epoch-millis or similar .notNullable() .comment('Timestamp of when entity should be updated'); table - .dateTime('last_discovery_at') // TOOD: timezone or change to epoch-millis or similar + .dateTime('last_discovery_at') // TODO: timezone or change to epoch-millis or similar .notNullable() .comment('The last timestamp of which this entity was discovered'); + table.unique(['entity_ref'], 'refresh_state_entity_ref_uniq'); table.index('entity_id', 'refresh_state_entity_id_idx'); table.index('entity_ref', 'refresh_state_entity_ref_idx'); table.index('next_update_at', 'refresh_state_next_update_at_idx'); @@ -188,6 +188,7 @@ exports.down = async function down(knex) { table.dropIndex([], 'refresh_state_references_target_entity_id_idx'); }); await knex.schema.alterTable('refresh_state', table => { + table.dropUnique([], 'refresh_state_entity_ref_uniq'); table.dropIndex([], 'refresh_state_entity_id_idx'); table.dropIndex([], 'refresh_state_entity_ref_idx'); table.dropIndex([], 'refresh_state_next_update_at_idx'); diff --git a/plugins/catalog-backend/src/next/Stitcher.test.ts b/plugins/catalog-backend/src/next/Stitcher.test.ts new file mode 100644 index 0000000000..327d922c07 --- /dev/null +++ b/plugins/catalog-backend/src/next/Stitcher.test.ts @@ -0,0 +1,205 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { Knex } from 'knex'; +import { DatabaseManager } from './database/DatabaseManager'; +import { + DbRefreshStateReferencesRow, + DbRefreshStateRow, + DbRelationsRow, +} from './database/DefaultProcessingDatabase'; +import { DbSearchRow } from './search'; +import { DbFinalEntitiesRow, Stitcher } from './Stitcher'; + +describe('Stitcher', () => { + let db: Knex; + const logger = getVoidLogger(); + + beforeEach(async () => { + db = await DatabaseManager.createTestDatabaseConnection(); + await DatabaseManager.createDatabase(db); + }); + + it('runs the happy path', async () => { + const stitcher = new Stitcher(db, logger); + + await db.transaction(async tx => { + await tx<DbRefreshStateRow>('refresh_state').insert([ + { + entity_id: 'my-id', + entity_ref: 'k:ns/n', + unprocessed_entity: JSON.stringify({}), + processed_entity: JSON.stringify({ + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + }, + spec: { + k: 'v', + }, + }), + errors: '[]', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + }, + ]); + await tx<DbRefreshStateReferencesRow>('refresh_state_references').insert([ + { source_key: 'a', target_entity_ref: 'k:ns/n' }, + ]); + await tx<DbRelationsRow>('relations').insert([ + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/other', + }, + ]); + }); + + await stitcher.stitch(new Set(['k:ns/n'])); + + let firstEtag: string; + await db.transaction(async tx => { + const entities = await tx<DbFinalEntitiesRow>('final_entities'); + + expect(entities.length).toBe(1); + const entity = JSON.parse(entities[0].finalized_entity); + expect(entity).toEqual({ + relations: [ + { + type: 'looksAt', + target: { + kind: 'k', + namespace: 'ns', + name: 'other', + }, + }, + ], + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + etag: expect.any(String), + generation: 1, + uid: 'my-id', + }, + spec: { + k: 'v', + }, + }); + + firstEtag = entity.metadata.etag; + + const search = await tx<DbSearchRow>('search'); + expect(search).toEqual( + expect.arrayContaining([ + { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/other' }, + { entity_id: 'my-id', key: 'apiversion', value: 'a' }, + { entity_id: 'my-id', key: 'kind', value: 'k' }, + { entity_id: 'my-id', key: 'metadata.name', value: 'n' }, + { entity_id: 'my-id', key: 'metadata.namespace', value: 'ns' }, + { entity_id: 'my-id', key: 'metadata.uid', value: 'my-id' }, + { entity_id: 'my-id', key: 'spec.k', value: 'v' }, + ]), + ); + }); + + // Re-stitch without any changes + await stitcher.stitch(new Set(['k:ns/n'])); + + await db.transaction(async tx => { + const entities = await tx<DbFinalEntitiesRow>('final_entities'); + expect(entities.length).toBe(1); + const entity = JSON.parse(entities[0].finalized_entity); + expect(entities[0].etag).toEqual(firstEtag); + expect(entity.metadata.etag).toEqual(firstEtag); + }); + + // Now add one more relation and re-stitch + await db.transaction(async tx => { + await tx<DbRelationsRow>('relations').insert([ + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/third', + }, + ]); + }); + + await stitcher.stitch(new Set(['k:ns/n'])); + + await db.transaction(async tx => { + const entities = await tx<DbFinalEntitiesRow>('final_entities'); + + expect(entities.length).toBe(1); + const entity = JSON.parse(entities[0].finalized_entity); + expect(entity).toEqual({ + relations: expect.arrayContaining([ + { + type: 'looksAt', + target: { + kind: 'k', + namespace: 'ns', + name: 'other', + }, + }, + { + type: 'looksAt', + target: { + kind: 'k', + namespace: 'ns', + name: 'third', + }, + }, + ]), + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + etag: expect.any(String), + generation: 1, + uid: 'my-id', + }, + spec: { + k: 'v', + }, + }); + + expect(entities[0].etag).not.toEqual(firstEtag); + expect(entities[0].etag).toEqual(entity.metadata.etag); + + const search = await tx<DbSearchRow>('search'); + expect(search).toEqual( + expect.arrayContaining([ + { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/other' }, + { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/third' }, + { entity_id: 'my-id', key: 'apiversion', value: 'a' }, + { entity_id: 'my-id', key: 'kind', value: 'k' }, + { entity_id: 'my-id', key: 'metadata.name', value: 'n' }, + { entity_id: 'my-id', key: 'metadata.namespace', value: 'ns' }, + { entity_id: 'my-id', key: 'metadata.uid', value: 'my-id' }, + { entity_id: 'my-id', key: 'spec.k', value: 'v' }, + ]), + ); + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 04a8ab8cfc..cd9220e934 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -14,20 +14,14 @@ * limitations under the License. */ +import { Entity, parseEntityRef } from '@backstage/catalog-model'; +import { ConflictError } from '@backstage/errors'; +import { createHash } from 'crypto'; +import stableStringify from 'fast-json-stable-stringify'; import { Knex } from 'knex'; import { Logger } from 'winston'; import { Transaction } from '../database'; -import { ConflictError } from '@backstage/errors'; -import { - DbRefreshStateReferencesRow, - DbRefreshStateRow, - DbRelationsRow, -} from './database/DefaultProcessingDatabase'; -import { Entity, parseEntityRef } from '@backstage/catalog-model'; -import { createHash } from 'crypto'; -import stableStringify from 'fast-json-stable-stringify'; -import { buildEntitySearch } from '../database/search'; -import { DbEntitiesSearchRow } from '../database/types'; +import { buildEntitySearch, DbSearchRow } from './search'; // The number of items that are sent per batch to the database layer, when // doing .batchInsert calls to knex. This needs to be low enough to not cause @@ -58,6 +52,13 @@ export class Stitcher { await this.transaction(async txOpaque => { const tx = txOpaque as Knex.Transaction; + // Selecting from refresh_state and final_entities should yield exactly + // one row (except in abnormal cases where the stitch was invoked for + // something that didn't exist at all, in which case it's zero rows). + // The join with the temporary incoming_references still gives one row. + // The only result set "expanding" join is the one with relations, so + // the output should be at least one row (if zero or one relations were + // found), or at most the same number of rows as relations. const result: Array<{ entityId: string; processedEntity?: string; @@ -90,8 +91,14 @@ export class Stitcher { .leftOuterJoin('relations', { 'relations.source_entity_ref': 'refresh_state.entity_ref', }) - .where({ 'refresh_state.entity_ref': entityRef }); + .where({ 'refresh_state.entity_ref': entityRef }) + .orderBy('relationType', 'asc') + .orderBy('relationTarget', 'asc'); + // If there were no rows returned, it would mean that there was no + // matching row even in the refresh_state. This can happen for example + // if we emit a relation to something that hasn't been ingested yet. + // It's safe to ignore this stitch attempt in that case. if (!result.length) { this.logger.debug( `Unable to stitch ${entityRef}, item does not exist in refresh state table`, @@ -102,11 +109,15 @@ export class Stitcher { const { entityId, processedEntity, - errors, + // errors, incomingReferenceCount, previousEtag, } = result[0]; + // If there was no processed entity in place, the target hasn't been + // through the processing steps yet. It's safe to ignore this stitch + // attempt in that case, since another stitch will be triggered when + // that processing has finished. if (!processedEntity) { this.logger.debug( `Unable to stitch ${entityRef}, the entity has not yet been processed`, @@ -114,6 +125,7 @@ export class Stitcher { return; } + // Grab the processed entity and stitch all of the relevant data into it const entity = JSON.parse(processedEntity) as Entity; const isOrphan = Number(incomingReferenceCount) === 0; @@ -132,15 +144,16 @@ export class Stitcher { type: row.relationType!, target: parseEntityRef(row.relationTarget!), })); - entity.metadata.generation = 1; // If the output entity was actually not changed, just abort const etag = generateEntityEtag(entity); if (etag === previousEtag) { - console.log(`Skipped stitching of ${entityRef}, no changes`); + this.logger.debug(`Skipped stitching of ${entityRef}, no changes`); return; } + entity.metadata.uid = entityId; + entity.metadata.generation = 1; entity.metadata.etag = etag; await tx<DbFinalEntitiesRow>('final_entities') @@ -152,19 +165,9 @@ export class Stitcher { .onConflict('entity_id') .merge(['finalized_entity', 'etag']); - try { - const entries = buildEntitySearch(entityId, entity); - await tx<DbEntitiesSearchRow>('search') - .where({ entity_id: entityId }) - .delete(); - await tx.batchInsert('search', entries, BATCH_SIZE); - } catch (e) { - this.logger.debug( - `Failed to write search entries for ${entityId}`, - e, - ); - // intentionally ignored - } + const searchEntries = buildEntitySearch(entityId, entity); + await tx<DbSearchRow>('search').where({ entity_id: entityId }).delete(); + await tx.batchInsert('search', searchEntries, BATCH_SIZE); }); } } diff --git a/plugins/catalog-backend/src/next/search.test.ts b/plugins/catalog-backend/src/next/search.test.ts new file mode 100644 index 0000000000..be9a98fe69 --- /dev/null +++ b/plugins/catalog-backend/src/next/search.test.ts @@ -0,0 +1,160 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; +import { buildEntitySearch, mapToRows, traverse } from './search'; + +describe('search', () => { + describe('traverse', () => { + it('expands lists of strings to several rows', () => { + const input = { a: ['b', 'c', 'd'] }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'a', value: 'b' }, + { key: 'a.b', value: true }, + { key: 'a', value: 'c' }, + { key: 'a.c', value: true }, + { key: 'a', value: 'd' }, + { key: 'a.d', value: true }, + ]); + }); + + it('expands objects', () => { + const input = { a: { b: { c: 'd' }, e: 'f' } }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'a.b.c', value: 'd' }, + { key: 'a.e', value: 'f' }, + ]); + }); + + it('expands list of objects', () => { + const input = { root: { list: [{ a: 1 }, { a: 2 }] } }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'root.list.a', value: 1 }, + { key: 'root.list.a', value: 2 }, + ]); + }); + + it('skips over special keys', () => { + const input = { + state: { x: 1 }, + relations: [{ y: 2 }], + a: 'a', + metadata: { + b: 'b', + name: 'name', + namespace: 'namespace', + uid: 'uid', + etag: 'etag', + generation: 'generation', + c: 'c', + }, + d: 'd', + }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'a', value: 'a' }, + { key: 'metadata.b', value: 'b' }, + { key: 'metadata.c', value: 'c' }, + { key: 'd', value: 'd' }, + ]); + }); + }); + + describe('mapToRows', () => { + it('converts base types to strings or null', () => { + const input = [ + { key: 'a', value: true }, + { key: 'b', value: false }, + { key: 'c', value: 7 }, + { key: 'd', value: 'string' }, + { key: 'e', value: null }, + { key: 'f', value: undefined }, + ]; + const output = mapToRows(input, 'eid'); + expect(output).toEqual([ + { entity_id: 'eid', key: 'a', value: 'true' }, + { entity_id: 'eid', key: 'b', value: 'false' }, + { entity_id: 'eid', key: 'c', value: '7' }, + { entity_id: 'eid', key: 'd', value: 'string' }, + { entity_id: 'eid', key: 'e', value: null }, + { entity_id: 'eid', key: 'f', value: null }, + ]); + }); + + it('emits lowercase version of keys and values', () => { + const input = [{ key: 'fOo', value: 'BaR' }]; + const output = mapToRows(input, 'eid'); + expect(output).toEqual([{ entity_id: 'eid', key: 'foo', value: 'bar' }]); + }); + + it('skips very large values', () => { + const input = [{ key: 'foo', value: 'a'.repeat(10000) }]; + const output = mapToRows(input, 'eid'); + expect(output).toEqual([]); + }); + }); + + describe('buildEntitySearch', () => { + it('adds special keys even if missing', () => { + const input: Entity = { + apiVersion: 'a', + kind: 'b', + metadata: { name: 'n' }, + }; + expect(buildEntitySearch('eid', input)).toEqual([ + { entity_id: 'eid', key: 'apiversion', value: 'a' }, + { entity_id: 'eid', key: 'kind', value: 'b' }, + { entity_id: 'eid', key: 'metadata.name', value: 'n' }, + { entity_id: 'eid', key: 'metadata.namespace', value: null }, + { entity_id: 'eid', key: 'metadata.uid', value: null }, + { + entity_id: 'eid', + key: 'metadata.namespace', + value: ENTITY_DEFAULT_NAMESPACE, + }, + ]); + }); + + it('adds relations', () => { + const input: Entity = { + relations: [ + { type: 't1', target: { kind: 'k', namespace: 'ns', name: 'a' } }, + { type: 't2', target: { kind: 'k', namespace: 'ns', name: 'b' } }, + ], + apiVersion: 'a', + kind: 'b', + metadata: { name: 'n' }, + }; + expect(buildEntitySearch('eid', input)).toEqual([ + { entity_id: 'eid', key: 'apiversion', value: 'a' }, + { entity_id: 'eid', key: 'kind', value: 'b' }, + { entity_id: 'eid', key: 'metadata.name', value: 'n' }, + { entity_id: 'eid', key: 'metadata.namespace', value: null }, + { entity_id: 'eid', key: 'metadata.uid', value: null }, + { + entity_id: 'eid', + key: 'metadata.namespace', + value: ENTITY_DEFAULT_NAMESPACE, + }, + { entity_id: 'eid', key: 'relations', value: 't1:k:ns/a' }, + { entity_id: 'eid', key: 'relations', value: 't2:k:ns/b' }, + ]); + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/search.ts b/plugins/catalog-backend/src/next/search.ts new file mode 100644 index 0000000000..4aa8bae1a8 --- /dev/null +++ b/plugins/catalog-backend/src/next/search.ts @@ -0,0 +1,191 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + ENTITY_DEFAULT_NAMESPACE, + stringifyEntityRef, +} from '@backstage/catalog-model'; + +export type DbSearchRow = { + entity_id: string; + key: string; + value: string | null; +}; + +// These are excluded in the generic loop, either because they do not make sense +// to index, or because they are special-case always inserted whether they are +// null or not +const SPECIAL_KEYS = [ + 'state', + 'relations', + 'metadata.name', + 'metadata.namespace', + 'metadata.uid', + 'metadata.etag', + 'metadata.generation', +]; + +// The maximum length allowed for search values. These columns are indexed, and +// database engines do not like to index on massive values. For example, +// postgres will balk after 8191 byte line sizes. +const MAX_VALUE_LENGTH = 200; + +type Kv = { + key: string; + value: unknown; +}; + +// Helper for traversing through a nested structure and outputting a list of +// path->value entries of the leaves. +// +// For example, this yaml structure +// +// a: 1 +// b: +// c: null +// e: [f, g] +// h: +// - i: 1 +// j: k +// - i: 2 +// j: l +// +// will result in +// +// "a", 1 +// "b.c", null +// "b.e": "f" +// "b.e.f": true +// "b.e": "g" +// "b.e.g": true +// "h.i": 1 +// "h.j": "k" +// "h.i": 2 +// "h.j": "l" +export function traverse(root: unknown): Kv[] { + const output: Kv[] = []; + + function visit(path: string, current: unknown) { + if (SPECIAL_KEYS.includes(path)) { + return; + } + + // empty or scalar + if ( + current === undefined || + current === null || + ['string', 'number', 'boolean'].includes(typeof current) + ) { + output.push({ key: path, value: current }); + return; + } + + // unknown + if (typeof current !== 'object') { + return; + } + + // array + if (Array.isArray(current)) { + for (const item of current) { + // NOTE(freben): The reason that these are output in two different ways, + // is to support use cases where you want to express that MORE than one + // tag is present in a list. Since the EntityFilters structure is a + // record, you can't have several entries of the same key. Therefore + // you will have to match on + // + // { "a.b": ["true"], "a.c": ["true"] } + // + // rather than + // + // { "a": ["b", "c"] } + // + // because the latter means EITHER b or c has to be present. + visit(path, item); + if (typeof item === 'string') { + output.push({ key: `${path}.${item}`, value: true }); + } + } + return; + } + + // object + for (const [key, value] of Object.entries(current!)) { + visit(path ? `${path}.${key}` : key, value); + } + } + + visit('', root); + + return output; +} + +// Translates a number of raw data rows to search table rows +export function mapToRows(input: Kv[], entityId: string): DbSearchRow[] { + const result: DbSearchRow[] = []; + + for (const { key: rawKey, value: rawValue } of input) { + const key = rawKey.toLocaleLowerCase('en-US'); + if (rawValue === undefined || rawValue === null) { + result.push({ entity_id: entityId, key, value: null }); + } else { + const value = String(rawValue).toLocaleLowerCase('en-US'); + if (value.length <= MAX_VALUE_LENGTH) { + result.push({ entity_id: entityId, key, value }); + } + } + } + + return result; +} + +/** + * Generates all of the search rows that are relevant for this entity. + * + * @param entityId The uid of the entity + * @param entity The entity + * @returns A list of entity search rows + */ +export function buildEntitySearch( + entityId: string, + entity: Entity, +): DbSearchRow[] { + // Visit the base structure recursively + const raw = traverse(entity); + + // Start with some special keys that are always present because you want to + // be able to easily search for null specifically + raw.push({ key: 'metadata.name', value: entity.metadata.name }); + raw.push({ key: 'metadata.namespace', value: entity.metadata.namespace }); + raw.push({ key: 'metadata.uid', value: entity.metadata.uid }); + + // Namespace not specified has the default value "default", so we want to + // match on that as well + if (!entity.metadata.namespace) { + raw.push({ key: 'metadata.namespace', value: ENTITY_DEFAULT_NAMESPACE }); + } + + // Visit relations + for (const relation of entity.relations ?? []) { + raw.push({ + key: 'relations', + value: `${relation.type}:${stringifyEntityRef(relation.target)}`, + }); + } + + return mapToRows(raw, entityId); +} diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index e0616fb336..cc9cc48ad6 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -120,6 +120,7 @@ export type ReplaceProcessingItemsRequest = removed: Entity[]; type: 'delta'; }; + export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise<void>; getNextProcessingItem(): Promise<ProcessingItem>; From bd231a3d63310049c2467fff15670f351cec3e41 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sun, 4 Apr 2021 19:45:23 +0200 Subject: [PATCH 295/462] catalog-backend/next: add Context Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/next/Context/BaseContext.ts | 26 ++++++++++++ .../src/next/Context/ContextWithValue.ts | 40 +++++++++++++++++++ .../src/next/Context/TransactionContext.ts | 40 +++++++++++++++++++ .../catalog-backend/src/next/Context/index.ts | 21 ++++++++++ .../catalog-backend/src/next/Context/types.ts | 23 +++++++++++ 5 files changed, 150 insertions(+) create mode 100644 plugins/catalog-backend/src/next/Context/BaseContext.ts create mode 100644 plugins/catalog-backend/src/next/Context/ContextWithValue.ts create mode 100644 plugins/catalog-backend/src/next/Context/TransactionContext.ts create mode 100644 plugins/catalog-backend/src/next/Context/index.ts create mode 100644 plugins/catalog-backend/src/next/Context/types.ts diff --git a/plugins/catalog-backend/src/next/Context/BaseContext.ts b/plugins/catalog-backend/src/next/Context/BaseContext.ts new file mode 100644 index 0000000000..c9553cffd5 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/BaseContext.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Context, ContextKey } from './types'; + +/** + * A base Context implementation that does not hold any value. + */ +export class BaseContext implements Context { + getContextValue<T>(key: ContextKey<T>): T { + return key.defaultValue; + } +} diff --git a/plugins/catalog-backend/src/next/Context/ContextWithValue.ts b/plugins/catalog-backend/src/next/Context/ContextWithValue.ts new file mode 100644 index 0000000000..8e61e2c6f2 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/ContextWithValue.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseContext } from './BaseContext'; +import { Context, ContextKey } from './types'; + +/** + * A Context implementation that holds a single value, optionally extending an existing context. + */ +export class ContextWithValue implements Context { + static create(key: ContextKey<unknown>, value: unknown, parent?: Context) { + return new ContextWithValue(parent ?? new BaseContext(), key, value); + } + + private constructor( + private readonly parent: Context, + private readonly key: ContextKey<unknown>, + private readonly value: unknown, + ) {} + + getContextValue<T>(key: ContextKey<T>): T { + if (this.key === key) { + return this.value as T; + } + return this.parent.getContextValue(key); + } +} diff --git a/plugins/catalog-backend/src/next/Context/TransactionContext.ts b/plugins/catalog-backend/src/next/Context/TransactionContext.ts new file mode 100644 index 0000000000..6ac50fbc07 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/TransactionContext.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Context, ContextKey } from './types'; +import { Knex } from 'knex'; +import { ContextWithValue } from './ContextWithValue'; + +const transactionContextKey = new ContextKey<Knex.Transaction | undefined>( + undefined, +); + +/** + * TransactionContext handles the wrapping of a knex transaction in a Context. + */ +export class TransactionContext { + static create(tx: Knex.Transaction, parent?: Context) { + return ContextWithValue.create(transactionContextKey, tx, parent); + } + + static getTransaction(context: Context): Knex.Transaction { + const transaction = context.getContextValue(transactionContextKey); + if (!transaction) { + throw new Error(`No transaction available in context`); + } + return transaction; + } +} diff --git a/plugins/catalog-backend/src/next/Context/index.ts b/plugins/catalog-backend/src/next/Context/index.ts new file mode 100644 index 0000000000..992f5e89a6 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { BaseContext } from './BaseContext'; +export { ContextWithValue } from './ContextWithValue'; +export { TransactionContext } from './TransactionContext'; +export { ContextKey } from './types'; +export type { Context } from './types'; diff --git a/plugins/catalog-backend/src/next/Context/types.ts b/plugins/catalog-backend/src/next/Context/types.ts new file mode 100644 index 0000000000..0973b83515 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/types.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class ContextKey<T> { + constructor(readonly defaultValue: T) {} +} + +export interface Context { + getContextValue<T>(key: ContextKey<T>): T; +} From 065e532aade1047d3d06a0d6a308091e63e6eb06 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 28 Apr 2021 10:30:03 +0200 Subject: [PATCH 296/462] catalog-backend: tweak Context API Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../Context/{BaseContext.ts => BackgroundContext.ts} | 2 +- .../src/next/Context/ContextWithValue.ts | 5 ++--- .../{TransactionContext.ts => TransactionValue.ts} | 10 +++++----- plugins/catalog-backend/src/next/Context/index.ts | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) rename plugins/catalog-backend/src/next/Context/{BaseContext.ts => BackgroundContext.ts} (93%) rename plugins/catalog-backend/src/next/Context/{TransactionContext.ts => TransactionValue.ts} (77%) diff --git a/plugins/catalog-backend/src/next/Context/BaseContext.ts b/plugins/catalog-backend/src/next/Context/BackgroundContext.ts similarity index 93% rename from plugins/catalog-backend/src/next/Context/BaseContext.ts rename to plugins/catalog-backend/src/next/Context/BackgroundContext.ts index c9553cffd5..72b9a3b1ed 100644 --- a/plugins/catalog-backend/src/next/Context/BaseContext.ts +++ b/plugins/catalog-backend/src/next/Context/BackgroundContext.ts @@ -19,7 +19,7 @@ import { Context, ContextKey } from './types'; /** * A base Context implementation that does not hold any value. */ -export class BaseContext implements Context { +export class BackgroundContext implements Context { getContextValue<T>(key: ContextKey<T>): T { return key.defaultValue; } diff --git a/plugins/catalog-backend/src/next/Context/ContextWithValue.ts b/plugins/catalog-backend/src/next/Context/ContextWithValue.ts index 8e61e2c6f2..e8f94fd922 100644 --- a/plugins/catalog-backend/src/next/Context/ContextWithValue.ts +++ b/plugins/catalog-backend/src/next/Context/ContextWithValue.ts @@ -14,15 +14,14 @@ * limitations under the License. */ -import { BaseContext } from './BaseContext'; import { Context, ContextKey } from './types'; /** * A Context implementation that holds a single value, optionally extending an existing context. */ export class ContextWithValue implements Context { - static create(key: ContextKey<unknown>, value: unknown, parent?: Context) { - return new ContextWithValue(parent ?? new BaseContext(), key, value); + static create(parent: Context, key: ContextKey<unknown>, value: unknown) { + return new ContextWithValue(parent, key, value); } private constructor( diff --git a/plugins/catalog-backend/src/next/Context/TransactionContext.ts b/plugins/catalog-backend/src/next/Context/TransactionValue.ts similarity index 77% rename from plugins/catalog-backend/src/next/Context/TransactionContext.ts rename to plugins/catalog-backend/src/next/Context/TransactionValue.ts index 6ac50fbc07..6959d13a18 100644 --- a/plugins/catalog-backend/src/next/Context/TransactionContext.ts +++ b/plugins/catalog-backend/src/next/Context/TransactionValue.ts @@ -23,14 +23,14 @@ const transactionContextKey = new ContextKey<Knex.Transaction | undefined>( ); /** - * TransactionContext handles the wrapping of a knex transaction in a Context. + * TransactionValue handles the wrapping of a knex transaction in a Context. */ -export class TransactionContext { - static create(tx: Knex.Transaction, parent?: Context) { - return ContextWithValue.create(transactionContextKey, tx, parent); +export class TransactionValue { + static in(parent: Context, tx: Knex.Transaction) { + return ContextWithValue.create(parent, transactionContextKey, tx); } - static getTransaction(context: Context): Knex.Transaction { + static from(context: Context): Knex.Transaction { const transaction = context.getContextValue(transactionContextKey); if (!transaction) { throw new Error(`No transaction available in context`); diff --git a/plugins/catalog-backend/src/next/Context/index.ts b/plugins/catalog-backend/src/next/Context/index.ts index 992f5e89a6..61dd4a2958 100644 --- a/plugins/catalog-backend/src/next/Context/index.ts +++ b/plugins/catalog-backend/src/next/Context/index.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -export { BaseContext } from './BaseContext'; +export { BackgroundContext } from './BackgroundContext'; export { ContextWithValue } from './ContextWithValue'; -export { TransactionContext } from './TransactionContext'; +export { TransactionValue } from './TransactionValue'; export { ContextKey } from './types'; export type { Context } from './types'; From 213cd261b6ccc691bc457907106ffba32b95a695 Mon Sep 17 00:00:00 2001 From: Martina Iglesias Fernandez <martina@roadie.io> Date: Fri, 23 Apr 2021 18:51:52 +0200 Subject: [PATCH 297/462] [chart] Update docker image Signed-off-by: Martina Iglesias Fernandez <martina@roadie.io> --- contrib/chart/backstage/templates/backend-deployment.yaml | 7 +++++++ contrib/chart/backstage/templates/frontend-deployment.yaml | 2 +- contrib/chart/backstage/values.yaml | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/contrib/chart/backstage/templates/backend-deployment.yaml b/contrib/chart/backstage/templates/backend-deployment.yaml index 144fc93e62..3096fc37ab 100644 --- a/contrib/chart/backstage/templates/backend-deployment.yaml +++ b/contrib/chart/backstage/templates/backend-deployment.yaml @@ -26,6 +26,13 @@ spec: {{- end}} containers: - name: {{ .Chart.Name }}-backend + command: ["node"] + args: + - "packages/backend" + - "--config" + - "app-config.yaml" + - "--config" + - {{ printf "/usr/src/app/%s" (include "backstage.appConfigFilename" .) | quote }} image: {{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag }} imagePullPolicy: {{ .Values.backend.image.pullPolicy }} ports: diff --git a/contrib/chart/backstage/templates/frontend-deployment.yaml b/contrib/chart/backstage/templates/frontend-deployment.yaml index 9c674cc160..56f720e834 100644 --- a/contrib/chart/backstage/templates/frontend-deployment.yaml +++ b/contrib/chart/backstage/templates/frontend-deployment.yaml @@ -1,3 +1,4 @@ +{{- if .Values.frontend.enabled }} apiVersion: apps/v1 kind: Deployment metadata: @@ -46,7 +47,6 @@ spec: {{- if .Values.global.nodeSelector }} nodeSelector: {{- toYaml .Values.global.nodeSelector | nindent 8 }} {{- end }} -{{- if .Values.frontend.enabled }} --- apiVersion: v1 kind: Service diff --git a/contrib/chart/backstage/values.yaml b/contrib/chart/backstage/values.yaml index bd80bc22b6..78eb7cb92a 100644 --- a/contrib/chart/backstage/values.yaml +++ b/contrib/chart/backstage/values.yaml @@ -3,7 +3,7 @@ # Declare variables to be passed into your templates. frontend: - enabled: true + enabled: false replicaCount: 1 image: repository: martinaif/backstage-k8s-demo-frontend @@ -23,7 +23,7 @@ backend: replicaCount: 1 image: repository: martinaif/backstage-k8s-demo-backend - tag: test1 + tag: 20210423T1550 pullPolicy: IfNotPresent containerPort: 7000 resources: From 7e1617ce0e79dbff7f905389a337d5f6f6d2e6d2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 21 Apr 2021 19:58:02 +0200 Subject: [PATCH 298/462] catalog-backend: WIP EntityProvider mutation interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: blam <ben@blam.sh> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../next/DefaultCatalogProcessingEngine.ts | 15 ++-- .../src/next/DefaultLocationStore.ts | 68 ++++++++++--------- .../src/next/NextCatalogBuilder.ts | 3 +- plugins/catalog-backend/src/next/types.ts | 21 +++--- 4 files changed, 55 insertions(+), 52 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 934ab3a1cc..b423b61041 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -19,6 +19,8 @@ import { CatalogProcessingEngine, EntityProvider, EntityMessage, + EntityProviderConnection, + EntityProviderMutation, ProcessingStateManager, CatalogProcessingOrchestrator, } from './types'; @@ -27,8 +29,13 @@ import { Logger } from 'winston'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { Stitcher } from './Stitcher'; +class Connection implements EntityProviderConnection { + constructor(private readonly stateManager: ProcessingStateManager) {} + + async applyMutation(mutation: EntityProviderMutation): Promise<void> {} +} + export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { - private subscriptions: Subscription[] = []; private running: boolean = false; constructor( @@ -41,11 +48,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - const id = 'databaseProvider'; - const subscription = provider - .entityChange$() - .subscribe({ next: m => this.onNext(id, m) }); - this.subscriptions.push(subscription); + provider.connect(new Connection(this.stateManager)); } this.running = true; diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index b21fe9da02..a6b4adcca4 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -16,24 +16,29 @@ import { LocationSpec, Location } from '@backstage/catalog-model'; import { Database } from '../database'; -import { LocationStore } from './types'; +import { + LocationStore, + EntityProvider, + EntityProviderConnection, +} from './types'; import { v4 as uuidv4 } from 'uuid'; +import { locationSpecToLocationEntity } from './util'; import { ConflictError } from '@backstage/errors'; -import { Observable } from '@backstage/core'; -import ObservableImpl from 'zen-observable'; export type LocationMessage = | { all: Location[] } | { added: Location[]; removed: Location[] }; -export class DefaultLocationStore implements LocationStore { - private subscribers = new Set< - ZenObservable.SubscriptionObserver<LocationMessage> - >(); +export class DefaultLocationStore implements LocationStore, EntityProvider { + private _connection: EntityProviderConnection | undefined; constructor(private readonly db: Database) {} createLocation(spec: LocationSpec): Promise<Location> { + if (!this.connection) { + throw new Error('location store is not initialized'); + } + return this.db.transaction(async tx => { // TODO: id should really be type and target combined and not a uuid. @@ -55,7 +60,11 @@ export class DefaultLocationStore implements LocationStore { target: spec.target, }); - this.notifyAddition(location); + await this.connection.applyMutation({ + type: 'delta', + added: [locationSpecToLocationEntity(location)], + removed: [], + }); return location; }); @@ -75,40 +84,33 @@ export class DefaultLocationStore implements LocationStore { } deleteLocation(id: string): Promise<void> { + if (!this.connection) { + throw new Error('location store is not initialized'); + } + return this.db.transaction(async tx => { const location = await this.db.location(id); if (!location) { throw new ConflictError(`No location found with id: ${id}`); } await this.db.removeLocation(tx, id); - this.notifyDeletion(location); - }); - } - - private notifyAddition(location: Location) { - for (const subscriber of this.subscribers) { - subscriber.next({ - added: [location], - removed: [], - }); - } - } - - private notifyDeletion(location: Location) { - for (const subscriber of this.subscribers) { - subscriber.next({ + await this.connection.applyMutation({ + type: 'delta', added: [], - removed: [location], + removed: [locationSpecToLocationEntity(location)], }); - } + }); } - location$(): Observable<LocationMessage> { - return new ObservableImpl<LocationMessage>(subscriber => { - this.subscribers.add(subscriber); - return () => { - this.subscribers.delete(subscriber); - }; - }); + private get connection(): EntityProviderConnection { + if (!this._connection) { + throw new Error('location store is not initialized'); + } + + return this._connection; + } + + async connect(connection: EntityProviderConnection): Promise<void> { + this._connection = connection; } } diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index c3e0a6bd9c..1796847164 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -272,11 +272,10 @@ export class NextCatalogBuilder { const entitiesCatalog = new NextEntitiesCatalog(dbClient); const locationStore = new DefaultLocationStore(db); - const dbLocationProvider = new DatabaseLocationProvider(locationStore); const stitcher = new Stitcher(dbClient, logger); const processingEngine = new DefaultCatalogProcessingEngine( logger, - [dbLocationProvider], // entityproviders + [locationStore], // entityproviders stateManager, orchestrator, stitcher, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 0aeb290224..c3854d631f 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity, EntityName, @@ -21,7 +22,6 @@ import { EntityRelationSpec, } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; -import { Observable } from '@backstage/core'; // << nooo export interface LocationEntity { apiVersion: 'backstage.io/v1alpha1'; @@ -45,20 +45,11 @@ export interface LocationService { deleteLocation(id: string): Promise<void>; } -export type EntityMessage = - | { all: Entity[] } - | { added: Entity[]; removed: EntityName[] }; - export interface LocationStore { - // extends EntityProvider createLocation(spec: LocationSpec): Promise<Location>; listLocations(): Promise<Location[]>; getLocation(id: string): Promise<Location>; deleteLocation(id: string): Promise<void>; - - location$(): Observable< - { all: Location[] } | { added: Location[]; removed: Location[] } - >; } export interface CatalogProcessingEngine { @@ -66,8 +57,16 @@ export interface CatalogProcessingEngine { stop(): Promise<void>; } +export type EntityProviderMutation = + | { type: 'full'; entities: Iterable<Entity> } + | { type: 'delta'; added: Iterable<Entity>; removed: Iterable<Entity> }; + +export interface EntityProviderConnection { + applyMutation(mutation: EntityProviderMutation): Promise<void>; +} + export interface EntityProvider { - entityChange$(): Observable<EntityMessage>; + connect(connection: EntityProviderConnection): Promise<void>; } export type EntityProcessingRequest = { From d9e5eeb575d316f60924dbd19a0c034cc433d162 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 22 Apr 2021 19:41:40 +0200 Subject: [PATCH 299/462] chore: worked on some more of the new catalog migration with fixing deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Signed-off-by: blam <ben@blam.sh> --- .../20210302150147_refresh_state.js | 33 ++-- .../next/DefaultCatalogProcessingEngine.ts | 38 +++- .../src/next/DefaultLocationStore.ts | 4 - .../src/next/DefaultProcessingStateManager.ts | 13 +- .../src/next/database/DatabaseManager.ts | 114 +++++++++++ .../DefaultProcessingDatabase.test.ts | 31 +++ .../database/DefaultProcessingDatabase.ts | 180 +++++++++++++++++- .../src/next/database/types.ts | 17 ++ plugins/catalog-backend/src/next/types.ts | 21 +- 9 files changed, 405 insertions(+), 46 deletions(-) create mode 100644 plugins/catalog-backend/src/next/database/DatabaseManager.ts create mode 100644 plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 6abab6270b..14c75b2530 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -59,13 +59,14 @@ exports.up = async function up(knex) { .notNullable() .comment('JSON array containing all errors related to entity'); table - .dateTime('next_update_at') + .dateTime('next_update_at') // TOOD: timezone or change to epoch-millis or similar .notNullable() .comment('Timestamp of when entity should be updated'); table - .dateTime('last_discovery_at') + .dateTime('last_discovery_at') // TOOD: timezone or change to epoch-millis or similar .notNullable() .comment('The last timestamp of which this entity was discovered'); + table.index('entity_id', 'refresh_state_entity_id_idx'); table.index('entity_ref', 'refresh_state_entity_ref_idx'); table.index('next_update_at', 'refresh_state_next_update_at_idx'); }); @@ -94,38 +95,35 @@ exports.up = async function up(knex) { 'Holds edges between refresh state rows. Every time when an entity is processed and emits another entity, an edge will be stored to represent that fact. This is used to detect orphans and ultimately deletions.', ); table - .text('source_special_key') + .text('source_key') .nullable() .comment( 'When the reference source is not an entity, this is an opaque identifier for that source.', ); table - .text('source_entity_id') + .text('source_entity_ref') .nullable() - .references('entity_id') + .references('entity_ref') .inTable('refresh_state') .onDelete('CASCADE') .comment( - 'When the reference source is an entity, this is the ID of the source entity.', + 'When the reference source is an entity, this is the EntityRef of the source entity.', ); table - .text('target_entity_id') + .text('target_entity_ref') .notNullable() - .references('entity_id') + .references('entity_ref') .inTable('refresh_state') .onDelete('CASCADE') - .comment('The ID of the target entity.'); + .comment('The EntityRef of the target entity.'); + table.index('source_key', 'refresh_state_references_source_key_idx'); table.index( - 'source_special_key', - 'refresh_state_references_source_special_key_idx', + 'source_entity_ref', + 'refresh_state_references_source_entity_ref_idx', ); table.index( - 'source_entity_id', - 'refresh_state_references_source_entity_id_idx', - ); - table.index( - 'target_entity_id', - 'refresh_state_references_target_entity_id_idx', + 'target_entity_ref', + 'refresh_state_references_target_entity_ref_idx', ); }); @@ -165,6 +163,7 @@ exports.down = async function down(knex) { table.dropIndex([], 'refresh_state_references_target_entity_id_idx'); }); await knex.schema.alterTable('refresh_state', table => { + table.dropIndex([], 'refresh_state_entity_id_idx'); table.dropIndex([], 'refresh_state_entity_ref_idx'); table.dropIndex([], 'refresh_state_next_update_at_idx'); }); diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index b423b61041..7f49bf832d 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -30,9 +30,31 @@ import { stringifyEntityRef } from '@backstage/catalog-model'; import { Stitcher } from './Stitcher'; class Connection implements EntityProviderConnection { - constructor(private readonly stateManager: ProcessingStateManager) {} + constructor( + private readonly config: { + stateManager: ProcessingStateManager; + id: string; + }, + ) {} - async applyMutation(mutation: EntityProviderMutation): Promise<void> {} + async applyMutation(mutation: EntityProviderMutation): Promise<void> { + if (mutation.type === 'full') { + await this.config.stateManager.replaceProcessingItems({ + id: this.config.id, + type: 'full', + items: mutation.entities, + }); + + return; + } + + await this.config.stateManager.replaceProcessingItems({ + id: this.config.id, + type: 'delta', + added: mutation.added, + removed: mutation.removed, + }); + } } export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { @@ -48,7 +70,9 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - provider.connect(new Connection(this.stateManager)); + // TODO: this ID should be some form of identifier for the EntityProvider + const id = 'databaseProvider'; + provider.connect(new Connection({ stateManager: this.stateManager, id })); } this.running = true; @@ -57,12 +81,12 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { const { id, entity, - state: intialState, + state: initialState, } = await this.stateManager.getNextProcessingItem(); const result = await this.orchestrator.process({ entity, - state: intialState, + state: initialState, }); for (const error of result.errors) { @@ -95,10 +119,6 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async stop() { this.running = false; - - for (const subscription of this.subscriptions) { - subscription.unsubscribe(); - } } private async onNext(id: string, message: EntityMessage) { diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index a6b4adcca4..dff424b1a9 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -35,10 +35,6 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { constructor(private readonly db: Database) {} createLocation(spec: LocationSpec): Promise<Location> { - if (!this.connection) { - throw new Error('location store is not initialized'); - } - return this.db.transaction(async tx => { // TODO: id should really be type and target combined and not a uuid. diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index 91090bc139..d2765c3101 100644 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -17,14 +17,23 @@ import { ProcessingDatabase, RefreshStateItem } from './database/types'; import { AddProcessingItemRequest, - ProccessingItem, + ProcessingItem, ProcessingItemResult, ProcessingStateManager, + ReplaceProcessingItemsRequest, } from './types'; export class DefaultProcessingStateManager implements ProcessingStateManager { constructor(private readonly db: ProcessingDatabase) {} + replaceProcessingItems( + request: ReplaceProcessingItemsRequest, + ): Promise<void> { + return this.db.transaction(async tx => { + await this.db.replaceUnprocessedEntities(tx, request); + }); + } + async setProcessingItemResult(result: ProcessingItemResult) { return this.db.transaction(async tx => { await this.db.updateProcessedEntity(tx, { @@ -44,7 +53,7 @@ export class DefaultProcessingStateManager implements ProcessingStateManager { }); } - async getNextProcessingItem(): Promise<ProccessingItem> { + async getNextProcessingItem(): Promise<ProcessingItem> { const entities = await new Promise<RefreshStateItem[]>(resolve => this.popFromQueue(resolve), ); diff --git a/plugins/catalog-backend/src/next/database/DatabaseManager.ts b/plugins/catalog-backend/src/next/database/DatabaseManager.ts new file mode 100644 index 0000000000..4c9e45950f --- /dev/null +++ b/plugins/catalog-backend/src/next/database/DatabaseManager.ts @@ -0,0 +1,114 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger, resolvePackagePath } from '@backstage/backend-common'; +import knexFactory, { Knex } from 'knex'; +import { v4 as uuidv4 } from 'uuid'; +import { Logger } from 'winston'; +import { CommonDatabase } from '../../database/CommonDatabase'; +import { Database } from '../../database/types'; +import fs from 'fs-extra'; + +export type CreateDatabaseOptions = { + logger: Logger; +}; + +const defaultOptions: CreateDatabaseOptions = { + logger: getVoidLogger(), +}; + +export class DatabaseManager { + public static async createDatabase( + knex: Knex, + options: Partial<CreateDatabaseOptions> = {}, + ): Promise<Database> { + const allMigrations = resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrations', + ); + + const migrationsDir = resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrationsv2', + ); + await fs.copy(allMigrations, migrationsDir); + + await knex.migrate.latest({ + directory: migrationsDir, + }); + const { logger } = { ...defaultOptions, ...options }; + return new CommonDatabase(knex, logger); + } + + public static async createInMemoryDatabase(): Promise<Database> { + const knex = await this.createInMemoryDatabaseConnection(); + return await this.createDatabase(knex); + } + + public static async createInMemoryDatabaseConnection(): Promise<Knex> { + const knex = knexFactory({ + client: 'sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }); + + knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { + resource.run('PRAGMA foreign_keys = ON', () => {}); + }); + + return knex; + } + + public static async createTestDatabase(): Promise<Database> { + const knex = await this.createTestDatabaseConnection(); + return await this.createDatabase(knex); + } + + public static async createTestDatabaseConnection(): Promise<Knex> { + const config: Knex.Config<any> = { + /* + client: 'pg', + connection: { + host: 'localhost', + user: 'postgres', + password: 'postgres', + }, + */ + client: 'sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }; + + let knex = knexFactory(config); + if (typeof config.connection !== 'string') { + const tempDbName = `d${uuidv4().replace(/-/g, '')}`; + await knex.raw(`CREATE DATABASE ${tempDbName};`); + knex = knexFactory({ + ...config, + connection: { + ...config.connection, + database: tempDbName, + }, + }); + } + + knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { + resource.run('PRAGMA foreign_keys = ON', () => {}); + }); + + return knex; + } +} diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts new file mode 100644 index 0000000000..fd2e9e6750 --- /dev/null +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// import { DefaultProcessingDatabase } from './DefaultProcessingDatabase'; +import { DatabaseManager } from './DatabaseManager'; +import { Knex } from 'knex'; + +describe('Default Processing Database', () => { + let db: Knex | undefined; + + beforeEach(async () => { + db = await DatabaseManager.createTestDatabaseConnection(); + await DatabaseManager.createDatabase(db); + }); + + it('should write some stuff', async () => { + await db('refresh_state_referencess').select(); + }); +}); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index cf2d4e121c..b799bd6284 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -15,6 +15,7 @@ */ import { ConflictError, NotFoundError } from '@backstage/errors'; +import { stringifyEntityRef, Entity } from '@backstage/catalog-model'; import { Knex } from 'knex'; import { Transaction } from '../../database'; import lodash from 'lodash'; @@ -24,20 +25,21 @@ import { AddUnprocessedEntitiesOptions, UpdateProcessedEntityOptions, GetProcessableEntitiesResult, + ReplaceUnprocessedEntitiesOptions, } from './types'; import type { Logger } from 'winston'; -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; + import { v4 as uuid } from 'uuid'; export type DbRefreshStateRow = { entity_id: string; entity_ref: string; unprocessed_entity: string; - processed_entity: string; - cache: string; + processed_entity?: string; + cache?: string; next_update_at: string; last_discovery_at: string; // remove? - errors: string; + errors?: string; }; export type DbRelationsRow = { @@ -47,10 +49,10 @@ export type DbRelationsRow = { type: string; }; -export type DbRefreshStateReferences = { - source_special_key?: string; - source_entity_id?: string; - target_entity_id: string; +export type DbRefreshStateReferencesRow = { + source_key?: string; + source_entity_ref?: string; + target_entity_ref: string; }; // The number of items that are sent per batch to the database layer, when @@ -128,6 +130,164 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ); } + async replaceUnprocessedEntities( + txOpaque: Transaction, + options: ReplaceUnprocessedEntitiesOptions, + ): Promise<void> { + const tx = txOpaque as Knex.Transaction; + const entityIds = new Array<string>(); + + if (options.type === 'full') { + const oldRefs = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .where({ source_key: options.sourceKey }) + .select('target_entity_ref') + .then(rows => rows.map(r => r.target_entity_ref)); + + const items = options.items.map(entity => ({ + entity, + ref: stringifyEntityRef(entity), + id: uuid(), + })); + + const oldRefsSet = new Set(oldRefs); + const newRefsSet = new Set(items.map(item => item.ref)); + const toAdd = items.filter(item => !oldRefsSet.has(item.ref)); + const toRemove = oldRefs.filter(ref => !newRefsSet.has(ref)); + + if (toRemove.length) { + // TODO(freben): Batch split, to not hit variable limits? + + // get all refs where source = any of the toRemove + // delete all state rows matching any of the toRemove + // revisit the targets of all of those refs + // verify if they have references, otherwise delete from refresh_state + + const current = [...toRemove]; + while (true) { + + tx.withRecursive('r', function refs() { + return tx.select({ }) + .from({ r1: 'refresh_state_references' }) + .where({ source_key: options.sourceKey }) + .whereIn('target_entity_ref', toRemove) + .unionAll(function recurse() { + return tx.select({ }) + .from({ r2: 'refresh_state_references' }) + .whereNotExists() + }) + }) + .select().from('refs'); + + const nextLayerToRemove = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .whereIn('source_entity_ref', toRemove) + .leftOuterJoin('refresh_state_references AS b', function f() { + + }) + + .whereNotNull('b.source_target_ref') + .select('target_entity_ref'); + + await tx<DbRefreshStateRow>('refresh_state') + .whereIn('entity_ref', toRemove) + .delete(); + + const refsThatStillHaveASourcePointingAtThe = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .whereIn('target_entity_ref', nextLayerTargetRefs) + .groupBy('target_entity_ref') + .select('target_entity_ref'); + + } + + + + + if (toAdd.length) { + const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(item => ({ + entity_id: item.id, + entity_ref: item.ref, + unprocessed_entity: JSON.stringify(item.entity), + errors: '', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + })); + const stateReferences: DbRefreshStateReferencesRow[] = toAdd.map( + item => ({ + source_key: options.sourceKey, + target_entity_ref: item.ref, + }), + ); + // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense + await tx.batchInsert('refresh_state', state, BATCH_SIZE); + await tx.batchInsert('refresh_state_references', stateReferences, BATCH_SIZE); + } + + + for (const entity of options.items) { + const entityRef = stringifyEntityRef(entity); + await tx<DbRefreshStateRow>('refresh_state') + .insert({ + entity_id: uuid(), + entity_ref: entityRef, + unprocessed_entity: JSON.stringify(entity), + errors: '', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + }) + .onConflict('entity_ref') + .merge(['unprocessed_entity', 'last_discovery_at']); + + const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( + 'refresh_state', + ).where({ entity_ref: entityRef }); + entityIds.push(entityId); + } + const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( + entityId => ({ + source_key: options.sourceKey, + target_entityRef: entityRef, + }), + ); + await tx.batchInsert( + 'refresh_state_references', + referenceRows, + BATCH_SIZE, + ); + return; + } + + for (const entity of options.removed) { + const entityRef = stringifyEntityRef(entity); + const [result] = await tx<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: entityRef }) + .select('entity_id'); + + if (!result) { + this.logger.info( + `Unable to delete entity '${entityRef}', entity does not exist in refresh state`, + ); + continue; + } + + const referenceResults = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + // todo correct key? + .where({ source_entity_id: result.entity_id }) + .select(); + + await tx<DbRefreshStateReferencesRow>('refresh_state_references') + // todo correct key? + .where({ source_entity_id: result.entity_id }) + .delete(); + } + } + async addUnprocessedEntities( txOpaque: Transaction, options: AddUnprocessedEntitiesOptions, @@ -160,11 +320,11 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ? { source_special_key: options.id } : { source_entity_id: options.id }; // copied from update refs - await tx<DbRefreshStateReferences>('refresh_state_references') + await tx<DbRefreshStateReferencesRow>('refresh_state_references') .where(key) .delete(); - const referenceRows: DbRefreshStateReferences[] = entityIds.map( + const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( entityId => ({ ...key, target_entity_id: entityId, diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index 22e9e90c8e..b926676887 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -50,6 +50,19 @@ export type GetProcessableEntitiesResult = { items: RefreshStateItem[]; }; +export type ReplaceUnprocessedEntitiesOptions = + | { + sourceKey: string; + items: Entity[]; + type: 'full'; + } + | { + sourceKey: string; + added: Entity[]; + removed: Entity[]; + type: 'delta'; + }; + export interface ProcessingDatabase { transaction<T>(fn: (tx: Transaction) => Promise<T>): Promise<T>; @@ -58,6 +71,10 @@ export interface ProcessingDatabase { options: AddUnprocessedEntitiesOptions, ): Promise<void>; + replaceUnprocessedEntities( + txOpaque: Transaction, + options: ReplaceUnprocessedEntitiesOptions, + ): Promise<void>; getProcessableEntities( txOpaque: Transaction, request: { processBatchSize: number }, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index c3854d631f..f8b4de1c41 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -58,8 +58,8 @@ export interface CatalogProcessingEngine { } export type EntityProviderMutation = - | { type: 'full'; entities: Iterable<Entity> } - | { type: 'delta'; added: Iterable<Entity>; removed: Iterable<Entity> }; + | { type: 'full'; entities: Entity[] } + | { type: 'delta'; added: Entity[]; removed: Entity[] }; export interface EntityProviderConnection { applyMutation(mutation: EntityProviderMutation): Promise<void>; @@ -108,14 +108,27 @@ export type AddProcessingItemRequest = { entities: Entity[]; }; -export type ProccessingItem = { +export type ProcessingItem = { id: string; entity: Entity; state: Map<string, JsonObject>; }; +export type ReplaceProcessingItemsRequest = + | { + id: string; + items: Entity[]; + type: 'full'; + } + | { + id: string; + added: Entity[]; + removed: Entity[]; + type: 'delta'; + }; export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise<void>; - getNextProcessingItem(): Promise<ProccessingItem>; + getNextProcessingItem(): Promise<ProcessingItem>; addProcessingItems(request: AddProcessingItemRequest): Promise<void>; + replaceProcessingItems(request: ReplaceProcessingItemsRequest): Promise<void>; } From 87ff2b455a9390ff9067fea7e01c20d4f984dcfe Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 23 Apr 2021 15:05:04 +0200 Subject: [PATCH 300/462] feat: added support for full sync replace with an awesome sql statement courtesy of @freben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Signed-off-by: blam <ben@blam.sh> --- .../20210302150147_refresh_state.js | 3 + .../DefaultProcessingDatabase.test.ts | 271 +++++++++++++++++- .../database/DefaultProcessingDatabase.ts | 220 +++++++------- 3 files changed, 390 insertions(+), 104 deletions(-) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 14c75b2530..2afeda02c0 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -94,6 +94,9 @@ exports.up = async function up(knex) { table.comment( 'Holds edges between refresh state rows. Every time when an entity is processed and emits another entity, an edge will be stored to represent that fact. This is used to detect orphans and ultimately deletions.', ); + table + .increments('id') + .comment('Primary key to distinguish unique lines from each other'); table .text('source_key') .nullable() diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index fd2e9e6750..ee04a2baf8 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -16,16 +16,283 @@ // import { DefaultProcessingDatabase } from './DefaultProcessingDatabase'; import { DatabaseManager } from './DatabaseManager'; import { Knex } from 'knex'; +import { + DbRefreshStateReferencesRow, + DbRefreshStateRow, + DefaultProcessingDatabase, +} from './DefaultProcessingDatabase'; + +import { Entity } from '@backstage/catalog-model'; +import * as uuid from 'uuid'; +import { getVoidLogger } from '@backstage/backend-common'; describe('Default Processing Database', () => { let db: Knex | undefined; + let processingDatabase: DefaultProcessingDatabase | undefined; + + const logger = getVoidLogger(); beforeEach(async () => { db = await DatabaseManager.createTestDatabaseConnection(); await DatabaseManager.createDatabase(db); + + processingDatabase = new DefaultProcessingDatabase(db!, logger); }); - it('should write some stuff', async () => { - await db('refresh_state_referencess').select(); + describe('replaceUnprocessedEntities', () => { + const insertRefRow = async (ref: DbRefreshStateReferencesRow) => { + return db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).insert(ref); + }; + + const insertRefreshStateRow = async (ref: DbRefreshStateRow) => { + await db!<DbRefreshStateRow>('refresh_state').insert(ref); + }; + + const createLocations = async (entityRefs: string[]) => { + for (const ref of entityRefs) { + await insertRefreshStateRow({ + entity_id: uuid.v4(), + entity_ref: ref, + unprocessed_entity: '{}', + processed_entity: '{}', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + } + }; + + it('replaces all existing state correctly for simple dependency chains', async () => { + /* + config -> location:default/root -> location:default/root-1 -> location:default/root-2 + database -> location:default/second -> location:default/root-2 + */ + await createLocations([ + 'location:default/root', + 'location:default/root-1', + 'location:default/root-2', + 'location:default/second', + ]); + + await insertRefRow({ + source_key: 'config', + target_entity_ref: 'location:default/root', + }); + + await insertRefRow({ + source_key: 'database', + target_entity_ref: 'location:default/second', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root', + target_entity_ref: 'location:default/root-1', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root-1', + target_entity_ref: 'location:default/root-2', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/second', + target_entity_ref: 'location:default/root-2', + }); + + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'full', + sourceKey: 'config', + items: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + for (const ref of ['location:default/root', 'location:default/root-1']) { + expect(currentRefreshState.some(t => t.entity_ref === ref)).toBeFalsy(); + } + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root' && + t.target_entity_ref === 'location:default/root-1', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root-1' && + t.target_entity_ref === 'location:default/root-2', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.target_entity_ref === 'location:default/root-1' && + t.source_key === 'config', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.target_entity_ref === 'location:default/new-root' && + t.source_key === 'config', + ), + ).toBeTruthy(); + }); + + it('should work for more complex chains', async () => { + /* + config -> location:default/root -> location:default/root-1 -> location:default/root-2 + config -> location:default/root -> location:default/root-1a -> location:default/root-2 + */ + await createLocations([ + 'location:default/root', + 'location:default/root-1', + 'location:default/root-2', + 'location:default/root-1a', + ]); + + await insertRefRow({ + source_key: 'config', + target_entity_ref: 'location:default/root', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root', + target_entity_ref: 'location:default/root-1', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root', + target_entity_ref: 'location:default/root-1a', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root-1', + target_entity_ref: 'location:default/root-2', + }); + + await insertRefRow({ + source_entity_ref: 'location:default/root-1a', + target_entity_ref: 'location:default/root-2', + }); + + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'full', + sourceKey: 'config', + items: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + const deletedRefs = [ + 'location:default/root', + 'location:default/root-1', + 'location:default/root-1a', + 'location:default/root-2', + ]; + + for (const ref of deletedRefs) { + expect(currentRefreshState.some(t => t.entity_ref === ref)).toBeFalsy(); + } + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'config' && + t.target_entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'config' && + t.target_entity_ref === 'location:default/root', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root' && + t.target_entity_ref === 'location:default/root-1', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root' && + t.target_entity_ref === 'location:default/root-1a', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root-1' && + t.target_entity_ref === 'location:default/root-2', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_entity_ref === 'location:default/root-1a' && + t.target_entity_ref === 'location:default/root-2', + ), + ).toBeFalsy(); + }); }); }); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index b799bd6284..f0c5443651 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -135,7 +135,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { options: ReplaceUnprocessedEntitiesOptions, ): Promise<void> { const tx = txOpaque as Knex.Transaction; - const entityIds = new Array<string>(); if (options.type === 'full') { const oldRefs = await tx<DbRefreshStateReferencesRow>( @@ -158,55 +157,95 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { if (toRemove.length) { // TODO(freben): Batch split, to not hit variable limits? - - // get all refs where source = any of the toRemove - // delete all state rows matching any of the toRemove - // revisit the targets of all of those refs - // verify if they have references, otherwise delete from refresh_state - - const current = [...toRemove]; - while (true) { - - tx.withRecursive('r', function refs() { - return tx.select({ }) - .from({ r1: 'refresh_state_references' }) - .where({ source_key: options.sourceKey }) - .whereIn('target_entity_ref', toRemove) - .unionAll(function recurse() { - return tx.select({ }) - .from({ r2: 'refresh_state_references' }) - .whereNotExists() - }) + /* + WITH RECURSIVE + -- All the refs that can be reached from each individual root + root_reach(id, entity_ref) AS ( + -- Start with all roots + SELECT id, target_entity_ref + FROM refresh_state_references + WHERE source_key IS NOT NULL + UNION + -- For each match, select all children + SELECT root_reach.id, target_entity_ref + FROM refresh_state_references, root_reach + WHERE source_entity_ref = root_reach.entity_ref + ) + -- Start out with our own matching row (see the WHERE that + -- matches on source_key and target_entity_ref below) + SELECT us.entity_ref + FROM refresh_state_references + -- Expand the entire tree that emanates from that row + JOIN root_reach AS us + ON us.id = refresh_state_references.id + -- Expand with all roots that target the same node but + -- aren't ourselves + LEFT OUTER JOIN root_reach AS them + ON them.entity_ref = us.entity_ref + AND them.id != us.id + -- Keep only the matches that had no other rooots + WHERE refresh_state_references.source_key = "R1" + AND refresh_state_references.target_entity_ref = "A" + AND them.id IS NULL; + */ + const removedCount = await tx<DbRefreshStateRow>('refresh_state') + .whereIn('entity_ref', function orphanedEntityRefs(orphans) { + return ( + orphans + // All the refs that can be reached from each individual root + .withRecursive('root_reach', function rootReach(outer) { + // Start with all roots + return outer + .select({ id: 'id', entity_ref: 'target_entity_ref' }) + .from('refresh_state_references') + .whereNotNull('source_key') + .union(function recurse(inner) { + return ( + inner + // For each match, select all children + .select({ + id: 'root_reach.id', + entity_ref: + 'refresh_state_references.target_entity_ref', + }) + .from('refresh_state_references') + .crossJoin('root_reach', { + 'root_reach.entity_ref': + 'refresh_state_references.source_entity_ref', + }) + ); + }); + }) + .select('us.entity_ref') + // Start out with our own matching row + .from('refresh_state_references') + .where('source_key', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + // Expand the entire tree that emanates from that row + .leftJoin({ us: 'root_reach' }, function us() { + this.on('us.id', '=', 'refresh_state_references.id'); + }) + // Expand with all roots that target the same node but aren't ourselves + .leftOuterJoin({ them: 'root_reach' }, function them() { + this.on('them.entity_ref', '=', 'us.entity_ref'); + this.andOn('them.id', '!=', 'us.id'); + }) + // Keep only the matches that had no other rooots + .whereNull('them.id') + ); }) - .select().from('refs'); + .delete(); - const nextLayerToRemove = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .whereIn('source_entity_ref', toRemove) - .leftOuterJoin('refresh_state_references AS b', function f() { - - }) - - .whereNotNull('b.source_target_ref') - .select('target_entity_ref'); - - await tx<DbRefreshStateRow>('refresh_state') - .whereIn('entity_ref', toRemove) - .delete(); - - const refsThatStillHaveASourcePointingAtThe = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .whereIn('target_entity_ref', nextLayerTargetRefs) - .groupBy('target_entity_ref') - .select('target_entity_ref'); + await tx<DbRefreshStateReferencesRow>('refresh_state_references') + .where('source_key', '=', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + .delete(); + console.log( + `REMOVED, ${removedCount} entities: ${JSON.stringify(toRemove)}`, + ); } - - - if (toAdd.length) { const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(item => ({ entity_id: item.id, @@ -224,67 +263,44 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ); // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense await tx.batchInsert('refresh_state', state, BATCH_SIZE); - await tx.batchInsert('refresh_state_references', stateReferences, BATCH_SIZE); - } - - - for (const entity of options.items) { - const entityRef = stringifyEntityRef(entity); - await tx<DbRefreshStateRow>('refresh_state') - .insert({ - entity_id: uuid(), - entity_ref: entityRef, - unprocessed_entity: JSON.stringify(entity), - errors: '', - next_update_at: tx.fn.now(), - last_discovery_at: tx.fn.now(), - }) - .onConflict('entity_ref') - .merge(['unprocessed_entity', 'last_discovery_at']); - - const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( - 'refresh_state', - ).where({ entity_ref: entityRef }); - entityIds.push(entityId); - } - const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( - entityId => ({ - source_key: options.sourceKey, - target_entityRef: entityRef, - }), - ); - await tx.batchInsert( - 'refresh_state_references', - referenceRows, - BATCH_SIZE, - ); - return; - } - - for (const entity of options.removed) { - const entityRef = stringifyEntityRef(entity); - const [result] = await tx<DbRefreshStateRow>('refresh_state') - .where({ entity_ref: entityRef }) - .select('entity_id'); - - if (!result) { - this.logger.info( - `Unable to delete entity '${entityRef}', entity does not exist in refresh state`, + await tx.batchInsert( + 'refresh_state_references', + stateReferences, + BATCH_SIZE, ); - continue; } - const referenceResults = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - // todo correct key? - .where({ source_entity_id: result.entity_id }) - .select(); + // for (const entity of options.items) { + // const entityRef = stringifyEntityRef(entity); + // await tx<DbRefreshStateRow>('refresh_state') + // .insert({ + // entity_id: uuid(), + // entity_ref: entityRef, + // unprocessed_entity: JSON.stringify(entity), + // errors: '', + // next_update_at: tx.fn.now(), + // last_discovery_at: tx.fn.now(), + // }) + // .onConflict('entity_ref') + // .merge(['unprocessed_entity', 'last_discovery_at']); - await tx<DbRefreshStateReferencesRow>('refresh_state_references') - // todo correct key? - .where({ source_entity_id: result.entity_id }) - .delete(); + // const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( + // 'refresh_state', + // ).where({ entity_ref: entityRef }); + // entityIds.push(entityId); + // } + // const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( + // entityId => ({ + // source_key: options.sourceKey, + // target_entityRef: entityRef, + // }), + // ); + // await tx.batchInsert( + // 'refresh_state_references', + // referenceRows, + // BATCH_SIZE, + // ); + // return; } } From 3f6c50a5291775994b0f90890f286b0018f74a7e Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 23 Apr 2021 16:01:36 +0200 Subject: [PATCH 301/462] feat: support delta and full sync with the same code and simplify things MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com> Signed-off-by: blam <ben@blam.sh> --- .../DefaultProcessingDatabase.test.ts | 89 +++++++ .../database/DefaultProcessingDatabase.ts | 242 ++++++++---------- 2 files changed, 201 insertions(+), 130 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index ee04a2baf8..c4784c081d 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -294,5 +294,94 @@ describe('Default Processing Database', () => { ), ).toBeFalsy(); }); + + it('should add new locations using the delta options', async () => { + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'delta', + sourceKey: 'lols', + removed: [], + added: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'lols' && + t.target_entity_ref === 'location:default/new-root', + ), + ).toBeTruthy(); + }); + + it('should remove old locations using the delta options', async () => { + await createLocations(['location:default/new-root']); + + await insertRefRow({ + source_key: 'lols', + target_entity_ref: 'location:default/new-root', + }); + + await processingDatabase!.transaction(async tx => { + await processingDatabase!.replaceUnprocessedEntities(tx, { + type: 'delta', + sourceKey: 'lols', + added: [], + removed: [ + { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + ], + }); + }); + + const currentRefreshState = await db!<DbRefreshStateRow>( + 'refresh_state', + ).select(); + + const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + expect( + currentRefreshState.some( + t => t.entity_ref === 'location:default/new-root', + ), + ).toBeFalsy(); + + expect( + currentRefRowState.some( + t => + t.source_key === 'lols' && + t.target_entity_ref === 'location:default/new-root', + ), + ).toBeFalsy(); + }); }); }); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index f0c5443651..a80325d469 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -130,34 +130,48 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ); } + private async createDelta( + tx: Knex.Transaction, + options: ReplaceUnprocessedEntitiesOptions, + ): Promise<{ toAdd: Entity[]; toRemove: string[] }> { + if (options.type === 'delta') { + return { + toAdd: options.added, + toRemove: options.removed.map(e => stringifyEntityRef(e)), + }; + } + + const oldRefs = await tx<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ) + .where({ source_key: options.sourceKey }) + .select('target_entity_ref') + .then(rows => rows.map(r => r.target_entity_ref)); + + const items = options.items.map(entity => ({ + entity, + ref: stringifyEntityRef(entity), + })); + + const oldRefsSet = new Set(oldRefs); + const newRefsSet = new Set(items.map(item => item.ref)); + const toAdd = items.filter(item => !oldRefsSet.has(item.ref)); + const toRemove = oldRefs.filter(ref => !newRefsSet.has(ref)); + + return { toAdd: toAdd.map(({ entity }) => entity), toRemove }; + } + async replaceUnprocessedEntities( txOpaque: Transaction, options: ReplaceUnprocessedEntitiesOptions, ): Promise<void> { const tx = txOpaque as Knex.Transaction; - if (options.type === 'full') { - const oldRefs = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .where({ source_key: options.sourceKey }) - .select('target_entity_ref') - .then(rows => rows.map(r => r.target_entity_ref)); + const { toAdd, toRemove } = await this.createDelta(tx, options); - const items = options.items.map(entity => ({ - entity, - ref: stringifyEntityRef(entity), - id: uuid(), - })); - - const oldRefsSet = new Set(oldRefs); - const newRefsSet = new Set(items.map(item => item.ref)); - const toAdd = items.filter(item => !oldRefsSet.has(item.ref)); - const toRemove = oldRefs.filter(ref => !newRefsSet.has(ref)); - - if (toRemove.length) { - // TODO(freben): Batch split, to not hit variable limits? - /* + if (toRemove.length) { + // TODO(freben): Batch split, to not hit variable limits? + /* WITH RECURSIVE -- All the refs that can be reached from each individual root root_reach(id, entity_ref) AS ( @@ -188,119 +202,87 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { AND refresh_state_references.target_entity_ref = "A" AND them.id IS NULL; */ - const removedCount = await tx<DbRefreshStateRow>('refresh_state') - .whereIn('entity_ref', function orphanedEntityRefs(orphans) { - return ( - orphans - // All the refs that can be reached from each individual root - .withRecursive('root_reach', function rootReach(outer) { - // Start with all roots - return outer - .select({ id: 'id', entity_ref: 'target_entity_ref' }) - .from('refresh_state_references') - .whereNotNull('source_key') - .union(function recurse(inner) { - return ( - inner - // For each match, select all children - .select({ - id: 'root_reach.id', - entity_ref: - 'refresh_state_references.target_entity_ref', - }) - .from('refresh_state_references') - .crossJoin('root_reach', { - 'root_reach.entity_ref': - 'refresh_state_references.source_entity_ref', - }) - ); - }); - }) - .select('us.entity_ref') - // Start out with our own matching row - .from('refresh_state_references') - .where('source_key', options.sourceKey) - .whereIn('target_entity_ref', toRemove) - // Expand the entire tree that emanates from that row - .leftJoin({ us: 'root_reach' }, function us() { - this.on('us.id', '=', 'refresh_state_references.id'); - }) - // Expand with all roots that target the same node but aren't ourselves - .leftOuterJoin({ them: 'root_reach' }, function them() { - this.on('them.entity_ref', '=', 'us.entity_ref'); - this.andOn('them.id', '!=', 'us.id'); - }) - // Keep only the matches that had no other rooots - .whereNull('them.id') - ); - }) - .delete(); + const removedCount = await tx<DbRefreshStateRow>('refresh_state') + .whereIn('entity_ref', function orphanedEntityRefs(orphans) { + return ( + orphans + // All the refs that can be reached from each individual root + .withRecursive('root_reach', function rootReach(outer) { + // Start with all roots + return outer + .select({ id: 'id', entity_ref: 'target_entity_ref' }) + .from('refresh_state_references') + .whereNotNull('source_key') + .union(function recurse(inner) { + return ( + inner + // For each match, select all children + .select({ + id: 'root_reach.id', + entity_ref: + 'refresh_state_references.target_entity_ref', + }) + .from('refresh_state_references') + .crossJoin('root_reach', { + 'root_reach.entity_ref': + 'refresh_state_references.source_entity_ref', + }) + ); + }); + }) + .select('us.entity_ref') + // Start out with our own matching row + .from('refresh_state_references') + .where('source_key', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + // Expand the entire tree that emanates from that row + .leftJoin({ us: 'root_reach' }, function us() { + this.on('us.id', '=', 'refresh_state_references.id'); + }) + // Expand with all roots that target the same node but aren't ourselves + .leftOuterJoin({ them: 'root_reach' }, function them() { + this.on('them.entity_ref', '=', 'us.entity_ref'); + this.andOn('them.id', '!=', 'us.id'); + }) + // Keep only the matches that had no other rooots + .whereNull('them.id') + ); + }) + .delete(); - await tx<DbRefreshStateReferencesRow>('refresh_state_references') - .where('source_key', '=', options.sourceKey) - .whereIn('target_entity_ref', toRemove) - .delete(); + await tx<DbRefreshStateReferencesRow>('refresh_state_references') + .where('source_key', '=', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + .delete(); - console.log( - `REMOVED, ${removedCount} entities: ${JSON.stringify(toRemove)}`, - ); - } + this.logger.debug( + `removed, ${removedCount} entities: ${JSON.stringify(toRemove)}`, + ); + } - if (toAdd.length) { - const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(item => ({ - entity_id: item.id, - entity_ref: item.ref, - unprocessed_entity: JSON.stringify(item.entity), - errors: '', - next_update_at: tx.fn.now(), - last_discovery_at: tx.fn.now(), - })); - const stateReferences: DbRefreshStateReferencesRow[] = toAdd.map( - item => ({ - source_key: options.sourceKey, - target_entity_ref: item.ref, - }), - ); - // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense - await tx.batchInsert('refresh_state', state, BATCH_SIZE); - await tx.batchInsert( - 'refresh_state_references', - stateReferences, - BATCH_SIZE, - ); - } + if (toAdd.length) { + const state: Knex.DbRecord<DbRefreshStateRow>[] = toAdd.map(entity => ({ + entity_id: uuid(), + entity_ref: stringifyEntityRef(entity), + unprocessed_entity: JSON.stringify(entity), + errors: '', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + })); - // for (const entity of options.items) { - // const entityRef = stringifyEntityRef(entity); - // await tx<DbRefreshStateRow>('refresh_state') - // .insert({ - // entity_id: uuid(), - // entity_ref: entityRef, - // unprocessed_entity: JSON.stringify(entity), - // errors: '', - // next_update_at: tx.fn.now(), - // last_discovery_at: tx.fn.now(), - // }) - // .onConflict('entity_ref') - // .merge(['unprocessed_entity', 'last_discovery_at']); - - // const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( - // 'refresh_state', - // ).where({ entity_ref: entityRef }); - // entityIds.push(entityId); - // } - // const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( - // entityId => ({ - // source_key: options.sourceKey, - // target_entityRef: entityRef, - // }), - // ); - // await tx.batchInsert( - // 'refresh_state_references', - // referenceRows, - // BATCH_SIZE, - // ); - // return; + const stateReferences: DbRefreshStateReferencesRow[] = toAdd.map( + entity => ({ + source_key: options.sourceKey, + target_entity_ref: stringifyEntityRef(entity), + }), + ); + // TODO(freben): Concurrency? If we did these one by one, a .onConflict().merge would have made sense + await tx.batchInsert('refresh_state', state, BATCH_SIZE); + await tx.batchInsert( + 'refresh_state_references', + stateReferences, + BATCH_SIZE, + ); } } From 11ef45c0972a439085dbf772057d299dadccc63c Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 10:14:45 +0200 Subject: [PATCH 302/462] catalog-backend: Remove obervables Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/package.json | 4 +- .../src/next/DatabaseLocationProvider.ts | 71 ------------------- .../next/DefaultCatalogProcessingEngine.ts | 27 +------ .../src/next/DefaultLocationStore.ts | 4 -- plugins/catalog-backend/src/next/types.ts | 5 +- 5 files changed, 5 insertions(+), 106 deletions(-) delete mode 100644 plugins/catalog-backend/src/next/DatabaseLocationProvider.ts diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 9afb537637..5f70ec60e1 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -33,7 +33,6 @@ "@backstage/backend-common": "^0.6.3", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/plugin-search-backend-node": "^0.1.3", @@ -61,8 +60,7 @@ "winston": "^3.2.1", "yaml": "^1.9.2", "yn": "^4.0.0", - "yup": "^0.29.3", - "zen-observable": "^0.8.15" + "yup": "^0.29.3" }, "devDependencies": { "@backstage/cli": "^0.6.9", diff --git a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts b/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts deleted file mode 100644 index eaf5a78556..0000000000 --- a/plugins/catalog-backend/src/next/DatabaseLocationProvider.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2021 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Observable } from '@backstage/core'; -import { ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -import { EntityProvider, LocationStore, EntityMessage } from './types'; -import ObservableImpl from 'zen-observable'; -import { - locationSpecToLocationEntity, - locationSpecToMetadataName, -} from './util'; - -export class DatabaseLocationProvider implements EntityProvider { - private subscribers = new Set< - ZenObservable.SubscriptionObserver<EntityMessage> - >(); - - constructor(private readonly store: LocationStore) { - store.location$().subscribe({ - next: locations => { - if ('all' in locations) { - this.notify({ - all: locations.all.map(l => locationSpecToLocationEntity(l)), - }); - } else { - this.notify({ - added: locations.added.map(l => locationSpecToLocationEntity(l)), - removed: locations.removed.map(l => ({ - kind: 'Location', - namespace: ENTITY_DEFAULT_NAMESPACE, - name: locationSpecToMetadataName(l), - })), - }); - } - }, - }); - } - - private notify(message: EntityMessage) { - for (const subscriber of this.subscribers) { - subscriber.next(message); - } - } - - entityChange$(): Observable<EntityMessage> { - return new ObservableImpl(subscriber => { - this.store.listLocations().then(locations => { - subscriber.next({ - all: locations.map(l => locationSpecToLocationEntity(l)), - }); - this.subscribers.add(subscriber); - }); - return () => { - this.subscribers.delete(subscriber); - }; - }); - } -} diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 7f49bf832d..b71b2c1045 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -14,11 +14,9 @@ * limitations under the License. */ -import { Subscription } from '@backstage/core'; import { CatalogProcessingEngine, EntityProvider, - EntityMessage, EntityProviderConnection, EntityProviderMutation, ProcessingStateManager, @@ -40,7 +38,7 @@ class Connection implements EntityProviderConnection { async applyMutation(mutation: EntityProviderMutation): Promise<void> { if (mutation.type === 'full') { await this.config.stateManager.replaceProcessingItems({ - id: this.config.id, + sourceKey: this.config.id, type: 'full', items: mutation.entities, }); @@ -49,7 +47,7 @@ class Connection implements EntityProviderConnection { } await this.config.stateManager.replaceProcessingItems({ - id: this.config.id, + sourceKey: this.config.id, type: 'delta', added: mutation.added, removed: mutation.removed, @@ -120,25 +118,4 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async stop() { this.running = false; } - - private async onNext(id: string, message: EntityMessage) { - if ('all' in message) { - // TODO unhandled rejection - await this.stateManager.addProcessingItems({ - id, - type: 'provider', - entities: message.all, - }); - } - - if ('added' in message) { - await this.stateManager.addProcessingItems({ - id, - type: 'provider', - entities: message.added, - }); - - // TODO deletions of message.removed - } - } } diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index dff424b1a9..21206f0a7b 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -25,10 +25,6 @@ import { v4 as uuidv4 } from 'uuid'; import { locationSpecToLocationEntity } from './util'; import { ConflictError } from '@backstage/errors'; -export type LocationMessage = - | { all: Location[] } - | { added: Location[]; removed: Location[] }; - export class DefaultLocationStore implements LocationStore, EntityProvider { private _connection: EntityProviderConnection | undefined; diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index f8b4de1c41..a39ab9a8ff 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -16,7 +16,6 @@ import { Entity, - EntityName, LocationSpec, Location, EntityRelationSpec, @@ -116,12 +115,12 @@ export type ProcessingItem = { export type ReplaceProcessingItemsRequest = | { - id: string; + sourceKey: string; items: Entity[]; type: 'full'; } | { - id: string; + sourceKey: string; added: Entity[]; removed: Entity[]; type: 'delta'; From fd7cd5d44959a3bd1d356eca4837dfd419372eb4 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 13:56:32 +0200 Subject: [PATCH 303/462] Refactor deferredEntities processing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultLocationStore.ts | 8 + .../src/next/DefaultProcessingStateManager.ts | 39 ++- .../src/next/NextCatalogBuilder.ts | 1 - plugins/catalog-backend/src/next/Stitcher.ts | 4 +- .../DefaultProcessingDatabase.test.ts | 83 ++++-- .../database/DefaultProcessingDatabase.ts | 236 ++++++++++-------- .../src/next/database/types.ts | 7 +- 7 files changed, 222 insertions(+), 156 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index 21206f0a7b..40870cff7b 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -104,5 +104,13 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; + const locations = await this.db.locations(); + const entities = locations.map(location => { + return locationSpecToLocationEntity(location); + }); + await this.connection.applyMutation({ + type: 'full', + entities, + }); } } diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index d2765c3101..0003b7a7cf 100644 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -49,35 +49,28 @@ export class DefaultProcessingStateManager implements ProcessingStateManager { async addProcessingItems(request: AddProcessingItemRequest) { return this.db.transaction(async tx => { - await this.db.addUnprocessedEntities(tx, request); + // await this.db.addUnprocessedEntities(tx, request); }); } async getNextProcessingItem(): Promise<ProcessingItem> { - const entities = await new Promise<RefreshStateItem[]>(resolve => - this.popFromQueue(resolve), - ); - const { id, state, unprocessedEntity } = entities[0]; - return { - id, - entity: unprocessedEntity, - state, - }; - } - - async popFromQueue(resolve: (rows: RefreshStateItem[]) => void) { - const entities = await this.db.transaction(async tx => { - return this.db.getProcessableEntities(tx, { - processBatchSize: 1, + for (;;) { + const { items } = await this.db.transaction(async tx => { + return this.db.getProcessableEntities(tx, { + processBatchSize: 1, + }); }); - }); - // No entities require refresh, wait and try again. - if (!entities.items.length) { - setTimeout(() => this.popFromQueue(resolve), 1000); - return; + if (items.length) { + const { id, state, unprocessedEntity } = items[0]; + return { + id, + entity: unprocessedEntity, + state, + }; + } + + await new Promise<void>(resolve => setTimeout(resolve, 1000)); } - - resolve(entities.items); } } diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 1796847164..d720bd331a 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -67,7 +67,6 @@ import { LocationAnalyzer } from '../ingestion/types'; import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; -import { DatabaseLocationProvider } from '../next/DatabaseLocationProvider'; import { DefaultLocationStore } from './DefaultLocationStore'; import { DefaultProcessingStateManager } from './DefaultProcessingStateManager'; import { CatalogProcessingEngine } from '../next/types'; diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 3e5e3ac24b..f53b7c6fad 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -76,8 +76,8 @@ export class Stitcher { const [reference_count_result] = await tx<DbRefreshStateReferences>( 'refresh_state_references', ) - .where({ target_entity_id: entity.metadata.uid }) - .count({ reference_count: 'target_entity_id' }); + .where({ target_entity_ref: entityRef }) + .count({ reference_count: 'target_entity_ref' }); if (Number(reference_count_result.reference_count) === 0) { this.logger.debug(`${entityRef} is orphan`); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index c4784c081d..14990a2a79 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -27,27 +27,26 @@ import * as uuid from 'uuid'; import { getVoidLogger } from '@backstage/backend-common'; describe('Default Processing Database', () => { - let db: Knex | undefined; - let processingDatabase: DefaultProcessingDatabase | undefined; - + let db: Knex; + let processingDatabase: DefaultProcessingDatabase; const logger = getVoidLogger(); beforeEach(async () => { db = await DatabaseManager.createTestDatabaseConnection(); await DatabaseManager.createDatabase(db); - processingDatabase = new DefaultProcessingDatabase(db!, logger); + processingDatabase = new DefaultProcessingDatabase(db, logger); }); describe('replaceUnprocessedEntities', () => { const insertRefRow = async (ref: DbRefreshStateReferencesRow) => { - return db!<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ).insert(ref); + return db<DbRefreshStateReferencesRow>('refresh_state_references').insert( + ref, + ); }; const insertRefreshStateRow = async (ref: DbRefreshStateRow) => { - await db!<DbRefreshStateRow>('refresh_state').insert(ref); + await db<DbRefreshStateRow>('refresh_state').insert(ref); }; const createLocations = async (entityRefs: string[]) => { @@ -101,8 +100,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/root-2', }); - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'full', sourceKey: 'config', items: [ @@ -117,11 +116,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); @@ -205,8 +204,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/root-2', }); - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'full', sourceKey: 'config', items: [ @@ -221,11 +220,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); @@ -296,8 +295,8 @@ describe('Default Processing Database', () => { }); it('should add new locations using the delta options', async () => { - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'delta', sourceKey: 'lols', removed: [], @@ -313,11 +312,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); @@ -336,6 +335,42 @@ describe('Default Processing Database', () => { ).toBeTruthy(); }); + it('should not remove locations that are referenced elsewhere', async () => { + /* + config-1 -> location:default/root + config-2 -> location:default/root + */ + await createLocations(['location:default/root']); + + await insertRefRow({ + source_key: 'config-1', + target_entity_ref: 'location:default/root', + }); + await insertRefRow({ + source_key: 'config-2', + target_entity_ref: 'location:default/root', + }); + + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { + type: 'full', + sourceKey: 'config-1', + items: [], + }); + }); + + const currentRefRowState = await db<DbRefreshStateReferencesRow>( + 'refresh_state_references', + ).select(); + + expect(currentRefRowState).toEqual({ + source_key: 'config-2', + target_entity_ref: 'location:default/root', + }); + + // TODO: assert that root wasn't removed + }); + it('should remove old locations using the delta options', async () => { await createLocations(['location:default/new-root']); @@ -344,8 +379,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/new-root', }); - await processingDatabase!.transaction(async tx => { - await processingDatabase!.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(async tx => { + await processingDatabase.replaceUnprocessedEntities(tx, { type: 'delta', sourceKey: 'lols', added: [], @@ -361,11 +396,11 @@ describe('Default Processing Database', () => { }); }); - const currentRefreshState = await db!<DbRefreshStateRow>( + const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', ).select(); - const currentRefRowState = await db!<DbRefreshStateReferencesRow>( + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index a80325d469..dc5e6036f5 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -26,10 +26,12 @@ import { UpdateProcessedEntityOptions, GetProcessableEntitiesResult, ReplaceUnprocessedEntitiesOptions, + RefreshStateItem, } from './types'; import type { Logger } from 'winston'; import { v4 as uuid } from 'uuid'; +import { JsonObject } from '@backstage/config'; export type DbRefreshStateRow = { entity_id: string; @@ -88,7 +90,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { errors, }) .where('entity_id', id); - if (refreshResult === 0) { throw new NotFoundError(`Processing state not found for ${id}`); } @@ -96,8 +97,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { // Schedule all deferred entities for future processing. await this.addUnprocessedEntities(tx, { entities: deferredEntities, - id, - type: 'entity', + entityRef: stringifyEntityRef(processedEntity), }); // Update fragments @@ -172,80 +172,104 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { if (toRemove.length) { // TODO(freben): Batch split, to not hit variable limits? /* - WITH RECURSIVE - -- All the refs that can be reached from each individual root - root_reach(id, entity_ref) AS ( - -- Start with all roots - SELECT id, target_entity_ref - FROM refresh_state_references - WHERE source_key IS NOT NULL - UNION - -- For each match, select all children - SELECT root_reach.id, target_entity_ref - FROM refresh_state_references, root_reach - WHERE source_entity_ref = root_reach.entity_ref - ) - -- Start out with our own matching row (see the WHERE that - -- matches on source_key and target_entity_ref below) - SELECT us.entity_ref - FROM refresh_state_references - -- Expand the entire tree that emanates from that row - JOIN root_reach AS us - ON us.id = refresh_state_references.id - -- Expand with all roots that target the same node but - -- aren't ourselves - LEFT OUTER JOIN root_reach AS them - ON them.entity_ref = us.entity_ref - AND them.id != us.id - -- Keep only the matches that had no other rooots - WHERE refresh_state_references.source_key = "R1" - AND refresh_state_references.target_entity_ref = "A" - AND them.id IS NULL; - */ + WITH RECURSIVE + -- All the nodes that can be reached downwards from our root + descendants(root_id, entity_ref) AS ( + SELECT id, target_entity_ref + FROM refresh_state_references + WHERE source_key = "R1" AND target_entity_ref = "A" + UNION + SELECT descendants.root_id, target_entity_ref + FROM descendants + JOIN refresh_state_references ON source_entity_ref = descendants.entity_ref + ), + -- All the nodes that can be reached upwards from the descendants + ancestors(root_id, via_entity_ref, to_entity_ref) AS ( + SELECT NULL, entity_ref, entity_ref + FROM descendants + UNION + SELECT + CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END, + source_entity_ref, + ancestors.to_entity_ref + FROM ancestors + JOIN refresh_state_references ON target_entity_ref = ancestors.via_entity_ref + ) + -- Start out with all of the descendants + SELECT descendants.entity_ref + FROM descendants + -- Expand with all ancestors that point to those, but aren't the current root + LEFT OUTER JOIN ancestors + ON ancestors.to_entity_ref = descendants.entity_ref + AND ancestors.root_id IS NOT NULL + AND ancestors.root_id != descendants.root_id + -- Exclude all lines that had such a foreign ancestor + WHERE ancestors.root_id IS NULL; + */ const removedCount = await tx<DbRefreshStateRow>('refresh_state') .whereIn('entity_ref', function orphanedEntityRefs(orphans) { return ( orphans - // All the refs that can be reached from each individual root - .withRecursive('root_reach', function rootReach(outer) { - // Start with all roots + // All the nodes that can be reached downwards from our root + .withRecursive('descendants', function descendants(outer) { return outer - .select({ id: 'id', entity_ref: 'target_entity_ref' }) + .select({ root_id: 'id', entity_ref: 'target_entity_ref' }) .from('refresh_state_references') - .whereNotNull('source_key') - .union(function recurse(inner) { - return ( - inner - // For each match, select all children - .select({ - id: 'root_reach.id', - entity_ref: - 'refresh_state_references.target_entity_ref', - }) - .from('refresh_state_references') - .crossJoin('root_reach', { - 'root_reach.entity_ref': - 'refresh_state_references.source_entity_ref', - }) - ); + .where('source_key', options.sourceKey) + .whereIn('target_entity_ref', toRemove) + .union(function recursive(inner) { + return inner + .select({ + root_id: 'descendants.root_id', + entity_ref: + 'refresh_state_references.target_entity_ref', + }) + .from('descendants') + .join('refresh_state_references', { + 'descendants.entity_ref': + 'refresh_state_references.source_entity_ref', + }); }); }) - .select('us.entity_ref') - // Start out with our own matching row - .from('refresh_state_references') - .where('source_key', options.sourceKey) - .whereIn('target_entity_ref', toRemove) - // Expand the entire tree that emanates from that row - .leftJoin({ us: 'root_reach' }, function us() { - this.on('us.id', '=', 'refresh_state_references.id'); + // All the nodes that can be reached upwards from the descendants + .withRecursive('ancestors', function ancestors(outer) { + return outer + .select({ + root_id: tx.raw('NULL', []), + via_entity_ref: 'entity_ref', + to_entity_ref: 'entity_ref', + }) + .from('descendants') + .union(function recursive(inner) { + return inner + .select({ + root_id: tx.raw( + 'CASE WHEN source_key IS NOT NULL THEN id ELSE NULL END', + [], + ), + via_entity_ref: 'source_entity_ref', + to_entity_ref: 'ancestors.to_entity_ref', + }) + .from('ancestors') + .join('refresh_state_references', { + target_entity_ref: 'ancestors.via_entity_ref', + }); + }); }) - // Expand with all roots that target the same node but aren't ourselves - .leftOuterJoin({ them: 'root_reach' }, function them() { - this.on('them.entity_ref', '=', 'us.entity_ref'); - this.andOn('them.id', '!=', 'us.id'); + // Start out with all of the descendants + .select('descendants.entity_ref') + .from('descendants') + // Expand with all ancestors that point to those, but aren't the current root + .leftOuterJoin('ancestors', function keepaliveRoots() { + this.on( + 'ancestors.to_entity_ref', + '=', + 'descendants.entity_ref', + ); + this.andOnNotNull('ancestors.root_id'); + this.andOn('ancestors.root_id', '!=', 'descendants.root_id'); }) - // Keep only the matches that had no other rooots - .whereNull('them.id') + .whereNull('ancestors.root_id') ); }) .delete(); @@ -291,44 +315,45 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { options: AddUnprocessedEntitiesOptions, ): Promise<void> { const tx = txOpaque as Knex.Transaction; - const entityIds = new Array<string>(); - for (const entity of options.entities) { - const entityRef = stringifyEntityRef(entity); - await tx<DbRefreshStateRow>('refresh_state') - .insert({ + const stateRows = options.entities.map( + entity => + ({ entity_id: uuid(), - entity_ref: entityRef, + entity_ref: stringifyEntityRef(entity), unprocessed_entity: JSON.stringify(entity), errors: '', next_update_at: tx.fn.now(), last_discovery_at: tx.fn.now(), - }) + } as Knex.DbRecord<DbRefreshStateRow>), + ); + const stateReferenceRows = stateRows.map( + stateRow => + ({ + source_entity_ref: options.entityRef, + target_entity_ref: stateRow.entity_ref, + } as Knex.DbRecord<DbRefreshStateReferencesRow>), + ); + + // Upsert all of the unprocessed entities into the refresh_state table, by + // their entity ref. + // TODO(freben): Can this be batched somehow? + for (const row of stateRows) { + await tx<DbRefreshStateRow>('refresh_state') + .insert(row) .onConflict('entity_ref') .merge(['unprocessed_entity', 'last_discovery_at']); - - const [{ entity_id: entityId }] = await tx<DbRefreshStateRow>( - 'refresh_state', - ).where({ entity_ref: entityRef }); - entityIds.push(entityId); } - const key = - options.type === 'provider' - ? { source_special_key: options.id } - : { source_entity_id: options.id }; - // copied from update refs + // Replace all references for the originating entity before creating new ones await tx<DbRefreshStateReferencesRow>('refresh_state_references') - .where(key) + .where({ source_entity_ref: options.entityRef }) .delete(); - - const referenceRows: DbRefreshStateReferencesRow[] = entityIds.map( - entityId => ({ - ...key, - target_entity_id: entityId, - }), + await tx.batchInsert( + 'refresh_state_references', + stateReferenceRows, + BATCH_SIZE, ); - await tx.batchInsert('refresh_state_references', referenceRows, BATCH_SIZE); } async getProcessableEntities( @@ -356,16 +381,23 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { }); return { - items: items.map(i => ({ - id: i.entity_id, - entityRef: i.entity_ref, - unprocessedEntity: JSON.parse(i.unprocessed_entity) as Entity, - processedEntity: JSON.parse(i.processed_entity) as Entity, - nextUpdateAt: i.next_update_at, - lastDiscoveryAt: i.last_discovery_at, - state: JSON.parse(i.cache), - errors: i.errors, - })), + items: items.map( + i => + ({ + id: i.entity_id, + entityRef: i.entity_ref, + unprocessedEntity: JSON.parse(i.unprocessed_entity) as Entity, + processedEntity: i.processed_entity + ? (JSON.parse(i.processed_entity) as Entity) + : undefined, + nextUpdateAt: i.next_update_at, + lastDiscoveryAt: i.last_discovery_at, + state: i.cache + ? JSON.parse(i.cache) + : new Map<string, JsonObject>(), + errors: i.errors, + } as RefreshStateItem), + ), }; } diff --git a/plugins/catalog-backend/src/next/database/types.ts b/plugins/catalog-backend/src/next/database/types.ts index b926676887..d7a1dcd20b 100644 --- a/plugins/catalog-backend/src/next/database/types.ts +++ b/plugins/catalog-backend/src/next/database/types.ts @@ -19,8 +19,7 @@ import { JsonObject } from '@backstage/config'; import { Transaction } from '../../database/types'; export type AddUnprocessedEntitiesOptions = { - type: 'entity' | 'provider'; - id: string; + entityRef: string; entities: Entity[]; }; @@ -39,11 +38,11 @@ export type RefreshStateItem = { id: string; entityRef: string; unprocessedEntity: Entity; - processedEntity: Entity; + processedEntity?: Entity; nextUpdateAt: string; lastDiscoveryAt: string; // remove? state: Map<string, JsonObject>; - errors: string; + errors?: string; }; export type GetProcessableEntitiesResult = { From 19b07a6f67b3c5ba58d11258be9db4a6c2596326 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 14:02:41 +0200 Subject: [PATCH 304/462] Remove addProcessingItems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/Stitcher.ts | 4 ++-- plugins/catalog-backend/src/next/types.ts | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index f53b7c6fad..57f5ae9167 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -19,7 +19,7 @@ import { Logger } from 'winston'; import { Transaction } from '../database'; import { ConflictError } from '@backstage/errors'; import { - DbRefreshStateReferences, + DbRefreshStateReferencesRow, DbRefreshStateRow, DbRelationsRow, } from './database/DefaultProcessingDatabase'; @@ -73,7 +73,7 @@ export class Stitcher { return; } - const [reference_count_result] = await tx<DbRefreshStateReferences>( + const [reference_count_result] = await tx<DbRefreshStateReferencesRow>( 'refresh_state_references', ) .where({ target_entity_ref: entityRef }) diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index a39ab9a8ff..ef3bab797b 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -101,12 +101,6 @@ export type ProcessingItemResult = { deferredEntities: Entity[]; }; -export type AddProcessingItemRequest = { - type: 'entity' | 'provider'; - id: string; - entities: Entity[]; -}; - export type ProcessingItem = { id: string; entity: Entity; @@ -128,6 +122,5 @@ export type ReplaceProcessingItemsRequest = export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise<void>; getNextProcessingItem(): Promise<ProcessingItem>; - addProcessingItems(request: AddProcessingItemRequest): Promise<void>; replaceProcessingItems(request: ReplaceProcessingItemsRequest): Promise<void>; } From e0c39cd7e308a20f5e91b4cb04283589c5bc2251 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 14:12:57 +0200 Subject: [PATCH 305/462] Add moar tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index 14990a2a79..f67b8603db 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -359,16 +359,26 @@ describe('Default Processing Database', () => { }); }); + const currentRefreshState = await db<DbRefreshStateRow>( + 'refresh_state', + ).select(); + const currentRefRowState = await db<DbRefreshStateReferencesRow>( 'refresh_state_references', ).select(); - expect(currentRefRowState).toEqual({ - source_key: 'config-2', - target_entity_ref: 'location:default/root', - }); + expect(currentRefRowState).toEqual([ + expect.objectContaining({ + source_key: 'config-2', + target_entity_ref: 'location:default/root', + }), + ]); - // TODO: assert that root wasn't removed + expect(currentRefreshState).toEqual([ + expect.objectContaining({ + entity_ref: 'location:default/root', + }), + ]); }); it('should remove old locations using the delta options', async () => { From ac48004b7d8f60e3389ca30890a4abdc5d00493e Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 14:15:29 +0200 Subject: [PATCH 306/462] Remove dead code Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultProcessingStateManager.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts index 0003b7a7cf..9c1d20ae9c 100644 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts @@ -14,9 +14,8 @@ * limitations under the License. */ -import { ProcessingDatabase, RefreshStateItem } from './database/types'; +import { ProcessingDatabase } from './database/types'; import { - AddProcessingItemRequest, ProcessingItem, ProcessingItemResult, ProcessingStateManager, @@ -47,12 +46,6 @@ export class DefaultProcessingStateManager implements ProcessingStateManager { }); } - async addProcessingItems(request: AddProcessingItemRequest) { - return this.db.transaction(async tx => { - // await this.db.addUnprocessedEntities(tx, request); - }); - } - async getNextProcessingItem(): Promise<ProcessingItem> { for (;;) { const { items } = await this.db.transaction(async tx => { From c58f8fd1477b6ca536d54ce6ef3aae2b92cd944a Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 15:38:31 +0200 Subject: [PATCH 307/462] Add all migration files to migrationsv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../migrationsv2/20200511113813_init.js | 133 ++++++++++ ...0200520140700_location_update_log_table.js | 43 ++++ ...7114117_location_update_log_latest_view.js | 45 ++++ .../migrationsv2/20200702153613_entities.js | 236 ++++++++++++++++++ ..._location_update_log_latest_deduplicate.js | 44 ++++ ...904_location_update_log_duplication_fix.js | 87 +++++++ .../20200807120600_entitySearch.js | 41 +++ .../20200809202832_add_bootstrap_location.js | 42 ++++ .../20200923104503_case_insensitivity.js | 32 +++ .../20201005122705_add_entity_full_name.js | 60 +++++ .../20201006130744_entity_data_column.js | 66 +++++ ...6203131_entity_remove_redundant_columns.js | 50 ++++ .../20201007201501_index_entity_search.js | 37 +++ .../20201019130742_add_relations_table.js | 54 ++++ .../20201123205611_relations_table_uniq.js | 93 +++++++ .../migrationsv2/20201210185851_fk_index.js | 45 ++++ .../20201230103504_update_log_varchar.js | 73 ++++++ .../20210209121210_locations_fk_index.js | 45 ++++ .../src/next/database/DatabaseManager.ts | 15 -- 19 files changed, 1226 insertions(+), 15 deletions(-) create mode 100644 plugins/catalog-backend/migrationsv2/20200511113813_init.js create mode 100644 plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js create mode 100644 plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js create mode 100644 plugins/catalog-backend/migrationsv2/20200702153613_entities.js create mode 100644 plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js create mode 100644 plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js create mode 100644 plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js create mode 100644 plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js create mode 100644 plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js create mode 100644 plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js create mode 100644 plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js create mode 100644 plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js create mode 100644 plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js create mode 100644 plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js create mode 100644 plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js create mode 100644 plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js create mode 100644 plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js create mode 100644 plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js diff --git a/plugins/catalog-backend/migrationsv2/20200511113813_init.js b/plugins/catalog-backend/migrationsv2/20200511113813_init.js new file mode 100644 index 0000000000..7f3d75e35c --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200511113813_init.js @@ -0,0 +1,133 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + return ( + knex.schema + // + // locations + // + .createTable('locations', table => { + table.comment( + 'Registered locations that shall be contiuously scanned for catalog item updates', + ); + table + .uuid('id') + .primary() + .notNullable() + .comment('Auto-generated ID of the location'); + table.string('type').notNullable().comment('The type of location'); + table + .string('target') + .notNullable() + .comment('The actual target of the location'); + }) + // + // entities + // + .createTable('entities', table => { + table.comment('All entities currently stored in the catalog'); + table.uuid('id').primary().comment('Auto-generated ID of the entity'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .nullable() + .comment('The location that originated the entity'); + table + .string('etag') + .notNullable() + .comment( + 'An opaque string that changes for each update operation to any part of the entity, including metadata.', + ); + table + .string('generation') + .notNullable() + .unsigned() + .comment( + 'A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes.', + ); + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table + .string('kind') + .notNullable() + .comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + table + .string('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .string('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + }) + .alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + }) + // + // entities_search + // + .createTable('entities_search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + }) + ); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + return knex.schema + .dropTable('entities_search') + .alterTable('entities', table => { + table.dropUnique([], 'entities_unique_name'); + }) + .dropTable('entities') + .dropTable('locations'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js b/plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js new file mode 100644 index 0000000000..d8093fc9b4 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200520140700_location_update_log_table.js @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + return knex.schema.createTable('location_update_log', table => { + table.uuid('id').primary(); + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + return knex.schema.dropTableIfExists('location_update_log'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js b/plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js new file mode 100644 index 0000000000..a0f0f33a65 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200527114117_location_update_log_latest_view.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Get list sorted by created_at timestamp in descending order + // Grouped by location_id + return knex.schema.raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + ORDER BY created_at DESC; + `); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + return knex.schema.raw(`DROP VIEW location_update_log_latest;`); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200702153613_entities.js b/plugins/catalog-backend/migrationsv2/20200702153613_entities.js new file mode 100644 index 0000000000..0f1c204f9b --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200702153613_entities.js @@ -0,0 +1,236 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // SQLite does not support FK and PK + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.dropForeign(['entity_id']); + }); + await knex.schema.alterTable('entities', table => { + table.dropPrimary('entities_pkey'); + }); + } + await knex.schema.alterTable('entities', table => { + table.dropUnique([], 'entities_unique_name'); + }); + // Setup temporary tables + await knex.schema.renameTable('entities_search', 'tmp_entities_search'); + await knex.schema.renameTable('entities', 'tmp_entities'); + + // + // entities + // + await knex.schema + .createTable('entities', table => { + table.comment('All entities currently stored in the catalog'); + table.uuid('id').primary().comment('Auto-generated ID of the entity'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .nullable() + .comment('The location that originated the entity'); + table + .string('etag') + .notNullable() + .comment( + 'An opaque string that changes for each update operation to any part of the entity, including metadata.', + ); + table + .string('generation') + .notNullable() + .unsigned() + .comment( + 'A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes.', + ); + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table + .string('kind') + .notNullable() + .comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + table + .text('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .text('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + }) + .alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + }); + + await knex.schema.raw(`INSERT INTO entities SELECT * FROM tmp_entities`); + + // + // entities_search + // + await knex.schema.createTable('entities_search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + }); + await knex.schema.raw( + `INSERT INTO entities_search SELECT * FROM tmp_entities_search`, + ); + + // Clean up + await knex.schema.dropTable('tmp_entities'); + return knex.schema.dropTable('tmp_entities_search'); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + // SQLite does not support FK and PK + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.dropForeign(['entity_id']); + }); + await knex.schema.alterTable('entities', table => { + table.dropPrimary('entities_pkey'); + }); + } + await knex.schema.alterTable('entities', table => { + table.dropUnique([], 'entities_unique_name'); + }); + + // Setup temporary tables + await knex.schema.renameTable('entities_search', 'tmp_entities_search'); + await knex.schema.renameTable('entities', 'tmp_entities'); + + // + // entities + // + await knex.schema + .createTable('entities', table => { + table.comment('All entities currently stored in the catalog'); + table.uuid('id').primary().comment('Auto-generated ID of the entity'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .nullable() + .comment('The location that originated the entity'); + table + .string('etag') + .notNullable() + .comment( + 'An opaque string that changes for each update operation to any part of the entity, including metadata.', + ); + table + .string('generation') + .notNullable() + .unsigned() + .comment( + 'A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes.', + ); + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table + .string('kind') + .notNullable() + .comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + table + .string('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .string('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + }) + .alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + }); + + await knex.schema.raw(`INSERT INTO entities SELECT * FROM tmp_entities`); + + // + // entities_search + // + await knex.schema.createTable('entities_search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + }); + await knex.schema.raw( + `INSERT INTO entities_search SELECT * FROM tmp_entities_search`, + ); + + // Clean up + await knex.schema.dropTable('tmp_entities'); + return knex.schema.dropTable('tmp_entities_search'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js b/plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js new file mode 100644 index 0000000000..87b41a80fc --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200721115244_location_update_log_latest_deduplicate.js @@ -0,0 +1,44 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = function up(knex) { + return knex.schema.raw(`DROP VIEW location_update_log_latest;`).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; +`); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = function down(knex) { + knex.schema.raw(`DROP VIEW location_update_log_latest;`); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js b/plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js new file mode 100644 index 0000000000..de2b194cff --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200805163904_location_update_log_duplication_fix.js @@ -0,0 +1,87 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = function up(knex) { + return knex.schema + .raw('DROP VIEW location_update_log_latest;') + .dropTable('location_update_log') + .createTable('location_update_log', table => { + table.bigIncrements('id').primary(); // instead of uuid, so we can MAX it + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = function down(knex) { + return knex.schema + .raw('DROP VIEW location_update_log_latest;') + .dropTable('location_update_log') + .createTable('location_update_log', table => { + table.uuid('id').primary(); + table.enum('status', ['success', 'fail']).notNullable(); + table.dateTime('created_at').defaultTo(knex.fn.now()).notNullable(); + table.string('message'); + table + .uuid('location_id') + .references('id') + .inTable('locations') + .onUpdate('CASCADE') + .onDelete('CASCADE'); + table.string('entity_name').nullable(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(created_at) AS MAXDATE + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.created_at = t2.MAXDATE + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js b/plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js new file mode 100644 index 0000000000..45226e53b4 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200807120600_entitySearch.js @@ -0,0 +1,41 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Sqlite does not support alter column. + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.text('value').nullable().alter(); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + // Sqlite does not support alter column. + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_search', table => { + table.string('value').nullable().alter(); + }); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js b/plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js new file mode 100644 index 0000000000..a90813fe85 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200809202832_add_bootstrap_location.js @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Adds a single 'bootstrap' location that can be used to trigger work in processors. + // This is primarily here to fulfill foreign key constraints. + await knex('locations').insert({ + id: require('uuid').v4(), + type: 'bootstrap', + target: 'bootstrap', + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex('locations') + .where({ + type: 'bootstrap', + target: 'bootstrap', + }) + .del(); +}; diff --git a/plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js b/plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js new file mode 100644 index 0000000000..ea5ba9e58d --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20200923104503_case_insensitivity.js @@ -0,0 +1,32 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex('entities') + .where({ namespace: null }) + .update({ namespace: 'default' }); + await knex('entities_search').update({ + key: knex.raw('LOWER(key)'), + value: knex.raw('LOWER(value)'), + }); +}; + +exports.down = async function down() {}; diff --git a/plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js b/plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js new file mode 100644 index 0000000000..aae1861658 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201005122705_add_entity_full_name.js @@ -0,0 +1,60 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table.text('full_name').nullable(); + }); + + await knex('entities').update({ + full_name: knex.raw( + "LOWER(kind) || ':' || LOWER(COALESCE(namespace, 'default')) || '/' || LOWER(name)", + ), + }); + + // SQLite does not support alter column + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.text('full_name').notNullable().alter(); + }); + } + + await knex.schema.alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['full_name'], 'entities_unique_full_name'); + table.dropUnique([], 'entities_unique_name'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.dropUnique([], 'entities_unique_full_name'); + table.unique(['kind', 'namespace', 'name'], 'entities_unique_name'); + }); + + await knex.schema.alterTable('entities_search', table => { + table.dropColumn('full_name'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js b/plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js new file mode 100644 index 0000000000..a8964efbf6 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201006130744_entity_data_column.js @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table + .text('data') + .nullable() + .comment('The entire JSON data blob of the entity'); + }); + + await knex('entities').update({ + // apiVersion and kind should not contain any JSON unsafe chars, and both + // metadata and spec are already valid serialized JSON + data: knex.raw( + `'{"apiVersion":"' || api_version || '","kind":"' || kind || '","metadata":' || metadata || COALESCE(',"spec":' || spec, '') || '}'`, + ), + }); + + await knex.schema.alterTable('entities', table => { + table.dropColumn('metadata'); + table.dropColumn('spec'); + }); + + // SQLite does not support ALTER COLUMN. + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.text('data').notNullable().alter(); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + table + .text('metadata') + .notNullable() + .comment('The entire metadata JSON blob of the entity'); + table + .text('spec') + .nullable() + .comment('The entire spec JSON blob of the entity'); + table.dropColumn('data'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js b/plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js new file mode 100644 index 0000000000..f40df5f73e --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201006203131_entity_remove_redundant_columns.js @@ -0,0 +1,50 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table.dropColumn('api_version'); + table.dropColumn('kind'); + table.dropColumn('name'); + table.dropColumn('namespace'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + table + .string('api_version') + .notNullable() + .comment('The apiVersion field of the entity'); + table.string('kind').notNullable().comment('The kind field of the entity'); + table + .string('name') + .nullable() + .comment('The metadata.name field of the entity'); + table + .string('namespace') + .nullable() + .comment('The metadata.namespace field of the entity'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js b/plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js new file mode 100644 index 0000000000..77bf0529eb --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201007201501_index_entity_search.js @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities_search', table => { + table.index(['key'], 'entities_search_key'); + table.index(['value'], 'entities_search_value'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities_search', table => { + table.dropIndex('', 'entities_search_key'); + table.dropIndex('', 'entities_search_value'); + }); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js b/plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js new file mode 100644 index 0000000000..85e729f814 --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201019130742_add_relations_table.js @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.createTable('entities_relations', table => { + table.comment('All relations between entities in the catalog'); + table + .uuid('originating_entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .string('source_full_name') + .notNullable() + .comment('The full name of the source entity of the relation'); + table + .string('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .string('target_full_name') + .notNullable() + .comment('The full name of the target entity of the relation'); + + table.primary(['source_full_name', 'type', 'target_full_name']); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.dropTable('entities_relations'); +}; diff --git a/plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js b/plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js new file mode 100644 index 0000000000..9e8198b5eb --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201123205611_relations_table_uniq.js @@ -0,0 +1,93 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client === 'sqlite3') { + // sqlite doesn't support dropPrimary so we recreate it properly instead + await knex.schema.dropTable('entities_relations'); + await knex.schema.createTable('entities_relations', table => { + table.comment('All relations between entities in the catalog'); + table + .uuid('originating_entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .string('source_full_name') + .notNullable() + .comment('The full name of the source entity of the relation'); + table + .string('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .string('target_full_name') + .notNullable() + .comment('The full name of the target entity of the relation'); + table.index('source_full_name', 'source_full_name_idx'); + }); + } else { + await knex.schema.alterTable('entities_relations', table => { + table.dropPrimary(); + table.index('source_full_name', 'source_full_name_idx'); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client === 'sqlite3') { + await knex.schema.dropTable('entities_relations'); + await knex.schema.createTable('entities_relations', table => { + table.comment('All relations between entities in the catalog'); + table + .uuid('originating_entity_id') + .references('id') + .inTable('entities') + .onDelete('CASCADE') + .notNullable() + .comment('The entity that provided the relation'); + table + .string('source_full_name') + .notNullable() + .comment('The full name of the source entity of the relation'); + table + .string('type') + .notNullable() + .comment('The type of the relation between the entities'); + table + .string('target_full_name') + .notNullable() + .comment('The full name of the target entity of the relation'); + + table.primary(['source_full_name', 'type', 'target_full_name']); + }); + } else { + await knex.schema.alterTable('entities_relations', table => { + table.dropIndex([], 'source_full_name_idx'); + table.primary(['source_full_name', 'type', 'target_full_name']); + }); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js b/plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js new file mode 100644 index 0000000000..abb26cd5fc --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201210185851_fk_index.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_relations', table => { + table.index('originating_entity_id', 'originating_entity_id_idx'); + }); + await knex.schema.alterTable('entities_search', table => { + table.index('entity_id', 'entity_id_idx'); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities_relations', table => { + table.dropIndex([], 'originating_entity_id_idx'); + }); + await knex.schema.alterTable('entities_relations', table => { + table.dropIndex([], 'entity_id_idx'); + }); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js b/plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js new file mode 100644 index 0000000000..d924b0414a --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20201230103504_update_log_varchar.js @@ -0,0 +1,73 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client !== 'sqlite3') { + // We actually just want to widen columns, but can't do that while a + // view is dependent on them - so we just reconstruct it exactly as it was + await knex.schema + .raw('DROP VIEW location_update_log_latest;') + .alterTable('location_update_log', table => { + table.text('message').alter(); + table.text('entity_name').nullable().alter(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema + .raw('DROP VIEW location_update_log_latest;') + .alterTable('location_update_log', table => { + table.string('message').alter(); + table.string('entity_name').nullable().alter(); + }).raw(` + CREATE VIEW location_update_log_latest AS + SELECT t1.* FROM location_update_log t1 + JOIN + ( + SELECT location_id, MAX(id) AS MAXID + FROM location_update_log + GROUP BY location_id + ) t2 + ON t1.location_id = t2.location_id + AND t1.id = t2.MAXID + GROUP BY t1.location_id, t1.id + ORDER BY created_at DESC; + `); + } +}; diff --git a/plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js b/plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js new file mode 100644 index 0000000000..ccfb1faffb --- /dev/null +++ b/plugins/catalog-backend/migrationsv2/20210209121210_locations_fk_index.js @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.index('location_id', 'entity_location_id_idx'); + }); + await knex.schema.alterTable('location_update_log', table => { + table.index('location_id', 'update_log_location_id_idx'); + }); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable('entities', table => { + table.dropIndex([], 'entity_location_id_idx'); + }); + await knex.schema.alterTable('location_update_log', table => { + table.dropIndex([], 'update_log_location_id_idx'); + }); + } +}; diff --git a/plugins/catalog-backend/src/next/database/DatabaseManager.ts b/plugins/catalog-backend/src/next/database/DatabaseManager.ts index 4c9e45950f..f660f73ecb 100644 --- a/plugins/catalog-backend/src/next/database/DatabaseManager.ts +++ b/plugins/catalog-backend/src/next/database/DatabaseManager.ts @@ -20,7 +20,6 @@ import { v4 as uuidv4 } from 'uuid'; import { Logger } from 'winston'; import { CommonDatabase } from '../../database/CommonDatabase'; import { Database } from '../../database/types'; -import fs from 'fs-extra'; export type CreateDatabaseOptions = { logger: Logger; @@ -35,16 +34,10 @@ export class DatabaseManager { knex: Knex, options: Partial<CreateDatabaseOptions> = {}, ): Promise<Database> { - const allMigrations = resolvePackagePath( - '@backstage/plugin-catalog-backend', - 'migrations', - ); - const migrationsDir = resolvePackagePath( '@backstage/plugin-catalog-backend', 'migrationsv2', ); - await fs.copy(allMigrations, migrationsDir); await knex.migrate.latest({ directory: migrationsDir, @@ -79,14 +72,6 @@ export class DatabaseManager { public static async createTestDatabaseConnection(): Promise<Knex> { const config: Knex.Config<any> = { - /* - client: 'pg', - connection: { - host: 'localhost', - user: 'postgres', - password: 'postgres', - }, - */ client: 'sqlite3', connection: ':memory:', useNullAsDefault: true, From aad89f55460c1d9f96165d677e188edd7d304daf Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 15:43:22 +0200 Subject: [PATCH 308/462] Add configLocationProvider and provider identifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/ConfigLocationProvider.ts | 49 +++++++++++++++++++ .../next/DefaultCatalogProcessingEngine.ts | 9 ++-- .../src/next/DefaultLocationStore.ts | 4 ++ .../src/next/NextCatalogBuilder.ts | 7 +-- plugins/catalog-backend/src/next/types.ts | 1 + 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 plugins/catalog-backend/src/next/ConfigLocationProvider.ts diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts new file mode 100644 index 0000000000..5b93fcfd98 --- /dev/null +++ b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EntityProviderConnection, EntityProvider } from './types'; +import path from 'path'; +import { Config } from '@backstage/config'; +import { locationSpecToLocationEntity } from './util'; + +export class ConfigLocationProvider implements EntityProvider { + private connection: EntityProviderConnection | undefined; + + constructor(private readonly config: Config) {} + + getProviderName(): string { + return 'ConfigLocationProvider'; + } + + async connect(connection: EntityProviderConnection): Promise<void> { + this.connection = connection; + + const locationConfigs = + this.config.getOptionalConfigArray('catalog.locations') ?? []; + + const entities = locationConfigs.map(location => + locationSpecToLocationEntity({ + type: location.getString('type'), + target: path.resolve(location.getString('target')), + }), + ); + + await this.connection.applyMutation({ + type: 'full', + entities, + }); + } +} diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index b71b2c1045..1934b0aea7 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -68,9 +68,12 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - // TODO: this ID should be some form of identifier for the EntityProvider - const id = 'databaseProvider'; - provider.connect(new Connection({ stateManager: this.stateManager, id })); + provider.connect( + new Connection({ + stateManager: this.stateManager, + id: provider.getProviderName(), + }), + ); } this.running = true; diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index 40870cff7b..a56e5d1585 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -30,6 +30,10 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { constructor(private readonly db: Database) {} + getProviderName(): string { + return 'DefaultLocationStore'; + } + createLocation(spec: LocationSpec): Promise<Location> { return this.db.transaction(async tx => { // TODO: id should really be type and target combined and not a uuid. diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index d720bd331a..0699a13f58 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -50,6 +50,7 @@ import { GithubDiscoveryProcessor, GithubOrgReaderProcessor, LdapOrgReaderProcessor, + LocationEntityProcessor, MicrosoftGraphOrgReaderProcessor, PlaceholderProcessor, PlaceholderResolver, @@ -73,6 +74,7 @@ import { CatalogProcessingEngine } from '../next/types'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; import { CommonDatabase } from '../database/CommonDatabase'; +import { ConfigLocationProvider } from './ConfigLocationProvider'; export type CatalogEnvironment = { logger: Logger; @@ -272,9 +274,10 @@ export class NextCatalogBuilder { const locationStore = new DefaultLocationStore(db); const stitcher = new Stitcher(dbClient, logger); + const configLocationProvider = new ConfigLocationProvider(config); const processingEngine = new DefaultCatalogProcessingEngine( logger, - [locationStore], // entityproviders + [locationStore, configLocationProvider], stateManager, orchestrator, stitcher, @@ -322,7 +325,6 @@ export class NextCatalogBuilder { // These are always there no matter what const processors: CatalogProcessor[] = [ - StaticLocationProcessor.fromConfig(config), new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }), new BuiltinKindsEntityProcessor(), ]; @@ -338,7 +340,6 @@ export class NextCatalogBuilder { MicrosoftGraphOrgReaderProcessor.fromConfig(config, { logger }), new UrlReaderProcessor({ reader, logger }), CodeOwnersProcessor.fromConfig(config, { logger, reader }), - // new LocationEntityProcessor({ integrations }), new AnnotateLocationEntityProcessor({ integrations }), ); } diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index ef3bab797b..e0616fb336 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -65,6 +65,7 @@ export interface EntityProviderConnection { } export interface EntityProvider { + getProviderName(): string; connect(connection: EntityProviderConnection): Promise<void>; } From b7200a4b70334521fd391e58c4f75f33e3339e13 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 26 Apr 2021 16:53:44 +0200 Subject: [PATCH 309/462] chore: remove unused imports Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/NextCatalogBuilder.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 0699a13f58..24b763a098 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -50,11 +50,9 @@ import { GithubDiscoveryProcessor, GithubOrgReaderProcessor, LdapOrgReaderProcessor, - LocationEntityProcessor, MicrosoftGraphOrgReaderProcessor, PlaceholderProcessor, PlaceholderResolver, - StaticLocationProcessor, UrlReaderProcessor, } from '../ingestion'; import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer'; From 72becbd2cc5fa95246da21b234c4f916e2a8cb9b Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 14:16:49 +0200 Subject: [PATCH 310/462] catalog-backend: Add ConfigLocationProvider tests Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/ConfigLocationProvider.test.ts | 67 +++++++++++++++++++ .../src/next/ConfigLocationProvider.ts | 14 ++-- 2 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts b/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts new file mode 100644 index 0000000000..9aaba13c48 --- /dev/null +++ b/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigLocationProvider } from './ConfigLocationProvider'; +import { EntityProviderConnection } from './types'; +import { ConfigReader } from '@backstage/config'; +import { resolvePackagePath } from '@backstage/backend-common'; +import path from 'path'; + +describe('Config Location Provider', () => { + it('should apply mutation with the correct paths in the config', async () => { + const mockConfig = new ConfigReader({ + catalog: { + locations: [ + { type: 'file', target: './lols.yaml' }, + { type: 'url', target: 'https://github.com/backstage/backstage' }, + ], + }, + }); + + const mockConnection = ({ + applyMutation: jest.fn(), + } as unknown) as EntityProviderConnection; + const locationProvider = new ConfigLocationProvider(mockConfig); + + await locationProvider.connect(mockConnection); + + expect(mockConnection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: path.join( + resolvePackagePath('@backstage/plugin-catalog-backend'), + './lols.yaml', + ), + type: 'file', + }, + }), + ]), + }); + expect(mockConnection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: 'https://github.com/backstage/backstage', + type: 'url', + }, + }), + ]), + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts index 5b93fcfd98..8a65487df1 100644 --- a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts +++ b/plugins/catalog-backend/src/next/ConfigLocationProvider.ts @@ -34,12 +34,14 @@ export class ConfigLocationProvider implements EntityProvider { const locationConfigs = this.config.getOptionalConfigArray('catalog.locations') ?? []; - const entities = locationConfigs.map(location => - locationSpecToLocationEntity({ - type: location.getString('type'), - target: path.resolve(location.getString('target')), - }), - ); + const entities = locationConfigs.map(location => { + const type = location.getString('type'); + const target = location.getString('target'); + return locationSpecToLocationEntity({ + type, + target: type === 'file' ? path.resolve(target) : target, + }); + }); await this.connection.applyMutation({ type: 'full', From bbf0878afc247917a82121328b01102fbd87a871 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 18:28:55 +0200 Subject: [PATCH 311/462] WIP tests for DefaultProcessingDatabase Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index f67b8603db..a5c1e56cff 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -429,4 +429,66 @@ describe('Default Processing Database', () => { ).toBeFalsy(); }); }); + + describe('updateProcessedEntity', () => { + it('should throw if the entity does not exist', async () => { + await processingDatabase.transaction(async tx => { + await expect( + processingDatabase.updateProcessedEntity(tx, { + id: '9', + processedEntity: { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + deferredEntities: [], + relations: [], + }), + ).rejects.toThrow('Processing state not found for 9'); + }); + }); + + it('should update a processed entity', async () => { + await db<DbRefreshStateRow>('refresh_state').insert({ + entity_id: '123', + entity_ref: 'Component:default/wacka', + unprocessed_entity: '', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + + const deferredEntity = { + apiVersion: '1.0.0', + metadata: { + name: 'deferred', + }, + kind: 'Location', + } as Entity; + + await processingDatabase.transaction(async tx => { + await processingDatabase.updateProcessedEntity(tx, { + id: '123', + processedEntity: { + apiVersion: '1.0.0', + metadata: { + name: 'new-root', + }, + kind: 'Location', + } as Entity, + deferredEntities: [deferredEntity], + relations: [], + }); + }); + + console.log( + await db<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: 'deferred' }) + .select(), + ); + expect(1).toBeDefined(); + }); + }); }); From c6af78b93b0bc09c19f5d87d23a764eb01f7e7c4 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 18:30:00 +0200 Subject: [PATCH 312/462] Combine stitiching queries Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/Stitcher.ts | 118 ++++++++++++++----- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 57f5ae9167..04a8ab8cfc 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -26,6 +26,14 @@ import { import { Entity, parseEntityRef } from '@backstage/catalog-model'; import { createHash } from 'crypto'; import stableStringify from 'fast-json-stable-stringify'; +import { buildEntitySearch } from '../database/search'; +import { DbEntitiesSearchRow } from '../database/types'; + +// The number of items that are sent per batch to the database layer, when +// doing .batchInsert calls to knex. This needs to be low enough to not cause +// errors in the underlying engine due to exceeding query limits, but large +// enough to get the speed benefits. +const BATCH_SIZE = 50; export type DbFinalEntitiesRow = { entity_id: string; @@ -49,64 +57,114 @@ export class Stitcher { for (const entityRef of entityRefs) { await this.transaction(async txOpaque => { const tx = txOpaque as Knex.Transaction; - const [result] = await tx<DbRefreshStateRow>('refresh_state') - .select('entity_id', 'processed_entity') - .where({ entity_ref: entityRef }); - if (!result) { + const result: Array<{ + entityId: string; + processedEntity?: string; + errors: string; + incomingReferenceCount: string | number; + previousEtag?: string; + relationType?: string; + relationTarget?: string; + }> = await tx + .with('incoming_references', function incomingReferences(builder) { + return builder + .from('refresh_state_references') + .where({ target_entity_ref: entityRef }) + .count({ count: '*' }); + }) + .select({ + entityId: 'refresh_state.entity_id', + processedEntity: 'refresh_state.processed_entity', + errors: 'refresh_state.errors', + incomingReferenceCount: 'incoming_references.count', + previousEtag: 'final_entities.etag', + relationType: 'relations.type', + relationTarget: 'relations.target_entity_ref', + }) + .from('refresh_state') + .leftJoin('incoming_references', {}) + .leftOuterJoin('final_entities', { + 'final_entities.entity_id': 'refresh_state.entity_id', + }) + .leftOuterJoin('relations', { + 'relations.source_entity_ref': 'refresh_state.entity_ref', + }) + .where({ 'refresh_state.entity_ref': entityRef }); + + if (!result.length) { this.logger.debug( `Unable to stitch ${entityRef}, item does not exist in refresh state table`, ); return; - } else if (!result.processed_entity) { + } + + const { + entityId, + processedEntity, + errors, + incomingReferenceCount, + previousEtag, + } = result[0]; + + if (!processedEntity) { this.logger.debug( `Unable to stitch ${entityRef}, the entity has not yet been processed`, ); return; } - const entity: Entity = JSON.parse(result.processed_entity); + const entity = JSON.parse(processedEntity) as Entity; + const isOrphan = Number(incomingReferenceCount) === 0; - const entityId = entity?.metadata?.uid; - if (!entityId) { - this.logger.error(`missing ID in entity ${JSON.stringify(entity)}`); - return; - } - - const [reference_count_result] = await tx<DbRefreshStateReferencesRow>( - 'refresh_state_references', - ) - .where({ target_entity_ref: entityRef }) - .count({ reference_count: 'target_entity_ref' }); - - if (Number(reference_count_result.reference_count) === 0) { - this.logger.debug(`${entityRef} is orphan`); + if (isOrphan) { + this.logger.debug(`${entityRef} is an orphan`); entity.metadata.annotations = { ...entity.metadata.annotations, ['backstage.io/orphan']: 'true', }; } - const relationResults = await tx<DbRelationsRow>('relations') - .where({ source_entity_ref: entityRef }) - .select(); - - // TODO: entityRef is lower case and should be uppercase in the final result. - entity.relations = relationResults.map(relation => ({ - type: relation.type, - target: parseEntityRef(relation.target_entity_ref), - })); + // TODO: entityRef is lower case and should be uppercase in the final result + entity.relations = result + .filter(row => row.relationType) + .map(row => ({ + type: row.relationType!, + target: parseEntityRef(row.relationTarget!), + })); entity.metadata.generation = 1; + + // If the output entity was actually not changed, just abort const etag = generateEntityEtag(entity); + if (etag === previousEtag) { + console.log(`Skipped stitching of ${entityRef}, no changes`); + return; + } + entity.metadata.etag = etag; + await tx<DbFinalEntitiesRow>('final_entities') .insert({ - finalized_entity: JSON.stringify(entity), entity_id: entityId, + finalized_entity: JSON.stringify(entity), etag, }) .onConflict('entity_id') .merge(['finalized_entity', 'etag']); + + try { + const entries = buildEntitySearch(entityId, entity); + await tx<DbEntitiesSearchRow>('search') + .where({ entity_id: entityId }) + .delete(); + await tx.batchInsert('search', entries, BATCH_SIZE); + } catch (e) { + this.logger.debug( + `Failed to write search entries for ${entityId}`, + e, + ); + // intentionally ignored + } }); } } From 5c60c66ff508bae37ccfcb597d5e6e6c030a68aa Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 27 Apr 2021 18:30:22 +0200 Subject: [PATCH 313/462] Create search table Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../20210302150147_refresh_state.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 2afeda02c0..755a645894 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -154,6 +154,28 @@ exports.up = async function up(knex) { table.index('source_entity_ref', 'relations_source_entity_ref_idx'); table.index('originating_entity_id', 'relations_source_entity_id_idx'); }); + + await knex.schema.createTable('search', table => { + table.comment( + 'Flattened key-values from the entities, used for quick filtering', + ); + table + .uuid('entity_id') + .references('entity_id') + .inTable('refresh_state') + .onDelete('CASCADE') + .comment('The entity that matches this key/value'); + table + .string('key') + .notNullable() + .comment('A key that occurs in the entity'); + table + .string('value') + .nullable() + .comment('The corresponding value to match on'); + table.index(['key'], 'search_key_idx'); + table.index(['value'], 'search_value_idx'); + }); }; /** @@ -177,6 +199,12 @@ exports.down = async function down(knex) { table.index('source_entity_ref', 'relations_source_entity_ref_idx'); table.index('originating_entity_id', 'relations_source_entity_id_idx'); }); + await knex.schema.alterTable('search', table => { + table.dropIndex([], 'search_key_idx'); + table.dropIndex([], 'search_value_idx'); + }); + + await knex.schema.dropTable('search'); await knex.schema.dropTable('final_entities'); await knex.schema.dropTable('relations'); await knex.schema.dropTable('references'); From d798708943c6b851a96de8837653040eaad5a757 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 27 Apr 2021 21:23:35 +0200 Subject: [PATCH 314/462] chore(tests): Added some more tests for DefaultLocationStore and fixing migration so it will run properly on PG Signed-off-by: blam <ben@blam.sh> --- .../20210302150147_refresh_state.js | 2 +- .../src/next/DefaultLocationStore.test.ts | 146 ++++++++++++++++++ .../src/next/DefaultLocationStore.ts | 26 ++-- 3 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 plugins/catalog-backend/src/next/DefaultLocationStore.test.ts diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 755a645894..bbaf4820cd 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -160,7 +160,7 @@ exports.up = async function up(knex) { 'Flattened key-values from the entities, used for quick filtering', ); table - .uuid('entity_id') + .text('entity_id') .references('entity_id') .inTable('refresh_state') .onDelete('CASCADE') diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts new file mode 100644 index 0000000000..be20179e9a --- /dev/null +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -0,0 +1,146 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { DatabaseManager } from './database/DatabaseManager'; +import { DefaultLocationStore } from './DefaultLocationStore'; +import { v4 } from 'uuid'; + +describe('Default Location Store', () => { + const createLocationStore = async () => { + const db = await DatabaseManager.createTestDatabase(); + const connection = { applyMutation: jest.fn() }; + const store = new DefaultLocationStore(db); + await store.connect(connection); + return { store, connection }; + }; + + it('should do a full sync with the locations on connect', async () => { + const { connection } = await createLocationStore(); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: [], + }); + }); + + describe('listLocations', () => { + it('lists empty locations when there is no locations', async () => { + const { store } = await createLocationStore(); + + expect(await store.listLocations()).toEqual([]); + }); + + it('lists locations that are added to the db', async () => { + const { store } = await createLocationStore(); + + await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + const listLocations = await store.listLocations(); + + expect(listLocations).toHaveLength(1); + expect(listLocations).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }), + ]), + ); + }); + }); + + describe('createLocation', () => { + it('throws when the location already exists', async () => { + const { store } = await createLocationStore(); + const spec = { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }; + await store.createLocation(spec); + + await expect(() => store.createLocation(spec)).rejects.toThrow( + new RegExp(`Location ${spec.type}:${spec.target} already exists`), + ); + }); + + it('calls apply mutation when adding a new location', async () => { + const { store, connection } = await createLocationStore(); + + await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + removed: [], + added: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), + }); + }); + }); + + describe('deleteLocation', () => { + it('throws if the location does not exist', async () => { + const { store } = await createLocationStore(); + + const id = v4(); + + await expect(() => store.deleteLocation(id)).rejects.toThrow( + new RegExp(`Found no location with ID ${id}`), + ); + }); + + it('calls apply mutation when adding a new location', async () => { + const { store, connection } = await createLocationStore(); + + const location = await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + await store.deleteLocation(location.id); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), + }); + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index a56e5d1585..28db3790b6 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -34,10 +34,8 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return 'DefaultLocationStore'; } - createLocation(spec: LocationSpec): Promise<Location> { + async createLocation(spec: LocationSpec): Promise<Location> { return this.db.transaction(async tx => { - // TODO: id should really be type and target combined and not a uuid. - // Attempt to find a previous location matching the spec const previousLocations = await this.listLocations(); const previousLocation = previousLocations.some( @@ -50,6 +48,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { ); } + // TODO: id should really be type and target combined and not a uuid. const location = await this.db.addLocation(tx, { id: uuidv4(), type: spec.type, @@ -68,11 +67,17 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async listLocations(): Promise<Location[]> { const dbLocations = await this.db.locations(); - return dbLocations.map(item => ({ - id: item.id, - target: item.target, - type: item.type, - })); + return ( + dbLocations + // TODO(blam): We should create a mutation to remove this location for everyone + // eventually when it's all done and dusted + .filter(({ type }) => type !== 'bootstrap') + .map(item => ({ + id: item.id, + target: item.target, + type: item.type, + })) + ); } getLocation(id: string): Promise<Location> { @@ -86,9 +91,6 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return this.db.transaction(async tx => { const location = await this.db.location(id); - if (!location) { - throw new ConflictError(`No location found with id: ${id}`); - } await this.db.removeLocation(tx, id); await this.connection.applyMutation({ type: 'delta', @@ -108,7 +110,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; - const locations = await this.db.locations(); + const locations = await this.listLocations(); const entities = locations.map(location => { return locationSpecToLocationEntity(location); }); From a60c2d9f8f4f3dfbb529e10ddaf7ab0679ee7772 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Wed, 28 Apr 2021 09:18:35 +0200 Subject: [PATCH 315/462] Update processed entity tests Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index a5c1e56cff..d76bd74260 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -19,10 +19,11 @@ import { Knex } from 'knex'; import { DbRefreshStateReferencesRow, DbRefreshStateRow, + DbRelationsRow, DefaultProcessingDatabase, } from './DefaultProcessingDatabase'; -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityRelationSpec } from '@backstage/catalog-model'; import * as uuid from 'uuid'; import { getVoidLogger } from '@backstage/backend-common'; @@ -452,8 +453,8 @@ describe('Default Processing Database', () => { it('should update a processed entity', async () => { await db<DbRefreshStateRow>('refresh_state').insert({ - entity_id: '123', - entity_ref: 'Component:default/wacka', + entity_id: '321', + entity_ref: 'location:default/new-root', unprocessed_entity: '', errors: '', next_update_at: 'now()', @@ -468,9 +469,23 @@ describe('Default Processing Database', () => { kind: 'Location', } as Entity; + const relation: EntityRelationSpec = { + source: { + kind: 'Component', + namespace: 'Default', + name: 'foo', + }, + target: { + kind: 'Component', + namespace: 'Default', + name: 'foo', + }, + type: 'url', + }; + await processingDatabase.transaction(async tx => { await processingDatabase.updateProcessedEntity(tx, { - id: '123', + id: '321', processedEntity: { apiVersion: '1.0.0', metadata: { @@ -479,16 +494,24 @@ describe('Default Processing Database', () => { kind: 'Location', } as Entity, deferredEntities: [deferredEntity], - relations: [], + relations: [relation], }); }); - console.log( - await db<DbRefreshStateRow>('refresh_state') - .where({ entity_ref: 'deferred' }) - .select(), - ); - expect(1).toBeDefined(); + const deferredResult = await db<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: 'location:default/deferred' }) + .select(); + expect(deferredResult.length).toBe(1); + + const [relations] = await db<DbRelationsRow>('relations') + .where({ originating_entity_id: '321' }) + .select(); + expect(relations).toEqual({ + originating_entity_id: '321', + source_entity_ref: 'component:default/foo', + type: 'url', + target_entity_ref: 'component:default/foo', + }); }); }); }); From 35b3246116ee756abeb27760073c9e5561f046c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 09:18:36 +0200 Subject: [PATCH 316/462] update the stitcher including search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../20210302150147_refresh_state.js | 7 +- .../catalog-backend/src/next/Stitcher.test.ts | 205 ++++++++++++++++++ plugins/catalog-backend/src/next/Stitcher.ts | 59 ++--- .../catalog-backend/src/next/search.test.ts | 160 ++++++++++++++ plugins/catalog-backend/src/next/search.ts | 191 ++++++++++++++++ plugins/catalog-backend/src/next/types.ts | 1 + 6 files changed, 592 insertions(+), 31 deletions(-) create mode 100644 plugins/catalog-backend/src/next/Stitcher.test.ts create mode 100644 plugins/catalog-backend/src/next/search.test.ts create mode 100644 plugins/catalog-backend/src/next/search.ts diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index bbaf4820cd..4d2c30f194 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -33,7 +33,6 @@ exports.up = async function up(knex) { ); table .text('entity_ref') - .unique() .notNullable() .comment('A reference to the entity that the refresh state is tied to'); table @@ -59,13 +58,14 @@ exports.up = async function up(knex) { .notNullable() .comment('JSON array containing all errors related to entity'); table - .dateTime('next_update_at') // TOOD: timezone or change to epoch-millis or similar + .dateTime('next_update_at') // TODO: timezone or change to epoch-millis or similar .notNullable() .comment('Timestamp of when entity should be updated'); table - .dateTime('last_discovery_at') // TOOD: timezone or change to epoch-millis or similar + .dateTime('last_discovery_at') // TODO: timezone or change to epoch-millis or similar .notNullable() .comment('The last timestamp of which this entity was discovered'); + table.unique(['entity_ref'], 'refresh_state_entity_ref_uniq'); table.index('entity_id', 'refresh_state_entity_id_idx'); table.index('entity_ref', 'refresh_state_entity_ref_idx'); table.index('next_update_at', 'refresh_state_next_update_at_idx'); @@ -188,6 +188,7 @@ exports.down = async function down(knex) { table.dropIndex([], 'refresh_state_references_target_entity_id_idx'); }); await knex.schema.alterTable('refresh_state', table => { + table.dropUnique([], 'refresh_state_entity_ref_uniq'); table.dropIndex([], 'refresh_state_entity_id_idx'); table.dropIndex([], 'refresh_state_entity_ref_idx'); table.dropIndex([], 'refresh_state_next_update_at_idx'); diff --git a/plugins/catalog-backend/src/next/Stitcher.test.ts b/plugins/catalog-backend/src/next/Stitcher.test.ts new file mode 100644 index 0000000000..327d922c07 --- /dev/null +++ b/plugins/catalog-backend/src/next/Stitcher.test.ts @@ -0,0 +1,205 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { Knex } from 'knex'; +import { DatabaseManager } from './database/DatabaseManager'; +import { + DbRefreshStateReferencesRow, + DbRefreshStateRow, + DbRelationsRow, +} from './database/DefaultProcessingDatabase'; +import { DbSearchRow } from './search'; +import { DbFinalEntitiesRow, Stitcher } from './Stitcher'; + +describe('Stitcher', () => { + let db: Knex; + const logger = getVoidLogger(); + + beforeEach(async () => { + db = await DatabaseManager.createTestDatabaseConnection(); + await DatabaseManager.createDatabase(db); + }); + + it('runs the happy path', async () => { + const stitcher = new Stitcher(db, logger); + + await db.transaction(async tx => { + await tx<DbRefreshStateRow>('refresh_state').insert([ + { + entity_id: 'my-id', + entity_ref: 'k:ns/n', + unprocessed_entity: JSON.stringify({}), + processed_entity: JSON.stringify({ + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + }, + spec: { + k: 'v', + }, + }), + errors: '[]', + next_update_at: tx.fn.now(), + last_discovery_at: tx.fn.now(), + }, + ]); + await tx<DbRefreshStateReferencesRow>('refresh_state_references').insert([ + { source_key: 'a', target_entity_ref: 'k:ns/n' }, + ]); + await tx<DbRelationsRow>('relations').insert([ + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/other', + }, + ]); + }); + + await stitcher.stitch(new Set(['k:ns/n'])); + + let firstEtag: string; + await db.transaction(async tx => { + const entities = await tx<DbFinalEntitiesRow>('final_entities'); + + expect(entities.length).toBe(1); + const entity = JSON.parse(entities[0].finalized_entity); + expect(entity).toEqual({ + relations: [ + { + type: 'looksAt', + target: { + kind: 'k', + namespace: 'ns', + name: 'other', + }, + }, + ], + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + etag: expect.any(String), + generation: 1, + uid: 'my-id', + }, + spec: { + k: 'v', + }, + }); + + firstEtag = entity.metadata.etag; + + const search = await tx<DbSearchRow>('search'); + expect(search).toEqual( + expect.arrayContaining([ + { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/other' }, + { entity_id: 'my-id', key: 'apiversion', value: 'a' }, + { entity_id: 'my-id', key: 'kind', value: 'k' }, + { entity_id: 'my-id', key: 'metadata.name', value: 'n' }, + { entity_id: 'my-id', key: 'metadata.namespace', value: 'ns' }, + { entity_id: 'my-id', key: 'metadata.uid', value: 'my-id' }, + { entity_id: 'my-id', key: 'spec.k', value: 'v' }, + ]), + ); + }); + + // Re-stitch without any changes + await stitcher.stitch(new Set(['k:ns/n'])); + + await db.transaction(async tx => { + const entities = await tx<DbFinalEntitiesRow>('final_entities'); + expect(entities.length).toBe(1); + const entity = JSON.parse(entities[0].finalized_entity); + expect(entities[0].etag).toEqual(firstEtag); + expect(entity.metadata.etag).toEqual(firstEtag); + }); + + // Now add one more relation and re-stitch + await db.transaction(async tx => { + await tx<DbRelationsRow>('relations').insert([ + { + originating_entity_id: 'my-id', + source_entity_ref: 'k:ns/n', + type: 'looksAt', + target_entity_ref: 'k:ns/third', + }, + ]); + }); + + await stitcher.stitch(new Set(['k:ns/n'])); + + await db.transaction(async tx => { + const entities = await tx<DbFinalEntitiesRow>('final_entities'); + + expect(entities.length).toBe(1); + const entity = JSON.parse(entities[0].finalized_entity); + expect(entity).toEqual({ + relations: expect.arrayContaining([ + { + type: 'looksAt', + target: { + kind: 'k', + namespace: 'ns', + name: 'other', + }, + }, + { + type: 'looksAt', + target: { + kind: 'k', + namespace: 'ns', + name: 'third', + }, + }, + ]), + apiVersion: 'a', + kind: 'k', + metadata: { + name: 'n', + namespace: 'ns', + etag: expect.any(String), + generation: 1, + uid: 'my-id', + }, + spec: { + k: 'v', + }, + }); + + expect(entities[0].etag).not.toEqual(firstEtag); + expect(entities[0].etag).toEqual(entity.metadata.etag); + + const search = await tx<DbSearchRow>('search'); + expect(search).toEqual( + expect.arrayContaining([ + { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/other' }, + { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/third' }, + { entity_id: 'my-id', key: 'apiversion', value: 'a' }, + { entity_id: 'my-id', key: 'kind', value: 'k' }, + { entity_id: 'my-id', key: 'metadata.name', value: 'n' }, + { entity_id: 'my-id', key: 'metadata.namespace', value: 'ns' }, + { entity_id: 'my-id', key: 'metadata.uid', value: 'my-id' }, + { entity_id: 'my-id', key: 'spec.k', value: 'v' }, + ]), + ); + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index 04a8ab8cfc..cd9220e934 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -14,20 +14,14 @@ * limitations under the License. */ +import { Entity, parseEntityRef } from '@backstage/catalog-model'; +import { ConflictError } from '@backstage/errors'; +import { createHash } from 'crypto'; +import stableStringify from 'fast-json-stable-stringify'; import { Knex } from 'knex'; import { Logger } from 'winston'; import { Transaction } from '../database'; -import { ConflictError } from '@backstage/errors'; -import { - DbRefreshStateReferencesRow, - DbRefreshStateRow, - DbRelationsRow, -} from './database/DefaultProcessingDatabase'; -import { Entity, parseEntityRef } from '@backstage/catalog-model'; -import { createHash } from 'crypto'; -import stableStringify from 'fast-json-stable-stringify'; -import { buildEntitySearch } from '../database/search'; -import { DbEntitiesSearchRow } from '../database/types'; +import { buildEntitySearch, DbSearchRow } from './search'; // The number of items that are sent per batch to the database layer, when // doing .batchInsert calls to knex. This needs to be low enough to not cause @@ -58,6 +52,13 @@ export class Stitcher { await this.transaction(async txOpaque => { const tx = txOpaque as Knex.Transaction; + // Selecting from refresh_state and final_entities should yield exactly + // one row (except in abnormal cases where the stitch was invoked for + // something that didn't exist at all, in which case it's zero rows). + // The join with the temporary incoming_references still gives one row. + // The only result set "expanding" join is the one with relations, so + // the output should be at least one row (if zero or one relations were + // found), or at most the same number of rows as relations. const result: Array<{ entityId: string; processedEntity?: string; @@ -90,8 +91,14 @@ export class Stitcher { .leftOuterJoin('relations', { 'relations.source_entity_ref': 'refresh_state.entity_ref', }) - .where({ 'refresh_state.entity_ref': entityRef }); + .where({ 'refresh_state.entity_ref': entityRef }) + .orderBy('relationType', 'asc') + .orderBy('relationTarget', 'asc'); + // If there were no rows returned, it would mean that there was no + // matching row even in the refresh_state. This can happen for example + // if we emit a relation to something that hasn't been ingested yet. + // It's safe to ignore this stitch attempt in that case. if (!result.length) { this.logger.debug( `Unable to stitch ${entityRef}, item does not exist in refresh state table`, @@ -102,11 +109,15 @@ export class Stitcher { const { entityId, processedEntity, - errors, + // errors, incomingReferenceCount, previousEtag, } = result[0]; + // If there was no processed entity in place, the target hasn't been + // through the processing steps yet. It's safe to ignore this stitch + // attempt in that case, since another stitch will be triggered when + // that processing has finished. if (!processedEntity) { this.logger.debug( `Unable to stitch ${entityRef}, the entity has not yet been processed`, @@ -114,6 +125,7 @@ export class Stitcher { return; } + // Grab the processed entity and stitch all of the relevant data into it const entity = JSON.parse(processedEntity) as Entity; const isOrphan = Number(incomingReferenceCount) === 0; @@ -132,15 +144,16 @@ export class Stitcher { type: row.relationType!, target: parseEntityRef(row.relationTarget!), })); - entity.metadata.generation = 1; // If the output entity was actually not changed, just abort const etag = generateEntityEtag(entity); if (etag === previousEtag) { - console.log(`Skipped stitching of ${entityRef}, no changes`); + this.logger.debug(`Skipped stitching of ${entityRef}, no changes`); return; } + entity.metadata.uid = entityId; + entity.metadata.generation = 1; entity.metadata.etag = etag; await tx<DbFinalEntitiesRow>('final_entities') @@ -152,19 +165,9 @@ export class Stitcher { .onConflict('entity_id') .merge(['finalized_entity', 'etag']); - try { - const entries = buildEntitySearch(entityId, entity); - await tx<DbEntitiesSearchRow>('search') - .where({ entity_id: entityId }) - .delete(); - await tx.batchInsert('search', entries, BATCH_SIZE); - } catch (e) { - this.logger.debug( - `Failed to write search entries for ${entityId}`, - e, - ); - // intentionally ignored - } + const searchEntries = buildEntitySearch(entityId, entity); + await tx<DbSearchRow>('search').where({ entity_id: entityId }).delete(); + await tx.batchInsert('search', searchEntries, BATCH_SIZE); }); } } diff --git a/plugins/catalog-backend/src/next/search.test.ts b/plugins/catalog-backend/src/next/search.test.ts new file mode 100644 index 0000000000..be9a98fe69 --- /dev/null +++ b/plugins/catalog-backend/src/next/search.test.ts @@ -0,0 +1,160 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; +import { buildEntitySearch, mapToRows, traverse } from './search'; + +describe('search', () => { + describe('traverse', () => { + it('expands lists of strings to several rows', () => { + const input = { a: ['b', 'c', 'd'] }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'a', value: 'b' }, + { key: 'a.b', value: true }, + { key: 'a', value: 'c' }, + { key: 'a.c', value: true }, + { key: 'a', value: 'd' }, + { key: 'a.d', value: true }, + ]); + }); + + it('expands objects', () => { + const input = { a: { b: { c: 'd' }, e: 'f' } }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'a.b.c', value: 'd' }, + { key: 'a.e', value: 'f' }, + ]); + }); + + it('expands list of objects', () => { + const input = { root: { list: [{ a: 1 }, { a: 2 }] } }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'root.list.a', value: 1 }, + { key: 'root.list.a', value: 2 }, + ]); + }); + + it('skips over special keys', () => { + const input = { + state: { x: 1 }, + relations: [{ y: 2 }], + a: 'a', + metadata: { + b: 'b', + name: 'name', + namespace: 'namespace', + uid: 'uid', + etag: 'etag', + generation: 'generation', + c: 'c', + }, + d: 'd', + }; + const output = traverse(input); + expect(output).toEqual([ + { key: 'a', value: 'a' }, + { key: 'metadata.b', value: 'b' }, + { key: 'metadata.c', value: 'c' }, + { key: 'd', value: 'd' }, + ]); + }); + }); + + describe('mapToRows', () => { + it('converts base types to strings or null', () => { + const input = [ + { key: 'a', value: true }, + { key: 'b', value: false }, + { key: 'c', value: 7 }, + { key: 'd', value: 'string' }, + { key: 'e', value: null }, + { key: 'f', value: undefined }, + ]; + const output = mapToRows(input, 'eid'); + expect(output).toEqual([ + { entity_id: 'eid', key: 'a', value: 'true' }, + { entity_id: 'eid', key: 'b', value: 'false' }, + { entity_id: 'eid', key: 'c', value: '7' }, + { entity_id: 'eid', key: 'd', value: 'string' }, + { entity_id: 'eid', key: 'e', value: null }, + { entity_id: 'eid', key: 'f', value: null }, + ]); + }); + + it('emits lowercase version of keys and values', () => { + const input = [{ key: 'fOo', value: 'BaR' }]; + const output = mapToRows(input, 'eid'); + expect(output).toEqual([{ entity_id: 'eid', key: 'foo', value: 'bar' }]); + }); + + it('skips very large values', () => { + const input = [{ key: 'foo', value: 'a'.repeat(10000) }]; + const output = mapToRows(input, 'eid'); + expect(output).toEqual([]); + }); + }); + + describe('buildEntitySearch', () => { + it('adds special keys even if missing', () => { + const input: Entity = { + apiVersion: 'a', + kind: 'b', + metadata: { name: 'n' }, + }; + expect(buildEntitySearch('eid', input)).toEqual([ + { entity_id: 'eid', key: 'apiversion', value: 'a' }, + { entity_id: 'eid', key: 'kind', value: 'b' }, + { entity_id: 'eid', key: 'metadata.name', value: 'n' }, + { entity_id: 'eid', key: 'metadata.namespace', value: null }, + { entity_id: 'eid', key: 'metadata.uid', value: null }, + { + entity_id: 'eid', + key: 'metadata.namespace', + value: ENTITY_DEFAULT_NAMESPACE, + }, + ]); + }); + + it('adds relations', () => { + const input: Entity = { + relations: [ + { type: 't1', target: { kind: 'k', namespace: 'ns', name: 'a' } }, + { type: 't2', target: { kind: 'k', namespace: 'ns', name: 'b' } }, + ], + apiVersion: 'a', + kind: 'b', + metadata: { name: 'n' }, + }; + expect(buildEntitySearch('eid', input)).toEqual([ + { entity_id: 'eid', key: 'apiversion', value: 'a' }, + { entity_id: 'eid', key: 'kind', value: 'b' }, + { entity_id: 'eid', key: 'metadata.name', value: 'n' }, + { entity_id: 'eid', key: 'metadata.namespace', value: null }, + { entity_id: 'eid', key: 'metadata.uid', value: null }, + { + entity_id: 'eid', + key: 'metadata.namespace', + value: ENTITY_DEFAULT_NAMESPACE, + }, + { entity_id: 'eid', key: 'relations', value: 't1:k:ns/a' }, + { entity_id: 'eid', key: 'relations', value: 't2:k:ns/b' }, + ]); + }); + }); +}); diff --git a/plugins/catalog-backend/src/next/search.ts b/plugins/catalog-backend/src/next/search.ts new file mode 100644 index 0000000000..4aa8bae1a8 --- /dev/null +++ b/plugins/catalog-backend/src/next/search.ts @@ -0,0 +1,191 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + ENTITY_DEFAULT_NAMESPACE, + stringifyEntityRef, +} from '@backstage/catalog-model'; + +export type DbSearchRow = { + entity_id: string; + key: string; + value: string | null; +}; + +// These are excluded in the generic loop, either because they do not make sense +// to index, or because they are special-case always inserted whether they are +// null or not +const SPECIAL_KEYS = [ + 'state', + 'relations', + 'metadata.name', + 'metadata.namespace', + 'metadata.uid', + 'metadata.etag', + 'metadata.generation', +]; + +// The maximum length allowed for search values. These columns are indexed, and +// database engines do not like to index on massive values. For example, +// postgres will balk after 8191 byte line sizes. +const MAX_VALUE_LENGTH = 200; + +type Kv = { + key: string; + value: unknown; +}; + +// Helper for traversing through a nested structure and outputting a list of +// path->value entries of the leaves. +// +// For example, this yaml structure +// +// a: 1 +// b: +// c: null +// e: [f, g] +// h: +// - i: 1 +// j: k +// - i: 2 +// j: l +// +// will result in +// +// "a", 1 +// "b.c", null +// "b.e": "f" +// "b.e.f": true +// "b.e": "g" +// "b.e.g": true +// "h.i": 1 +// "h.j": "k" +// "h.i": 2 +// "h.j": "l" +export function traverse(root: unknown): Kv[] { + const output: Kv[] = []; + + function visit(path: string, current: unknown) { + if (SPECIAL_KEYS.includes(path)) { + return; + } + + // empty or scalar + if ( + current === undefined || + current === null || + ['string', 'number', 'boolean'].includes(typeof current) + ) { + output.push({ key: path, value: current }); + return; + } + + // unknown + if (typeof current !== 'object') { + return; + } + + // array + if (Array.isArray(current)) { + for (const item of current) { + // NOTE(freben): The reason that these are output in two different ways, + // is to support use cases where you want to express that MORE than one + // tag is present in a list. Since the EntityFilters structure is a + // record, you can't have several entries of the same key. Therefore + // you will have to match on + // + // { "a.b": ["true"], "a.c": ["true"] } + // + // rather than + // + // { "a": ["b", "c"] } + // + // because the latter means EITHER b or c has to be present. + visit(path, item); + if (typeof item === 'string') { + output.push({ key: `${path}.${item}`, value: true }); + } + } + return; + } + + // object + for (const [key, value] of Object.entries(current!)) { + visit(path ? `${path}.${key}` : key, value); + } + } + + visit('', root); + + return output; +} + +// Translates a number of raw data rows to search table rows +export function mapToRows(input: Kv[], entityId: string): DbSearchRow[] { + const result: DbSearchRow[] = []; + + for (const { key: rawKey, value: rawValue } of input) { + const key = rawKey.toLocaleLowerCase('en-US'); + if (rawValue === undefined || rawValue === null) { + result.push({ entity_id: entityId, key, value: null }); + } else { + const value = String(rawValue).toLocaleLowerCase('en-US'); + if (value.length <= MAX_VALUE_LENGTH) { + result.push({ entity_id: entityId, key, value }); + } + } + } + + return result; +} + +/** + * Generates all of the search rows that are relevant for this entity. + * + * @param entityId The uid of the entity + * @param entity The entity + * @returns A list of entity search rows + */ +export function buildEntitySearch( + entityId: string, + entity: Entity, +): DbSearchRow[] { + // Visit the base structure recursively + const raw = traverse(entity); + + // Start with some special keys that are always present because you want to + // be able to easily search for null specifically + raw.push({ key: 'metadata.name', value: entity.metadata.name }); + raw.push({ key: 'metadata.namespace', value: entity.metadata.namespace }); + raw.push({ key: 'metadata.uid', value: entity.metadata.uid }); + + // Namespace not specified has the default value "default", so we want to + // match on that as well + if (!entity.metadata.namespace) { + raw.push({ key: 'metadata.namespace', value: ENTITY_DEFAULT_NAMESPACE }); + } + + // Visit relations + for (const relation of entity.relations ?? []) { + raw.push({ + key: 'relations', + value: `${relation.type}:${stringifyEntityRef(relation.target)}`, + }); + } + + return mapToRows(raw, entityId); +} diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index e0616fb336..cc9cc48ad6 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -120,6 +120,7 @@ export type ReplaceProcessingItemsRequest = removed: Entity[]; type: 'delta'; }; + export interface ProcessingStateManager { setProcessingItemResult(result: ProcessingItemResult): Promise<void>; getNextProcessingItem(): Promise<ProcessingItem>; From ec848a257d8ad6fb25b11c6e1329358c56492bf8 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 28 Apr 2021 11:57:33 +0200 Subject: [PATCH 317/462] chore: disable tests for now Signed-off-by: blam <ben@blam.sh> --- plugins/catalog-backend/package.json | 1 - plugins/catalog-backend/src/next/DefaultLocationStore.test.ts | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 5f70ec60e1..a5bb9e00af 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -78,7 +78,6 @@ "files": [ "dist", "migrations/**/*.{js,d.ts}", - "migrationsv2/**/*.{js,d.ts}", "config.d.ts" ], "configSchema": "config.d.ts" diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts index be20179e9a..d30509eaec 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -17,7 +17,8 @@ import { DatabaseManager } from './database/DatabaseManager'; import { DefaultLocationStore } from './DefaultLocationStore'; import { v4 } from 'uuid'; -describe('Default Location Store', () => { +/* eslint-disable */ +xdescribe('Default Location Store', () => { const createLocationStore = async () => { const db = await DatabaseManager.createTestDatabase(); const connection = { applyMutation: jest.fn() }; From e2000428aec1302800520aa9a2ce2bfdc79a51cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 12:18:41 +0200 Subject: [PATCH 318/462] add forgotten index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../migrationsv2/20210302150147_refresh_state.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 4d2c30f194..7b0cf9b2a6 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -173,6 +173,7 @@ exports.up = async function up(knex) { .string('value') .nullable() .comment('The corresponding value to match on'); + table.index(['entity_id'], 'search_entity_id_idx'); table.index(['key'], 'search_key_idx'); table.index(['value'], 'search_value_idx'); }); @@ -201,6 +202,7 @@ exports.down = async function down(knex) { table.index('originating_entity_id', 'relations_source_entity_id_idx'); }); await knex.schema.alterTable('search', table => { + table.dropIndex([], 'search_entity_id_idx'); table.dropIndex([], 'search_key_idx'); table.dropIndex([], 'search_value_idx'); }); From 1ce80ff02230fba7afe6284425a15ff30112d981 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Wed, 28 Apr 2021 12:50:03 +0200 Subject: [PATCH 319/462] Resolve issues with AsyncAPI rendering by updating `@asyncapi/react-component` to `0.23.0` Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/calm-zebras-remain.md | 7 ++++ plugins/api-docs/package.json | 2 +- .../AsyncApiDefinitionWidget.tsx | 10 +---- yarn.lock | 38 +++++++++---------- 4 files changed, 28 insertions(+), 29 deletions(-) create mode 100644 .changeset/calm-zebras-remain.md diff --git a/.changeset/calm-zebras-remain.md b/.changeset/calm-zebras-remain.md new file mode 100644 index 0000000000..3b961ab3f2 --- /dev/null +++ b/.changeset/calm-zebras-remain.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Resolve issues with AsyncAPI rendering by updating `@asyncapi/react-component` +to `0.23.0`. The theming of the component is adjusted to the latest styling +changes. diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 51df09ba80..532dacf684 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@asyncapi/react-component": "^0.22.3", + "@asyncapi/react-component": "^0.23.0", "@backstage/catalog-model": "^0.7.7", "@backstage/core": "^0.7.6", "@backstage/plugin-catalog-react": "^0.1.4", diff --git a/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx index a908a91b14..300c9d0c8a 100644 --- a/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx @@ -88,18 +88,10 @@ const useStyles = makeStyles(theme => ({ '& .asyncapi__enum': { color: theme.palette.secondary.main, }, - '& .asyncapi__toggle-arrow:before': { - content: '">"', - 'font-family': 'inherit', - }, - '& .asyncapi__anchor-icon:before': { - content: '"🔗"', - 'font-family': 'inherit', - }, '& .asyncapi__info, .asyncapi__channel, .asyncapi__channels > div, .asyncapi__schema, .asyncapi__channel-operations-list .asyncapi__messages-list-item .asyncapi__message, .asyncapi__message, .asyncapi__server, .asyncapi__servers > div, .asyncapi__messages > div, .asyncapi__schemas > div': { 'background-color': 'inherit', }, - '& .asyncapi__channel-parameters-header, .asyncapi__channel-operations-header, .asyncapi__channel-operation-oneOf-subscribe-header, .asyncapi__channel-operation-oneOf-publish-header': { + '& .asyncapi__channel-parameters-header, .asyncapi__channel-operations-header, .asyncapi__channel-operation-oneOf-subscribe-header, .asyncapi__channel-operation-oneOf-publish-header, .asyncapi__channel-operation-message-header, .asyncapi__message-header, .asyncapi__message-header-title, .asyncapi__message-header-title > h3, .asyncapi__bindings, .asyncapi__bindings-header, .asyncapi__bindings-header > h4': { 'background-color': 'inherit', color: theme.palette.text.primary, }, diff --git a/yarn.lock b/yarn.lock index 80819e5307..66be73ae3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -69,22 +69,22 @@ dependencies: tslib "~2.0.1" -"@asyncapi/avro-schema-parser@^0.2.0": - version "0.2.0" - resolved "https://registry.npmjs.org/@asyncapi/avro-schema-parser/-/avro-schema-parser-0.2.0.tgz#c9da2bb2858aca5a3b9e9a0e600084afd3765551" - integrity sha512-/oPDPudF82RGFXz5uhF77PSDZkAR+yHpdxUEbJ5jwk/X3RB74VRk8dqSgTqhUO+pLh+/Hut3x3VFacA8C9L2QA== +"@asyncapi/avro-schema-parser@^0.2.1": + version "0.2.1" + resolved "https://registry.npmjs.org/@asyncapi/avro-schema-parser/-/avro-schema-parser-0.2.1.tgz#0b7d9953e12084e6f556db261ae08bd8f6690faa" + integrity sha512-RZJaHsdYM4dChYSrb/TWrVCn/r2qcus+9/8iLL8+SMINHb0ECgH8tFZFJpr3Tq+LV2SBFaRQ+9kuecjQ8BNDSA== -"@asyncapi/openapi-schema-parser@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@asyncapi/openapi-schema-parser/-/openapi-schema-parser-2.0.0.tgz#80e2f38e92b6635dde19aae07b92e3caa0effc58" - integrity sha512-XfDp3EIs6ptar3jARQZzi3ObmS44l6Qozc5GJmZJUQ6mHLTTqUGJ0nxcrXAW88vosjilgJVaQ63oGolA6smSHQ== +"@asyncapi/openapi-schema-parser@^2.0.1": + version "2.0.1" + resolved "https://registry.npmjs.org/@asyncapi/openapi-schema-parser/-/openapi-schema-parser-2.0.1.tgz#4d6e82cced907b14e0ad6f98261ff2562d968d96" + integrity sha512-algbtdM1gcAOa8+V8kp7WeBhdaNac82jmZUXx8YjyNfRVo02N2juDrjeBAGJd+FNva9Mb4MM7qfkJoAFpTL5VQ== dependencies: "@openapi-contrib/openapi-schema-to-json-schema" "^3.0.0" -"@asyncapi/parser@^1.4.4": - version "1.4.4" - resolved "https://registry.npmjs.org/@asyncapi/parser/-/parser-1.4.4.tgz#66f2642e3f9ae4166cdea2480b665250b1edbd59" - integrity sha512-HEYEDM0BzfCxXNAv/pIS5yZWe11xB8fQo9G/SmsbpJavOpcF0sVZVIELva/NxHVz/ZUKPMKCa4Gqz7DF/lMqpw== +"@asyncapi/parser@^1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@asyncapi/parser/-/parser-1.5.0.tgz#d70616a1e6081c7dd86957befd5dccc46b9a77df" + integrity sha512-HzrehCcT6R+iqtktNmrUM9wRUEMBqnCeXIrGJT0txBMS1QduNRmXGjvuDpxqwyaATPH/xu1gSp2l6pFP/hyVbA== dependencies: "@apidevtools/json-schema-ref-parser" "^9.0.6" "@asyncapi/specs" "^2.7.7" @@ -96,14 +96,14 @@ node-fetch "^2.6.0" tiny-merge-patch "^0.1.2" -"@asyncapi/react-component@^0.22.3": - version "0.22.3" - resolved "https://registry.npmjs.org/@asyncapi/react-component/-/react-component-0.22.3.tgz#6ea7fb1044308e6d46f8455218920389becf2b22" - integrity sha512-f47sboqEQ0jNp0z2A+WGzBYYMS3ASmTwAXG/q6SwLuHBW15bSjaIYOVK3E8bmftBl+wVcEgAqUc6RKGtD9iVJg== +"@asyncapi/react-component@^0.23.0": + version "0.23.0" + resolved "https://registry.npmjs.org/@asyncapi/react-component/-/react-component-0.23.0.tgz#dce9a95cd0fb0d9f0364278088ad31194d411d52" + integrity sha512-mX70k3j5eSM7ets8BBZWnu6RsNXapLKD/7np+dMeXFk7KFbigVQXXr3hS0k2R+c8tRfkhlklicibq5ar1+fjDA== dependencies: - "@asyncapi/avro-schema-parser" "^0.2.0" - "@asyncapi/openapi-schema-parser" "^2.0.0" - "@asyncapi/parser" "^1.4.4" + "@asyncapi/avro-schema-parser" "^0.2.1" + "@asyncapi/openapi-schema-parser" "^2.0.1" + "@asyncapi/parser" "^1.5.0" constate "^1.2.0" dompurify "^2.1.1" markdown-it "^11.0.1" From 11461a20b304c47eae7581b9a77de5e033ab78e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 14:50:05 +0200 Subject: [PATCH 320/462] await the connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../catalog-backend/src/next/DefaultCatalogProcessingEngine.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 1934b0aea7..9de9f0ffd5 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -68,7 +68,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { async start() { for (const provider of this.entityProviders) { - provider.connect( + await provider.connect( new Connection({ stateManager: this.stateManager, id: provider.getProviderName(), From d1b1306d98a51f4a6e9814fb18a4abdb7179c2e8 Mon Sep 17 00:00:00 2001 From: Will <willsewell@monzo.com> Date: Tue, 27 Apr 2021 15:36:01 +0100 Subject: [PATCH 321/462] catalog-client: allow `filter` param to be specified multiple times This is possible on the backend, see: - https://github.com/backstage/backstage/blob/f9d077f5f6c3bf1e20255359798dd1febbeb3e27/plugins/catalog-backend/src/database/types.ts#L129-L131 - https://github.com/backstage/backstage/blob/f9d077f5f6c3bf1e20255359798dd1febbeb3e27/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts#L25-L42 Signed-off-by: Will Sewell <willsewell@monzo.com> --- .changeset/twenty-peas-deny.md | 5 +++ .../catalog-client/src/CatalogClient.test.ts | 32 +++++++++++++++++++ packages/catalog-client/src/CatalogClient.ts | 25 ++++++++++----- packages/catalog-client/src/types.ts | 5 ++- 4 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 .changeset/twenty-peas-deny.md diff --git a/.changeset/twenty-peas-deny.md b/.changeset/twenty-peas-deny.md new file mode 100644 index 0000000000..61c9cb3587 --- /dev/null +++ b/.changeset/twenty-peas-deny.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': minor +--- + +Allow `filter` param to be specified multiple times diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 19da45e4ec..fefe670a55 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -79,6 +79,37 @@ describe('CatalogClient', () => { it('builds entity search filters properly', async () => { expect.assertions(2); + server.use( + rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { + expect(req.url.search).toBe( + '?filter=a=1,b=2,b=3,%C3%B6=%3D&filter=a=2', + ); + return res(ctx.json([])); + }), + ); + + const response = await client.getEntities( + { + filter: [ + { + a: '1', + b: ['2', '3'], + ö: '=', + }, + { + a: '2', + }, + ], + }, + { token }, + ); + + expect(response.items).toEqual([]); + }); + + it('builds entity legacy search filters properly', async () => { + expect.assertions(2); + server.use( rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { expect(req.url.search).toBe('?filter=a=1,b=2,b=3,%C3%B6=%3D'); @@ -88,6 +119,7 @@ describe('CatalogClient', () => { const response = await client.getEntities( { + // The legacy value of filter is not an array filter: { a: '1', b: ['2', '3'], diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 3de25e9808..a246b3abab 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -56,18 +56,27 @@ export class CatalogClient implements CatalogApi { request?: CatalogEntitiesRequest, options?: CatalogRequestOptions, ): Promise<CatalogListResponse<Entity>> { - const { filter = {}, fields = [] } = request ?? {}; + const { filter = [], fields = [] } = request ?? {}; + const filterItems = [filter].flat(); const params: string[] = []; - const filterParts: string[] = []; - for (const [key, value] of Object.entries(filter)) { - for (const v of [value].flat()) { - filterParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`); + // filter param can occur multiple times, for example + // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component' + // the "outer array" defined by `filter` occurrences corresponds to "anyOf" filters + // the "inner array" defined within a `filter` param corresponds to "allOf" filters + for (const filterItem of filterItems) { + const filterParts: string[] = []; + for (const [key, value] of Object.entries(filterItem)) { + for (const v of [value].flat()) { + filterParts.push( + `${encodeURIComponent(key)}=${encodeURIComponent(v)}`, + ); + } } - } - if (filterParts.length) { - params.push(`filter=${filterParts.join(',')}`); + if (filterParts.length) { + params.push(`filter=${filterParts.join(',')}`); + } } if (fields.length) { diff --git a/packages/catalog-client/src/types.ts b/packages/catalog-client/src/types.ts index 0d25bf7483..9035657ddc 100644 --- a/packages/catalog-client/src/types.ts +++ b/packages/catalog-client/src/types.ts @@ -17,7 +17,10 @@ import { Entity, EntityName, Location } from '@backstage/catalog-model'; export type CatalogEntitiesRequest = { - filter?: Record<string, string | string[]> | undefined; + filter?: + | Record<string, string | string[]>[] + | Record<string, string | string[]> // Legacy type preserved for backwards compatibility + | undefined; fields?: string[] | undefined; }; From 17644ca68eb67dea67b1691f34181c61b811326a Mon Sep 17 00:00:00 2001 From: Will <willsewell@monzo.com> Date: Wed, 28 Apr 2021 14:23:10 +0100 Subject: [PATCH 322/462] Don't treat singuler `filter` type as legacy Instead it's a convenience type for when only a single instance of a param is required. Signed-off-by: Will Sewell <willsewell@monzo.com> --- packages/catalog-client/src/CatalogClient.test.ts | 5 ++--- packages/catalog-client/src/types.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index fefe670a55..359e3a2c60 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -76,7 +76,7 @@ describe('CatalogClient', () => { expect(response).toEqual(defaultResponse); }); - it('builds entity search filters properly', async () => { + it('builds multiple entity search filters properly', async () => { expect.assertions(2); server.use( @@ -107,7 +107,7 @@ describe('CatalogClient', () => { expect(response.items).toEqual([]); }); - it('builds entity legacy search filters properly', async () => { + it('builds single entity search filter properly', async () => { expect.assertions(2); server.use( @@ -119,7 +119,6 @@ describe('CatalogClient', () => { const response = await client.getEntities( { - // The legacy value of filter is not an array filter: { a: '1', b: ['2', '3'], diff --git a/packages/catalog-client/src/types.ts b/packages/catalog-client/src/types.ts index 9035657ddc..ef907eafa9 100644 --- a/packages/catalog-client/src/types.ts +++ b/packages/catalog-client/src/types.ts @@ -19,7 +19,7 @@ import { Entity, EntityName, Location } from '@backstage/catalog-model'; export type CatalogEntitiesRequest = { filter?: | Record<string, string | string[]>[] - | Record<string, string | string[]> // Legacy type preserved for backwards compatibility + | Record<string, string | string[]> | undefined; fields?: string[] | undefined; }; From bd877d4518ec75be2ce9d63ad6cd26da93d1808c Mon Sep 17 00:00:00 2001 From: Will <willsewell@monzo.com> Date: Wed, 28 Apr 2021 14:25:05 +0100 Subject: [PATCH 323/462] Make "patch"-level change instead of "minor" Signed-off-by: Will Sewell <willsewell@monzo.com> --- .changeset/twenty-peas-deny.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/twenty-peas-deny.md b/.changeset/twenty-peas-deny.md index 61c9cb3587..df335ea95a 100644 --- a/.changeset/twenty-peas-deny.md +++ b/.changeset/twenty-peas-deny.md @@ -1,5 +1,5 @@ --- -'@backstage/catalog-client': minor +'@backstage/catalog-client': patch --- Allow `filter` param to be specified multiple times From d8b81fd28bf3cacf96cf62739e092f01568234fb Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 28 Apr 2021 16:11:29 +0200 Subject: [PATCH 324/462] changesets: add changeset for json-schema bump Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/tough-walls-wash.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/tough-walls-wash.md diff --git a/.changeset/tough-walls-wash.md b/.changeset/tough-walls-wash.md new file mode 100644 index 0000000000..a45adcfbf6 --- /dev/null +++ b/.changeset/tough-walls-wash.md @@ -0,0 +1,9 @@ +--- +'@backstage/catalog-model': patch +'@backstage/cli': patch +'@backstage/config-loader': patch +'@backstage/config': patch +'@backstage/plugin-scaffolder': patch +--- + +Bump `json-schema` dependency from `0.2.5` to `0.3.0`. From 55e1d9f3a58696ad23e50e49a1a48a173aef10bb Mon Sep 17 00:00:00 2001 From: jrusso1020 <jrusso@brex.com> Date: Wed, 28 Apr 2021 08:45:35 -0600 Subject: [PATCH 325/462] update JSON Signed-off-by: jrusso1020 <jrusso@brex.com> --- docs/features/software-catalog/descriptor-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 0dba11fd62..eb087a9c5f 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -77,7 +77,7 @@ This is the same entity as returned in JSON from the software catalog API: "etag": "ZjU2MWRkZWUtMmMxZS00YTZiLWFmMWMtOTE1NGNiZDdlYzNk", "generation": 1, "labels": { - "backstage.io/custom": "ValueStuff" + "example.com/custom": "custom_label_value" }, "links": [{ "url": "https://admin.example-org.com", From d6cfbc797f768de5760eec9b93ade77ad9282597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 17:05:55 +0200 Subject: [PATCH 326/462] Tweaks to the v2 catalog ingestion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../20210302150147_refresh_state.js | 14 ++++++-- .../src/next/NextEntitiesCatalog.ts | 2 +- .../catalog-backend/src/next/Stitcher.test.ts | 25 ++++++------- plugins/catalog-backend/src/next/Stitcher.ts | 36 +++++++++++-------- .../catalog-backend/src/next/search.test.ts | 4 +-- plugins/catalog-backend/src/next/search.ts | 4 +-- 6 files changed, 50 insertions(+), 35 deletions(-) diff --git a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js index 7b0cf9b2a6..4c03405910 100644 --- a/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrationsv2/20210302150147_refresh_state.js @@ -83,10 +83,18 @@ exports.up = async function up(knex) { .inTable('refresh_state') .onDelete('CASCADE') .comment( - 'Entity ID which correspond to the ID in the refresh_state table', + 'Entity ID which corresponds to the ID in the refresh_state table', ); - table.text('etag').notNullable().comment('Etag to be used for caching'); - table.text('finalized_entity').notNullable().comment('The final entity'); + table + .text('hash') + .notNullable() + .comment( + 'Stable hash of the entity data, to be used for caching and avoiding redundant work', + ); + table + .text('final_entity') + .notNullable() + .comment('The JSON encoded final entity'); table.index('entity_id', 'final_entities_entity_id_idx'); }); diff --git a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts index 5bddd47f41..e87bb01e1f 100644 --- a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts @@ -37,7 +37,7 @@ export class NextEntitiesCatalog implements EntitiesCatalog { 'final_entities', ).select(); - const entities = dbResponse.map(e => JSON.parse(e.finalized_entity)); + const entities = dbResponse.map(e => JSON.parse(e.final_entity)); return { entities, diff --git a/plugins/catalog-backend/src/next/Stitcher.test.ts b/plugins/catalog-backend/src/next/Stitcher.test.ts index 327d922c07..f38af384fa 100644 --- a/plugins/catalog-backend/src/next/Stitcher.test.ts +++ b/plugins/catalog-backend/src/next/Stitcher.test.ts @@ -74,12 +74,12 @@ describe('Stitcher', () => { await stitcher.stitch(new Set(['k:ns/n'])); - let firstEtag: string; + let firstHash: string; await db.transaction(async tx => { const entities = await tx<DbFinalEntitiesRow>('final_entities'); expect(entities.length).toBe(1); - const entity = JSON.parse(entities[0].finalized_entity); + const entity = JSON.parse(entities[0].final_entity); expect(entity).toEqual({ relations: [ { @@ -105,12 +105,13 @@ describe('Stitcher', () => { }, }); - firstEtag = entity.metadata.etag; + expect(entity.metadata.etag).toEqual(entities[0].hash); + firstHash = entities[0].hash; const search = await tx<DbSearchRow>('search'); expect(search).toEqual( expect.arrayContaining([ - { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/other' }, + { entity_id: 'my-id', key: 'relations.looksat', value: 'k:ns/other' }, { entity_id: 'my-id', key: 'apiversion', value: 'a' }, { entity_id: 'my-id', key: 'kind', value: 'k' }, { entity_id: 'my-id', key: 'metadata.name', value: 'n' }, @@ -127,9 +128,9 @@ describe('Stitcher', () => { await db.transaction(async tx => { const entities = await tx<DbFinalEntitiesRow>('final_entities'); expect(entities.length).toBe(1); - const entity = JSON.parse(entities[0].finalized_entity); - expect(entities[0].etag).toEqual(firstEtag); - expect(entity.metadata.etag).toEqual(firstEtag); + const entity = JSON.parse(entities[0].final_entity); + expect(entities[0].hash).toEqual(firstHash); + expect(entity.metadata.etag).toEqual(firstHash); }); // Now add one more relation and re-stitch @@ -150,7 +151,7 @@ describe('Stitcher', () => { const entities = await tx<DbFinalEntitiesRow>('final_entities'); expect(entities.length).toBe(1); - const entity = JSON.parse(entities[0].finalized_entity); + const entity = JSON.parse(entities[0].final_entity); expect(entity).toEqual({ relations: expect.arrayContaining([ { @@ -184,14 +185,14 @@ describe('Stitcher', () => { }, }); - expect(entities[0].etag).not.toEqual(firstEtag); - expect(entities[0].etag).toEqual(entity.metadata.etag); + expect(entities[0].hash).not.toEqual(firstHash); + expect(entities[0].hash).toEqual(entity.metadata.etag); const search = await tx<DbSearchRow>('search'); expect(search).toEqual( expect.arrayContaining([ - { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/other' }, - { entity_id: 'my-id', key: 'relations', value: 'looksat:k:ns/third' }, + { entity_id: 'my-id', key: 'relations.looksat', value: 'k:ns/other' }, + { entity_id: 'my-id', key: 'relations.looksat', value: 'k:ns/third' }, { entity_id: 'my-id', key: 'apiversion', value: 'a' }, { entity_id: 'my-id', key: 'kind', value: 'k' }, { entity_id: 'my-id', key: 'metadata.name', value: 'n' }, diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index cd9220e934..bdc028d923 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -31,11 +31,11 @@ const BATCH_SIZE = 50; export type DbFinalEntitiesRow = { entity_id: string; - etag: string; - finalized_entity: string; + hash: string; + final_entity: string; }; -function generateEntityEtag(entity: Entity) { +function generateStableHash(entity: Entity) { return createHash('sha1') .update(stableStringify({ ...entity })) .digest('hex'); @@ -64,7 +64,7 @@ export class Stitcher { processedEntity?: string; errors: string; incomingReferenceCount: string | number; - previousEtag?: string; + previousHash?: string; relationType?: string; relationTarget?: string; }> = await tx @@ -79,7 +79,7 @@ export class Stitcher { processedEntity: 'refresh_state.processed_entity', errors: 'refresh_state.errors', incomingReferenceCount: 'incoming_references.count', - previousEtag: 'final_entities.etag', + previousHash: 'final_entities.hash', relationType: 'relations.type', relationTarget: 'relations.target_entity_ref', }) @@ -111,7 +111,7 @@ export class Stitcher { processedEntity, // errors, incomingReferenceCount, - previousEtag, + previousHash, } = result[0]; // If there was no processed entity in place, the target hasn't been @@ -125,7 +125,8 @@ export class Stitcher { return; } - // Grab the processed entity and stitch all of the relevant data into it + // Grab the processed entity and stitch all of the relevant data into + // it const entity = JSON.parse(processedEntity) as Entity; const isOrphan = Number(incomingReferenceCount) === 0; @@ -137,33 +138,38 @@ export class Stitcher { }; } - // TODO: entityRef is lower case and should be uppercase in the final result + // TODO: entityRef is lower case and should be uppercase in the final + // result entity.relations = result - .filter(row => row.relationType) + .filter(row => row.relationType /* exclude null row, if relevant */) .map(row => ({ type: row.relationType!, target: parseEntityRef(row.relationTarget!), })); // If the output entity was actually not changed, just abort - const etag = generateEntityEtag(entity); - if (etag === previousEtag) { + const hash = generateStableHash(entity); + if (hash === previousHash) { this.logger.debug(`Skipped stitching of ${entityRef}, no changes`); return; } entity.metadata.uid = entityId; entity.metadata.generation = 1; - entity.metadata.etag = etag; + if (!entity.metadata.etag) { + // If the original data source did not have its own etag handling, + // use the hash as a good-quality etag + entity.metadata.etag = hash; + } await tx<DbFinalEntitiesRow>('final_entities') .insert({ entity_id: entityId, - finalized_entity: JSON.stringify(entity), - etag, + final_entity: JSON.stringify(entity), + hash, }) .onConflict('entity_id') - .merge(['finalized_entity', 'etag']); + .merge(['final_entity', 'hash']); const searchEntries = buildEntitySearch(entityId, entity); await tx<DbSearchRow>('search').where({ entity_id: entityId }).delete(); diff --git a/plugins/catalog-backend/src/next/search.test.ts b/plugins/catalog-backend/src/next/search.test.ts index be9a98fe69..ff1cba01b9 100644 --- a/plugins/catalog-backend/src/next/search.test.ts +++ b/plugins/catalog-backend/src/next/search.test.ts @@ -152,8 +152,8 @@ describe('search', () => { key: 'metadata.namespace', value: ENTITY_DEFAULT_NAMESPACE, }, - { entity_id: 'eid', key: 'relations', value: 't1:k:ns/a' }, - { entity_id: 'eid', key: 'relations', value: 't2:k:ns/b' }, + { entity_id: 'eid', key: 'relations.t1', value: 'k:ns/a' }, + { entity_id: 'eid', key: 'relations.t2', value: 'k:ns/b' }, ]); }); }); diff --git a/plugins/catalog-backend/src/next/search.ts b/plugins/catalog-backend/src/next/search.ts index 4aa8bae1a8..5ff0721f91 100644 --- a/plugins/catalog-backend/src/next/search.ts +++ b/plugins/catalog-backend/src/next/search.ts @@ -182,8 +182,8 @@ export function buildEntitySearch( // Visit relations for (const relation of entity.relations ?? []) { raw.push({ - key: 'relations', - value: `${relation.type}:${stringifyEntityRef(relation.target)}`, + key: `relations.${relation.type}`, + value: stringifyEntityRef(relation.target), }); } From d5b892d0410eb2c75711087acc81a876a47a953f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20A=CC=8Ahsberg?= <mathias.ahsberg@resurs.se> Date: Wed, 28 Apr 2021 15:18:55 +0000 Subject: [PATCH 327/462] Wrap Bitbucket types into separate namespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathias Åhsberg <mathias.ahsberg@resurs.se> --- .../processors/BitbucketDiscoveryProcessor.ts | 4 ++-- .../BitbucketRepositoryParser.test.ts | 6 ++--- .../bitbucket/BitbucketRepositoryParser.ts | 4 ++-- .../ingestion/processors/bitbucket/types.ts | 24 ++++++++++--------- .../src/ingestion/processors/index.ts | 3 +-- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts index f92a5c6f7c..858219423f 100644 --- a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts @@ -22,7 +22,7 @@ import { } from '@backstage/integration'; import { LocationSpec } from '@backstage/catalog-model'; import { - Repository, + Bitbucket, BitbucketRepositoryParser, BitbucketClient, defaultRepositoryParser, @@ -159,5 +159,5 @@ function escapeRegExp(str: string): RegExp { type Result = { scanned: number; - matches: Repository[]; + matches: Bitbucket.Repository[]; }; diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts index ab5080f446..e0d430f77b 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { defaultRepositoryParser } from './BitbucketRepositoryParser'; -import { Project, Repository } from './types'; +import { Bitbucket } from './types'; import { BitbucketClient } from './client'; import { results } from '../index'; @@ -36,12 +36,12 @@ describe('BitbucketRepositoryParser', () => { const actual = await defaultRepositoryParser({ client: {} as BitbucketClient, repository: { - project: {} as Project, + project: {} as Bitbucket.Project, slug: 'repo-slug', links: { self: [{ href: browseUrl }], }, - } as Repository, + } as Bitbucket.Repository, path: path, }); diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts index f786b6dac8..05e3c6822a 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Repository } from './types'; +import { Bitbucket } from './types'; import { CatalogProcessorResult } from '../types'; import { results } from '../index'; import { BitbucketClient } from './client'; export type BitbucketRepositoryParser = (options: { client: BitbucketClient; - repository: Repository; + repository: Bitbucket.Repository; path: string; }) => AsyncIterable<CatalogProcessorResult>; diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts index 75dd372faa..8a8656f666 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts @@ -13,16 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type Project = { - key: string; -}; +export namespace Bitbucket { + export type Project = { + key: string; + }; -export type Repository = { - project: Project; - slug: string; - links: Record<string, Link[]>; -}; + export type Repository = { + project: Project; + slug: string; + links: Record<string, Link[]>; + }; -export type Link = { - href: string; -}; + export type Link = { + href: string; + }; +} diff --git a/plugins/catalog-backend/src/ingestion/processors/index.ts b/plugins/catalog-backend/src/ingestion/processors/index.ts index 8d1a7967cd..c8f51bbccc 100644 --- a/plugins/catalog-backend/src/ingestion/processors/index.ts +++ b/plugins/catalog-backend/src/ingestion/processors/index.ts @@ -36,6 +36,5 @@ export { UrlReaderProcessor } from './UrlReaderProcessor'; export { parseEntityYaml } from './util/parse'; export { results }; -export * from './bitbucket/types'; export { BitbucketClient } from './bitbucket'; -export type { BitbucketRepositoryParser } from './bitbucket'; +export type { BitbucketRepositoryParser, Bitbucket } from './bitbucket'; From a7a68535e161ade9970e396056c18857c45bafec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 18:31:26 +0200 Subject: [PATCH 328/462] Minor typo entites -> entities and remove unused type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/next/DefaultCatalogProcessingEngine.ts | 2 +- .../next/DefaultCatalogProcessingOrchestrator.ts | 10 +++++----- plugins/catalog-backend/src/next/types.ts | 14 +------------- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 9de9f0ffd5..1397d9038a 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -105,7 +105,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { state: result.state, errors: result.errors, relations: result.relations, - deferredEntities: result.deferredEntites, + deferredEntities: result.deferredEntities, }); const setOfThingsToStitch = new Set<string>([ diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts index 1880b5d17e..8fbb19e536 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts @@ -179,7 +179,7 @@ export class DefaultCatalogProcessingOrchestrator ); } - // Backwards compatible processing of location entites + // Backwards compatible processing of location entities if (isLocationEntity(entity)) { const { type = location.type } = entity.spec; const targets = new Array<string>(); @@ -268,7 +268,7 @@ function createEmitter(logger: Logger, parentEntity: Entity) { const errors = new Array<Error>(); const relations = new Array<EntityRelationSpec>(); - const deferredEntites = new Array<Entity>(); + const deferredEntities = new Array<Entity>(); const emit = (i: CatalogProcessorResult) => { if (done) { @@ -282,7 +282,7 @@ function createEmitter(logger: Logger, parentEntity: Entity) { if (i.type === 'entity') { const originLocation = getEntityOriginLocationRef(parentEntity); - deferredEntites.push({ + deferredEntities.push({ ...i.entity, metadata: { ...i.entity.metadata, @@ -294,7 +294,7 @@ function createEmitter(logger: Logger, parentEntity: Entity) { }, }); } else if (i.type === 'location') { - deferredEntites.push( + deferredEntities.push( locationSpecToLocationEntity(i.location, parentEntity), ); } else if (i.type === 'relation') { @@ -311,7 +311,7 @@ function createEmitter(logger: Logger, parentEntity: Entity) { return { errors, relations, - deferredEntites, + deferredEntities, }; }, }; diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index cc9cc48ad6..202576fddd 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -22,18 +22,6 @@ import { } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; -export interface LocationEntity { - apiVersion: 'backstage.io/v1alpha1'; - kind: 'Location'; - metadata: { - name: string; // type:target - namespace: 'default'; - }; - spec: { - location: { type: string; target: string }; - }; -} - export interface LocationService { createLocation( spec: LocationSpec, @@ -80,7 +68,7 @@ export type EntityProcessingResult = ok: true; state: Map<string, JsonObject>; completedEntity: Entity; - deferredEntites: Entity[]; + deferredEntities: Entity[]; relations: EntityRelationSpec[]; errors: Error[]; } From 30821b2b413bf1a46daf09c0c5600864d6f962a1 Mon Sep 17 00:00:00 2001 From: Tim Hansen <timbonicus@gmail.com> Date: Wed, 28 Apr 2021 10:57:00 -0600 Subject: [PATCH 329/462] Update cost-insights and circleci logos Signed-off-by: Tim Hansen <timbonicus@gmail.com> --- microsite/data/plugins/circleci.yaml | 2 +- microsite/data/plugins/cost-insights.yaml | 2 +- microsite/static/img/circleci.png | Bin 0 -> 16688 bytes microsite/static/img/cost-insights.png | Bin 0 -> 105171 bytes 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 microsite/static/img/circleci.png create mode 100644 microsite/static/img/cost-insights.png diff --git a/microsite/data/plugins/circleci.yaml b/microsite/data/plugins/circleci.yaml index 0acad832fa..cffbedca37 100644 --- a/microsite/data/plugins/circleci.yaml +++ b/microsite/data/plugins/circleci.yaml @@ -5,7 +5,7 @@ authorUrl: https://github.com/spotify category: CI/CD description: Automate your development process with CI hosted in the cloud or on a private server. documentation: https://github.com/backstage/backstage/tree/master/plugins/circleci -iconUrl: https://www.saaves.com/storage/brochure/logo-circleci-icon1583764538.png +iconUrl: img/circleci.png npmPackageName: '@backstage/plugin-circleci' tags: - ci diff --git a/microsite/data/plugins/cost-insights.yaml b/microsite/data/plugins/cost-insights.yaml index daa4f55a02..ec2d162b9d 100644 --- a/microsite/data/plugins/cost-insights.yaml +++ b/microsite/data/plugins/cost-insights.yaml @@ -5,7 +5,7 @@ authorUrl: https://github.com/spotify category: Discovery description: Visualize, understand and optimize your team's cloud costs. documentation: https://github.com/backstage/backstage/tree/master/plugins/cost-insights -iconUrl: https://www.materialui.co/materialIcons/editor/monetization_on_white_192x192.png +iconUrl: img/cost-insights.png npmPackageName: '@backstage/plugin-cost-insights' tags: - web diff --git a/microsite/static/img/circleci.png b/microsite/static/img/circleci.png new file mode 100644 index 0000000000000000000000000000000000000000..3fc450d54d9afbea45c5717cd68f9315dce7fa01 GIT binary patch literal 16688 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 literal 0 HcmV?d00001 diff --git a/microsite/static/img/cost-insights.png b/microsite/static/img/cost-insights.png new file mode 100644 index 0000000000000000000000000000000000000000..768247cb19e8eca4abf4aad034e60304fc5110c8 GIT binary patch literal 105171 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 BKA8Xj literal 0 HcmV?d00001 From b98de52ae834349b5d23097f38dc2fb237c87246 Mon Sep 17 00:00:00 2001 From: Phil Kuang <pkuang@factset.com> Date: Tue, 27 Apr 2021 21:36:51 -0400 Subject: [PATCH 330/462] feat(CostInsights): support a display friendly name prop for projects Signed-off-by: Phil Kuang <pkuang@factset.com> --- .changeset/cost-insights-gorgeous-dancers-hope.md | 5 +++++ .../components/ProjectSelect/ProjectSelect.test.tsx | 6 ++++-- .../src/components/ProjectSelect/ProjectSelect.tsx | 11 +++++++---- plugins/cost-insights/src/types/Project.ts | 1 + 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .changeset/cost-insights-gorgeous-dancers-hope.md diff --git a/.changeset/cost-insights-gorgeous-dancers-hope.md b/.changeset/cost-insights-gorgeous-dancers-hope.md new file mode 100644 index 0000000000..8e0abce57f --- /dev/null +++ b/.changeset/cost-insights-gorgeous-dancers-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +Support a `name` prop for Projects for display purposes diff --git a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx index 1bd57a9eed..1820b9e35a 100644 --- a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx +++ b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.test.tsx @@ -23,7 +23,7 @@ import { renderInTestApp } from '@backstage/test-utils'; const mockProjects = [ { id: 'project1' }, - { id: 'project2' }, + { id: 'project2', name: 'Project 2' }, { id: 'project3' }, ]; @@ -56,7 +56,9 @@ describe('<ProjectSelect />', () => { await waitFor(() => rendered.getByTestId('option-all')); mockProjects.forEach(project => - expect(rendered.getByText(project.id)).toBeInTheDocument(), + expect( + rendered.getByText(project.name ?? project.id), + ).toBeInTheDocument(), ); }); }); diff --git a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx index bc34eb9c8d..25fdc0c171 100644 --- a/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx +++ b/plugins/cost-insights/src/components/ProjectSelect/ProjectSelect.tsx @@ -33,7 +33,9 @@ export const ProjectSelect = ({ const projectOptions = projects .filter(p => p.id) - .sort((a, b) => (a.id as string).localeCompare(b.id as string)); + .sort((a, b) => + ((a.name ?? a.id) as string).localeCompare((b.name ?? b.id) as string), + ); const handleOnChange = (e: React.ChangeEvent<{ value: unknown }>) => { onSelect(e.target.value as string); @@ -41,9 +43,10 @@ export const ProjectSelect = ({ const renderValue = (value: unknown) => { const proj = value as string; + const projectObj = projects.find(p => p.id === proj); return ( <b data-testid={`selected-${proj}`}> - {proj === 'all' ? 'All Projects' : proj} + {proj === 'all' ? 'All Projects' : projectObj?.name ?? proj} </b> ); }; @@ -52,7 +55,7 @@ export const ProjectSelect = ({ <Select className={classes.select} variant="outlined" - value={project || 'all'} + value={project ?? 'all'} renderValue={renderValue} onChange={handleOnChange} data-testid="project-filter-select" @@ -64,7 +67,7 @@ export const ProjectSelect = ({ value={proj.id} data-testid={`option-${proj.id}`} > - {proj.id === 'all' ? 'All Projects' : proj.id} + {proj.id === 'all' ? 'All Projects' : proj.name ?? proj.id} </MenuItem> ))} </Select> diff --git a/plugins/cost-insights/src/types/Project.ts b/plugins/cost-insights/src/types/Project.ts index 24259f6910..6ac61f1fb7 100644 --- a/plugins/cost-insights/src/types/Project.ts +++ b/plugins/cost-insights/src/types/Project.ts @@ -16,4 +16,5 @@ export interface Project { id: string; + name?: string; } From 410be7722c1541e4b5ff140b7ff75ef381829a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 19:25:24 +0200 Subject: [PATCH 331/462] exclude status instead of state, and also attachments while we're at it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/catalog-backend/src/next/search.test.ts | 5 +++-- plugins/catalog-backend/src/next/search.ts | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend/src/next/search.test.ts b/plugins/catalog-backend/src/next/search.test.ts index ff1cba01b9..2e0b07b4a9 100644 --- a/plugins/catalog-backend/src/next/search.test.ts +++ b/plugins/catalog-backend/src/next/search.test.ts @@ -52,8 +52,9 @@ describe('search', () => { it('skips over special keys', () => { const input = { - state: { x: 1 }, - relations: [{ y: 2 }], + status: { x: 1 }, + attachments: [{ y: 2 }], + relations: [{ z: 3 }], a: 'a', metadata: { b: 'b', diff --git a/plugins/catalog-backend/src/next/search.ts b/plugins/catalog-backend/src/next/search.ts index 5ff0721f91..383b29fd70 100644 --- a/plugins/catalog-backend/src/next/search.ts +++ b/plugins/catalog-backend/src/next/search.ts @@ -30,8 +30,9 @@ export type DbSearchRow = { // to index, or because they are special-case always inserted whether they are // null or not const SPECIAL_KEYS = [ - 'state', + 'attachments', 'relations', + 'status', 'metadata.name', 'metadata.namespace', 'metadata.uid', From 0f26d52325c62fc1e47ee03f5e2449e37665a13c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 19:25:56 +0200 Subject: [PATCH 332/462] remove unnecessary copying of migration files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/next/NextCatalogBuilder.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 24b763a098..7129809c71 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -243,19 +243,13 @@ export class NextCatalogBuilder { const parser = this.parser || defaultEntityDataParser; const dbClient = await database.getClient(); - const allMigrations = resolvePackagePath( - '@backstage/plugin-catalog-backend', - 'migrations', - ); - - const migrationsDir = resolvePackagePath( - '@backstage/plugin-catalog-backend', - 'migrationsv2', - ); - await fs.copy(allMigrations, migrationsDir); await dbClient.migrate.latest({ - directory: migrationsDir, + directory: resolvePackagePath( + '@backstage/plugin-catalog-backend', + 'migrationsv2', + ), }); + const db = new CommonDatabase(dbClient, logger); const processingDatabase = new DefaultProcessingDatabase(dbClient, logger); From f4009504d34e5259ff7f2ef31981e9c23138bab6 Mon Sep 17 00:00:00 2001 From: ImgBotApp <ImgBotHelp@gmail.com> Date: Wed, 28 Apr 2021 18:38:11 +0000 Subject: [PATCH 333/462] [ImgBot] Optimize images *Total -- 119.00kb -> 98.54kb (17.19%) /microsite/static/img/circleci.png -- 16.30kb -> 9.54kb (41.43%) /microsite/static/img/cost-insights.png -- 102.71kb -> 89.00kb (13.35%) Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com> --- microsite/static/img/circleci.png | Bin 16688 -> 9774 bytes microsite/static/img/cost-insights.png | Bin 105171 -> 91134 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/microsite/static/img/circleci.png b/microsite/static/img/circleci.png index 3fc450d54d9afbea45c5717cd68f9315dce7fa01..85f262e4b31af221482e868387c1a1a469cc6f8a 100644 GIT binary patch literal 9774 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 literal 16688 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 diff --git a/microsite/static/img/cost-insights.png b/microsite/static/img/cost-insights.png index 768247cb19e8eca4abf4aad034e60304fc5110c8..7296dd35240f8fd694b1cf40c2f853fc08699c16 100644 GIT binary patch literal 91134 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 Z^7w!MLFX&C81Mni;OcdqaxJ^a{{y<3k$3<A literal 105171 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 BKA8Xj From 0f2e4098f0a441cfa23039fc7127369dd885e727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Wed, 28 Apr 2021 21:07:21 +0200 Subject: [PATCH 334/462] some light renaming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- ...r.test.ts => ConfigLocationEntityProvider.test.ts} | 10 +++++----- ...ionProvider.ts => ConfigLocationEntityProvider.ts} | 6 +++--- .../src/next/DefaultCatalogProcessingEngine.ts | 9 ++++----- .../{DefaultService.ts => DefaultLocationService.ts} | 0 .../src/next/DefaultLocationStore.test.ts | 6 +++--- .../catalog-backend/src/next/DefaultLocationStore.ts | 4 ++-- .../catalog-backend/src/next/NextCatalogBuilder.ts | 11 +++++------ .../src/next/database/DatabaseManager.ts | 4 ++-- 8 files changed, 24 insertions(+), 26 deletions(-) rename plugins/catalog-backend/src/next/{ConfigLocationProvider.test.ts => ConfigLocationEntityProvider.test.ts} (90%) rename plugins/catalog-backend/src/next/{ConfigLocationProvider.ts => ConfigLocationEntityProvider.ts} (91%) rename plugins/catalog-backend/src/next/{DefaultService.ts => DefaultLocationService.ts} (100%) diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts b/plugins/catalog-backend/src/next/ConfigLocationEntityProvider.test.ts similarity index 90% rename from plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts rename to plugins/catalog-backend/src/next/ConfigLocationEntityProvider.test.ts index 9aaba13c48..226e5c06a8 100644 --- a/plugins/catalog-backend/src/next/ConfigLocationProvider.test.ts +++ b/plugins/catalog-backend/src/next/ConfigLocationEntityProvider.test.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import { ConfigLocationProvider } from './ConfigLocationProvider'; -import { EntityProviderConnection } from './types'; -import { ConfigReader } from '@backstage/config'; import { resolvePackagePath } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; import path from 'path'; +import { ConfigLocationEntityProvider } from './ConfigLocationEntityProvider'; +import { EntityProviderConnection } from './types'; -describe('Config Location Provider', () => { +describe('ConfigLocationEntityProvider', () => { it('should apply mutation with the correct paths in the config', async () => { const mockConfig = new ConfigReader({ catalog: { @@ -34,7 +34,7 @@ describe('Config Location Provider', () => { const mockConnection = ({ applyMutation: jest.fn(), } as unknown) as EntityProviderConnection; - const locationProvider = new ConfigLocationProvider(mockConfig); + const locationProvider = new ConfigLocationEntityProvider(mockConfig); await locationProvider.connect(mockConnection); diff --git a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts b/plugins/catalog-backend/src/next/ConfigLocationEntityProvider.ts similarity index 91% rename from plugins/catalog-backend/src/next/ConfigLocationProvider.ts rename to plugins/catalog-backend/src/next/ConfigLocationEntityProvider.ts index 8a65487df1..bccbd0ba41 100644 --- a/plugins/catalog-backend/src/next/ConfigLocationProvider.ts +++ b/plugins/catalog-backend/src/next/ConfigLocationEntityProvider.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { EntityProviderConnection, EntityProvider } from './types'; -import path from 'path'; import { Config } from '@backstage/config'; +import path from 'path'; +import { EntityProvider, EntityProviderConnection } from './types'; import { locationSpecToLocationEntity } from './util'; -export class ConfigLocationProvider implements EntityProvider { +export class ConfigLocationEntityProvider implements EntityProvider { private connection: EntityProviderConnection | undefined; constructor(private readonly config: Config) {} diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 1397d9038a..e724fe79d8 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -14,19 +14,18 @@ * limitations under the License. */ +import { stringifyEntityRef } from '@backstage/catalog-model'; +import { Logger } from 'winston'; +import { Stitcher } from './Stitcher'; import { CatalogProcessingEngine, + CatalogProcessingOrchestrator, EntityProvider, EntityProviderConnection, EntityProviderMutation, ProcessingStateManager, - CatalogProcessingOrchestrator, } from './types'; -import { Logger } from 'winston'; -import { stringifyEntityRef } from '@backstage/catalog-model'; -import { Stitcher } from './Stitcher'; - class Connection implements EntityProviderConnection { constructor( private readonly config: { diff --git a/plugins/catalog-backend/src/next/DefaultService.ts b/plugins/catalog-backend/src/next/DefaultLocationService.ts similarity index 100% rename from plugins/catalog-backend/src/next/DefaultService.ts rename to plugins/catalog-backend/src/next/DefaultLocationService.ts diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts index d30509eaec..f9bb97477c 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { v4 as uuid } from 'uuid'; import { DatabaseManager } from './database/DatabaseManager'; import { DefaultLocationStore } from './DefaultLocationStore'; -import { v4 } from 'uuid'; /* eslint-disable */ -xdescribe('Default Location Store', () => { +xdescribe('DefaultLocationStore', () => { const createLocationStore = async () => { const db = await DatabaseManager.createTestDatabase(); const connection = { applyMutation: jest.fn() }; @@ -111,7 +111,7 @@ xdescribe('Default Location Store', () => { it('throws if the location does not exist', async () => { const { store } = await createLocationStore(); - const id = v4(); + const id = uuid(); await expect(() => store.deleteLocation(id)).rejects.toThrow( new RegExp(`Found no location with ID ${id}`), diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index 28db3790b6..f6267df6a5 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -21,7 +21,7 @@ import { EntityProvider, EntityProviderConnection, } from './types'; -import { v4 as uuidv4 } from 'uuid'; +import { v4 as uuid } from 'uuid'; import { locationSpecToLocationEntity } from './util'; import { ConflictError } from '@backstage/errors'; @@ -50,7 +50,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { // TODO: id should really be type and target combined and not a uuid. const location = await this.db.addLocation(tx, { - id: uuidv4(), + id: uuid(), type: spec.type, target: spec.target, }); diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 7129809c71..10500fdc15 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -19,7 +19,6 @@ import { resolvePackagePath, UrlReader, } from '@backstage/backend-common'; -import fs from 'fs-extra'; import { DefaultNamespaceEntityPolicy, EntityPolicies, @@ -39,6 +38,7 @@ import { EntitiesCatalog, LocationsCatalog, } from '../catalog'; +import { CommonDatabase } from '../database/CommonDatabase'; import { AnnotateLocationEntityProcessor, BitbucketDiscoveryProcessor, @@ -63,16 +63,15 @@ import { } from '../ingestion/processors/PlaceholderProcessor'; import { defaultEntityDataParser } from '../ingestion/processors/util/parse'; import { LocationAnalyzer } from '../ingestion/types'; +import { CatalogProcessingEngine } from '../next/types'; +import { ConfigLocationEntityProvider } from './ConfigLocationEntityProvider'; +import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; -import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; import { DefaultLocationStore } from './DefaultLocationStore'; import { DefaultProcessingStateManager } from './DefaultProcessingStateManager'; -import { CatalogProcessingEngine } from '../next/types'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; -import { CommonDatabase } from '../database/CommonDatabase'; -import { ConfigLocationProvider } from './ConfigLocationProvider'; export type CatalogEnvironment = { logger: Logger; @@ -266,7 +265,7 @@ export class NextCatalogBuilder { const locationStore = new DefaultLocationStore(db); const stitcher = new Stitcher(dbClient, logger); - const configLocationProvider = new ConfigLocationProvider(config); + const configLocationProvider = new ConfigLocationEntityProvider(config); const processingEngine = new DefaultCatalogProcessingEngine( logger, [locationStore, configLocationProvider], diff --git a/plugins/catalog-backend/src/next/database/DatabaseManager.ts b/plugins/catalog-backend/src/next/database/DatabaseManager.ts index f660f73ecb..22ae4e782f 100644 --- a/plugins/catalog-backend/src/next/database/DatabaseManager.ts +++ b/plugins/catalog-backend/src/next/database/DatabaseManager.ts @@ -16,7 +16,7 @@ import { getVoidLogger, resolvePackagePath } from '@backstage/backend-common'; import knexFactory, { Knex } from 'knex'; -import { v4 as uuidv4 } from 'uuid'; +import { v4 as uuid } from 'uuid'; import { Logger } from 'winston'; import { CommonDatabase } from '../../database/CommonDatabase'; import { Database } from '../../database/types'; @@ -79,7 +79,7 @@ export class DatabaseManager { let knex = knexFactory(config); if (typeof config.connection !== 'string') { - const tempDbName = `d${uuidv4().replace(/-/g, '')}`; + const tempDbName = `d${uuid().replace(/-/g, '')}`; await knex.raw(`CREATE DATABASE ${tempDbName};`); knex = knexFactory({ ...config, From 2a4ad54f77fd8e4dbaf03573ada95dba2689b707 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 23:17:43 +0000 Subject: [PATCH 335/462] chore(deps): bump y18n from 3.2.1 to 3.2.2 Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2. - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/commits) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 19aff83248..1e7d42537e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27074,9 +27074,9 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== y18n@^4.0.0: version "4.0.0" From 54ef04e72ac16e2f09ee6016c6dcf714c8683094 Mon Sep 17 00:00:00 2001 From: Heather Lee <heatherl@splunk.com> Date: Wed, 28 Apr 2021 17:21:26 -0700 Subject: [PATCH 336/462] Added lax option to app:build Signed-off-by: Heather Lee <heatherl@splunk.com> --- packages/cli/src/commands/app/build.ts | 1 + packages/cli/src/commands/index.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/cli/src/commands/app/build.ts b/packages/cli/src/commands/app/build.ts index 21189e9427..0da4112646 100644 --- a/packages/cli/src/commands/app/build.ts +++ b/packages/cli/src/commands/app/build.ts @@ -30,6 +30,7 @@ export default async (cmd: Command) => { ...(await loadCliConfig({ args: cmd.config, fromPackage: name, + mockEnv: cmd.lax, })), }); }; diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index c770239464..ae39941106 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -29,6 +29,7 @@ export function registerCommands(program: CommanderStatic) { .command('app:build') .description('Build an app for a production release') .option('--stats', 'Write bundle stats to output directory') + .option('--lax', 'Do not require environment variables to be set') .option(...configOption) .action(lazy(() => import('./app/build').then(m => m.default))); From fc79a6dd3c9932327b50b161409c33469700d231 Mon Sep 17 00:00:00 2001 From: Heather Lee <heatherl@splunk.com> Date: Wed, 28 Apr 2021 17:27:58 -0700 Subject: [PATCH 337/462] Added changeset Signed-off-by: Heather Lee <heatherl@splunk.com> --- .changeset/nice-shirts-fetch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nice-shirts-fetch.md diff --git a/.changeset/nice-shirts-fetch.md b/.changeset/nice-shirts-fetch.md new file mode 100644 index 0000000000..e9537e63b3 --- /dev/null +++ b/.changeset/nice-shirts-fetch.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Added lax option to backstage-cli app:build command From 3923318d8780f51f416f4b688da8d0c9bdfa4d06 Mon Sep 17 00:00:00 2001 From: Heather Lee <heatherl@splunk.com> Date: Wed, 28 Apr 2021 17:41:45 -0700 Subject: [PATCH 338/462] Updated documentation Signed-off-by: Heather Lee <heatherl@splunk.com> --- docs/cli/commands.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/cli/commands.md b/docs/cli/commands.md index 324d17463c..a99d4cd9d0 100644 --- a/docs/cli/commands.md +++ b/docs/cli/commands.md @@ -111,6 +111,7 @@ Usage: backstage-cli app:build Options: --stats Write bundle stats to output directory + --lax Do not require environment variables to be set --config &lt;path&gt; Config files to load instead of app-config.yaml (default: []) -h, --help display help for command ``` @@ -486,6 +487,7 @@ Usage: backstage-cli config:print [options] Options: --package &lt;name&gt; Only load config schema that applies to the given package + --lax Do not require environment variables to be set --frontend Print only the frontend configuration --with-secrets Include secrets in the printed configuration --format &lt;format&gt; Format to print the configuration in, either json or yaml [yaml] @@ -506,6 +508,7 @@ Usage: backstage-cli config:check [options] Options: --package &lt;name&gt; Only load config schema that applies to the given package + --lax Do not require environment variables to be set --config &lt;path&gt; Config files to load instead of app-config.yaml (default: []) -h, --help display help for command ``` From c9307150662e018160c6948ca5c342e7c1787da8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Apr 2021 04:15:56 +0000 Subject: [PATCH 339/462] chore(deps): bump @kubernetes/client-node from 0.14.0 to 0.14.3 Bumps [@kubernetes/client-node](https://github.com/kubernetes-client/javascript) from 0.14.0 to 0.14.3. - [Release notes](https://github.com/kubernetes-client/javascript/releases) - [Changelog](https://github.com/kubernetes-client/javascript/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes-client/javascript/compare/0.14.0...0.14.3) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1e7d42537e..43e5c33ca5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2961,9 +2961,9 @@ integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== "@kubernetes/client-node@^0.14.0": - version "0.14.0" - resolved "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.14.0.tgz#a02806f3b6fdb68fb51d451ee8ff01faa446f557" - integrity sha512-/37JHuEUAQ5GQ4kLKBmCYvGgf5W1KZWKreKGWFYH8VvT2Hl/o0aJZasu2w0EHEfmE11JCn0X9arVmOTyVCYvww== + version "0.14.3" + resolved "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.14.3.tgz#5ed9b88873419080547f22cb74eb502bf6671fca" + integrity sha512-9hHGDNm2JEFQcRTpDxVoAVr0fowU+JH/l5atCXY9VXwvFM18pW5wr2LzLP+Q2Rh+uQv7Moz4gEjEKSCgVKykEQ== dependencies: "@types/js-yaml" "^3.12.1" "@types/node" "^10.12.0" From 08e32cf91327ac57628499c61524fc4e2dff3c46 Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Thu, 29 Apr 2021 10:36:53 +0200 Subject: [PATCH 340/462] Add support for oneOf and allOf Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- .changeset/tough-planes-jump.md | 2 +- .../MultistepJsonForm/schema.test.ts | 96 +++++++++++++++++++ .../components/MultistepJsonForm/schema.ts | 20 +++- 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/.changeset/tough-planes-jump.md b/.changeset/tough-planes-jump.md index a30315e9e4..ebbec65159 100644 --- a/.changeset/tough-planes-jump.md +++ b/.changeset/tough-planes-jump.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -Support anyOf schemas in the scaffolder template +Support `anyOf`, `oneOf` and `allOf` schemas in the scaffolder template. diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts index edfde0ea90..64dd705952 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts @@ -94,6 +94,28 @@ describe('transformSchemaToProps', () => { }, }, ], + oneOf: [ + { + properties: { + field4: { + type: 'string', + default: 'Value 1', + 'ui:readonly': true, + }, + }, + }, + ], + allOf: [ + { + properties: { + field5: { + type: 'string', + default: 'Value 1', + 'ui:readonly': true, + }, + }, + }, + ], properties: { field1: { type: 'object', @@ -117,6 +139,28 @@ describe('transformSchemaToProps', () => { }, }, ], + oneOf: [ + { + properties: { + field4: { + type: 'string', + default: 'Value 1', + 'ui:readonly': true, + }, + }, + }, + ], + allOf: [ + { + properties: { + field5: { + type: 'string', + default: 'Value 1', + 'ui:readonly': true, + }, + }, + }, + ], }, field2: { type: 'string', @@ -144,6 +188,26 @@ describe('transformSchemaToProps', () => { }, }, ], + oneOf: [ + { + properties: { + field4: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], + allOf: [ + { + properties: { + field5: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], properties: { field1: { type: 'object', @@ -165,6 +229,26 @@ describe('transformSchemaToProps', () => { }, }, ], + oneOf: [ + { + properties: { + field4: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], + allOf: [ + { + properties: { + field5: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], }, field2: { type: 'string', @@ -175,10 +259,22 @@ describe('transformSchemaToProps', () => { field3: { 'ui:readonly': true, }, + field4: { + 'ui:readonly': true, + }, + field5: { + 'ui:readonly': true, + }, field1: { field3: { 'ui:readonly': true, }, + field4: { + 'ui:readonly': true, + }, + field5: { + 'ui:readonly': true, + }, }, field2: { 'ui:derp': 'xerp', diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts index c189bbf1a7..b4aa3e309d 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts @@ -26,7 +26,7 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { return; } - const { properties, anyOf } = schema; + const { properties, anyOf, oneOf, allOf } = schema; for (const propName in schema) { if (!schema.hasOwnProperty(propName)) { @@ -63,6 +63,24 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { extractUiSchema(schemaNode, uiSchema); } } + + if (Array.isArray(oneOf)) { + for (const schemaNode of oneOf) { + if (!isObject(schemaNode)) { + continue; + } + extractUiSchema(schemaNode, uiSchema); + } + } + + if (Array.isArray(allOf)) { + for (const schemaNode of allOf) { + if (!isObject(schemaNode)) { + continue; + } + extractUiSchema(schemaNode, uiSchema); + } + } } export function transformSchemaToProps( From e9e56b01ac3d115c81fc511c8f82afa36ce9a9c8 Mon Sep 17 00:00:00 2001 From: Jussi Hallila <jussi@hallila.com> Date: Thu, 29 Apr 2021 09:43:10 +0200 Subject: [PATCH 341/462] Add possibility to use path style discovery on S3 tech docs. Enables the possibility to support S3-like buckets that rely on path style API like Localstack. Signed-off-by: Jussi Hallila <jussi@hallila.com> --- .changeset/tricky-yaks-melt.md | 6 ++++++ .github/styles/vocab.txt | 2 ++ docs/features/techdocs/configuration.md | 5 +++++ packages/techdocs-common/src/stages/publish/awsS3.ts | 7 +++++++ plugins/techdocs-backend/config.d.ts | 7 +++++++ 5 files changed, 27 insertions(+) create mode 100644 .changeset/tricky-yaks-melt.md diff --git a/.changeset/tricky-yaks-melt.md b/.changeset/tricky-yaks-melt.md new file mode 100644 index 0000000000..3679e6d1da --- /dev/null +++ b/.changeset/tricky-yaks-melt.md @@ -0,0 +1,6 @@ +--- +'@backstage/techdocs-common': patch +--- + +Adding optional config to enable S3-like API for tech-docs using s3ForcePathStyle option. +This allows providers like LocalStack, Minio and Wasabi (+possibly others) to be used to host tech docs. diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index a12f638a74..694226b8cc 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -41,8 +41,10 @@ Kaewkasi Knex Leasot Lerna +LocalStack Luxon Minikube +Minio Mkdocs Monorepo Namespaces diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md index c7876f3874..aa38dd42b1 100644 --- a/docs/features/techdocs/configuration.md +++ b/docs/features/techdocs/configuration.md @@ -78,6 +78,11 @@ techdocs: # https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property endpoint: ${AWS_ENDPOINT} + # (Optional) Whether to use path style URLs when communicating with S3. + # Defaults to false. + # This allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used to host tech docs. + s3ForcePathStyle: false + # Required when techdocs.publisher.type is set to 'azureBlobStorage'. Skip otherwise. azureBlobStorage: diff --git a/packages/techdocs-common/src/stages/publish/awsS3.ts b/packages/techdocs-common/src/stages/publish/awsS3.ts index 9c6684fdca..d628c860fd 100644 --- a/packages/techdocs-common/src/stages/publish/awsS3.ts +++ b/packages/techdocs-common/src/stages/publish/awsS3.ts @@ -80,10 +80,17 @@ export class AwsS3Publish implements PublisherBase { 'techdocs.publisher.awsS3.endpoint', ); + // AWS forcePathStyle is an optional config. If missing, it defaults to false. Needs to be enabled for cases + // where endpoint url points to locally hosted S3 compatible storage like Localstack + const s3ForcePathStyle = config.getOptionalBoolean( + 'techdocs.publisher.awsS3.s3ForcePathStyle', + ); + const storageClient = new aws.S3({ credentials, ...(region && { region }), ...(endpoint && { endpoint }), + ...(s3ForcePathStyle && { s3ForcePathStyle }), }); return new AwsS3Publish(storageClient, bucketName, logger); diff --git a/plugins/techdocs-backend/config.d.ts b/plugins/techdocs-backend/config.d.ts index 83b79f2f6c..57dbb5108e 100644 --- a/plugins/techdocs-backend/config.d.ts +++ b/plugins/techdocs-backend/config.d.ts @@ -90,6 +90,13 @@ export interface Config { * @visibility secret */ endpoint?: string; + /** + * (Optional) Whether to use path style URLs when communicating with S3. + * Defaults to false. + * This allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used to host tech docs. + * @visibility backend + */ + endpoint?: string; }; } | { From c6367d81afe6475568a2447d3c2fa85534ea489f Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 29 Apr 2021 10:58:33 +0200 Subject: [PATCH 342/462] chore: updating variable names in terraform doc Signed-off-by: blam <ben@blam.sh> --- .../techdocs-s3-storage/terraform.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/contrib/terraform/techdocs-s3-storage/terraform.tf b/contrib/terraform/techdocs-s3-storage/terraform.tf index ca267f0f12..f256663f43 100644 --- a/contrib/terraform/techdocs-s3-storage/terraform.tf +++ b/contrib/terraform/techdocs-s3-storage/terraform.tf @@ -2,15 +2,15 @@ # Variables #========================== -variable "backstage-bucket" { +variable "backstage_bucket" { default = "backstage_bucket_for_my_corp" } -variable "backstage-iam" { +variable "backstage_iam" { default = "backstage" } -variable "shared-managed-tag-value" { +variable "shared_managed_tag" { default = "terraform_for_my_corp" } @@ -19,7 +19,7 @@ variable "shared-managed-tag-value" { #========================== resource "aws_s3_bucket" "backstage" { - bucket = var.backstage-bucket + bucket = var.backstage_bucket acl = "private" provider = aws @@ -36,8 +36,8 @@ resource "aws_s3_bucket" "backstage" { } tags = { - Name = var.backstage-bucket - "Managed By Terraform" = var.shared-managed-tag-value + Name = var.backstage_bucket + "Managed By Terraform" = var.shared_managed_tag } } @@ -56,16 +56,16 @@ resource "aws_s3_bucket_public_access_block" "backstage" { #========================== resource "aws_iam_user" "backstage" { - name = var.backstage-iam + name = var.backstage_iam } resource "aws_iam_user_policy" "backstage" { - name = var.backstage-iam + name = var.backstage_iam user = aws_iam_user.backstage.name - policy = data.aws_iam_policy_document.backstage-policy.json + policy = data.aws_iam_policy_document.backstage_policy.json } -data "aws_iam_policy_document" "backstage-policy" { +data "aws_iam_policy_document" "backstage_policy" { statement { actions = [ "s3:PutObject", From a99e0bc42c08d81a5a01794baca372f726082860 Mon Sep 17 00:00:00 2001 From: Eric Peterson <iamEAP@users.noreply.github.com> Date: Thu, 29 Apr 2021 11:38:21 +0200 Subject: [PATCH 343/462] [Search] Improvements to DefaultCatalogCollator (#5491) * Add owner/lifecycle to default catalog document and allow location to be configured by integrators. Signed-off-by: Eric Peterson <ericpeterson@spotify.com> * Test the DefaultCatalogCollator Signed-off-by: Eric Peterson <ericpeterson@spotify.com> * Changeset. Signed-off-by: Eric Peterson <ericpeterson@spotify.com> --- .changeset/search-moar-catalog-yo.md | 5 + packages/backend/src/plugins/search.ts | 2 +- .../src/search/DefaultCatalogCollator.test.ts | 91 +++++++++++++++++++ .../src/search/DefaultCatalogCollator.ts | 37 ++++++-- 4 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 .changeset/search-moar-catalog-yo.md create mode 100644 plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts diff --git a/.changeset/search-moar-catalog-yo.md b/.changeset/search-moar-catalog-yo.md new file mode 100644 index 0000000000..4e665157e1 --- /dev/null +++ b/.changeset/search-moar-catalog-yo.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Entity lifecycle and owner are now indexed by the `DefaultCatalogCollator`. A `locationTemplate` may now optionally be provided to its constructor to reflect a custom catalog entity path in the Backstage frontend. diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts index dcd48aaf40..1691f53485 100644 --- a/packages/backend/src/plugins/search.ts +++ b/packages/backend/src/plugins/search.ts @@ -32,7 +32,7 @@ export default async function createPlugin({ indexBuilder.addCollator({ type: 'software-catalog', defaultRefreshIntervalSeconds: 600, - collator: new DefaultCatalogCollator(discovery), + collator: new DefaultCatalogCollator({ discovery }), }); const { scheduler } = await indexBuilder.build(); diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts new file mode 100644 index 0000000000..0764912f0f --- /dev/null +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { Entity } from '@backstage/catalog-model'; +import { DefaultCatalogCollator } from './DefaultCatalogCollator'; + +const expectedEntities: Entity[] = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-entity', + description: 'The expected description', + }, + spec: { + type: 'some-type', + lifecycle: 'experimental', + owner: 'someone', + }, + }, +]; + +jest.mock('cross-fetch', () => ({ + __esModule: true, + default: async () => { + return { + json: async () => { + return expectedEntities; + }, + }; + }, +})); + +describe('DefaultCatalogCollator', () => { + let mockDiscoveryApi: jest.Mocked<PluginEndpointDiscovery>; + let collator: DefaultCatalogCollator; + + beforeEach(() => { + mockDiscoveryApi = { + getBaseUrl: jest.fn().mockResolvedValueOnce('http://localhost:7000'), + getExternalBaseUrl: jest.fn(), + }; + collator = new DefaultCatalogCollator({ discovery: mockDiscoveryApi }); + }); + + it('fetches from the configured catalog service', async () => { + const documents = await collator.execute(); + expect(mockDiscoveryApi.getBaseUrl).toHaveBeenCalledWith('catalog'); + expect(documents).toHaveLength(expectedEntities.length); + }); + + it('maps a returned entity to an expected CatalogEntityDocument', async () => { + const documents = await collator.execute(); + expect(documents[0]).toMatchObject({ + title: expectedEntities[0].metadata.name, + location: '/catalog/default/component/test-entity', + text: expectedEntities[0].metadata.description, + namespace: 'default', + componentType: expectedEntities[0]!.spec!.type, + lifecycle: expectedEntities[0]!.spec!.lifecycle, + owner: expectedEntities[0]!.spec!.owner, + }); + }); + + it('maps a returned entity with a custom locationTemplate', async () => { + // Provide an alternate location template. + collator = new DefaultCatalogCollator({ + discovery: mockDiscoveryApi, + locationTemplate: '/software/:name', + }); + + const documents = await collator.execute(); + expect(documents[0]).toMatchObject({ + location: '/software/test-entity', + }); + }); +}); diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts index 72bf43f8f9..068b9e36ae 100644 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts @@ -23,13 +23,35 @@ export interface CatalogEntityDocument extends IndexableDocument { componentType: string; namespace: string; kind: string; + lifecycle: string; + owner: string; } export class DefaultCatalogCollator implements DocumentCollator { protected discovery: PluginEndpointDiscovery; + protected locationTemplate: string; - constructor(discovery: PluginEndpointDiscovery) { + constructor({ + discovery, + locationTemplate, + }: { + discovery: PluginEndpointDiscovery; + locationTemplate?: string; + }) { this.discovery = discovery; + this.locationTemplate = + locationTemplate || '/catalog/:namespace/:kind/:name'; + } + + protected applyArgsToFormat( + format: string, + args: Record<string, string>, + ): string { + let formatted = format; + for (const [key, value] of Object.entries(args)) { + formatted = formatted.replace(`:${key}`, value); + } + return formatted.toLowerCase(); } async execute() { @@ -37,17 +59,20 @@ export class DefaultCatalogCollator implements DocumentCollator { const res = await fetch(`${baseUrl}/entities`); const entities: Entity[] = await res.json(); return entities.map( - (entity): CatalogEntityDocument => { + (entity: Entity): CatalogEntityDocument => { return { title: entity.metadata.name, - // TODO: Use a config-based template approach for entity location. - location: `/catalog/${ - entity.metadata.namespace || 'default' - }/component/${entity.metadata.name}`, + location: this.applyArgsToFormat(this.locationTemplate, { + namespace: entity.metadata.namespace || 'default', + kind: entity.kind, + name: entity.metadata.name, + }), text: entity.metadata.description || '', componentType: entity.spec?.type?.toString() || 'other', namespace: entity.metadata.namespace || 'default', kind: entity.kind, + lifecycle: (entity.spec?.lifecycle as string) || '', + owner: (entity.spec?.owner as string) || '', }; }, ); From 85409a343ea196ad2814b52fba160f3bccf9d968 Mon Sep 17 00:00:00 2001 From: David Tuite <david@roadie.io> Date: Thu, 29 Apr 2021 10:35:29 +0100 Subject: [PATCH 344/462] Mention error handling on GitHub discovery docs Signed-off-by: David Tuite <david@roadie.io> --- docs/integrations/github/discovery.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index a578d0893d..3e776c8088 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -52,3 +52,13 @@ Backstage to use the [github-apps plugin](../../plugins/github-apps.md). This is true for any method of adding GitHub entities to the catalog, but especially easy to hit with automatic discovery. + +## Error handling + +Syntax errors or other types of errors present in `catalog-info.yaml` files will +be logged for investigation and the importer will continue. Errors do not cause +the process to fail. + +When multiple `catalog-info.yaml` files with the same `metadata.name` property +are discovered, one will be skipped and the process will continue. This action +will be logged for later investication. From ce563d118be2535e7a080252427e1da92af3a000 Mon Sep 17 00:00:00 2001 From: David Tuite <david@roadie.io> Date: Thu, 29 Apr 2021 10:48:04 +0100 Subject: [PATCH 345/462] Fix spelling error Signed-off-by: David Tuite <david@roadie.io> --- docs/integrations/github/discovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 3e776c8088..8d2ca8fb32 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -61,4 +61,4 @@ the process to fail. When multiple `catalog-info.yaml` files with the same `metadata.name` property are discovered, one will be skipped and the process will continue. This action -will be logged for later investication. +will be logged for later investigation. From 4b1ce5edb03474a862de13f78f541ab011b13543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Thu, 29 Apr 2021 12:19:57 +0200 Subject: [PATCH 346/462] fix master lint errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .../src/stages/publish/awsS3.test.ts | 55 ++++++++---------- .../stages/publish/azureBlobStorage.test.ts | 32 +++++------ .../src/stages/publish/googleStorage.test.ts | 53 ++++++++--------- .../src/stages/publish/googleStorage.ts | 2 +- .../src/stages/publish/openStackSwift.test.ts | 57 +++++++++---------- 5 files changed, 90 insertions(+), 109 deletions(-) diff --git a/packages/techdocs-common/src/stages/publish/awsS3.test.ts b/packages/techdocs-common/src/stages/publish/awsS3.test.ts index 15da3b7cfc..f094457346 100644 --- a/packages/techdocs-common/src/stages/publish/awsS3.test.ts +++ b/packages/techdocs-common/src/stages/publish/awsS3.test.ts @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { getVoidLogger } from '@backstage/backend-common'; import { Entity, - ENTITY_DEFAULT_NAMESPACE, EntityName, + ENTITY_DEFAULT_NAMESPACE, } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import mockFs from 'mock-fs'; @@ -154,7 +155,6 @@ describe('AwsS3Publish', () => { }); it('should fail to publish a directory', async () => { - expect.assertions(3); const wrongPathToGeneratedDirectory = path.join( rootDir, 'wrong', @@ -171,23 +171,22 @@ describe('AwsS3Publish', () => { }), ).rejects.toThrowError(); - await publisher - .publish({ - entity, - directory: wrongPathToGeneratedDirectory, - }) - .catch(error => { - expect(error.message).toEqual( - // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error - // Issue reported https://github.com/tschaub/mock-fs/issues/118 - expect.stringContaining( - `Unable to upload file(s) to AWS S3. Error: Failed to read template directory: ENOENT, no such file or directory`, - ), - ); - expect(error.message).toEqual( - expect.stringContaining(wrongPathToGeneratedDirectory), - ); - }); + const fails = publisher.publish({ + entity, + directory: wrongPathToGeneratedDirectory, + }); + + // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error + // Issue reported https://github.com/tschaub/mock-fs/issues/118 + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining( + 'Unable to upload file(s) to AWS S3. Error: Failed to read template directory: ENOENT, no such file or directory', + ), + }); + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining(wrongPathToGeneratedDirectory), + }); + mockFs.restore(); }); }); @@ -265,18 +264,12 @@ describe('AwsS3Publish', () => { const entity = createMockEntity(); const entityRootDir = getEntityRootDir(entity); - await publisher - .fetchTechDocsMetadata(entityNameMock) - .catch(error => - expect(error).toEqual( - new Error( - `TechDocs metadata fetch failed, The file ${path.join( - entityRootDir, - 'techdocs_metadata.json', - )} does not exist !`, - ), - ), - ); + const fails = publisher.fetchTechDocsMetadata(entityNameMock); + + const errorPath = path.join(entityRootDir, 'techdocs_metadata.json'); + await expect(fails).rejects.toMatchObject({ + message: `TechDocs metadata fetch failed, The file ${errorPath} does not exist !`, + }); }); }); }); diff --git a/packages/techdocs-common/src/stages/publish/azureBlobStorage.test.ts b/packages/techdocs-common/src/stages/publish/azureBlobStorage.test.ts index c431e924a8..1160ffe49d 100644 --- a/packages/techdocs-common/src/stages/publish/azureBlobStorage.test.ts +++ b/packages/techdocs-common/src/stages/publish/azureBlobStorage.test.ts @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { getVoidLogger } from '@backstage/backend-common'; import { Entity, - ENTITY_DEFAULT_NAMESPACE, EntityName, + ENTITY_DEFAULT_NAMESPACE, } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import mockFs from 'mock-fs'; @@ -157,7 +158,6 @@ describe('publishing with valid credentials', () => { }); it('should fail to publish a directory', async () => { - expect.assertions(1); const wrongPathToGeneratedDirectory = path.join( rootDir, 'wrong', @@ -168,22 +168,20 @@ describe('publishing with valid credentials', () => { const entity = createMockEntity(); - await publisher - .publish({ - entity, - directory: wrongPathToGeneratedDirectory, - }) - .catch(error => { - // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error - // Issue reported https://github.com/tschaub/mock-fs/issues/118 - expect.stringContaining( - `Unable to upload file(s) to Azure Blob Storage. Error: Failed to read template directory: ENOENT, no such file or directory`, - ); + const fails = publisher.publish({ + entity, + directory: wrongPathToGeneratedDirectory, + }); + + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining( + `Unable to upload file(s) to Azure Blob Storage. Error: Failed to read template directory: ENOENT, no such file or directory`, + ), + }); + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining(wrongPathToGeneratedDirectory), + }); - expect(error.message).toEqual( - expect.stringContaining(wrongPathToGeneratedDirectory), - ); - }); mockFs.restore(); }); diff --git a/packages/techdocs-common/src/stages/publish/googleStorage.test.ts b/packages/techdocs-common/src/stages/publish/googleStorage.test.ts index 7e580b16bc..19e4938763 100644 --- a/packages/techdocs-common/src/stages/publish/googleStorage.test.ts +++ b/packages/techdocs-common/src/stages/publish/googleStorage.test.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { getVoidLogger } from '@backstage/backend-common'; import { Entity, @@ -146,8 +147,6 @@ describe('GoogleGCSPublish', () => { }); it('should fail to publish a directory', async () => { - expect.assertions(3); - const wrongPathToGeneratedDirectory = path.join( rootDir, 'wrong', @@ -165,23 +164,21 @@ describe('GoogleGCSPublish', () => { }), ).rejects.toThrowError(); - await publisher - .publish({ - entity, - directory: wrongPathToGeneratedDirectory, - }) - .catch(error => { - expect(error.message).toEqual( - // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error - // Issue reported https://github.com/tschaub/mock-fs/issues/118 - expect.stringContaining( - `Unable to upload file(s) to Google Cloud Storage. Error: Failed to read template directory: ENOENT, no such file or directory`, - ), - ); - expect(error.message).toEqual( - expect.stringContaining(wrongPathToGeneratedDirectory), - ); - }); + const fails = publisher.publish({ + entity, + directory: wrongPathToGeneratedDirectory, + }); + + // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error + // Issue reported https://github.com/tschaub/mock-fs/issues/118 + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining( + `Unable to upload file(s) to Google Cloud Storage. Error: Failed to read template directory: ENOENT, no such file or directory`, + ), + }); + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining(wrongPathToGeneratedDirectory), + }); mockFs.restore(); }); @@ -264,16 +261,14 @@ describe('GoogleGCSPublish', () => { const entity = createMockEntity(); const entityRootDir = getEntityRootDir(entity); - await publisher - .fetchTechDocsMetadata(entityNameMock) - .catch(errorMessage => - expect(errorMessage).toEqual( - `The file ${path.join( - entityRootDir, - 'techdocs_metadata.json', - )} does not exist !`, - ), - ); + const fails = publisher.fetchTechDocsMetadata(entityNameMock); + + await expect(fails).rejects.toMatchObject({ + message: `The file ${path.join( + entityRootDir, + 'techdocs_metadata.json', + )} does not exist !`, + }); }); }); }); diff --git a/packages/techdocs-common/src/stages/publish/googleStorage.ts b/packages/techdocs-common/src/stages/publish/googleStorage.ts index 28fbb42ece..8adafc361a 100644 --- a/packages/techdocs-common/src/stages/publish/googleStorage.ts +++ b/packages/techdocs-common/src/stages/publish/googleStorage.ts @@ -168,7 +168,7 @@ export class GoogleGCSPublish implements PublisherBase { .createReadStream() .on('error', err => { this.logger.error(err.message); - reject(err.message); + reject(err); }) .on('data', chunk => { fileStreamChunks.push(chunk); diff --git a/packages/techdocs-common/src/stages/publish/openStackSwift.test.ts b/packages/techdocs-common/src/stages/publish/openStackSwift.test.ts index 6f0aacede0..e179aeb9a7 100644 --- a/packages/techdocs-common/src/stages/publish/openStackSwift.test.ts +++ b/packages/techdocs-common/src/stages/publish/openStackSwift.test.ts @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { getVoidLogger } from '@backstage/backend-common'; import { Entity, - ENTITY_DEFAULT_NAMESPACE, EntityName, + ENTITY_DEFAULT_NAMESPACE, } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import mockFs from 'mock-fs'; @@ -157,7 +158,6 @@ describe('OpenStackSwiftPublish', () => { }); it('should fail to publish a directory', async () => { - expect.assertions(3); const wrongPathToGeneratedDirectory = path.join( rootDir, 'wrong', @@ -174,23 +174,22 @@ describe('OpenStackSwiftPublish', () => { }), ).rejects.toThrowError(); - await publisher - .publish({ - entity, - directory: wrongPathToGeneratedDirectory, - }) - .catch(error => { - expect(error.message).toEqual( - // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error - // Issue reported https://github.com/tschaub/mock-fs/issues/118 - expect.stringContaining( - `Unable to upload file(s) to OpenStack Swift. Error: Failed to read template directory: ENOENT, no such file or directory`, - ), - ); - expect(error.message).toEqual( - expect.stringContaining(wrongPathToGeneratedDirectory), - ); - }); + const fails = publisher.publish({ + entity, + directory: wrongPathToGeneratedDirectory, + }); + + // Can not do exact error message match due to mockFs adding unexpected characters in the path when throwing the error + // Issue reported https://github.com/tschaub/mock-fs/issues/118 + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining( + `Unable to upload file(s) to OpenStack Swift. Error: Failed to read template directory: ENOENT, no such file or directory`, + ), + }); + await expect(fails).rejects.toMatchObject({ + message: expect.stringContaining(wrongPathToGeneratedDirectory), + }); + mockFs.restore(); }); }); @@ -268,18 +267,14 @@ describe('OpenStackSwiftPublish', () => { const entity = createMockEntity(); const entityRootDir = getEntityRootDir(entity); - await publisher - .fetchTechDocsMetadata(entityNameMock) - .catch(error => - expect(error).toEqual( - new Error( - `TechDocs metadata fetch failed, The file ${path.join( - entityRootDir, - 'techdocs_metadata.json', - )} does not exist !`, - ), - ), - ); + const fails = publisher.fetchTechDocsMetadata(entityNameMock); + + await expect(fails).rejects.toMatchObject({ + message: `TechDocs metadata fetch failed, The file ${path.join( + entityRootDir, + 'techdocs_metadata.json', + )} does not exist !`, + }); }); }); }); From 6179bff5f08b71359f0deece5d2068f2ecc168bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Thu, 29 Apr 2021 12:59:42 +0200 Subject: [PATCH 347/462] depend on core, not core-api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- plugins/catalog/package.json | 1 - plugins/catalog/src/components/EntityLayout/EntityLayout.tsx | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index d87ca5b7d9..b6b306c260 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -33,7 +33,6 @@ "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", "@backstage/core": "^0.7.6", - "@backstage/core-api": "^0.2.17", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx index e3a8a89b71..dfd27631f8 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx @@ -20,6 +20,7 @@ import { RELATION_OWNED_BY, } from '@backstage/catalog-model'; import { + attachComponentData, Content, Header, HeaderLabel, @@ -34,12 +35,11 @@ import { getEntityRelations, useEntityCompoundName, } from '@backstage/plugin-catalog-react'; -import { attachComponentData } from '@backstage/core-api'; import { Box, TabProps } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; import { - default as React, Children, + default as React, Fragment, isValidElement, useContext, From 44abfaada67300d542caead0a505df4d664c074a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Apr 2021 11:32:12 +0000 Subject: [PATCH 348/462] Version Packages --- .changeset/calm-zebras-remain.md | 7 ---- .../cost-insights-gorgeous-dancers-hope.md | 5 --- .changeset/empty-lizards-doubt.md | 5 --- .changeset/gentle-days-return.md | 21 ---------- .changeset/healthy-phones-press.md | 5 --- .changeset/kind-suns-melt.md | 5 --- .changeset/little-trees-fold.md | 5 --- .changeset/long-ladybugs-promise.md | 5 --- .changeset/pink-islands-help.md | 5 --- .changeset/rare-parrots-share.md | 6 --- .changeset/search-moar-catalog-yo.md | 5 --- .changeset/search-odd-ads-invite.md | 5 --- .changeset/six-rocks-allow.md | 5 --- .changeset/sixty-dragons-retire.md | 5 --- .changeset/small-snakes-shake.md | 5 --- .changeset/small-ways-hunt.md | 6 --- .changeset/techdocs-lovely-wombats-relate.md | 6 --- .changeset/techdocs-mean-humans-hammer.md | 5 --- .changeset/techdocs-quiet-pens-prove.md | 5 --- .changeset/techdocs-red-donkeys-share.md | 5 --- .changeset/techdocs-swift-waves-sleep.md | 12 ------ .changeset/techdocs-young-walls-decide.md | 5 --- .changeset/thin-coins-compete.md | 5 --- .changeset/thirty-humans-knock.md | 5 --- .changeset/tough-planes-jump.md | 5 --- .changeset/witty-lies-shave.md | 5 --- packages/app/CHANGELOG.md | 42 +++++++++++++++++++ packages/app/package.json | 36 ++++++++-------- packages/core/CHANGELOG.md | 8 ++++ packages/core/package.json | 2 +- packages/create-app/CHANGELOG.md | 39 +++++++++++++++++ packages/create-app/package.json | 2 +- packages/techdocs-common/CHANGELOG.md | 6 +++ packages/techdocs-common/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 14 +++++++ plugins/api-docs/package.json | 4 +- plugins/badges/package.json | 2 +- plugins/bitrise/CHANGELOG.md | 10 +++++ plugins/bitrise/package.json | 4 +- plugins/catalog-backend/CHANGELOG.md | 8 ++++ plugins/catalog-backend/package.json | 4 +- plugins/catalog-import/CHANGELOG.md | 10 +++++ plugins/catalog-import/package.json | 4 +- plugins/catalog/CHANGELOG.md | 13 ++++++ plugins/catalog/package.json | 4 +- plugins/circleci/CHANGELOG.md | 10 +++++ plugins/circleci/package.json | 4 +- plugins/cloudbuild/package.json | 2 +- plugins/code-coverage-backend/CHANGELOG.md | 6 +++ plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/package.json | 2 +- plugins/config-schema/package.json | 2 +- plugins/cost-insights/CHANGELOG.md | 11 +++++ plugins/cost-insights/package.json | 4 +- plugins/explore/CHANGELOG.md | 10 +++++ plugins/explore/package.json | 4 +- plugins/fossa/CHANGELOG.md | 10 +++++ plugins/fossa/package.json | 4 +- plugins/gcp-projects/package.json | 2 +- plugins/github-actions/CHANGELOG.md | 11 +++++ plugins/github-actions/package.json | 4 +- plugins/github-deployments/CHANGELOG.md | 10 +++++ plugins/github-deployments/package.json | 4 +- plugins/gitops-profiles/package.json | 2 +- plugins/graphiql/CHANGELOG.md | 10 +++++ plugins/graphiql/package.json | 4 +- plugins/jenkins/CHANGELOG.md | 10 +++++ plugins/jenkins/package.json | 4 +- plugins/kafka/package.json | 2 +- plugins/kubernetes/package.json | 2 +- plugins/lighthouse/CHANGELOG.md | 10 +++++ plugins/lighthouse/package.json | 4 +- plugins/newrelic/package.json | 2 +- plugins/org/package.json | 2 +- plugins/pagerduty/CHANGELOG.md | 10 +++++ plugins/pagerduty/package.json | 4 +- plugins/register-component/CHANGELOG.md | 10 +++++ plugins/register-component/package.json | 4 +- plugins/rollbar/CHANGELOG.md | 10 +++++ plugins/rollbar/package.json | 4 +- plugins/scaffolder-backend/CHANGELOG.md | 6 +++ plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 12 ++++++ plugins/scaffolder/package.json | 4 +- plugins/search-backend-node/CHANGELOG.md | 6 +++ plugins/search-backend-node/package.json | 2 +- plugins/search/CHANGELOG.md | 10 +++++ plugins/search/package.json | 4 +- plugins/sentry/CHANGELOG.md | 10 +++++ plugins/sentry/package.json | 4 +- plugins/sonarqube/CHANGELOG.md | 10 +++++ plugins/sonarqube/package.json | 4 +- plugins/splunk-on-call/package.json | 2 +- plugins/tech-radar/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 26 ++++++++++++ plugins/techdocs/package.json | 4 +- plugins/todo/package.json | 2 +- plugins/user-settings/package.json | 2 +- plugins/welcome/package.json | 2 +- 99 files changed, 441 insertions(+), 241 deletions(-) delete mode 100644 .changeset/calm-zebras-remain.md delete mode 100644 .changeset/cost-insights-gorgeous-dancers-hope.md delete mode 100644 .changeset/empty-lizards-doubt.md delete mode 100644 .changeset/gentle-days-return.md delete mode 100644 .changeset/healthy-phones-press.md delete mode 100644 .changeset/kind-suns-melt.md delete mode 100644 .changeset/little-trees-fold.md delete mode 100644 .changeset/long-ladybugs-promise.md delete mode 100644 .changeset/pink-islands-help.md delete mode 100644 .changeset/rare-parrots-share.md delete mode 100644 .changeset/search-moar-catalog-yo.md delete mode 100644 .changeset/search-odd-ads-invite.md delete mode 100644 .changeset/six-rocks-allow.md delete mode 100644 .changeset/sixty-dragons-retire.md delete mode 100644 .changeset/small-snakes-shake.md delete mode 100644 .changeset/small-ways-hunt.md delete mode 100644 .changeset/techdocs-lovely-wombats-relate.md delete mode 100644 .changeset/techdocs-mean-humans-hammer.md delete mode 100644 .changeset/techdocs-quiet-pens-prove.md delete mode 100644 .changeset/techdocs-red-donkeys-share.md delete mode 100644 .changeset/techdocs-swift-waves-sleep.md delete mode 100644 .changeset/techdocs-young-walls-decide.md delete mode 100644 .changeset/thin-coins-compete.md delete mode 100644 .changeset/thirty-humans-knock.md delete mode 100644 .changeset/tough-planes-jump.md delete mode 100644 .changeset/witty-lies-shave.md diff --git a/.changeset/calm-zebras-remain.md b/.changeset/calm-zebras-remain.md deleted file mode 100644 index 3b961ab3f2..0000000000 --- a/.changeset/calm-zebras-remain.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Resolve issues with AsyncAPI rendering by updating `@asyncapi/react-component` -to `0.23.0`. The theming of the component is adjusted to the latest styling -changes. diff --git a/.changeset/cost-insights-gorgeous-dancers-hope.md b/.changeset/cost-insights-gorgeous-dancers-hope.md deleted file mode 100644 index 8e0abce57f..0000000000 --- a/.changeset/cost-insights-gorgeous-dancers-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-cost-insights': patch ---- - -Support a `name` prop for Projects for display purposes diff --git a/.changeset/empty-lizards-doubt.md b/.changeset/empty-lizards-doubt.md deleted file mode 100644 index cfe1e128fc..0000000000 --- a/.changeset/empty-lizards-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-actions': patch ---- - -Wrap EmptyState in Card diff --git a/.changeset/gentle-days-return.md b/.changeset/gentle-days-return.md deleted file mode 100644 index 96552173bd..0000000000 --- a/.changeset/gentle-days-return.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-explore': patch -'@backstage/plugin-fossa': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-github-deployments': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-lighthouse': patch -'@backstage/plugin-pagerduty': patch -'@backstage/plugin-register-component': patch -'@backstage/plugin-rollbar': patch -'@backstage/plugin-sentry': patch -'@backstage/plugin-sonarqube': patch ---- - -Updated README to have up-to-date install instructions. diff --git a/.changeset/healthy-phones-press.md b/.changeset/healthy-phones-press.md deleted file mode 100644 index c771caefc5..0000000000 --- a/.changeset/healthy-phones-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Allow passing NavLinkProps to SidebarItem component to use in NavLink diff --git a/.changeset/kind-suns-melt.md b/.changeset/kind-suns-melt.md deleted file mode 100644 index 7cbec28fea..0000000000 --- a/.changeset/kind-suns-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Added fields filtering in get API entities to avoid the requesting of unused data diff --git a/.changeset/little-trees-fold.md b/.changeset/little-trees-fold.md deleted file mode 100644 index 4963dd5aa1..0000000000 --- a/.changeset/little-trees-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Updates the end to end test in the app to match the new catalog index page title. To apply this change to an existing app, update `packages/app/cypress/integration/app.js` to search for `"My Company Catalog"` instead of `"My Company Service Catalog"`. diff --git a/.changeset/long-ladybugs-promise.md b/.changeset/long-ladybugs-promise.md deleted file mode 100644 index 7d683650c3..0000000000 --- a/.changeset/long-ladybugs-promise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Enable starred templates on Scaffolder frontend diff --git a/.changeset/pink-islands-help.md b/.changeset/pink-islands-help.md deleted file mode 100644 index c7672f484f..0000000000 --- a/.changeset/pink-islands-help.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-code-coverage-backend': patch ---- - -Include migrations diff --git a/.changeset/rare-parrots-share.md b/.changeset/rare-parrots-share.md deleted file mode 100644 index 917ec5a18e..0000000000 --- a/.changeset/rare-parrots-share.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-catalog': patch -'@backstage/plugin-scaffolder': patch ---- - -Removed unused `swr` dependency. diff --git a/.changeset/search-moar-catalog-yo.md b/.changeset/search-moar-catalog-yo.md deleted file mode 100644 index 4e665157e1..0000000000 --- a/.changeset/search-moar-catalog-yo.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Entity lifecycle and owner are now indexed by the `DefaultCatalogCollator`. A `locationTemplate` may now optionally be provided to its constructor to reflect a custom catalog entity path in the Backstage frontend. diff --git a/.changeset/search-odd-ads-invite.md b/.changeset/search-odd-ads-invite.md deleted file mode 100644 index 0dde3d0c1f..0000000000 --- a/.changeset/search-odd-ads-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-node': patch ---- - -Introduced Scheduler which is responsible for adding new tasks to a schedule together with it's interval timer as well as starting and stopping the scheduler processes. diff --git a/.changeset/six-rocks-allow.md b/.changeset/six-rocks-allow.md deleted file mode 100644 index f207654f45..0000000000 --- a/.changeset/six-rocks-allow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/techdocs-common': patch ---- - -Gracefully handle HTTP request failures in download method of AzureBlobStorage publisher. diff --git a/.changeset/sixty-dragons-retire.md b/.changeset/sixty-dragons-retire.md deleted file mode 100644 index 62965c6e88..0000000000 --- a/.changeset/sixty-dragons-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Use `RouteRef` to generate path to search page. diff --git a/.changeset/small-snakes-shake.md b/.changeset/small-snakes-shake.md deleted file mode 100644 index 6db9db3754..0000000000 --- a/.changeset/small-snakes-shake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Support `gridItem` variant for `EntityLinksCard`. diff --git a/.changeset/small-ways-hunt.md b/.changeset/small-ways-hunt.md deleted file mode 100644 index f0b8dc88cc..0000000000 --- a/.changeset/small-ways-hunt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core': patch -'@backstage/plugin-catalog': patch ---- - -Add `if` prop to `EntityLayout.Route` to conditionally render tabs diff --git a/.changeset/techdocs-lovely-wombats-relate.md b/.changeset/techdocs-lovely-wombats-relate.md deleted file mode 100644 index 33ed205c89..0000000000 --- a/.changeset/techdocs-lovely-wombats-relate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Use `EntityRefLink` in header and use relations to reference the owner of the -document. diff --git a/.changeset/techdocs-mean-humans-hammer.md b/.changeset/techdocs-mean-humans-hammer.md deleted file mode 100644 index 7697650250..0000000000 --- a/.changeset/techdocs-mean-humans-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fix TechDocs landing page table wrong copied link diff --git a/.changeset/techdocs-quiet-pens-prove.md b/.changeset/techdocs-quiet-pens-prove.md deleted file mode 100644 index 379c20e72a..0000000000 --- a/.changeset/techdocs-quiet-pens-prove.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Add customization and exportable components for TechDocs landing page diff --git a/.changeset/techdocs-red-donkeys-share.md b/.changeset/techdocs-red-donkeys-share.md deleted file mode 100644 index 29d932d0b8..0000000000 --- a/.changeset/techdocs-red-donkeys-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Disable color transitions on links to avoid issues in dark mode. diff --git a/.changeset/techdocs-swift-waves-sleep.md b/.changeset/techdocs-swift-waves-sleep.md deleted file mode 100644 index 79d10931cd..0000000000 --- a/.changeset/techdocs-swift-waves-sleep.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -Make `techdocsStorageApiRef` and `techdocsApiRef` use interfaces instead of the -actual implementation classes. - -This renames the classes `TechDocsApi` to `TechDocsClient` and `TechDocsStorageApi` -to `TechDocsStorageClient` and renames the interfaces `TechDocs` to `TechDocsApi` -and `TechDocsStorage` to `TechDocsStorageApi` to comply the pattern elsewhere in -the project. This also fixes the types returned by some methods on those -interfaces. diff --git a/.changeset/techdocs-young-walls-decide.md b/.changeset/techdocs-young-walls-decide.md deleted file mode 100644 index 8dc0373234..0000000000 --- a/.changeset/techdocs-young-walls-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Rework state management to avoid rendering multiple while navigating between pages. diff --git a/.changeset/thin-coins-compete.md b/.changeset/thin-coins-compete.md deleted file mode 100644 index 36511ec1cb..0000000000 --- a/.changeset/thin-coins-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Added the `nebula-preview` preview to `Octokit` for repository visibility. diff --git a/.changeset/thirty-humans-knock.md b/.changeset/thirty-humans-knock.md deleted file mode 100644 index 47545af282..0000000000 --- a/.changeset/thirty-humans-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Improve owner example value in `MissingAnnotationEmptyState`. diff --git a/.changeset/tough-planes-jump.md b/.changeset/tough-planes-jump.md deleted file mode 100644 index ebbec65159..0000000000 --- a/.changeset/tough-planes-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Support `anyOf`, `oneOf` and `allOf` schemas in the scaffolder template. diff --git a/.changeset/witty-lies-shave.md b/.changeset/witty-lies-shave.md deleted file mode 100644 index 68fd4b1137..0000000000 --- a/.changeset/witty-lies-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Switch out the time-based personal greeting for a plain title on the catalog index page, and remove the clocks for different timezones. diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 7262b2ae29..e9d3e63ad0 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,47 @@ # example-app +## 0.2.26 + +### Patch Changes + +- Updated dependencies [1ce80ff02] +- Updated dependencies [b98de52ae] +- Updated dependencies [4c42ecca2] +- Updated dependencies [c614ede9a] +- Updated dependencies [9afcac5af] +- Updated dependencies [07a7806c3] +- Updated dependencies [f6efa71ee] +- Updated dependencies [19a4dd710] +- Updated dependencies [dcd54c7cd] +- Updated dependencies [da546ce00] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6fbd7beca] +- Updated dependencies [15cbe6815] +- Updated dependencies [39bdaa004] +- Updated dependencies [cb8c848a3] +- Updated dependencies [21fddf452] +- Updated dependencies [17915e29b] +- Updated dependencies [6eaecbd81] +- Updated dependencies [23769512a] +- Updated dependencies [1a142ae8a] + - @backstage/plugin-api-docs@0.4.12 + - @backstage/plugin-cost-insights@0.8.5 + - @backstage/plugin-github-actions@0.4.4 + - @backstage/plugin-catalog-import@0.5.4 + - @backstage/plugin-circleci@0.2.13 + - @backstage/plugin-explore@0.3.4 + - @backstage/plugin-graphiql@0.2.10 + - @backstage/plugin-jenkins@0.4.2 + - @backstage/plugin-lighthouse@0.2.15 + - @backstage/plugin-pagerduty@0.3.3 + - @backstage/plugin-rollbar@0.3.4 + - @backstage/plugin-sentry@0.3.9 + - @backstage/core@0.7.7 + - @backstage/plugin-scaffolder@0.9.2 + - @backstage/plugin-catalog@0.5.6 + - @backstage/plugin-search@0.3.5 + - @backstage/plugin-techdocs@0.9.0 + ## 0.2.25 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index ba9af03310..402d09ade4 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,39 +1,39 @@ { "name": "example-app", - "version": "0.2.25", + "version": "0.2.26", "private": true, "bundled": true, "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/cli": "^0.6.9", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/integration-react": "^0.1.1", - "@backstage/plugin-api-docs": "^0.4.11", + "@backstage/plugin-api-docs": "^0.4.12", "@backstage/plugin-badges": "^0.2.0", - "@backstage/plugin-catalog": "^0.5.5", - "@backstage/plugin-catalog-import": "^0.5.3", + "@backstage/plugin-catalog": "^0.5.6", + "@backstage/plugin-catalog-import": "^0.5.4", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/plugin-circleci": "^0.2.12", + "@backstage/plugin-circleci": "^0.2.13", "@backstage/plugin-cloudbuild": "^0.2.13", "@backstage/plugin-code-coverage": "^0.1.2", - "@backstage/plugin-cost-insights": "^0.8.4", - "@backstage/plugin-explore": "^0.3.2", + "@backstage/plugin-cost-insights": "^0.8.5", + "@backstage/plugin-explore": "^0.3.4", "@backstage/plugin-gcp-projects": "^0.2.5", - "@backstage/plugin-github-actions": "^0.4.2", - "@backstage/plugin-graphiql": "^0.2.9", - "@backstage/plugin-jenkins": "^0.4.1", + "@backstage/plugin-github-actions": "^0.4.4", + "@backstage/plugin-graphiql": "^0.2.10", + "@backstage/plugin-jenkins": "^0.4.2", "@backstage/plugin-kafka": "^0.2.6", "@backstage/plugin-kubernetes": "^0.4.2", - "@backstage/plugin-lighthouse": "^0.2.14", + "@backstage/plugin-lighthouse": "^0.2.15", "@backstage/plugin-newrelic": "^0.2.6", "@backstage/plugin-org": "^0.3.12", - "@backstage/plugin-pagerduty": "0.3.2", - "@backstage/plugin-rollbar": "^0.3.3", - "@backstage/plugin-scaffolder": "^0.9.1", - "@backstage/plugin-search": "^0.3.4", - "@backstage/plugin-sentry": "^0.3.8", + "@backstage/plugin-pagerduty": "0.3.3", + "@backstage/plugin-rollbar": "^0.3.4", + "@backstage/plugin-scaffolder": "^0.9.2", + "@backstage/plugin-search": "^0.3.5", + "@backstage/plugin-sentry": "^0.3.9", "@backstage/plugin-tech-radar": "^0.3.9", - "@backstage/plugin-techdocs": "^0.8.0", + "@backstage/plugin-techdocs": "^0.9.0", "@backstage/plugin-todo": "^0.1.0", "@backstage/plugin-user-settings": "^0.2.8", "@backstage/theme": "^0.2.6", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 1b556ac1c3..974dcd3b91 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/core +## 0.7.7 + +### Patch Changes + +- 9afcac5af: Allow passing NavLinkProps to SidebarItem component to use in NavLink +- e0c9ed759: Add `if` prop to `EntityLayout.Route` to conditionally render tabs +- 6eaecbd81: Improve owner example value in `MissingAnnotationEmptyState`. + ## 0.7.6 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 344ea10398..59391e122a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core", "description": "Core API used by Backstage plugins and apps", - "version": "0.7.6", + "version": "0.7.7", "private": false, "publishConfig": { "access": "public", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index c821a3ab81..430e7f003a 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/create-app +## 0.3.20 + +### Patch Changes + +- 73f3f5d78: Updates the end to end test in the app to match the new catalog index page title. To apply this change to an existing app, update `packages/app/cypress/integration/app.js` to search for `"My Company Catalog"` instead of `"My Company Service Catalog"`. +- Updated dependencies [1ce80ff02] +- Updated dependencies [4c42ecca2] +- Updated dependencies [c614ede9a] +- Updated dependencies [9afcac5af] +- Updated dependencies [07a7806c3] +- Updated dependencies [f6efa71ee] +- Updated dependencies [19a4dd710] +- Updated dependencies [a99e0bc42] +- Updated dependencies [dcd54c7cd] +- Updated dependencies [da546ce00] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6fbd7beca] +- Updated dependencies [15cbe6815] +- Updated dependencies [39bdaa004] +- Updated dependencies [cb8c848a3] +- Updated dependencies [21fddf452] +- Updated dependencies [17915e29b] +- Updated dependencies [a1783f306] +- Updated dependencies [6eaecbd81] +- Updated dependencies [23769512a] +- Updated dependencies [1a142ae8a] + - @backstage/plugin-api-docs@0.4.12 + - @backstage/plugin-github-actions@0.4.4 + - @backstage/plugin-catalog-import@0.5.4 + - @backstage/plugin-explore@0.3.4 + - @backstage/plugin-lighthouse@0.2.15 + - @backstage/core@0.7.7 + - @backstage/plugin-scaffolder@0.9.2 + - @backstage/plugin-catalog@0.5.6 + - @backstage/plugin-catalog-backend@0.8.1 + - @backstage/plugin-search@0.3.5 + - @backstage/plugin-techdocs@0.9.0 + - @backstage/plugin-scaffolder-backend@0.10.1 + ## 0.3.19 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 5cf6cdd78e..071a0a5ebd 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "0.3.19", + "version": "0.3.20", "private": false, "publishConfig": { "access": "public" diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md index 9dd6447a14..1788502e45 100644 --- a/packages/techdocs-common/CHANGELOG.md +++ b/packages/techdocs-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/techdocs-common +## 0.5.1 + +### Patch Changes + +- f4af06ebe: Gracefully handle HTTP request failures in download method of AzureBlobStorage publisher. + ## 0.5.0 ### Minor Changes diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index c41dce72b1..e749b33919 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/techdocs-common", "description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "0.5.0", + "version": "0.5.1", "main": "src/index.ts", "types": "src/index.ts", "private": false, diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index a2d5a28e41..f268ba1c4d 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-api-docs +## 0.4.12 + +### Patch Changes + +- 1ce80ff02: Resolve issues with AsyncAPI rendering by updating `@asyncapi/react-component` + to `0.23.0`. The theming of the component is adjusted to the latest styling + changes. +- c614ede9a: Updated README to have up-to-date install instructions. +- 07a7806c3: Added fields filtering in get API entities to avoid the requesting of unused data +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.4.11 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 532dacf684..5c9f9ca7ee 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.4.11", + "version": "0.4.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "dependencies": { "@asyncapi/react-component": "^0.23.0", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.6", "@material-icons/font": "^1.0.2", diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 9f0c49af7e..8f7b5865a1 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/theme": "^0.2.6", diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 66314933bb..ecb26efd50 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-bitrise +## 0.1.2 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.1.1 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 83911cdfc4..950392f732 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bitrise", - "version": "0.1.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,7 +21,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.2", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.2", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 28efc1c5d3..ed87e4dbc5 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-catalog-backend +## 0.8.1 + +### Patch Changes + +- a99e0bc42: Entity lifecycle and owner are now indexed by the `DefaultCatalogCollator`. A `locationTemplate` may now optionally be provided to its constructor to reflect a custom catalog entity path in the Backstage frontend. +- Updated dependencies [e1e757569] + - @backstage/plugin-search-backend-node@0.1.4 + ## 0.8.0 ### Minor Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index a5bb9e00af..7649067a44 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "0.8.0", + "version": "0.8.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ "@backstage/config": "^0.1.4", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", - "@backstage/plugin-search-backend-node": "^0.1.3", + "@backstage/plugin-search-backend-node": "^0.1.4", "@backstage/search-common": "^0.1.1", "@octokit/graphql": "^4.5.8", "@types/express": "^4.17.6", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 8c189a5f9b..4b0d264a52 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-import +## 0.5.4 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.5.3 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 9ba32d830c..ca540fe8be 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.5.3", + "version": "0.5.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.6", "@backstage/catalog-client": "^0.3.9", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/integration": "^0.5.0", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 35e000f130..d6254a347a 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog +## 0.5.6 + +### Patch Changes + +- 19a4dd710: Removed unused `swr` dependency. +- da546ce00: Support `gridItem` variant for `EntityLinksCard`. +- e0c9ed759: Add `if` prop to `EntityLayout.Route` to conditionally render tabs +- 1a142ae8a: Switch out the time-based personal greeting for a plain title on the catalog index page, and remove the clocks for different timezones. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.5.5 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 965a0b327b..4f54735611 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "0.5.5", + "version": "0.5.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "dependencies": { "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index ff01f44258..8c6d6e094d 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-circleci +## 0.2.13 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.2.12 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 5c05c0ee6f..20c757eda0 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-circleci", - "version": "0.2.12", + "version": "0.2.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.2", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 6ad0b8bfa9..cb2a08fce1 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -32,7 +32,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index cfc08db5c4..d7a0f136f5 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-code-coverage-backend +## 0.1.3 + +### Patch Changes + +- d47c2628b: Include migrations + ## 0.1.2 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 3ae76e3fe0..c2bebbf293 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-coverage-backend", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 1adc94fff7..f5c36811cc 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -22,7 +22,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.6", diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 55f785a7a4..a017529400 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/errors": "^0.1.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index 47fa9633bf..c86a71f8c9 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cost-insights +## 0.8.5 + +### Patch Changes + +- b98de52ae: Support a `name` prop for Projects for display purposes +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.8.4 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index c68fdde509..39e3fe1791 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-cost-insights", - "version": "0.8.4", + "version": "0.8.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ }, "dependencies": { "@backstage/config": "^0.1.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index bebf6a8c44..78275577f5 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-explore +## 0.3.4 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.3.3 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 7c2eb5c90d..be61bc1fd9 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore", - "version": "0.3.3", + "version": "0.3.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/plugin-explore-react": "^0.0.4", "@backstage/theme": "^0.2.6", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index fe916804d2..bd7af91dca 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-fossa +## 0.2.6 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.2.5 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 23f9cfde74..ba7e1a381e 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-fossa", - "version": "0.2.5", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 509576cf2b..0930c791e4 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index a2c6e6bf1f..6896a7f877 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-github-actions +## 0.4.4 + +### Patch Changes + +- 4c42ecca2: Wrap EmptyState in Card +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.4.3 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 6a95803d6f..2c26061cf3 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-actions", - "version": "0.4.3", + "version": "0.4.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,7 +34,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.5", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/integration": "^0.5.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index e7f849ef2e..23c8943349 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-github-deployments +## 0.1.4 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.1.3 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 12a36c160e..049e02de4c 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-deployments", - "version": "0.1.3", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,7 +21,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index ae614fe504..d1897b018c 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index 67e39d6600..681005b13f 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-graphiql +## 0.2.10 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.2.9 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 4aa26587ad..9ce1603b57 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.2.9", + "version": "0.2.10", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index ab57d71f61..ac734e9a95 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-jenkins +## 0.4.2 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.4.1 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index edee4bc2ee..d1cabd2143 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-jenkins", - "version": "0.4.1", + "version": "0.4.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index a7295469d6..0963d3178f 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 03013e1480..8d21c79a24 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -33,7 +33,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.4", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/plugin-kubernetes-backend": "^0.3.2", "@backstage/theme": "^0.2.6", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index 26eb041442..cb2cb5b9d1 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-lighthouse +## 0.2.15 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.2.14 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 45980df00c..2fce507756 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-lighthouse", - "version": "0.2.14", + "version": "0.2.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,7 +33,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.2", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 0951d972c2..2dbb2a7eb8 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/org/package.json b/plugins/org/package.json index 5bed02e9c8..9ad4704630 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/core-api": "^0.2.16", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.6", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index 0cd9d0cfb8..b7fc7fec40 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-pagerduty +## 0.3.3 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.3.2 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index c0e3afec34..821b89a5b1 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-pagerduty", - "version": "0.3.2", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/register-component/CHANGELOG.md b/plugins/register-component/CHANGELOG.md index 424887263c..3634972e9a 100644 --- a/plugins/register-component/CHANGELOG.md +++ b/plugins/register-component/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-register-component +## 0.2.14 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.2.13 ### Patch Changes diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index 2870ef79f1..38d1e3202e 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-register-component", - "version": "0.2.13", + "version": "0.2.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 2e9bc946a2..1d8c2c399e 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-rollbar +## 0.3.4 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.3.3 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 6d654866af..64ea010b54 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-rollbar", - "version": "0.3.3", + "version": "0.3.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index cb1855e041..f591568d44 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-scaffolder-backend +## 0.10.1 + +### Patch Changes + +- a1783f306: Added the `nebula-preview` preview to `Octokit` for repository visibility. + ## 0.10.0 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 729ef58d99..355bed4de0 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "0.10.0", + "version": "0.10.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index fee76f8775..1d0bbcede9 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder +## 0.9.2 + +### Patch Changes + +- f6efa71ee: Enable starred templates on Scaffolder frontend +- 19a4dd710: Removed unused `swr` dependency. +- 23769512a: Support `anyOf`, `oneOf` and `allOf` schemas in the scaffolder template. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.9.1 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 2b4feecb7b..3c2c308c24 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "0.9.1", + "version": "0.9.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,7 +33,7 @@ "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index e7a9d9aa0a..da49bd0726 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-search-backend-node +## 0.1.4 + +### Patch Changes + +- e1e757569: Introduced Scheduler which is responsible for adding new tasks to a schedule together with it's interval timer as well as starting and stopping the scheduler processes. + ## 0.1.3 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index b5d13af01c..e39fbb5579 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "0.1.3", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 35f3ee97c1..b4bcd1f855 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-search +## 0.3.5 + +### Patch Changes + +- dcd54c7cd: Use `RouteRef` to generate path to search page. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.3.4 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index c7ab201efe..2b9db3444e 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "0.3.4", + "version": "0.3.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/catalog-model": "^0.7.3", "@backstage/plugin-catalog-react": "^0.1.2", "@backstage/search-common": "^0.1.1", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index dc45bcae60..261972384a 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-sentry +## 0.3.9 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.3.8 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 9908af2e24..e34d8bcef9 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sentry", - "version": "0.3.8", + "version": "0.3.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index 0ed86737dd..48b9292791 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-sonarqube +## 0.1.17 + +### Patch Changes + +- c614ede9a: Updated README to have up-to-date install instructions. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.1.16 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 97243bb930..c31b99bac8 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube", - "version": "0.1.16", + "version": "0.1.17", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,7 +34,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index ecaf21f8eb..9e93004bf5 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.4", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 5a1c2e2095..37ad7d8211 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -30,7 +30,7 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 4f89cd9844..847121c0cf 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-techdocs +## 0.9.0 + +### Minor Changes + +- 21fddf452: Make `techdocsStorageApiRef` and `techdocsApiRef` use interfaces instead of the + actual implementation classes. + + This renames the classes `TechDocsApi` to `TechDocsClient` and `TechDocsStorageApi` + to `TechDocsStorageClient` and renames the interfaces `TechDocs` to `TechDocsApi` + and `TechDocsStorage` to `TechDocsStorageApi` to comply the pattern elsewhere in + the project. This also fixes the types returned by some methods on those + interfaces. + +### Patch Changes + +- 6fbd7beca: Use `EntityRefLink` in header and use relations to reference the owner of the + document. +- 15cbe6815: Fix TechDocs landing page table wrong copied link +- 39bdaa004: Add customization and exportable components for TechDocs landing page +- cb8c848a3: Disable color transitions on links to avoid issues in dark mode. +- 17915e29b: Rework state management to avoid rendering multiple while navigating between pages. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + ## 0.8.0 ### Minor Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 7bde151663..632feac3c1 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "0.8.0", + "version": "0.9.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,7 +33,7 @@ "dependencies": { "@backstage/config": "^0.1.4", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.6", "@backstage/errors": "^0.1.1", diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 7339e568c3..92390857ef 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -27,7 +27,7 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", "@backstage/theme": "^0.2.6", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index d410dc103e..08ae87d3ec 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index b276b86835..189b6eeb59 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -30,7 +30,7 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.7.6", + "@backstage/core": "^0.7.7", "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", From 86891fd2742b8b7624cb80619781aff0383b3385 Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Thu, 29 Apr 2021 12:36:41 +0100 Subject: [PATCH 349/462] Rename 'param' -> 'parameter' in changeset Signed-off-by: Will Sewell <willsewell@monzo.com> --- .changeset/twenty-peas-deny.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/twenty-peas-deny.md b/.changeset/twenty-peas-deny.md index df335ea95a..d149a9337c 100644 --- a/.changeset/twenty-peas-deny.md +++ b/.changeset/twenty-peas-deny.md @@ -2,4 +2,4 @@ '@backstage/catalog-client': patch --- -Allow `filter` param to be specified multiple times +Allow `filter` parameter to be specified multiple times From 1d6159e40db6f665fb8396b5a097fc33ed84776a Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Wed, 14 Apr 2021 17:53:48 +0200 Subject: [PATCH 350/462] kubernetes-common: Adds initial shared types and files Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- packages/kubernetes-common/.eslintrc.js | 0 packages/kubernetes-common/CHANGELOG.md | 7 + packages/kubernetes-common/README.md | 3 + packages/kubernetes-common/package.json | 48 ++++++ packages/kubernetes-common/src/index.ts | 17 ++ packages/kubernetes-common/src/types.ts | 208 ++++++++++++++++++++++++ 6 files changed, 283 insertions(+) create mode 100644 packages/kubernetes-common/.eslintrc.js create mode 100644 packages/kubernetes-common/CHANGELOG.md create mode 100644 packages/kubernetes-common/README.md create mode 100644 packages/kubernetes-common/package.json create mode 100644 packages/kubernetes-common/src/index.ts create mode 100644 packages/kubernetes-common/src/types.ts diff --git a/packages/kubernetes-common/.eslintrc.js b/packages/kubernetes-common/.eslintrc.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/kubernetes-common/CHANGELOG.md b/packages/kubernetes-common/CHANGELOG.md new file mode 100644 index 0000000000..4b73dbafad --- /dev/null +++ b/packages/kubernetes-common/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/techdocs-common + +## 0.1.0 + +### Minor Changes + +- Adds the following types to be shared by the backend and the front end: \ No newline at end of file diff --git a/packages/kubernetes-common/README.md b/packages/kubernetes-common/README.md new file mode 100644 index 0000000000..db3989cdcb --- /dev/null +++ b/packages/kubernetes-common/README.md @@ -0,0 +1,3 @@ +# @backstage/kubernetes-common + +Common types and functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend. \ No newline at end of file diff --git a/packages/kubernetes-common/package.json b/packages/kubernetes-common/package.json new file mode 100644 index 0000000000..ff541911ba --- /dev/null +++ b/packages/kubernetes-common/package.json @@ -0,0 +1,48 @@ +{ + "name": "@backstage/kubernetes-common", + "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/kubernetes-common" + }, + "keywords": [ + "techdocs", + "kubernetes" + ], + "files": [ + "dist" + ], + "scripts": { + "build": "backstage-cli build --outputs cjs,types", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, + "dependencies": { + "@kubernetes/client-node": "^0.14.0" + }, + "devDependencies": { + "@backstage/cli": "^0.6.5" + }, + "jest": { + "roots": [ + ".." + ] + } +} diff --git a/packages/kubernetes-common/src/index.ts b/packages/kubernetes-common/src/index.ts new file mode 100644 index 0000000000..50e9534751 --- /dev/null +++ b/packages/kubernetes-common/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './types'; diff --git a/packages/kubernetes-common/src/types.ts b/packages/kubernetes-common/src/types.ts new file mode 100644 index 0000000000..84ca08585b --- /dev/null +++ b/packages/kubernetes-common/src/types.ts @@ -0,0 +1,208 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ExtensionsV1beta1Ingress, + V1ConfigMap, + V1Deployment, + V1HorizontalPodAutoscaler, + V1Pod, + V1ReplicaSet, + V1Service, +} from '@kubernetes/client-node'; +import { Entity } from '@backstage/catalog-model'; + +export interface ClusterDetails { + name: string; + url: string; + authProvider: string; + serviceAccountToken?: string | undefined; +} + +export interface KubernetesRequestBody { + auth?: { + google?: string; + }; + entity: Entity; +} + +export interface ClusterObjects { + cluster: { name: string }; + resources: FetchResponse[]; + errors: KubernetesFetchError[]; +} + +export interface ObjectsByEntityResponse { + items: ClusterObjects[]; +} + +export interface FetchResponseWrapper { + errors: KubernetesFetchError[]; + responses: FetchResponse[]; +} + +export type FetchResponse = + | PodFetchResponse + | ServiceFetchResponse + | ConfigMapFetchResponse + | DeploymentFetchResponse + | ReplicaSetsFetchResponse + | HorizontalPodAutoscalersFetchResponse + | IngressesFetchResponse + | CustomResourceFetchResponse; + +// TODO fairly sure there's a easier way to do this + +export type KubernetesObjectTypes = + | 'pods' + | 'services' + | 'configmaps' + | 'deployments' + | 'replicasets' + | 'horizontalpodautoscalers' + | 'ingresses' + | 'customresources'; + +export interface PodFetchResponse { + type: 'pods'; + resources: Array<V1Pod>; +} + +export interface ServiceFetchResponse { + type: 'services'; + resources: Array<V1Service>; +} + +export interface ConfigMapFetchResponse { + type: 'configmaps'; + resources: Array<V1ConfigMap>; +} + +export interface DeploymentFetchResponse { + type: 'deployments'; + resources: Array<V1Deployment>; +} + +export interface ReplicaSetsFetchResponse { + type: 'replicasets'; + resources: Array<V1ReplicaSet>; +} + +export interface HorizontalPodAutoscalersFetchResponse { + type: 'horizontalpodautoscalers'; + resources: Array<V1HorizontalPodAutoscaler>; +} + +export interface IngressesFetchResponse { + type: 'ingresses'; + resources: Array<ExtensionsV1beta1Ingress>; +} + +export interface CustomResourceFetchResponse { + type: 'customresources'; + resources: Array<any>; +} + +export interface ObjectFetchParams { + serviceId: string; + clusterDetails: ClusterDetails; + objectTypesToFetch: Set<KubernetesObjectTypes>; + labelSelector: string; + customResources: CustomResource[]; +} + +// Fetches information from a kubernetes cluster using the cluster details object +// to target a specific cluster +export interface KubernetesFetcher { + fetchObjectsForService( + params: ObjectFetchParams, + ): Promise<FetchResponseWrapper>; +} + +// Used to locate which cluster(s) a service is running on +export interface KubernetesServiceLocator { + getClustersByServiceId(serviceId: string): Promise<ClusterDetails[]>; +} + +// Used to load cluster details from different sources +export interface KubernetesClustersSupplier { + getClusters(): Promise<ClusterDetails[]>; +} + +export type KubernetesErrorTypes = + | 'BAD_REQUEST' + | 'UNAUTHORIZED_ERROR' + | 'SYSTEM_ERROR' + | 'UNKNOWN_ERROR'; + +export interface KubernetesFetchError { + errorType: KubernetesErrorTypes; + statusCode?: number; + resourcePath?: string; +} + +export interface ConfigClusterLocatorMethod { + /** + * @visibility frontend + */ + type: 'config'; + clusters: { + /** + * @visibility frontend + */ + url: string; + /** + * @visibility frontend + */ + name: string; + /** + * @visibility secret + */ + serviceAccountToken: string | undefined; + /** + * @visibility frontend + */ + authProvider: 'aws' | 'google' | 'serviceAccount'; + }[]; +} + +export interface GKEClusterLocatorMethod { + /** + * @visibility frontend + */ + type: 'gke'; + /** + * @visibility frontend + */ + projectId: string; + /** + * @visibility frontend + */ + region?: string; +} + +export type ClusterLocatorMethod = + | ConfigClusterLocatorMethod + | GKEClusterLocatorMethod; + +export type ServiceLocatorMethod = 'multiTenant' | 'http'; // TODO implement http +export type AuthProviderType = 'google' | 'serviceAccount' | 'aws'; + +export interface CustomResource { + group: string; + apiVersion: string; + plural: string; +} From 1f790d756fa6a796217b693eef109f872b80dfc1 Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Wed, 14 Apr 2021 17:54:18 +0200 Subject: [PATCH 351/462] kubernetes-backend: Updates kube backend to reexport types from common Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes-backend/package.json | 1 + plugins/kubernetes-backend/src/types/types.ts | 208 ++---------------- 2 files changed, 16 insertions(+), 193 deletions(-) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 7a8b16bc8a..6c600f4d8b 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -34,6 +34,7 @@ "@backstage/backend-common": "^0.6.3", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", + "@backstage/kubernetes-common": "^0.1.0", "@google-cloud/container": "^2.2.0", "@kubernetes/client-node": "^0.14.0", "@types/express": "^4.17.6", diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index c597c718c5..2316740af0 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -14,196 +14,18 @@ * limitations under the License. */ -import { - ExtensionsV1beta1Ingress, - V1ConfigMap, - V1Deployment, - V1HorizontalPodAutoscaler, - V1Pod, - V1ReplicaSet, - V1Service, -} from '@kubernetes/client-node'; -import { Entity } from '@backstage/catalog-model'; - -export interface ClusterDetails { - name: string; - url: string; - authProvider: string; - serviceAccountToken?: string | undefined; - skipTLSVerify?: boolean; -} - -export interface KubernetesRequestBody { - auth?: { - google?: string; - }; - entity: Entity; -} - -export interface ClusterObjects { - cluster: { name: string }; - resources: FetchResponse[]; - errors: KubernetesFetchError[]; -} - -export interface ObjectsByEntityResponse { - items: ClusterObjects[]; -} - -export interface FetchResponseWrapper { - errors: KubernetesFetchError[]; - responses: FetchResponse[]; -} - -export type FetchResponse = - | PodFetchResponse - | ServiceFetchResponse - | ConfigMapFetchResponse - | DeploymentFetchResponse - | ReplicaSetsFetchResponse - | HorizontalPodAutoscalersFetchResponse - | IngressesFetchResponse - | CustomResourceFetchResponse; - -// TODO fairly sure there's a easier way to do this - -export type KubernetesObjectTypes = - | 'pods' - | 'services' - | 'configmaps' - | 'deployments' - | 'replicasets' - | 'horizontalpodautoscalers' - | 'ingresses' - | 'customresources'; - -export interface PodFetchResponse { - type: 'pods'; - resources: Array<V1Pod>; -} - -export interface ServiceFetchResponse { - type: 'services'; - resources: Array<V1Service>; -} - -export interface ConfigMapFetchResponse { - type: 'configmaps'; - resources: Array<V1ConfigMap>; -} - -export interface DeploymentFetchResponse { - type: 'deployments'; - resources: Array<V1Deployment>; -} - -export interface ReplicaSetsFetchResponse { - type: 'replicasets'; - resources: Array<V1ReplicaSet>; -} - -export interface HorizontalPodAutoscalersFetchResponse { - type: 'horizontalpodautoscalers'; - resources: Array<V1HorizontalPodAutoscaler>; -} - -export interface IngressesFetchResponse { - type: 'ingresses'; - resources: Array<ExtensionsV1beta1Ingress>; -} - -export interface CustomResourceFetchResponse { - type: 'customresources'; - resources: Array<any>; -} - -export interface ObjectFetchParams { - serviceId: string; - clusterDetails: ClusterDetails; - objectTypesToFetch: Set<KubernetesObjectTypes>; - labelSelector: string; - customResources: CustomResource[]; -} - -// Fetches information from a kubernetes cluster using the cluster details object -// to target a specific cluster -export interface KubernetesFetcher { - fetchObjectsForService( - params: ObjectFetchParams, - ): Promise<FetchResponseWrapper>; -} - -// Used to locate which cluster(s) a service is running on -export interface KubernetesServiceLocator { - getClustersByServiceId(serviceId: string): Promise<ClusterDetails[]>; -} - -// Used to load cluster details from different sources -export interface KubernetesClustersSupplier { - getClusters(): Promise<ClusterDetails[]>; -} - -export type KubernetesErrorTypes = - | 'BAD_REQUEST' - | 'UNAUTHORIZED_ERROR' - | 'SYSTEM_ERROR' - | 'UNKNOWN_ERROR'; - -export interface KubernetesFetchError { - errorType: KubernetesErrorTypes; - statusCode?: number; - resourcePath?: string; -} - -export interface ConfigClusterLocatorMethod { - /** - * @visibility frontend - */ - type: 'config'; - clusters: { - /** - * @visibility frontend - */ - url: string; - /** - * @visibility frontend - */ - name: string; - /** - * @visibility secret - */ - serviceAccountToken: string | undefined; - /** - * @visibility frontend - */ - authProvider: 'aws' | 'google' | 'serviceAccount'; - }[]; -} - -export interface GKEClusterLocatorMethod { - /** - * @visibility frontend - */ - type: 'gke'; - /** - * @visibility frontend - */ - projectId: string; - /** - * @visibility frontend - */ - region?: string; -} - -export type ClusterLocatorMethod = - | ConfigClusterLocatorMethod - | GKEClusterLocatorMethod; - -export type ServiceLocatorMethod = 'multiTenant' | 'http'; // TODO implement http -export type AuthProviderType = 'google' | 'serviceAccount' | 'aws'; - -export interface CustomResource { - group: string; - apiVersion: string; - plural: string; -} +export type { + ClusterDetails, + CustomResource, + FetchResponse, + FetchResponseWrapper, + KubernetesClustersSupplier, + KubernetesErrorTypes, + KubernetesFetchError, + KubernetesFetcher, + KubernetesObjectTypes, + KubernetesRequestBody, + KubernetesServiceLocator, + ObjectFetchParams, + ServiceLocatorMethod, +} from '@backstage/kubernetes-common'; From 0b61c22e0af1fdc74e74b5556cef9994b64b3c7e Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Wed, 14 Apr 2021 17:55:09 +0200 Subject: [PATCH 352/462] kubernetes: Updates kubernetes frontend to use common Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes/package.json | 4 ++-- plugins/kubernetes/schema.d.ts | 2 +- plugins/kubernetes/src/api/KubernetesBackendClient.ts | 2 +- plugins/kubernetes/src/api/types.ts | 2 +- .../src/components/KubernetesContent/ErrorPanel.tsx | 2 +- .../src/components/KubernetesContent/KubernetesContent.tsx | 2 +- .../kubernetes/src/error-detection/error-detection.test.ts | 2 +- plugins/kubernetes/src/error-detection/error-detection.ts | 2 +- plugins/kubernetes/src/hooks/useKubernetesObjects.ts | 2 +- .../src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts | 2 +- .../kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts | 2 +- .../src/kubernetes-auth-provider/KubernetesAuthProviders.ts | 2 +- .../ServiceAccountKubernetesAuthProvider.ts | 2 +- plugins/kubernetes/src/kubernetes-auth-provider/types.ts | 2 +- plugins/kubernetes/src/utils/response.ts | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 03013e1480..7c607b1776 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -34,8 +34,8 @@ "@backstage/catalog-model": "^0.7.4", "@backstage/config": "^0.1.4", "@backstage/core": "^0.7.6", - "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/plugin-kubernetes-backend": "^0.3.2", + "@backstage/kubernetes-common": "^0.1.0", + "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/theme": "^0.2.6", "@kubernetes/client-node": "^0.14.0", "@material-ui/core": "^4.11.0", diff --git a/plugins/kubernetes/schema.d.ts b/plugins/kubernetes/schema.d.ts index 196f5ba76d..e421100760 100644 --- a/plugins/kubernetes/schema.d.ts +++ b/plugins/kubernetes/schema.d.ts @@ -17,7 +17,7 @@ import { ClusterLocatorMethod, CustomResource, -} from '@backstage/plugin-kubernetes-backend'; +} from '@backstage/kubernetes-common'; export interface Config { kubernetes?: { diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes/src/api/KubernetesBackendClient.ts index 1eadec3fb0..0bbba7c8f7 100644 --- a/plugins/kubernetes/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes/src/api/KubernetesBackendClient.ts @@ -19,7 +19,7 @@ import { KubernetesApi } from './types'; import { KubernetesRequestBody, ObjectsByEntityResponse, -} from '@backstage/plugin-kubernetes-backend'; +} from '@backstage/kubernetes-common'; export class KubernetesBackendClient implements KubernetesApi { private readonly discoveryApi: DiscoveryApi; diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes/src/api/types.ts index da1b36989a..a575aea4b8 100644 --- a/plugins/kubernetes/src/api/types.ts +++ b/plugins/kubernetes/src/api/types.ts @@ -18,7 +18,7 @@ import { createApiRef } from '@backstage/core'; import { KubernetesRequestBody, ObjectsByEntityResponse, -} from '@backstage/plugin-kubernetes-backend'; +} from '@backstage/kubernetes-common'; export const kubernetesApiRef = createApiRef<KubernetesApi>({ id: 'plugin.kubernetes.service', diff --git a/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx b/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx index 650e6ddff1..2261cd5e3f 100644 --- a/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx +++ b/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { WarningPanel } from '@backstage/core'; import { Typography } from '@material-ui/core'; -import { ClusterObjects } from '@backstage/plugin-kubernetes-backend'; +import { ClusterObjects } from '@backstage/kubernetes-common'; const clustersWithErrorsToErrorMessage = ( clustersWithErrors: ClusterObjects[], diff --git a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx index cda8dd7e6b..5b30c62949 100644 --- a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx +++ b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx @@ -31,7 +31,7 @@ import { StatusOK, } from '@backstage/core'; import { Entity } from '@backstage/catalog-model'; -import { ClusterObjects } from '@backstage/plugin-kubernetes-backend'; +import { ClusterObjects } from '@backstage/kubernetes-common'; import { ErrorPanel } from './ErrorPanel'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { DeploymentsAccordions } from '../DeploymentsAccordions'; diff --git a/plugins/kubernetes/src/error-detection/error-detection.test.ts b/plugins/kubernetes/src/error-detection/error-detection.test.ts index 8a4575c8be..50cf81a522 100644 --- a/plugins/kubernetes/src/error-detection/error-detection.test.ts +++ b/plugins/kubernetes/src/error-detection/error-detection.test.ts @@ -30,7 +30,7 @@ import * as maxedOutHpa from './__fixtures__/hpa-maxed-out.json'; import { FetchResponse, ObjectsByEntityResponse, -} from '@backstage/plugin-kubernetes-backend'; +} from '@backstage/kubernetes-common'; const CLUSTER_NAME = 'cluster-a'; diff --git a/plugins/kubernetes/src/error-detection/error-detection.ts b/plugins/kubernetes/src/error-detection/error-detection.ts index a44747969d..5cffbc181f 100644 --- a/plugins/kubernetes/src/error-detection/error-detection.ts +++ b/plugins/kubernetes/src/error-detection/error-detection.ts @@ -15,7 +15,7 @@ */ import { DetectedError, DetectedErrorsByCluster } from './types'; -import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-backend'; +import { ObjectsByEntityResponse } from '@backstage/kubernetes-common'; import { groupResponses } from '../utils/response'; import { detectErrorsInPods } from './pods'; import { detectErrorsInDeployments } from './deployments'; diff --git a/plugins/kubernetes/src/hooks/useKubernetesObjects.ts b/plugins/kubernetes/src/hooks/useKubernetesObjects.ts index 7c4de9ff1a..44434ec8f5 100644 --- a/plugins/kubernetes/src/hooks/useKubernetesObjects.ts +++ b/plugins/kubernetes/src/hooks/useKubernetesObjects.ts @@ -22,7 +22,7 @@ import { useEffect, useState } from 'react'; import { KubernetesRequestBody, ObjectsByEntityResponse, -} from '@backstage/plugin-kubernetes-backend'; +} from '@backstage/kubernetes-common'; export interface KubernetesObjects { kubernetesObjects: ObjectsByEntityResponse | undefined; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts index cab81f3622..cb14574bdc 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts @@ -15,7 +15,7 @@ */ import { KubernetesAuthProvider } from './types'; -import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-backend'; +import { KubernetesRequestBody } from '@backstage/kubernetes-common'; export class AwsKubernetesAuthProvider implements KubernetesAuthProvider { async decorateRequestBodyForAuth( diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts index 570806a1a4..649f0c14da 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts @@ -16,7 +16,7 @@ import { OAuthApi } from '@backstage/core'; import { KubernetesAuthProvider } from './types'; -import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-backend'; +import { KubernetesRequestBody } from '@backstage/kubernetes-common'; export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { authProvider: OAuthApi; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts index dc9d9b5e0d..bc74b2717f 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts @@ -15,7 +15,7 @@ */ import { OAuthApi } from '@backstage/core'; -import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-backend'; +import { KubernetesRequestBody } from '@backstage/kubernetes-common'; import { KubernetesAuthProvider, KubernetesAuthProvidersApi } from './types'; import { GoogleKubernetesAuthProvider } from './GoogleKubernetesAuthProvider'; import { ServiceAccountKubernetesAuthProvider } from './ServiceAccountKubernetesAuthProvider'; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts index 5d33521ae4..f54c51bf48 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts @@ -15,7 +15,7 @@ */ import { KubernetesAuthProvider } from './types'; -import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-backend'; +import { KubernetesRequestBody } from '@backstage/kubernetes-common'; export class ServiceAccountKubernetesAuthProvider implements KubernetesAuthProvider { diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/types.ts b/plugins/kubernetes/src/kubernetes-auth-provider/types.ts index 2bed2838b9..afb2615939 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/types.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/types.ts @@ -15,7 +15,7 @@ */ import { createApiRef } from '@backstage/core'; -import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-backend'; +import { KubernetesRequestBody } from '@backstage/kubernetes-common'; export interface KubernetesAuthProvider { decorateRequestBodyForAuth( diff --git a/plugins/kubernetes/src/utils/response.ts b/plugins/kubernetes/src/utils/response.ts index a9b10e7759..a38010ba74 100644 --- a/plugins/kubernetes/src/utils/response.ts +++ b/plugins/kubernetes/src/utils/response.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FetchResponse } from '@backstage/plugin-kubernetes-backend'; +import { FetchResponse } from '@backstage/kubernetes-common'; import { GroupedResponses } from '../types/types'; // TODO this could probably be a lodash groupBy From f53fba29f6559c4ca0560100e1bccdef424a6476 Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Wed, 14 Apr 2021 18:15:47 +0200 Subject: [PATCH 353/462] kubernetes-common: Adds changeset and fixes linting Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- .changeset/silly-tables-build.md | 6 ++++++ packages/kubernetes-common/.eslintrc.js | 3 +++ packages/kubernetes-common/CHANGELOG.md | 2 +- packages/kubernetes-common/README.md | 2 +- packages/kubernetes-common/package.json | 1 + 5 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 .changeset/silly-tables-build.md diff --git a/.changeset/silly-tables-build.md b/.changeset/silly-tables-build.md new file mode 100644 index 0000000000..3f7b3182dd --- /dev/null +++ b/.changeset/silly-tables-build.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-kubernetes-backend': patch +--- + +Adds @backstage/kubernetes-common library to share types between kubernetes frontend and backend. diff --git a/packages/kubernetes-common/.eslintrc.js b/packages/kubernetes-common/.eslintrc.js index e69de29bb2..16a033dbc6 100644 --- a/packages/kubernetes-common/.eslintrc.js +++ b/packages/kubernetes-common/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/packages/kubernetes-common/CHANGELOG.md b/packages/kubernetes-common/CHANGELOG.md index 4b73dbafad..a10c37c7d1 100644 --- a/packages/kubernetes-common/CHANGELOG.md +++ b/packages/kubernetes-common/CHANGELOG.md @@ -4,4 +4,4 @@ ### Minor Changes -- Adds the following types to be shared by the backend and the front end: \ No newline at end of file +- Adds types to be shared by the backend and the front end. diff --git a/packages/kubernetes-common/README.md b/packages/kubernetes-common/README.md index db3989cdcb..0034efbbff 100644 --- a/packages/kubernetes-common/README.md +++ b/packages/kubernetes-common/README.md @@ -1,3 +1,3 @@ # @backstage/kubernetes-common -Common types and functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend. \ No newline at end of file +Common types and functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend. diff --git a/packages/kubernetes-common/package.json b/packages/kubernetes-common/package.json index ff541911ba..9494b29ed0 100644 --- a/packages/kubernetes-common/package.json +++ b/packages/kubernetes-common/package.json @@ -35,6 +35,7 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { + "@backstage/catalog-model": "^0.7.6", "@kubernetes/client-node": "^0.14.0" }, "devDependencies": { From 1cf63d00df1abc0d62f0f1f0f57e3750a46b86db Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 15 Apr 2021 10:21:25 +0200 Subject: [PATCH 354/462] plugin-kubernetes-common: Moves packages/kuberntes-common to plugins as per ADR11 Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-backend/src/types/types.ts | 2 +- {packages => plugins}/kubernetes-common/.eslintrc.js | 0 {packages => plugins}/kubernetes-common/CHANGELOG.md | 2 +- {packages => plugins}/kubernetes-common/README.md | 2 +- {packages => plugins}/kubernetes-common/package.json | 4 ++-- {packages => plugins}/kubernetes-common/src/index.ts | 0 {packages => plugins}/kubernetes-common/src/types.ts | 0 plugins/kubernetes/schema.d.ts | 2 +- plugins/kubernetes/src/api/KubernetesBackendClient.ts | 2 +- plugins/kubernetes/src/api/types.ts | 2 +- .../src/components/KubernetesContent/ErrorPanel.tsx | 2 +- .../src/components/KubernetesContent/KubernetesContent.tsx | 2 +- .../kubernetes/src/error-detection/error-detection.test.ts | 2 +- plugins/kubernetes/src/error-detection/error-detection.ts | 2 +- plugins/kubernetes/src/hooks/useKubernetesObjects.ts | 2 +- .../src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts | 2 +- .../kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts | 2 +- .../src/kubernetes-auth-provider/KubernetesAuthProviders.ts | 2 +- .../ServiceAccountKubernetesAuthProvider.ts | 2 +- plugins/kubernetes/src/kubernetes-auth-provider/types.ts | 2 +- plugins/kubernetes/src/utils/response.ts | 2 +- 22 files changed, 20 insertions(+), 20 deletions(-) rename {packages => plugins}/kubernetes-common/.eslintrc.js (100%) rename {packages => plugins}/kubernetes-common/CHANGELOG.md (70%) rename {packages => plugins}/kubernetes-common/README.md (73%) rename {packages => plugins}/kubernetes-common/package.json (92%) rename {packages => plugins}/kubernetes-common/src/index.ts (100%) rename {packages => plugins}/kubernetes-common/src/types.ts (100%) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 6c600f4d8b..3c8380b661 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -34,7 +34,7 @@ "@backstage/backend-common": "^0.6.3", "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/kubernetes-common": "^0.1.0", + "@backstage/plugin-kubernetes-common": "^0.1.0", "@google-cloud/container": "^2.2.0", "@kubernetes/client-node": "^0.14.0", "@types/express": "^4.17.6", diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 2316740af0..119ca0451e 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -28,4 +28,4 @@ export type { KubernetesServiceLocator, ObjectFetchParams, ServiceLocatorMethod, -} from '@backstage/kubernetes-common'; +} from '@backstage/plugin-kubernetes-common'; diff --git a/packages/kubernetes-common/.eslintrc.js b/plugins/kubernetes-common/.eslintrc.js similarity index 100% rename from packages/kubernetes-common/.eslintrc.js rename to plugins/kubernetes-common/.eslintrc.js diff --git a/packages/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md similarity index 70% rename from packages/kubernetes-common/CHANGELOG.md rename to plugins/kubernetes-common/CHANGELOG.md index a10c37c7d1..44c9066ada 100644 --- a/packages/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,4 +1,4 @@ -# @backstage/techdocs-common +# @backstage/plugin-kubernetes-common ## 0.1.0 diff --git a/packages/kubernetes-common/README.md b/plugins/kubernetes-common/README.md similarity index 73% rename from packages/kubernetes-common/README.md rename to plugins/kubernetes-common/README.md index 0034efbbff..c366d0493c 100644 --- a/packages/kubernetes-common/README.md +++ b/plugins/kubernetes-common/README.md @@ -1,3 +1,3 @@ -# @backstage/kubernetes-common +# @backstage/plugin-kubernetes-common Common types and functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend. diff --git a/packages/kubernetes-common/package.json b/plugins/kubernetes-common/package.json similarity index 92% rename from packages/kubernetes-common/package.json rename to plugins/kubernetes-common/package.json index 9494b29ed0..813b965c2c 100644 --- a/packages/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,5 +1,5 @@ { - "name": "@backstage/kubernetes-common", + "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", "version": "0.1.0", "main": "src/index.ts", @@ -14,7 +14,7 @@ "repository": { "type": "git", "url": "https://github.com/backstage/backstage", - "directory": "packages/kubernetes-common" + "directory": "plugin/kubernetes-common" }, "keywords": [ "techdocs", diff --git a/packages/kubernetes-common/src/index.ts b/plugins/kubernetes-common/src/index.ts similarity index 100% rename from packages/kubernetes-common/src/index.ts rename to plugins/kubernetes-common/src/index.ts diff --git a/packages/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts similarity index 100% rename from packages/kubernetes-common/src/types.ts rename to plugins/kubernetes-common/src/types.ts diff --git a/plugins/kubernetes/schema.d.ts b/plugins/kubernetes/schema.d.ts index e421100760..9845fa4e47 100644 --- a/plugins/kubernetes/schema.d.ts +++ b/plugins/kubernetes/schema.d.ts @@ -17,7 +17,7 @@ import { ClusterLocatorMethod, CustomResource, -} from '@backstage/kubernetes-common'; +} from '@backstage/plugin-kubernetes-common'; export interface Config { kubernetes?: { diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes/src/api/KubernetesBackendClient.ts index 0bbba7c8f7..19f1602143 100644 --- a/plugins/kubernetes/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes/src/api/KubernetesBackendClient.ts @@ -19,7 +19,7 @@ import { KubernetesApi } from './types'; import { KubernetesRequestBody, ObjectsByEntityResponse, -} from '@backstage/kubernetes-common'; +} from '@backstage/plugin-kubernetes-common'; export class KubernetesBackendClient implements KubernetesApi { private readonly discoveryApi: DiscoveryApi; diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes/src/api/types.ts index a575aea4b8..2e91783132 100644 --- a/plugins/kubernetes/src/api/types.ts +++ b/plugins/kubernetes/src/api/types.ts @@ -18,7 +18,7 @@ import { createApiRef } from '@backstage/core'; import { KubernetesRequestBody, ObjectsByEntityResponse, -} from '@backstage/kubernetes-common'; +} from '@backstage/plugin-kubernetes-common'; export const kubernetesApiRef = createApiRef<KubernetesApi>({ id: 'plugin.kubernetes.service', diff --git a/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx b/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx index 2261cd5e3f..ba0026ac47 100644 --- a/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx +++ b/plugins/kubernetes/src/components/KubernetesContent/ErrorPanel.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { WarningPanel } from '@backstage/core'; import { Typography } from '@material-ui/core'; -import { ClusterObjects } from '@backstage/kubernetes-common'; +import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; const clustersWithErrorsToErrorMessage = ( clustersWithErrors: ClusterObjects[], diff --git a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx index 5b30c62949..1461f52112 100644 --- a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx +++ b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx @@ -31,7 +31,7 @@ import { StatusOK, } from '@backstage/core'; import { Entity } from '@backstage/catalog-model'; -import { ClusterObjects } from '@backstage/kubernetes-common'; +import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; import { ErrorPanel } from './ErrorPanel'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { DeploymentsAccordions } from '../DeploymentsAccordions'; diff --git a/plugins/kubernetes/src/error-detection/error-detection.test.ts b/plugins/kubernetes/src/error-detection/error-detection.test.ts index 50cf81a522..5079ed9245 100644 --- a/plugins/kubernetes/src/error-detection/error-detection.test.ts +++ b/plugins/kubernetes/src/error-detection/error-detection.test.ts @@ -30,7 +30,7 @@ import * as maxedOutHpa from './__fixtures__/hpa-maxed-out.json'; import { FetchResponse, ObjectsByEntityResponse, -} from '@backstage/kubernetes-common'; +} from '@backstage/plugin-kubernetes-common'; const CLUSTER_NAME = 'cluster-a'; diff --git a/plugins/kubernetes/src/error-detection/error-detection.ts b/plugins/kubernetes/src/error-detection/error-detection.ts index 5cffbc181f..91544fe623 100644 --- a/plugins/kubernetes/src/error-detection/error-detection.ts +++ b/plugins/kubernetes/src/error-detection/error-detection.ts @@ -15,7 +15,7 @@ */ import { DetectedError, DetectedErrorsByCluster } from './types'; -import { ObjectsByEntityResponse } from '@backstage/kubernetes-common'; +import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { groupResponses } from '../utils/response'; import { detectErrorsInPods } from './pods'; import { detectErrorsInDeployments } from './deployments'; diff --git a/plugins/kubernetes/src/hooks/useKubernetesObjects.ts b/plugins/kubernetes/src/hooks/useKubernetesObjects.ts index 44434ec8f5..1dfe85fe38 100644 --- a/plugins/kubernetes/src/hooks/useKubernetesObjects.ts +++ b/plugins/kubernetes/src/hooks/useKubernetesObjects.ts @@ -22,7 +22,7 @@ import { useEffect, useState } from 'react'; import { KubernetesRequestBody, ObjectsByEntityResponse, -} from '@backstage/kubernetes-common'; +} from '@backstage/plugin-kubernetes-common'; export interface KubernetesObjects { kubernetesObjects: ObjectsByEntityResponse | undefined; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts index cb14574bdc..ef541b0173 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/AwsKubernetesAuthProvider.ts @@ -15,7 +15,7 @@ */ import { KubernetesAuthProvider } from './types'; -import { KubernetesRequestBody } from '@backstage/kubernetes-common'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export class AwsKubernetesAuthProvider implements KubernetesAuthProvider { async decorateRequestBodyForAuth( diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts index 649f0c14da..9c9db0b9fc 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.ts @@ -16,7 +16,7 @@ import { OAuthApi } from '@backstage/core'; import { KubernetesAuthProvider } from './types'; -import { KubernetesRequestBody } from '@backstage/kubernetes-common'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { authProvider: OAuthApi; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts index bc74b2717f..a96565f0c0 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts @@ -15,7 +15,7 @@ */ import { OAuthApi } from '@backstage/core'; -import { KubernetesRequestBody } from '@backstage/kubernetes-common'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { KubernetesAuthProvider, KubernetesAuthProvidersApi } from './types'; import { GoogleKubernetesAuthProvider } from './GoogleKubernetesAuthProvider'; import { ServiceAccountKubernetesAuthProvider } from './ServiceAccountKubernetesAuthProvider'; diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts index f54c51bf48..b88fd7679e 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/ServiceAccountKubernetesAuthProvider.ts @@ -15,7 +15,7 @@ */ import { KubernetesAuthProvider } from './types'; -import { KubernetesRequestBody } from '@backstage/kubernetes-common'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export class ServiceAccountKubernetesAuthProvider implements KubernetesAuthProvider { diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/types.ts b/plugins/kubernetes/src/kubernetes-auth-provider/types.ts index afb2615939..8d4cead11a 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/types.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/types.ts @@ -15,7 +15,7 @@ */ import { createApiRef } from '@backstage/core'; -import { KubernetesRequestBody } from '@backstage/kubernetes-common'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export interface KubernetesAuthProvider { decorateRequestBodyForAuth( diff --git a/plugins/kubernetes/src/utils/response.ts b/plugins/kubernetes/src/utils/response.ts index a38010ba74..1d860ca226 100644 --- a/plugins/kubernetes/src/utils/response.ts +++ b/plugins/kubernetes/src/utils/response.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FetchResponse } from '@backstage/kubernetes-common'; +import { FetchResponse } from '@backstage/plugin-kubernetes-common'; import { GroupedResponses } from '../types/types'; // TODO this could probably be a lodash groupBy From a3b25f6c2e0bb1f17e3513567211f945b6fde5ac Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 15 Apr 2021 11:43:08 +0200 Subject: [PATCH 355/462] kubernetes: Removes schema.d.ts Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes/package.json | 4 +--- plugins/kubernetes/schema.d.ts | 42 --------------------------------- 2 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 plugins/kubernetes/schema.d.ts diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 7c607b1776..c808678922 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -19,7 +19,6 @@ "backstage", "kubernetes" ], - "configSchema": "schema.d.ts", "scripts": { "build": "backstage-cli plugin:build", "start": "backstage-cli plugin:serve", @@ -63,7 +62,6 @@ "msw": "^0.21.2" }, "files": [ - "dist", - "schema.d.ts" + "dist" ] } diff --git a/plugins/kubernetes/schema.d.ts b/plugins/kubernetes/schema.d.ts deleted file mode 100644 index 9845fa4e47..0000000000 --- a/plugins/kubernetes/schema.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - ClusterLocatorMethod, - CustomResource, -} from '@backstage/plugin-kubernetes-common'; - -export interface Config { - kubernetes?: { - /** - * @visibility frontend - */ - serviceLocatorMethod: { - /** - * @visibility frontend - */ - type: 'multiTenant'; - }; - /** - * @visibility frontend - */ - clusterLocatorMethods: ClusterLocatorMethod[]; - /** - * @visibility frontend - */ - customResources?: CustomResource[]; - }; -} From 219313b29db39fdface66981e5c7b8450f928761 Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 15 Apr 2021 11:48:01 +0200 Subject: [PATCH 356/462] kubernetes-backend: Moves backend specific types back from common Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes-backend/src/types/types.ts | 118 ++++++++++++++++-- plugins/kubernetes-common/src/types.ts | 111 +--------------- 2 files changed, 113 insertions(+), 116 deletions(-) diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 119ca0451e..b7822557c2 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -14,18 +14,116 @@ * limitations under the License. */ -export type { - ClusterDetails, - CustomResource, +import type { + FetchResponse, + KubernetesFetchError, +} from '@backstage/plugin-kubernetes-common'; + +export type { FetchResponse, - FetchResponseWrapper, - KubernetesClustersSupplier, KubernetesErrorTypes, KubernetesFetchError, - KubernetesFetcher, - KubernetesObjectTypes, KubernetesRequestBody, - KubernetesServiceLocator, - ObjectFetchParams, - ServiceLocatorMethod, } from '@backstage/plugin-kubernetes-common'; + +export type ClusterLocatorMethod = + | ConfigClusterLocatorMethod + | GKEClusterLocatorMethod; + +export interface ConfigClusterLocatorMethod { + /** + * @visibility frontend + */ + type: 'config'; + clusters: { + /** + * @visibility frontend + */ + url: string; + /** + * @visibility frontend + */ + name: string; + /** + * @visibility secret + */ + serviceAccountToken: string | undefined; + /** + * @visibility frontend + */ + authProvider: 'aws' | 'google' | 'serviceAccount'; + }[]; +} + +export interface GKEClusterLocatorMethod { + /** + * @visibility frontend + */ + type: 'gke'; + /** + * @visibility frontend + */ + projectId: string; + /** + * @visibility frontend + */ + region?: string; +} + +export interface CustomResource { + group: string; + apiVersion: string; + plural: string; +} + +export interface ObjectFetchParams { + serviceId: string; + clusterDetails: ClusterDetails; + objectTypesToFetch: Set<KubernetesObjectTypes>; + labelSelector: string; + customResources: CustomResource[]; +} + +// Fetches information from a kubernetes cluster using the cluster details object +// to target a specific cluster +export interface KubernetesFetcher { + fetchObjectsForService( + params: ObjectFetchParams, + ): Promise<FetchResponseWrapper>; +} + +export interface FetchResponseWrapper { + errors: KubernetesFetchError[]; + responses: FetchResponse[]; +} + +// TODO fairly sure there's a easier way to do this + +export type KubernetesObjectTypes = + | 'pods' + | 'services' + | 'configmaps' + | 'deployments' + | 'replicasets' + | 'horizontalpodautoscalers' + | 'ingresses' + | 'customresources'; + +// Used to load cluster details from different sources +export interface KubernetesClustersSupplier { + getClusters(): Promise<ClusterDetails[]>; +} + +// Used to locate which cluster(s) a service is running on +export interface KubernetesServiceLocator { + getClustersByServiceId(serviceId: string): Promise<ClusterDetails[]>; +} + +export type ServiceLocatorMethod = 'multiTenant' | 'http'; // TODO implement http + +export interface ClusterDetails { + name: string; + url: string; + authProvider: string; + serviceAccountToken?: string | undefined; +} diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index 84ca08585b..23dc4f0f3c 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -25,13 +25,6 @@ import { } from '@kubernetes/client-node'; import { Entity } from '@backstage/catalog-model'; -export interface ClusterDetails { - name: string; - url: string; - authProvider: string; - serviceAccountToken?: string | undefined; -} - export interface KubernetesRequestBody { auth?: { google?: string; @@ -49,10 +42,7 @@ export interface ObjectsByEntityResponse { items: ClusterObjects[]; } -export interface FetchResponseWrapper { - errors: KubernetesFetchError[]; - responses: FetchResponse[]; -} +export type AuthProviderType = 'google' | 'serviceAccount' | 'aws'; export type FetchResponse = | PodFetchResponse @@ -64,18 +54,6 @@ export type FetchResponse = | IngressesFetchResponse | CustomResourceFetchResponse; -// TODO fairly sure there's a easier way to do this - -export type KubernetesObjectTypes = - | 'pods' - | 'services' - | 'configmaps' - | 'deployments' - | 'replicasets' - | 'horizontalpodautoscalers' - | 'ingresses' - | 'customresources'; - export interface PodFetchResponse { type: 'pods'; resources: Array<V1Pod>; @@ -116,30 +94,10 @@ export interface CustomResourceFetchResponse { resources: Array<any>; } -export interface ObjectFetchParams { - serviceId: string; - clusterDetails: ClusterDetails; - objectTypesToFetch: Set<KubernetesObjectTypes>; - labelSelector: string; - customResources: CustomResource[]; -} - -// Fetches information from a kubernetes cluster using the cluster details object -// to target a specific cluster -export interface KubernetesFetcher { - fetchObjectsForService( - params: ObjectFetchParams, - ): Promise<FetchResponseWrapper>; -} - -// Used to locate which cluster(s) a service is running on -export interface KubernetesServiceLocator { - getClustersByServiceId(serviceId: string): Promise<ClusterDetails[]>; -} - -// Used to load cluster details from different sources -export interface KubernetesClustersSupplier { - getClusters(): Promise<ClusterDetails[]>; +export interface KubernetesFetchError { + errorType: KubernetesErrorTypes; + statusCode?: number; + resourcePath?: string; } export type KubernetesErrorTypes = @@ -147,62 +105,3 @@ export type KubernetesErrorTypes = | 'UNAUTHORIZED_ERROR' | 'SYSTEM_ERROR' | 'UNKNOWN_ERROR'; - -export interface KubernetesFetchError { - errorType: KubernetesErrorTypes; - statusCode?: number; - resourcePath?: string; -} - -export interface ConfigClusterLocatorMethod { - /** - * @visibility frontend - */ - type: 'config'; - clusters: { - /** - * @visibility frontend - */ - url: string; - /** - * @visibility frontend - */ - name: string; - /** - * @visibility secret - */ - serviceAccountToken: string | undefined; - /** - * @visibility frontend - */ - authProvider: 'aws' | 'google' | 'serviceAccount'; - }[]; -} - -export interface GKEClusterLocatorMethod { - /** - * @visibility frontend - */ - type: 'gke'; - /** - * @visibility frontend - */ - projectId: string; - /** - * @visibility frontend - */ - region?: string; -} - -export type ClusterLocatorMethod = - | ConfigClusterLocatorMethod - | GKEClusterLocatorMethod; - -export type ServiceLocatorMethod = 'multiTenant' | 'http'; // TODO implement http -export type AuthProviderType = 'google' | 'serviceAccount' | 'aws'; - -export interface CustomResource { - group: string; - apiVersion: string; - plural: string; -} From 99930d194c3cab71dd7bc0f54921ab586ce925f0 Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 15 Apr 2021 13:35:55 +0200 Subject: [PATCH 357/462] kubernetes-common: Exports types in a way that pleases the transpiler Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes-backend/src/types/types.ts | 9 +++++---- plugins/kubernetes-common/package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index b7822557c2..344e265426 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -15,17 +15,18 @@ */ import type { - FetchResponse, - KubernetesFetchError, + FetchResponse as FetchResponseCommon, + KubernetesFetchError as KubernetesFetchErrorCommon, } from '@backstage/plugin-kubernetes-common'; export type { - FetchResponse, KubernetesErrorTypes, - KubernetesFetchError, KubernetesRequestBody, } from '@backstage/plugin-kubernetes-common'; +export type KubernetesFetchError = KubernetesFetchErrorCommon; +export type FetchResponse = FetchResponseCommon; + export type ClusterLocatorMethod = | ConfigClusterLocatorMethod | GKEClusterLocatorMethod; diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 813b965c2c..682223d92e 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -24,7 +24,7 @@ "dist" ], "scripts": { - "build": "backstage-cli build --outputs cjs,types", + "build": "backstage-cli build", "lint": "backstage-cli lint", "test": "backstage-cli test", "prepack": "backstage-cli prepack", From fb4ebd961edc3059c89c5f230c4371e29fa9ecaa Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 15 Apr 2021 14:11:20 +0200 Subject: [PATCH 358/462] plugin-kubernetes-common: Adds pass with no tests, since these are just types Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes-common/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 682223d92e..3551eb6413 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -26,7 +26,7 @@ "scripts": { "build": "backstage-cli build", "lint": "backstage-cli lint", - "test": "backstage-cli test", + "test": "backstage-cli test --passWithNoTests", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", "clean": "backstage-cli clean" From 34a4aa2c1e44664a08cdabc4bc2e68eabe86b14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20A=CC=8Ahsberg?= <mathias.ahsberg@resurs.se> Date: Wed, 28 Apr 2021 15:52:33 +0000 Subject: [PATCH 359/462] Pass processor logger to repository parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathias Åhsberg <mathias.ahsberg@resurs.se> --- .../processors/BitbucketDiscoveryProcessor.ts | 19 ++++++++------- .../BitbucketRepositoryParser.test.ts | 16 ++++--------- .../bitbucket/BitbucketRepositoryParser.ts | 15 ++++++------ .../ingestion/processors/bitbucket/client.ts | 9 -------- .../ingestion/processors/bitbucket/types.ts | 23 ++++++++----------- 5 files changed, 31 insertions(+), 51 deletions(-) diff --git a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts index 858219423f..9c56eb14e3 100644 --- a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts @@ -22,11 +22,11 @@ import { } from '@backstage/integration'; import { LocationSpec } from '@backstage/catalog-model'; import { - Bitbucket, BitbucketRepositoryParser, BitbucketClient, defaultRepositoryParser, paginated, + BitbucketRepository, } from './bitbucket'; import { CatalogProcessor, CatalogProcessorEmit } from './types'; @@ -66,20 +66,19 @@ export class BitbucketDiscoveryProcessor implements CatalogProcessor { return false; } - const bitbucketConfig = this.integrations.bitbucket.byUrl(location.target) - ?.config; - if (!bitbucketConfig) { + const integration = this.integrations.bitbucket.byUrl(location.target); + if (!integration) { throw new Error( `There is no Bitbucket integration that matches ${location.target}. Please add a configuration entry for it under integrations.bitbucket`, ); - } else if (bitbucketConfig.host === 'bitbucket.org') { + } else if (integration.config.host === 'bitbucket.org') { throw new Error( `Component discovery for Bitbucket Cloud is not yet supported`, ); } const client = new BitbucketClient({ - config: bitbucketConfig, + config: integration.config, }); const startTimestamp = Date.now(); this.logger.info(`Reading Bitbucket repositories from ${location.target}`); @@ -90,9 +89,9 @@ export class BitbucketDiscoveryProcessor implements CatalogProcessor { for (const repository of result.matches) { for await (const entity of this.parser({ - client: client, - repository: repository, - path: catalogPath, + integration: integration, + target: `${repository.links.self[0]}${catalogPath}`, + logger: this.logger, })) { emit(entity); } @@ -159,5 +158,5 @@ function escapeRegExp(str: string): RegExp { type Result = { scanned: number; - matches: Bitbucket.Repository[]; + matches: BitbucketRepository[]; }; diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts index e0d430f77b..3d42d9c4ba 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.test.ts @@ -14,9 +14,9 @@ * limitations under the License. */ import { defaultRepositoryParser } from './BitbucketRepositoryParser'; -import { Bitbucket } from './types'; -import { BitbucketClient } from './client'; import { results } from '../index'; +import { getVoidLogger } from '@backstage/backend-common'; +import { BitbucketIntegration } from '@backstage/integration'; describe('BitbucketRepositoryParser', () => { describe('defaultRepositoryParser', () => { @@ -34,15 +34,9 @@ describe('BitbucketRepositoryParser', () => { ), ]; const actual = await defaultRepositoryParser({ - client: {} as BitbucketClient, - repository: { - project: {} as Bitbucket.Project, - slug: 'repo-slug', - links: { - self: [{ href: browseUrl }], - }, - } as Bitbucket.Repository, - path: path, + integration: {} as BitbucketIntegration, + target: `${browseUrl}${path}`, + logger: getVoidLogger(), }); let i = 0; diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts index 05e3c6822a..9ad038f9ec 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/BitbucketRepositoryParser.ts @@ -13,25 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Bitbucket } from './types'; import { CatalogProcessorResult } from '../types'; import { results } from '../index'; -import { BitbucketClient } from './client'; +import { Logger } from 'winston'; +import { BitbucketIntegration } from '@backstage/integration'; export type BitbucketRepositoryParser = (options: { - client: BitbucketClient; - repository: Bitbucket.Repository; - path: string; + integration: BitbucketIntegration; + target: string; + logger: Logger; }) => AsyncIterable<CatalogProcessorResult>; export const defaultRepositoryParser: BitbucketRepositoryParser = async function* defaultRepositoryParser({ - repository, - path, + target, }) { yield results.location( { type: 'url', - target: `${repository.links.self[0].href}${path}`, + target: target, }, // Not all locations may actually exist, since the user defined them as a wildcard pattern. // Thus, we emit them as optional and let the downstream processor find them while not outputting diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/client.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/client.ts index 601461dcf5..c3c27aedfc 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/client.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/client.ts @@ -41,15 +41,6 @@ export class BitbucketClient { ); } - async getRaw( - projectKey: string, - repo: string, - path: string, - ): Promise<Response> { - const request = `${this.config.apiBaseUrl}/projects/${projectKey}/repos/${repo}/raw/${path}`; - return fetch(request, getBitbucketRequestOptions(this.config)); - } - private async pagedRequest( endpoint: string, options?: ListOptions, diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts index 8a8656f666..32dc28eb98 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/types.ts @@ -13,18 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export namespace Bitbucket { - export type Project = { +export type BitbucketRepository = { + project: { key: string; }; - - export type Repository = { - project: Project; - slug: string; - links: Record<string, Link[]>; - }; - - export type Link = { - href: string; - }; -} + slug: string; + links: Record< + string, + { + href: string; + }[] + >; +}; From b2e2ec75337768330b277365bfc689cbc77188b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Thu, 29 Apr 2021 15:43:53 +0200 Subject: [PATCH 360/462] Update tech radar README for composability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/spotty-pigs-bathe.md | 5 +++++ plugins/tech-radar/README.md | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 .changeset/spotty-pigs-bathe.md diff --git a/.changeset/spotty-pigs-bathe.md b/.changeset/spotty-pigs-bathe.md new file mode 100644 index 0000000000..0585f335dc --- /dev/null +++ b/.changeset/spotty-pigs-bathe.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-radar': patch +--- + +Update README for composability diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md index 21f90ec432..7f97f88ed4 100644 --- a/plugins/tech-radar/README.md +++ b/plugins/tech-radar/README.md @@ -18,7 +18,7 @@ It serves and scales well for teams and companies of all sizes that want to have The Tech Radar can be used in two ways: -- **Simple (Recommended)** - This gives you an out-of-the-box Tech Radar experience. It lives on the `/tech-radar` URL of your Backstage installation, and you can set a variety of configuration directly in your `apis.ts`. +- **Simple (Recommended)** - This gives you an out-of-the-box Tech Radar experience. It lives on the `/tech-radar` URL of your Backstage installation. - **Advanced** - This gives you the React UI component directly. It enables you to insert the Radar on your own layout or page for a more customized feel. ### Install @@ -26,6 +26,7 @@ The Tech Radar can be used in two ways: For either simple or advanced installations, you'll need to add the dependency using Yarn: ```sh +cd packages/app yarn add @backstage/plugin-tech-radar ``` @@ -34,17 +35,16 @@ yarn add @backstage/plugin-tech-radar Modify your app routes to include the Router component exported from the tech radar, for example: ```tsx -import { Router as TechRadarRouter } from '@backstage/plugin-tech-radar'; +// in packages/app/src/App.tsx +import { TechRadarPage } from '@backstage/plugin-tech-radar'; -// Inside App component -<Routes> - {/* other routes ... */} - <Route - path="/tech-radar" - element={<TechRadarRouter width={1500} height={800} />} - /> - {/* other routes ... */} -</Routes>; +const routes = ( + <FlatRoutes> + {/* ... */} + <Route + path="/tech-radar" + element={<TechRadarPage width={1500} height={800} />} + /> ``` If you'd like to configure it more, see the `TechRadarPageProps` and `TechRadarComponentProps` types for options: From 6e9d535c697ad1bde957b2c55023d6029b1c2096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20A=CC=8Ahsberg?= <mathias.ahsberg@resurs.se> Date: Thu, 29 Apr 2021 14:20:41 +0000 Subject: [PATCH 361/462] Do not expose Bitbucket internals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathias Åhsberg <mathias.ahsberg@resurs.se> --- .../BitbucketDiscoveryProcessor.test.ts | 211 ++++++++---------- .../processors/BitbucketDiscoveryProcessor.ts | 2 +- .../ingestion/processors/bitbucket/index.ts | 6 +- .../src/ingestion/processors/index.ts | 3 +- 4 files changed, 93 insertions(+), 129 deletions(-) diff --git a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.test.ts index 73f4281a51..1f01b77f42 100644 --- a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.test.ts @@ -17,21 +17,73 @@ import { getVoidLogger } from '@backstage/backend-common'; import { BitbucketDiscoveryProcessor } from './BitbucketDiscoveryProcessor'; import { ConfigReader } from '@backstage/config'; import { LocationSpec } from '@backstage/catalog-model'; -import { - BitbucketClient, - BitbucketRepositoryParser, - PagedResponse, -} from './bitbucket'; +import { BitbucketRepositoryParser, PagedResponse } from './bitbucket'; import { results } from './index'; +import { RequestHandler, rest } from 'msw'; +import { setupServer } from 'msw/node'; -function pagedResponse(values: any): PagedResponse<any> { - return { - values: values, - isLastPage: true, - } as PagedResponse<any>; +const server = setupServer(); + +function setupStubs(projects: any[]) { + function pagedResponse(values: any): PagedResponse<any> { + return { + values: values, + isLastPage: true, + } as PagedResponse<any>; + } + + function stubbedProject( + project: string, + repos: string[], + ): RequestHandler<any, any> { + return rest.get( + `https://bitbucket.mycompany.com/api/rest/1.0/projects/${project}/repos`, + (_, res, ctx) => { + const response = []; + for (const repo of repos) { + response.push({ + slug: repo, + links: { + self: [ + { + href: `https://bitbucket.mycompany.com/projects/${project}/repos/${repo}/browse`, + }, + ], + }, + }); + } + return res(ctx.json(pagedResponse(response))); + }, + ); + } + + server.use( + rest.get( + `https://bitbucket.mycompany.com/api/rest/1.0/projects`, + (_, res, ctx) => { + return res( + ctx.json( + pagedResponse( + projects.map(p => { + return { key: p.key }; + }), + ), + ), + ); + }, + ), + ); + + for (const project of projects) { + server.use(stubbedProject(project.key, project.repos)); + } } describe('BitbucketDiscoveryProcessor', () => { + beforeAll(() => server.listen()); + afterEach(() => server.resetHandlers()); + afterAll(() => server.close()); + afterEach(() => jest.resetAllMocks()); describe('reject unrelated entries', () => { @@ -81,58 +133,29 @@ describe('BitbucketDiscoveryProcessor', () => { const processor = BitbucketDiscoveryProcessor.fromConfig( new ConfigReader({ integrations: { - bitbucket: [{ host: 'bitbucket.mycompany.com', token: 'blob' }], + bitbucket: [ + { + host: 'bitbucket.mycompany.com', + token: 'blob', + apiBaseUrl: 'https://bitbucket.mycompany.com/api/rest/1.0', + }, + ], }, }), { logger: getVoidLogger() }, ); it('output all repositories', async () => { + setupStubs([ + { key: 'backstage', repos: ['backstage'] }, + { key: 'demo', repos: ['demo'] }, + ]); const location: LocationSpec = { type: 'bitbucket-discovery', target: 'https://bitbucket.mycompany.com/projects/*/repos/*/catalog.yaml', }; - jest - .spyOn(BitbucketClient.prototype, 'listProjects') - .mockResolvedValue( - pagedResponse([{ key: 'backstage' }, { key: 'demo' }]), - ); - jest - .spyOn(BitbucketClient.prototype, 'listRepositories') - .mockResolvedValueOnce( - pagedResponse([ - { - slug: 'backstage', - links: { - self: [ - { - href: - 'https://bitbucket.mycompany.com/projects/backstage/repos/backstage/browse', - }, - ], - }, - }, - ]), - ); - jest - .spyOn(BitbucketClient.prototype, 'listRepositories') - .mockResolvedValueOnce( - pagedResponse([ - { - slug: 'demo', - links: { - self: [ - { - href: - 'https://bitbucket.mycompany.com/projects/demo/repos/demo/browse', - }, - ], - }, - }, - ]), - ); const emitter = jest.fn(); await processor.readLocation(location, false, emitter); @@ -158,44 +181,16 @@ describe('BitbucketDiscoveryProcessor', () => { }); it('output repositories with wildcards', async () => { + setupStubs([ + { key: 'backstage', repos: ['backstage', 'techdocs-cli'] }, + { key: 'demo', repos: ['demo'] }, + ]); const location: LocationSpec = { type: 'bitbucket-discovery', target: 'https://bitbucket.mycompany.com/projects/backstage/repos/techdocs-*/catalog.yaml', }; - jest - .spyOn(BitbucketClient.prototype, 'listProjects') - .mockResolvedValue(pagedResponse([{ key: 'backstage' }])); - jest - .spyOn(BitbucketClient.prototype, 'listRepositories') - .mockResolvedValueOnce( - pagedResponse([ - { slug: 'backstage' }, - { - slug: 'techdocs-cli', - links: { - self: [ - { - href: - 'https://bitbucket.mycompany.com/projects/backstage/repos/techdocs-cli/browse', - }, - ], - }, - }, - { - slug: 'techdocs-container', - links: { - self: [ - { - href: - 'https://bitbucket.mycompany.com/projects/backstage/repos/techdocs-container/browse', - }, - ], - }, - }, - ]), - ); const emitter = jest.fn(); await processor.readLocation(location, false, emitter); @@ -208,46 +203,15 @@ describe('BitbucketDiscoveryProcessor', () => { }, optional: true, }); - expect(emitter).toHaveBeenCalledWith({ - type: 'location', - location: { - type: 'url', - target: - 'https://bitbucket.mycompany.com/projects/backstage/repos/techdocs-container/browse/catalog.yaml', - }, - optional: true, - }); }); it('filter unrelated repositories', async () => { + setupStubs([{ key: 'backstage', repos: ['test', 'abctest', 'testxyz'] }]); const location: LocationSpec = { type: 'bitbucket-discovery', target: 'https://bitbucket.mycompany.com/projects/backstage/repos/test/catalog.yaml', }; - jest - .spyOn(BitbucketClient.prototype, 'listProjects') - .mockResolvedValue(pagedResponse([{ key: 'backstage' }])); - jest - .spyOn(BitbucketClient.prototype, 'listRepositories') - .mockResolvedValue( - pagedResponse([ - { slug: 'abstest' }, - { slug: 'testxyz' }, - { - slug: 'test', - links: { - self: [ - { - href: - 'https://bitbucket.mycompany.com/projects/backstage/repos/test', - }, - ], - }, - }, - ]), - ); - const emitter = jest.fn(); await processor.readLocation(location, false, emitter); @@ -256,7 +220,7 @@ describe('BitbucketDiscoveryProcessor', () => { location: { type: 'url', target: - 'https://bitbucket.mycompany.com/projects/backstage/repos/test/catalog.yaml', + 'https://bitbucket.mycompany.com/projects/backstage/repos/test/browse/catalog.yaml', }, optional: true, }); @@ -277,26 +241,27 @@ describe('BitbucketDiscoveryProcessor', () => { const processor = BitbucketDiscoveryProcessor.fromConfig( new ConfigReader({ integrations: { - bitbucket: [{ host: 'bitbucket.mycompany.com', token: 'blob' }], + bitbucket: [ + { + host: 'bitbucket.mycompany.com', + token: 'blob', + apiBaseUrl: 'https://bitbucket.mycompany.com/api/rest/1.0', + }, + ], }, }), { parser: customRepositoryParser, logger: getVoidLogger() }, ); it('use custom repository parser', async () => { + setupStubs([{ key: 'backstage', repos: ['test'] }]); + const location: LocationSpec = { type: 'bitbucket-discovery', target: 'https://bitbucket.mycompany.com/projects/backstage/repos/test/catalog.yaml', }; - jest - .spyOn(BitbucketClient.prototype, 'listProjects') - .mockResolvedValue(pagedResponse([{ key: 'backstage' }])); - jest - .spyOn(BitbucketClient.prototype, 'listRepositories') - .mockResolvedValue(pagedResponse([{ slug: 'test' }])); - const emitter = jest.fn(); await processor.readLocation(location, false, emitter); diff --git a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts index 9c56eb14e3..399adfbc14 100644 --- a/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/BitbucketDiscoveryProcessor.ts @@ -90,7 +90,7 @@ export class BitbucketDiscoveryProcessor implements CatalogProcessor { for (const repository of result.matches) { for await (const entity of this.parser({ integration: integration, - target: `${repository.links.self[0]}${catalogPath}`, + target: `${repository.links.self[0].href}${catalogPath}`, logger: this.logger, })) { emit(entity); diff --git a/plugins/catalog-backend/src/ingestion/processors/bitbucket/index.ts b/plugins/catalog-backend/src/ingestion/processors/bitbucket/index.ts index ba2a2b3afe..06effffcd2 100644 --- a/plugins/catalog-backend/src/ingestion/processors/bitbucket/index.ts +++ b/plugins/catalog-backend/src/ingestion/processors/bitbucket/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ export { BitbucketClient, paginated } from './client'; -export type { PagedResponse } from './client'; -export * from './types'; -export type { BitbucketRepositoryParser } from './BitbucketRepositoryParser'; export { defaultRepositoryParser } from './BitbucketRepositoryParser'; +export type { PagedResponse } from './client'; +export type { BitbucketRepository } from './types'; +export type { BitbucketRepositoryParser } from './BitbucketRepositoryParser'; diff --git a/plugins/catalog-backend/src/ingestion/processors/index.ts b/plugins/catalog-backend/src/ingestion/processors/index.ts index c8f51bbccc..a92cc9ed3b 100644 --- a/plugins/catalog-backend/src/ingestion/processors/index.ts +++ b/plugins/catalog-backend/src/ingestion/processors/index.ts @@ -36,5 +36,4 @@ export { UrlReaderProcessor } from './UrlReaderProcessor'; export { parseEntityYaml } from './util/parse'; export { results }; -export { BitbucketClient } from './bitbucket'; -export type { BitbucketRepositoryParser, Bitbucket } from './bitbucket'; +export type { BitbucketRepositoryParser } from './bitbucket'; From cec7fb9b372c7ba20565119918f030ea50990bb4 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Tue, 30 Mar 2021 17:23:24 +0200 Subject: [PATCH 362/462] Add support for json schema to API docs Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/six-mayflies-peel.md | 5 + packages/catalog-model/examples/all-apis.yaml | 1 + .../examples/apis/config-schema-api.yaml | 11 + plugins/api-docs/README.md | 1 + plugins/api-docs/dev/index.tsx | 15 + .../api-docs/dev/jsonschema-example-api.yaml | 32 + plugins/api-docs/package.json | 3 + .../ApiDefinitionCard/ApiDefinitionWidget.tsx | 9 + .../JsonSchemaDefinitionWidget.test.tsx | 61 + .../JsonSchemaDefinitionWidget.tsx | 50 + .../JsonSchemaDefinitionWidget/index.ts | 17 + plugins/api-docs/src/components/index.ts | 1 + yarn.lock | 1038 ++++++++++++++++- 13 files changed, 1238 insertions(+), 6 deletions(-) create mode 100644 .changeset/six-mayflies-peel.md create mode 100644 packages/catalog-model/examples/apis/config-schema-api.yaml create mode 100644 plugins/api-docs/dev/jsonschema-example-api.yaml create mode 100644 plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx create mode 100644 plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx create mode 100644 plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts diff --git a/.changeset/six-mayflies-peel.md b/.changeset/six-mayflies-peel.md new file mode 100644 index 0000000000..9d022bca0a --- /dev/null +++ b/.changeset/six-mayflies-peel.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Add support for displaying JSON schemas. diff --git a/packages/catalog-model/examples/all-apis.yaml b/packages/catalog-model/examples/all-apis.yaml index e23f1b3656..8ec9203b28 100644 --- a/packages/catalog-model/examples/all-apis.yaml +++ b/packages/catalog-model/examples/all-apis.yaml @@ -5,6 +5,7 @@ metadata: description: A collection of all Backstage example APIs spec: targets: + - ./apis/config-schema-api.yaml - ./apis/hello-world-api.yaml - ./apis/petstore-api.yaml - ./apis/spotify-api.yaml diff --git a/packages/catalog-model/examples/apis/config-schema-api.yaml b/packages/catalog-model/examples/apis/config-schema-api.yaml new file mode 100644 index 0000000000..4bd8976614 --- /dev/null +++ b/packages/catalog-model/examples/apis/config-schema-api.yaml @@ -0,0 +1,11 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: config-schema + description: A Backstage config schemas. +spec: + type: jsonschema + lifecycle: production + owner: team-a + definition: + $text: https://github.com/backstage/backstage/blob/master/plugins/config-schema/dev/example-schema.json diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index dac4b6ff4d..f995a7d002 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -15,6 +15,7 @@ Right now, the following API formats are supported: - [OpenAPI](https://swagger.io/specification/) 2 & 3 - [AsyncAPI](https://www.asyncapi.com/docs/specifications/latest/) - [GraphQL](https://graphql.org/learn/schema/) +- [JSON Schema](https://json-schema.org/) Other formats are displayed as plain text, but this can easily be extended. diff --git a/plugins/api-docs/dev/index.tsx b/plugins/api-docs/dev/index.tsx index fbfab37f5b..d51d3a714c 100644 --- a/plugins/api-docs/dev/index.tsx +++ b/plugins/api-docs/dev/index.tsx @@ -27,6 +27,7 @@ import { } from '../src'; import asyncapiApiEntity from './asyncapi-example-api.yaml'; import graphqlApiEntity from './graphql-example-api.yaml'; +import jsonschemaApiEntity from './jsonschema-example-api.yaml'; import openapiApiEntity from './openapi-example-api.yaml'; import otherApiEntity from './other-example-api.yaml'; @@ -41,6 +42,7 @@ createDevApp() items: [ openapiApiEntity, asyncapiApiEntity, + jsonschemaApiEntity, graphqlApiEntity, otherApiEntity, ], @@ -87,6 +89,19 @@ createDevApp() </Page> ), }) + .addPage({ + title: 'JSON Schema', + element: ( + <Page themeId="home"> + <Header title="JSON Schema" /> + <Content> + <EntityProvider entity={(jsonschemaApiEntity as any) as Entity}> + <EntityApiDefinitionCard /> + </EntityProvider> + </Content> + </Page> + ), + }) .addPage({ title: 'GraphQL', element: ( diff --git a/plugins/api-docs/dev/jsonschema-example-api.yaml b/plugins/api-docs/dev/jsonschema-example-api.yaml new file mode 100644 index 0000000000..a34b4f9a49 --- /dev/null +++ b/plugins/api-docs/dev/jsonschema-example-api.yaml @@ -0,0 +1,32 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: persons + description: Person dataset +spec: + type: jsonschema + lifecycle: experimental + owner: team-c + # From https://json-schema.org/learn/miscellaneous-examples.html + definition: | + { + "$id": "https://example.com/person.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Person", + "type": "object", + "properties": { + "firstName": { + "type": "string", + "description": "The person's first name." + }, + "lastName": { + "type": "string", + "description": "The person's last name." + }, + "age": { + "description": "Age in years which must be equal to or greater than zero.", + "type": "integer", + "minimum": 0 + } + } + } diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 5c9f9ca7ee..be5d5186d2 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -38,6 +38,9 @@ "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", + "@stoplight/json-schema-viewer": "^4.0.0-beta.16", + "@stoplight/mosaic": "^1.0.0-beta.46", + "@stoplight/reporter": "^1.10.0", "@types/react": "^16.9", "graphiql": "^1.0.0-alpha.10", "graphql": "^15.3.0", diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx index 360404af40..fc23c338ee 100644 --- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx @@ -16,6 +16,7 @@ import React from 'react'; import { AsyncApiDefinitionWidget } from '../AsyncApiDefinitionWidget'; import { GraphQlDefinitionWidget } from '../GraphQlDefinitionWidget'; +import { JsonSchemaDefinitionWidget } from '../JsonSchemaDefinitionWidget'; import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget'; export type ApiDefinitionWidget = { @@ -51,5 +52,13 @@ export function defaultDefinitionWidgets(): ApiDefinitionWidget[] { <GraphQlDefinitionWidget definition={definition} /> ), }, + { + type: 'jsonschema', + title: 'JSON Schema', + rawLanguage: 'json', + component: definition => ( + <JsonSchemaDefinitionWidget definition={definition} /> + ), + }, ]; } diff --git a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx new file mode 100644 index 0000000000..b4077e6ea2 --- /dev/null +++ b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { JsonSchemaDefinitionWidget } from './JsonSchemaDefinitionWidget'; + +describe('<JsonSchemaDefinitionWidget />', () => { + it('renders json schema', async () => { + // From https://json-schema.org/learn/miscellaneous-examples.html + const definition = ` +{ + "$id": "https://example.com/person.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Person", + "type": "object", + "properties": { + "firstName": { + "type": "string", + "description": "The person's first name." + }, + "lastName": { + "type": "string", + "description": "The person's last name." + }, + "age": { + "description": "Age in years which must be equal to or greater than zero.", + "type": "integer", + "minimum": 0 + } + } +} + `; + const { getByText } = await renderInTestApp( + <JsonSchemaDefinitionWidget definition={definition} />, + ); + + expect(getByText(/lastName/i)).toBeInTheDocument(); + expect(getByText(/The person's last name./i)).toBeInTheDocument(); + }); + + it('renders error if definition is missing', async () => { + const { getByText } = await renderInTestApp( + <JsonSchemaDefinitionWidget definition="{}" />, + ); + expect(getByText(/No schema defined/i)).toBeInTheDocument(); + }); +}); diff --git a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx new file mode 100644 index 0000000000..ea8ac652c8 --- /dev/null +++ b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx @@ -0,0 +1,50 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useTheme } from '@material-ui/core'; +import { JsonSchemaViewer } from '@stoplight/json-schema-viewer'; +import { injectStyles, useThemeStore } from '@stoplight/mosaic'; +import React, { useMemo } from 'react'; +import { useEffectOnce } from 'react-use'; + +injectStyles(); + +type Props = { + definition: any; +}; + +export const JsonSchemaDefinitionWidget = ({ definition }: Props) => { + const schema = useMemo(() => JSON.parse(definition), [definition]); + const theme = useTheme(); + const themeStore = useThemeStore(); + + useEffectOnce(() => { + themeStore.setColor('background', theme.palette.background.paper); + themeStore.setColor('text', theme.palette.text.primary); + themeStore.setColor('primary', theme.palette.primary.main); + themeStore.setColor('success', theme.palette.success.main); + themeStore.setColor('warning', theme.palette.warning.main); + themeStore.setColor('danger', theme.palette.error.main); + themeStore.setMode(theme.palette.type); + }); + return ( + <JsonSchemaViewer + schema={schema} + emptyText="No schema defined" + defaultExpandedDepth={5} + /> + ); +}; diff --git a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts new file mode 100644 index 0000000000..47d2619ec2 --- /dev/null +++ b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { JsonSchemaDefinitionWidget } from './JsonSchemaDefinitionWidget'; diff --git a/plugins/api-docs/src/components/index.ts b/plugins/api-docs/src/components/index.ts index cfd985f47c..afac37dc31 100644 --- a/plugins/api-docs/src/components/index.ts +++ b/plugins/api-docs/src/components/index.ts @@ -20,3 +20,4 @@ export * from './AsyncApiDefinitionWidget'; export * from './ComponentsCards'; export * from './OpenApiDefinitionWidget'; export * from './PlainApiDefinitionWidget'; +export * from './JsonSchemaDefinitionWidget'; diff --git a/yarn.lock b/yarn.lock index 5fdd60715c..4831b9f51a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,24 @@ # yarn lockfile v1 +"@amplitude/types@^1.5.4": + version "1.5.4" + resolved "https://registry.npmjs.org/@amplitude/types/-/types-1.5.4.tgz#7fcbcbfb321d794b6367596cd950a92c752431d1" + integrity sha512-+e+wqlO5E4lNTM19lATf+lJldV+VD2RGzrDEy45cPEtfpXxHJUHwhfOKZkKg/zlx+YAubcpNhWLm2NSPpHUs9A== + +"@amplitude/ua-parser-js@0.7.24": + version "0.7.24" + resolved "https://registry.npmjs.org/@amplitude/ua-parser-js/-/ua-parser-js-0.7.24.tgz#2ce605af7d2c38d4a01313fb2385df55fbbd69aa" + integrity sha512-VbQuJymJ20WEw0HtI2np7EdC3NJGUWi8+Xdbc7uk8WfMIF308T0howpzkQ3JFMN7ejnrcSM/OyNGveeE3TP3TA== + +"@amplitude/utils@^1.0.5": + version "1.5.4" + resolved "https://registry.npmjs.org/@amplitude/utils/-/utils-1.5.4.tgz#457e847d751522ac8dd910037667d780ef501642" + integrity sha512-VAd/ibhwBBeL8pKqCz8tjCnSx8epOvUa+Je6sA3AB4R8855xl+bdrDjYwMmOWOILvEH3Pltq2jVJCE2thBoFdQ== + dependencies: + "@amplitude/types" "^1.5.4" + tslib "^1.9.3" + "@apidevtools/json-schema-ref-parser@^9.0.6": version "9.0.6" resolved "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz#5d9000a3ac1fd25404da886da6b266adcd99cf1c" @@ -1623,6 +1641,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.13.17", "@babel/runtime@^7.6.2": + version "7.13.17" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec" + integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -2077,6 +2102,32 @@ dependencies: yaml-ast-parser "0.0.43" +"@fortawesome/fontawesome-common-types@^0.2.35": + version "0.2.35" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz#01dd3d054da07a00b764d78748df20daf2b317e9" + integrity sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw== + +"@fortawesome/fontawesome-svg-core@^1.2.35": + version "1.2.35" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz#85aea8c25645fcec88d35f2eb1045c38d3e65cff" + integrity sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.35" + +"@fortawesome/free-solid-svg-icons@^5.15.2", "@fortawesome/free-solid-svg-icons@^5.15.3": + version "5.15.3" + resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz#52eebe354f60dc77e0bde934ffc5c75ffd04f9d8" + integrity sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.35" + +"@fortawesome/react-fontawesome@^0.1.14": + version "0.1.14" + resolved "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz#bf28875c3935b69ce2dc620e1060b217a47f64ca" + integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA== + dependencies: + prop-types "^15.7.2" + "@gitbeaker/core@^28.0.2", "@gitbeaker/core@^28.2.0": version "28.2.0" resolved "https://registry.npmjs.org/@gitbeaker/core/-/core-28.2.0.tgz#87e6f789faf55d726f75d05e470020e4bbb8e08c" @@ -2733,6 +2784,21 @@ resolved "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== +"@internationalized/message@3.0.0-alpha.0": + version "3.0.0-alpha.0" + resolved "https://registry.npmjs.org/@internationalized/message/-/message-3.0.0-alpha.0.tgz#83015e2057d2b6b5034a3e23983b1e051f9d9e36" + integrity sha512-NT2eiVq5f5z7Yi9Hmchb8GAGYjEpYbYcD4u/Oxo5XG9XFbrnz7zNvrJJlzuQ+2jPozabq6pFKurqaFmM49DYUg== + dependencies: + "@babel/runtime" "^7.6.2" + intl-messageformat "^2.2.0" + +"@internationalized/number@3.0.0-alpha.0": + version "3.0.0-alpha.0" + resolved "https://registry.npmjs.org/@internationalized/number/-/number-3.0.0-alpha.0.tgz#27190fbc1d73a24ac96dfafdfe7aa4e520090eed" + integrity sha512-8aOD2I3HmEscIZO/cm1jkcrYMSmRPhoW9G1OsuQb4Ge/Y9HsJVGB9otTylUEXJUmoXi/eD8Mr1gx3+0FLCM4eA== + dependencies: + "@babel/runtime" "^7.6.2" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.0.0" resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" @@ -4233,6 +4299,445 @@ prop-types "^15.6.1" react-lifecycles-compat "^3.0.4" +"@react-aria/button@~3.3.1": + version "3.3.1" + resolved "https://registry.npmjs.org/@react-aria/button/-/button-3.3.1.tgz#f180ffa95e3e822b7da4937421cf8280dd17af17" + integrity sha512-LXNuo0L79AhYqnxV+Y3J3xt7hPcmCVCEpZaC/dBzovR1MLunrdpk3QAXsRt3tqza1XvoqdvNhNHQm1Z1kyBTUg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/utils" "^3.6.0" + "@react-stately/toggle" "^3.2.1" + "@react-types/button" "^3.3.1" + +"@react-aria/dialog@~3.1.2": + version "3.1.2" + resolved "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.1.2.tgz#868970e7fdaa6ddb91a0d8d5b492778607d417fd" + integrity sha512-CUHzLdcKxnQ1IpbJOJ3BIDe762QoTOFXZfDAheNiTi24ym85w7KkW7dnfJDK2+J5RY15c5KWooOZvTaBmIJ7Xw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/utils" "^3.3.0" + "@react-stately/overlays" "^3.1.1" + "@react-types/dialog" "^3.3.0" + +"@react-aria/focus@^3.2.2", "@react-aria/focus@^3.2.3", "@react-aria/focus@^3.2.4", "@react-aria/focus@~3.2.4": + version "3.2.4" + resolved "https://registry.npmjs.org/@react-aria/focus/-/focus-3.2.4.tgz#86c4fbde51a7cae414407b2d421fb5b311cd62f5" + integrity sha512-qoJoUDSriI7RCRq3L7yDOPtFZfquyjLA9d2pOJzvMx1F6dEqfNCaycyIg9lHykHXXhShgrXwfpyGTXoSUQpmtw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.3.4" + "@react-aria/utils" "^3.7.0" + "@react-types/shared" "^3.5.0" + clsx "^1.1.1" + +"@react-aria/i18n@^3.3.0": + version "3.3.0" + resolved "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.3.0.tgz#7f92ae81f6536b19b17b89c0991ddb6c10f2512a" + integrity sha512-8KYk0tQiEf9Kd9xdF4cKliP1169WSIryKFnZgnm9dvZl96TyfDK1xJpZQy58XjRdbS/H45CKydFmMcZEElu3BQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@internationalized/message" "3.0.0-alpha.0" + "@internationalized/number" "3.0.0-alpha.0" + "@react-aria/ssr" "^3.0.1" + "@react-aria/utils" "^3.6.0" + "@react-types/shared" "^3.4.0" + +"@react-aria/interactions@^3.2.1", "@react-aria/interactions@^3.3.3", "@react-aria/interactions@^3.3.4", "@react-aria/interactions@~3.3.4": + version "3.3.4" + resolved "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.3.4.tgz#a5b3a87f886cf0f4e28cbd13fbe02c7efb4f1e2e" + integrity sha512-WzT9aIRWvLZvZvuwNKKUkZzeomZgIrquAtwgRYGWbjSbrYPOT9B3w/GBEWZDYUG0c1K8NkIEAxTX0e+QI+tqAA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils" "^3.7.0" + "@react-types/shared" "^3.5.0" + +"@react-aria/label@^3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-aria/label/-/label-3.1.1.tgz#03dc5c4813cd1f51760ba48783c186c2eeda1189" + integrity sha512-9kZKJonYSXeY6hZULZrsujAb6uXDGEy8qPq0tjTVoTA3+gx26LOmLCLgvHFtxUK1e4s99rHmaSPdOtq5qu3EVQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils" "^3.3.0" + "@react-types/label" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-aria/listbox@~3.2.4": + version "3.2.4" + resolved "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.2.4.tgz#3162e47d64e1f6cd8fdfe45766cb88c3852a525d" + integrity sha512-IYs4oS2wzWVcWEtKG57zZLZI507WlDy24wuzymwgFxxIRXDVaBsSMOs7+uE7N1P4fLOa1yAlv170AvKDDbIJ2g== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.3.3" + "@react-aria/label" "^3.1.1" + "@react-aria/selection" "^3.3.2" + "@react-aria/utils" "^3.6.0" + "@react-stately/collections" "^3.3.0" + "@react-stately/list" "^3.2.2" + "@react-types/listbox" "^3.1.1" + "@react-types/shared" "^3.4.0" + +"@react-aria/menu@^3.2.0": + version "3.2.0" + resolved "https://registry.npmjs.org/@react-aria/menu/-/menu-3.2.0.tgz#cd9417105b3230f1c34ddddddb31a95f462393e2" + integrity sha512-CFgC82ZO/LjJtMhDUJFdE3+PV0jS88LK9CCr6w11ggp+U3Q2fPXPdkAVeEB3cJn4KI0TRCBgE+4EneIzdTEgcw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.3.4" + "@react-aria/overlays" "^3.6.2" + "@react-aria/selection" "^3.4.0" + "@react-aria/utils" "^3.7.0" + "@react-stately/collections" "^3.3.1" + "@react-stately/menu" "^3.2.1" + "@react-stately/tree" "^3.1.3" + "@react-types/button" "^3.3.1" + "@react-types/menu" "^3.1.1" + "@react-types/shared" "^3.5.0" + +"@react-aria/overlays@^3.6.1", "@react-aria/overlays@^3.6.2", "@react-aria/overlays@~3.6.2": + version "3.6.2" + resolved "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.6.2.tgz#0a9fcb7426d4321dc80ee636282228eb7be83a84" + integrity sha512-6f9o1fypGcB/VcprvoDm5280glaiAp/9RZeNPP+HPXE5MxpQIzFDJCzTrSezAUYNkueh/KNMpUxOUUgytloScQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.4" + "@react-aria/utils" "^3.7.0" + "@react-aria/visually-hidden" "^3.2.1" + "@react-stately/overlays" "^3.1.1" + "@react-types/button" "^3.3.1" + "@react-types/overlays" "^3.4.0" + dom-helpers "^3.3.1" + +"@react-aria/select@~3.3.1": + version "3.3.1" + resolved "https://registry.npmjs.org/@react-aria/select/-/select-3.3.1.tgz#cfa694ff4b2020846e08b58f6f0a489f0d2b24ff" + integrity sha512-E/EZ4SKf8P5EMVznCmTjfa9y1cR6L+WIzXHTFAlwrmmIzNirHSipbFp6LpJzoByqd0p9IKxhBdxqFP92url0Qg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.4" + "@react-aria/label" "^3.1.1" + "@react-aria/menu" "^3.2.0" + "@react-aria/selection" "^3.4.0" + "@react-aria/utils" "^3.7.0" + "@react-aria/visually-hidden" "^3.2.1" + "@react-stately/select" "^3.1.1" + "@react-types/button" "^3.3.1" + "@react-types/select" "^3.2.0" + "@react-types/shared" "^3.5.0" + +"@react-aria/selection@^3.3.2", "@react-aria/selection@^3.4.0": + version "3.4.0" + resolved "https://registry.npmjs.org/@react-aria/selection/-/selection-3.4.0.tgz#abd7aa5435f504e314a72122f2bcaef43b06fa78" + integrity sha512-ddxiB9zhy8JEkG4+DElSMNrSKxRI3RQKyOwQf4i3omqXj8bMH1XJesFwbdGNmR/zrbzXvr35ln9y3S0WS+4ClA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.4" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.4" + "@react-aria/utils" "^3.7.0" + "@react-stately/collections" "^3.3.1" + "@react-stately/selection" "^3.4.0" + "@react-types/shared" "^3.5.0" + +"@react-aria/separator@~3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-aria/separator/-/separator-3.1.1.tgz#bfcd71bb5ab50dc04a7f307b84bd77955f08002f" + integrity sha512-VbiqQsTtKKMjvMcPVWgTbDHzx7qMP3VFC+y9cEVajicMwRoO4bn7kJgcSzainXpWx70bhT5RW1mt84fzxMF+Lg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils" "^3.3.0" + "@react-types/shared" "^3.2.1" + +"@react-aria/ssr@^3.0.1", "@react-aria/ssr@~3.0.1": + version "3.0.1" + resolved "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.0.1.tgz#5f7c111f9ecd184b8f6140139703c1ee552dca30" + integrity sha512-rweMNcSkUO4YkcmgFIoZFvgPyHN2P9DOjq3VOHnZ8SG3Y4TTvSY6Iv90KgzeEfmWCUqqt65FYH4JgrpGNToEMw== + dependencies: + "@babel/runtime" "^7.6.2" + +"@react-aria/tooltip@~3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.1.1.tgz#e0dfdd9e51b581563f684927249d70e1bad761e3" + integrity sha512-wTszWN6lG3A9Ofdrhv1vG9aOmoqzuUZCbG9ZbXZ9+RtiOMwP/WnuSLWXcMH+KaWYpaImy7h1MDfOgHeaPxCbag== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.3" + "@react-aria/interactions" "^3.3.3" + "@react-aria/overlays" "^3.6.1" + "@react-aria/utils" "^3.6.0" + "@react-stately/tooltip" "^3.0.2" + "@react-types/shared" "^3.4.0" + "@react-types/tooltip" "^3.1.1" + +"@react-aria/utils@^3.3.0", "@react-aria/utils@^3.6.0", "@react-aria/utils@^3.7.0", "@react-aria/utils@~3.7.0": + version "3.7.0" + resolved "https://registry.npmjs.org/@react-aria/utils/-/utils-3.7.0.tgz#0aab1f682e9f1781cfadd2dd1ef9494bfaca0cbf" + integrity sha512-sMCdX0eF+4B05I+SX9V/NzI1/fD45vabi0dNyJhbSu2xNI82VIYgPcMBDjGU83NJSnjY969R3/JbbLjBrtKUgA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/ssr" "^3.0.1" + "@react-stately/utils" "^3.2.0" + "@react-types/shared" "^3.5.0" + clsx "^1.1.1" + +"@react-aria/visually-hidden@^3.2.1": + version "3.2.1" + resolved "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.2.1.tgz#c022c562346140a473242448045add59269a74fd" + integrity sha512-ba7bQD09MuzUghtPyrQoXHgQnRRfOu039roVKPz2em9gHD0Wy4ap2UPwlzx35KzNq6FdCzMDZeSZHSnUWlzKnw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.2.1" + "@react-aria/utils" "^3.3.0" + clsx "^1.1.1" + +"@react-hook/debounce@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz#9eea8b5d81d4cb67cd72dd8657b3ff724afc7cad" + integrity sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag== + dependencies: + "@react-hook/latest" "^1.0.2" + +"@react-hook/event@^1.2.1": + version "1.2.3" + resolved "https://registry.npmjs.org/@react-hook/event/-/event-1.2.3.tgz#cfe86d5cf36f53e85b367ff619990d001b5c82ae" + integrity sha512-WMBwLnYY2rubLeecsi4skl1imfx0oiXTgazV/1ByPT6WkmLvxUao3hC+mxps5D/+JK4Fq3uG9OWU/dn5jMtXyg== + dependencies: + "@react-hook/passive-layout-effect" "^1.2.0" + +"@react-hook/latest@^1.0.2": + version "1.0.3" + resolved "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80" + integrity sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg== + +"@react-hook/passive-layout-effect@^1.2.0": + version "1.2.1" + resolved "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz#c06dac2d011f36d61259aa1c6df4f0d5e28bc55e" + integrity sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg== + +"@react-hook/resize-observer@^1.1.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.0.tgz#a44b385d998f4ab33aa9481a43c4ac33af21f7d7" + integrity sha512-7Cpy0aaZ3xXlSabQ43aZcfgzwYSidrshEKGDqpfvdx7pHnGDGskr8m1Ajb6yamJUSdTRgqCemYQcwouCqMmZoQ== + dependencies: + "@react-hook/latest" "^1.0.2" + "@react-hook/passive-layout-effect" "^1.2.0" + "@types/raf-schd" "^4.0.0" + raf-schd "^4.0.2" + resize-observer-polyfill "^1.5.1" + +"@react-hook/size@^2.1.1": + version "2.1.1" + resolved "https://registry.npmjs.org/@react-hook/size/-/size-2.1.1.tgz#10d3fb5bc61e128f0d7924714a925a04c992ed1f" + integrity sha512-QtHDsrvz8p4cai2UKxBpzk0r/uM63UyhmozTVChaDHJsVpN5/7A2yu8wuGyNhExdeCYMclLM21QjY1dyqpGbuQ== + dependencies: + "@react-hook/passive-layout-effect" "^1.2.0" + "@react-hook/resize-observer" "^1.1.0" + +"@react-hook/throttle@^2.2.0": + version "2.2.0" + resolved "https://registry.npmjs.org/@react-hook/throttle/-/throttle-2.2.0.tgz#d0402714a06e1ba0bc1da1fdf5c3c5cd0e08d45a" + integrity sha512-LJ5eg+yMV8lXtqK3lR+OtOZ2WH/EfWvuiEEu0M3bhR7dZRfTyEJKxH1oK9uyBxiXPtWXiQggWbZirMCXam51tg== + dependencies: + "@react-hook/latest" "^1.0.2" + +"@react-hook/window-size@^3.0.7": + version "3.0.7" + resolved "https://registry.npmjs.org/@react-hook/window-size/-/window-size-3.0.7.tgz#00d176e7a8eb55814e161eae34aae20afbcbe35d" + integrity sha512-bK5ed/jN+cxy0s1jt2CelCnUt7jZRseUvPQ22ZJkUl/QDOsD+7CA/6wcqC3c0QweM/fPBRP6uI56TJ48SnlVww== + dependencies: + "@react-hook/debounce" "^3.0.0" + "@react-hook/event" "^1.2.1" + "@react-hook/throttle" "^2.2.0" + +"@react-spectrum/utils@~3.5.1": + version "3.5.1" + resolved "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.5.1.tgz#dd733913e30e0ed59c6bdae430531283b4cdcc96" + integrity sha512-lSdxCtshkj9dsi9sGcem6s9lak2XT55uyZGZr2S3w6iwm3aS7OlJNoT/4xtUFGW3t1bF2oxNngHX6eLl+quFyw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/ssr" "^3.0.1" + "@react-aria/utils" "^3.6.0" + "@react-types/shared" "^3.4.0" + clsx "^1.1.1" + +"@react-stately/collections@^3.2.1", "@react-stately/collections@^3.3.0", "@react-stately/collections@^3.3.1": + version "3.3.1" + resolved "https://registry.npmjs.org/@react-stately/collections/-/collections-3.3.1.tgz#683acf6e7a4e9ea174e1cf82a13bb8175ba0a1a0" + integrity sha512-bBiOj0hszFpCbk9KhSm04Jo87GAODm8kA52uFiGAO99yb2ypO+UTFYseBExFQ59cV7b++UMCfdJe/+Ymv9RALg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-types/shared" "^3.5.0" + +"@react-stately/list@^3.2.1", "@react-stately/list@^3.2.2": + version "3.2.2" + resolved "https://registry.npmjs.org/@react-stately/list/-/list-3.2.2.tgz#fb368cc7678503179202d11aef0ef8d48d1cbf12" + integrity sha512-8sJvy0cUhllhUMadYjX1qKmTxAWMRGxkvZpU/6reOEChlvibjAwbn2paoR8yZ+ppieeQOBe+AAYTl53gK8fKDA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.3.0" + "@react-stately/selection" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/menu@^3.2.1": + version "3.2.1" + resolved "https://registry.npmjs.org/@react-stately/menu/-/menu-3.2.1.tgz#314646217e5dd49fa1da6886d33f485d44d6f0dd" + integrity sha512-8cpCynynjjn3qWNzrZMJEpsdk4tkXK9q3Xaw0ADqVym/NC/wPU3P3cqL4HY+ETar01tS2x8K23qYHbOZz0cQtQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/overlays" "^3.1.1" + "@react-stately/utils" "^3.1.1" + "@react-types/menu" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/overlays@^3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.1.1.tgz#6c1a393b77148184f7b1df22ece832d694d5a8b4" + integrity sha512-79YYXvmWKflezNPhc4fvXA1rDZurZvvEJcmbStNlR5Ryrnk/sQiOQCoVWooi2M4glSMT3UOTvD7YEnXxARcuIQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/utils" "^3.1.1" + "@react-types/overlays" "^3.2.1" + +"@react-stately/select@^3.1.1", "@react-stately/select@~3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-stately/select/-/select-3.1.1.tgz#f49602ee7fc71f14550360bfa7c5becab58ac877" + integrity sha512-cl63nW66IJPsn9WQjKvghAIFKdFKuU1txx4zdEGY9tcwB/Yc+bgniLGOOTExJqN/RdPW9uBny5jjWcc4OQXyJA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.2.1" + "@react-stately/list" "^3.2.1" + "@react-stately/menu" "^3.2.1" + "@react-stately/selection" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/select" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/selection@^3.2.1", "@react-stately/selection@^3.4.0": + version "3.4.0" + resolved "https://registry.npmjs.org/@react-stately/selection/-/selection-3.4.0.tgz#795134e17b59f21cc4979b30179bccdfc2e3b9c1" + integrity sha512-5RV9f1Tm4WSTDguL1iizYcgzeWiK6Qe2EZ03zaaE9gm5UyyIrEPQD4WW9Semio2cUF8IFuWLaOvRCk+un7p53Q== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.3.1" + "@react-stately/utils" "^3.1.1" + "@react-types/shared" "^3.5.0" + +"@react-stately/toggle@^3.2.1": + version "3.2.1" + resolved "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.2.1.tgz#8b10b5eb99c3c4df2c36d17a5f23b77773ed7722" + integrity sha512-gZVuJ8OYoATUoXzdprsyx6O1w3wCrN+J0KnjhrjjKTrBG68n3pZH0p6dM0XpsaCzlSv0UgNa4fhHS3dYfr/ovw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/utils" "^3.1.1" + "@react-types/checkbox" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/tooltip@^3.0.2", "@react-stately/tooltip@~3.0.3": + version "3.0.3" + resolved "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.0.3.tgz#577fbf3cca39db7047ec2d77ddc03a56c454a82a" + integrity sha512-N98S8ccHEpgbgM6wIMZwqz37s8IQTa+5nPr8eVnIs5wqwdnAARFjvckr2okOGwaksofp1wtpcYbnNrIBwexJOg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/overlays" "^3.1.1" + "@react-stately/utils" "^3.2.0" + "@react-types/tooltip" "^3.1.1" + +"@react-stately/tree@^3.1.3": + version "3.1.3" + resolved "https://registry.npmjs.org/@react-stately/tree/-/tree-3.1.3.tgz#5ceb1aa3793836a503253ddd47fc9227ac59c7b4" + integrity sha512-xwM2C3ppd8yJfduwgff7Gl2bNPMVeF4K65InFJZNVx5JLKFF6DJLAPTORAHLpCN+AoB8bY4sRK3V5fNBVpz0oQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.3.1" + "@react-stately/selection" "^3.4.0" + "@react-stately/utils" "^3.1.1" + "@react-types/shared" "^3.5.0" + +"@react-stately/utils@^3.1.1", "@react-stately/utils@^3.2.0": + version "3.2.0" + resolved "https://registry.npmjs.org/@react-stately/utils/-/utils-3.2.0.tgz#0b90a70fee3236025ad8bed1f0e3555d5fc10296" + integrity sha512-vVBJvHVLnQySgqZ7OfP3ngDdwfGscJDsSD3WcN5ntHiT3JlZ5bksQReDkJEs20SFu2ST4w/0K7O4m97SbuMl2Q== + dependencies: + "@babel/runtime" "^7.6.2" + +"@react-types/button@^3.3.1": + version "3.3.1" + resolved "https://registry.npmjs.org/@react-types/button/-/button-3.3.1.tgz#4bdd325bc7df19c33911af256f63eae91e2a452e" + integrity sha512-xKLGSzGfsDBMe0SM7icOLNmzW38sdNSDSGMdrTLd3ygxb6pXY/LlcTdx7Sq28hdW8XL/ikFAnoQeS1VLXZHj7w== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/checkbox@^3.2.1": + version "3.2.2" + resolved "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.2.2.tgz#7182d44a533e2ffd2c9118372cbc2c33b006eb18" + integrity sha512-WAAqLdjf6GUWjsMN5NaFMFumOtGTq+3+48CpM0ah2L+qmhMdj1s4gvHDerhls6u4ovRK/7zhg7XK+qQwcYVqMg== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/dialog@^3.3.0": + version "3.3.0" + resolved "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.3.0.tgz#60a2b53f250ee082b53aef9340c80f1afe654bc7" + integrity sha512-63Vsr/UOZiaajlNDQUgWDi6v3EMenV1f8Cwh+L4lcyIJnbC6WeC2VEV3ld/TYVC0U58SQ0k7u2EIyHkWjc5kdQ== + dependencies: + "@react-types/overlays" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-types/label@^3.2.1": + version "3.4.0" + resolved "https://registry.npmjs.org/@react-types/label/-/label-3.4.0.tgz#6023dc9dd0146324ead52e08540cd60e57a3e27f" + integrity sha512-l84ysm1dcjL/5qVk9iN74z+/Ul0999XqnwTu6aTbuwAXqMk2sTU45eK2Yp/FJ7YWeflcF1vsomTkjMkX0BHKMw== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/listbox@^3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.1.1.tgz#b896303ccb87123cf59ee2c089953d7928497c9b" + integrity sha512-HAljfdpbyLoJL9iwqz7Fw9MOmRwfzODeN+sr5ncE0eXJxnRBFhb5LjbjAN1dUBrKFBkv3etGlYu5HvX+PJjpew== + dependencies: + "@react-types/shared" "^3.2.1" + +"@react-types/menu@^3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-types/menu/-/menu-3.1.1.tgz#e5aa52ac07c083243540dd5da0790a85fd1628c6" + integrity sha512-/xZWp4/3P/8dKFAGuzxz8IccSXvJH0TmHIk2/xnj2Eyw9152IfutIpOda3iswhjrx1LEkzUgdJ8bCdiebgg6QQ== + dependencies: + "@react-types/overlays" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-types/overlays@^3.2.1", "@react-types/overlays@^3.4.0": + version "3.4.0" + resolved "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.4.0.tgz#3c4619906bb12e3697e770b59c2090bb18da25bd" + integrity sha512-ddiMB6JXR7acQnRFEL2/6SSdBropmNrcAFk3qFCfovuVZh6STYhPmoAgj06mJFDoAD63pxayysfPG2EvLl2yAw== + dependencies: + "@react-types/shared" "^3.3.0" + +"@react-types/select@^3.1.1", "@react-types/select@^3.2.0": + version "3.2.0" + resolved "https://registry.npmjs.org/@react-types/select/-/select-3.2.0.tgz#31b9e0f94fc24f053f4a1f073e174ffd59bac055" + integrity sha512-9vYhQWr1iB+3KWTZ1RxS2xZq0n0CJfsTRbEr0akLrtE/pRLC4O4l8RMFD49HyX0fShvz1FStmxTE2x7k8yVc4w== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/shared@^3.2.1", "@react-types/shared@^3.3.0", "@react-types/shared@^3.4.0", "@react-types/shared@^3.5.0": + version "3.5.0" + resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.5.0.tgz#dbc90e8fe711967e66d6f3ce0e17d34b24bd6283" + integrity sha512-997Me7AegwJOI10ye/Q5ds6fT+VBc6XcsXYzPqOD+HIbyL1kUQNDF/VoO37ib7KEH8jXH9aceoX9blz3Q1QcpA== + +"@react-types/tooltip@^3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.1.1.tgz#7d45a4dd8c57c422a1a2dcb03b6c043e7481c3ca" + integrity sha512-18gM2Co9tzCDfN0tEdfboD18sXDtD6YiKctd8HQ8tBiRO4IF1ce9ubKe6++Lj+38GQPq7GWFFoUiS1WArTWIHA== + dependencies: + "@react-types/overlays" "^3.4.0" + "@react-types/shared" "^3.4.0" + "@rjsf/core@^2.4.0": version "2.5.1" resolved "https://registry.npmjs.org/@rjsf/core/-/core-2.5.1.tgz#95a842d22bab5f83929662fcd73739108e9f5cbb" @@ -4440,6 +4945,179 @@ dependencies: any-observable "^0.3.0" +"@sentry/apm@5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/apm/-/apm-5.13.2.tgz#3a0809912426f52e19b1f4a603e99423a0ac8fb9" + integrity sha512-Pv6PRVkcmmYYIT422gXm968F8YQyf5uN1RSHOFBjWsxI3Ke/uRgeEdIVKPDo78GklBfETyRN6GyLEZ555jRe6g== + dependencies: + "@sentry/browser" "5.13.2" + "@sentry/hub" "5.13.2" + "@sentry/minimal" "5.13.2" + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/apm@5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/apm/-/apm-5.19.2.tgz#369fdcbc9fa5db992f707b24f3165e106a277cf7" + integrity sha512-V7p5niqG/Nn1OSMAyreChiIrQFYzFHKADKNaDEvIXqC4hxFnMG8lPRqEFJH49fNjsFBFfIG9iY1rO1ZFg3S42Q== + dependencies: + "@sentry/browser" "5.19.2" + "@sentry/hub" "5.19.2" + "@sentry/minimal" "5.19.2" + "@sentry/types" "5.19.2" + "@sentry/utils" "5.19.2" + tslib "^1.9.3" + +"@sentry/browser@5.13.2", "@sentry/browser@~5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/browser/-/browser-5.13.2.tgz#fcca630c8c80447ba8392803d4e4450fd2231b92" + integrity sha512-4MeauHs8Rf1c2FF6n84wrvA4LexEL1K/Tg3r+1vigItiqyyyYBx1sPjHGZeKeilgBi+6IEV5O8sy30QIrA/NsQ== + dependencies: + "@sentry/core" "5.13.2" + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/browser@5.19.2", "@sentry/browser@~5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/browser/-/browser-5.19.2.tgz#8bad445b8d1efd50e6510bb43b3018b941f6e5cb" + integrity sha512-o6Z532n+0N5ANDzgR9GN+Q6CU7zVlIJvBEW234rBiB+ZZj6XwTLS1dD+JexGr8lCo8PeXI2rypKcj1jUGLVW8w== + dependencies: + "@sentry/core" "5.19.2" + "@sentry/types" "5.19.2" + "@sentry/utils" "5.19.2" + tslib "^1.9.3" + +"@sentry/core@5.13.2", "@sentry/core@~5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/core/-/core-5.13.2.tgz#d89e199beef612d0a01e5c4df4e0bb7efcb72c74" + integrity sha512-iB7CQSt9e0EJhSmcNOCjzJ/u7E7qYJ3mI3h44GO83n7VOmxBXKSvtUl9FpKFypbWrsdrDz8HihLgAZZoMLWpPA== + dependencies: + "@sentry/hub" "5.13.2" + "@sentry/minimal" "5.13.2" + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/core@5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/core/-/core-5.19.2.tgz#99a64ef0e55230fc02a083c48fa07ada85de4929" + integrity sha512-sfbBsVXpA0WYJUichz5IhvqKD8xJUfQvsszrTsUKa7PQAMAboOmuh6bo8KquaVQnAZyZWZU08UduvlSV3tA7tw== + dependencies: + "@sentry/hub" "5.19.2" + "@sentry/minimal" "5.19.2" + "@sentry/types" "5.19.2" + "@sentry/utils" "5.19.2" + tslib "^1.9.3" + +"@sentry/electron@~1.3.0": + version "1.3.2" + resolved "https://registry.npmjs.org/@sentry/electron/-/electron-1.3.2.tgz#83c40943f2fad5e72c77dadf524fd59d1a773e3f" + integrity sha512-fhD6cF7Jy0AXAVNHrUnxhzK5d/reXpzRcp5Ggnr+IRoijGe7rsq/AlOX8KhLS6SmQdI/XXb3F7fxHdItBV9+7w== + dependencies: + "@sentry/browser" "~5.13.2" + "@sentry/core" "~5.13.2" + "@sentry/minimal" "~5.13.2" + "@sentry/node" "~5.13.2" + "@sentry/types" "~5.13.2" + "@sentry/utils" "~5.13.2" + electron-fetch "^1.4.0" + form-data "2.5.1" + util.promisify "1.0.1" + +"@sentry/hub@5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.13.2.tgz#875a5ba983d6ada5caae5b6b4decd0257ef5cdb7" + integrity sha512-/U7yq3DTuRz8SRpZVKAaenW9sD2F5wbj12kDVPxPnGspyqhy0wBWKs9j0YJfBiDXMKOwp3HX964O3ygtwjnfAw== + dependencies: + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/hub@5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.19.2.tgz#ab7f3d2d253c3441b2833a530b17c6de2418b2c7" + integrity sha512-2KkEYX4q9TDCOiaVEo2kQ1W0IXyZxJxZtIjDdFQyes9T4ubYlKHAbvCjTxHSQv37lDO4t7sOIApWG9rlkHzlEA== + dependencies: + "@sentry/types" "5.19.2" + "@sentry/utils" "5.19.2" + tslib "^1.9.3" + +"@sentry/minimal@5.13.2", "@sentry/minimal@~5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.13.2.tgz#e42e33dc74fc935f8857d1a43a528afd741640fd" + integrity sha512-VV0eA3HgrnN3mac1XVPpSCLukYsU+QxegbmpnZ8UL8eIQSZ/ZikYxagDNlZbdnmXHUpOEUeag2gxVntSCo5UcA== + dependencies: + "@sentry/hub" "5.13.2" + "@sentry/types" "5.13.2" + tslib "^1.9.3" + +"@sentry/minimal@5.19.2", "@sentry/minimal@~5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.19.2.tgz#0fc2fdf9911a0cb31b52f7ccad061b74785724a3" + integrity sha512-rApEOkjy+ZmkeqEItgFvUFxe5l+dht9AumuUzq74pWp+HJqxxv9IVTusKppBsE1adjtmyhwK4O3Wr8qyc75xlw== + dependencies: + "@sentry/hub" "5.19.2" + "@sentry/types" "5.19.2" + tslib "^1.9.3" + +"@sentry/node@~5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/node/-/node-5.13.2.tgz#3be5608e00fb3fe1b813ad8365073a465d19f5f6" + integrity sha512-LwNOUvc0+28jYfI0o4HmkDTEYdY3dWvSCnL5zggO12buon7Wc+jirXZbEQAx84HlXu7sGSjtKCTzUQOphv7sPw== + dependencies: + "@sentry/apm" "5.13.2" + "@sentry/core" "5.13.2" + "@sentry/hub" "5.13.2" + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + cookie "^0.3.1" + https-proxy-agent "^4.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/node@~5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/node/-/node-5.19.2.tgz#8c1c2f6c983c3d8b25143e5b99c4b6cc745125ec" + integrity sha512-gbww3iTWkdvYIAhOmULbv8znKwkIpklGJ0SPtAh0orUMuaa0lVht+6HQIhRgeXp50lMzNaYC3fuzkbFfYgpS7A== + dependencies: + "@sentry/apm" "5.19.2" + "@sentry/core" "5.19.2" + "@sentry/hub" "5.19.2" + "@sentry/types" "5.19.2" + "@sentry/utils" "5.19.2" + cookie "^0.3.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/types@5.13.2", "@sentry/types@~5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/types/-/types-5.13.2.tgz#8e68c31f8fb99b4074374bff13ed01035b373d8c" + integrity sha512-mgAEQyc77PYBnAjnslSXUz6aKgDlunlg2c2qSK/ivKlEkTgTWWW/dE76++qVdrqM8SupnqQoiXyPDL0wUNdB3g== + +"@sentry/types@5.19.2", "@sentry/types@~5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/types/-/types-5.19.2.tgz#ead586f0b64b91c396d3521b938ca25f7b59d655" + integrity sha512-O6zkW8oM1qK5Uma9+B/UMlmlm9/gkw9MooqycWuEhIaKfDBj/yVbwb/UTiJmNkGc5VJQo0v1uXUZZQt6/Xq1GA== + +"@sentry/utils@5.13.2", "@sentry/utils@~5.13.2": + version "5.13.2" + resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.13.2.tgz#441594f4f9412bfd1690739ce986bf3a49687806" + integrity sha512-LwPQl6WRMKEnd16kg35HS3yE+VhBc8vN4+BBIlrgs7X0aoT+AbEd/sQLMisDgxNboCF44Ho3RCKtztiPb9blqg== + dependencies: + "@sentry/types" "5.13.2" + tslib "^1.9.3" + +"@sentry/utils@5.19.2": + version "5.19.2" + resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.19.2.tgz#f2819d9de5abc33173019e81955904247e4a8246" + integrity sha512-gEPkC0CJwvIWqcTcPSdIzqJkJa9N5vZzUZyBvdu1oiyJu7MfazpJEvj3whfJMysSfXJQxoJ+a1IPrA73VY23VA== + dependencies: + "@sentry/types" "5.19.2" + tslib "^1.9.3" + "@sideway/address@^4.1.0": version "4.1.1" resolved "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d" @@ -4508,6 +5186,168 @@ resolved "https://registry.npmjs.org/@spotify/prettier-config/-/prettier-config-9.0.0.tgz#7b562d56573c6fc0094446fbc92b22bc318945dc" integrity sha512-In1q0tIiqTYKAGe3KOHDcFDdZRFISyQeSeipeTHGfki23ebHRZcjxvqj5SSdBkw65D4VpSREMi0s9i5iJiMcTw== +"@stoplight/beaver-logger@^4.0.12": + version "4.0.12" + resolved "https://registry.npmjs.org/@stoplight/beaver-logger/-/beaver-logger-4.0.12.tgz#f754d2f20b4728f5e96fdec574729988e4fb0c2d" + integrity sha512-VPSqZ706GaAB/7VcXcKvzaxaKwHmr2jUNcn0mTvhR3dwglmDEsqoKRvzTxH+Zu1VUIRjdcy9zmU7mSfjKjPt7Q== + dependencies: + belter "^1.0.17" + zalgo-promise "^1.0.26" + +"@stoplight/json-schema-merge-allof@^0.7.5": + version "0.7.6" + resolved "https://registry.npmjs.org/@stoplight/json-schema-merge-allof/-/json-schema-merge-allof-0.7.6.tgz#39efac12a497ed29a06ae48e0141885634a045a4" + integrity sha512-xLbJC2VOd9AxO1VvvgyP/mWOqZbeg6mLpYzlzU4egDTTIrTsSqtv+yFakpPciuuMlOmJU/KzZK9C5AbMgE+VgQ== + dependencies: + compute-lcm "^1.1.0" + json-schema-compare "^0.2.2" + lodash "^4.17.4" + +"@stoplight/json-schema-tree@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@stoplight/json-schema-tree/-/json-schema-tree-2.0.0.tgz#00d54cb6aa2a791c34be91fc30cc92e6d448258c" + integrity sha512-vnzcb0TC07xh89lAVGjBTJ2CWvCqmDJDIs3u+gvgvjDPY86CQ0Wl4D2Cmb0iuqd986aiDPc8vDQf1N0dSq5+9A== + dependencies: + "@stoplight/json" "^3.12.0" + "@stoplight/json-schema-merge-allof" "^0.7.5" + "@stoplight/lifecycle" "^2.3.2" + "@types/json-schema" "^7.0.7" + magic-error "^0.0.0" + +"@stoplight/json-schema-viewer@^4.0.0-beta.16": + version "4.0.0-beta.16" + resolved "https://registry.npmjs.org/@stoplight/json-schema-viewer/-/json-schema-viewer-4.0.0-beta.16.tgz#8f55debcb1e84ddcd6f55012ed52712560beaca5" + integrity sha512-f6GijfWi15maRQH4J/ulc8tFpoc+ejGeckiIH+USTLPd7fmGiIU5wINbJSVbLJ5Hccky8wraxlCzfdRuck84Jw== + dependencies: + "@fortawesome/free-solid-svg-icons" "^5.15.2" + "@stoplight/json" "^3.10.0" + "@stoplight/json-schema-tree" "^2.0.0" + "@stoplight/mosaic" "1.0.0-beta.46" + "@stoplight/react-error-boundary" "^1.0.0" + "@types/json-schema" "^7.0.7" + classnames "^2.2.6" + lodash "^4.17.19" + +"@stoplight/json@^3.10.0", "@stoplight/json@^3.12.0": + version "3.12.0" + resolved "https://registry.npmjs.org/@stoplight/json/-/json-3.12.0.tgz#26c8d32da78eac6a760ba2c9cca6ae717dc417b4" + integrity sha512-c0bvFOGICk8QWIat72Td2GG6Bdvq/6O2jQcDZ8rEjh56YOdC/YPn1S8ihKu3AntJCtvqC9eTfadWBqkNK9HAjw== + dependencies: + "@stoplight/ordered-object-literal" "^1.0.1" + "@stoplight/types" "^11.9.0" + jsonc-parser "~2.2.1" + lodash "^4.17.15" + safe-stable-stringify "^1.1" + +"@stoplight/lifecycle@^2.3.2": + version "2.3.2" + resolved "https://registry.npmjs.org/@stoplight/lifecycle/-/lifecycle-2.3.2.tgz#d61dff9ba20648241432e2daaef547214dc8976e" + integrity sha512-v0u8p27FA/eg04b4z6QXw4s0NeeFcRzyvseBW0+k/q4jtpg7EhVCqy42EbbbU43NTNDpIeQ81OcvkFz+6CYshw== + dependencies: + wolfy87-eventemitter "~5.2.8" + +"@stoplight/mosaic@1.0.0-beta.46": + version "1.0.0-beta.46" + resolved "https://registry.npmjs.org/@stoplight/mosaic/-/mosaic-1.0.0-beta.46.tgz#35fa3c9aebdb3c3535d1d8dd53cc52f1b2b1f5db" + integrity sha512-GlGLb2RzvzS7CQpq006c6eZhe7tIgRvDIt/nYqx+FXJEh0M045I2EObstdbyQt/sL7Zw5lae3uxiQ/1j8FqkRA== + dependencies: + "@fortawesome/fontawesome-svg-core" "^1.2.35" + "@fortawesome/free-solid-svg-icons" "^5.15.3" + "@fortawesome/react-fontawesome" "^0.1.14" + "@react-aria/button" "~3.3.1" + "@react-aria/dialog" "~3.1.2" + "@react-aria/focus" "~3.2.4" + "@react-aria/interactions" "~3.3.4" + "@react-aria/listbox" "~3.2.4" + "@react-aria/overlays" "~3.6.2" + "@react-aria/select" "~3.3.1" + "@react-aria/separator" "~3.1.1" + "@react-aria/ssr" "~3.0.1" + "@react-aria/tooltip" "~3.1.1" + "@react-aria/utils" "~3.7.0" + "@react-hook/size" "^2.1.1" + "@react-hook/window-size" "^3.0.7" + "@react-spectrum/utils" "~3.5.1" + "@react-stately/select" "~3.1.1" + "@react-stately/tooltip" "~3.0.3" + clsx "^1.1.1" + copy-to-clipboard "^3.3.1" + deepmerge "^4.2.2" + lodash.get "^4.4.2" + polished "^4.1.1" + reakit "npm:@stoplight/reakit@~1.3.5" + ts-keycode-enum "^1.0.6" + tslib "^2.1.0" + zustand "^3.3.3" + +"@stoplight/mosaic@^1.0.0-beta.46": + version "1.0.0-beta.47" + resolved "https://registry.npmjs.org/@stoplight/mosaic/-/mosaic-1.0.0-beta.47.tgz#6b212163af3ab7fb981dee75785f1b967299171e" + integrity sha512-Rp6aXslPB0X2hqj8MFmbYSWUvSjo/ResDFNQoMHD1BCBGw0nTmlcPZaQDKQApUFQrDBzih+OGRKTk0mGxrTP3A== + dependencies: + "@fortawesome/fontawesome-svg-core" "^1.2.35" + "@fortawesome/free-solid-svg-icons" "^5.15.3" + "@fortawesome/react-fontawesome" "^0.1.14" + "@react-aria/button" "~3.3.1" + "@react-aria/dialog" "~3.1.2" + "@react-aria/focus" "~3.2.4" + "@react-aria/interactions" "~3.3.4" + "@react-aria/listbox" "~3.2.4" + "@react-aria/overlays" "~3.6.2" + "@react-aria/select" "~3.3.1" + "@react-aria/separator" "~3.1.1" + "@react-aria/ssr" "~3.0.1" + "@react-aria/tooltip" "~3.1.1" + "@react-aria/utils" "~3.7.0" + "@react-hook/size" "^2.1.1" + "@react-hook/window-size" "^3.0.7" + "@react-spectrum/utils" "~3.5.1" + "@react-stately/select" "~3.1.1" + "@react-stately/tooltip" "~3.0.3" + clsx "^1.1.1" + copy-to-clipboard "^3.3.1" + deepmerge "^4.2.2" + lodash.get "^4.4.2" + polished "^4.1.1" + reakit "npm:@stoplight/reakit@~1.3.5" + ts-keycode-enum "^1.0.6" + tslib "^2.1.0" + zustand "^3.3.3" + +"@stoplight/ordered-object-literal@^1.0.1": + version "1.0.2" + resolved "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.2.tgz#2a88a5ebc8b68b54837ac9a9ae7b779cdd862062" + integrity sha512-0ZMS/9sNU3kVo/6RF3eAv7MK9DY8WLjiVJB/tVyfF2lhr2R4kqh534jZ0PlrFB9CRXrdndzn1DbX6ihKZXft2w== + +"@stoplight/react-error-boundary@^1.0.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@stoplight/react-error-boundary/-/react-error-boundary-1.1.0.tgz#9b0fb5d0538abbf9a416723b90f5b776bf68a75d" + integrity sha512-z/1gDVQAafqYuJksL212F1DXHSr604KDqAspZwbC+kWVqCsddQBmXzwI4Lqqem4wHbNGeVZYk3svW+sILX/PUQ== + dependencies: + "@stoplight/types" "^11.9.0" + +"@stoplight/reporter@^1.10.0": + version "1.10.0" + resolved "https://registry.npmjs.org/@stoplight/reporter/-/reporter-1.10.0.tgz#cbb58a7842422178ff56410e3f009517a474a5ba" + integrity sha512-XdHIT+TwS00rEhsEClCddrACZCqxK+sh/R2EBFuXBTbWMIwujoWVTLPxEwhVkfm2JF57pK3jzULOFxEnNRnmpQ== + dependencies: + "@sentry/browser" "~5.19.2" + "@sentry/electron" "~1.3.0" + "@sentry/minimal" "~5.19.2" + "@sentry/node" "~5.19.2" + "@sentry/types" "~5.19.2" + "@stoplight/beaver-logger" "^4.0.12" + "@types/amplitude-js" "^5.11.0" + amplitude-js "^7.1.0" + +"@stoplight/types@^11.9.0": + version "11.10.0" + resolved "https://registry.npmjs.org/@stoplight/types/-/types-11.10.0.tgz#60bbee770526f4de9cd1c613c7ab84c4e4674126" + integrity sha512-ffHD9i4UHS8Gsg7Ar8pKjI9B4kq7MRekE7tCROFGcFDzQhfRx9T92AduoLAtP/010XNYq23yDKpLBRPIEk8+xg== + dependencies: + "@types/json-schema" "^7.0.4" + utility-types "^3.10.0" + "@storybook/addon-actions@^6.1.11": version "6.1.17" resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.1.17.tgz#9d32336284738cefa69b99acafa4b132d5533600" @@ -5631,6 +6471,11 @@ dependencies: "@types/node" "*" +"@types/amplitude-js@^5.11.0": + version "5.11.1" + resolved "https://registry.npmjs.org/@types/amplitude-js/-/amplitude-js-5.11.1.tgz#4883aa6f484530df3557de8683ff4529fcb7ec65" + integrity sha512-2BAZ8sMlOq4t0zC5LEBRL551u/kJPr+BTOe9OUtFT7J1U4Kgm+gHYmV4nYwq9sZnNj6MisCllKiiL27WEur7Sw== + "@types/anymatch@*": version "1.3.1" resolved "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -6211,6 +7056,11 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/json-schema@^7.0.7": + version "7.0.7" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + "@types/json-stable-stringify@^1.0.32": version "1.0.32" resolved "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" @@ -6532,6 +7382,11 @@ resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a" integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ== +"@types/raf-schd@^4.0.0": + version "4.0.1" + resolved "https://registry.npmjs.org/@types/raf-schd/-/raf-schd-4.0.1.tgz#1f9e03736f277fe9c7b82102bf18570a6ee19f82" + integrity sha512-Ha+EnKHFIh9EKW0/XZJPUd3EGDFisEvauaBd4VVCRPKeOqUxNEc9TodiY2Zhk33XCgzJucoFEcaoNcBAPHTQ2A== + "@types/raf@^3.4.0": version "3.4.0" resolved "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz#2b72cbd55405e071f1c4d29992638e022b20acc2" @@ -7418,6 +8273,11 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== +agent-base@5: + version "5.1.1" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" + integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== + agent-base@6: version "6.0.1" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4" @@ -7507,6 +8367,16 @@ alphanum-sort@^1.0.0: resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +amplitude-js@^7.1.0: + version "7.4.4" + resolved "https://registry.npmjs.org/amplitude-js/-/amplitude-js-7.4.4.tgz#1abd76f96a44ebdbf90e7371b37d071010deffe6" + integrity sha512-3Ojj1draRcXvfxi5P+Ye/6Y4roxtf1lQEjczcLDnHU9vxbPtT4fDblC9+cdJy7XmlJkGoq+KvnItlWfLuHV9GQ== + dependencies: + "@amplitude/ua-parser-js" "0.7.24" + "@amplitude/utils" "^1.0.5" + blueimp-md5 "^2.10.0" + query-string "5" + anafanafo@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/anafanafo/-/anafanafo-1.0.0.tgz#2e67190aed5dc67f5f0043b710146e7276c1afb8" @@ -8715,6 +9585,15 @@ before-after-hook@^2.1.0: resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A== +belter@^1.0.17: + version "1.0.165" + resolved "https://registry.npmjs.org/belter/-/belter-1.0.165.tgz#8bc32f0f30b94b67b80a63727b1584acd69942f0" + integrity sha512-TVOfXtLTTU3yyORjiYD2s9+fnTdxZp69KtR3pSDquLrdtK3OUmypgukVL+pIbcE6VMc85FRoFR48gybNZ2zHZQ== + dependencies: + cross-domain-safe-weakmap "^1" + cross-domain-utils "^2" + zalgo-promise "^1" + better-opn@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/better-opn/-/better-opn-2.0.0.tgz#c70d198e51164bdc220306a28a885d9ac7a14c44" @@ -8810,6 +9689,11 @@ bluebird@~3.4.1: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= +blueimp-md5@^2.10.0: + version "2.18.0" + resolved "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz#1152be1335f0c6b3911ed9e36db54f3e6ac52935" + integrity sha512-vE52okJvzsVWhcgUHOv+69OG3Mdg151xyn41aVQN/5W5S+S43qZhxECtYLAEHMSFWX6Mv5IZrzj3T5+JqXfj5Q== + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -8831,6 +9715,11 @@ body-parser@1.19.0, body-parser@^1.18.3: raw-body "2.4.0" type-is "~1.6.17" +body-scroll-lock@^3.1.5: + version "3.1.5" + resolved "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" + integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== + bonjour@^3.5.0: version "3.5.0" resolved "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" @@ -9863,7 +10752,7 @@ clone@^1.0.2: resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -clsx@^1.0.1, clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.0: +clsx@^1.0.1, clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.0, clsx@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== @@ -10403,6 +11292,11 @@ cookie@0.4.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + cookie@^0.4.1, cookie@~0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" @@ -10605,6 +11499,20 @@ create-require@^1.1.0: resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-domain-safe-weakmap@^1: + version "1.0.28" + resolved "https://registry.npmjs.org/cross-domain-safe-weakmap/-/cross-domain-safe-weakmap-1.0.28.tgz#d6c3c5af954340ce5f9d4ee5f3c38dba9513a165" + integrity sha512-gfQiQYSdWr9cYFVpmzp+b6MyTnefefDHr+fvm+JVv20hQxetV5J6chZOAusrpM/kFpTTbVDnHCziBFaREvgc0Q== + dependencies: + cross-domain-utils "^2.0.0" + +cross-domain-utils@^2, cross-domain-utils@^2.0.0: + version "2.0.34" + resolved "https://registry.npmjs.org/cross-domain-utils/-/cross-domain-utils-2.0.34.tgz#3f8dc8d82a5434213787433f17b76f51c316e382" + integrity sha512-ke4PirGRXwEElEmE/7k5aCvCW+EqbgseT7AOObzFfaVnOLuEVN9SjVWoOfS/qAT0rDPn3ggmNDW6mguMBy4HgA== + dependencies: + zalgo-promise "^1.0.11" + cross-env@^7.0.0: version "7.0.3" resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -11740,7 +12648,7 @@ dom-converter@^0.2: dependencies: utila "~0.4" -dom-helpers@^3.4.0: +dom-helpers@^3.3.1, dom-helpers@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== @@ -12030,6 +12938,13 @@ ejs@^3.1.2: dependencies: jake "^10.6.1" +electron-fetch@^1.4.0: + version "1.7.3" + resolved "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.7.3.tgz#06cf363d7f64073ec00a37e9949ec9d29ce6b08a" + integrity sha512-1AVMaxrHXTTMqd7EK0MGWusdqNr07Rpj8Th6bG4at0oNgIi/1LBwa9CjT/0Zy+M0k/tSJPS04nFxHj0SXDVgVw== + dependencies: + encoding "^0.1.13" + electron-to-chromium@^1.3.378: version "1.3.509" resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.509.tgz#830fcb89cd66dc2984d18d794973b99e3f00584c" @@ -12131,7 +13046,7 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12: +encoding@^0.1.12, encoding@^0.1.13: version "0.1.13" resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -13550,7 +14465,7 @@ fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.0.5, for tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@^2.3.1, form-data@^2.3.2, form-data@^2.5.0: +form-data@2.5.1, form-data@^2.3.1, form-data@^2.3.2, form-data@^2.5.0: version "2.5.1" resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== @@ -15095,6 +16010,14 @@ https-proxy-agent@^2.2.1: agent-base "^4.3.0" debug "^3.1.0" +https-proxy-agent@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" + integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== + dependencies: + agent-base "5" + debug "4" + https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -15487,6 +16410,18 @@ interpret@^2.0.0, interpret@^2.2.0: resolved "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +intl-messageformat-parser@1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075" + integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU= + +intl-messageformat@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc" + integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw= + dependencies: + intl-messageformat-parser "1.4.0" + invariant@^2.0.0, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -17027,6 +17962,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonc-parser@~2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" + integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -17795,7 +18735,7 @@ lodash.flattendeep@^4.0.0: resolved "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= -lodash.get@^4, lodash.get@^4.0.0: +lodash.get@^4, lodash.get@^4.0.0, lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= @@ -18060,6 +19000,11 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= + lunr@^2.3.9: version "2.3.9" resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -18085,6 +19030,11 @@ macos-release@^2.2.0: resolved "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== +magic-error@^0.0.0: + version "0.0.0" + resolved "https://registry.npmjs.org/magic-error/-/magic-error-0.0.0.tgz#f8630c98c55764b4851601901fdcb63428758b7d" + integrity sha512-ZMU3ylGOb/YQEpJo0XtAXbPGmKJtwzc3cuOHPrKgosV8AAc6db8dlQYLe0cp64P3BxkYZGoUvkvdNR5JM78beA== + magic-string@^0.25.7: version "0.25.7" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" @@ -20881,6 +21831,13 @@ polished@^3.4.4: dependencies: "@babel/runtime" "^7.9.2" +polished@^4.1.1: + version "4.1.2" + resolved "https://registry.npmjs.org/polished/-/polished-4.1.2.tgz#c04fcc203e287e2d866e9cfcaf102dae1c01a816" + integrity sha512-jq4t3PJUpVRcveC53nnbEX35VyQI05x3tniwp26WFdm1dwaNUBHAi5awa/roBlwQxx1uRhwNSYeAi/aMbfiJCQ== + dependencies: + "@babel/runtime" "^7.13.17" + popper.js@1.16.1-lts: version "1.16.1-lts" resolved "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" @@ -21731,6 +22688,15 @@ qs@~6.5.2: resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +query-string@5: + version "5.1.1" + resolved "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + query-string@^4.1.0: version "4.3.4" resolved "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -22645,6 +23611,36 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +reakit-system@^0.15.1: + version "0.15.1" + resolved "https://registry.npmjs.org/reakit-system/-/reakit-system-0.15.1.tgz#bf5cc7a03f60a817373bc9cbb4a689c1f4100547" + integrity sha512-PkqfAyEohtcEu/gUvKriCv42NywDtUgvocEN3147BI45dOFAB89nrT7wRIbIcKJiUT598F+JlPXAZZVLWhc1Kg== + dependencies: + reakit-utils "^0.15.1" + +reakit-utils@^0.15.1: + version "0.15.1" + resolved "https://registry.npmjs.org/reakit-utils/-/reakit-utils-0.15.1.tgz#797f0a43f6a1dbc22d161224d5d2272e287dbfe3" + integrity sha512-6cZgKGvOkAMQgkwU9jdYbHfkuIN1Pr+vwcB19plLvcTfVN0Or10JhIuj9X+JaPZyI7ydqTDFaKNdUcDP69o/+Q== + +reakit-warning@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/reakit-warning/-/reakit-warning-0.6.1.tgz#dba33bb8866aebe30e67ac433ead707d16d38a36" + integrity sha512-poFUV0EyxB+CcV9uTNBAFmcgsnR2DzAbOTkld4Ul+QOKSeEHZB3b3+MoZQgcYHmbvG19Na1uWaM7ES+/Eyr8tQ== + dependencies: + reakit-utils "^0.15.1" + +"reakit@npm:@stoplight/reakit@~1.3.5": + version "1.3.5" + resolved "https://registry.npmjs.org/@stoplight/reakit/-/reakit-1.3.5.tgz#0c1a1ae89a92de98413d3723b993c05d943bd56b" + integrity sha512-/Con1m4eSaztckgnEPckNPMkAIcOCYku60mANTGScevY9wYk56V2L6vpv6HR4r8gsFCl4S/CVoNCVMxkxi/pGw== + dependencies: + "@popperjs/core" "^2.5.4" + body-scroll-lock "^3.1.5" + reakit-system "^0.15.1" + reakit-utils "^0.15.1" + reakit-warning "^0.6.1" + recharts-scale@^0.4.2: version "0.4.3" resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.3.tgz#040b4f638ed687a530357292ecac880578384b59" @@ -23389,6 +24385,11 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" +safe-stable-stringify@^1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a" + integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -25542,6 +26543,11 @@ ts-jest@^26.4.3: semver "7.x" yargs-parser "20.x" +ts-keycode-enum@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/ts-keycode-enum/-/ts-keycode-enum-1.0.6.tgz#aeefd1c2fc7b0557f86a0e696e300905bbb4c1c1" + integrity sha512-DF8+Cf/FJJnPRxwz8agCoDelQXKZWQOS/gnnwx01nZ106tPJdB3BgJ9QTtLwXgR82D8O+nTjuZzWgf0Rg4vuRA== + ts-loader@^8.0.17: version "8.0.17" resolved "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.17.tgz#98f2ccff9130074f4079fd89b946b4c637b1f2fc" @@ -26220,7 +27226,7 @@ util.promisify@1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" -util.promisify@^1.0.0, util.promisify@~1.0.0: +util.promisify@1.0.1, util.promisify@^1.0.0, util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== @@ -26249,6 +27255,11 @@ utila@^0.4.0, utila@~0.4: resolved "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= +utility-types@^3.10.0: + version "3.10.0" + resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + utils-merge@1.0.1, utils-merge@1.x.x: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -26809,6 +27820,11 @@ winston@^3.2.1: triple-beam "^1.3.0" winston-transport "^4.3.0" +wolfy87-eventemitter@~5.2.8: + version "5.2.9" + resolved "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz#e879f770b30fbb6512a8afbb330c388591099c2a" + integrity sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw== + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -27268,6 +28284,11 @@ z-schema@~3.18.3: optionalDependencies: commander "^2.7.1" +zalgo-promise@^1, zalgo-promise@^1.0.11, zalgo-promise@^1.0.26: + version "1.0.46" + resolved "https://registry.npmjs.org/zalgo-promise/-/zalgo-promise-1.0.46.tgz#325988d75d0be4cd63a266bad5e18f8f6cd85675" + integrity sha512-tzPpQRqaQQavxl17TY98nznvmr+judUg3My7ugsUcRDbdqisYOE2z79HNNDgXnyX3eA0mf2bMOJrqHptt00npg== + zen-observable-ts@^0.8.21: version "0.8.21" resolved "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d" @@ -27313,6 +28334,11 @@ zombie@^6.1.4: tough-cookie "^2.3.4" ws "^6.1.2" +zustand@^3.3.3: + version "3.4.2" + resolved "https://registry.npmjs.org/zustand/-/zustand-3.4.2.tgz#22f0e0503a364672c6e3bb83399e69479bcea9b2" + integrity sha512-/v0RRbzi8NNyiXf7vw2eizPfJaTlTbXNM3fjQ6xF+qr5Xc0cF0ypaa0ARLOvyaKsGx/q2p5azVhfGxl4uHK0Ag== + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" From 4075c63675b7b9ec530d796ec8ecfa26108fc342 Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Sat, 24 Apr 2021 07:56:47 +0200 Subject: [PATCH 363/462] fix: optional git config for techdocs feedback Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- .changeset/ten-cups-relax.md | 5 +++++ .../src/reader/transformers/addGitFeedbackLink.ts | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/ten-cups-relax.md diff --git a/.changeset/ten-cups-relax.md b/.changeset/ten-cups-relax.md new file mode 100644 index 0000000000..9e32ad3856 --- /dev/null +++ b/.changeset/ten-cups-relax.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Make git config optional for techdocs feedback links diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts index d19d90228c..c74f06934d 100644 --- a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts @@ -35,20 +35,20 @@ export const addGitFeedbackLink = (configApi: any): Transformer => { const sourceURL = new URL(sourceAnchor.href); const githubHosts = configApi - .getConfigArray('integrations.github') - .map((integration: any) => integration.data.host); + .getOptionalConfigArray('integrations.github') + ?.map((integration: any) => integration.data.host); const gitlabHosts = configApi - .getConfigArray('integrations.gitlab') - .map((integration: any) => integration.data.host); + .getOptionalConfigArray('integrations.gitlab') + ?.map((integration: any) => integration.data.host); // don't show if can't identify edit link hostname as a gitlab/github hosting if ( - githubHosts.includes(sourceURL.hostname) || + githubHosts?.includes(sourceURL.hostname) || sourceURL.origin.includes('github') ) { gitHost = 'github'; } else if ( - gitlabHosts.includes(sourceURL.hostname) || + gitlabHosts?.includes(sourceURL.hostname) || sourceURL.origin.includes('gitlab') ) { gitHost = 'gitlab'; From b61b268fd00d8f49ff9e2042cacd0cac8d480482 Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Sat, 24 Apr 2021 15:41:29 +0200 Subject: [PATCH 364/462] Update tests Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- .../src/reader/transformers/addGitFeedbackLink.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts index 4c9ea04fe9..5d88aab62e 100644 --- a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts @@ -18,10 +18,10 @@ import { createTestShadowDom } from '../../test-utils'; import { addGitFeedbackLink } from './addGitFeedbackLink'; const configApi = { - getConfigArray: function getConfigArray(key: string) { + getOptionalConfigArray: function getOptionalConfigArray(key: string) { return key === 'integrations.github' ? [{ data: { host: 'self-hosted-git-hub-provider.com' } }] - : []; + : undefined; }, }; From b9abc32f4928742b250e77d8d9a830037027cac5 Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Wed, 28 Apr 2021 23:41:52 +0200 Subject: [PATCH 365/462] Use ScmIntegrationsApi Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- plugins/techdocs/package.json | 2 ++ plugins/techdocs/src/plugin.ts | 24 +++++++---------- .../src/reader/components/Reader.test.tsx | 11 ++++++++ .../techdocs/src/reader/components/Reader.tsx | 9 ++++--- .../reader/components/TechDocsPage.test.tsx | 11 ++++++++ .../transformers/addGitFeedbackLink.test.ts | 26 ++++++++++--------- .../reader/transformers/addGitFeedbackLink.ts | 19 +++++--------- 7 files changed, 59 insertions(+), 43 deletions(-) diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 632feac3c1..55e5dadb54 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -34,6 +34,8 @@ "@backstage/config": "^0.1.4", "@backstage/catalog-model": "^0.7.7", "@backstage/core": "^0.7.7", + "@backstage/integration": "^0.5.0", + "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/theme": "^0.2.6", "@backstage/errors": "^0.1.1", diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index 97dd6f2150..bbd0b77ba9 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -13,21 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import { configApiRef, @@ -39,6 +24,10 @@ import { discoveryApiRef, identityApiRef, } from '@backstage/core'; +import { + ScmIntegrationsApi, + scmIntegrationsApiRef, +} from '@backstage/integration-react'; import { techdocsApiRef, techdocsStorageApiRef } from './api'; import { TechDocsClient, TechDocsStorageClient } from './client'; @@ -60,6 +49,11 @@ export const rootCatalogDocsRouteRef = createRouteRef({ export const techdocsPlugin = createPlugin({ id: 'techdocs', apis: [ + createApiFactory({ + api: scmIntegrationsApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), + }), createApiFactory({ api: techdocsStorageApiRef, deps: { diff --git a/plugins/techdocs/src/reader/components/Reader.test.tsx b/plugins/techdocs/src/reader/components/Reader.test.tsx index b39134b0cd..fbdac95658 100644 --- a/plugins/techdocs/src/reader/components/Reader.test.tsx +++ b/plugins/techdocs/src/reader/components/Reader.test.tsx @@ -14,7 +14,12 @@ * limitations under the License. */ +import { ConfigReader } from '@backstage/config'; import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { + ScmIntegrationsApi, + scmIntegrationsApiRef, +} from '@backstage/integration-react'; import { wrapInTestApp } from '@backstage/test-utils'; import { act, render } from '@testing-library/react'; import React from 'react'; @@ -39,9 +44,15 @@ describe('<Reader />', () => { entityId: 'Component::backstage', }); + const scmIntegrationsApi: ScmIntegrationsApi = ScmIntegrationsApi.fromConfig( + new ConfigReader({ + integrations: {}, + }), + ); const techdocsStorageApi: Partial<TechDocsStorageApi> = {}; const apiRegistry = ApiRegistry.from([ + [scmIntegrationsApiRef, scmIntegrationsApi], [techdocsStorageApiRef, techdocsStorageApi], ]); diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index b16a566afa..82b5245cfa 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ import { EntityName } from '@backstage/catalog-model'; -import { configApiRef, useApi } from '@backstage/core'; +import { useApi } from '@backstage/core'; +import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { BackstageTheme } from '@backstage/theme'; import { useTheme } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; @@ -54,7 +55,7 @@ export const Reader = ({ entityId, onReady }: Props) => { const [loadedPath, setLoadedPath] = useState(''); const [atInitialLoad, setAtInitialLoad] = useState(true); const [newerDocsExist, setNewerDocsExist] = useState(false); - const configApi = useApi(configApiRef); + const scmIntegrationsApi = useApi(scmIntegrationsApiRef); const { value: isSynced, @@ -145,7 +146,7 @@ export const Reader = ({ entityId, onReady }: Props) => { rewriteDocLinks(), removeMkdocsHeader(), simplifyMkdocsFooter(), - addGitFeedbackLink(configApi), + addGitFeedbackLink(scmIntegrationsApi), injectCss({ css: ` body { @@ -327,7 +328,7 @@ export const Reader = ({ entityId, onReady }: Props) => { theme.palette.background.default, newerDocsExist, isSynced, - configApi, + scmIntegrationsApi, ]); // docLoadError not considered an error state if sync request is still ongoing diff --git a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx index 52ddd3794e..5b638ff668 100644 --- a/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsPage.test.tsx @@ -16,6 +16,11 @@ import React from 'react'; import { TechDocsPage } from './TechDocsPage'; import { render, act } from '@testing-library/react'; +import { ConfigReader } from '@backstage/config'; +import { + ScmIntegrationsApi, + scmIntegrationsApiRef, +} from '@backstage/integration-react'; import { wrapInTestApp } from '@backstage/test-utils'; import { ApiRegistry, ApiProvider } from '@backstage/core'; import { @@ -50,6 +55,11 @@ describe('<TechDocsPage />', () => { entityId: 'Component::backstage', }); + const scmIntegrationsApi: ScmIntegrationsApi = ScmIntegrationsApi.fromConfig( + new ConfigReader({ + integrations: {}, + }), + ); const techdocsApi: Partial<TechDocsApi> = { getEntityMetadata: () => Promise.resolve({ @@ -72,6 +82,7 @@ describe('<TechDocsPage />', () => { }; const apiRegistry = ApiRegistry.from([ + [scmIntegrationsApiRef, scmIntegrationsApi], [techdocsApiRef, techdocsApi], [techdocsStorageApiRef, techdocsStorageApi], ]); diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts index 5d88aab62e..1b53b0141e 100644 --- a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.test.ts @@ -14,16 +14,18 @@ * limitations under the License. */ +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; import { createTestShadowDom } from '../../test-utils'; import { addGitFeedbackLink } from './addGitFeedbackLink'; -const configApi = { - getOptionalConfigArray: function getOptionalConfigArray(key: string) { - return key === 'integrations.github' - ? [{ data: { host: 'self-hosted-git-hub-provider.com' } }] - : undefined; - }, -}; +const integrations = ScmIntegrations.fromConfig( + new ConfigReader({ + integrations: { + github: [{ host: 'self-hosted-git-hub-provider.com' }], + }, + }), +); describe('addGitFeedbackLink', () => { it('adds a feedback link when a Gitlab source edit link is available', () => { @@ -38,7 +40,7 @@ describe('addGitFeedbackLink', () => { </html> `, { - preTransformers: [addGitFeedbackLink(configApi)], + preTransformers: [addGitFeedbackLink(integrations)], postTransformers: [], }, ); @@ -63,7 +65,7 @@ describe('addGitFeedbackLink', () => { </html> `, { - preTransformers: [addGitFeedbackLink(configApi)], + preTransformers: [addGitFeedbackLink(integrations)], postTransformers: [], }, ); @@ -87,7 +89,7 @@ describe('addGitFeedbackLink', () => { </html> `, { - preTransformers: [addGitFeedbackLink(configApi)], + preTransformers: [addGitFeedbackLink(integrations)], postTransformers: [], }, ); @@ -107,7 +109,7 @@ describe('addGitFeedbackLink', () => { </html> `, { - preTransformers: [addGitFeedbackLink(configApi)], + preTransformers: [addGitFeedbackLink(integrations)], postTransformers: [], }, ); @@ -127,7 +129,7 @@ describe('addGitFeedbackLink', () => { </html> `, { - preTransformers: [addGitFeedbackLink(configApi)], + preTransformers: [addGitFeedbackLink(integrations)], postTransformers: [], }, ); diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts index c74f06934d..5d45946238 100644 --- a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts @@ -15,12 +15,15 @@ */ import type { Transformer } from './index'; +import { ScmIntegrationRegistry } from '@backstage/integration'; import FeedbackOutlinedIcon from '@material-ui/icons/FeedbackOutlined'; import React from 'react'; import ReactDOM from 'react-dom'; // requires repo -export const addGitFeedbackLink = (configApi: any): Transformer => { +export const addGitFeedbackLink = ( + scmIntegrationsApi: ScmIntegrationRegistry, +): Transformer => { return dom => { // attempting to use selectors that are more likely to be static as MkDocs updates over time const sourceAnchor = dom.querySelector( @@ -34,21 +37,13 @@ export const addGitFeedbackLink = (configApi: any): Transformer => { let gitHost = ''; const sourceURL = new URL(sourceAnchor.href); - const githubHosts = configApi - .getOptionalConfigArray('integrations.github') - ?.map((integration: any) => integration.data.host); - const gitlabHosts = configApi - .getOptionalConfigArray('integrations.gitlab') - ?.map((integration: any) => integration.data.host); + const integration = scmIntegrationsApi.byUrl(sourceURL); // don't show if can't identify edit link hostname as a gitlab/github hosting - if ( - githubHosts?.includes(sourceURL.hostname) || - sourceURL.origin.includes('github') - ) { + if (integration?.type === 'github' || sourceURL.origin.includes('github')) { gitHost = 'github'; } else if ( - gitlabHosts?.includes(sourceURL.hostname) || + integration?.type === 'gitlab' || sourceURL.origin.includes('gitlab') ) { gitHost = 'gitlab'; From 5f1f40a65c28c9d3d5168cd312964ce39c94864f Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Thu, 29 Apr 2021 10:33:26 +0200 Subject: [PATCH 366/462] Remove incorreect api factory creation Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- plugins/techdocs/src/plugin.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index bbd0b77ba9..202d49373c 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -49,11 +49,6 @@ export const rootCatalogDocsRouteRef = createRouteRef({ export const techdocsPlugin = createPlugin({ id: 'techdocs', apis: [ - createApiFactory({ - api: scmIntegrationsApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), - }), createApiFactory({ api: techdocsStorageApiRef, deps: { From 6381b7ec87b5f70f9dc1d3b7a618285a9cb43113 Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Thu, 29 Apr 2021 17:13:43 +0200 Subject: [PATCH 367/462] tsc Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- plugins/techdocs/src/plugin.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index 202d49373c..e25f245fb4 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -24,10 +24,6 @@ import { discoveryApiRef, identityApiRef, } from '@backstage/core'; -import { - ScmIntegrationsApi, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; import { techdocsApiRef, techdocsStorageApiRef } from './api'; import { TechDocsClient, TechDocsStorageClient } from './client'; From 4e6168da41070c0f58d2f7bf95ed7a433a6e5f52 Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Thu, 29 Apr 2021 16:16:24 +0100 Subject: [PATCH 368/462] Update public API docs Result of running `yarn build:api-reports`. Signed-off-by: Will Sewell <willsewell@monzo.com> --- packages/catalog-client/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index a17a6cdc10..4b489ff2e4 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -67,7 +67,7 @@ export class CatalogClient implements CatalogApi { // @public (undocumented) export type CatalogEntitiesRequest = { - filter?: Record<string, string | string[]> | undefined; + filter?: Record<string, string | string[]>[] | Record<string, string | string[]> | undefined; fields?: string[] | undefined; }; From 37dc8d6e9c5dcdbe1b08b358b862e89fb84cddda Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 29 Apr 2021 14:26:11 +0200 Subject: [PATCH 369/462] kubernetes-backend: Adds skipTLSVerify to ClusterDetails Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- plugins/kubernetes-backend/src/types/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 344e265426..d61c35e167 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -127,4 +127,5 @@ export interface ClusterDetails { url: string; authProvider: string; serviceAccountToken?: string | undefined; + skipTLSVerify?: boolean; } From e6715553b305fff00497be9e72c0aeb66c97d67a Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 29 Apr 2021 17:32:59 +0200 Subject: [PATCH 370/462] kubernetes-backend: Use imports directly from common Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- .../GoogleKubernetesAuthTranslator.ts | 3 ++- .../ServiceAccountKubernetesAuthTranslator.ts | 3 ++- .../src/kubernetes-auth-translator/types.ts | 3 ++- .../src/service/KubernetesFanOutHandler.ts | 2 +- .../src/service/KubernetesFetcher.ts | 8 +++++--- plugins/kubernetes-backend/src/service/router.ts | 2 +- plugins/kubernetes-backend/src/types/types.ts | 12 ++---------- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts index 0dd2a4bcc2..9dc4519966 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts @@ -15,7 +15,8 @@ */ import { KubernetesAuthTranslator } from './types'; -import { KubernetesRequestBody, ClusterDetails } from '../types/types'; +import { ClusterDetails } from '../types/types'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export class GoogleKubernetesAuthTranslator implements KubernetesAuthTranslator { diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/ServiceAccountKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/ServiceAccountKubernetesAuthTranslator.ts index 6433e41546..3610bd4d9f 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/ServiceAccountKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/ServiceAccountKubernetesAuthTranslator.ts @@ -15,7 +15,8 @@ */ import { KubernetesAuthTranslator } from './types'; -import { KubernetesRequestBody, ClusterDetails } from '../types/types'; +import { ClusterDetails } from '../types/types'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export class ServiceAccountKubernetesAuthTranslator implements KubernetesAuthTranslator { diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts index c01a57889c..7a04e230c6 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { KubernetesRequestBody, ClusterDetails } from '../types/types'; +import { ClusterDetails } from '../types/types'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; export interface KubernetesAuthTranslator { decorateClusterDetailsWithAuth( diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts index 6db6e2ad4a..75e2f8233c 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -20,9 +20,9 @@ import { CustomResource, KubernetesFetcher, KubernetesObjectTypes, - KubernetesRequestBody, KubernetesServiceLocator, } from '../types/types'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { KubernetesAuthTranslator } from '../kubernetes-auth-translator/types'; import { KubernetesAuthTranslatorGenerator } from '../kubernetes-auth-translator/KubernetesAuthTranslatorGenerator'; diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts index 10e5640bab..6958bd3387 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts @@ -32,15 +32,17 @@ import lodash, { Dictionary } from 'lodash'; import { Logger } from 'winston'; import { ClusterDetails, - FetchResponse, FetchResponseWrapper, - KubernetesErrorTypes, KubernetesFetcher, - KubernetesFetchError, KubernetesObjectTypes, ObjectFetchParams, CustomResource, } from '../types/types'; +import { + FetchResponse, + KubernetesFetchError, + KubernetesErrorTypes, +} from '@backstage/plugin-kubernetes-common'; import { KubernetesClientProvider } from './KubernetesClientProvider'; export interface Clients { diff --git a/plugins/kubernetes-backend/src/service/router.ts b/plugins/kubernetes-backend/src/service/router.ts index 189f2eb9c5..ab7bb5befa 100644 --- a/plugins/kubernetes-backend/src/service/router.ts +++ b/plugins/kubernetes-backend/src/service/router.ts @@ -23,11 +23,11 @@ import { MultiTenantServiceLocator } from '../service-locator/MultiTenantService import { ClusterDetails, KubernetesClustersSupplier, - KubernetesRequestBody, KubernetesServiceLocator, ServiceLocatorMethod, CustomResource, } from '../types/types'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { KubernetesClientProvider } from './KubernetesClientProvider'; import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index d61c35e167..0be0b447af 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -15,18 +15,10 @@ */ import type { - FetchResponse as FetchResponseCommon, - KubernetesFetchError as KubernetesFetchErrorCommon, + FetchResponse, + KubernetesFetchError, } from '@backstage/plugin-kubernetes-common'; -export type { - KubernetesErrorTypes, - KubernetesRequestBody, -} from '@backstage/plugin-kubernetes-common'; - -export type KubernetesFetchError = KubernetesFetchErrorCommon; -export type FetchResponse = FetchResponseCommon; - export type ClusterLocatorMethod = | ConfigClusterLocatorMethod | GKEClusterLocatorMethod; From 5550c49028c945bd7320d6bc1ac3bf26c2ec4155 Mon Sep 17 00:00:00 2001 From: Juan Lulkin <jmaiz@spotify.com> Date: Thu, 29 Apr 2021 17:33:42 +0200 Subject: [PATCH 371/462] plugin-kubernetes: Fixes common lib name Signed-off-by: Juan Lulkin <jmaiz@spotify.com> --- .changeset/silly-tables-build.md | 2 +- plugins/kubernetes/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/silly-tables-build.md b/.changeset/silly-tables-build.md index 3f7b3182dd..cb2fd73950 100644 --- a/.changeset/silly-tables-build.md +++ b/.changeset/silly-tables-build.md @@ -3,4 +3,4 @@ '@backstage/plugin-kubernetes-backend': patch --- -Adds @backstage/kubernetes-common library to share types between kubernetes frontend and backend. +Adds @backstage/plugin-kubernetes-common library to share types between kubernetes frontend and backend. diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index c808678922..d305ea4b4b 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -33,7 +33,7 @@ "@backstage/catalog-model": "^0.7.4", "@backstage/config": "^0.1.4", "@backstage/core": "^0.7.6", - "@backstage/kubernetes-common": "^0.1.0", + "@backstage/plugin-kubernetes-common": "^0.1.0", "@backstage/plugin-catalog-react": "^0.1.3", "@backstage/theme": "^0.2.6", "@kubernetes/client-node": "^0.14.0", From 7c8a0c1b09a2d8319a7d5daad63b80d6eb2bea3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 04:08:24 +0000 Subject: [PATCH 372/462] chore(deps-dev): bump @types/luxon from 1.26.0 to 1.26.5 Bumps [@types/luxon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/luxon) from 1.26.0 to 1.26.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/luxon) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e5bbc026c6..6d1cabbc22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6295,9 +6295,9 @@ integrity sha512-09sXZZVsB3Ib41U0fC+O1O+4UOZT1bl/e+/QubPxpqDWHNEchvx/DEb1KJMOwq6K3MTNzZFoNSzVdR++o1DVnw== "@types/luxon@^1.25.0": - version "1.26.0" - resolved "https://registry.npmjs.org/@types/luxon/-/luxon-1.26.0.tgz#8e783986370ad3bb9f885d93eb1a91caeecaed36" - integrity sha512-zYmLYGczqBaOFaFjR1giG1QCbGMlXWOJcYgH9Mnk0MGcZHq1aer3ZwGXX8vd9NOfai6mAI/mVU6jD9hK0Wys7Q== + version "1.26.5" + resolved "https://registry.npmjs.org/@types/luxon/-/luxon-1.26.5.tgz#843fb705e16e4d2a90847a351b799ea9d879859e" + integrity sha512-XeQxxRMyJi1znfzHw4CGDLyup/raj84SnjjkI2fDootZPGlB0yqtvlvEIAmzHDa5wiEI5JJevZOWxpcofsaV+A== "@types/markdown-to-jsx@^6.11.0": version "6.11.2" From 799c1d69cf4e009e603c215cf788553e7c927508 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 04:11:42 +0000 Subject: [PATCH 373/462] chore(deps-dev): bump start-server-and-test from 1.12.0 to 1.12.1 Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.12.0 to 1.12.1. - [Release notes](https://github.com/bahmutov/start-server-and-test/releases) - [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.12.0...v1.12.1) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index e5bbc026c6..0fd3ad76c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24297,9 +24297,9 @@ stacktrace-js@^2.0.0, stacktrace-js@^2.0.2: stacktrace-gps "^3.0.4" start-server-and-test@^1.10.11: - version "1.12.0" - resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.12.0.tgz#e836553c928a13026f79c740757d378b92bee8d6" - integrity sha512-y3M/PLUPkPBsgKoengMIMQeceT8uOnOc4bkdor/RSCK9Ih/j8z4WthSCrAboXLjgtJJWOporAiEQsnYox+THXg== + version "1.12.1" + resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.12.1.tgz#bf84eb5c5a4c8a98b93ed36519035b3f76179f0e" + integrity sha512-qGQ2HQiF2yDIfyaHsXkHfoE5UOl4zJUbJ/gx2xOkfX7iPMXW9qHmoFyaMfIDJVLNkxCK7RxSrvWEI9hNVKQluw== dependencies: bluebird "3.7.2" check-more-types "2.24.0" @@ -24307,7 +24307,7 @@ start-server-and-test@^1.10.11: execa "3.4.0" lazy-ass "1.6.0" ps-tree "1.2.0" - wait-on "5.2.1" + wait-on "5.3.0" start-server-webpack-plugin@^2.2.5: version "2.2.5" @@ -26420,14 +26420,14 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" -wait-on@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/wait-on/-/wait-on-5.2.1.tgz#05b66fcb4d7f5da01537f03e7cf96e8836422996" - integrity sha512-H2F986kNWMU9hKlI9l/ppO6tN8ZSJd35yBljMLa1/vjzWP++Qh6aXyt77/u7ySJFZQqBtQxnvm/xgG48AObXcw== +wait-on@5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/wait-on/-/wait-on-5.3.0.tgz#584e17d4b3fe7b46ac2b9f8e5e102c005c2776c7" + integrity sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg== dependencies: axios "^0.21.1" joi "^17.3.0" - lodash "^4.17.20" + lodash "^4.17.21" minimist "^1.2.5" rxjs "^6.6.3" From d8d22dd9332ba4cbfd413e199526580a398c2418 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 04:14:12 +0000 Subject: [PATCH 374/462] chore(deps-dev): bump @types/passport-google-oauth20 from 2.0.3 to 2.0.7 Bumps [@types/passport-google-oauth20](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/passport-google-oauth20) from 2.0.3 to 2.0.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/passport-google-oauth20) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e5bbc026c6..3723040450 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6453,9 +6453,9 @@ "@types/passport-oauth2" "*" "@types/passport-google-oauth20@^2.0.3": - version "2.0.3" - resolved "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.3.tgz#f554ff6d39f395acff3f1d762e54462194dac8da" - integrity sha512-6EUEGzEg4acwowvgR/yVZIj8S2Kkwc6JmlY2/wnM1wJHNz20o7s1TIGrxnah8ymLgJasYDpy95P3TMMqlmetPw== + version "2.0.7" + resolved "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.7.tgz#0d97b7a886a0c0d2158682145cd949b29f8efe86" + integrity sha512-0HPVSqDmOWk5fRLb+bqGal+6iWsERiEco/Mli77yy5NEy22IfkoRoqZTSZ8UtXDWY9DCZlpS1Jqq56iWx2torw== dependencies: "@types/express" "*" "@types/passport" "*" From 3816ee1a91aee34a07ad9118527827213e05e69e Mon Sep 17 00:00:00 2001 From: Thomas Viaud <t.viaud@elsevier.com> Date: Fri, 30 Apr 2021 11:12:19 +0100 Subject: [PATCH 375/462] feat(scaffolder-backend,githubPR): Fixing Github URL submitted to get credentials Signed-off-by: Thomas Viaud <t.viaud@elsevier.com> --- .../scaffolder/actions/builtin/publish/githubPullRequest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts index e2e4f17efb..18aef2b54c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts @@ -29,7 +29,7 @@ import { InputError, CustomErrorBase } from '@backstage/errors'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; import globby from 'globby'; -class GithubResponseError extends CustomErrorBase {} +class GithubResponseError extends CustomErrorBase { } type CreatePullRequestResponse = { data: { html_url: string }; @@ -87,7 +87,7 @@ export const defaultClientFactory = async ({ } const { token } = await credentialsProvider.getCredentials({ - url: `${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, + url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, }); if (!token) { From 69eefb5aeb8dd3bb08a2827fb384875d9d05e86a Mon Sep 17 00:00:00 2001 From: Thomas Viaud <t.viaud@elsevier.com> Date: Fri, 30 Apr 2021 11:13:38 +0100 Subject: [PATCH 376/462] feat(scaffolder-backend,doc): Adding Documentation for plugin Signed-off-by: Thomas Viaud <t.viaud@elsevier.com> --- .changeset/old-horses-brake.md | 6 ++++++ plugins/scaffolder-backend/README.md | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 .changeset/old-horses-brake.md diff --git a/.changeset/old-horses-brake.md b/.changeset/old-horses-brake.md new file mode 100644 index 0000000000..ea41019b23 --- /dev/null +++ b/.changeset/old-horses-brake.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fix GithubPR built-in action `credentialsProvider.getCredentials` URL. +Adding Documentation for GitHub PR built-in action. diff --git a/plugins/scaffolder-backend/README.md b/plugins/scaffolder-backend/README.md index 185938b006..2e8cc41ace 100644 --- a/plugins/scaffolder-backend/README.md +++ b/plugins/scaffolder-backend/README.md @@ -1,7 +1,18 @@ -# Title +# Scaffolder Backend Welcome to the scaffolder plugin! -## Sub-section 1 +## Jobs +Documentation for `Jobs` here +## Stages +Documentation for `Stages` here +## Tasks +Documentation for `Tasks` here -## Sub-section 2 +## Actions +### Built-in: +* #### GitHub Pull Request + * Minimum permissions required for GitHub App for creating a Pull Request with the built-in action: + - Read and Write permissions for `Contents`. + - Read and write permissions for `Pull Requests` and `Issues`. + - Read permissions on `Metadata`. From 900cb4c39d440e90eab2492d4df5eeb55ec9353c Mon Sep 17 00:00:00 2001 From: Thomas Viaud <t.viaud@elsevier.com> Date: Fri, 30 Apr 2021 11:28:59 +0100 Subject: [PATCH 377/462] Run Prettier on scaffolder-backend files Signed-off-by: Thomas Viaud <t.viaud@elsevier.com> --- plugins/scaffolder-backend/README.md | 17 ++++++++++++----- .../builtin/publish/githubPullRequest.ts | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder-backend/README.md b/plugins/scaffolder-backend/README.md index 2e8cc41ace..304d43a750 100644 --- a/plugins/scaffolder-backend/README.md +++ b/plugins/scaffolder-backend/README.md @@ -3,16 +3,23 @@ Welcome to the scaffolder plugin! ## Jobs + Documentation for `Jobs` here + ## Stages + Documentation for `Stages` here + ## Tasks + Documentation for `Tasks` here ## Actions + ### Built-in: -* #### GitHub Pull Request - * Minimum permissions required for GitHub App for creating a Pull Request with the built-in action: - - Read and Write permissions for `Contents`. - - Read and write permissions for `Pull Requests` and `Issues`. - - Read permissions on `Metadata`. + +- #### GitHub Pull Request + - Minimum permissions required for GitHub App for creating a Pull Request with the built-in action: + - Read and Write permissions for `Contents`. + - Read and write permissions for `Pull Requests` and `Issues`. + - Read permissions on `Metadata`. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts index 18aef2b54c..8f44fc3e19 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts @@ -87,7 +87,9 @@ export const defaultClientFactory = async ({ } const { token } = await credentialsProvider.getCredentials({ - url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, + url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent( + repo, + )}`, }); if (!token) { From 939b9d0fffdd69fb2cc976d93ac2d4baec15f0cf Mon Sep 17 00:00:00 2001 From: Thomas Viaud <t.viaud@elsevier.com> Date: Fri, 30 Apr 2021 11:38:11 +0100 Subject: [PATCH 378/462] Fixing Prettier Warning Signed-off-by: Thomas Viaud <t.viaud@elsevier.com> --- .../src/scaffolder/actions/builtin/publish/githubPullRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts index 8f44fc3e19..5dd4046811 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts @@ -29,7 +29,7 @@ import { InputError, CustomErrorBase } from '@backstage/errors'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; import globby from 'globby'; -class GithubResponseError extends CustomErrorBase { } +class GithubResponseError extends CustomErrorBase {} type CreatePullRequestResponse = { data: { html_url: string }; From a1351acc87647697b59604d7f34832af2c3140d8 Mon Sep 17 00:00:00 2001 From: Raghunandan <soapraj@gmail.com> Date: Fri, 30 Apr 2021 13:46:35 +0200 Subject: [PATCH 379/462] awsS3 option endpoint -> s3ForcePathStyle Signed-off-by: Raghunandan <soapraj@gmail.com> --- plugins/techdocs-backend/config.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-backend/config.d.ts b/plugins/techdocs-backend/config.d.ts index 57dbb5108e..6a76172638 100644 --- a/plugins/techdocs-backend/config.d.ts +++ b/plugins/techdocs-backend/config.d.ts @@ -96,7 +96,7 @@ export interface Config { * This allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used to host tech docs. * @visibility backend */ - endpoint?: string; + s3ForcePathStyle?: boolean; }; } | { From 382f8f8f84db1e3e95ba448a5f0c3a8cd6748c53 Mon Sep 17 00:00:00 2001 From: Simon Knittel <hallo@simonknittel.de> Date: Fri, 30 Apr 2021 15:19:25 +0200 Subject: [PATCH 380/462] Add support for non-organization accounts in GitHub Discovery Signed-off-by: Simon Knittel <hallo@simonknittel.de> --- .../src/ingestion/processors/github/github.ts | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/plugins/catalog-backend/src/ingestion/processors/github/github.ts b/plugins/catalog-backend/src/ingestion/processors/github/github.ts index e07ea8917b..0b7f3d831d 100644 --- a/plugins/catalog-backend/src/ingestion/processors/github/github.ts +++ b/plugins/catalog-backend/src/ingestion/processors/github/github.ts @@ -21,6 +21,7 @@ import { graphql } from '@octokit/graphql'; export type QueryResponse = { organization: Organization; + user: User; }; export type Organization = { @@ -41,6 +42,7 @@ export type User = { avatarUrl?: string; email?: string; name?: string; + repositories?: Connection<Repository>; }; export type Team = { @@ -243,13 +245,27 @@ export async function getOrganizationRepositories( } } } + user(login: $org) { + name + repositories(first: 100, after: $cursor) { + nodes { + name + url + isArchived + } + pageInfo { + hasNextPage + endCursor + } + } + } } `; const repositories = await queryWithPaging( client, query, - r => r.organization?.repositories, + r => r.organization?.repositories || r.user?.repositories, x => x, { org }, ); @@ -327,10 +343,16 @@ export async function queryWithPaging< let cursor: string | undefined = undefined; for (let j = 0; j < 1000 /* just for sanity */; ++j) { - const response: Response = await client(query, { - ...variables, - cursor, - }); + let response: Response; + + try { + response = await client(query, { + ...variables, + cursor, + }); + } catch (e) { + response = e.data; + } const conn = connection(response); if (!conn) { From 80888659bff5549b3f6d7ec0381a33c6c6ee92ad Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Fri, 30 Apr 2021 15:37:55 +0200 Subject: [PATCH 381/462] chore: Align react-hook-form version across project Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .changeset/fuzzy-dancers-complain.md | 6 ++++++ packages/core/package.json | 2 +- plugins/register-component/package.json | 2 +- yarn.lock | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 .changeset/fuzzy-dancers-complain.md diff --git a/.changeset/fuzzy-dancers-complain.md b/.changeset/fuzzy-dancers-complain.md new file mode 100644 index 0000000000..a23e6bc3df --- /dev/null +++ b/.changeset/fuzzy-dancers-complain.md @@ -0,0 +1,6 @@ +--- +'@backstage/core': patch +'@backstage/plugin-catalog-import': patch +--- + +Bump react-hook-form version to be the same for the entire project. diff --git a/packages/core/package.json b/packages/core/package.json index 59391e122a..75f5f67ae1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -57,7 +57,7 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "react-helmet": "6.1.0", - "react-hook-form": "^6.6.0", + "react-hook-form": "^6.15.4", "react-markdown": "^5.0.2", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index 38d1e3202e..bd51a7db0b 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -39,7 +39,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-hook-form": "^6.6.0", + "react-hook-form": "^6.15.4", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", "react-use": "^15.3.3" diff --git a/yarn.lock b/yarn.lock index f24ce68740..6e9fe60885 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22074,7 +22074,7 @@ react-helmet@6.1.0: react-fast-compare "^3.1.1" react-side-effect "^2.1.0" -react-hook-form@^6.15.4, react-hook-form@^6.6.0: +react-hook-form@^6.15.4: version "6.15.4" resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-6.15.4.tgz#328003e1ccc096cd158899ffe7e3b33735a9b024" integrity sha512-K+Sw33DtTMengs8OdqFJI3glzNl1wBzSefD/ksQw/hJf9CnOHQAU6qy82eOrh0IRNt2G53sjr7qnnw1JDjvx1w== From c1238cc022fdfe9467ef23833770629cd0c65846 Mon Sep 17 00:00:00 2001 From: Simon Knittel <hallo@simonknittel.de> Date: Sat, 1 May 2021 11:07:17 +0200 Subject: [PATCH 382/462] Use different query for GitHub Discovery depending on the repository owner Signed-off-by: Simon Knittel <hallo@simonknittel.de> --- .../src/ingestion/processors/github/github.ts | 97 +++++++++++++------ 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/plugins/catalog-backend/src/ingestion/processors/github/github.ts b/plugins/catalog-backend/src/ingestion/processors/github/github.ts index 0b7f3d831d..f5230ce044 100644 --- a/plugins/catalog-backend/src/ingestion/processors/github/github.ts +++ b/plugins/catalog-backend/src/ingestion/processors/github/github.ts @@ -66,6 +66,14 @@ export type Connection<T> = { nodes: T[]; }; +export type RepositoryOwnerType = { + __typename: 'Organization' | 'User'; +}; + +export type RepositoryOwnerResponse = { + repositoryOwner: RepositoryOwnerType | null; +}; + /** * Gets all the users out of a GitHub organization. * @@ -229,38 +237,49 @@ export async function getOrganizationRepositories( client: typeof graphql, org: string, ): Promise<{ repositories: Repository[] }> { - const query = ` - query repositories($org: String!, $cursor: String) { - organization(login: $org) { - name - repositories(first: 100, after: $cursor) { - nodes { - name - url - isArchived - } - pageInfo { - hasNextPage - endCursor - } - } - } - user(login: $org) { - name - repositories(first: 100, after: $cursor) { - nodes { - name - url - isArchived - } - pageInfo { - hasNextPage - endCursor - } - } - } + let query = ``; + + switch (await getLoginType(client, org)) { + case 'Organization': + query = ` + query repositories($org: String!, $cursor: String) { + organization(login: $org) { + name + repositories(first: 100, after: $cursor) { + nodes { + name + url + isArchived + } + pageInfo { + hasNextPage + endCursor + } + } + } + }`; + break; + + default: + query = ` + query repositories($org: String!, $cursor: String) { + user(login: $org) { + name + repositories(first: 100, after: $cursor) { + nodes { + name + url + isArchived + } + pageInfo { + hasNextPage + endCursor + } + } + } + }`; + break; } - `; const repositories = await queryWithPaging( client, @@ -372,3 +391,19 @@ export async function queryWithPaging< return result; } + +export async function getLoginType(client: typeof graphql, login: string) { + const query = ` + query repositoryOwner($login: String!) { + repositoryOwner(login: $login) { + __typename + } + }`; + + const response: RepositoryOwnerResponse = await client(query, { login }); + if (response.repositoryOwner === null) { + throw new Error(`Unknown repository owner for "${login}"`); + } + + return response.repositoryOwner.__typename; +} From 650af9bc9543fda44cffa9f634d09ab11b419c0d Mon Sep 17 00:00:00 2001 From: David Tuite <david@roadie.io> Date: Sat, 1 May 2021 11:14:34 +0100 Subject: [PATCH 383/462] Move processor error handling to configuration docs Signed-off-by: David Tuite <david@roadie.io> --- docs/features/software-catalog/configuration.md | 7 +++++++ docs/integrations/github/discovery.md | 10 ---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 1afdff418a..0f5dd9a765 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -37,6 +37,13 @@ The locations added through static configuration cannot be removed through the catalog locations API. To remove these locations, you must remove them from the configuration. +Syntax errors or other types of errors present in `catalog-info.yaml` files will +be logged for investigation. Errors do not cause processing to abort. + +When multiple `catalog-info.yaml` files with the same `metadata.name` property +are discovered, one will be processed and all others will be skipped. This +action is logged for further investigation. + ### Integration Processors Integrations may simply provide a mechanism to handle `url` location type for an diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 8d2ca8fb32..a578d0893d 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -52,13 +52,3 @@ Backstage to use the [github-apps plugin](../../plugins/github-apps.md). This is true for any method of adding GitHub entities to the catalog, but especially easy to hit with automatic discovery. - -## Error handling - -Syntax errors or other types of errors present in `catalog-info.yaml` files will -be logged for investigation and the importer will continue. Errors do not cause -the process to fail. - -When multiple `catalog-info.yaml` files with the same `metadata.name` property -are discovered, one will be skipped and the process will continue. This action -will be logged for later investigation. From 227439a7237aa084c82fb2b7a6cfd1aa528675fe Mon Sep 17 00:00:00 2001 From: Simon Knittel <hallo@simonknittel.de> Date: Sat, 1 May 2021 13:40:11 +0200 Subject: [PATCH 384/462] Switch back to a single query again; Update tests and add changeset Signed-off-by: Simon Knittel <hallo@simonknittel.de> --- .changeset/stupid-feet-reply.md | 5 + .../processors/github/github.test.ts | 2 +- .../src/ingestion/processors/github/github.ts | 98 ++++--------------- 3 files changed, 27 insertions(+), 78 deletions(-) create mode 100644 .changeset/stupid-feet-reply.md diff --git a/.changeset/stupid-feet-reply.md b/.changeset/stupid-feet-reply.md new file mode 100644 index 0000000000..d7213b1bdc --- /dev/null +++ b/.changeset/stupid-feet-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Add support for non-organization accounts in GitHub Discovery diff --git a/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts b/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts index 15280b96b8..88bddc93fb 100644 --- a/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts @@ -156,7 +156,7 @@ describe('github', () => { describe('getOrganizationRepositories', () => { it('read repositories', async () => { const input: QueryResponse = { - organization: { + repositoryOwner: { repositories: { nodes: [ { diff --git a/plugins/catalog-backend/src/ingestion/processors/github/github.ts b/plugins/catalog-backend/src/ingestion/processors/github/github.ts index f5230ce044..f6cfcb8901 100644 --- a/plugins/catalog-backend/src/ingestion/processors/github/github.ts +++ b/plugins/catalog-backend/src/ingestion/processors/github/github.ts @@ -20,8 +20,8 @@ import { graphql } from '@octokit/graphql'; // Graphql types export type QueryResponse = { - organization: Organization; - user: User; + organization?: Organization; + repositoryOwner?: Organization | User; }; export type Organization = { @@ -66,14 +66,6 @@ export type Connection<T> = { nodes: T[]; }; -export type RepositoryOwnerType = { - __typename: 'Organization' | 'User'; -}; - -export type RepositoryOwnerResponse = { - repositoryOwner: RepositoryOwnerType | null; -}; - /** * Gets all the users out of a GitHub organization. * @@ -237,54 +229,28 @@ export async function getOrganizationRepositories( client: typeof graphql, org: string, ): Promise<{ repositories: Repository[] }> { - let query = ``; - - switch (await getLoginType(client, org)) { - case 'Organization': - query = ` - query repositories($org: String!, $cursor: String) { - organization(login: $org) { + const query = ` + query repositories($org: String!, $cursor: String) { + repositoryOwner(login: $org) { + login + repositories(first: 100, after: $cursor) { + nodes { name - repositories(first: 100, after: $cursor) { - nodes { - name - url - isArchived - } - pageInfo { - hasNextPage - endCursor - } - } + url + isArchived } - }`; - break; - - default: - query = ` - query repositories($org: String!, $cursor: String) { - user(login: $org) { - name - repositories(first: 100, after: $cursor) { - nodes { - name - url - isArchived - } - pageInfo { - hasNextPage - endCursor - } - } + pageInfo { + hasNextPage + endCursor } - }`; - break; - } + } + } + }`; const repositories = await queryWithPaging( client, query, - r => r.organization?.repositories || r.user?.repositories, + r => r.repositoryOwner?.repositories, x => x, { org }, ); @@ -362,16 +328,10 @@ export async function queryWithPaging< let cursor: string | undefined = undefined; for (let j = 0; j < 1000 /* just for sanity */; ++j) { - let response: Response; - - try { - response = await client(query, { - ...variables, - cursor, - }); - } catch (e) { - response = e.data; - } + const response: Response = await client(query, { + ...variables, + cursor, + }); const conn = connection(response); if (!conn) { @@ -391,19 +351,3 @@ export async function queryWithPaging< return result; } - -export async function getLoginType(client: typeof graphql, login: string) { - const query = ` - query repositoryOwner($login: String!) { - repositoryOwner(login: $login) { - __typename - } - }`; - - const response: RepositoryOwnerResponse = await client(query, { login }); - if (response.repositoryOwner === null) { - throw new Error(`Unknown repository owner for "${login}"`); - } - - return response.repositoryOwner.__typename; -} From 05687486777479e13dcfb636336498e086d78be2 Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Sat, 1 May 2021 08:26:22 -0400 Subject: [PATCH 385/462] Add custom logo instructions Signed-off-by: Adam Harvey <adaharve@cisco.com> --- docs/getting-started/app-custom-theme.md | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index 181f541929..4dbc6bfa48 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -135,3 +135,31 @@ const themeOptions = createThemeOptions({ }, }); ``` + +## Custom Logo + +In addition to a custom theme, you can also customize the logo displayed at the +far top left of the site. + +In your frontend app, locate `src/components/Root/` folder. You'll find two +components: + +- `LogoFull.tsx` - A larger logo used when the Sidebar navigation is opened. +- `LogoIcon.tsx` - A smaller logo used when the sidebar navigation is closed. + +To replace the images, you can simply replace the relevant code in those +components with raw SVG definitions. + +You can also use another web image format such as PNG by importing it. To do +this, place your new image into a new subdirectory such as +`src/components/Root/logo/my-company-logo.png`, and then add this code: + +```jsx +import MyCustomLogoFull from './logo/my-company-logo.png'; + +//... + +const LogoFull = () => { + return <img src={MyCustomLogoFull} />; +}; +``` From 550a5ff0b65173d6e150e1580c6ab259143d825b Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Sat, 1 May 2021 08:26:44 -0400 Subject: [PATCH 386/462] Reword personalized sentence Signed-off-by: Adam Harvey <adaharve@cisco.com> --- docs/features/software-catalog/configuration.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 1afdff418a..b184bc85de 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -111,8 +111,7 @@ catalog: > deleting entities will not work in this mode.** A common use case for this configuration is when organizations have a remote -source that should be mirrored into backstage. If we want backstage to be a -mirror of this remote source we cannot allow users to also register entities -with e.g. +source that should be mirrored into Backstage. To make Backstage a mirror of +this remote source, users cannot also register new entities with e.g. the [catalog-import](https://github.com/backstage/backstage/tree/master/plugins/catalog-import) plugin. From 2dea4154dfad82622021ca6b88b066d3154d91e2 Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Sat, 1 May 2021 08:27:03 -0400 Subject: [PATCH 387/462] Proper caps of Backstage Signed-off-by: Adam Harvey <adaharve@cisco.com> --- docs/features/software-templates/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-templates/installation.md b/docs/features/software-templates/installation.md index 96eea3c750..c682ca6ddf 100644 --- a/docs/features/software-templates/installation.md +++ b/docs/features/software-templates/installation.md @@ -262,6 +262,6 @@ library. By default it will use the [spotify/backstage-cookiecutter](https://github.com/backstage/backstage/blob/37e35b910afc7d1270855aed0ec4718aba366c91/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile) docker image. -If you are running backstage from a Docker container and you want to avoid +If you are running Backstage from a Docker container and you want to avoid calling a container inside a container, you can set up Cookiecutter in your own image, this will use the local installation instead. From 6f3d98450fcad40d6703a962be67a4a745f6a29d Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Sat, 1 May 2021 08:28:34 -0400 Subject: [PATCH 388/462] Clarifications on usage Signed-off-by: Adam Harvey <adaharve@cisco.com> --- microsite/README.md | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/microsite/README.md b/microsite/README.md index 9589def3e3..285622f1f8 100644 --- a/microsite/README.md +++ b/microsite/README.md @@ -1,3 +1,9 @@ +# Backstage Documentation + +This folder holds the service and configuration that runs Backstage's documentation hosted at https://backstage.io. + +It pulls content in from the [root `/docs`](../docs/) folder and builds it into the resulting HTML web site. + This website was created with [Docusaurus](https://docusaurus.io/). # What's In This Document @@ -10,6 +16,8 @@ This website was created with [Docusaurus](https://docusaurus.io/). # Getting Started +Testing the web site locally is a great way to see what final website will look like after publishing, and is ideal for testing more complex changes, large updates to navigation, or complex page designs that may include special alignment, which may not otherwise be validated through continuous integration. + ## Installation ``` @@ -22,7 +30,7 @@ $ yarn install $ yarn start ``` -This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. +This command starts a local development server and opens up a browser window. Most content changes made to the `docs/` root folder are reflected live without having to restart the server. ## Build @@ -57,9 +65,9 @@ my-docusaurus/ siteConfig.js ``` -# Editing Content +## Editing Content -## Editing an existing docs page +### Editing an existing docs page Edit docs by navigating to `docs/` and editing the corresponding document: @@ -76,7 +84,7 @@ Edit me... For more information about docs, click [here](https://docusaurus.io/docs/en/navigation) -## Editing an existing blog post +### Editing an existing blog post Edit blog posts by navigating to `website/blog` and editing the corresponding post: @@ -93,9 +101,9 @@ Edit me... For more information about blog posts, click [here](https://docusaurus.io/docs/en/adding-blog) -# Adding Content +## Adding Content -## Adding a new docs page to an existing sidebar +### Adding a new docs page to an existing sidebar 1. Create the doc as a new markdown file in `/docs`, example `docs/newly-created-doc.md`: @@ -126,7 +134,7 @@ My new content here.. For more information about adding new docs, click [here](https://docusaurus.io/docs/en/navigation) -## Adding a new blog post +### Adding a new blog post 1. Make sure there is a header link to your blog in `website/siteConfig.js`: @@ -157,7 +165,7 @@ Lorem Ipsum... For more information about blog posts, click [here](https://docusaurus.io/docs/en/adding-blog) -## Adding items to your site's top navigation bar +### Adding items to your site's top navigation bar 1. Add links to docs, custom pages or external links by editing the headerLinks field of `website/siteConfig.js`: @@ -181,7 +189,7 @@ For more information about blog posts, click [here](https://docusaurus.io/docs/e For more information about the navigation bar, click [here](https://docusaurus.io/docs/en/navigation) -## Adding custom pages +### Adding custom pages 1. Docusaurus uses React components to build pages. The components are saved as .js files in `website/pages/en`: 1. If you want your page to show up in your navigation header, you will need to update `website/siteConfig.js` to add to the `headerLinks` element: @@ -199,11 +207,11 @@ For more information about the navigation bar, click [here](https://docusaurus.i } ``` -For more information about custom pages, click [here](https://docusaurus.io/docs/en/custom-pages). +Learn more about [Docusaurus custom pages](https://docusaurus.io/docs/en/custom-pages). -# Full Documentation +## Full Documentation -Full documentation can be found on the [website](https://docusaurus.io/). +Full documentation can be found on the [Docusaurus website](https://docusaurus.io/). ## Additional notes From b99ac3f6e1d29bc75d26a16edb2851784802109e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Sun, 2 May 2021 22:13:05 +0200 Subject: [PATCH 389/462] Minor composability etc docs changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- docs/features/kubernetes/installation.md | 60 ++++++--------- .../features/software-catalog/installation.md | 2 + .../software-templates/installation.md | 2 + docs/features/techdocs/getting-started.md | 4 +- ...integrating-plugin-into-service-catalog.md | 2 +- docs/tutorials/switching-sqlite-postgres.md | 5 +- ...0-04-30-how-to-quickly-set-up-backstage.md | 14 +--- packages/backend-common/README.md | 2 + packages/backend/src/plugins/kubernetes.ts | 3 +- packages/cli/README.md | 4 +- packages/core-api/README.md | 4 +- packages/core/README.md | 4 +- packages/dev-utils/README.md | 4 +- packages/test-utils/README.md | 4 +- packages/theme/README.md | 4 +- plugins/api-docs/README.md | 10 +-- plugins/app-backend/README.md | 4 +- plugins/bitrise/README.md | 8 +- plugins/catalog-import/README.md | 4 +- plugins/circleci/README.md | 34 +++++---- plugins/cost-insights/README.md | 2 + .../contrib/aws-cost-explorer-api.md | 2 + plugins/fossa/README.md | 4 +- plugins/github-actions/README.md | 27 ++++--- plugins/github-deployments/README.md | 4 +- plugins/graphiql/README.md | 1 + plugins/jenkins/README.md | 40 +++++----- plugins/kafka-backend/README.md | 9 ++- plugins/kafka/README.md | 38 ++++------ plugins/lighthouse/README.md | 73 ++++++++----------- .../lighthouse/src/components/Intro/index.tsx | 3 +- plugins/pagerduty/README.md | 2 + plugins/register-component/README.md | 1 + plugins/rollbar/README.md | 12 ++- plugins/sentry/README.md | 4 +- plugins/sonarqube/README.md | 3 +- plugins/splunk-on-call/README.md | 2 + plugins/tech-radar/README.md | 5 +- .../docs/code/code-sample.md | 26 +++---- 39 files changed, 216 insertions(+), 220 deletions(-) diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 10968b427c..36bb724be6 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -8,44 +8,36 @@ The Kubernetes feature is a plugin to Backstage, and it is exposed as a tab when viewing entities in the software catalog. If you haven't setup Backstage already, read the -[Getting Started](../../getting-started/index.md). +[Getting Started](../../getting-started/index.md) guide. ## Adding the Kubernetes frontend plugin -The first step is to add the frontend Kubernetes plugin to your Backstage -application. Navigate to your new Backstage application directory. And then to +The first step is to add the Kubernetes frontend plugin to your Backstage +application. Navigate to your new Backstage application directory, and then to your `packages/app` directory, and install the `@backstage/plugin-kubernetes` package. ```bash -cd my-backstage-app/ +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-kubernetes ``` Once the package has been installed, you need to import the plugin in your app -by adding the "Kubernetes" tab to the catalog entity page. In -`packages/app/src/components/catalog/EntityPage.tsx`, you'll add a router to get -to the tab, and add the tab itself. - -`EntityPage.tsx`: +by adding the "Kubernetes" tab to the respective catalog pages. ```tsx -import { Router as KubernetesRouter } from '@backstage/plugin-kubernetes'; +// In packages/app/src/components/catalog/EntityPage.tsx +import { EntityKubernetesContent } from '@backstage/plugin-kubernetes'; -// ... - -const ServiceEntityPage = ({ entity }: { entity: Entity }) => ( - <EntityPageLayout> - // ... - <EntityPageLayout.Content - path="/kubernetes/*" - title="Kubernetes" - element={<KubernetesRouter entity={entity} />} - /> - // ... - </EntityPageLayout> -); +// You can add the tab to any number of pages, the service page is shown as an +// example here +const serviceEntityPage = ( + <EntityLayout> + {/* other tabs... */} + <EntityLayout.Route path="/kubernetes" title="Kubernetes"> + <EntityKubernetesContent /> + </EntityLayout.Route> ``` That's it! But now, we need the Kubernetes Backend plugin for the frontend to @@ -57,17 +49,16 @@ Navigate to `packages/backend` of your Backstage app, and install the `@backstage/plugin-kubernetes-backend` package. ```bash -cd my-backstage-app/ +# From your Backstage root directory cd packages/backend yarn add @backstage/plugin-kubernetes-backend ``` Create a file called `kubernetes.ts` inside `packages/backend/src/plugins/` and -add the following - -`kubernetes.ts`: +add the following: ```typescript +// In packages/backend/src/plugins/kubernetes.ts import { createRouter } from '@backstage/plugin-kubernetes-backend'; import { PluginEnvironment } from '../types'; @@ -83,18 +74,15 @@ And import the plugin to `packages/backend/src/index.ts`. There are three lines of code you'll need to add, and they should be added near similar code in your existing Backstage backend. -`index.ts`: - ```typescript +// In packages/backend/src/index.ts import kubernetes from './plugins/kubernetes'; - // ... - -const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes')); - -// ... - -apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv)); +async function main() { + // ... + const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes')); + // ... + apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv)); ``` That's it! The Kubernetes frontend and backend have now been added to your diff --git a/docs/features/software-catalog/installation.md b/docs/features/software-catalog/installation.md index df473f886f..0b622fb093 100644 --- a/docs/features/software-catalog/installation.md +++ b/docs/features/software-catalog/installation.md @@ -18,6 +18,7 @@ The catalog frontend plugin should be installed in your `app` package, which is created as a part of `@backstage/create-app`. To install the package, run: ```bash +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-catalog ``` @@ -103,6 +104,7 @@ The catalog backend should be installed in your `backend` package, which is created as a part of `@backstage/create-app`. To install the package, run: ```bash +# From your Backstage root directory cd packages/backend yarn add @backstage/plugin-catalog-backend ``` diff --git a/docs/features/software-templates/installation.md b/docs/features/software-templates/installation.md index c682ca6ddf..5acaf0e499 100644 --- a/docs/features/software-templates/installation.md +++ b/docs/features/software-templates/installation.md @@ -20,6 +20,7 @@ The scaffolder frontend plugin should be installed in your `app` package, which is created as a part of `@backstage/create-app`. To install the package, run: ```bash +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-scaffolder ``` @@ -57,6 +58,7 @@ The scaffolder backend should be installed in your `backend` package, which is created as a part of `@backstage/create-app`. To install the package, run: ```bash +# From your Backstage root directory cd packages/backend yarn add @backstage/plugin-scaffolder-backend ``` diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index 223b276d68..520db2245c 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -22,7 +22,7 @@ Navigate to your new Backstage application directory. And then to your `packages/app` directory, and install the `@backstage/plugin-techdocs` package. ```bash -cd my-backstage-app/ +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-techdocs ``` @@ -54,7 +54,7 @@ Navigate to `packages/backend` of your Backstage app, and install the `@backstage/plugin-techdocs-backend` package. ```bash -cd my-backstage-app/ +# From your Backstage root directory cd packages/backend yarn add @backstage/plugin-techdocs-backend ``` diff --git a/docs/plugins/integrating-plugin-into-service-catalog.md b/docs/plugins/integrating-plugin-into-service-catalog.md index 01de779635..047b6f14e6 100644 --- a/docs/plugins/integrating-plugin-into-service-catalog.md +++ b/docs/plugins/integrating-plugin-into-service-catalog.md @@ -1,7 +1,7 @@ --- id: integrating-plugin-into-service-catalog title: Integrate into the Service Catalog -description: Documentation on How to integrate plugin into service catalog +description: How to integrate a plugin into service catalog --- > This is an advanced use case and currently is an experimental feature. Expect diff --git a/docs/tutorials/switching-sqlite-postgres.md b/docs/tutorials/switching-sqlite-postgres.md index a759b7dc49..fafd2ad586 100644 --- a/docs/tutorials/switching-sqlite-postgres.md +++ b/docs/tutorials/switching-sqlite-postgres.md @@ -17,11 +17,11 @@ switch between database backends. ## Install PostgreSQL -First, swap out SQLite for PostgreSQL in your `backend` package: +First, add PostgreSQL to your `backend` package: ```shell +# From your Backstage root directory cd packages/backend -yarn remove sqlite3 yarn add pg ``` @@ -46,7 +46,6 @@ backend: + #ssl: require # see https://www.postgresql.org/docs/current/libpq-ssl.html Table 33.1. SSL Mode Descriptions (e.g. require) + #ca: # if you have a CA file and want to verify it you can uncomment this section + #$file: <file-path>/ca/server.crt - ``` If you have an `app-config.local.yaml` for local development, a similar update diff --git a/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md b/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md index 65102c919f..7289878bc1 100644 --- a/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md +++ b/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md @@ -45,7 +45,7 @@ The only thing you need to do is to start the app: ```bash cd my-app -yarn start +yarn dev ``` And you are good to go! 👍 @@ -101,18 +101,12 @@ We provide a collection of public Backstage plugins (look for packages with the Install in your app’s package folder (`<root>/packages/app`) with: ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-<plugin-name> ``` -Then add it to your app's `plugin.ts` file to import and register it: - -`<root>/packages/app/src/plugin.ts`: - -```js -export { plugin as PluginName } from '@backstage/plugin-<plugin-name>'; -``` - -A plugin registers its own `route` in the app — read the documentation for the specific plugin you are installing for more information on that. +After that, you inject the plugin into the application where you want it to be exposed. Please read the documentation for the specific plugin you are installing for more information. ### Creating an internal plugin diff --git a/packages/backend-common/README.md b/packages/backend-common/README.md index dc08d89416..dc69790bc3 100644 --- a/packages/backend-common/README.md +++ b/packages/backend-common/README.md @@ -8,6 +8,8 @@ error handling and similar. Add the library to your backend package: ```sh +# From your Backstage root directory +cd packages/backend yarn add @backstage/backend-common ``` diff --git a/packages/backend/src/plugins/kubernetes.ts b/packages/backend/src/plugins/kubernetes.ts index 131c5c8eee..7906765533 100644 --- a/packages/backend/src/plugins/kubernetes.ts +++ b/packages/backend/src/plugins/kubernetes.ts @@ -15,12 +15,11 @@ */ import { createRouter } from '@backstage/plugin-kubernetes-backend'; -import { Router } from 'express'; import { PluginEnvironment } from '../types'; export default async function createPlugin({ logger, config, -}: PluginEnvironment): Promise<Router> { +}: PluginEnvironment) { return await createRouter({ logger, config }); } diff --git a/packages/cli/README.md b/packages/cli/README.md index cd6ad8094e..eb5e0e461b 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -7,13 +7,13 @@ This package provides a CLI for developing Backstage plugins and apps. Install the package via npm or Yarn: ```sh -$ npm install --save @backstage/cli +npm install --save @backstage/cli ``` or ```sh -$ yarn add @backstage/cli +yarn add @backstage/cli ``` ## Development diff --git a/packages/core-api/README.md b/packages/core-api/README.md index f7b8b6c337..a4325a9c5d 100644 --- a/packages/core-api/README.md +++ b/packages/core-api/README.md @@ -7,13 +7,13 @@ This package provides the core API used by Backstage plugins and apps. Do not install this package directly, it is reexported by `@backstage/core`. Install that instead: ```sh -$ npm install --save @backstage/core +npm install --save @backstage/core ``` or ```sh -$ yarn add @backstage/core +yarn add @backstage/core ``` ## Documentation diff --git a/packages/core/README.md b/packages/core/README.md index 6d8519d46f..0f827d6074 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -7,13 +7,13 @@ This package provides the core API used by Backstage plugins and apps. Install the package via npm or Yarn: ```sh -$ npm install --save @backstage/core +npm install --save @backstage/core ``` or ```sh -$ yarn add @backstage/core +yarn add @backstage/core ``` ## Documentation diff --git a/packages/dev-utils/README.md b/packages/dev-utils/README.md index 4b08a5ca6d..85d961ad0b 100644 --- a/packages/dev-utils/README.md +++ b/packages/dev-utils/README.md @@ -9,13 +9,13 @@ This package provides utilities that help in developing plugins for Backstage, l Install the package via npm or Yarn: ```sh -$ npm install --save-dev @backstage/dev-utils +npm install --save-dev @backstage/dev-utils ``` or ```sh -$ yarn add -D @backstage/dev-utils +yarn add -D @backstage/dev-utils ``` ## Documentation diff --git a/packages/test-utils/README.md b/packages/test-utils/README.md index 0f95d4ab26..ace7339733 100644 --- a/packages/test-utils/README.md +++ b/packages/test-utils/README.md @@ -7,13 +7,13 @@ This package provides utilities that can be used to test plugins and apps for Ba Install the package via npm or Yarn: ```sh -$ npm install --save-dev @backstage/test-utils +npm install --save-dev @backstage/test-utils ``` or ```sh -$ yarn add -D @backstage/test-utils +yarn add -D @backstage/test-utils ``` ## Documentation diff --git a/packages/theme/README.md b/packages/theme/README.md index 9855d6730d..de94ff1623 100644 --- a/packages/theme/README.md +++ b/packages/theme/README.md @@ -7,13 +7,13 @@ This package provides the extended Material UI Theme(s) that power Backstage. Install the package via npm or Yarn: ```sh -$ npm install --save @backstage/theme +npm install --save @backstage/theme ``` or ```sh -$ yarn add @backstage/theme +yarn add @backstage/theme ``` ## Documentation diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index dac4b6ff4d..60d8986d9b 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -28,15 +28,15 @@ To link that a component provides or consumes an API, see the [`providesApis`](h 1. Install the API docs plugin ```bash -# packages/app - +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-api-docs ``` 2. Add the `ApiExplorerPage` extension to the app: ```tsx -// packages/app/src/App.tsx +// In packages/app/src/App.tsx import { ApiExplorerPage } from '@backstage/plugin-api-docs'; @@ -56,7 +56,7 @@ import { } from '@backstage/plugin-api-docs'; const apiPage = ( - <EntityLayoutWrapper> + <EntityLayout> <EntityLayout.Route path="/" title="Overview"> <Grid container spacing={3}> <Grid item md={6}> @@ -80,7 +80,7 @@ const apiPage = ( </Grid> </Grid> </EntityLayout.Route> - </EntityLayoutWrapper> + </EntityLayout> ); // ... diff --git a/plugins/app-backend/README.md b/plugins/app-backend/README.md index 2dc302accb..a35cecfb9c 100644 --- a/plugins/app-backend/README.md +++ b/plugins/app-backend/README.md @@ -7,7 +7,9 @@ This backend plugin can be installed to serve static content of a Backstage app. Add both this package and your local frontend app package as dependencies to your backend, for example ```bash -yarn add @backstage/plugin-app-backend example-app +# From your Backstage root directory +cd packages/backend +yarn add @backstage/plugin-app-backend app ``` By adding the app package as a dependency we ensure that it is built as part of the backend, and that it can be resolved at runtime. diff --git a/plugins/bitrise/README.md b/plugins/bitrise/README.md index 411db3198e..1add03df23 100644 --- a/plugins/bitrise/README.md +++ b/plugins/bitrise/README.md @@ -8,9 +8,9 @@ Welcome to the Bitrise plugin! ## Installation ```sh -# The plugin must be added in the app package -$ cd packages/app -$ yarn add @backstage/plugin-bitrise +# From your Backstage root directory +cd packages/app +yarn add @backstage/plugin-bitrise ``` Bitrise Plugin exposes an entity tab component named `EntityBitriseContent`. You can include it in the @@ -22,7 +22,7 @@ import { EntityBitriseContent } from '@backstage/plugin-bitrise'; // Farther down at the website declaration const websiteEntityPage = ( - <EntityLayoutWrapper> + <EntityLayout> {/* Place the following section where you want the tab to appear */} <EntityLayout.Route path="/bitrise" title="Bitrise"> <EntityBitriseContent /> diff --git a/plugins/catalog-import/README.md b/plugins/catalog-import/README.md index 5e773ad288..bad48a8486 100644 --- a/plugins/catalog-import/README.md +++ b/plugins/catalog-import/README.md @@ -18,8 +18,8 @@ Some features are not yet available for all supported Git providers. 1. Install the Catalog Import Plugin: ```bash -# packages/app - +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-catalog-import ``` diff --git a/plugins/circleci/README.md b/plugins/circleci/README.md index 868ae6e26a..c878c66e56 100644 --- a/plugins/circleci/README.md +++ b/plugins/circleci/README.md @@ -7,34 +7,35 @@ Website: [https://circleci.com/](https://circleci.com/) ## Setup -1. If you have standalone app (you didn't clone this repo), then do +1. If you have a standalone app (you didn't clone this repo), then do ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-circleci ``` -2. Add the `EntityCircleCIContent` extension to the entity page in the app: +2. Add the `EntityCircleCIContent` extension to the entity page in your app: ```tsx -// packages/app/src/components/catalog/EntityPage.tsx -import { EntityCircleCIContent } from '@backstage/plugin-circleci'; +// In packages/app/src/components/catalog/EntityPage.tsx +import { + EntityCircleCIContent, + isCircleCIAvailable, +} from '@backstage/plugin-circleci'; -// ... -const serviceEntityPage = ( - <EntityPageLayout> - ... - <EntityLayout.Route path="/circle-ci" title="Circle CI"> +// For example in the CI/CD section +const cicdContent = ( + <EntitySwitch> + <EntitySwitch.Case if={isCircleCIAvailable}> <EntityCircleCIContent /> - </EntityLayout.Route> - ... - </EntityPageLayout> -); + </EntitySwitch.Case> ``` 4. Add proxy config: ```yaml -// app-config.yaml +# In app-config.yaml proxy: '/circleci/api': target: https://circleci.com/api/v1.1 @@ -42,10 +43,11 @@ proxy: Circle-Token: ${CIRCLECI_AUTH_TOKEN} ``` -5. Get and provide `CIRCLECI_AUTH_TOKEN` as env variable (https://circleci.com/docs/api/#add-an-api-token) -6. Add `circleci.com/project-slug` annotation to your catalog-info.yaml file in format <git-provider>/<owner>/<project> (https://backstage.io/docs/architecture-decisions/adrs-adr002#format) +5. Get and provide a `CIRCLECI_AUTH_TOKEN` as an environment variable (see the [CircleCI docs](https://circleci.com/docs/api/#add-an-api-token)). +6. Add a `circleci.com/project-slug` annotation to your respective `catalog-info.yaml` files, on the format <git-provider>/<owner>/<project> (https://backstage.io/docs/architecture-decisions/adrs-adr002#format). ```yaml +# Example catalog-info.yaml entity definition file apiVersion: backstage.io/v1alpha1 kind: Component metadata: diff --git a/plugins/cost-insights/README.md b/plugins/cost-insights/README.md index f737c022f3..3fee89e77a 100644 --- a/plugins/cost-insights/README.md +++ b/plugins/cost-insights/README.md @@ -16,6 +16,8 @@ Learn more with the Backstage blog post [New Cost Insights plugin: The engineer' ## Install ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-cost-insights ``` diff --git a/plugins/cost-insights/contrib/aws-cost-explorer-api.md b/plugins/cost-insights/contrib/aws-cost-explorer-api.md index 10622b7917..d6c5250759 100644 --- a/plugins/cost-insights/contrib/aws-cost-explorer-api.md +++ b/plugins/cost-insights/contrib/aws-cost-explorer-api.md @@ -33,6 +33,8 @@ Cost Explorer permission policy: Install the AWS Cost Explorer SDK. The AWS docs recommend using the SDK over making calls to the API directly as it simplifies authentication and provides direct access to commands. ```bash +# From your Backstage root directory +cd packages/app yarn add @aws-sdk/client-cost-explorer ``` diff --git a/plugins/fossa/README.md b/plugins/fossa/README.md index 11f3e90e1c..6ca2e1a96f 100644 --- a/plugins/fossa/README.md +++ b/plugins/fossa/README.md @@ -9,8 +9,8 @@ The FOSSA Plugin displays code statistics from [FOSSA](https://fossa.com/). 1. Install the FOSSA Plugin: ```bash -# packages/app - +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-fossa ``` diff --git a/plugins/github-actions/README.md b/plugins/github-actions/README.md index 87c68839c1..d027368c8b 100644 --- a/plugins/github-actions/README.md +++ b/plugins/github-actions/README.md @@ -11,15 +11,15 @@ TBD ### Generic Requirements 1. Provide OAuth credentials: - 1. [Create an OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) with callback URL set to `http://localhost:7000/api/auth/github`. - 2. Take Client ID and Client Secret from the newly created app's settings page and put them into `AUTH_GITHUB_CLIENT_ID` and `AUTH_GITHUB_CLIENT_SECRET` env variables. + 1. [Create an OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) with the callback URL set to `http://localhost:7000/api/auth/github`. + 2. Take the Client ID and Client Secret from the newly created app's settings page and put them into `AUTH_GITHUB_CLIENT_ID` and `AUTH_GITHUB_CLIENT_SECRET` environment variables. 2. Annotate your component with a correct GitHub Actions repository and owner: The annotation key is `github.com/project-slug`. Example: - ``` + ```yaml apiVersion: backstage.io/v1alpha1 kind: Component metadata: @@ -38,6 +38,7 @@ TBD 1. Install the plugin dependency in your Backstage app package: ```bash +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-github-actions ``` @@ -45,22 +46,24 @@ yarn add @backstage/plugin-github-actions 2. Add to the app `EntityPage` component: ```tsx -// packages/app/src/components/catalog/EntityPage.tsx -import { EntityGithubActionsContent } from '@backstage/plugin-github-actions'; +// In packages/app/src/components/catalog/EntityPage.tsx +import { + EntityGithubActionsContent, + isGithubActionsAvailable, +} from '@backstage/plugin-github-actions'; -// ... +// You can add the tab to any number of pages, the service page is shown as an +// example here const serviceEntityPage = ( - <EntityPageLayout> - ... + <EntityLayout> + {/* other tabs... */} <EntityLayout.Route path="/github-actions" title="GitHub Actions"> <EntityGithubActionsContent /> </EntityLayout.Route> - ... - </EntityPageLayout> -); ``` -2. Run the app with `yarn start` and the backend with `yarn --cwd packages/backend start`, navigate to `/github-actions/`. +3. Run the app with `yarn start` and the backend with `yarn start-backend`. + Then navigate to `/github-actions/` under any entity. ## Features diff --git a/plugins/github-deployments/README.md b/plugins/github-deployments/README.md index 1bb8846105..8284ceba56 100644 --- a/plugins/github-deployments/README.md +++ b/plugins/github-deployments/README.md @@ -13,8 +13,8 @@ The GitHub Deployments Plugin displays recent deployments from GitHub. 1. Install the GitHub Deployments Plugin. ```bash -# packages/app - +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-github-deployments ``` diff --git a/plugins/graphiql/README.md b/plugins/graphiql/README.md index 39372890d1..b95f055a56 100644 --- a/plugins/graphiql/README.md +++ b/plugins/graphiql/README.md @@ -12,6 +12,7 @@ By exposing GraphiQL as a plugin instead of a standalone app, it's possible to p Start out by installing the plugin in your Backstage app: ```bash +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-graphiql ``` diff --git a/plugins/jenkins/README.md b/plugins/jenkins/README.md index f406393190..69304cb847 100644 --- a/plugins/jenkins/README.md +++ b/plugins/jenkins/README.md @@ -11,25 +11,25 @@ Website: [https://jenkins.io/](https://jenkins.io/) 1. If you have a standalone app (you didn't clone this repo), then do ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-jenkins ``` 2. Add the `EntityJenkinsContent` extension to the entity page in the app: ```tsx -// packages/app/src/components/catalog/EntityPage.tsx -import { EntityJenkinsContent } from '@backstage/plugin-circleci'; +// In packages/app/src/components/catalog/EntityPage.tsx +import { EntityJenkinsContent } from '@backstage/plugin-jenkins'; -// ... +// You can add the tab to any number of pages, the service page is shown as an +// example here const serviceEntityPage = ( - <EntityPageLayout> - ... + <EntityLayout> + {/* other tabs... */} <EntityLayout.Route path="/jenkins" title="Jenkins"> <EntityJenkinsContent /> </EntityLayout.Route> - ... - </EntityPageLayout> -); ``` 3. Add proxy configuration to `app-config.yaml` @@ -43,14 +43,18 @@ proxy: Authorization: Basic ${JENKINS_BASIC_AUTH_HEADER} ``` -4. Add an environment variable which contains the Jenkins credentials, (note: use an API token not your password). Here user is the name of the user created in Jenkins. +4. Add an environment variable which contains the Jenkins credentials (NOTE: + use an API token, not your password). Here `user` is the name of the user + created in Jenkins. ```shell export JENKINS_BASIC_AUTH_HEADER=$(echo -n user:api-token | base64) ``` -5. Run app with `yarn start` -6. Add the Jenkins folder annotation to your `catalog-info.yaml`, (note: currently this plugin only supports folders and Git SCM) +5. Run the app with `yarn start` + +6. Add the Jenkins folder annotation to your `catalog-info.yaml`, (NOTE: + currently this plugin only supports folders and Git SCM) ```yaml apiVersion: backstage.io/v1alpha1 @@ -68,11 +72,11 @@ spec: 7. Register your component -8. Click the component in the catalog you should now see Jenkins builds, and a last build result for your master build. +8. Click the component in the catalog. You should now see Jenkins builds, and a + last build result for your master build. -Note: - -If you are not using environment variable then you can directly type API token in app-config.yaml +Note: If you are not using environment variables, you can directly type the API +token into `app-config.yaml`. ```yaml proxy: @@ -83,7 +87,8 @@ proxy: Authorization: Basic YWRtaW46MTFlYzI1NmU0Mzg1MDFjM2Y1Yzc2Yjc1MWE3ZTQ3YWY4Mw== ``` -YWRtaW46MTFlYzI1NmU0Mzg1MDFjM2Y1Yzc2Yjc1MWE3ZTQ3YWY4Mw== is the base64 of user and it's API token e.g. admin:11ec256e438501c3f5c76b751a7e47af83 +The string starting with `YWR...` is the base64 encoding of the user and their +API token, e.g. `admin:11ec256e438501c3f5c76b751a7e47af83`. ## Features @@ -94,4 +99,5 @@ YWRtaW46MTFlYzI1NmU0Mzg1MDFjM2Y1Yzc2Yjc1MWE3ZTQ3YWY4Mw== is the base64 of user a ## Limitations - Only works with organization folder projects backed by GitHub -- No pagination support currently, limited to 50 projects - don't run this on a Jenkins with lots of builds +- No pagination support currently, limited to 50 projects - don't run this on a + Jenkins instance with lots of builds diff --git a/plugins/kafka-backend/README.md b/plugins/kafka-backend/README.md index 14914e5ba6..d18a232fa4 100644 --- a/plugins/kafka-backend/README.md +++ b/plugins/kafka-backend/README.md @@ -1,6 +1,7 @@ # Kafka Backend -This is the backend part of the Kafka plugin. It responds to Kafka requests from the frontend. +This is the backend part of the Kafka plugin. It responds to Kafka requests +from the frontend. ## Configuration @@ -16,7 +17,9 @@ A list of the brokers' host names and ports to connect to. ### `ssl` (optional) -Configure TLS connection to the Kafka cluster. The options are passed directly to [tls.connect] and used to create the TLS secure context. Normally these would include `key` and `cert`. +Configure TLS connection to the Kafka cluster. The options are passed directly +to [tls.connect] and used to create the TLS secure context. Normally these +would include `key` and `cert`. Example: @@ -39,7 +42,7 @@ kafka: clusters: - name: prod brokers: - - my-cluser:9092 + - my-cluster:9092 ssl: true sasl: mechanism: plain # or 'scram-sha-256' or 'scram-sha-512' diff --git a/plugins/kafka/README.md b/plugins/kafka/README.md index a2ea01cf7d..7da44ae9b6 100644 --- a/plugins/kafka/README.md +++ b/plugins/kafka/README.md @@ -7,7 +7,9 @@ 1. Run: ```bash -yarn add @backstage/plugin-kafka @backstage/plugin-kafka-backend +# From your Backstage root directory +yarn --cwd packages/app add @backstage/plugin-kafka +yarn --cwd packages/backend add @backstage/plugin-kafka-backend ``` 2. Add the plugin backend: @@ -29,41 +31,31 @@ export default async function createPlugin({ And then add to `packages/backend/src/index.ts`: ```js -// ... +// In packages/backend/src/index.ts import kafka from './plugins/kafka'; // ... async function main() { // ... const kafkaEnv = useHotMemoize(module, () => createEnv('kafka')); // ... - - const apiRouter = Router(); - // ... apiRouter.use('/kafka', await kafka(kafkaEnv)); - // ... ``` -3. Add the plugin frontend to `packages/app/src/plugin.ts`: - -```js -export { plugin as Kafka } from '@backstage/plugin-kafka'; -``` - -4. Register the plugin frontend router in `packages/app/src/components/catalog/EntityPage.tsx`: +3. Add the plugin as a tab to your service entities: ```jsx -import { Router as KafkaRouter } from '@backstage/plugin-kafka'; +// In packages/app/src/components/catalog/EntityPage.tsx +import { EntityKafkaContent } from '@backstage/plugin-kafka'; -// Then, somewhere inside <EntityPageLayout> - -<EntityPageLayout.Content - path="/kafka/*" - title="Kafka" - element={<KafkaRouter entity={entity} />} -/>; +const serviceEntityPage = ( + <EntityLayout> + {/* other tabs... */} + <EntityLayout.Route path="/kafka" title="Kafka"> + <EntityKafkaContent /> + </EntityLayout.Route> ``` -5. Add broker configs for the backend in your `app-config.yaml` (see +4. Add broker configs for the backend in your `app-config.yaml` (see [kafka-backend](https://github.com/backstage/backstage/blob/master/plugins/kafka-backend/README.md) for more options): @@ -76,7 +68,7 @@ kafka: - localhost:9092 ``` -6. Add `kafka.apache.org/consumer-groups` annotation to your services: +5. Add the `kafka.apache.org/consumer-groups` annotation to your services: ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/lighthouse/README.md b/plugins/lighthouse/README.md index 028547ea3e..06c9a1da12 100644 --- a/plugins/lighthouse/README.md +++ b/plugins/lighthouse/README.md @@ -28,20 +28,21 @@ _It's likely you will need to [enable CORS](https://developer.mozilla.org/en-US/ When you have an instance running that Backstage can hook into, first install the plugin into your app: ```sh -$ yarn add @backstage/plugin-lighthouse +# From your Backstage root directory +cd packages/app +yarn add @backstage/plugin-lighthouse ``` Modify your app routes in `App.tsx` to include the `LighthousePage` component exported from the plugin, for example: ```tsx -// At the top imports +// In packages/app/src/App.tsx import { LighthousePage } from '@backstage/plugin-lighthouse'; -<FlatRoutes> - // ... - <Route path="/lighthouse" element={<LighthousePage />} /> - // ... -</FlatRoutes>; +const routes = ( + <FlatRoutes> + {/* ...other routes */} + <Route path="/lighthouse" element={<LighthousePage />} /> ``` Then configure the `lighthouse-audit-service` URL in your [`app-config.yaml`](https://github.com/backstage/backstage/blob/master/app-config.yaml). @@ -63,55 +64,45 @@ kind: Component metadata: # ... annotations: - # ... lighthouse.com/website-url: # A single website url e.g. https://backstage.io/ ``` > NOTE: The plugin only supports one website URL per component at this time. -Add a **Lighthouse tab** to the EntityPage: +Add a Lighthouse tab to the entity page: ```tsx -// packages/app/src/components/catalog/EntityPage.tsx -import { EmbeddedRouter as LighthouseRouter } from '@backstage/plugin-lighthouse'; +// In packages/app/src/components/catalog/EntityPage.tsx +import { EntityLighthouseContent } from '@backstage/plugin-lighthouse'; -// ... -const WebsiteEntityPage = ({ entity }: { entity: Entity }) => ( - <EntityPageLayout> - // ... - <EntityPageLayout.Content - path="/lighthouse/*" - title="Lighthouse" - element={<LighthouseRouter entity={entity} />} - /> - </EntityPageLayout> -); +const websiteEntityPage = ( + <EntityLayout> + {/* other tabs... */} + <EntityLayout.Route path="/lighthouse" title="Lighthouse"> + <EntityLighthouseContent /> + </EntityLayout.Route> ``` -> NOTE: The embedded router renders page content without a header section allowing it to be rendered within a -> catalog plugin page. +> NOTE: The embedded router renders page content without a header section +> allowing it to be rendered within a catalog plugin page. Add a **Lighthouse card** to the overview tab on the EntityPage: ```tsx -// packages/app/src/components/catalog/EntityPage.tsx +// In packages/app/src/components/catalog/EntityPage.tsx import { - LastLighthouseAuditCard, - isPluginApplicableToEntity as isLighthouseAvailable, + EntityLastLighthouseAuditCard, + isLighthouseAvailable, } from '@backstage/plugin-lighthouse'; -// ... - -const OverviewContent = ({ entity }: { entity: Entity }) => ( - <Grid container spacing={3}> - // ... - {isLighthouseAvailable(entity) && ( - <Grid item sm={4}> - <LastLighthouseAuditCard /> - </Grid> - )} - </Grid> -); +const overviewContent = ( + <Grid container spacing={3} alignItems="stretch"> + {/* ...other content */} + <EntitySwitch> + <EntitySwitch.Case if={isLighthouseAvailable}> + <Grid item md={6}> + <EntityLastLighthouseAuditCard /> + </Grid> + </EntitySwitch.Case> + </EntitySwitch> ``` - -Link Lighthouse diff --git a/plugins/lighthouse/src/components/Intro/index.tsx b/plugins/lighthouse/src/components/Intro/index.tsx index a89518a5ed..6b0307f9ec 100644 --- a/plugins/lighthouse/src/components/Intro/index.tsx +++ b/plugins/lighthouse/src/components/Intro/index.tsx @@ -46,7 +46,8 @@ with the environment variable \`LAS_CORS\` set to \`true\`._ When you have an instance running that Backstage can hook into, first install the plugin into your app: \`\`\`sh -$ yarn add @backstage/plugin-lighthouse +cd packages/app +yarn add @backstage/plugin-lighthouse \`\`\` Modify your app routes in \`App.tsx\` to include the \`LighthousePage\` component exported from the plugin, for example: diff --git a/plugins/pagerduty/README.md b/plugins/pagerduty/README.md index 36f380fdd5..e1ec7f89c7 100644 --- a/plugins/pagerduty/README.md +++ b/plugins/pagerduty/README.md @@ -19,6 +19,8 @@ This plugin provides: Install the plugin: ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-pagerduty ``` diff --git a/plugins/register-component/README.md b/plugins/register-component/README.md index 9c5304385e..47db1a7a55 100644 --- a/plugins/register-component/README.md +++ b/plugins/register-component/README.md @@ -19,6 +19,7 @@ When installed it is accessible on [localhost:3000/register-component](localhost 1. Install plugin and its dependency `plugin-catalog` ```bash +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-register-component ``` diff --git a/plugins/rollbar/README.md b/plugins/rollbar/README.md index 3a33fe223c..bdf0541fa0 100644 --- a/plugins/rollbar/README.md +++ b/plugins/rollbar/README.md @@ -9,25 +9,23 @@ Website: [https://rollbar.com/](https://rollbar.com/) 2. If you have standalone app (you didn't clone this repo), then do ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-rollbar ``` 3. Add to the app `EntityPage` component: ```tsx -// packages/app/src/components/catalog/EntityPage.tsx +// In packages/app/src/components/catalog/EntityPage.tsx import { EntityRollbarContent } from '@backstage/plugin-rollbar'; -// ... const serviceEntityPage = ( - <EntityPageLayout> - ... + <EntityLayout> + {/* other tabs... */} <EntityLayout.Route path="/rollbar" title="Rollbar"> <EntityRollbarContent /> </EntityLayout.Route> - ... - </EntityPageLayout> -); ``` 4. Setup the `app-config.yaml` and account token environment variable diff --git a/plugins/sentry/README.md b/plugins/sentry/README.md index 9bdb2dc16d..e0c56e842c 100644 --- a/plugins/sentry/README.md +++ b/plugins/sentry/README.md @@ -9,8 +9,8 @@ The Sentry Plugin displays issues from [Sentry](https://sentry.io). 1. Install the Sentry Plugin: ```bash -# packages/app - +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-sentry ``` diff --git a/plugins/sonarqube/README.md b/plugins/sonarqube/README.md index 5c12832e57..d0251e91ef 100644 --- a/plugins/sonarqube/README.md +++ b/plugins/sonarqube/README.md @@ -9,7 +9,8 @@ The SonarQube Plugin displays code statistics from [SonarCloud](https://sonarclo 1. Install the SonarQube Plugin: ```bash -# packages/app +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-sonarqube ``` diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index 5c1dda33fc..33cfa091ca 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -20,6 +20,8 @@ This plugin provides: Install the plugin: ```bash +# From your Backstage root directory +cd packages/app yarn add @backstage/plugin-splunk-on-call ``` diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md index 7f97f88ed4..814ab6cba5 100644 --- a/plugins/tech-radar/README.md +++ b/plugins/tech-radar/README.md @@ -26,6 +26,7 @@ The Tech Radar can be used in two ways: For either simple or advanced installations, you'll need to add the dependency using Yarn: ```sh +# From your Backstage root directory cd packages/app yarn add @backstage/plugin-tech-radar ``` @@ -35,12 +36,12 @@ yarn add @backstage/plugin-tech-radar Modify your app routes to include the Router component exported from the tech radar, for example: ```tsx -// in packages/app/src/App.tsx +// In packages/app/src/App.tsx import { TechRadarPage } from '@backstage/plugin-tech-radar'; const routes = ( <FlatRoutes> - {/* ... */} + {/* ...other routes */} <Route path="/tech-radar" element={<TechRadarPage width={1500} height={800} />} diff --git a/plugins/techdocs-backend/examples/documented-component/docs/code/code-sample.md b/plugins/techdocs-backend/examples/documented-component/docs/code/code-sample.md index 9f8e1bd739..f41ab1d506 100644 --- a/plugins/techdocs-backend/examples/documented-component/docs/code/code-sample.md +++ b/plugins/techdocs-backend/examples/documented-component/docs/code/code-sample.md @@ -5,19 +5,19 @@ This page provides some sample code which may be used in your example component. This code uses TypeScript, and the Markdown code fence to wrap the code. ```typescript -const DefaultEntityPage = ({ entity }: { entity: Entity }) => ( - <EntityPageLayout> - <EntityPageLayout.Content - path="/*" - title="Overview" - element={<ComponentOverviewContent entity={entity} />} - /> - <EntityPageLayout.Content - path="/docs/*" - title="Docs" - element={<DocsRouter entity={entity} />} - /> - </EntityPageLayout> +const serviceEntityPage = ( + <EntityLayout> + <EntityLayout.Route path="/" title="Overview"> + <Grid container spacing={3} alignItems="stretch"> + <Grid item md={6}> + <EntityAboutCard variant="gridItem" /> + </Grid> + </Grid> + </EntityLayout.Route> + <EntityLayout.Route path="/docs" title="Docs"> + <EntityTechdocsContent /> + </EntityLayout.Route> + </EntityLayout> ); ``` From 8f276d072bf841b67ee9215db5f72ebd47dbefc6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 04:20:11 +0000 Subject: [PATCH 390/462] chore(deps): bump swagger-ui-react from 3.45.1 to 3.48.0 Bumps [swagger-ui-react](https://github.com/swagger-api/swagger-ui) from 3.45.1 to 3.48.0. - [Release notes](https://github.com/swagger-api/swagger-ui/releases) - [Commits](https://github.com/swagger-api/swagger-ui/compare/v3.45.1...v3.48.0) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 55 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/yarn.lock b/yarn.lock index f24ce68740..ac1a9f27c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1608,10 +1608,10 @@ core-js "^2.6.5" regenerator-runtime "^0.13.4" -"@babel/runtime-corejs3@^7.10.2", "@babel/runtime-corejs3@^7.11.2", "@babel/runtime-corejs3@^7.13.10": - version "7.13.10" - resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.13.10.tgz#14c3f4c85de22ba88e8e86685d13e8861a82fe86" - integrity sha512-x/XYVQ1h684pp1mJwOV4CyvqZXqbc8CMsMGUnAbuc82ZCdv1U63w5RSUzgDSXQHG5Rps/kiksH6g2D5BuaKyXg== +"@babel/runtime-corejs3@^7.10.2", "@babel/runtime-corejs3@^7.11.2", "@babel/runtime-corejs3@^7.13.17": + version "7.14.0" + resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz#6bf5fbc0b961f8e3202888cb2cd0fb7a0a9a3f66" + integrity sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg== dependencies: core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" @@ -9677,10 +9677,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.5, classnames@^2.2.6: - version "2.2.6" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" - integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== +classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== clean-css@^4.2.3: version "4.2.3" @@ -11832,10 +11832,10 @@ domhandler@^4.0.0: dependencies: domelementtype "^2.1.0" -dompurify@^2.0.12, dompurify@^2.1.1, dompurify@^2.2.7: - version "2.2.7" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.2.7.tgz#a5f055a2a471638680e779bd08fc334962d11fd8" - integrity sha512-jdtDffdGNY+C76jvodNTu9jt5yYj59vuTUyx+wXdzcSwAGTYZDAQkQ7Iwx9zcGrA4ixC1syU4H3RZROqRxokxg== +dompurify@^2.0.12, dompurify@^2.1.1, dompurify@^2.2.8: + version "2.2.8" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.2.8.tgz#ce88e395f6d00b6dc53f80d6b2a6fdf5446873c6" + integrity sha512-9H0UL59EkDLgY3dUFjLV6IEUaHm5qp3mxSqWw7Yyx4Zhk2Jn2cmLe+CNPP3xy13zl8Bqg+0NehQzkdMoVhGRww== domutils@1.5.1: version "1.5.1" @@ -23583,12 +23583,7 @@ sentence-case@^3.0.4: tslib "^2.0.3" upper-case-first "^2.0.2" -serialize-error@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" - integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= - -serialize-error@^8.0.1: +serialize-error@^8.0.1, serialize-error@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ== @@ -24859,10 +24854,10 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -swagger-client@^3.13.1: - version "3.13.1" - resolved "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.1.tgz#d2531ede4a498911aa084384e387e5008e7b6a70" - integrity sha512-Hmy4+wVVa3kveWzC7PIeUwiAY5qcYbm4XlC4uZ7e5kAePfB2cprXImiqrZHIzL+ndU0YTN7I+9w/ZayTisn3Jg== +swagger-client@^3.13.2: + version "3.13.2" + resolved "https://registry.npmjs.org/swagger-client/-/swagger-client-3.13.2.tgz#df1a1fe92e6db87ab5f76cee6381dcb7da1ad117" + integrity sha512-kamtyXtmbZiA2C5YTVqJYgoPJgzqtM5RbeP23Rt/YPYjMArTKZ2fjx1UTsI0aSbws0GluU5pVHiGp8YMciSUfw== dependencies: "@babel/runtime-corejs3" "^7.11.2" btoa "^1.2.1" @@ -24880,19 +24875,19 @@ swagger-client@^3.13.1: url "~0.11.0" swagger-ui-react@^3.37.2: - version "3.45.1" - resolved "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.45.1.tgz#6c8e551c5c1d443e7195acd9614f2f6bc4557daf" - integrity sha512-ATXMVIb5YaxxmHJdvPq1nnXxsJ1FCo02fQI2gExEtZCQkouMThZh50DRxdKYNae53Ovz3w8glxxwmsMuWtmKaQ== + version "3.48.0" + resolved "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.48.0.tgz#f53e1b7de5bc2628635a2d832e254043badb3a91" + integrity sha512-39cibLdJYeujP5CAzBg+LiNFyIuHomi4Blru/1hyFyiTkFx9yYGvcFpZrKFKq1Me4GSUCQJ1DzUyUMblo+VFcA== dependencies: - "@babel/runtime-corejs3" "^7.13.10" + "@babel/runtime-corejs3" "^7.13.17" "@braintree/sanitize-url" "^5.0.0" "@kyleshockey/object-assign-deep" "^0.4.2" "@kyleshockey/xml" "^1.0.2" base64-js "^1.5.1" - classnames "^2.2.6" + classnames "^2.3.1" css.escape "1.5.1" deep-extend "0.6.0" - dompurify "^2.2.7" + dompurify "^2.2.8" ieee754 "^1.2.1" immutable "^3.x.x" js-file-download "^0.4.12" @@ -24913,9 +24908,9 @@ swagger-ui-react@^3.37.2: redux-immutable "3.1.0" remarkable "^2.0.1" reselect "^4.0.0" - serialize-error "^2.1.0" + serialize-error "^8.1.0" sha.js "^2.4.11" - swagger-client "^3.13.1" + swagger-client "^3.13.2" url-parse "^1.5.1" xml-but-prettier "^1.0.1" zenscroll "^4.0.2" From e8438df861915f2944d6b6dbb41521665a629805 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 04:44:57 +0000 Subject: [PATCH 391/462] chore(deps): bump @octokit/auth-app from 2.10.5 to 3.4.0 Bumps [@octokit/auth-app](https://github.com/octokit/auth-app.js) from 2.10.5 to 3.4.0. - [Release notes](https://github.com/octokit/auth-app.js/releases) - [Commits](https://github.com/octokit/auth-app.js/compare/v2.10.5...v3.4.0) Signed-off-by: dependabot[bot] <support@github.com> --- packages/integration/package.json | 2 +- yarn.lock | 123 +++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 38 deletions(-) diff --git a/packages/integration/package.json b/packages/integration/package.json index dcfae4ea05..797a2c0b48 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -33,7 +33,7 @@ "cross-fetch": "^3.0.6", "git-url-parse": "^11.4.4", "@octokit/rest": "^18.0.12", - "@octokit/auth-app": "^2.10.5", + "@octokit/auth-app": "^3.4.0", "luxon": "^1.25.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index f24ce68740..4d4549357c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3955,11 +3955,13 @@ puka "^1.0.1" read-package-json-fast "^2.0.1" -"@octokit/auth-app@^2.10.5": - version "2.10.5" - resolved "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-2.10.5.tgz#85d69cb96818f5da34bf0b81bb637d3675ad4e9a" - integrity sha512-6yXyjtcBWpuPYSdZN8z8IIjGSqkPmiJzdmCdod8at41ANB1FtaKbUIDL5+IkG+svv68NIYs+XORbhBRFXYB3bw== +"@octokit/auth-app@^3.4.0": + version "3.4.0" + resolved "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-3.4.0.tgz#af9f68512e7b8dd071b49e1470a1ddf88ff6a3a3" + integrity sha512-zBVgTnLJb0uoNMGCpcDkkAbPeavHX7oAjJkaDv2nqMmsXSsCw4AbUhjl99EtJQG/JqFY/kLFHM9330Wn0k70+g== dependencies: + "@octokit/auth-oauth-app" "^4.1.0" + "@octokit/auth-oauth-user" "^1.2.3" "@octokit/request" "^5.4.11" "@octokit/request-error" "^2.0.0" "@octokit/types" "^6.0.3" @@ -3969,6 +3971,41 @@ universal-github-app-jwt "^1.0.1" universal-user-agent "^6.0.0" +"@octokit/auth-oauth-app@^4.1.0": + version "4.1.2" + resolved "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-4.1.2.tgz#bf3ff30c260e6e9f10b950386f279befb8fe907d" + integrity sha512-bdNGNRmuDJjKoHla3mUGtkk/xcxKngnQfBEnyk+7VwMqrABKvQB1wQRSrwSWkPPUX7Lcj2ttkPAPG7+iBkMRnw== + dependencies: + "@octokit/auth-oauth-device" "^3.1.1" + "@octokit/auth-oauth-user" "^1.2.1" + "@octokit/request" "^5.3.0" + "@octokit/types" "^6.0.3" + "@types/btoa-lite" "^1.0.0" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-device@^3.1.1": + version "3.1.1" + resolved "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-3.1.1.tgz#380499f9a850425e2c7bdeb62afc070181c536a9" + integrity sha512-ykDZROilszXZJ6pYdl6SZ15UZniCs0zDcKgwOZpMz3U0QDHPUhFGXjHToBCAIHwbncMu+jLt4/Nw4lq3FwAw/w== + dependencies: + "@octokit/oauth-methods" "^1.1.0" + "@octokit/request" "^5.4.14" + "@octokit/types" "^6.10.0" + universal-user-agent "^6.0.0" + +"@octokit/auth-oauth-user@^1.2.1", "@octokit/auth-oauth-user@^1.2.3": + version "1.2.4" + resolved "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-1.2.4.tgz#3594eb7d40cb462240e7e90849781dfa0045aed5" + integrity sha512-efOajupCZBP1veqx5w59Qey0lIud1rDUgxTRjjkQDU3eOBmkAasY1pXemDsQwW0I85jb1P/gn2dMejedVxf9kw== + dependencies: + "@octokit/auth-oauth-device" "^3.1.1" + "@octokit/oauth-methods" "^1.1.0" + "@octokit/request" "^5.4.14" + "@octokit/types" "^6.12.2" + btoa-lite "^1.0.0" + universal-user-agent "^6.0.0" + "@octokit/auth-token@^2.4.4": version "2.4.4" resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.4.tgz#ee31c69b01d0378c12fd3ffe406030f3d94d3b56" @@ -4006,20 +4043,31 @@ "@octokit/types" "^6.0.3" universal-user-agent "^6.0.0" +"@octokit/oauth-authorization-url@^4.3.1": + version "4.3.1" + resolved "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-4.3.1.tgz#008d09bf427a7f61c70b5283040d60a456011a51" + integrity sha512-sI/SOEAvzRhqdzj+kJl+2ifblRve2XU6ZB36Lq25Su8R31zE3GoKToSLh64nWFnKePNi2RrdcMm94UEIQZslOw== + +"@octokit/oauth-methods@^1.1.0": + version "1.2.2" + resolved "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-1.2.2.tgz#3d98c548aa2ace36ad8d0ce6593fd49dcbe103cc" + integrity sha512-CFMUMn9DdPLMcpffhKgkwIIClfv0ZToJM4qcg4O0egCoHMYkVlxl22bBoo9qCnuF1U/xn871KEXuozKIX+bA2w== + dependencies: + "@octokit/oauth-authorization-url" "^4.3.1" + "@octokit/request" "^5.4.14" + "@octokit/request-error" "^2.0.5" + "@octokit/types" "^6.12.2" + btoa-lite "^1.0.0" + "@octokit/openapi-types@^2.2.0": version "2.2.0" resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-2.2.0.tgz#123e0438a0bc718ccdac3b5a2e69b3dd00daa85b" integrity sha512-274lNUDonw10kT8wHg8fCcUc1ZjZHbWv0/TbAwb0ojhBQqZYc1cQ/4yqTVTtPMDeZ//g7xVEYe/s3vURkRghPg== -"@octokit/openapi-types@^5.3.2": - version "5.3.2" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-5.3.2.tgz#b8ac43c5c3d00aef61a34cf744e315110c78deb4" - integrity sha512-NxF1yfYOUO92rCx3dwvA2onF30Vdlg7YUkMVXkeptqpzA3tRLplThhFleV/UKWFgh7rpKu1yYRbvNDUtzSopKA== - -"@octokit/openapi-types@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-6.0.0.tgz#7da8d7d5a72d3282c1a3ff9f951c8133a707480d" - integrity sha512-CnDdK7ivHkBtJYzWzZm7gEkanA7gKH6a09Eguz7flHw//GacPJLmkHA3f3N++MJmlxD1Fl+mB7B32EEpSCwztQ== +"@octokit/openapi-types@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.0.0.tgz#0f6992db9854af15eca77d71ab0ec7fad2f20411" + integrity sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw== "@octokit/plugin-enterprise-rest@^6.0.1": version "6.0.1" @@ -4054,27 +4102,25 @@ "@octokit/types" "^6.13.0" deprecation "^2.3.1" -"@octokit/request-error@^2.0.0": - version "2.0.2" - resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz#0e76b83f5d8fdda1db99027ea5f617c2e6ba9ed0" - integrity sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw== +"@octokit/request-error@^2.0.0", "@octokit/request-error@^2.0.5": + version "2.0.5" + resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz#72cc91edc870281ad583a42619256b380c600143" + integrity sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg== dependencies: - "@octokit/types" "^5.0.1" + "@octokit/types" "^6.0.3" deprecation "^2.0.0" once "^1.4.0" -"@octokit/request@^5.3.0", "@octokit/request@^5.4.11", "@octokit/request@^5.4.12": - version "5.4.13" - resolved "https://registry.npmjs.org/@octokit/request/-/request-5.4.13.tgz#eec5987b3e96f984fc5f41967e001170c6d23a18" - integrity sha512-WcNRH5XPPtg7i1g9Da5U9dvZ6YbTffw9BN2rVezYiE7couoSyaRsw0e+Tl8uk1fArHE7Dn14U7YqUDy59WaqEw== +"@octokit/request@^5.3.0", "@octokit/request@^5.4.11", "@octokit/request@^5.4.12", "@octokit/request@^5.4.14": + version "5.4.15" + resolved "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz#829da413dc7dd3aa5e2cdbb1c7d0ebe1f146a128" + integrity sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag== dependencies: "@octokit/endpoint" "^6.0.1" "@octokit/request-error" "^2.0.0" - "@octokit/types" "^6.0.3" - deprecation "^2.0.0" + "@octokit/types" "^6.7.1" is-plain-object "^5.0.0" node-fetch "^2.6.1" - once "^1.4.0" universal-user-agent "^6.0.0" "@octokit/rest@^18.0.12", "@octokit/rest@^18.1.0": @@ -4104,19 +4150,12 @@ dependencies: "@types/node" ">= 8" -"@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.0.3", "@octokit/types@^6.12.2": - version "6.12.2" - resolved "https://registry.npmjs.org/@octokit/types/-/types-6.12.2.tgz#5b44add079a478b8eb27d78cf384cc47e4411362" - integrity sha512-kCkiN8scbCmSq+gwdJV0iLgHc0O/GTPY1/cffo9kECu1MvatLPh9E+qFhfRIktKfHEA6ZYvv6S1B4Wnv3bi3pA== +"@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.0.3", "@octokit/types@^6.10.0", "@octokit/types@^6.12.2", "@octokit/types@^6.13.0", "@octokit/types@^6.7.1", "@octokit/types@^6.8.2": + version "6.14.2" + resolved "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz#64c9457f38fb8522bdbba3c8cc814590a2d61bf5" + integrity sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA== dependencies: - "@octokit/openapi-types" "^5.3.2" - -"@octokit/types@^6.13.0", "@octokit/types@^6.8.2": - version "6.13.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-6.13.0.tgz#779e5b7566c8dde68f2f6273861dd2f0409480d0" - integrity sha512-W2J9qlVIU11jMwKHUp5/rbVUeErqelCsO5vW5PKNb7wAXQVUz87Rc+imjlEvpvbH8yUb+KHmv8NEjVZdsdpyxA== - dependencies: - "@octokit/openapi-types" "^6.0.0" + "@octokit/openapi-types" "^7.0.0" "@open-draft/until@^1.0.3": version "1.0.3" @@ -5711,6 +5750,11 @@ resolved "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw== +"@types/btoa-lite@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz#e190a5a548e0b348adb0df9ac7fa5f1151c7cca4" + integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg== + "@types/cacheable-request@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" @@ -9032,6 +9076,11 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= + btoa@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" From 1268d64f0e8d43f113db2080613816cfc4ff9634 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 04:44:03 +0000 Subject: [PATCH 392/462] chore(deps): bump winston from 3.2.1 to 3.3.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [winston](https://github.com/winstonjs/winston) from 3.2.1 to 3.3.3. - [Release notes](https://github.com/winstonjs/winston/releases) - [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md) - [Commits](https://github.com/winstonjs/winston/compare/3.2.1...v3.3.3) Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- packages/backend-common/api-report.md | 3 +- yarn.lock | 99 +++++++++++++-------------- 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 58b9aa36d9..9969d0ea27 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -12,7 +12,6 @@ import cors from 'cors'; import Docker from 'dockerode'; import { ErrorRequestHandler } from 'express'; import express from 'express'; -import { Format } from 'logform'; import { GithubCredentialsProvider } from '@backstage/integration'; import { GitHubIntegration } from '@backstage/integration'; import { GitLabIntegration } from '@backstage/integration'; @@ -64,7 +63,7 @@ export class BitbucketUrlReader implements UrlReader { } // @public (undocumented) -export const coloredFormat: Format; +export const coloredFormat: winston.Logform.Format; // @public @deprecated export const createDatabase: typeof createDatabaseClient; diff --git a/yarn.lock b/yarn.lock index f24ce68740..50cdc9906a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1925,6 +1925,15 @@ debug "^3.1.0" lodash.once "^4.1.1" +"@dabh/diagnostics@^2.0.2": + version "2.0.2" + resolved "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" + integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + "@date-io/core@1.x", "@date-io/core@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" @@ -8133,7 +8142,7 @@ async@^2.0.1, async@^2.6.1, async@^2.6.2: dependencies: lodash "^4.17.14" -async@^3.2.0: +async@^3.1.0, async@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== @@ -9993,11 +10002,6 @@ colorette@1.2.1, colorette@^1.2.1: resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== -colornames@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" - integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= - colors@^1.1.2, colors@^1.2.1: version "1.4.0" resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -11591,15 +11595,6 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -diagnostics@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" - integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ== - dependencies: - colorspace "1.1.x" - enabled "1.0.x" - kuler "1.0.x" - dicer@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872" @@ -12119,12 +12114,10 @@ emotion-theming@^10.0.19: "@emotion/weak-memoize" "0.2.5" hoist-non-react-statics "^3.3.0" -enabled@1.0.x: - version "1.0.2" - resolved "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" - integrity sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M= - dependencies: - env-variable "0.0.x" +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== encodeurl@~1.0.2: version "1.0.2" @@ -12190,11 +12183,6 @@ env-paths@^2.2.0: resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== -env-variable@0.0.x: - version "0.0.6" - resolved "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz#74ab20b3786c545b62b4a4813ab8cf22726c9808" - integrity sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg== - envinfo@^7.7.4: version "7.7.4" resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.7.4.tgz#c6311cdd38a0e86808c1c9343f667e4267c4a320" @@ -13491,6 +13479,11 @@ fn-name@~3.0.0: resolved "https://registry.npmjs.org/fn-name/-/fn-name-3.0.0.tgz#0596707f635929634d791f452309ab41558e3c5c" integrity sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA== +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + follow-redirects@^1.0.0, follow-redirects@^1.10.0: version "1.13.0" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" @@ -17341,12 +17334,10 @@ knex@^0.95.1: tarn "^3.0.1" tildify "2.0.0" -kuler@1.0.x: - version "1.0.1" - resolved "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" - integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ== - dependencies: - colornames "^1.1.1" +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== language-subtag-registry@~0.3.2: version "0.3.21" @@ -17946,7 +17937,7 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -logform@^2.1.1: +logform@^2.1.1, logform@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== @@ -19823,10 +19814,12 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -one-time@0.0.4: - version "0.0.4" - resolved "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" - integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4= +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" onetime@^1.0.0: version "1.1.0" @@ -22590,7 +22583,7 @@ read@1, read@~1.0.1: dependencies: mute-stream "~0.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -26786,28 +26779,28 @@ windows-release@^3.1.0: dependencies: execa "^1.0.0" -winston-transport@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66" - integrity sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A== +winston-transport@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" + integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== dependencies: - readable-stream "^2.3.6" + readable-stream "^2.3.7" triple-beam "^1.2.0" winston@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz#63061377976c73584028be2490a1846055f77f07" - integrity sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw== + version "3.3.3" + resolved "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" + integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== dependencies: - async "^2.6.1" - diagnostics "^1.1.1" - is-stream "^1.1.0" - logform "^2.1.1" - one-time "0.0.4" - readable-stream "^3.1.1" + "@dabh/diagnostics" "^2.0.2" + async "^3.1.0" + is-stream "^2.0.0" + logform "^2.2.0" + one-time "^1.0.0" + readable-stream "^3.4.0" stack-trace "0.0.x" triple-beam "^1.3.0" - winston-transport "^4.3.0" + winston-transport "^4.4.0" word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" From 38ca0516827020389256018d0074fdc6305da053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Mon, 3 May 2021 11:15:22 +0200 Subject: [PATCH 393/462] The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/five-knives-flash.md | 10 +++++ packages/app/package.json | 2 +- packages/backend-common/package.json | 2 +- packages/backend/package.json | 2 +- .../packages/backend/package.json.hbs | 2 +- packages/integration/package.json | 2 +- plugins/catalog-import/package.json | 2 +- plugins/github-actions/package.json | 2 +- .../WorkflowRunDetails/WorkflowRunDetails.tsx | 6 +-- plugins/scaffolder-backend/package.json | 2 +- yarn.lock | 40 +++++-------------- 11 files changed, 32 insertions(+), 40 deletions(-) create mode 100644 .changeset/five-knives-flash.md diff --git a/.changeset/five-knives-flash.md b/.changeset/five-knives-flash.md new file mode 100644 index 0000000000..9076f6f456 --- /dev/null +++ b/.changeset/five-knives-flash.md @@ -0,0 +1,10 @@ +--- +'@backstage/backend-common': patch +'@backstage/create-app': patch +'@backstage/integration': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. diff --git a/packages/app/package.json b/packages/app/package.json index 402d09ade4..fb1ea02699 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -39,7 +39,7 @@ "@backstage/theme": "^0.2.6", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "@roadiehq/backstage-plugin-buildkite": "^1.0.0", "@roadiehq/backstage-plugin-github-insights": "^1.0.0", "@roadiehq/backstage-plugin-github-pull-requests": "^1.0.0", diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 998ac475d9..64e3137f7c 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -35,7 +35,7 @@ "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@google-cloud/storage": "^5.8.0", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "@types/cors": "^2.8.6", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", diff --git a/packages/backend/package.json b/packages/backend/package.json index 440ceca8e5..0422088d64 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -47,7 +47,7 @@ "@backstage/plugin-techdocs-backend": "^0.7.0", "@backstage/plugin-todo-backend": "^0.1.3", "@gitbeaker/node": "^28.0.2", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "azure-devops-node-api": "^10.1.1", "dockerode": "^3.2.1", "example-app": "^0.2.25", diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 138bcaec8d..e2b5b04a60 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -29,7 +29,7 @@ "@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", "@gitbeaker/node": "^28.0.2", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "dockerode": "^3.2.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", diff --git a/packages/integration/package.json b/packages/integration/package.json index 797a2c0b48..b7c8bee957 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -32,7 +32,7 @@ "@backstage/config": "^0.1.2", "cross-fetch": "^3.0.6", "git-url-parse": "^11.4.4", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "@octokit/auth-app": "^3.4.0", "luxon": "^1.25.0" }, diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index ca540fe8be..ccc2dd24a7 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -40,7 +40,7 @@ "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "@types/react": "^16.9", "git-url-parse": "^11.4.4", "js-base64": "^3.6.0", diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 2c26061cf3..89b569bd95 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -40,7 +40,7 @@ "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "moment": "^2.27.0", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index 38d84a4b6d..0624438ffe 100644 --- a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -202,13 +202,13 @@ export const WorkflowRunDetails = ({ entity }: { entity: Entity }) => { <TableCell> <Typography noWrap>Message</Typography> </TableCell> - <TableCell>{details.value?.head_commit.message}</TableCell> + <TableCell>{details.value?.head_commit?.message}</TableCell> </TableRow> <TableRow> <TableCell> <Typography noWrap>Commit ID</Typography> </TableCell> - <TableCell>{details.value?.head_commit.id}</TableCell> + <TableCell>{details.value?.head_commit?.id}</TableCell> </TableRow> <TableRow> <TableCell> @@ -231,7 +231,7 @@ export const WorkflowRunDetails = ({ entity }: { entity: Entity }) => { <TableCell> <Typography noWrap>Author</Typography> </TableCell> - <TableCell>{`${details.value?.head_commit.author?.name} (${details.value?.head_commit.author?.email})`}</TableCell> + <TableCell>{`${details.value?.head_commit?.author?.name} (${details.value?.head_commit?.author?.email})`}</TableCell> </TableRow> <TableRow> <TableCell> diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 355bed4de0..bbeeecceb0 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -37,7 +37,7 @@ "@backstage/integration": "^0.5.1", "@gitbeaker/core": "^28.0.2", "@gitbeaker/node": "^28.0.2", - "@octokit/rest": "^18.0.12", + "@octokit/rest": "^18.5.3", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "@types/git-url-parse": "^9.0.0", diff --git a/yarn.lock b/yarn.lock index 4d4549357c..61abdf1b85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4086,20 +4086,12 @@ resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.2.tgz#394d59ec734cd2f122431fbaf05099861ece3c44" integrity sha512-oTJSNAmBqyDR41uSMunLQKMX0jmEXbwD1fpz8FG27lScV3RhtGfBa1/BBLym+PxcC16IBlF7KH9vP1BUYxA+Eg== -"@octokit/plugin-rest-endpoint-methods@4.13.5": - version "4.13.5" - resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.13.5.tgz#ad76285b82fe05fbb4adf2774a9c887f3534a880" - integrity sha512-kYKcWkFm4Ldk8bZai2RVEP1z97k1C/Ay2FN9FNTBg7JIyKoiiJjks4OtT6cuKeZX39tqa+C3J9xeYc6G+6g8uQ== +"@octokit/plugin-rest-endpoint-methods@5.0.1": + version "5.0.1" + resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.0.1.tgz#631b8d4edc6798b03489911252a25f2a4e58c594" + integrity sha512-vvWbPtPqLyIzJ7A4IPdTl+8IeuKAwMJ4LjvmqWOOdfSuqWQYZXq2CEd0hsnkidff2YfKlguzujHs/reBdAx8Sg== dependencies: - "@octokit/types" "^6.12.2" - deprecation "^2.3.1" - -"@octokit/plugin-rest-endpoint-methods@5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.0.0.tgz#cf2cdeb24ea829c31688216a5b165010b61f9a98" - integrity sha512-Jc7CLNUueIshXT+HWt6T+M0sySPjF32mSFQAK7UfAg8qGeRI6OM1GSBxDLwbXjkqy2NVdnqCedJcP1nC785JYg== - dependencies: - "@octokit/types" "^6.13.0" + "@octokit/types" "^6.13.1" deprecation "^2.3.1" "@octokit/request-error@^2.0.0", "@octokit/request-error@^2.0.5": @@ -4123,25 +4115,15 @@ node-fetch "^2.6.1" universal-user-agent "^6.0.0" -"@octokit/rest@^18.0.12", "@octokit/rest@^18.1.0": - version "18.3.5" - resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.3.5.tgz#a89903d46e0b4273bd3234674ec2777a651d68ab" - integrity sha512-ZPeRms3WhWxQBEvoIh0zzf8xdU2FX0Capa7+lTca8YHmRsO3QNJzf1H3PcuKKsfgp91/xVDRtX91sTe1kexlbw== +"@octokit/rest@^18.1.0", "@octokit/rest@^18.1.1", "@octokit/rest@^18.5.3": + version "18.5.3" + resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.5.3.tgz#6a2e6006a87ebbc34079c419258dd29ec9ff659d" + integrity sha512-KPAsUCr1DOdLVbZJgGNuE/QVLWEaVBpFQwDAz/2Cnya6uW2wJ/P5RVGk0itx7yyN1aGa8uXm2pri4umEqG1JBA== dependencies: "@octokit/core" "^3.2.3" "@octokit/plugin-paginate-rest" "^2.6.2" "@octokit/plugin-request-log" "^1.0.2" - "@octokit/plugin-rest-endpoint-methods" "4.13.5" - -"@octokit/rest@^18.1.1": - version "18.5.2" - resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.5.2.tgz#0369e554b7076e3749005147be94c661c7a5a74b" - integrity sha512-Kz03XYfKS0yYdi61BkL9/aJ0pP2A/WK5vF/syhu9/kY30J8He3P68hv9GRpn8bULFx2K0A9MEErn4v3QEdbZcw== - dependencies: - "@octokit/core" "^3.2.3" - "@octokit/plugin-paginate-rest" "^2.6.2" - "@octokit/plugin-request-log" "^1.0.2" - "@octokit/plugin-rest-endpoint-methods" "5.0.0" + "@octokit/plugin-rest-endpoint-methods" "5.0.1" "@octokit/types@^5.0.0", "@octokit/types@^5.0.1": version "5.5.0" @@ -4150,7 +4132,7 @@ dependencies: "@types/node" ">= 8" -"@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.0.3", "@octokit/types@^6.10.0", "@octokit/types@^6.12.2", "@octokit/types@^6.13.0", "@octokit/types@^6.7.1", "@octokit/types@^6.8.2": +"@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.0.3", "@octokit/types@^6.10.0", "@octokit/types@^6.12.2", "@octokit/types@^6.13.0", "@octokit/types@^6.13.1", "@octokit/types@^6.7.1", "@octokit/types@^6.8.2": version "6.14.2" resolved "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz#64c9457f38fb8522bdbba3c8cc814590a2d61bf5" integrity sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA== From 81c54d1f25255af82a4060d5d71ea61f7f51379d Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Mon, 3 May 2021 12:07:48 +0100 Subject: [PATCH 394/462] Fetch useRelatedEntities in batches Rather than making a request per relation, filter multiple relations in a single request. To avoid the query string getting very large, make multiple requests on bacthes of 100 relations. Signed-off-by: Will Sewell <willsewell@monzo.com> --- .changeset/friendly-readers-promise.md | 5 ++++ .../src/hooks/useRelatedEntities.ts | 30 ++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 .changeset/friendly-readers-promise.md diff --git a/.changeset/friendly-readers-promise.md b/.changeset/friendly-readers-promise.md new file mode 100644 index 0000000000..30607d5db2 --- /dev/null +++ b/.changeset/friendly-readers-promise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Fetch relations in batches in `useRelatedEntities` diff --git a/plugins/catalog-react/src/hooks/useRelatedEntities.ts b/plugins/catalog-react/src/hooks/useRelatedEntities.ts index baf6cf5fc7..15182d3c2f 100644 --- a/plugins/catalog-react/src/hooks/useRelatedEntities.ts +++ b/plugins/catalog-react/src/hooks/useRelatedEntities.ts @@ -18,6 +18,8 @@ import { useApi } from '@backstage/core'; import { useAsync } from 'react-use'; import { catalogApiRef } from '../api'; +const BATCH_SIZE = 100; + export function useRelatedEntities( entity: Entity, { type, kind }: { type?: string; kind?: string }, @@ -40,16 +42,28 @@ export function useRelatedEntities( return []; } - // TODO: This code could be more efficient if there was an endpoint in the - // backend that either returns the relations of entity (filtered by type) - // or if there is a way to perform a batch request by entity name. However, - // such an implementation would probably be better placed in the graphql API. + // Make requests in separate batches to limit query string size + // (there is a `filter` param for each relation) + const relationBatches = []; + for (let i = 0; i < relations.length; i += BATCH_SIZE) { + relationBatches.push(relations.slice(i, i + BATCH_SIZE)); + } + const results = await Promise.all( - relations?.map(r => catalogApi.getEntityByName(r.target)), + relationBatches.map(batch => { + return catalogApi.getEntities({ + filter: batch.map(({ target }) => { + return { + kind: target.kind, + 'metadata.name': target.name, + 'metadata.namespace': target.namespace, + }; + }), + }); + }), ); - // Skip entities that where not found, for example if a relation references - // an entity that doesn't exist. - return results.filter(e => e) as Entity[]; + + return results.map(r => r.items).flat(); }, [entity, type]); return { From f65adcde73a392ffae0fc58a1efeb25ef8a698d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= <freben@gmail.com> Date: Mon, 3 May 2021 13:25:12 +0200 Subject: [PATCH 395/462] Fix most of the yarn install transitive dependency warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/flat-keys-happen.md | 6 ++++++ packages/cli/package.json | 1 + packages/core/package.json | 1 + packages/storybook/package.json | 4 +++- yarn.lock | 25 +++++++++++++++---------- 5 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 .changeset/flat-keys-happen.md diff --git a/.changeset/flat-keys-happen.md b/.changeset/flat-keys-happen.md new file mode 100644 index 0000000000..ce01f86bcf --- /dev/null +++ b/.changeset/flat-keys-happen.md @@ -0,0 +1,6 @@ +--- +'@backstage/cli': patch +'@backstage/core': patch +--- + +Fix some transitive dependency warnings in yarn diff --git a/packages/cli/package.json b/packages/cli/package.json index 1110efefe6..46e99b762b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -86,6 +86,7 @@ "lodash": "^4.17.19", "mini-css-extract-plugin": "^0.9.0", "ora": "^5.3.0", + "postcss": "^8.1.0", "raw-loader": "^4.0.1", "react": "^16.0.0", "react-dev-utils": "^11.0.4", diff --git a/packages/core/package.json b/packages/core/package.json index 59391e122a..d2a8f96679 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -48,6 +48,7 @@ "d3-shape": "^2.0.0", "d3-zoom": "^2.0.0", "dagre": "^0.8.5", + "history": "^5.0.0", "immer": "^9.0.1", "lodash": "^4.17.15", "material-table": "^1.69.1", diff --git a/packages/storybook/package.json b/packages/storybook/package.json index 01aabac0de..4a4c1431c5 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -14,7 +14,9 @@ ] }, "dependencies": { - "@backstage/theme": "^0.2.0" + "@backstage/theme": "^0.2.0", + "react": "^16.12.0", + "react-dom": "^16.12.0" }, "devDependencies": { "@storybook/addon-actions": "^6.1.11", diff --git a/yarn.lock b/yarn.lock index 548c404f0f..d3f45a3efd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10002,6 +10002,11 @@ colorette@1.2.1, colorette@^1.2.1: resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + colors@^1.1.2, colors@^1.2.1: version "1.4.0" resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -19070,10 +19075,10 @@ nanoid@^2.1.0: resolved "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== -nanoid@^3.1.20: - version "3.1.20" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== +nanoid@^3.1.22: + version "3.1.22" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" + integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== nanomatch@^1.2.9: version "1.2.13" @@ -21295,13 +21300,13 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^ source-map "^0.6.1" supports-color "^6.1.0" -postcss@^8.0.2: - version "8.2.6" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe" - integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg== +postcss@^8.0.2, postcss@^8.1.0: + version "8.2.13" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.13.tgz#dbe043e26e3c068e45113b1ed6375d2d37e2129f" + integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ== dependencies: - colorette "^1.2.1" - nanoid "^3.1.20" + colorette "^1.2.2" + nanoid "^3.1.22" source-map "^0.6.1" postgres-array@~1.0.0: From e0bfd3d44888e89cae10bd423f0742f48be8dfc6 Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Wed, 21 Apr 2021 17:14:11 +0200 Subject: [PATCH 396/462] Refactor the runDockerContainer function to a ContainerRunner interface. Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- .changeset/bright-bags-hope.md | 56 +++++++ .changeset/eight-dingos-exist.md | 58 ++++++++ .changeset/few-games-collect.md | 61 ++++++++ .changeset/spicy-countries-hope.md | 27 ++++ .changeset/wild-stingrays-yawn.md | 115 +++++++++++++++ .../software-templates/installation.md | 15 +- .../writing-custom-actions.md | 7 +- docs/features/techdocs/getting-started.md | 11 +- .../src/util/ContainerRunner.ts | 31 ++++ ....test.ts => DockerContainerRunner.test.ts} | 31 ++-- .../src/util/DockerContainerRunner.ts | 117 +++++++++++++++ packages/backend-common/src/util/docker.ts | 137 ------------------ packages/backend-common/src/util/index.ts | 3 +- packages/backend/src/plugins/scaffolder.ts | 15 +- packages/backend/src/plugins/techdocs.ts | 10 +- .../backend/src/plugins/scaffolder.ts | 19 ++- .../packages/backend/src/plugins/techdocs.ts | 17 ++- packages/techdocs-common/package.json | 2 - .../src/stages/generate/generators.test.ts | 12 +- .../src/stages/generate/generators.ts | 12 +- .../src/stages/generate/techdocs.ts | 18 ++- .../src/stages/generate/types.ts | 3 - plugins/scaffolder-backend/package.json | 2 - .../actions/builtin/createBuiltinActions.ts | 13 +- .../builtin/fetch/cookiecutter.test.ts | 17 +-- .../actions/builtin/fetch/cookiecutter.ts | 13 +- .../src/scaffolder/jobs/processor.ts | 10 +- .../src/scaffolder/stages/legacy.ts | 11 +- .../stages/templater/cookiecutter.test.ts | 40 ++--- .../stages/templater/cookiecutter.ts | 22 ++- .../scaffolder/stages/templater/cra/index.ts | 18 ++- .../stages/templater/templaters.test.ts | 7 +- .../src/scaffolder/stages/templater/types.ts | 5 +- .../src/service/router.test.ts | 15 +- .../scaffolder-backend/src/service/router.ts | 6 - plugins/techdocs-backend/package.json | 2 +- .../src/DocsBuilder/builder.ts | 6 - .../techdocs-backend/src/service/router.ts | 4 - .../src/service/standaloneServer.ts | 31 ++-- 39 files changed, 652 insertions(+), 347 deletions(-) create mode 100644 .changeset/bright-bags-hope.md create mode 100644 .changeset/eight-dingos-exist.md create mode 100644 .changeset/few-games-collect.md create mode 100644 .changeset/spicy-countries-hope.md create mode 100644 .changeset/wild-stingrays-yawn.md create mode 100644 packages/backend-common/src/util/ContainerRunner.ts rename packages/backend-common/src/util/{docker.test.ts => DockerContainerRunner.test.ts} (89%) create mode 100644 packages/backend-common/src/util/DockerContainerRunner.ts delete mode 100644 packages/backend-common/src/util/docker.ts diff --git a/.changeset/bright-bags-hope.md b/.changeset/bright-bags-hope.md new file mode 100644 index 0000000000..88ef046fb7 --- /dev/null +++ b/.changeset/bright-bags-hope.md @@ -0,0 +1,56 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. +It also provides the `ContainerRunner` to the individual templaters instead of to the `createRouter` function. + +To apply this change to an existing backend application, add the following to `src/plugins/scaffolder.ts`: + +```diff +- import { SingleHostDiscovery } from '@backstage/backend-common'; ++ import { ++ DockerContainerRunner, ++ SingleHostDiscovery, ++ } from '@backstage/backend-common'; + + + export default async function createPlugin({ + logger, + config, + database, + reader, + }: PluginEnvironment): Promise<Router> { ++ const dockerClient = new Docker(); ++ const containerRunner = new DockerContainerRunner({ dockerClient }); + ++ const cookiecutterTemplater = new CookieCutter({ containerRunner }); +- const cookiecutterTemplater = new CookieCutter(); ++ const craTemplater = new CreateReactAppTemplater({ containerRunner }); +- const craTemplater = new CreateReactAppTemplater(); + const templaters = new Templaters(); + + templaters.register('cookiecutter', cookiecutterTemplater); + templaters.register('cra', craTemplater); + + const preparers = await Preparers.fromConfig(config, { logger }); + const publishers = await Publishers.fromConfig(config, { logger }); + +- const dockerClient = new Docker(); + + const discovery = SingleHostDiscovery.fromConfig(config); + const catalogClient = new CatalogClient({ discoveryApi: discovery }); + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, +- dockerClient, + database, + catalogClient, + reader, + }); + } +``` diff --git a/.changeset/eight-dingos-exist.md b/.changeset/eight-dingos-exist.md new file mode 100644 index 0000000000..da05523a15 --- /dev/null +++ b/.changeset/eight-dingos-exist.md @@ -0,0 +1,58 @@ +--- +'@backstage/backend-common': minor +--- + +Refactor the `runDockerContainer(…)` function to an interface-based api. +This gives the option to replace the docker runtime in the future. + +Packages and plugins that previously used the `dockerode` as argument should be migrated to use the new `ContainerRunner` interface instead. + +```diff + import { +- runDockerContainer, ++ ContainerRunner, + PluginEndpointDiscovery, + } from '@backstage/backend-common'; +- import Docker from 'dockerode'; + + type RouterOptions = { + // ... +- dockerClient: Docker, ++ containerRunner: ContainerRunner; + }; + + export async function createRouter({ + // ... +- dockerClient, ++ containerRunner, + }: RouterOptions): Promise<express.Router> { + // ... + ++ await containerRunner.runContainer({ +- await runDockerContainer({ + image: 'docker', + // ... +- dockerClient, + }); + + // ... + } +``` + +To keep the `dockerode` based runtime, use the `DockerContainerRunner` implementation: + +```diff ++ import { ++ ContainerRunner, ++ DockerContainerRunner ++ } from '@backstage/backend-common'; +- import { runDockerContainer } from '@backstage/backend-common'; + ++ const containerRunner: ContainerRUnner = new DockerContainerRunner({dockerClient}); ++ await containerRunner.runContainer({ +- await runDockerContainer({ + image: 'docker', + // ... +- dockerClient, + }); +``` diff --git a/.changeset/few-games-collect.md b/.changeset/few-games-collect.md new file mode 100644 index 0000000000..f6a27f66c7 --- /dev/null +++ b/.changeset/few-games-collect.md @@ -0,0 +1,61 @@ +--- +'@backstage/plugin-techdocs-backend': minor +--- + +Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. +It also provides the `ContainerRunner` to the generators instead of to the `createRouter` function. + +To apply this change to an existing backend application, add the following to `src/plugins/techdocs.ts`: + +```diff ++ import { DockerContainerRunner } from '@backstage/backend-common'; + + // ... + + export default async function createPlugin({ + logger, + config, + discovery, + reader, + }: PluginEnvironment): Promise<Router> { + // Preparers are responsible for fetching source files for documentation. + const preparers = await Preparers.fromConfig(config, { + logger, + reader, + }); + ++ // Docker client (conditionally) used by the generators, based on techdocs.generators config. ++ const dockerClient = new Docker(); ++ const containerRunner = new DockerContainerRunner({ dockerClient }); + + // Generators are used for generating documentation sites. + const generators = await Generators.fromConfig(config, { + logger, ++ containerRunner, + }); + + // Publisher is used for + // 1. Publishing generated files to storage + // 2. Fetching files from storage and passing them to TechDocs frontend. + const publisher = await Publisher.fromConfig(config, { + logger, + discovery, + }); + + // checks if the publisher is working and logs the result + await publisher.getReadiness(); + +- // Docker client (conditionally) used by the generators, based on techdocs.generators config. +- const dockerClient = new Docker(); + + return await createRouter({ + preparers, + generators, + publisher, +- dockerClient, + logger, + config, + discovery, + }); + } +``` diff --git a/.changeset/spicy-countries-hope.md b/.changeset/spicy-countries-hope.md new file mode 100644 index 0000000000..574a117f6e --- /dev/null +++ b/.changeset/spicy-countries-hope.md @@ -0,0 +1,27 @@ +--- +'@backstage/techdocs-common': minor +--- + +Migrate the package to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. +It also no longer provides the `ContainerRunner` as an input to the `GeneratorBase#run(…)` function, but expects it as a constructor parameter instead. + +If you use the `TechdocsGenerator` you need to update the usage: + +```diff ++ const containerRunner = new DockerContainerRunner({ dockerClient }); + +- const generator = new TechdocsGenerator(logger, config); ++ const techdocsGenerator = new TechdocsGenerator({ ++ logger, ++ containerRunner, ++ config, ++ }); + + await this.generator.run({ + inputDir: preparedDir, + outputDir, +- dockerClient: this.dockerClient, + parsedLocationAnnotation, + etag: newEtag, + }); +``` diff --git a/.changeset/wild-stingrays-yawn.md b/.changeset/wild-stingrays-yawn.md new file mode 100644 index 0000000000..6d8538c025 --- /dev/null +++ b/.changeset/wild-stingrays-yawn.md @@ -0,0 +1,115 @@ +--- +'@backstage/create-app': patch +--- + +The `scaffolder-backend` and `techdocs-backend` plugins have been updated. +In order to update, you need to apply the following changes to your existing backend application: + +`@backstage/plugin-techdocs-backend`: + +```diff +// packages/backend/src/plugin/techdocs.ts + ++ import { DockerContainerRunner } from '@backstage/backend-common'; + + // ... + + export default async function createPlugin({ + logger, + config, + discovery, + reader, + }: PluginEnvironment): Promise<Router> { + // Preparers are responsible for fetching source files for documentation. + const preparers = await Preparers.fromConfig(config, { + logger, + reader, + }); + ++ // Docker client (conditionally) used by the generators, based on techdocs.generators config. ++ const dockerClient = new Docker(); ++ const containerRunner = new DockerContainerRunner({ dockerClient }); + + // Generators are used for generating documentation sites. + const generators = await Generators.fromConfig(config, { + logger, ++ containerRunner, + }); + + // Publisher is used for + // 1. Publishing generated files to storage + // 2. Fetching files from storage and passing them to TechDocs frontend. + const publisher = await Publisher.fromConfig(config, { + logger, + discovery, + }); + + // checks if the publisher is working and logs the result + await publisher.getReadiness(); + +- // Docker client (conditionally) used by the generators, based on techdocs.generators config. +- const dockerClient = new Docker(); + + return await createRouter({ + preparers, + generators, + publisher, +- dockerClient, + logger, + config, + discovery, + }); + } +``` + +`@backstage/plugin-scaffolder-backend`: + +```diff +// packages/backend/src/plugin/scaffolder.ts + +- import { SingleHostDiscovery } from '@backstage/backend-common'; ++ import { ++ DockerContainerRunner, ++ SingleHostDiscovery, ++ } from '@backstage/backend-common'; + + + export default async function createPlugin({ + logger, + config, + database, + reader, + }: PluginEnvironment): Promise<Router> { ++ const dockerClient = new Docker(); ++ const containerRunner = new DockerContainerRunner({ dockerClient }); + ++ const cookiecutterTemplater = new CookieCutter({ containerRunner }); +- const cookiecutterTemplater = new CookieCutter(); ++ const craTemplater = new CreateReactAppTemplater({ containerRunner }); +- const craTemplater = new CreateReactAppTemplater(); + const templaters = new Templaters(); + + templaters.register('cookiecutter', cookiecutterTemplater); + templaters.register('cra', craTemplater); + + const preparers = await Preparers.fromConfig(config, { logger }); + const publishers = await Publishers.fromConfig(config, { logger }); + +- const dockerClient = new Docker(); + + const discovery = SingleHostDiscovery.fromConfig(config); + const catalogClient = new CatalogClient({ discoveryApi: discovery }); + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, +- dockerClient, + database, + catalogClient, + reader, + }); + } +``` diff --git a/docs/features/software-templates/installation.md b/docs/features/software-templates/installation.md index 5acaf0e499..ad7e6d1062 100644 --- a/docs/features/software-templates/installation.md +++ b/docs/features/software-templates/installation.md @@ -70,6 +70,10 @@ creating a file called `packages/backend/src/plugins/scaffolder.ts` with the following contents to get you up and running quickly. ```ts +import { + DockerContainerRunner, + SingleHostDiscovery, +} from '@backstage/backend-common'; import { CookieCutter, createRouter, @@ -78,7 +82,6 @@ import { CreateReactAppTemplater, Templaters, } from '@backstage/plugin-scaffolder-backend'; -import { SingleHostDiscovery } from '@backstage/backend-common'; import type { PluginEnvironment } from '../types'; import Docker from 'dockerode'; import { CatalogClient } from '@backstage/catalog-client'; @@ -89,8 +92,11 @@ export default async function createPlugin({ database, reader, }: PluginEnvironment) { - const cookiecutterTemplater = new CookieCutter(); - const craTemplater = new CreateReactAppTemplater(); + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + + const cookiecutterTemplater = new CookieCutter({ containerRunner }); + const craTemplater = new CreateReactAppTemplater({ containerRunner }); const templaters = new Templaters(); templaters.register('cookiecutter', cookiecutterTemplater); @@ -99,8 +105,6 @@ export default async function createPlugin({ const preparers = await Preparers.fromConfig(config, { logger }); const publishers = await Publishers.fromConfig(config, { logger }); - const dockerClient = new Docker(); - const discovery = SingleHostDiscovery.fromConfig(config); const catalogClient = new CatalogClient({ discoveryApi: discovery }); @@ -110,7 +114,6 @@ export default async function createPlugin({ publishers, logger, config, - dockerClient, database, catalogClient, reader, diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index ff145ee5af..90dd603c8f 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -106,7 +106,6 @@ return await createRouter({ publishers, logger, config, - dockerClient, database, catalogClient, reader, @@ -124,7 +123,6 @@ return await createRouter({ publishers, logger, config, - dockerClient, database, catalogClient, reader, @@ -136,11 +134,9 @@ return await createRouter({ want to have those as well as your new one, you'll need to do the following: ```ts - -import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend`; +import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend'; const builtInActions = createBuiltinActions({ - dockerClient, integrations, catalogClient, templaters, @@ -155,7 +151,6 @@ return await createRouter({ publishers, logger, config, - dockerClient, database, catalogClient, reader, diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index 520db2245c..51f07d5cde 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -63,6 +63,7 @@ Create a file called `techdocs.ts` inside `packages/backend/src/plugins/` and add the following ```typescript +import { DockerContainerRunner } from '@backstage/backend-common'; import { createRouter, Generators, @@ -84,9 +85,14 @@ export default async function createPlugin({ reader, }); + // Docker client (conditionally) used by the generators, based on techdocs.generators config. + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + // Generators are used for generating documentation sites. const generators = await Generators.fromConfig(config, { logger, + containerRunner, }); // Publisher is used for @@ -97,14 +103,13 @@ export default async function createPlugin({ discovery, }); - // Docker client (conditionally) used by the generators, based on techdocs.generators config. - const dockerClient = new Docker(); + // checks if the publisher is working and logs the result + await publisher.getReadiness(); return await createRouter({ preparers, generators, publisher, - dockerClient, logger, config, discovery, diff --git a/packages/backend-common/src/util/ContainerRunner.ts b/packages/backend-common/src/util/ContainerRunner.ts new file mode 100644 index 0000000000..7740e384e4 --- /dev/null +++ b/packages/backend-common/src/util/ContainerRunner.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Writable } from 'stream'; + +export type RunContainerOptions = { + imageName: string; + command?: string | string[]; + args: string[]; + logStream?: Writable; + mountDirs?: Record<string, string>; + workingDir?: string; + envVars?: Record<string, string>; +}; + +export interface ContainerRunner { + runContainer(opts: RunContainerOptions): Promise<void>; +} diff --git a/packages/backend-common/src/util/docker.test.ts b/packages/backend-common/src/util/DockerContainerRunner.test.ts similarity index 89% rename from packages/backend-common/src/util/docker.test.ts rename to packages/backend-common/src/util/DockerContainerRunner.test.ts index 2ec14494da..942264af84 100644 --- a/packages/backend-common/src/util/docker.test.ts +++ b/packages/backend-common/src/util/DockerContainerRunner.test.ts @@ -13,17 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import Docker from 'dockerode'; import mockFs from 'mock-fs'; import os from 'os'; import path from 'path'; import Stream, { PassThrough } from 'stream'; -import { runDockerContainer, UserOptions } from './docker'; +import { ContainerRunner } from './ContainerRunner'; +import { DockerContainerRunner, UserOptions } from './DockerContainerRunner'; const mockDocker = new Docker() as jest.Mocked<Docker>; const rootDir = os.platform() === 'win32' ? 'C:\\rootDir' : '/rootDir'; -describe('runDockerContainer', () => { +describe('DockerContainerRunner', () => { + let containerTaskApi: ContainerRunner; + beforeEach(() => { mockFs({ [rootDir]: { @@ -49,6 +53,8 @@ describe('runDockerContainer', () => { jest .spyOn(mockDocker, 'ping') .mockResolvedValue(Buffer.from('OK', 'utf-8')); + + containerTaskApi = new DockerContainerRunner({ dockerClient: mockDocker }); }); afterEach(() => { @@ -66,10 +72,9 @@ describe('runDockerContainer', () => { const envVarsArray = ['HOME=/tmp', 'LOG_LEVEL=debug']; it('should pull the docker container', async () => { - await runDockerContainer({ + await containerTaskApi.runContainer({ imageName, args, - dockerClient: mockDocker, }); expect(mockDocker.pull).toHaveBeenCalledWith( @@ -82,13 +87,12 @@ describe('runDockerContainer', () => { }); it('should call the dockerClient run command with the correct arguments passed through', async () => { - await runDockerContainer({ + await containerTaskApi.runContainer({ imageName, args, mountDirs, envVars, workingDir, - dockerClient: mockDocker, }); expect(mockDocker.run).toHaveBeenCalledWith( @@ -113,20 +117,18 @@ describe('runDockerContainer', () => { }); it('should ping docker to test availability', async () => { - await runDockerContainer({ + await containerTaskApi.runContainer({ imageName, args, - dockerClient: mockDocker, }); expect(mockDocker.ping).toHaveBeenCalled(); }); it('should pass through the user and group id from the host machine and set the home dir', async () => { - await runDockerContainer({ + await containerTaskApi.runContainer({ imageName, args, - dockerClient: mockDocker, }); const userOptions: UserOptions = {}; @@ -153,10 +155,9 @@ describe('runDockerContainer', () => { ]); await expect( - runDockerContainer({ + containerTaskApi.runContainer({ imageName, args, - dockerClient: mockDocker, }), ).rejects.toThrow(/Something went wrong with docker/); }); @@ -172,10 +173,9 @@ describe('runDockerContainer', () => { it('should throw with a descriptive error message including the docker error message', async () => { await expect( - runDockerContainer({ + containerTaskApi.runContainer({ imageName, args, - dockerClient: mockDocker, }), ).rejects.toThrow(new RegExp(`.+: ${dockerError}`)); }); @@ -183,11 +183,10 @@ describe('runDockerContainer', () => { it('should pass through the log stream to the docker client', async () => { const logStream = new PassThrough(); - await runDockerContainer({ + await containerTaskApi.runContainer({ imageName, args, logStream, - dockerClient: mockDocker, }); expect(mockDocker.run).toHaveBeenCalledWith( diff --git a/packages/backend-common/src/util/DockerContainerRunner.ts b/packages/backend-common/src/util/DockerContainerRunner.ts new file mode 100644 index 0000000000..a96ca1351b --- /dev/null +++ b/packages/backend-common/src/util/DockerContainerRunner.ts @@ -0,0 +1,117 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Docker from 'dockerode'; +import fs from 'fs-extra'; +import { PassThrough } from 'stream'; +import { ContainerRunner, RunContainerOptions } from './ContainerRunner'; + +export type UserOptions = { + User?: string; +}; + +export class DockerContainerRunner implements ContainerRunner { + private readonly dockerClient: Docker; + + constructor({ dockerClient }: { dockerClient: Docker }) { + this.dockerClient = dockerClient; + } + + async runContainer({ + imageName, + command, + args, + logStream = new PassThrough(), + mountDirs = {}, + workingDir, + envVars = {}, + }: RunContainerOptions) { + // Show a better error message when Docker is unavailable. + try { + await this.dockerClient.ping(); + } catch (e) { + throw new Error( + `This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with: ${e.message}`, + ); + } + + await new Promise<void>((resolve, reject) => { + this.dockerClient.pull(imageName, {}, (err, stream) => { + if (err) return reject(err); + stream.pipe(logStream, { end: false }); + stream.on('end', () => resolve()); + stream.on('error', (error: Error) => reject(error)); + return undefined; + }); + }); + + const userOptions: UserOptions = {}; + if (process.getuid && process.getgid) { + // Files that are created inside the Docker container will be owned by + // root on the host system on non Mac systems, because of reasons. Mainly the fact that + // volume sharing is done using NFS on Mac and actual mounts in Linux world. + // So we set the user in the container as the same user and group id as the host. + // On Windows we don't have process.getuid nor process.getgid + userOptions.User = `${process.getuid()}:${process.getgid()}`; + } + + // Initialize volumes to mount based on mountDirs map + const Volumes: { [T: string]: object } = {}; + for (const containerDir of Object.values(mountDirs)) { + Volumes[containerDir] = {}; + } + + // Create bind volumes + const Binds: string[] = []; + for (const [hostDir, containerDir] of Object.entries(mountDirs)) { + // Need to use realpath here as Docker mounting does not like + // symlinks for binding volumes + const realHostDir = await fs.realpath(hostDir); + Binds.push(`${realHostDir}:${containerDir}`); + } + + // Create docker environment variables array + const Env = []; + for (const [key, value] of Object.entries(envVars)) { + Env.push(`${key}=${value}`); + } + + const [ + { Error: error, StatusCode: statusCode }, + ] = await this.dockerClient.run(imageName, args, logStream, { + Volumes, + HostConfig: { + Binds, + }, + ...(workingDir ? { WorkingDir: workingDir } : {}), + Entrypoint: command, + Env, + ...userOptions, + } as Docker.ContainerCreateOptions); + + if (error) { + throw new Error( + `Docker failed to run with the following error message: ${error}`, + ); + } + + if (statusCode !== 0) { + throw new Error( + `Docker container returned a non-zero exit code (${statusCode})`, + ); + } + } +} diff --git a/packages/backend-common/src/util/docker.ts b/packages/backend-common/src/util/docker.ts deleted file mode 100644 index 356d645465..0000000000 --- a/packages/backend-common/src/util/docker.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Docker from 'dockerode'; -import fs from 'fs-extra'; -import { PassThrough, Writable } from 'stream'; - -export type UserOptions = { - User?: string; -}; - -export type RunDockerContainerOptions = { - imageName: string; - args: string[]; - logStream?: Writable; - dockerClient: Docker; - mountDirs?: Record<string, string>; - workingDir?: string; - envVars?: Record<string, string>; - createOptions?: Docker.ContainerCreateOptions; -}; - -/** - * - * @param options the options object - * @param options.imageName the image to run - * @param options.args the arguments to pass the container - * @param options.logStream the log streamer to capture log messages - * @param options.dockerClient the dockerClient to use - * @param options.mountDirs A map of host directories to mount on the container. - * Object Key: Path on host machine, Value: Path on Docker container - * @param options.workingDir Working dir in the container - * @param options.envVars Environment variables to set in the container. e.g. {'HOME': '/tmp'} - */ -export const runDockerContainer = async ({ - imageName, - args, - logStream = new PassThrough(), - dockerClient, - mountDirs = {}, - workingDir, - envVars = {}, - createOptions = {}, -}: RunDockerContainerOptions) => { - // Show a better error message when Docker is unavailable. - try { - await dockerClient.ping(); - } catch (e) { - throw new Error( - `This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with: ${e.message}`, - ); - } - - await new Promise<void>((resolve, reject) => { - dockerClient.pull(imageName, {}, (err, stream) => { - if (err) return reject(err); - stream.pipe(logStream, { end: false }); - stream.on('end', () => resolve()); - stream.on('error', (error: Error) => reject(error)); - return undefined; - }); - }); - - const userOptions: UserOptions = {}; - if (process.getuid && process.getgid) { - // Files that are created inside the Docker container will be owned by - // root on the host system on non Mac systems, because of reasons. Mainly the fact that - // volume sharing is done using NFS on Mac and actual mounts in Linux world. - // So we set the user in the container as the same user and group id as the host. - // On Windows we don't have process.getuid nor process.getgid - userOptions.User = `${process.getuid()}:${process.getgid()}`; - } - - // Initialize volumes to mount based on mountDirs map - const Volumes: { [T: string]: object } = {}; - for (const containerDir of Object.values(mountDirs)) { - Volumes[containerDir] = {}; - } - - // Create bind volumes - const Binds: string[] = []; - for (const [hostDir, containerDir] of Object.entries(mountDirs)) { - // Need to use realpath here as Docker mounting does not like - // symlinks for binding volumes - const realHostDir = await fs.realpath(hostDir); - Binds.push(`${realHostDir}:${containerDir}`); - } - - // Create docker environment variables array - const Env = []; - for (const [key, value] of Object.entries(envVars)) { - Env.push(`${key}=${value}`); - } - - const [{ Error: error, StatusCode: statusCode }] = await dockerClient.run( - imageName, - args, - logStream, - { - Volumes, - HostConfig: { - Binds, - }, - ...(workingDir ? { WorkingDir: workingDir } : {}), - Env, - ...userOptions, - ...createOptions, - }, - ); - - if (error) { - throw new Error( - `Docker failed to run with the following error message: ${error}`, - ); - } - - if (statusCode !== 0) { - throw new Error( - `Docker container returned a non-zero exit code (${statusCode})`, - ); - } - - return { error, statusCode }; -}; diff --git a/packages/backend-common/src/util/index.ts b/packages/backend-common/src/util/index.ts index 04715824b4..85c5436a2e 100644 --- a/packages/backend-common/src/util/index.ts +++ b/packages/backend-common/src/util/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ -export { runDockerContainer } from './docker'; +export type { ContainerRunner, RunContainerOptions } from './ContainerRunner'; +export { DockerContainerRunner } from './DockerContainerRunner'; diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index fca3f79270..9c7c3c12f3 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { SingleHostDiscovery } from '@backstage/backend-common'; +import { + DockerContainerRunner, + SingleHostDiscovery, +} from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { CookieCutter, @@ -34,8 +37,11 @@ export default async function createPlugin({ database, reader, }: PluginEnvironment): Promise<Router> { - const cookiecutterTemplater = new CookieCutter(); - const craTemplater = new CreateReactAppTemplater(); + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + + const cookiecutterTemplater = new CookieCutter({ containerRunner }); + const craTemplater = new CreateReactAppTemplater({ containerRunner }); const templaters = new Templaters(); templaters.register('cookiecutter', cookiecutterTemplater); @@ -44,8 +50,6 @@ export default async function createPlugin({ const preparers = await Preparers.fromConfig(config, { logger }); const publishers = await Publishers.fromConfig(config, { logger }); - const dockerClient = new Docker(); - const discovery = SingleHostDiscovery.fromConfig(config); const catalogClient = new CatalogClient({ discoveryApi: discovery }); @@ -55,7 +59,6 @@ export default async function createPlugin({ publishers, logger, config, - dockerClient, database, catalogClient, reader, diff --git a/packages/backend/src/plugins/techdocs.ts b/packages/backend/src/plugins/techdocs.ts index d0387cd15d..dbdc455e09 100644 --- a/packages/backend/src/plugins/techdocs.ts +++ b/packages/backend/src/plugins/techdocs.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { DockerContainerRunner } from '@backstage/backend-common'; import { createRouter, Generators, @@ -35,9 +36,14 @@ export default async function createPlugin({ reader, }); + // Docker client (conditionally) used by the generators, based on techdocs.generators config. + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + // Generators are used for generating documentation sites. const generators = await Generators.fromConfig(config, { logger, + containerRunner, }); // Publisher is used for @@ -51,14 +57,10 @@ export default async function createPlugin({ // checks if the publisher is working and logs the result await publisher.getReadiness(); - // Docker client (conditionally) used by the generators, based on techdocs.generators config. - const dockerClient = new Docker(); - return await createRouter({ preparers, generators, publisher, - dockerClient, logger, config, discovery, diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts index a3416c5080..333ffa11df 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts @@ -1,4 +1,7 @@ -import { SingleHostDiscovery } from '@backstage/backend-common'; +import { + DockerContainerRunner, + SingleHostDiscovery, +} from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { CookieCutter, @@ -6,7 +9,7 @@ import { createRouter, Preparers, Publishers, - Templaters + Templaters, } from '@backstage/plugin-scaffolder-backend'; import Docker from 'dockerode'; import { Router } from 'express'; @@ -18,8 +21,11 @@ export default async function createPlugin({ database, reader, }: PluginEnvironment): Promise<Router> { - const cookiecutterTemplater = new CookieCutter(); - const craTemplater = new CreateReactAppTemplater(); + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + + const cookiecutterTemplater = new CookieCutter({ containerRunner }); + const craTemplater = new CreateReactAppTemplater({ containerRunner }); const templaters = new Templaters(); templaters.register('cookiecutter', cookiecutterTemplater); @@ -28,8 +34,6 @@ export default async function createPlugin({ const preparers = await Preparers.fromConfig(config, { logger }); const publishers = await Publishers.fromConfig(config, { logger }); - const dockerClient = new Docker(); - const discovery = SingleHostDiscovery.fromConfig(config); const catalogClient = new CatalogClient({ discoveryApi: discovery }); @@ -39,9 +43,8 @@ export default async function createPlugin({ publishers, logger, config, - dockerClient, database, catalogClient, - reader + reader, }); } diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts index 231a7e7fd7..906d86d4a2 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts @@ -1,9 +1,9 @@ +import { DockerContainerRunner } from '@backstage/backend-common'; import { createRouter, - - Generators, Preparers, - - Publisher + Generators, + Preparers, + Publisher, } from '@backstage/plugin-techdocs-backend'; import Docker from 'dockerode'; import { Router } from 'express'; @@ -21,9 +21,14 @@ export default async function createPlugin({ reader, }); + // Docker client (conditionally) used by the generators, based on techdocs.generators config. + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + // Generators are used for generating documentation sites. const generators = await Generators.fromConfig(config, { logger, + containerRunner, }); // Publisher is used for @@ -37,14 +42,10 @@ export default async function createPlugin({ // checks if the publisher is working and logs the result await publisher.getReadiness(); - // Docker client (conditionally) used by the generators, based on techdocs.generators config. - const dockerClient = new Docker(); - return await createRouter({ preparers, generators, publisher, - dockerClient, logger, config, discovery, diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index e749b33919..1ac46163af 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -44,11 +44,9 @@ "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@google-cloud/storage": "^5.6.0", - "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "aws-sdk": "^2.840.0", "cross-fetch": "^3.0.6", - "dockerode": "^3.2.1", "express": "^4.17.1", "fs-extra": "^9.0.1", "git-url-parse": "^11.4.4", diff --git a/packages/techdocs-common/src/stages/generate/generators.test.ts b/packages/techdocs-common/src/stages/generate/generators.test.ts index 032aafbf49..610a3e8ad5 100644 --- a/packages/techdocs-common/src/stages/generate/generators.test.ts +++ b/packages/techdocs-common/src/stages/generate/generators.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; +import { ContainerRunner, getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { Generators } from './generators'; import { TechdocsGenerator } from './techdocs'; @@ -30,6 +30,10 @@ const mockEntity = { }; describe('generators', () => { + const containerRunner: jest.Mocked<ContainerRunner> = { + runContainer: jest.fn(), + }; + it('should return error if no generator is registered', async () => { const generators = new Generators(); @@ -40,7 +44,11 @@ describe('generators', () => { it('should return correct registered generator', async () => { const generators = new Generators(); - const techdocs = new TechdocsGenerator(logger, new ConfigReader({})); + const techdocs = new TechdocsGenerator({ + logger, + containerRunner, + config: new ConfigReader({}), + }); generators.register('techdocs', techdocs); diff --git a/packages/techdocs-common/src/stages/generate/generators.ts b/packages/techdocs-common/src/stages/generate/generators.ts index 57c4017b15..4a3af72931 100644 --- a/packages/techdocs-common/src/stages/generate/generators.ts +++ b/packages/techdocs-common/src/stages/generate/generators.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { ContainerRunner } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { Logger } from 'winston'; @@ -30,11 +31,18 @@ export class Generators implements GeneratorBuilder { static async fromConfig( config: Config, - { logger }: { logger: Logger }, + { + logger, + containerRunner, + }: { logger: Logger; containerRunner: ContainerRunner }, ): Promise<GeneratorBuilder> { const generators = new Generators(); - const techdocsGenerator = new TechdocsGenerator(logger, config); + const techdocsGenerator = new TechdocsGenerator({ + logger, + containerRunner, + config, + }); generators.register('techdocs', techdocsGenerator); return generators; diff --git a/packages/techdocs-common/src/stages/generate/techdocs.ts b/packages/techdocs-common/src/stages/generate/techdocs.ts index 0dfa952a17..1a6b0a581c 100644 --- a/packages/techdocs-common/src/stages/generate/techdocs.ts +++ b/packages/techdocs-common/src/stages/generate/techdocs.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { runDockerContainer } from '@backstage/backend-common'; +import { ContainerRunner } from '@backstage/backend-common'; import { Config } from '@backstage/config'; import path from 'path'; import { PassThrough } from 'stream'; @@ -48,20 +48,29 @@ const createStream = (): [string[], PassThrough] => { export class TechdocsGenerator implements GeneratorBase { private readonly logger: Logger; + private readonly containerRunner: ContainerRunner; private readonly options: TechdocsGeneratorOptions; - constructor(logger: Logger, config: Config) { + constructor({ + logger, + containerRunner, + config, + }: { + logger: Logger; + containerRunner: ContainerRunner; + config: Config; + }) { this.logger = logger; this.options = { runGeneratorIn: config.getOptionalString('techdocs.generators.techdocs') ?? 'docker', }; + this.containerRunner = containerRunner; } public async run({ inputDir, outputDir, - dockerClient, parsedLocationAnnotation, etag, }: GeneratorRunOptions): Promise<void> { @@ -100,7 +109,7 @@ export class TechdocsGenerator implements GeneratorBase { ); break; case 'docker': - await runDockerContainer({ + await this.containerRunner.runContainer({ imageName: 'spotify/techdocs', args: ['build', '-d', '/output'], logStream, @@ -109,7 +118,6 @@ export class TechdocsGenerator implements GeneratorBase { // Set the home directory inside the container as something that applications can // write to, otherwise they will just fail trying to write to / envVars: { HOME: '/tmp' }, - dockerClient, }); this.logger.info( `Successfully generated docs from ${inputDir} into ${outputDir} using techdocs-container`, diff --git a/packages/techdocs-common/src/stages/generate/types.ts b/packages/techdocs-common/src/stages/generate/types.ts index fda41ed442..249b809592 100644 --- a/packages/techdocs-common/src/stages/generate/types.ts +++ b/packages/techdocs-common/src/stages/generate/types.ts @@ -14,7 +14,6 @@ * limitations under the License. */ import { Entity } from '@backstage/catalog-model'; -import Docker from 'dockerode'; import { Writable } from 'stream'; import { ParsedLocationAnnotation } from '../../helpers'; @@ -23,7 +22,6 @@ import { ParsedLocationAnnotation } from '../../helpers'; * * @param {string} inputDir The directory of the uncompiled documentation, with the values from the frontend * @param {string} outputDir Directory to store generated docs in. Usually - a newly created temporary directory. - * @param {Docker} dockerClient A docker client to run any generator on top of your directory * @param {ParsedLocationAnnotation} parsedLocationAnnotation backstage.io/techdocs-ref annotation of an entity * @param {string} etag A unique identifier for the prepared tree e.g. commit SHA. If provided it will be stored in techdocs_metadata.json. * @param {Writable} [logStream] A dedicated log stream @@ -31,7 +29,6 @@ import { ParsedLocationAnnotation } from '../../helpers'; export type GeneratorRunOptions = { inputDir: string; outputDir: string; - dockerClient: Docker; parsedLocationAnnotation?: ParsedLocationAnnotation; etag?: string; logStream?: Writable; diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index bbeeecceb0..61dc4e2cbf 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -38,7 +38,6 @@ "@gitbeaker/core": "^28.0.2", "@gitbeaker/node": "^28.0.2", "@octokit/rest": "^18.5.3", - "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "@types/git-url-parse": "^9.0.0", "azure-devops-node-api": "^10.1.1", @@ -46,7 +45,6 @@ "compression": "^1.7.4", "cors": "^2.8.5", "cross-fetch": "^3.0.6", - "dockerode": "^3.2.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", "fs-extra": "^9.0.0", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index 2d4b8fb4c5..0209fc50dd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -17,6 +17,7 @@ import { UrlReader } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; import { ScmIntegrations } from '@backstage/integration'; +import { TemplaterBuilder } from '../../stages'; import { createCatalogRegisterAction } from './catalog'; import { createFetchCookiecutterAction, createFetchPlainAction } from './fetch'; import { @@ -26,23 +27,14 @@ import { createPublishGithubPullRequestAction, createPublishGitlabAction, } from './publish'; -import Docker from 'dockerode'; -import { TemplaterBuilder } from '../../stages'; export const createBuiltinActions = (options: { reader: UrlReader; integrations: ScmIntegrations; - dockerClient: Docker; catalogClient: CatalogApi; templaters: TemplaterBuilder; }) => { - const { - reader, - integrations, - dockerClient, - templaters, - catalogClient, - } = options; + const { reader, integrations, templaters, catalogClient } = options; return [ createFetchPlainAction({ @@ -52,7 +44,6 @@ export const createBuiltinActions = (options: { createFetchCookiecutterAction({ reader, integrations, - dockerClient, templaters, }), createPublishGithubAction({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts index 628107155d..a0f94816bd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts @@ -15,16 +15,16 @@ */ jest.mock('./helpers'); +import { getVoidLogger, UrlReader } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import mock from 'mock-fs'; import os from 'os'; import { resolve as resolvePath } from 'path'; -import { createFetchCookiecutterAction } from './cookiecutter'; -import { ScmIntegrations } from '@backstage/integration'; -import { ConfigReader } from '@backstage/config'; -import { Templaters } from '../../../stages/templater'; import { PassThrough } from 'stream'; -import { getVoidLogger, UrlReader } from '@backstage/backend-common'; +import { Templaters } from '../../../stages/templater'; +import { createFetchCookiecutterAction } from './cookiecutter'; import { fetchContents } from './helpers'; -import mock from 'mock-fs'; describe('fetch:cookiecutter', () => { const integrations = ScmIntegrations.fromConfig( @@ -40,7 +40,6 @@ describe('fetch:cookiecutter', () => { const templaters = new Templaters(); const cookiecutterTemplater = { run: jest.fn() }; - const mockDockerClient = {}; const mockTmpDir = os.tmpdir(); const mockContext = { input: { @@ -67,7 +66,6 @@ describe('fetch:cookiecutter', () => { const action = createFetchCookiecutterAction({ integrations, templaters, - dockerClient: mockDockerClient as any, reader: mockReader, }); @@ -102,7 +100,6 @@ describe('fetch:cookiecutter', () => { expect(cookiecutterTemplater.run).toHaveBeenCalledWith({ workspacePath: mockTmpDir, - dockerClient: mockDockerClient, logStream: mockContext.logStream, values: mockContext.input.values, }); @@ -123,7 +120,6 @@ describe('fetch:cookiecutter', () => { expect(cookiecutterTemplater.run).toHaveBeenCalledWith({ workspacePath: mockTmpDir, - dockerClient: mockDockerClient, logStream: mockContext.logStream, values: { ...mockContext.input.values, @@ -166,7 +162,6 @@ describe('fetch:cookiecutter', () => { const newAction = createFetchCookiecutterAction({ integrations, templaters: templatersWithoutCookiecutter, - dockerClient: mockDockerClient as any, reader: mockReader, }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts index fca791c7bd..83b373c3de 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.ts @@ -14,24 +14,22 @@ * limitations under the License. */ -import fs from 'fs-extra'; -import { resolve as resolvePath } from 'path'; -import Docker from 'dockerode'; import { UrlReader } from '@backstage/backend-common'; +import { JsonObject } from '@backstage/config'; import { InputError } from '@backstage/errors'; import { ScmIntegrations } from '@backstage/integration'; -import { JsonObject } from '@backstage/config'; +import fs from 'fs-extra'; +import { resolve as resolvePath } from 'path'; import { TemplaterBuilder, TemplaterValues } from '../../../stages/templater'; -import { fetchContents } from './helpers'; import { createTemplateAction } from '../../createTemplateAction'; +import { fetchContents } from './helpers'; export function createFetchCookiecutterAction(options: { - dockerClient: Docker; reader: UrlReader; integrations: ScmIntegrations; templaters: TemplaterBuilder; }) { - const { dockerClient, reader, templaters, integrations } = options; + const { reader, templaters, integrations } = options; return createTemplateAction<{ url: string; @@ -134,7 +132,6 @@ export function createFetchCookiecutterAction(options: { // Will execute the template in ./template and put the result in ./result await cookiecutter.run({ workspacePath: workDir, - dockerClient, logStream: ctx.logStream, values, }); diff --git a/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts b/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts index 425fc07946..005df09fec 100644 --- a/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts +++ b/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts @@ -19,20 +19,12 @@ import fs from 'fs-extra'; import { Processor, Job, StageContext, StageInput } from './types'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import * as uuid from 'uuid'; -import Docker from 'dockerode'; import path from 'path'; -import { TemplaterValues, TemplaterBase } from '../stages/templater'; -import { PreparerBuilder } from '../stages/prepare'; +import { TemplaterValues } from '../stages/templater'; import { makeLogStream } from './logger'; import { Logger } from 'winston'; import { Config } from '@backstage/config'; -export type JobProcessorArguments = { - preparers: PreparerBuilder; - templater: TemplaterBase; - dockerClient: Docker; -}; - export type JobAndDirectoryTuple = { job: Job; directory: string; diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts b/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts index c7c52fa320..bb7ab40d57 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts @@ -14,21 +14,19 @@ * limitations under the License. */ -import { FilePreparer, PreparerBuilder } from './prepare'; -import Docker from 'dockerode'; -import { TemplaterBuilder, TemplaterValues } from './templater'; -import { PublisherBuilder } from './publish'; import { createTemplateAction } from '../actions'; +import { FilePreparer, PreparerBuilder } from './prepare'; +import { PublisherBuilder } from './publish'; +import { TemplaterBuilder, TemplaterValues } from './templater'; type Options = { - dockerClient: Docker; preparers: PreparerBuilder; templaters: TemplaterBuilder; publishers: PublisherBuilder; }; export function createLegacyActions(options: Options) { - const { dockerClient, preparers, templaters, publishers } = options; + const { preparers, templaters, publishers } = options; return [ createTemplateAction({ @@ -55,7 +53,6 @@ export function createLegacyActions(options: Options) { const templater = templaters.get(ctx.input.templater as string); await templater.run({ workspacePath: ctx.workspacePath, - dockerClient, logStream: ctx.logStream, values: ctx.input.values as TemplaterValues, }); diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts index 7806f089ff..28e2800e55 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts @@ -14,16 +14,14 @@ * limitations under the License. */ -const runDockerContainer = jest.fn(); const runCommand = jest.fn(); const commandExists = jest.fn(); jest.mock('./helpers', () => ({ runCommand })); -jest.mock('@backstage/backend-common', () => ({ runDockerContainer })); jest.mock('command-exists-promise', () => commandExists); jest.mock('fs-extra'); -import Docker from 'dockerode'; +import { ContainerRunner } from '@backstage/backend-common'; import fs from 'fs-extra'; import parseGitUrl from 'git-url-parse'; import path from 'path'; @@ -31,7 +29,9 @@ import { PassThrough } from 'stream'; import { CookieCutter } from './cookiecutter'; describe('CookieCutter Templater', () => { - const mockDocker = {} as Docker; + const containerRunner: jest.Mocked<ContainerRunner> = { + runContainer: jest.fn(), + }; beforeEach(() => { jest.clearAllMocks(); @@ -50,11 +50,10 @@ describe('CookieCutter Templater', () => { jest.spyOn(fs, 'readdir').mockResolvedValueOnce(['newthing'] as any); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await templater.run({ workspacePath: 'tempdir', values, - dockerClient: mockDocker, }); expect(fs.ensureDir).toBeCalledWith(path.join('tempdir', 'intermediate')); @@ -83,11 +82,10 @@ describe('CookieCutter Templater', () => { }, }; - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await templater.run({ workspacePath: 'tempdir', values, - dockerClient: mockDocker, }); expect(fs.writeJSON).toBeCalledWith( @@ -115,12 +113,11 @@ describe('CookieCutter Templater', () => { }, }; - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await expect( templater.run({ workspacePath: 'tempdir', values, - dockerClient: mockDocker, }), ).rejects.toThrow('BAM'); }); @@ -140,14 +137,13 @@ describe('CookieCutter Templater', () => { .spyOn(fs, 'realpath') .mockImplementation(x => Promise.resolve(x.toString())); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await templater.run({ workspacePath: 'tempdir', values, - dockerClient: mockDocker, }); - expect(runDockerContainer).toHaveBeenCalledWith({ + expect(containerRunner.runContainer).toHaveBeenCalledWith({ imageName: 'spotify/backstage-cookiecutter', args: [ 'cookiecutter', @@ -164,7 +160,6 @@ describe('CookieCutter Templater', () => { }, workingDir: '/input', logStream: undefined, - dockerClient: mockDocker, }); }); @@ -177,14 +172,13 @@ describe('CookieCutter Templater', () => { jest.spyOn(fs, 'readdir').mockResolvedValueOnce(['newthing'] as any); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await templater.run({ workspacePath: 'tempdir', values, - dockerClient: mockDocker, }); - expect(runDockerContainer).toHaveBeenCalledWith( + expect(containerRunner.runContainer).toHaveBeenCalledWith( expect.objectContaining({ imageName: 'foo/cookiecutter-image-with-extensions', }), @@ -205,15 +199,14 @@ describe('CookieCutter Templater', () => { jest.spyOn(fs, 'readdir').mockResolvedValueOnce(['newthing'] as any); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await templater.run({ workspacePath: 'tempdir', values, logStream: stream, - dockerClient: mockDocker, }); - expect(runDockerContainer).toHaveBeenCalledWith({ + expect(containerRunner.runContainer).toHaveBeenCalledWith({ imageName: 'spotify/backstage-cookiecutter', args: [ 'cookiecutter', @@ -230,7 +223,6 @@ describe('CookieCutter Templater', () => { }, workingDir: '/input', logStream: stream, - dockerClient: mockDocker, }); }); @@ -250,12 +242,11 @@ describe('CookieCutter Templater', () => { jest.spyOn(fs, 'readdir').mockResolvedValueOnce(['newthing'] as any); commandExists.mockImplementationOnce(() => () => true); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await templater.run({ workspacePath: 'tempdir', values, logStream: stream, - dockerClient: mockDocker, }); expect(runCommand).toHaveBeenCalledWith({ @@ -280,7 +271,7 @@ describe('CookieCutter Templater', () => { .spyOn(fs, 'readdir') .mockImplementationOnce(() => Promise.resolve([])); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); await expect( templater.run({ workspacePath: 'tempdir', @@ -292,7 +283,6 @@ describe('CookieCutter Templater', () => { }, }, logStream: stream, - dockerClient: mockDocker, }), ).rejects.toThrow(/No data generated by cookiecutter/); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts index e60c5efb4d..8819a90d63 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { runDockerContainer } from '@backstage/backend-common'; +import { ContainerRunner } from '@backstage/backend-common'; import { JsonValue } from '@backstage/config'; import fs from 'fs-extra'; import path from 'path'; @@ -24,6 +24,12 @@ import { TemplaterBase, TemplaterRunOptions } from './types'; const commandExists = require('command-exists-promise'); export class CookieCutter implements TemplaterBase { + private readonly containerRunner: ContainerRunner; + + constructor({ containerRunner }: { containerRunner: ContainerRunner }) { + this.containerRunner = containerRunner; + } + private async fetchTemplateCookieCutter( directory: string, ): Promise<Record<string, JsonValue>> { @@ -40,7 +46,6 @@ export class CookieCutter implements TemplaterBase { public async run({ workspacePath, - dockerClient, values, logStream, }: TemplaterRunOptions): Promise<void> { @@ -74,23 +79,16 @@ export class CookieCutter implements TemplaterBase { logStream, }); } else { - await runDockerContainer({ + await this.containerRunner.runContainer({ imageName: imageName || 'spotify/backstage-cookiecutter', - args: [ - 'cookiecutter', - '--no-input', - '-o', - '/output', - '/input', - '--verbose', - ], + command: 'cookiecutter', + args: ['--no-input', '-o', '/output', '/input', '--verbose'], mountDirs, workingDir: '/input', // Set the home directory inside the container as something that applications can // write to, otherwise they will just fail trying to write to / envVars: { HOME: '/tmp' }, logStream, - dockerClient, }); } diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts index 3d03b002c0..36716b6c99 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { runDockerContainer } from '@backstage/backend-common'; +import { ContainerRunner } from '@backstage/backend-common'; import fs from 'fs-extra'; import path from 'path'; import * as yaml from 'yaml'; @@ -25,11 +25,16 @@ import { TemplaterBase, TemplaterRunOptions } from '../types'; const GITHUB_ACTIONS_ANNOTATION = 'github.com/project-slug'; export class CreateReactAppTemplater implements TemplaterBase { + private readonly containerRunner: ContainerRunner; + + constructor({ containerRunner }: { containerRunner: ContainerRunner }) { + this.containerRunner = containerRunner; + } + public async run({ workspacePath, values, logStream, - dockerClient, }: TemplaterRunOptions): Promise<void> { const { component_id: componentName, @@ -46,23 +51,20 @@ export class CreateReactAppTemplater implements TemplaterBase { [intermediateDir]: '/result', }; - await runDockerContainer({ + await this.containerRunner.runContainer({ imageName: 'node:lts-alpine', + command: ['npx'], args: [ 'create-react-app', componentName as string, withTypescript ? ' --template typescript' : '', ], mountDirs, + workingDir: '/result', logStream: logStream, - dockerClient: dockerClient, // Set the home directory inside the container as something that applications can // write to, otherwise they will just fail trying to write to / envVars: { HOME: '/tmp' }, - createOptions: { - Entrypoint: ['npx'], - WorkingDir: '/result', - }, }); // if cookiecutter was successful, intermediateDir will contain diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/templaters.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/templaters.test.ts index d390bfbd9d..713ec514c0 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/templaters.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/templaters.test.ts @@ -14,10 +14,15 @@ * limitations under the License. */ +import { ContainerRunner } from '@backstage/backend-common'; import { CookieCutter } from './cookiecutter'; import { Templaters } from './templaters'; describe('Templaters', () => { + const containerRunner: jest.Mocked<ContainerRunner> = { + runContainer: jest.fn(), + }; + it('should throw an error when the templater is not registered', () => { const templaters = new Templaters(); @@ -29,7 +34,7 @@ describe('Templaters', () => { }); it('should return the correct templater when the templater matches', () => { const templaters = new Templaters(); - const templater = new CookieCutter(); + const templater = new CookieCutter({ containerRunner }); templaters.register('cookiecutter', templater); diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/types.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/types.ts index fa14788d22..c5fe454e33 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/types.ts @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import type { Writable } from 'stream'; -import Docker from 'dockerode'; + import gitUrlParse from 'git-url-parse'; +import type { Writable } from 'stream'; /** * Currently the required template values. The owner @@ -48,7 +48,6 @@ export type TemplaterRunOptions = { workspacePath: string; values: TemplaterValues; logStream?: Writable; - dockerClient: Docker; }; export type TemplaterBase = { diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index bb52edaaea..e8aa76a63a 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -29,20 +29,17 @@ jest.doMock('fs-extra', () => ({ })); import { - SingleConnectionDatabaseManager, - PluginDatabaseManager, getVoidLogger, + PluginDatabaseManager, + SingleConnectionDatabaseManager, UrlReaders, } from '@backstage/backend-common'; +import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import express from 'express'; import request from 'supertest'; +import { Preparers, Publishers, Templaters } from '../scaffolder'; import { createRouter } from './router'; -import { Templaters, Preparers, Publishers } from '../scaffolder'; -import Docker from 'dockerode'; -import { CatalogApi } from '@backstage/catalog-client'; - -jest.mock('dockerode'); const createCatalogClient = (templates: any[] = []) => ({ @@ -115,7 +112,6 @@ describe('createRouter - working directory', () => { templaters: new Templaters(), publishers: new Publishers(), config: new ConfigReader(workDirConfig('/path')), - dockerClient: new Docker(), database: createDatabase(), catalogClient: createCatalogClient([template]), reader: mockUrlReader, @@ -130,7 +126,6 @@ describe('createRouter - working directory', () => { templaters: new Templaters(), publishers: new Publishers(), config: new ConfigReader(workDirConfig('/path')), - dockerClient: new Docker(), database: createDatabase(), catalogClient: createCatalogClient([template]), reader: mockUrlReader, @@ -160,7 +155,6 @@ describe('createRouter - working directory', () => { templaters: new Templaters(), publishers: new Publishers(), config: new ConfigReader({}), - dockerClient: new Docker(), database: createDatabase(), catalogClient: createCatalogClient([template]), reader: mockUrlReader, @@ -234,7 +228,6 @@ describe('createRouter', () => { templaters: new Templaters(), publishers: new Publishers(), config: new ConfigReader({}), - dockerClient: new Docker(), database: createDatabase(), catalogClient: createCatalogClient([template]), reader: mockUrlReader, diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 35a57da6a2..5e0790526e 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -15,7 +15,6 @@ */ import { Config } from '@backstage/config'; -import Docker from 'dockerode'; import express from 'express'; import { resolve as resolvePath, dirname } from 'path'; import Router from 'express-promise-router'; @@ -62,7 +61,6 @@ export interface RouterOptions { logger: Logger; config: Config; reader: UrlReader; - dockerClient: Docker; database: PluginDatabaseManager; catalogClient: CatalogApi; actions?: TemplateAction<any>[]; @@ -96,7 +94,6 @@ export async function createRouter( logger: parentLogger, config, reader, - dockerClient, database, catalogClient, actions, @@ -124,13 +121,11 @@ export async function createRouter( ? actions : [ ...createLegacyActions({ - dockerClient, preparers, publishers, templaters, }), ...createBuiltinActions({ - dockerClient, integrations, catalogClient, templaters, @@ -243,7 +238,6 @@ export async function createRouter( const templater = templaters.get(ctx.entity.spec.templater); await templater.run({ workspacePath: ctx.workspacePath, - dockerClient, logStream: ctx.logStream, values: ctx.values, }); diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 53e0865430..03d8e9e2ab 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -35,7 +35,6 @@ "@backstage/config": "^0.1.4", "@backstage/errors": "^0.1.1", "@backstage/techdocs-common": "^0.5.0", - "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "dockerode": "^3.2.1", @@ -47,6 +46,7 @@ }, "devDependencies": { "@backstage/cli": "^0.6.8", + "@types/dockerode": "^3.2.1", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/techdocs-backend/src/DocsBuilder/builder.ts b/plugins/techdocs-backend/src/DocsBuilder/builder.ts index 9dd53f159e..d1aa1e08be 100644 --- a/plugins/techdocs-backend/src/DocsBuilder/builder.ts +++ b/plugins/techdocs-backend/src/DocsBuilder/builder.ts @@ -28,7 +28,6 @@ import { PublisherBase, UrlPreparer, } from '@backstage/techdocs-common'; -import Docker from 'dockerode'; import fs from 'fs-extra'; import os from 'os'; import path from 'path'; @@ -41,7 +40,6 @@ type DocsBuilderArguments = { publisher: PublisherBase; entity: Entity; logger: Logger; - dockerClient: Docker; }; export class DocsBuilder { @@ -50,7 +48,6 @@ export class DocsBuilder { private publisher: PublisherBase; private entity: Entity; private logger: Logger; - private dockerClient: Docker; constructor({ preparers, @@ -58,14 +55,12 @@ export class DocsBuilder { publisher, entity, logger, - dockerClient, }: DocsBuilderArguments) { this.preparer = preparers.get(entity); this.generator = generators.get(entity); this.publisher = publisher; this.entity = entity; this.logger = logger; - this.dockerClient = dockerClient; } public async build(): Promise<void> { @@ -157,7 +152,6 @@ export class DocsBuilder { await this.generator.run({ inputDir: preparedDir, outputDir, - dockerClient: this.dockerClient, parsedLocationAnnotation, etag: newEtag, }); diff --git a/plugins/techdocs-backend/src/service/router.ts b/plugins/techdocs-backend/src/service/router.ts index 121ddddef5..9f383ea31d 100644 --- a/plugins/techdocs-backend/src/service/router.ts +++ b/plugins/techdocs-backend/src/service/router.ts @@ -24,7 +24,6 @@ import { PublisherBase, } from '@backstage/techdocs-common'; import fetch from 'cross-fetch'; -import Docker from 'dockerode'; import express from 'express'; import Router from 'express-promise-router'; import { Knex } from 'knex'; @@ -40,7 +39,6 @@ type RouterOptions = { discovery: PluginEndpointDiscovery; database?: Knex; // TODO: Make database required when we're implementing database stuff. config: Config; - dockerClient: Docker; }; export async function createRouter({ @@ -48,7 +46,6 @@ export async function createRouter({ generators, publisher, config, - dockerClient, logger, discovery, }: RouterOptions): Promise<express.Router> { @@ -165,7 +162,6 @@ export async function createRouter({ preparers, generators, publisher, - dockerClient, logger, entity, }); diff --git a/plugins/techdocs-backend/src/service/standaloneServer.ts b/plugins/techdocs-backend/src/service/standaloneServer.ts index 0fd23a4f7d..af03987870 100644 --- a/plugins/techdocs-backend/src/service/standaloneServer.ts +++ b/plugins/techdocs-backend/src/service/standaloneServer.ts @@ -16,21 +16,22 @@ import { createServiceBuilder, + DockerContainerRunner, SingleHostDiscovery, UrlReader, } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { + DirectoryPreparer, + Generators, + Preparers, + Publisher, + TechdocsGenerator, +} from '@backstage/techdocs-common'; +import Docker from 'dockerode'; import { Server } from 'http'; import { Logger } from 'winston'; import { createRouter } from './router'; -import Docker from 'dockerode'; -import { - Preparers, - DirectoryPreparer, - Generators, - TechdocsGenerator, - Publisher, -} from '@backstage/techdocs-common'; -import { ConfigReader } from '@backstage/config'; export interface ServerOptions { port: number; @@ -65,21 +66,25 @@ export async function startStandaloneServer( ); preparers.register('dir', directoryPreparer); + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + const generators = new Generators(); - const techdocsGenerator = new TechdocsGenerator(logger, config); + const techdocsGenerator = new TechdocsGenerator({ + logger, + containerRunner, + config, + }); generators.register('techdocs', techdocsGenerator); const publisher = await Publisher.fromConfig(config, { logger, discovery }); - const dockerClient = new Docker(); - logger.debug('Starting application server...'); const router = await createRouter({ preparers, generators, logger, publisher, - dockerClient, config, discovery, }); From e763b7b156c0b67ff7c7faa1d55e444414553b4d Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Mon, 3 May 2021 13:36:22 +0100 Subject: [PATCH 397/462] Reduce batch size to 20 Signed-off-by: Will Sewell <willsewell@monzo.com> --- plugins/catalog-react/src/hooks/useRelatedEntities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-react/src/hooks/useRelatedEntities.ts b/plugins/catalog-react/src/hooks/useRelatedEntities.ts index 15182d3c2f..5649a90f52 100644 --- a/plugins/catalog-react/src/hooks/useRelatedEntities.ts +++ b/plugins/catalog-react/src/hooks/useRelatedEntities.ts @@ -18,7 +18,7 @@ import { useApi } from '@backstage/core'; import { useAsync } from 'react-use'; import { catalogApiRef } from '../api'; -const BATCH_SIZE = 100; +const BATCH_SIZE = 20; export function useRelatedEntities( entity: Entity, From 1d7a40101ac1f44514093ee1683fd71d488c972d Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Mon, 3 May 2021 16:33:05 +0200 Subject: [PATCH 398/462] Update the API reports of backend-common and techdocs-common Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- packages/backend-common/api-report.md | 28 ++++++++++++++++++++++---- packages/techdocs-common/api-report.md | 13 ++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 9969d0ea27..f0cb066dc0 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -65,6 +65,12 @@ export class BitbucketUrlReader implements UrlReader { // @public (undocumented) export const coloredFormat: winston.Logform.Format; +// @public (undocumented) +export interface ContainerRunner { + // (undocumented) + runContainer(opts: RunContainerOptions): Promise<void>; +} + // @public @deprecated export const createDatabase: typeof createDatabaseClient; @@ -80,6 +86,15 @@ export function createServiceBuilder(_module: NodeModule): ServiceBuilderImpl; // @public (undocumented) export function createStatusCheckRouter(options: StatusCheckRouterOptions): Promise<express.Router>; +// @public (undocumented) +export class DockerContainerRunner implements ContainerRunner { + constructor({ dockerClient }: { + dockerClient: Docker; + }); + // (undocumented) + runContainer({ imageName, command, args, logStream, mountDirs, workingDir, envVars, }: RunContainerOptions): Promise<void>; +} + // @public export function ensureDatabaseExists(dbConfig: Config, ...databases: Array<string>): Promise<void>; @@ -255,10 +270,15 @@ export function requestLoggingHandler(logger?: Logger): RequestHandler; export function resolvePackagePath(name: string, ...paths: string[]): string; // @public (undocumented) -export const runDockerContainer: ({ imageName, args, logStream, dockerClient, mountDirs, workingDir, envVars, createOptions, }: RunDockerContainerOptions) => Promise<{ - error: any; - statusCode: any; -}>; +export type RunContainerOptions = { + imageName: string; + command?: string | string[]; + args: string[]; + logStream?: Writable; + mountDirs?: Record<string, string>; + workingDir?: string; + envVars?: Record<string, string>; +}; // @public export type SearchResponse = { diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index a53fb9e681..3fff030eee 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -6,7 +6,7 @@ import { AzureIntegrationConfig } from '@backstage/integration'; import { Config } from '@backstage/config'; -import Docker from 'dockerode'; +import { ContainerRunner } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; import express from 'express'; @@ -50,8 +50,9 @@ export type GeneratorBuilder = { // @public (undocumented) export class Generators implements GeneratorBuilder { // (undocumented) - static fromConfig(config: Config, { logger }: { + static fromConfig(config: Config, { logger, containerRunner, }: { logger: Logger; + containerRunner: ContainerRunner; }): Promise<GeneratorBuilder>; // (undocumented) get(entity: Entity): GeneratorBase; @@ -151,9 +152,13 @@ export type RemoteProtocol = 'url' | 'dir' | 'github' | 'gitlab' | 'file' | 'azu // @public (undocumented) export class TechdocsGenerator implements GeneratorBase { - constructor(logger: Logger, config: Config); + constructor({ logger, containerRunner, config, }: { + logger: Logger; + containerRunner: ContainerRunner; + config: Config; + }); // (undocumented) - run({ inputDir, outputDir, dockerClient, parsedLocationAnnotation, etag, }: GeneratorRunOptions): Promise<void>; + run({ inputDir, outputDir, parsedLocationAnnotation, etag, }: GeneratorRunOptions): Promise<void>; } // @public From 33c21766a9b2b80ba02f550be58b7d60a6205119 Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Mon, 3 May 2021 15:54:37 +0100 Subject: [PATCH 399/462] Add lodash to catalog-react Signed-off-by: Will Sewell <willsewell@monzo.com> --- plugins/catalog-react/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 91201a49a1..57a9479a3c 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -33,6 +33,7 @@ "@backstage/core": "^0.7.3", "@material-ui/core": "^4.11.0", "@types/react": "^16.9", + "lodash": "^4.17.15", "react": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", From cf3faccd846835da5883b66687750b4666b40ea0 Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Mon, 3 May 2021 15:58:33 +0100 Subject: [PATCH 400/462] Use lodash `chunk` to create batches Signed-off-by: Will Sewell <willsewell@monzo.com> --- plugins/catalog-react/src/hooks/useRelatedEntities.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-react/src/hooks/useRelatedEntities.ts b/plugins/catalog-react/src/hooks/useRelatedEntities.ts index 5649a90f52..25d96626d7 100644 --- a/plugins/catalog-react/src/hooks/useRelatedEntities.ts +++ b/plugins/catalog-react/src/hooks/useRelatedEntities.ts @@ -15,6 +15,7 @@ */ import { Entity } from '@backstage/catalog-model'; import { useApi } from '@backstage/core'; +import { chunk } from 'lodash'; import { useAsync } from 'react-use'; import { catalogApiRef } from '../api'; @@ -44,10 +45,7 @@ export function useRelatedEntities( // Make requests in separate batches to limit query string size // (there is a `filter` param for each relation) - const relationBatches = []; - for (let i = 0; i < relations.length; i += BATCH_SIZE) { - relationBatches.push(relations.slice(i, i + BATCH_SIZE)); - } + const relationBatches = chunk(relations, BATCH_SIZE); const results = await Promise.all( relationBatches.map(batch => { From f852f7381c625a9f025d7102d334322ee9568f51 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Mon, 3 May 2021 17:23:14 +0200 Subject: [PATCH 401/462] Revert "Add support for json schema to API docs" Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/six-mayflies-peel.md | 5 - packages/catalog-model/examples/all-apis.yaml | 1 - .../examples/apis/config-schema-api.yaml | 11 - plugins/api-docs/README.md | 1 - plugins/api-docs/dev/index.tsx | 15 - .../api-docs/dev/jsonschema-example-api.yaml | 32 - plugins/api-docs/package.json | 3 - .../ApiDefinitionCard/ApiDefinitionWidget.tsx | 9 - .../JsonSchemaDefinitionWidget.test.tsx | 61 - .../JsonSchemaDefinitionWidget.tsx | 50 - .../JsonSchemaDefinitionWidget/index.ts | 17 - plugins/api-docs/src/components/index.ts | 1 - yarn.lock | 1038 +---------------- 13 files changed, 6 insertions(+), 1238 deletions(-) delete mode 100644 .changeset/six-mayflies-peel.md delete mode 100644 packages/catalog-model/examples/apis/config-schema-api.yaml delete mode 100644 plugins/api-docs/dev/jsonschema-example-api.yaml delete mode 100644 plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx delete mode 100644 plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx delete mode 100644 plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts diff --git a/.changeset/six-mayflies-peel.md b/.changeset/six-mayflies-peel.md deleted file mode 100644 index 9d022bca0a..0000000000 --- a/.changeset/six-mayflies-peel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Add support for displaying JSON schemas. diff --git a/packages/catalog-model/examples/all-apis.yaml b/packages/catalog-model/examples/all-apis.yaml index 8ec9203b28..e23f1b3656 100644 --- a/packages/catalog-model/examples/all-apis.yaml +++ b/packages/catalog-model/examples/all-apis.yaml @@ -5,7 +5,6 @@ metadata: description: A collection of all Backstage example APIs spec: targets: - - ./apis/config-schema-api.yaml - ./apis/hello-world-api.yaml - ./apis/petstore-api.yaml - ./apis/spotify-api.yaml diff --git a/packages/catalog-model/examples/apis/config-schema-api.yaml b/packages/catalog-model/examples/apis/config-schema-api.yaml deleted file mode 100644 index 4bd8976614..0000000000 --- a/packages/catalog-model/examples/apis/config-schema-api.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: API -metadata: - name: config-schema - description: A Backstage config schemas. -spec: - type: jsonschema - lifecycle: production - owner: team-a - definition: - $text: https://github.com/backstage/backstage/blob/master/plugins/config-schema/dev/example-schema.json diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md index 1a05256704..60d8986d9b 100644 --- a/plugins/api-docs/README.md +++ b/plugins/api-docs/README.md @@ -15,7 +15,6 @@ Right now, the following API formats are supported: - [OpenAPI](https://swagger.io/specification/) 2 & 3 - [AsyncAPI](https://www.asyncapi.com/docs/specifications/latest/) - [GraphQL](https://graphql.org/learn/schema/) -- [JSON Schema](https://json-schema.org/) Other formats are displayed as plain text, but this can easily be extended. diff --git a/plugins/api-docs/dev/index.tsx b/plugins/api-docs/dev/index.tsx index d51d3a714c..fbfab37f5b 100644 --- a/plugins/api-docs/dev/index.tsx +++ b/plugins/api-docs/dev/index.tsx @@ -27,7 +27,6 @@ import { } from '../src'; import asyncapiApiEntity from './asyncapi-example-api.yaml'; import graphqlApiEntity from './graphql-example-api.yaml'; -import jsonschemaApiEntity from './jsonschema-example-api.yaml'; import openapiApiEntity from './openapi-example-api.yaml'; import otherApiEntity from './other-example-api.yaml'; @@ -42,7 +41,6 @@ createDevApp() items: [ openapiApiEntity, asyncapiApiEntity, - jsonschemaApiEntity, graphqlApiEntity, otherApiEntity, ], @@ -89,19 +87,6 @@ createDevApp() </Page> ), }) - .addPage({ - title: 'JSON Schema', - element: ( - <Page themeId="home"> - <Header title="JSON Schema" /> - <Content> - <EntityProvider entity={(jsonschemaApiEntity as any) as Entity}> - <EntityApiDefinitionCard /> - </EntityProvider> - </Content> - </Page> - ), - }) .addPage({ title: 'GraphQL', element: ( diff --git a/plugins/api-docs/dev/jsonschema-example-api.yaml b/plugins/api-docs/dev/jsonschema-example-api.yaml deleted file mode 100644 index a34b4f9a49..0000000000 --- a/plugins/api-docs/dev/jsonschema-example-api.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: API -metadata: - name: persons - description: Person dataset -spec: - type: jsonschema - lifecycle: experimental - owner: team-c - # From https://json-schema.org/learn/miscellaneous-examples.html - definition: | - { - "$id": "https://example.com/person.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Person", - "type": "object", - "properties": { - "firstName": { - "type": "string", - "description": "The person's first name." - }, - "lastName": { - "type": "string", - "description": "The person's last name." - }, - "age": { - "description": "Age in years which must be equal to or greater than zero.", - "type": "integer", - "minimum": 0 - } - } - } diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index be5d5186d2..5c9f9ca7ee 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -38,9 +38,6 @@ "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", - "@stoplight/json-schema-viewer": "^4.0.0-beta.16", - "@stoplight/mosaic": "^1.0.0-beta.46", - "@stoplight/reporter": "^1.10.0", "@types/react": "^16.9", "graphiql": "^1.0.0-alpha.10", "graphql": "^15.3.0", diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx index fc23c338ee..360404af40 100644 --- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx @@ -16,7 +16,6 @@ import React from 'react'; import { AsyncApiDefinitionWidget } from '../AsyncApiDefinitionWidget'; import { GraphQlDefinitionWidget } from '../GraphQlDefinitionWidget'; -import { JsonSchemaDefinitionWidget } from '../JsonSchemaDefinitionWidget'; import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget'; export type ApiDefinitionWidget = { @@ -52,13 +51,5 @@ export function defaultDefinitionWidgets(): ApiDefinitionWidget[] { <GraphQlDefinitionWidget definition={definition} /> ), }, - { - type: 'jsonschema', - title: 'JSON Schema', - rawLanguage: 'json', - component: definition => ( - <JsonSchemaDefinitionWidget definition={definition} /> - ), - }, ]; } diff --git a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx deleted file mode 100644 index b4077e6ea2..0000000000 --- a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.test.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { renderInTestApp } from '@backstage/test-utils'; -import React from 'react'; -import { JsonSchemaDefinitionWidget } from './JsonSchemaDefinitionWidget'; - -describe('<JsonSchemaDefinitionWidget />', () => { - it('renders json schema', async () => { - // From https://json-schema.org/learn/miscellaneous-examples.html - const definition = ` -{ - "$id": "https://example.com/person.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Person", - "type": "object", - "properties": { - "firstName": { - "type": "string", - "description": "The person's first name." - }, - "lastName": { - "type": "string", - "description": "The person's last name." - }, - "age": { - "description": "Age in years which must be equal to or greater than zero.", - "type": "integer", - "minimum": 0 - } - } -} - `; - const { getByText } = await renderInTestApp( - <JsonSchemaDefinitionWidget definition={definition} />, - ); - - expect(getByText(/lastName/i)).toBeInTheDocument(); - expect(getByText(/The person's last name./i)).toBeInTheDocument(); - }); - - it('renders error if definition is missing', async () => { - const { getByText } = await renderInTestApp( - <JsonSchemaDefinitionWidget definition="{}" />, - ); - expect(getByText(/No schema defined/i)).toBeInTheDocument(); - }); -}); diff --git a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx deleted file mode 100644 index ea8ac652c8..0000000000 --- a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/JsonSchemaDefinitionWidget.tsx +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useTheme } from '@material-ui/core'; -import { JsonSchemaViewer } from '@stoplight/json-schema-viewer'; -import { injectStyles, useThemeStore } from '@stoplight/mosaic'; -import React, { useMemo } from 'react'; -import { useEffectOnce } from 'react-use'; - -injectStyles(); - -type Props = { - definition: any; -}; - -export const JsonSchemaDefinitionWidget = ({ definition }: Props) => { - const schema = useMemo(() => JSON.parse(definition), [definition]); - const theme = useTheme(); - const themeStore = useThemeStore(); - - useEffectOnce(() => { - themeStore.setColor('background', theme.palette.background.paper); - themeStore.setColor('text', theme.palette.text.primary); - themeStore.setColor('primary', theme.palette.primary.main); - themeStore.setColor('success', theme.palette.success.main); - themeStore.setColor('warning', theme.palette.warning.main); - themeStore.setColor('danger', theme.palette.error.main); - themeStore.setMode(theme.palette.type); - }); - return ( - <JsonSchemaViewer - schema={schema} - emptyText="No schema defined" - defaultExpandedDepth={5} - /> - ); -}; diff --git a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts b/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts deleted file mode 100644 index 47d2619ec2..0000000000 --- a/plugins/api-docs/src/components/JsonSchemaDefinitionWidget/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { JsonSchemaDefinitionWidget } from './JsonSchemaDefinitionWidget'; diff --git a/plugins/api-docs/src/components/index.ts b/plugins/api-docs/src/components/index.ts index afac37dc31..cfd985f47c 100644 --- a/plugins/api-docs/src/components/index.ts +++ b/plugins/api-docs/src/components/index.ts @@ -20,4 +20,3 @@ export * from './AsyncApiDefinitionWidget'; export * from './ComponentsCards'; export * from './OpenApiDefinitionWidget'; export * from './PlainApiDefinitionWidget'; -export * from './JsonSchemaDefinitionWidget'; diff --git a/yarn.lock b/yarn.lock index 7a58a86325..8cb2ddd221 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,24 +2,6 @@ # yarn lockfile v1 -"@amplitude/types@^1.5.4": - version "1.5.4" - resolved "https://registry.npmjs.org/@amplitude/types/-/types-1.5.4.tgz#7fcbcbfb321d794b6367596cd950a92c752431d1" - integrity sha512-+e+wqlO5E4lNTM19lATf+lJldV+VD2RGzrDEy45cPEtfpXxHJUHwhfOKZkKg/zlx+YAubcpNhWLm2NSPpHUs9A== - -"@amplitude/ua-parser-js@0.7.24": - version "0.7.24" - resolved "https://registry.npmjs.org/@amplitude/ua-parser-js/-/ua-parser-js-0.7.24.tgz#2ce605af7d2c38d4a01313fb2385df55fbbd69aa" - integrity sha512-VbQuJymJ20WEw0HtI2np7EdC3NJGUWi8+Xdbc7uk8WfMIF308T0howpzkQ3JFMN7ejnrcSM/OyNGveeE3TP3TA== - -"@amplitude/utils@^1.0.5": - version "1.5.4" - resolved "https://registry.npmjs.org/@amplitude/utils/-/utils-1.5.4.tgz#457e847d751522ac8dd910037667d780ef501642" - integrity sha512-VAd/ibhwBBeL8pKqCz8tjCnSx8epOvUa+Je6sA3AB4R8855xl+bdrDjYwMmOWOILvEH3Pltq2jVJCE2thBoFdQ== - dependencies: - "@amplitude/types" "^1.5.4" - tslib "^1.9.3" - "@apidevtools/json-schema-ref-parser@^9.0.6": version "9.0.6" resolved "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz#5d9000a3ac1fd25404da886da6b266adcd99cf1c" @@ -1641,13 +1623,6 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.13.17", "@babel/runtime@^7.6.2": - version "7.13.17" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec" - integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -2111,32 +2086,6 @@ dependencies: yaml-ast-parser "0.0.43" -"@fortawesome/fontawesome-common-types@^0.2.35": - version "0.2.35" - resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz#01dd3d054da07a00b764d78748df20daf2b317e9" - integrity sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw== - -"@fortawesome/fontawesome-svg-core@^1.2.35": - version "1.2.35" - resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz#85aea8c25645fcec88d35f2eb1045c38d3e65cff" - integrity sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg== - dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.35" - -"@fortawesome/free-solid-svg-icons@^5.15.2", "@fortawesome/free-solid-svg-icons@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz#52eebe354f60dc77e0bde934ffc5c75ffd04f9d8" - integrity sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q== - dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.35" - -"@fortawesome/react-fontawesome@^0.1.14": - version "0.1.14" - resolved "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz#bf28875c3935b69ce2dc620e1060b217a47f64ca" - integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA== - dependencies: - prop-types "^15.7.2" - "@gitbeaker/core@^28.0.2", "@gitbeaker/core@^28.2.0": version "28.2.0" resolved "https://registry.npmjs.org/@gitbeaker/core/-/core-28.2.0.tgz#87e6f789faf55d726f75d05e470020e4bbb8e08c" @@ -2793,21 +2742,6 @@ resolved "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== -"@internationalized/message@3.0.0-alpha.0": - version "3.0.0-alpha.0" - resolved "https://registry.npmjs.org/@internationalized/message/-/message-3.0.0-alpha.0.tgz#83015e2057d2b6b5034a3e23983b1e051f9d9e36" - integrity sha512-NT2eiVq5f5z7Yi9Hmchb8GAGYjEpYbYcD4u/Oxo5XG9XFbrnz7zNvrJJlzuQ+2jPozabq6pFKurqaFmM49DYUg== - dependencies: - "@babel/runtime" "^7.6.2" - intl-messageformat "^2.2.0" - -"@internationalized/number@3.0.0-alpha.0": - version "3.0.0-alpha.0" - resolved "https://registry.npmjs.org/@internationalized/number/-/number-3.0.0-alpha.0.tgz#27190fbc1d73a24ac96dfafdfe7aa4e520090eed" - integrity sha512-8aOD2I3HmEscIZO/cm1jkcrYMSmRPhoW9G1OsuQb4Ge/Y9HsJVGB9otTylUEXJUmoXi/eD8Mr1gx3+0FLCM4eA== - dependencies: - "@babel/runtime" "^7.6.2" - "@istanbuljs/load-nyc-config@^1.0.0": version "1.0.0" resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" @@ -4329,445 +4263,6 @@ prop-types "^15.6.1" react-lifecycles-compat "^3.0.4" -"@react-aria/button@~3.3.1": - version "3.3.1" - resolved "https://registry.npmjs.org/@react-aria/button/-/button-3.3.1.tgz#f180ffa95e3e822b7da4937421cf8280dd17af17" - integrity sha512-LXNuo0L79AhYqnxV+Y3J3xt7hPcmCVCEpZaC/dBzovR1MLunrdpk3QAXsRt3tqza1XvoqdvNhNHQm1Z1kyBTUg== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/focus" "^3.2.2" - "@react-aria/i18n" "^3.3.0" - "@react-aria/interactions" "^3.3.3" - "@react-aria/utils" "^3.6.0" - "@react-stately/toggle" "^3.2.1" - "@react-types/button" "^3.3.1" - -"@react-aria/dialog@~3.1.2": - version "3.1.2" - resolved "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.1.2.tgz#868970e7fdaa6ddb91a0d8d5b492778607d417fd" - integrity sha512-CUHzLdcKxnQ1IpbJOJ3BIDe762QoTOFXZfDAheNiTi24ym85w7KkW7dnfJDK2+J5RY15c5KWooOZvTaBmIJ7Xw== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/focus" "^3.2.2" - "@react-aria/utils" "^3.3.0" - "@react-stately/overlays" "^3.1.1" - "@react-types/dialog" "^3.3.0" - -"@react-aria/focus@^3.2.2", "@react-aria/focus@^3.2.3", "@react-aria/focus@^3.2.4", "@react-aria/focus@~3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@react-aria/focus/-/focus-3.2.4.tgz#86c4fbde51a7cae414407b2d421fb5b311cd62f5" - integrity sha512-qoJoUDSriI7RCRq3L7yDOPtFZfquyjLA9d2pOJzvMx1F6dEqfNCaycyIg9lHykHXXhShgrXwfpyGTXoSUQpmtw== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/interactions" "^3.3.4" - "@react-aria/utils" "^3.7.0" - "@react-types/shared" "^3.5.0" - clsx "^1.1.1" - -"@react-aria/i18n@^3.3.0": - version "3.3.0" - resolved "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.3.0.tgz#7f92ae81f6536b19b17b89c0991ddb6c10f2512a" - integrity sha512-8KYk0tQiEf9Kd9xdF4cKliP1169WSIryKFnZgnm9dvZl96TyfDK1xJpZQy58XjRdbS/H45CKydFmMcZEElu3BQ== - dependencies: - "@babel/runtime" "^7.6.2" - "@internationalized/message" "3.0.0-alpha.0" - "@internationalized/number" "3.0.0-alpha.0" - "@react-aria/ssr" "^3.0.1" - "@react-aria/utils" "^3.6.0" - "@react-types/shared" "^3.4.0" - -"@react-aria/interactions@^3.2.1", "@react-aria/interactions@^3.3.3", "@react-aria/interactions@^3.3.4", "@react-aria/interactions@~3.3.4": - version "3.3.4" - resolved "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.3.4.tgz#a5b3a87f886cf0f4e28cbd13fbe02c7efb4f1e2e" - integrity sha512-WzT9aIRWvLZvZvuwNKKUkZzeomZgIrquAtwgRYGWbjSbrYPOT9B3w/GBEWZDYUG0c1K8NkIEAxTX0e+QI+tqAA== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/utils" "^3.7.0" - "@react-types/shared" "^3.5.0" - -"@react-aria/label@^3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-aria/label/-/label-3.1.1.tgz#03dc5c4813cd1f51760ba48783c186c2eeda1189" - integrity sha512-9kZKJonYSXeY6hZULZrsujAb6uXDGEy8qPq0tjTVoTA3+gx26LOmLCLgvHFtxUK1e4s99rHmaSPdOtq5qu3EVQ== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/utils" "^3.3.0" - "@react-types/label" "^3.2.1" - "@react-types/shared" "^3.2.1" - -"@react-aria/listbox@~3.2.4": - version "3.2.4" - resolved "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.2.4.tgz#3162e47d64e1f6cd8fdfe45766cb88c3852a525d" - integrity sha512-IYs4oS2wzWVcWEtKG57zZLZI507WlDy24wuzymwgFxxIRXDVaBsSMOs7+uE7N1P4fLOa1yAlv170AvKDDbIJ2g== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/interactions" "^3.3.3" - "@react-aria/label" "^3.1.1" - "@react-aria/selection" "^3.3.2" - "@react-aria/utils" "^3.6.0" - "@react-stately/collections" "^3.3.0" - "@react-stately/list" "^3.2.2" - "@react-types/listbox" "^3.1.1" - "@react-types/shared" "^3.4.0" - -"@react-aria/menu@^3.2.0": - version "3.2.0" - resolved "https://registry.npmjs.org/@react-aria/menu/-/menu-3.2.0.tgz#cd9417105b3230f1c34ddddddb31a95f462393e2" - integrity sha512-CFgC82ZO/LjJtMhDUJFdE3+PV0jS88LK9CCr6w11ggp+U3Q2fPXPdkAVeEB3cJn4KI0TRCBgE+4EneIzdTEgcw== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/interactions" "^3.3.4" - "@react-aria/overlays" "^3.6.2" - "@react-aria/selection" "^3.4.0" - "@react-aria/utils" "^3.7.0" - "@react-stately/collections" "^3.3.1" - "@react-stately/menu" "^3.2.1" - "@react-stately/tree" "^3.1.3" - "@react-types/button" "^3.3.1" - "@react-types/menu" "^3.1.1" - "@react-types/shared" "^3.5.0" - -"@react-aria/overlays@^3.6.1", "@react-aria/overlays@^3.6.2", "@react-aria/overlays@~3.6.2": - version "3.6.2" - resolved "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.6.2.tgz#0a9fcb7426d4321dc80ee636282228eb7be83a84" - integrity sha512-6f9o1fypGcB/VcprvoDm5280glaiAp/9RZeNPP+HPXE5MxpQIzFDJCzTrSezAUYNkueh/KNMpUxOUUgytloScQ== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/i18n" "^3.3.0" - "@react-aria/interactions" "^3.3.4" - "@react-aria/utils" "^3.7.0" - "@react-aria/visually-hidden" "^3.2.1" - "@react-stately/overlays" "^3.1.1" - "@react-types/button" "^3.3.1" - "@react-types/overlays" "^3.4.0" - dom-helpers "^3.3.1" - -"@react-aria/select@~3.3.1": - version "3.3.1" - resolved "https://registry.npmjs.org/@react-aria/select/-/select-3.3.1.tgz#cfa694ff4b2020846e08b58f6f0a489f0d2b24ff" - integrity sha512-E/EZ4SKf8P5EMVznCmTjfa9y1cR6L+WIzXHTFAlwrmmIzNirHSipbFp6LpJzoByqd0p9IKxhBdxqFP92url0Qg== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/i18n" "^3.3.0" - "@react-aria/interactions" "^3.3.4" - "@react-aria/label" "^3.1.1" - "@react-aria/menu" "^3.2.0" - "@react-aria/selection" "^3.4.0" - "@react-aria/utils" "^3.7.0" - "@react-aria/visually-hidden" "^3.2.1" - "@react-stately/select" "^3.1.1" - "@react-types/button" "^3.3.1" - "@react-types/select" "^3.2.0" - "@react-types/shared" "^3.5.0" - -"@react-aria/selection@^3.3.2", "@react-aria/selection@^3.4.0": - version "3.4.0" - resolved "https://registry.npmjs.org/@react-aria/selection/-/selection-3.4.0.tgz#abd7aa5435f504e314a72122f2bcaef43b06fa78" - integrity sha512-ddxiB9zhy8JEkG4+DElSMNrSKxRI3RQKyOwQf4i3omqXj8bMH1XJesFwbdGNmR/zrbzXvr35ln9y3S0WS+4ClA== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/focus" "^3.2.4" - "@react-aria/i18n" "^3.3.0" - "@react-aria/interactions" "^3.3.4" - "@react-aria/utils" "^3.7.0" - "@react-stately/collections" "^3.3.1" - "@react-stately/selection" "^3.4.0" - "@react-types/shared" "^3.5.0" - -"@react-aria/separator@~3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-aria/separator/-/separator-3.1.1.tgz#bfcd71bb5ab50dc04a7f307b84bd77955f08002f" - integrity sha512-VbiqQsTtKKMjvMcPVWgTbDHzx7qMP3VFC+y9cEVajicMwRoO4bn7kJgcSzainXpWx70bhT5RW1mt84fzxMF+Lg== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/utils" "^3.3.0" - "@react-types/shared" "^3.2.1" - -"@react-aria/ssr@^3.0.1", "@react-aria/ssr@~3.0.1": - version "3.0.1" - resolved "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.0.1.tgz#5f7c111f9ecd184b8f6140139703c1ee552dca30" - integrity sha512-rweMNcSkUO4YkcmgFIoZFvgPyHN2P9DOjq3VOHnZ8SG3Y4TTvSY6Iv90KgzeEfmWCUqqt65FYH4JgrpGNToEMw== - dependencies: - "@babel/runtime" "^7.6.2" - -"@react-aria/tooltip@~3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.1.1.tgz#e0dfdd9e51b581563f684927249d70e1bad761e3" - integrity sha512-wTszWN6lG3A9Ofdrhv1vG9aOmoqzuUZCbG9ZbXZ9+RtiOMwP/WnuSLWXcMH+KaWYpaImy7h1MDfOgHeaPxCbag== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/focus" "^3.2.3" - "@react-aria/interactions" "^3.3.3" - "@react-aria/overlays" "^3.6.1" - "@react-aria/utils" "^3.6.0" - "@react-stately/tooltip" "^3.0.2" - "@react-types/shared" "^3.4.0" - "@react-types/tooltip" "^3.1.1" - -"@react-aria/utils@^3.3.0", "@react-aria/utils@^3.6.0", "@react-aria/utils@^3.7.0", "@react-aria/utils@~3.7.0": - version "3.7.0" - resolved "https://registry.npmjs.org/@react-aria/utils/-/utils-3.7.0.tgz#0aab1f682e9f1781cfadd2dd1ef9494bfaca0cbf" - integrity sha512-sMCdX0eF+4B05I+SX9V/NzI1/fD45vabi0dNyJhbSu2xNI82VIYgPcMBDjGU83NJSnjY969R3/JbbLjBrtKUgA== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/ssr" "^3.0.1" - "@react-stately/utils" "^3.2.0" - "@react-types/shared" "^3.5.0" - clsx "^1.1.1" - -"@react-aria/visually-hidden@^3.2.1": - version "3.2.1" - resolved "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.2.1.tgz#c022c562346140a473242448045add59269a74fd" - integrity sha512-ba7bQD09MuzUghtPyrQoXHgQnRRfOu039roVKPz2em9gHD0Wy4ap2UPwlzx35KzNq6FdCzMDZeSZHSnUWlzKnw== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/interactions" "^3.2.1" - "@react-aria/utils" "^3.3.0" - clsx "^1.1.1" - -"@react-hook/debounce@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz#9eea8b5d81d4cb67cd72dd8657b3ff724afc7cad" - integrity sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag== - dependencies: - "@react-hook/latest" "^1.0.2" - -"@react-hook/event@^1.2.1": - version "1.2.3" - resolved "https://registry.npmjs.org/@react-hook/event/-/event-1.2.3.tgz#cfe86d5cf36f53e85b367ff619990d001b5c82ae" - integrity sha512-WMBwLnYY2rubLeecsi4skl1imfx0oiXTgazV/1ByPT6WkmLvxUao3hC+mxps5D/+JK4Fq3uG9OWU/dn5jMtXyg== - dependencies: - "@react-hook/passive-layout-effect" "^1.2.0" - -"@react-hook/latest@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80" - integrity sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg== - -"@react-hook/passive-layout-effect@^1.2.0": - version "1.2.1" - resolved "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz#c06dac2d011f36d61259aa1c6df4f0d5e28bc55e" - integrity sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg== - -"@react-hook/resize-observer@^1.1.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.0.tgz#a44b385d998f4ab33aa9481a43c4ac33af21f7d7" - integrity sha512-7Cpy0aaZ3xXlSabQ43aZcfgzwYSidrshEKGDqpfvdx7pHnGDGskr8m1Ajb6yamJUSdTRgqCemYQcwouCqMmZoQ== - dependencies: - "@react-hook/latest" "^1.0.2" - "@react-hook/passive-layout-effect" "^1.2.0" - "@types/raf-schd" "^4.0.0" - raf-schd "^4.0.2" - resize-observer-polyfill "^1.5.1" - -"@react-hook/size@^2.1.1": - version "2.1.1" - resolved "https://registry.npmjs.org/@react-hook/size/-/size-2.1.1.tgz#10d3fb5bc61e128f0d7924714a925a04c992ed1f" - integrity sha512-QtHDsrvz8p4cai2UKxBpzk0r/uM63UyhmozTVChaDHJsVpN5/7A2yu8wuGyNhExdeCYMclLM21QjY1dyqpGbuQ== - dependencies: - "@react-hook/passive-layout-effect" "^1.2.0" - "@react-hook/resize-observer" "^1.1.0" - -"@react-hook/throttle@^2.2.0": - version "2.2.0" - resolved "https://registry.npmjs.org/@react-hook/throttle/-/throttle-2.2.0.tgz#d0402714a06e1ba0bc1da1fdf5c3c5cd0e08d45a" - integrity sha512-LJ5eg+yMV8lXtqK3lR+OtOZ2WH/EfWvuiEEu0M3bhR7dZRfTyEJKxH1oK9uyBxiXPtWXiQggWbZirMCXam51tg== - dependencies: - "@react-hook/latest" "^1.0.2" - -"@react-hook/window-size@^3.0.7": - version "3.0.7" - resolved "https://registry.npmjs.org/@react-hook/window-size/-/window-size-3.0.7.tgz#00d176e7a8eb55814e161eae34aae20afbcbe35d" - integrity sha512-bK5ed/jN+cxy0s1jt2CelCnUt7jZRseUvPQ22ZJkUl/QDOsD+7CA/6wcqC3c0QweM/fPBRP6uI56TJ48SnlVww== - dependencies: - "@react-hook/debounce" "^3.0.0" - "@react-hook/event" "^1.2.1" - "@react-hook/throttle" "^2.2.0" - -"@react-spectrum/utils@~3.5.1": - version "3.5.1" - resolved "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.5.1.tgz#dd733913e30e0ed59c6bdae430531283b4cdcc96" - integrity sha512-lSdxCtshkj9dsi9sGcem6s9lak2XT55uyZGZr2S3w6iwm3aS7OlJNoT/4xtUFGW3t1bF2oxNngHX6eLl+quFyw== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-aria/i18n" "^3.3.0" - "@react-aria/ssr" "^3.0.1" - "@react-aria/utils" "^3.6.0" - "@react-types/shared" "^3.4.0" - clsx "^1.1.1" - -"@react-stately/collections@^3.2.1", "@react-stately/collections@^3.3.0", "@react-stately/collections@^3.3.1": - version "3.3.1" - resolved "https://registry.npmjs.org/@react-stately/collections/-/collections-3.3.1.tgz#683acf6e7a4e9ea174e1cf82a13bb8175ba0a1a0" - integrity sha512-bBiOj0hszFpCbk9KhSm04Jo87GAODm8kA52uFiGAO99yb2ypO+UTFYseBExFQ59cV7b++UMCfdJe/+Ymv9RALg== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-types/shared" "^3.5.0" - -"@react-stately/list@^3.2.1", "@react-stately/list@^3.2.2": - version "3.2.2" - resolved "https://registry.npmjs.org/@react-stately/list/-/list-3.2.2.tgz#fb368cc7678503179202d11aef0ef8d48d1cbf12" - integrity sha512-8sJvy0cUhllhUMadYjX1qKmTxAWMRGxkvZpU/6reOEChlvibjAwbn2paoR8yZ+ppieeQOBe+AAYTl53gK8fKDA== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/collections" "^3.3.0" - "@react-stately/selection" "^3.2.1" - "@react-stately/utils" "^3.1.1" - "@react-types/shared" "^3.2.1" - -"@react-stately/menu@^3.2.1": - version "3.2.1" - resolved "https://registry.npmjs.org/@react-stately/menu/-/menu-3.2.1.tgz#314646217e5dd49fa1da6886d33f485d44d6f0dd" - integrity sha512-8cpCynynjjn3qWNzrZMJEpsdk4tkXK9q3Xaw0ADqVym/NC/wPU3P3cqL4HY+ETar01tS2x8K23qYHbOZz0cQtQ== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/overlays" "^3.1.1" - "@react-stately/utils" "^3.1.1" - "@react-types/menu" "^3.1.1" - "@react-types/shared" "^3.2.1" - -"@react-stately/overlays@^3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.1.1.tgz#6c1a393b77148184f7b1df22ece832d694d5a8b4" - integrity sha512-79YYXvmWKflezNPhc4fvXA1rDZurZvvEJcmbStNlR5Ryrnk/sQiOQCoVWooi2M4glSMT3UOTvD7YEnXxARcuIQ== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/utils" "^3.1.1" - "@react-types/overlays" "^3.2.1" - -"@react-stately/select@^3.1.1", "@react-stately/select@~3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-stately/select/-/select-3.1.1.tgz#f49602ee7fc71f14550360bfa7c5becab58ac877" - integrity sha512-cl63nW66IJPsn9WQjKvghAIFKdFKuU1txx4zdEGY9tcwB/Yc+bgniLGOOTExJqN/RdPW9uBny5jjWcc4OQXyJA== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/collections" "^3.2.1" - "@react-stately/list" "^3.2.1" - "@react-stately/menu" "^3.2.1" - "@react-stately/selection" "^3.2.1" - "@react-stately/utils" "^3.1.1" - "@react-types/select" "^3.1.1" - "@react-types/shared" "^3.2.1" - -"@react-stately/selection@^3.2.1", "@react-stately/selection@^3.4.0": - version "3.4.0" - resolved "https://registry.npmjs.org/@react-stately/selection/-/selection-3.4.0.tgz#795134e17b59f21cc4979b30179bccdfc2e3b9c1" - integrity sha512-5RV9f1Tm4WSTDguL1iizYcgzeWiK6Qe2EZ03zaaE9gm5UyyIrEPQD4WW9Semio2cUF8IFuWLaOvRCk+un7p53Q== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/collections" "^3.3.1" - "@react-stately/utils" "^3.1.1" - "@react-types/shared" "^3.5.0" - -"@react-stately/toggle@^3.2.1": - version "3.2.1" - resolved "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.2.1.tgz#8b10b5eb99c3c4df2c36d17a5f23b77773ed7722" - integrity sha512-gZVuJ8OYoATUoXzdprsyx6O1w3wCrN+J0KnjhrjjKTrBG68n3pZH0p6dM0XpsaCzlSv0UgNa4fhHS3dYfr/ovw== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/utils" "^3.1.1" - "@react-types/checkbox" "^3.2.1" - "@react-types/shared" "^3.2.1" - -"@react-stately/tooltip@^3.0.2", "@react-stately/tooltip@~3.0.3": - version "3.0.3" - resolved "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.0.3.tgz#577fbf3cca39db7047ec2d77ddc03a56c454a82a" - integrity sha512-N98S8ccHEpgbgM6wIMZwqz37s8IQTa+5nPr8eVnIs5wqwdnAARFjvckr2okOGwaksofp1wtpcYbnNrIBwexJOg== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/overlays" "^3.1.1" - "@react-stately/utils" "^3.2.0" - "@react-types/tooltip" "^3.1.1" - -"@react-stately/tree@^3.1.3": - version "3.1.3" - resolved "https://registry.npmjs.org/@react-stately/tree/-/tree-3.1.3.tgz#5ceb1aa3793836a503253ddd47fc9227ac59c7b4" - integrity sha512-xwM2C3ppd8yJfduwgff7Gl2bNPMVeF4K65InFJZNVx5JLKFF6DJLAPTORAHLpCN+AoB8bY4sRK3V5fNBVpz0oQ== - dependencies: - "@babel/runtime" "^7.6.2" - "@react-stately/collections" "^3.3.1" - "@react-stately/selection" "^3.4.0" - "@react-stately/utils" "^3.1.1" - "@react-types/shared" "^3.5.0" - -"@react-stately/utils@^3.1.1", "@react-stately/utils@^3.2.0": - version "3.2.0" - resolved "https://registry.npmjs.org/@react-stately/utils/-/utils-3.2.0.tgz#0b90a70fee3236025ad8bed1f0e3555d5fc10296" - integrity sha512-vVBJvHVLnQySgqZ7OfP3ngDdwfGscJDsSD3WcN5ntHiT3JlZ5bksQReDkJEs20SFu2ST4w/0K7O4m97SbuMl2Q== - dependencies: - "@babel/runtime" "^7.6.2" - -"@react-types/button@^3.3.1": - version "3.3.1" - resolved "https://registry.npmjs.org/@react-types/button/-/button-3.3.1.tgz#4bdd325bc7df19c33911af256f63eae91e2a452e" - integrity sha512-xKLGSzGfsDBMe0SM7icOLNmzW38sdNSDSGMdrTLd3ygxb6pXY/LlcTdx7Sq28hdW8XL/ikFAnoQeS1VLXZHj7w== - dependencies: - "@react-types/shared" "^3.4.0" - -"@react-types/checkbox@^3.2.1": - version "3.2.2" - resolved "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.2.2.tgz#7182d44a533e2ffd2c9118372cbc2c33b006eb18" - integrity sha512-WAAqLdjf6GUWjsMN5NaFMFumOtGTq+3+48CpM0ah2L+qmhMdj1s4gvHDerhls6u4ovRK/7zhg7XK+qQwcYVqMg== - dependencies: - "@react-types/shared" "^3.4.0" - -"@react-types/dialog@^3.3.0": - version "3.3.0" - resolved "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.3.0.tgz#60a2b53f250ee082b53aef9340c80f1afe654bc7" - integrity sha512-63Vsr/UOZiaajlNDQUgWDi6v3EMenV1f8Cwh+L4lcyIJnbC6WeC2VEV3ld/TYVC0U58SQ0k7u2EIyHkWjc5kdQ== - dependencies: - "@react-types/overlays" "^3.2.1" - "@react-types/shared" "^3.2.1" - -"@react-types/label@^3.2.1": - version "3.4.0" - resolved "https://registry.npmjs.org/@react-types/label/-/label-3.4.0.tgz#6023dc9dd0146324ead52e08540cd60e57a3e27f" - integrity sha512-l84ysm1dcjL/5qVk9iN74z+/Ul0999XqnwTu6aTbuwAXqMk2sTU45eK2Yp/FJ7YWeflcF1vsomTkjMkX0BHKMw== - dependencies: - "@react-types/shared" "^3.4.0" - -"@react-types/listbox@^3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.1.1.tgz#b896303ccb87123cf59ee2c089953d7928497c9b" - integrity sha512-HAljfdpbyLoJL9iwqz7Fw9MOmRwfzODeN+sr5ncE0eXJxnRBFhb5LjbjAN1dUBrKFBkv3etGlYu5HvX+PJjpew== - dependencies: - "@react-types/shared" "^3.2.1" - -"@react-types/menu@^3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-types/menu/-/menu-3.1.1.tgz#e5aa52ac07c083243540dd5da0790a85fd1628c6" - integrity sha512-/xZWp4/3P/8dKFAGuzxz8IccSXvJH0TmHIk2/xnj2Eyw9152IfutIpOda3iswhjrx1LEkzUgdJ8bCdiebgg6QQ== - dependencies: - "@react-types/overlays" "^3.2.1" - "@react-types/shared" "^3.2.1" - -"@react-types/overlays@^3.2.1", "@react-types/overlays@^3.4.0": - version "3.4.0" - resolved "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.4.0.tgz#3c4619906bb12e3697e770b59c2090bb18da25bd" - integrity sha512-ddiMB6JXR7acQnRFEL2/6SSdBropmNrcAFk3qFCfovuVZh6STYhPmoAgj06mJFDoAD63pxayysfPG2EvLl2yAw== - dependencies: - "@react-types/shared" "^3.3.0" - -"@react-types/select@^3.1.1", "@react-types/select@^3.2.0": - version "3.2.0" - resolved "https://registry.npmjs.org/@react-types/select/-/select-3.2.0.tgz#31b9e0f94fc24f053f4a1f073e174ffd59bac055" - integrity sha512-9vYhQWr1iB+3KWTZ1RxS2xZq0n0CJfsTRbEr0akLrtE/pRLC4O4l8RMFD49HyX0fShvz1FStmxTE2x7k8yVc4w== - dependencies: - "@react-types/shared" "^3.4.0" - -"@react-types/shared@^3.2.1", "@react-types/shared@^3.3.0", "@react-types/shared@^3.4.0", "@react-types/shared@^3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.5.0.tgz#dbc90e8fe711967e66d6f3ce0e17d34b24bd6283" - integrity sha512-997Me7AegwJOI10ye/Q5ds6fT+VBc6XcsXYzPqOD+HIbyL1kUQNDF/VoO37ib7KEH8jXH9aceoX9blz3Q1QcpA== - -"@react-types/tooltip@^3.1.1": - version "3.1.1" - resolved "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.1.1.tgz#7d45a4dd8c57c422a1a2dcb03b6c043e7481c3ca" - integrity sha512-18gM2Co9tzCDfN0tEdfboD18sXDtD6YiKctd8HQ8tBiRO4IF1ce9ubKe6++Lj+38GQPq7GWFFoUiS1WArTWIHA== - dependencies: - "@react-types/overlays" "^3.4.0" - "@react-types/shared" "^3.4.0" - "@rjsf/core@^2.4.0": version "2.5.1" resolved "https://registry.npmjs.org/@rjsf/core/-/core-2.5.1.tgz#95a842d22bab5f83929662fcd73739108e9f5cbb" @@ -4975,179 +4470,6 @@ dependencies: any-observable "^0.3.0" -"@sentry/apm@5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/apm/-/apm-5.13.2.tgz#3a0809912426f52e19b1f4a603e99423a0ac8fb9" - integrity sha512-Pv6PRVkcmmYYIT422gXm968F8YQyf5uN1RSHOFBjWsxI3Ke/uRgeEdIVKPDo78GklBfETyRN6GyLEZ555jRe6g== - dependencies: - "@sentry/browser" "5.13.2" - "@sentry/hub" "5.13.2" - "@sentry/minimal" "5.13.2" - "@sentry/types" "5.13.2" - "@sentry/utils" "5.13.2" - tslib "^1.9.3" - -"@sentry/apm@5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/apm/-/apm-5.19.2.tgz#369fdcbc9fa5db992f707b24f3165e106a277cf7" - integrity sha512-V7p5niqG/Nn1OSMAyreChiIrQFYzFHKADKNaDEvIXqC4hxFnMG8lPRqEFJH49fNjsFBFfIG9iY1rO1ZFg3S42Q== - dependencies: - "@sentry/browser" "5.19.2" - "@sentry/hub" "5.19.2" - "@sentry/minimal" "5.19.2" - "@sentry/types" "5.19.2" - "@sentry/utils" "5.19.2" - tslib "^1.9.3" - -"@sentry/browser@5.13.2", "@sentry/browser@~5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/browser/-/browser-5.13.2.tgz#fcca630c8c80447ba8392803d4e4450fd2231b92" - integrity sha512-4MeauHs8Rf1c2FF6n84wrvA4LexEL1K/Tg3r+1vigItiqyyyYBx1sPjHGZeKeilgBi+6IEV5O8sy30QIrA/NsQ== - dependencies: - "@sentry/core" "5.13.2" - "@sentry/types" "5.13.2" - "@sentry/utils" "5.13.2" - tslib "^1.9.3" - -"@sentry/browser@5.19.2", "@sentry/browser@~5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/browser/-/browser-5.19.2.tgz#8bad445b8d1efd50e6510bb43b3018b941f6e5cb" - integrity sha512-o6Z532n+0N5ANDzgR9GN+Q6CU7zVlIJvBEW234rBiB+ZZj6XwTLS1dD+JexGr8lCo8PeXI2rypKcj1jUGLVW8w== - dependencies: - "@sentry/core" "5.19.2" - "@sentry/types" "5.19.2" - "@sentry/utils" "5.19.2" - tslib "^1.9.3" - -"@sentry/core@5.13.2", "@sentry/core@~5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/core/-/core-5.13.2.tgz#d89e199beef612d0a01e5c4df4e0bb7efcb72c74" - integrity sha512-iB7CQSt9e0EJhSmcNOCjzJ/u7E7qYJ3mI3h44GO83n7VOmxBXKSvtUl9FpKFypbWrsdrDz8HihLgAZZoMLWpPA== - dependencies: - "@sentry/hub" "5.13.2" - "@sentry/minimal" "5.13.2" - "@sentry/types" "5.13.2" - "@sentry/utils" "5.13.2" - tslib "^1.9.3" - -"@sentry/core@5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/core/-/core-5.19.2.tgz#99a64ef0e55230fc02a083c48fa07ada85de4929" - integrity sha512-sfbBsVXpA0WYJUichz5IhvqKD8xJUfQvsszrTsUKa7PQAMAboOmuh6bo8KquaVQnAZyZWZU08UduvlSV3tA7tw== - dependencies: - "@sentry/hub" "5.19.2" - "@sentry/minimal" "5.19.2" - "@sentry/types" "5.19.2" - "@sentry/utils" "5.19.2" - tslib "^1.9.3" - -"@sentry/electron@~1.3.0": - version "1.3.2" - resolved "https://registry.npmjs.org/@sentry/electron/-/electron-1.3.2.tgz#83c40943f2fad5e72c77dadf524fd59d1a773e3f" - integrity sha512-fhD6cF7Jy0AXAVNHrUnxhzK5d/reXpzRcp5Ggnr+IRoijGe7rsq/AlOX8KhLS6SmQdI/XXb3F7fxHdItBV9+7w== - dependencies: - "@sentry/browser" "~5.13.2" - "@sentry/core" "~5.13.2" - "@sentry/minimal" "~5.13.2" - "@sentry/node" "~5.13.2" - "@sentry/types" "~5.13.2" - "@sentry/utils" "~5.13.2" - electron-fetch "^1.4.0" - form-data "2.5.1" - util.promisify "1.0.1" - -"@sentry/hub@5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.13.2.tgz#875a5ba983d6ada5caae5b6b4decd0257ef5cdb7" - integrity sha512-/U7yq3DTuRz8SRpZVKAaenW9sD2F5wbj12kDVPxPnGspyqhy0wBWKs9j0YJfBiDXMKOwp3HX964O3ygtwjnfAw== - dependencies: - "@sentry/types" "5.13.2" - "@sentry/utils" "5.13.2" - tslib "^1.9.3" - -"@sentry/hub@5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.19.2.tgz#ab7f3d2d253c3441b2833a530b17c6de2418b2c7" - integrity sha512-2KkEYX4q9TDCOiaVEo2kQ1W0IXyZxJxZtIjDdFQyes9T4ubYlKHAbvCjTxHSQv37lDO4t7sOIApWG9rlkHzlEA== - dependencies: - "@sentry/types" "5.19.2" - "@sentry/utils" "5.19.2" - tslib "^1.9.3" - -"@sentry/minimal@5.13.2", "@sentry/minimal@~5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.13.2.tgz#e42e33dc74fc935f8857d1a43a528afd741640fd" - integrity sha512-VV0eA3HgrnN3mac1XVPpSCLukYsU+QxegbmpnZ8UL8eIQSZ/ZikYxagDNlZbdnmXHUpOEUeag2gxVntSCo5UcA== - dependencies: - "@sentry/hub" "5.13.2" - "@sentry/types" "5.13.2" - tslib "^1.9.3" - -"@sentry/minimal@5.19.2", "@sentry/minimal@~5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.19.2.tgz#0fc2fdf9911a0cb31b52f7ccad061b74785724a3" - integrity sha512-rApEOkjy+ZmkeqEItgFvUFxe5l+dht9AumuUzq74pWp+HJqxxv9IVTusKppBsE1adjtmyhwK4O3Wr8qyc75xlw== - dependencies: - "@sentry/hub" "5.19.2" - "@sentry/types" "5.19.2" - tslib "^1.9.3" - -"@sentry/node@~5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/node/-/node-5.13.2.tgz#3be5608e00fb3fe1b813ad8365073a465d19f5f6" - integrity sha512-LwNOUvc0+28jYfI0o4HmkDTEYdY3dWvSCnL5zggO12buon7Wc+jirXZbEQAx84HlXu7sGSjtKCTzUQOphv7sPw== - dependencies: - "@sentry/apm" "5.13.2" - "@sentry/core" "5.13.2" - "@sentry/hub" "5.13.2" - "@sentry/types" "5.13.2" - "@sentry/utils" "5.13.2" - cookie "^0.3.1" - https-proxy-agent "^4.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/node@~5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/node/-/node-5.19.2.tgz#8c1c2f6c983c3d8b25143e5b99c4b6cc745125ec" - integrity sha512-gbww3iTWkdvYIAhOmULbv8znKwkIpklGJ0SPtAh0orUMuaa0lVht+6HQIhRgeXp50lMzNaYC3fuzkbFfYgpS7A== - dependencies: - "@sentry/apm" "5.19.2" - "@sentry/core" "5.19.2" - "@sentry/hub" "5.19.2" - "@sentry/types" "5.19.2" - "@sentry/utils" "5.19.2" - cookie "^0.3.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/types@5.13.2", "@sentry/types@~5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/types/-/types-5.13.2.tgz#8e68c31f8fb99b4074374bff13ed01035b373d8c" - integrity sha512-mgAEQyc77PYBnAjnslSXUz6aKgDlunlg2c2qSK/ivKlEkTgTWWW/dE76++qVdrqM8SupnqQoiXyPDL0wUNdB3g== - -"@sentry/types@5.19.2", "@sentry/types@~5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/types/-/types-5.19.2.tgz#ead586f0b64b91c396d3521b938ca25f7b59d655" - integrity sha512-O6zkW8oM1qK5Uma9+B/UMlmlm9/gkw9MooqycWuEhIaKfDBj/yVbwb/UTiJmNkGc5VJQo0v1uXUZZQt6/Xq1GA== - -"@sentry/utils@5.13.2", "@sentry/utils@~5.13.2": - version "5.13.2" - resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.13.2.tgz#441594f4f9412bfd1690739ce986bf3a49687806" - integrity sha512-LwPQl6WRMKEnd16kg35HS3yE+VhBc8vN4+BBIlrgs7X0aoT+AbEd/sQLMisDgxNboCF44Ho3RCKtztiPb9blqg== - dependencies: - "@sentry/types" "5.13.2" - tslib "^1.9.3" - -"@sentry/utils@5.19.2": - version "5.19.2" - resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.19.2.tgz#f2819d9de5abc33173019e81955904247e4a8246" - integrity sha512-gEPkC0CJwvIWqcTcPSdIzqJkJa9N5vZzUZyBvdu1oiyJu7MfazpJEvj3whfJMysSfXJQxoJ+a1IPrA73VY23VA== - dependencies: - "@sentry/types" "5.19.2" - tslib "^1.9.3" - "@sideway/address@^4.1.0": version "4.1.1" resolved "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d" @@ -5216,168 +4538,6 @@ resolved "https://registry.npmjs.org/@spotify/prettier-config/-/prettier-config-9.0.0.tgz#7b562d56573c6fc0094446fbc92b22bc318945dc" integrity sha512-In1q0tIiqTYKAGe3KOHDcFDdZRFISyQeSeipeTHGfki23ebHRZcjxvqj5SSdBkw65D4VpSREMi0s9i5iJiMcTw== -"@stoplight/beaver-logger@^4.0.12": - version "4.0.12" - resolved "https://registry.npmjs.org/@stoplight/beaver-logger/-/beaver-logger-4.0.12.tgz#f754d2f20b4728f5e96fdec574729988e4fb0c2d" - integrity sha512-VPSqZ706GaAB/7VcXcKvzaxaKwHmr2jUNcn0mTvhR3dwglmDEsqoKRvzTxH+Zu1VUIRjdcy9zmU7mSfjKjPt7Q== - dependencies: - belter "^1.0.17" - zalgo-promise "^1.0.26" - -"@stoplight/json-schema-merge-allof@^0.7.5": - version "0.7.6" - resolved "https://registry.npmjs.org/@stoplight/json-schema-merge-allof/-/json-schema-merge-allof-0.7.6.tgz#39efac12a497ed29a06ae48e0141885634a045a4" - integrity sha512-xLbJC2VOd9AxO1VvvgyP/mWOqZbeg6mLpYzlzU4egDTTIrTsSqtv+yFakpPciuuMlOmJU/KzZK9C5AbMgE+VgQ== - dependencies: - compute-lcm "^1.1.0" - json-schema-compare "^0.2.2" - lodash "^4.17.4" - -"@stoplight/json-schema-tree@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@stoplight/json-schema-tree/-/json-schema-tree-2.0.0.tgz#00d54cb6aa2a791c34be91fc30cc92e6d448258c" - integrity sha512-vnzcb0TC07xh89lAVGjBTJ2CWvCqmDJDIs3u+gvgvjDPY86CQ0Wl4D2Cmb0iuqd986aiDPc8vDQf1N0dSq5+9A== - dependencies: - "@stoplight/json" "^3.12.0" - "@stoplight/json-schema-merge-allof" "^0.7.5" - "@stoplight/lifecycle" "^2.3.2" - "@types/json-schema" "^7.0.7" - magic-error "^0.0.0" - -"@stoplight/json-schema-viewer@^4.0.0-beta.16": - version "4.0.0-beta.16" - resolved "https://registry.npmjs.org/@stoplight/json-schema-viewer/-/json-schema-viewer-4.0.0-beta.16.tgz#8f55debcb1e84ddcd6f55012ed52712560beaca5" - integrity sha512-f6GijfWi15maRQH4J/ulc8tFpoc+ejGeckiIH+USTLPd7fmGiIU5wINbJSVbLJ5Hccky8wraxlCzfdRuck84Jw== - dependencies: - "@fortawesome/free-solid-svg-icons" "^5.15.2" - "@stoplight/json" "^3.10.0" - "@stoplight/json-schema-tree" "^2.0.0" - "@stoplight/mosaic" "1.0.0-beta.46" - "@stoplight/react-error-boundary" "^1.0.0" - "@types/json-schema" "^7.0.7" - classnames "^2.2.6" - lodash "^4.17.19" - -"@stoplight/json@^3.10.0", "@stoplight/json@^3.12.0": - version "3.12.0" - resolved "https://registry.npmjs.org/@stoplight/json/-/json-3.12.0.tgz#26c8d32da78eac6a760ba2c9cca6ae717dc417b4" - integrity sha512-c0bvFOGICk8QWIat72Td2GG6Bdvq/6O2jQcDZ8rEjh56YOdC/YPn1S8ihKu3AntJCtvqC9eTfadWBqkNK9HAjw== - dependencies: - "@stoplight/ordered-object-literal" "^1.0.1" - "@stoplight/types" "^11.9.0" - jsonc-parser "~2.2.1" - lodash "^4.17.15" - safe-stable-stringify "^1.1" - -"@stoplight/lifecycle@^2.3.2": - version "2.3.2" - resolved "https://registry.npmjs.org/@stoplight/lifecycle/-/lifecycle-2.3.2.tgz#d61dff9ba20648241432e2daaef547214dc8976e" - integrity sha512-v0u8p27FA/eg04b4z6QXw4s0NeeFcRzyvseBW0+k/q4jtpg7EhVCqy42EbbbU43NTNDpIeQ81OcvkFz+6CYshw== - dependencies: - wolfy87-eventemitter "~5.2.8" - -"@stoplight/mosaic@1.0.0-beta.46": - version "1.0.0-beta.46" - resolved "https://registry.npmjs.org/@stoplight/mosaic/-/mosaic-1.0.0-beta.46.tgz#35fa3c9aebdb3c3535d1d8dd53cc52f1b2b1f5db" - integrity sha512-GlGLb2RzvzS7CQpq006c6eZhe7tIgRvDIt/nYqx+FXJEh0M045I2EObstdbyQt/sL7Zw5lae3uxiQ/1j8FqkRA== - dependencies: - "@fortawesome/fontawesome-svg-core" "^1.2.35" - "@fortawesome/free-solid-svg-icons" "^5.15.3" - "@fortawesome/react-fontawesome" "^0.1.14" - "@react-aria/button" "~3.3.1" - "@react-aria/dialog" "~3.1.2" - "@react-aria/focus" "~3.2.4" - "@react-aria/interactions" "~3.3.4" - "@react-aria/listbox" "~3.2.4" - "@react-aria/overlays" "~3.6.2" - "@react-aria/select" "~3.3.1" - "@react-aria/separator" "~3.1.1" - "@react-aria/ssr" "~3.0.1" - "@react-aria/tooltip" "~3.1.1" - "@react-aria/utils" "~3.7.0" - "@react-hook/size" "^2.1.1" - "@react-hook/window-size" "^3.0.7" - "@react-spectrum/utils" "~3.5.1" - "@react-stately/select" "~3.1.1" - "@react-stately/tooltip" "~3.0.3" - clsx "^1.1.1" - copy-to-clipboard "^3.3.1" - deepmerge "^4.2.2" - lodash.get "^4.4.2" - polished "^4.1.1" - reakit "npm:@stoplight/reakit@~1.3.5" - ts-keycode-enum "^1.0.6" - tslib "^2.1.0" - zustand "^3.3.3" - -"@stoplight/mosaic@^1.0.0-beta.46": - version "1.0.0-beta.47" - resolved "https://registry.npmjs.org/@stoplight/mosaic/-/mosaic-1.0.0-beta.47.tgz#6b212163af3ab7fb981dee75785f1b967299171e" - integrity sha512-Rp6aXslPB0X2hqj8MFmbYSWUvSjo/ResDFNQoMHD1BCBGw0nTmlcPZaQDKQApUFQrDBzih+OGRKTk0mGxrTP3A== - dependencies: - "@fortawesome/fontawesome-svg-core" "^1.2.35" - "@fortawesome/free-solid-svg-icons" "^5.15.3" - "@fortawesome/react-fontawesome" "^0.1.14" - "@react-aria/button" "~3.3.1" - "@react-aria/dialog" "~3.1.2" - "@react-aria/focus" "~3.2.4" - "@react-aria/interactions" "~3.3.4" - "@react-aria/listbox" "~3.2.4" - "@react-aria/overlays" "~3.6.2" - "@react-aria/select" "~3.3.1" - "@react-aria/separator" "~3.1.1" - "@react-aria/ssr" "~3.0.1" - "@react-aria/tooltip" "~3.1.1" - "@react-aria/utils" "~3.7.0" - "@react-hook/size" "^2.1.1" - "@react-hook/window-size" "^3.0.7" - "@react-spectrum/utils" "~3.5.1" - "@react-stately/select" "~3.1.1" - "@react-stately/tooltip" "~3.0.3" - clsx "^1.1.1" - copy-to-clipboard "^3.3.1" - deepmerge "^4.2.2" - lodash.get "^4.4.2" - polished "^4.1.1" - reakit "npm:@stoplight/reakit@~1.3.5" - ts-keycode-enum "^1.0.6" - tslib "^2.1.0" - zustand "^3.3.3" - -"@stoplight/ordered-object-literal@^1.0.1": - version "1.0.2" - resolved "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.2.tgz#2a88a5ebc8b68b54837ac9a9ae7b779cdd862062" - integrity sha512-0ZMS/9sNU3kVo/6RF3eAv7MK9DY8WLjiVJB/tVyfF2lhr2R4kqh534jZ0PlrFB9CRXrdndzn1DbX6ihKZXft2w== - -"@stoplight/react-error-boundary@^1.0.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@stoplight/react-error-boundary/-/react-error-boundary-1.1.0.tgz#9b0fb5d0538abbf9a416723b90f5b776bf68a75d" - integrity sha512-z/1gDVQAafqYuJksL212F1DXHSr604KDqAspZwbC+kWVqCsddQBmXzwI4Lqqem4wHbNGeVZYk3svW+sILX/PUQ== - dependencies: - "@stoplight/types" "^11.9.0" - -"@stoplight/reporter@^1.10.0": - version "1.10.0" - resolved "https://registry.npmjs.org/@stoplight/reporter/-/reporter-1.10.0.tgz#cbb58a7842422178ff56410e3f009517a474a5ba" - integrity sha512-XdHIT+TwS00rEhsEClCddrACZCqxK+sh/R2EBFuXBTbWMIwujoWVTLPxEwhVkfm2JF57pK3jzULOFxEnNRnmpQ== - dependencies: - "@sentry/browser" "~5.19.2" - "@sentry/electron" "~1.3.0" - "@sentry/minimal" "~5.19.2" - "@sentry/node" "~5.19.2" - "@sentry/types" "~5.19.2" - "@stoplight/beaver-logger" "^4.0.12" - "@types/amplitude-js" "^5.11.0" - amplitude-js "^7.1.0" - -"@stoplight/types@^11.9.0": - version "11.10.0" - resolved "https://registry.npmjs.org/@stoplight/types/-/types-11.10.0.tgz#60bbee770526f4de9cd1c613c7ab84c4e4674126" - integrity sha512-ffHD9i4UHS8Gsg7Ar8pKjI9B4kq7MRekE7tCROFGcFDzQhfRx9T92AduoLAtP/010XNYq23yDKpLBRPIEk8+xg== - dependencies: - "@types/json-schema" "^7.0.4" - utility-types "^3.10.0" - "@storybook/addon-actions@^6.1.11": version "6.1.17" resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.1.17.tgz#9d32336284738cefa69b99acafa4b132d5533600" @@ -6501,11 +5661,6 @@ dependencies: "@types/node" "*" -"@types/amplitude-js@^5.11.0": - version "5.11.1" - resolved "https://registry.npmjs.org/@types/amplitude-js/-/amplitude-js-5.11.1.tgz#4883aa6f484530df3557de8683ff4529fcb7ec65" - integrity sha512-2BAZ8sMlOq4t0zC5LEBRL551u/kJPr+BTOe9OUtFT7J1U4Kgm+gHYmV4nYwq9sZnNj6MisCllKiiL27WEur7Sw== - "@types/anymatch@*": version "1.3.1" resolved "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -7091,11 +6246,6 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== -"@types/json-schema@^7.0.7": - version "7.0.7" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== - "@types/json-stable-stringify@^1.0.32": version "1.0.32" resolved "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" @@ -7417,11 +6567,6 @@ resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a" integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ== -"@types/raf-schd@^4.0.0": - version "4.0.1" - resolved "https://registry.npmjs.org/@types/raf-schd/-/raf-schd-4.0.1.tgz#1f9e03736f277fe9c7b82102bf18570a6ee19f82" - integrity sha512-Ha+EnKHFIh9EKW0/XZJPUd3EGDFisEvauaBd4VVCRPKeOqUxNEc9TodiY2Zhk33XCgzJucoFEcaoNcBAPHTQ2A== - "@types/raf@^3.4.0": version "3.4.0" resolved "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz#2b72cbd55405e071f1c4d29992638e022b20acc2" @@ -8308,11 +7453,6 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@5: - version "5.1.1" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" - integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== - agent-base@6: version "6.0.1" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4" @@ -8402,16 +7542,6 @@ alphanum-sort@^1.0.0: resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -amplitude-js@^7.1.0: - version "7.4.4" - resolved "https://registry.npmjs.org/amplitude-js/-/amplitude-js-7.4.4.tgz#1abd76f96a44ebdbf90e7371b37d071010deffe6" - integrity sha512-3Ojj1draRcXvfxi5P+Ye/6Y4roxtf1lQEjczcLDnHU9vxbPtT4fDblC9+cdJy7XmlJkGoq+KvnItlWfLuHV9GQ== - dependencies: - "@amplitude/ua-parser-js" "0.7.24" - "@amplitude/utils" "^1.0.5" - blueimp-md5 "^2.10.0" - query-string "5" - anafanafo@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/anafanafo/-/anafanafo-1.0.0.tgz#2e67190aed5dc67f5f0043b710146e7276c1afb8" @@ -9620,15 +8750,6 @@ before-after-hook@^2.1.0: resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A== -belter@^1.0.17: - version "1.0.165" - resolved "https://registry.npmjs.org/belter/-/belter-1.0.165.tgz#8bc32f0f30b94b67b80a63727b1584acd69942f0" - integrity sha512-TVOfXtLTTU3yyORjiYD2s9+fnTdxZp69KtR3pSDquLrdtK3OUmypgukVL+pIbcE6VMc85FRoFR48gybNZ2zHZQ== - dependencies: - cross-domain-safe-weakmap "^1" - cross-domain-utils "^2" - zalgo-promise "^1" - better-opn@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/better-opn/-/better-opn-2.0.0.tgz#c70d198e51164bdc220306a28a885d9ac7a14c44" @@ -9724,11 +8845,6 @@ bluebird@~3.4.1: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= -blueimp-md5@^2.10.0: - version "2.18.0" - resolved "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz#1152be1335f0c6b3911ed9e36db54f3e6ac52935" - integrity sha512-vE52okJvzsVWhcgUHOv+69OG3Mdg151xyn41aVQN/5W5S+S43qZhxECtYLAEHMSFWX6Mv5IZrzj3T5+JqXfj5Q== - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -9750,11 +8866,6 @@ body-parser@1.19.0, body-parser@^1.18.3: raw-body "2.4.0" type-is "~1.6.17" -body-scroll-lock@^3.1.5: - version "3.1.5" - resolved "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" - integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== - bonjour@^3.5.0: version "3.5.0" resolved "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" @@ -10792,7 +9903,7 @@ clone@^1.0.2: resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -clsx@^1.0.1, clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.0, clsx@^1.1.1: +clsx@^1.0.1, clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== @@ -11332,11 +10443,6 @@ cookie@0.4.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -cookie@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= - cookie@^0.4.1, cookie@~0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" @@ -11539,20 +10645,6 @@ create-require@^1.1.0: resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-domain-safe-weakmap@^1: - version "1.0.28" - resolved "https://registry.npmjs.org/cross-domain-safe-weakmap/-/cross-domain-safe-weakmap-1.0.28.tgz#d6c3c5af954340ce5f9d4ee5f3c38dba9513a165" - integrity sha512-gfQiQYSdWr9cYFVpmzp+b6MyTnefefDHr+fvm+JVv20hQxetV5J6chZOAusrpM/kFpTTbVDnHCziBFaREvgc0Q== - dependencies: - cross-domain-utils "^2.0.0" - -cross-domain-utils@^2, cross-domain-utils@^2.0.0: - version "2.0.34" - resolved "https://registry.npmjs.org/cross-domain-utils/-/cross-domain-utils-2.0.34.tgz#3f8dc8d82a5434213787433f17b76f51c316e382" - integrity sha512-ke4PirGRXwEElEmE/7k5aCvCW+EqbgseT7AOObzFfaVnOLuEVN9SjVWoOfS/qAT0rDPn3ggmNDW6mguMBy4HgA== - dependencies: - zalgo-promise "^1.0.11" - cross-env@^7.0.0: version "7.0.3" resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -12679,7 +11771,7 @@ dom-converter@^0.2: dependencies: utila "~0.4" -dom-helpers@^3.3.1, dom-helpers@^3.4.0: +dom-helpers@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== @@ -12969,13 +12061,6 @@ ejs@^3.1.2: dependencies: jake "^10.6.1" -electron-fetch@^1.4.0: - version "1.7.3" - resolved "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.7.3.tgz#06cf363d7f64073ec00a37e9949ec9d29ce6b08a" - integrity sha512-1AVMaxrHXTTMqd7EK0MGWusdqNr07Rpj8Th6bG4at0oNgIi/1LBwa9CjT/0Zy+M0k/tSJPS04nFxHj0SXDVgVw== - dependencies: - encoding "^0.1.13" - electron-to-chromium@^1.3.378: version "1.3.509" resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.509.tgz#830fcb89cd66dc2984d18d794973b99e3f00584c" @@ -13075,7 +12160,7 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12, encoding@^0.1.13: +encoding@^0.1.12: version "0.1.13" resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -14494,7 +13579,7 @@ fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.0.5, for tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@2.5.1, form-data@^2.3.1, form-data@^2.3.2, form-data@^2.5.0: +form-data@^2.3.1, form-data@^2.3.2, form-data@^2.5.0: version "2.5.1" resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== @@ -16039,14 +15124,6 @@ https-proxy-agent@^2.2.1: agent-base "^4.3.0" debug "^3.1.0" -https-proxy-agent@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" - integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== - dependencies: - agent-base "5" - debug "4" - https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -16439,18 +15516,6 @@ interpret@^2.0.0, interpret@^2.2.0: resolved "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -intl-messageformat-parser@1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075" - integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU= - -intl-messageformat@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc" - integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw= - dependencies: - intl-messageformat-parser "1.4.0" - invariant@^2.0.0, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -17991,11 +17056,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -jsonc-parser@~2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" - integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== - jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -18762,7 +17822,7 @@ lodash.flattendeep@^4.0.0: resolved "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= -lodash.get@^4, lodash.get@^4.0.0, lodash.get@^4.4.2: +lodash.get@^4, lodash.get@^4.0.0: version "4.4.2" resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= @@ -19027,11 +18087,6 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= - lunr@^2.3.9: version "2.3.9" resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -19057,11 +18112,6 @@ macos-release@^2.2.0: resolved "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== -magic-error@^0.0.0: - version "0.0.0" - resolved "https://registry.npmjs.org/magic-error/-/magic-error-0.0.0.tgz#f8630c98c55764b4851601901fdcb63428758b7d" - integrity sha512-ZMU3ylGOb/YQEpJo0XtAXbPGmKJtwzc3cuOHPrKgosV8AAc6db8dlQYLe0cp64P3BxkYZGoUvkvdNR5JM78beA== - magic-string@^0.25.7: version "0.25.7" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" @@ -21860,13 +20910,6 @@ polished@^3.4.4: dependencies: "@babel/runtime" "^7.9.2" -polished@^4.1.1: - version "4.1.2" - resolved "https://registry.npmjs.org/polished/-/polished-4.1.2.tgz#c04fcc203e287e2d866e9cfcaf102dae1c01a816" - integrity sha512-jq4t3PJUpVRcveC53nnbEX35VyQI05x3tniwp26WFdm1dwaNUBHAi5awa/roBlwQxx1uRhwNSYeAi/aMbfiJCQ== - dependencies: - "@babel/runtime" "^7.13.17" - popper.js@1.16.1-lts: version "1.16.1-lts" resolved "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" @@ -22717,15 +21760,6 @@ qs@~6.5.2: resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@5: - version "5.1.1" - resolved "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - query-string@^4.1.0: version "4.3.4" resolved "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -23640,36 +22674,6 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" -reakit-system@^0.15.1: - version "0.15.1" - resolved "https://registry.npmjs.org/reakit-system/-/reakit-system-0.15.1.tgz#bf5cc7a03f60a817373bc9cbb4a689c1f4100547" - integrity sha512-PkqfAyEohtcEu/gUvKriCv42NywDtUgvocEN3147BI45dOFAB89nrT7wRIbIcKJiUT598F+JlPXAZZVLWhc1Kg== - dependencies: - reakit-utils "^0.15.1" - -reakit-utils@^0.15.1: - version "0.15.1" - resolved "https://registry.npmjs.org/reakit-utils/-/reakit-utils-0.15.1.tgz#797f0a43f6a1dbc22d161224d5d2272e287dbfe3" - integrity sha512-6cZgKGvOkAMQgkwU9jdYbHfkuIN1Pr+vwcB19plLvcTfVN0Or10JhIuj9X+JaPZyI7ydqTDFaKNdUcDP69o/+Q== - -reakit-warning@^0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/reakit-warning/-/reakit-warning-0.6.1.tgz#dba33bb8866aebe30e67ac433ead707d16d38a36" - integrity sha512-poFUV0EyxB+CcV9uTNBAFmcgsnR2DzAbOTkld4Ul+QOKSeEHZB3b3+MoZQgcYHmbvG19Na1uWaM7ES+/Eyr8tQ== - dependencies: - reakit-utils "^0.15.1" - -"reakit@npm:@stoplight/reakit@~1.3.5": - version "1.3.5" - resolved "https://registry.npmjs.org/@stoplight/reakit/-/reakit-1.3.5.tgz#0c1a1ae89a92de98413d3723b993c05d943bd56b" - integrity sha512-/Con1m4eSaztckgnEPckNPMkAIcOCYku60mANTGScevY9wYk56V2L6vpv6HR4r8gsFCl4S/CVoNCVMxkxi/pGw== - dependencies: - "@popperjs/core" "^2.5.4" - body-scroll-lock "^3.1.5" - reakit-system "^0.15.1" - reakit-utils "^0.15.1" - reakit-warning "^0.6.1" - recharts-scale@^0.4.2: version "0.4.3" resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.3.tgz#040b4f638ed687a530357292ecac880578384b59" @@ -24414,11 +23418,6 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -safe-stable-stringify@^1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a" - integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw== - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -26567,11 +25566,6 @@ ts-jest@^26.4.3: semver "7.x" yargs-parser "20.x" -ts-keycode-enum@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/ts-keycode-enum/-/ts-keycode-enum-1.0.6.tgz#aeefd1c2fc7b0557f86a0e696e300905bbb4c1c1" - integrity sha512-DF8+Cf/FJJnPRxwz8agCoDelQXKZWQOS/gnnwx01nZ106tPJdB3BgJ9QTtLwXgR82D8O+nTjuZzWgf0Rg4vuRA== - ts-loader@^8.0.17: version "8.0.17" resolved "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.17.tgz#98f2ccff9130074f4079fd89b946b4c637b1f2fc" @@ -27250,7 +26244,7 @@ util.promisify@1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" -util.promisify@1.0.1, util.promisify@^1.0.0, util.promisify@~1.0.0: +util.promisify@^1.0.0, util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== @@ -27279,11 +26273,6 @@ utila@^0.4.0, utila@~0.4: resolved "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= -utility-types@^3.10.0: - version "3.10.0" - resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" - integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== - utils-merge@1.0.1, utils-merge@1.x.x: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -27844,11 +26833,6 @@ winston@^3.2.1: triple-beam "^1.3.0" winston-transport "^4.4.0" -wolfy87-eventemitter@~5.2.8: - version "5.2.9" - resolved "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz#e879f770b30fbb6512a8afbb330c388591099c2a" - integrity sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw== - word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -28308,11 +27292,6 @@ z-schema@~3.18.3: optionalDependencies: commander "^2.7.1" -zalgo-promise@^1, zalgo-promise@^1.0.11, zalgo-promise@^1.0.26: - version "1.0.46" - resolved "https://registry.npmjs.org/zalgo-promise/-/zalgo-promise-1.0.46.tgz#325988d75d0be4cd63a266bad5e18f8f6cd85675" - integrity sha512-tzPpQRqaQQavxl17TY98nznvmr+judUg3My7ugsUcRDbdqisYOE2z79HNNDgXnyX3eA0mf2bMOJrqHptt00npg== - zen-observable-ts@^0.8.21: version "0.8.21" resolved "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d" @@ -28358,11 +27337,6 @@ zombie@^6.1.4: tough-cookie "^2.3.4" ws "^6.1.2" -zustand@^3.3.3: - version "3.4.2" - resolved "https://registry.npmjs.org/zustand/-/zustand-3.4.2.tgz#22f0e0503a364672c6e3bb83399e69479bcea9b2" - integrity sha512-/v0RRbzi8NNyiXf7vw2eizPfJaTlTbXNM3fjQ6xF+qr5Xc0cF0ypaa0ARLOvyaKsGx/q2p5azVhfGxl4uHK0Ag== - zwitch@^1.0.0: version "1.0.5" resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" From 9314a859267a1a974ba4bfff74e31bcd86d9e1c5 Mon Sep 17 00:00:00 2001 From: jrusso1020 <jrusso@brex.com> Date: Mon, 3 May 2021 09:21:55 -0600 Subject: [PATCH 402/462] Close eventstreams upon completion Previously we were not closing eventSource's upon completion which lead to stale eventstream calls persisting across a session in the scaffolder. This calls eventSource.close() properly in order to clean up an eventStream once we get completion event Signed-off-by: jrusso1020 <jrusso@brex.com> --- .changeset/tame-masks-juggle.md | 5 +++++ plugins/scaffolder/src/api.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/tame-masks-juggle.md diff --git a/.changeset/tame-masks-juggle.md b/.changeset/tame-masks-juggle.md new file mode 100644 index 0000000000..91ee43945a --- /dev/null +++ b/.changeset/tame-masks-juggle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Close eventSource upon completion of a scaffolder task diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 6caa2a4446..0c5eb2b268 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -214,6 +214,7 @@ export class ScaffolderClient implements ScaffolderApi { subscriber.error(ex); } } + eventSource.close(); subscriber.complete(); }); eventSource.addEventListener('error', event => { From a030b5be86e6d6c8d1d01d8ed88a7a21cc28c51f Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Mon, 3 May 2021 17:35:04 +0200 Subject: [PATCH 403/462] Update invalid test Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- .../stages/templater/cookiecutter.test.ts | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts index 28e2800e55..59fb72d515 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts @@ -145,14 +145,8 @@ describe('CookieCutter Templater', () => { expect(containerRunner.runContainer).toHaveBeenCalledWith({ imageName: 'spotify/backstage-cookiecutter', - args: [ - 'cookiecutter', - '--no-input', - '-o', - '/output', - '/input', - '--verbose', - ], + command: 'cookiecutter', + args: ['--no-input', '-o', '/output', '/input', '--verbose'], envVars: { HOME: '/tmp' }, mountDirs: { [path.join('tempdir', 'template')]: '/input', @@ -208,14 +202,8 @@ describe('CookieCutter Templater', () => { expect(containerRunner.runContainer).toHaveBeenCalledWith({ imageName: 'spotify/backstage-cookiecutter', - args: [ - 'cookiecutter', - '--no-input', - '-o', - '/output', - '/input', - '--verbose', - ], + command: 'cookiecutter', + args: ['--no-input', '-o', '/output', '/input', '--verbose'], envVars: { HOME: '/tmp' }, mountDirs: { [path.join('tempdir', 'template')]: '/input', From fd9822432d86b47a62a6a156c04a64dbf44d7785 Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Mon, 3 May 2021 17:21:57 +0100 Subject: [PATCH 404/462] Group relations by kind and namespace Signed-off-by: Will Sewell <willsewell@monzo.com> --- .../src/hooks/useRelatedEntities.ts | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/plugins/catalog-react/src/hooks/useRelatedEntities.ts b/plugins/catalog-react/src/hooks/useRelatedEntities.ts index 25d96626d7..b47d941ff6 100644 --- a/plugins/catalog-react/src/hooks/useRelatedEntities.ts +++ b/plugins/catalog-react/src/hooks/useRelatedEntities.ts @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityRelation } from '@backstage/catalog-model'; import { useApi } from '@backstage/core'; -import { chunk } from 'lodash'; +import { chunk, groupBy } from 'lodash'; import { useAsync } from 'react-use'; import { catalogApiRef } from '../api'; @@ -43,25 +43,50 @@ export function useRelatedEntities( return []; } - // Make requests in separate batches to limit query string size - // (there is a `filter` param for each relation) - const relationBatches = chunk(relations, BATCH_SIZE); + // Group the relations by kind and namespace to reduce the size of the request query string. + // Without this grouping, the kind and namespace would need to be specified for each relation, e.g. + // `filter=kind=component,namespace=default,name=example1&filter=kind=component,namespace=default,name=example2` + // with grouping, we can generate a query a string like + // `filter=kind=component,namespace=default,name=example1,example2` + const relationsByKindAndNamespace: EntityRelation[][] = Object.values( + groupBy(relations, ({ target }) => { + return `${target.kind}:${target.namespace}`.toLowerCase(); + }), + ); + + // Split the names within each group into batches to further reduce the query string length. + const batchedRelationsByKindAndNamespace: { + kind: string; + namespace: string; + nameBatches: string[][]; + }[] = []; + for (const rs of relationsByKindAndNamespace) { + batchedRelationsByKindAndNamespace.push({ + // All relations in a group have the same kind and namespace, so its arbitrary which we pick + kind: rs[0].target.kind, + namespace: rs[0].target.namespace, + nameBatches: chunk( + rs.map(r => r.target.name), + BATCH_SIZE, + ), + }); + } const results = await Promise.all( - relationBatches.map(batch => { - return catalogApi.getEntities({ - filter: batch.map(({ target }) => { - return { - kind: target.kind, - 'metadata.name': target.name, - 'metadata.namespace': target.namespace, - }; - }), + batchedRelationsByKindAndNamespace.flatMap(rs => { + return rs.nameBatches.map(names => { + return catalogApi.getEntities({ + filter: { + kind: rs.kind, + 'metadata.namespace': rs.namespace, + 'metadata.name': names, + }, + }); }); }), ); - return results.map(r => r.items).flat(); + return results.flatMap(r => r.items); }, [entity, type]); return { From 4ca6998aad9767db9ccadea9a6d3a9651b5c74b1 Mon Sep 17 00:00:00 2001 From: Erik Larsson <erik.larsson@schibsted.com> Date: Tue, 4 May 2021 02:34:24 +0200 Subject: [PATCH 405/462] Remove deprecated condition Signed-off-by: Erik Larsson <erik.larsson@schibsted.com> --- .../src/reader/transformers/addGitFeedbackLink.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts index 5d45946238..0fc25d8cf3 100644 --- a/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts +++ b/plugins/techdocs/src/reader/transformers/addGitFeedbackLink.ts @@ -34,20 +34,12 @@ export const addGitFeedbackLink = ( if (!sourceAnchor || !sourceAnchor.href) { return dom; } - let gitHost = ''; const sourceURL = new URL(sourceAnchor.href); const integration = scmIntegrationsApi.byUrl(sourceURL); // don't show if can't identify edit link hostname as a gitlab/github hosting - if (integration?.type === 'github' || sourceURL.origin.includes('github')) { - gitHost = 'github'; - } else if ( - integration?.type === 'gitlab' || - sourceURL.origin.includes('gitlab') - ) { - gitHost = 'gitlab'; - } else { + if (integration?.type !== 'github' && integration?.type !== 'gitlab') { return dom; } @@ -61,7 +53,7 @@ export const addGitFeedbackLink = ( const repoPath = sourceURL.pathname.split('/').slice(0, 3).join('/'); const feedbackLink = sourceAnchor.cloneNode() as HTMLAnchorElement; - switch (gitHost) { + switch (integration?.type) { case 'gitlab': feedbackLink.href = `${sourceURL.origin}${repoPath}/issues/new?issue[title]=${issueTitle}&issue[description]=${issueDesc}`; break; From a3b310b7267c2ebe2d5a75c4c5e0c45da2d78fe1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 May 2021 04:22:50 +0000 Subject: [PATCH 406/462] chore(deps): bump core-js from 3.11.0 to 3.11.2 Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.11.0 to 3.11.2. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.11.2/packages/core-js) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8cb2ddd221..411c911199 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10491,9 +10491,9 @@ core-js-pure@^3.0.0, core-js-pure@^3.0.1: integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== core-js@3, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.5.0, core-js@^3.6.0, core-js@^3.6.5: - version "3.11.0" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.11.0.tgz#05dac6aa70c0a4ad842261f8957b961d36eb8926" - integrity sha512-bd79DPpx+1Ilh9+30aT5O1sgpQd4Ttg8oqkqi51ZzhedMM1omD2e6IOF48Z/DzDCZ2svp49tN/3vneTK6ZBkXw== + version "3.11.2" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.11.2.tgz#af087a43373fc6e72942917c4a4c3de43ed574d6" + integrity sha512-3tfrrO1JpJSYGKnd9LKTBPqgUES/UYiCzMKeqwR1+jF16q4kD1BY2NvqkfuzXwQ6+CIWm55V9cjD7PQd+hijdw== core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.10, core-js@^2.6.5: version "2.6.11" From 878a19f7a548c3ede499612660f615d424d1d947 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 May 2021 04:26:07 +0000 Subject: [PATCH 407/462] chore(deps): bump @types/ldapjs from 1.0.9 to 1.0.10 Bumps [@types/ldapjs](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ldapjs) from 1.0.9 to 1.0.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ldapjs) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8cb2ddd221..e2cba1dfa4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6303,9 +6303,9 @@ "@types/node" "*" "@types/ldapjs@^1.0.9": - version "1.0.9" - resolved "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-1.0.9.tgz#1224192d14cc5ab5218fcea72ebb04489c52cb95" - integrity sha512-3PvY7Drp1zoLbcGlothCAkoc5o6Jp9KvUPwHadlHyKp3yPvyeIh7w2zQc9UXMzgDRkoeGXUEODtbEs5XCh9ZyA== + version "1.0.10" + resolved "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-1.0.10.tgz#bac705c9e154b97d69496b5213cc28dbe9715a37" + integrity sha512-AMkMxkK/wjYtWebNH2O+rARfo7scBpW3T23g6zmGCwDgbyDbR79XWpcSqhPWdU+fChaF+I3dVyl9X2dT1CyI9w== dependencies: "@types/node" "*" From 81b609f01049ef8902bd47c405eabc33460731e1 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Fri, 30 Apr 2021 09:55:44 +0200 Subject: [PATCH 408/462] chore: test for getProcessableEntities Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index d76bd74260..ae17746799 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -514,4 +514,48 @@ describe('Default Processing Database', () => { }); }); }); + + describe('getProcessableEntities', () => { + it('should return entities to process', async () => { + const entity = JSON.stringify({ + apiVersion: '1.0.0', + metadata: { + name: 'xyz', + }, + kind: 'Location', + } as Entity); + await db<DbRefreshStateRow>('refresh_state').insert({ + entity_id: '2', + entity_ref: 'location:default/new-root', + unprocessed_entity: entity, + errors: '', + next_update_at: '2019-01-01 23:00:00', + last_discovery_at: 'now()', + }); + await db<DbRefreshStateRow>('refresh_state').insert({ + entity_id: '1', + entity_ref: 'location:default/foobar', + unprocessed_entity: entity, + errors: '', + next_update_at: '2042-01-01 23:00:00', + last_discovery_at: 'now()', + }); + + await processingDatabase.transaction(async tx => { + // request two items but only one can be processed. + const result = await processingDatabase.getProcessableEntities(tx, { + processBatchSize: 2, + }); + expect(result.items.length).toEqual(1); + expect(result.items[0].entityRef).toEqual('location:default/new-root'); + + // should not return the same item as there's nothing left to process. + await expect( + processingDatabase.getProcessableEntities(tx, { + processBatchSize: 2, + }), + ).resolves.toEqual({ items: [] }); + }); + }); + }); }); From f0f77473e0a75b45014e8a40ae5dd0d989f8eda6 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 29 Apr 2021 17:51:42 +0200 Subject: [PATCH 409/462] chore: add some more tests for TransactionValue Signed-off-by: blam <ben@blam.sh> --- .../src/next/Context/TransactionValue.test.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 plugins/catalog-backend/src/next/Context/TransactionValue.test.ts diff --git a/plugins/catalog-backend/src/next/Context/TransactionValue.test.ts b/plugins/catalog-backend/src/next/Context/TransactionValue.test.ts new file mode 100644 index 0000000000..97e554d0f6 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/TransactionValue.test.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TransactionValue } from './TransactionValue'; +import { Knex } from 'knex'; +import { BackgroundContext } from './BackgroundContext'; + +describe('TransactionValue Context', () => { + it('should be able to store tx values and retrieve them from a context', () => { + const tx = {} as Knex.Transaction; + const ctx = new BackgroundContext(); + + const nextCtx = TransactionValue.in(ctx, tx); + + expect(TransactionValue.from(nextCtx)).toBe(tx); + }); + + it('should throw when there is no tx value in the context', () => { + const ctx = new BackgroundContext(); + + expect(() => TransactionValue.from(ctx)).toThrow( + /No transaction available in context/, + ); + }); +}); From 8ecfa8e1ed494906068cbe52849d45b126309d20 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 30 Apr 2021 09:53:52 +0200 Subject: [PATCH 410/462] chore: added some moar tests for ProcessingDatabase Signed-off-by: blam <ben@blam.sh> --- .../DefaultProcessingDatabase.test.ts | 266 +++++++++++------- .../database/DefaultProcessingDatabase.ts | 1 + 2 files changed, 170 insertions(+), 97 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index ae17746799..46545771c0 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -23,15 +23,26 @@ import { DefaultProcessingDatabase, } from './DefaultProcessingDatabase'; -import { Entity, EntityRelationSpec } from '@backstage/catalog-model'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import * as uuid from 'uuid'; import { getVoidLogger } from '@backstage/backend-common'; +import { JsonObject } from '@backstage/config'; describe('Default Processing Database', () => { let db: Knex; let processingDatabase: DefaultProcessingDatabase; const logger = getVoidLogger(); + const insertRefRow = async (ref: DbRefreshStateReferencesRow) => { + return db<DbRefreshStateReferencesRow>('refresh_state_references').insert( + ref, + ); + }; + + const insertRefreshStateRow = async (ref: DbRefreshStateRow) => { + await db<DbRefreshStateRow>('refresh_state').insert(ref); + }; + beforeEach(async () => { db = await DatabaseManager.createTestDatabaseConnection(); await DatabaseManager.createDatabase(db); @@ -39,17 +50,160 @@ describe('Default Processing Database', () => { processingDatabase = new DefaultProcessingDatabase(db, logger); }); - describe('replaceUnprocessedEntities', () => { - const insertRefRow = async (ref: DbRefreshStateReferencesRow) => { - return db<DbRefreshStateReferencesRow>('refresh_state_references').insert( - ref, + describe('updateProcessedEntity', () => { + let id: string; + let processedEntity: Entity; + + beforeEach(() => { + id = uuid.v4(); + processedEntity = { + apiVersion: '1', + kind: 'Location', + metadata: { + name: 'fakelocation', + }, + spec: { + type: 'url', + target: 'somethingelse', + }, + }; + }); + + it('fails when there is no processing state for the entity', async () => { + await processingDatabase.transaction(async tx => { + await expect(() => + processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity, + state: new Map<string, JsonObject>(), + relations: [], + deferredEntities: [], + }), + ).rejects.toThrow(`Processing state not found for ${id}`); + }); + }); + + it('updates the refresh state entry with the cache, processed entity and errors', async () => { + await insertRefreshStateRow({ + entity_id: id, + entity_ref: 'location:default/fakelocation', + unprocessed_entity: '{}', + processed_entity: '{}', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + + const state = new Map<string, JsonObject>(); + state.set('hello', { t: 'something' }); + + await processingDatabase.transaction(tx => + processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity, + state, + relations: [], + deferredEntities: [], + errors: 'something broke', + }), ); - }; - const insertRefreshStateRow = async (ref: DbRefreshStateRow) => { - await db<DbRefreshStateRow>('refresh_state').insert(ref); - }; + const [entity] = await db<DbRefreshStateRow>('refresh_state').select(); + expect(entity.processed_entity).toEqual(JSON.stringify(processedEntity)); + expect(entity.cache).toEqual(JSON.stringify(state)); + expect(entity.errors).toEqual('something broke'); + }); + + it('removes old relations and stores the new relationships', async () => { + await insertRefreshStateRow({ + entity_id: id, + entity_ref: 'location:default/fakelocation', + unprocessed_entity: '{}', + processed_entity: '{}', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + + const relations = [ + { + source: { + kind: 'Component', + namespace: 'Default', + name: 'foo', + }, + target: { + kind: 'Component', + namespace: 'Default', + name: 'foo', + }, + type: 'memberOf', + }, + ]; + + await processingDatabase.transaction(tx => + processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity, + state: new Map<string, JsonObject>(), + relations: relations, + deferredEntities: [], + }), + ); + + const [savedRelations] = await db<DbRelationsRow>('relations') + .where({ originating_entity_id: id }) + .select(); + + expect(savedRelations).toEqual({ + originating_entity_id: id, + source_entity_ref: 'component:default/foo', + type: 'memberOf', + target_entity_ref: 'component:default/foo', + }); + }); + + it('adds deferred entities to the the refresh_state table to be picked up later', async () => { + await insertRefreshStateRow({ + entity_id: id, + entity_ref: 'location:default/fakelocation', + unprocessed_entity: '{}', + processed_entity: '{}', + errors: '', + next_update_at: 'now()', + last_discovery_at: 'now()', + }); + + const deferredEntities = [ + { + apiVersion: '1', + kind: 'Location', + metadata: { + name: 'next', + }, + }, + ]; + + await processingDatabase.transaction(tx => + processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity, + state: new Map<string, JsonObject>(), + relations: [], + deferredEntities, + }), + ); + + const refreshStateEntries = await db<DbRefreshStateRow>('refresh_state') + .where({ entity_ref: stringifyEntityRef(deferredEntities[0]) }) + .select(); + + expect(refreshStateEntries).toHaveLength(1); + }); + }); + + describe('replaceUnprocessedEntities', () => { const createLocations = async (entityRefs: string[]) => { for (const ref of entityRefs) { await insertRefreshStateRow({ @@ -101,8 +255,8 @@ describe('Default Processing Database', () => { target_entity_ref: 'location:default/root-2', }); - await processingDatabase.transaction(async tx => { - await processingDatabase.replaceUnprocessedEntities(tx, { + await processingDatabase.transaction(tx => + processingDatabase.replaceUnprocessedEntities(tx, { type: 'full', sourceKey: 'config', items: [ @@ -114,8 +268,8 @@ describe('Default Processing Database', () => { kind: 'Location', } as Entity, ], - }); - }); + }), + ); const currentRefreshState = await db<DbRefreshStateRow>( 'refresh_state', @@ -431,90 +585,6 @@ describe('Default Processing Database', () => { }); }); - describe('updateProcessedEntity', () => { - it('should throw if the entity does not exist', async () => { - await processingDatabase.transaction(async tx => { - await expect( - processingDatabase.updateProcessedEntity(tx, { - id: '9', - processedEntity: { - apiVersion: '1.0.0', - metadata: { - name: 'new-root', - }, - kind: 'Location', - } as Entity, - deferredEntities: [], - relations: [], - }), - ).rejects.toThrow('Processing state not found for 9'); - }); - }); - - it('should update a processed entity', async () => { - await db<DbRefreshStateRow>('refresh_state').insert({ - entity_id: '321', - entity_ref: 'location:default/new-root', - unprocessed_entity: '', - errors: '', - next_update_at: 'now()', - last_discovery_at: 'now()', - }); - - const deferredEntity = { - apiVersion: '1.0.0', - metadata: { - name: 'deferred', - }, - kind: 'Location', - } as Entity; - - const relation: EntityRelationSpec = { - source: { - kind: 'Component', - namespace: 'Default', - name: 'foo', - }, - target: { - kind: 'Component', - namespace: 'Default', - name: 'foo', - }, - type: 'url', - }; - - await processingDatabase.transaction(async tx => { - await processingDatabase.updateProcessedEntity(tx, { - id: '321', - processedEntity: { - apiVersion: '1.0.0', - metadata: { - name: 'new-root', - }, - kind: 'Location', - } as Entity, - deferredEntities: [deferredEntity], - relations: [relation], - }); - }); - - const deferredResult = await db<DbRefreshStateRow>('refresh_state') - .where({ entity_ref: 'location:default/deferred' }) - .select(); - expect(deferredResult.length).toBe(1); - - const [relations] = await db<DbRelationsRow>('relations') - .where({ originating_entity_id: '321' }) - .select(); - expect(relations).toEqual({ - originating_entity_id: '321', - source_entity_ref: 'component:default/foo', - type: 'url', - target_entity_ref: 'component:default/foo', - }); - }); - }); - describe('getProcessableEntities', () => { it('should return entities to process', async () => { const entity = JSON.stringify({ @@ -524,6 +594,7 @@ describe('Default Processing Database', () => { }, kind: 'Location', } as Entity); + await db<DbRefreshStateRow>('refresh_state').insert({ entity_id: '2', entity_ref: 'location:default/new-root', @@ -532,6 +603,7 @@ describe('Default Processing Database', () => { next_update_at: '2019-01-01 23:00:00', last_discovery_at: 'now()', }); + await db<DbRefreshStateRow>('refresh_state').insert({ entity_id: '1', entity_ref: 'location:default/foobar', diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index dc5e6036f5..984e7776ea 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -87,6 +87,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .update({ processed_entity: JSON.stringify(processedEntity), cache: JSON.stringify(state), + // TODO: should this also be JSON stringfy? errors, }) .where('entity_id', id); From 45ca6c76992fa8f86e9977222f54cdbb46a89247 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 10:53:36 +0200 Subject: [PATCH 411/462] Refactor StateManager into the ProcessingEngine And add some tests Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- packages/backend/src/plugins/catalog.ts | 2 +- .../DefaultCatalogProcessingEngine.test.ts | 95 +++++++++++++++ .../next/DefaultCatalogProcessingEngine.ts | 112 ++++++++++-------- .../src/next/DefaultProcessingStateManager.ts | 69 ----------- .../src/next/NextCatalogBuilder.ts | 5 +- plugins/catalog-backend/src/next/types.ts | 34 ------ 6 files changed, 160 insertions(+), 157 deletions(-) create mode 100644 plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts delete mode 100644 plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index e58d8cd3eb..7651836e2a 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -42,7 +42,7 @@ export default async function createPlugin( } = await builder.build(); // TODO(jhaals): run and manage in background. - processingEngine.start(); + await processingEngine.start(); return await createRouter({ entitiesCatalog, diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts new file mode 100644 index 0000000000..68ae8150d1 --- /dev/null +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts @@ -0,0 +1,95 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; + +import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; +import { Stitcher } from './Stitcher'; +import { CatalogProcessingOrchestrator } from './types'; + +describe('DefaultCatalogProcessingEngine', () => { + const db = ({ + transaction: jest.fn(), + getProcessableEntities: jest.fn(), + updateProcessedEntity: jest.fn(), + } as unknown) as jest.Mocked<DefaultProcessingDatabase>; + const orchestrator: jest.Mocked<CatalogProcessingOrchestrator> = { + process: jest.fn(), + }; + const stitcher = ({ + stitch: jest.fn(), + } as unknown) as jest.Mocked<Stitcher>; + + beforeEach(() => { + jest.resetAllMocks(); + }); + it('should process stuff', async () => { + orchestrator.process.mockResolvedValue({ + ok: true, + completedEntity: { + apiVersion: '1', + kind: 'Location', + metadata: { name: 'test' }, + }, + relations: [], + errors: [], + deferredEntities: [], + state: new Map(), + }); + const engine = new DefaultCatalogProcessingEngine( + getVoidLogger(), + [], + db, + orchestrator, + stitcher, + ); + + db.transaction.mockImplementation(cb => cb((() => {}) as any)); + + db.getProcessableEntities + .mockImplementation(async () => { + await engine.stop(); + return { items: [] }; + }) + .mockResolvedValueOnce({ + items: [ + { + entityRef: 'foo', + id: '1', + unprocessedEntity: { + apiVersion: '1', + kind: 'Location', + metadata: { name: 'test' }, + }, + state: new Map(), + nextUpdateAt: '', + lastDiscoveryAt: '', + }, + ], + }); + + await engine.start(); + await new Promise<void>(resolve => setTimeout(resolve, 1)); + expect(orchestrator.process).toBeCalledTimes(1); + expect(orchestrator.process).toBeCalledWith({ + entity: { apiVersion: '1', kind: 'Location', metadata: { name: 'test' } }, + state: expect.anything(), + }); + + await engine.stop(); + }); +}); diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index e724fe79d8..c8c49e4bd9 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -16,6 +16,7 @@ import { stringifyEntityRef } from '@backstage/catalog-model'; import { Logger } from 'winston'; +import { ProcessingDatabase } from './database/types'; import { Stitcher } from './Stitcher'; import { CatalogProcessingEngine, @@ -23,44 +24,46 @@ import { EntityProvider, EntityProviderConnection, EntityProviderMutation, - ProcessingStateManager, } from './types'; class Connection implements EntityProviderConnection { constructor( private readonly config: { - stateManager: ProcessingStateManager; + processingDatabase: ProcessingDatabase; id: string; }, ) {} async applyMutation(mutation: EntityProviderMutation): Promise<void> { + const db = this.config.processingDatabase; if (mutation.type === 'full') { - await this.config.stateManager.replaceProcessingItems({ - sourceKey: this.config.id, - type: 'full', - items: mutation.entities, + db.transaction(async tx => { + await db.replaceUnprocessedEntities(tx, { + sourceKey: this.config.id, + type: 'full', + items: mutation.entities, + }); }); - return; } - - await this.config.stateManager.replaceProcessingItems({ - sourceKey: this.config.id, - type: 'delta', - added: mutation.added, - removed: mutation.removed, + db.transaction(async tx => { + await db.replaceUnprocessedEntities(tx, { + sourceKey: this.config.id, + type: 'delta', + added: mutation.added, + removed: mutation.removed, + }); }); } } export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { - private running: boolean = false; + private running = false; constructor( private readonly logger: Logger, private readonly entityProviders: EntityProvider[], - private readonly stateManager: ProcessingStateManager, + private readonly processingDatabase: ProcessingDatabase, private readonly orchestrator: CatalogProcessingOrchestrator, private readonly stitcher: Stitcher, ) {} @@ -69,51 +72,60 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { for (const provider of this.entityProviders) { await provider.connect( new Connection({ - stateManager: this.stateManager, + processingDatabase: this.processingDatabase, id: provider.getProviderName(), }), ); } - this.running = true; + this.run(); + } + private async run() { while (this.running) { - const { - id, - entity, - state: initialState, - } = await this.stateManager.getNextProcessingItem(); - - const result = await this.orchestrator.process({ - entity, - state: initialState, + const { items } = await this.processingDatabase.transaction(async tx => { + return this.processingDatabase.getProcessableEntities(tx, { + processBatchSize: 1, + }); }); - for (const error of result.errors) { - this.logger.warn(error.message); + if (items.length) { + const { id, state, unprocessedEntity } = items[0]; + + const result = await this.orchestrator.process({ + entity: unprocessedEntity, + state, + }); + for (const error of result.errors) { + this.logger.warn(error.message); + } + if (!result.ok) { + return; + } + + result.completedEntity.metadata.uid = id; + await this.processingDatabase.transaction(async tx => { + await this.processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity: result.completedEntity, + state: result.state, + errors: JSON.stringify(result.errors), + relations: result.relations, + deferredEntities: result.deferredEntities, + }); + }); + + const setOfThingsToStitch = new Set<string>([ + stringifyEntityRef(result.completedEntity), + ...result.relations.map(relation => + stringifyEntityRef(relation.source), + ), + ]); + await this.stitcher.stitch(setOfThingsToStitch); + } else { + // Wait one second before fetching next item. + await new Promise<void>(resolve => setTimeout(resolve, 1000)); } - - if (!result.ok) { - return; - } - - result.completedEntity.metadata.uid = id; - await this.stateManager.setProcessingItemResult({ - id, - entity: result.completedEntity, - state: result.state, - errors: result.errors, - relations: result.relations, - deferredEntities: result.deferredEntities, - }); - - const setOfThingsToStitch = new Set<string>([ - stringifyEntityRef(result.completedEntity), - ...result.relations.map(relation => - stringifyEntityRef(relation.source), - ), - ]); - await this.stitcher.stitch(setOfThingsToStitch); } } diff --git a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts b/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts deleted file mode 100644 index 9c1d20ae9c..0000000000 --- a/plugins/catalog-backend/src/next/DefaultProcessingStateManager.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2021 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ProcessingDatabase } from './database/types'; -import { - ProcessingItem, - ProcessingItemResult, - ProcessingStateManager, - ReplaceProcessingItemsRequest, -} from './types'; - -export class DefaultProcessingStateManager implements ProcessingStateManager { - constructor(private readonly db: ProcessingDatabase) {} - - replaceProcessingItems( - request: ReplaceProcessingItemsRequest, - ): Promise<void> { - return this.db.transaction(async tx => { - await this.db.replaceUnprocessedEntities(tx, request); - }); - } - - async setProcessingItemResult(result: ProcessingItemResult) { - return this.db.transaction(async tx => { - await this.db.updateProcessedEntity(tx, { - id: result.id, - processedEntity: result.entity, - errors: JSON.stringify(result.errors), - state: result.state, - relations: result.relations, - deferredEntities: result.deferredEntities, - }); - }); - } - - async getNextProcessingItem(): Promise<ProcessingItem> { - for (;;) { - const { items } = await this.db.transaction(async tx => { - return this.db.getProcessableEntities(tx, { - processBatchSize: 1, - }); - }); - - if (items.length) { - const { id, state, unprocessedEntity } = items[0]; - return { - id, - entity: unprocessedEntity, - state, - }; - } - - await new Promise<void>(resolve => setTimeout(resolve, 1000)); - } - } -} diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 10500fdc15..dc09013964 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -69,7 +69,6 @@ import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase' import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; import { DefaultLocationStore } from './DefaultLocationStore'; -import { DefaultProcessingStateManager } from './DefaultProcessingStateManager'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; @@ -252,7 +251,7 @@ export class NextCatalogBuilder { const db = new CommonDatabase(dbClient, logger); const processingDatabase = new DefaultProcessingDatabase(dbClient, logger); - const stateManager = new DefaultProcessingStateManager(processingDatabase); + // const stateManager = new DefaultProcessingStateManager(processingDatabase); const integrations = ScmIntegrations.fromConfig(config); const orchestrator = new DefaultCatalogProcessingOrchestrator({ processors, @@ -269,7 +268,7 @@ export class NextCatalogBuilder { const processingEngine = new DefaultCatalogProcessingEngine( logger, [locationStore, configLocationProvider], - stateManager, + processingDatabase, orchestrator, stitcher, ); diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 202576fddd..410066eafd 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -80,37 +80,3 @@ export type EntityProcessingResult = export interface CatalogProcessingOrchestrator { process(request: EntityProcessingRequest): Promise<EntityProcessingResult>; } - -export type ProcessingItemResult = { - id: string; - entity: Entity; - state: Map<string, JsonObject>; - errors: Error[]; - relations: EntityRelationSpec[]; - deferredEntities: Entity[]; -}; - -export type ProcessingItem = { - id: string; - entity: Entity; - state: Map<string, JsonObject>; -}; - -export type ReplaceProcessingItemsRequest = - | { - sourceKey: string; - items: Entity[]; - type: 'full'; - } - | { - sourceKey: string; - added: Entity[]; - removed: Entity[]; - type: 'delta'; - }; - -export interface ProcessingStateManager { - setProcessingItemResult(result: ProcessingItemResult): Promise<void>; - getNextProcessingItem(): Promise<ProcessingItem>; - replaceProcessingItems(request: ReplaceProcessingItemsRequest): Promise<void>; -} From 0bd4dfa9d2c1de30ab54a038393466b7b3b59d8a Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 13:52:05 +0200 Subject: [PATCH 412/462] Fix review comments Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultProcessingDatabase.test.ts | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts index 46545771c0..7a0094dbf0 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.test.ts @@ -89,9 +89,9 @@ describe('Default Processing Database', () => { entity_ref: 'location:default/fakelocation', unprocessed_entity: '{}', processed_entity: '{}', - errors: '', - next_update_at: 'now()', - last_discovery_at: 'now()', + errors: '[]', + next_update_at: '2021-04-01 13:37:00', + last_discovery_at: '2021-04-01 13:37:00', }); const state = new Map<string, JsonObject>(); @@ -104,15 +104,17 @@ describe('Default Processing Database', () => { state, relations: [], deferredEntities: [], - errors: 'something broke', + errors: "['something broke']", }), ); - const [entity] = await db<DbRefreshStateRow>('refresh_state').select(); - - expect(entity.processed_entity).toEqual(JSON.stringify(processedEntity)); - expect(entity.cache).toEqual(JSON.stringify(state)); - expect(entity.errors).toEqual('something broke'); + const entities = await db<DbRefreshStateRow>('refresh_state').select(); + expect(entities.length).toBe(1); + expect(entities[0].processed_entity).toEqual( + JSON.stringify(processedEntity), + ); + expect(entities[0].cache).toEqual(JSON.stringify(state)); + expect(entities[0].errors).toEqual("['something broke']"); }); it('removes old relations and stores the new relationships', async () => { @@ -121,9 +123,9 @@ describe('Default Processing Database', () => { entity_ref: 'location:default/fakelocation', unprocessed_entity: '{}', processed_entity: '{}', - errors: '', - next_update_at: 'now()', - last_discovery_at: 'now()', + errors: '[]', + next_update_at: '2021-04-01 13:37:00', + last_discovery_at: '2021-04-01 13:37:00', }); const relations = [ @@ -152,11 +154,11 @@ describe('Default Processing Database', () => { }), ); - const [savedRelations] = await db<DbRelationsRow>('relations') + const savedRelations = await db<DbRelationsRow>('relations') .where({ originating_entity_id: id }) .select(); - - expect(savedRelations).toEqual({ + expect(savedRelations.length).toBe(1); + expect(savedRelations[0]).toEqual({ originating_entity_id: id, source_entity_ref: 'component:default/foo', type: 'memberOf', @@ -170,9 +172,9 @@ describe('Default Processing Database', () => { entity_ref: 'location:default/fakelocation', unprocessed_entity: '{}', processed_entity: '{}', - errors: '', - next_update_at: 'now()', - last_discovery_at: 'now()', + errors: '[]', + next_update_at: '2021-04-01 13:37:00', + last_discovery_at: '2021-04-01 13:37:00', }); const deferredEntities = [ @@ -211,9 +213,9 @@ describe('Default Processing Database', () => { entity_ref: ref, unprocessed_entity: '{}', processed_entity: '{}', - errors: '', - next_update_at: 'now()', - last_discovery_at: 'now()', + errors: '[]', + next_update_at: '2021-04-01 13:37:00', + last_discovery_at: '2021-04-01 13:37:00', }); } }; @@ -588,29 +590,29 @@ describe('Default Processing Database', () => { describe('getProcessableEntities', () => { it('should return entities to process', async () => { const entity = JSON.stringify({ + kind: 'Location', apiVersion: '1.0.0', metadata: { name: 'xyz', }, - kind: 'Location', } as Entity); await db<DbRefreshStateRow>('refresh_state').insert({ entity_id: '2', entity_ref: 'location:default/new-root', unprocessed_entity: entity, - errors: '', + errors: '[]', next_update_at: '2019-01-01 23:00:00', - last_discovery_at: 'now()', + last_discovery_at: '2021-04-01 13:37:00', }); await db<DbRefreshStateRow>('refresh_state').insert({ entity_id: '1', entity_ref: 'location:default/foobar', unprocessed_entity: entity, - errors: '', + errors: '[]', next_update_at: '2042-01-01 23:00:00', - last_discovery_at: 'now()', + last_discovery_at: '2021-04-01 13:37:00', }); await processingDatabase.transaction(async tx => { From 852b6bec95871b735cf2aacec3b8228a329dc7c0 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 14:13:25 +0200 Subject: [PATCH 413/462] Wrap test in waitForExpect Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/package.json | 3 ++- .../next/DefaultCatalogProcessingEngine.test.ts | 17 +++++++++++------ yarn.lock | 16 +++++++++++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 7649067a44..99df0acd09 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -73,7 +73,8 @@ "@types/yup": "^0.29.8", "msw": "^0.21.2", "sqlite3": "^5.0.0", - "supertest": "^6.1.3" + "supertest": "^6.1.3", + "wait-for-expect": "^3.0.2" }, "files": [ "dist", diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts index 68ae8150d1..b6363a697d 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts @@ -20,6 +20,7 @@ import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase' import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { Stitcher } from './Stitcher'; import { CatalogProcessingOrchestrator } from './types'; +import waitForExpect from 'wait-for-expect'; describe('DefaultCatalogProcessingEngine', () => { const db = ({ @@ -83,13 +84,17 @@ describe('DefaultCatalogProcessingEngine', () => { }); await engine.start(); - await new Promise<void>(resolve => setTimeout(resolve, 1)); - expect(orchestrator.process).toBeCalledTimes(1); - expect(orchestrator.process).toBeCalledWith({ - entity: { apiVersion: '1', kind: 'Location', metadata: { name: 'test' } }, - state: expect.anything(), + await waitForExpect(() => { + expect(orchestrator.process).toBeCalledTimes(1); + expect(orchestrator.process).toBeCalledWith({ + entity: { + apiVersion: '1', + kind: 'Location', + metadata: { name: 'test' }, + }, + state: expect.anything(), + }); }); - await engine.stop(); }); }); diff --git a/yarn.lock b/yarn.lock index bffef20f24..4d3c45ab5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14482,7 +14482,7 @@ graphql-extensions@^0.12.8: apollo-server-env "^3.0.0" apollo-server-types "^0.6.3" -graphql-language-service-interface@2.8.2, graphql-language-service-interface@^2.8.2: +graphql-language-service-interface@^2.8.2: version "2.8.2" resolved "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.8.2.tgz#b3bb2aef7eaf0dff0b4ea419fa412c5f66fa268b" integrity sha512-otbOQmhgkAJU1QJgQkMztNku6SbJLu/uodoFOYOOtJsizTjrMs93vkYaHCcYnLA3oi1Goj27XcHjMnRCYQOZXQ== @@ -14492,7 +14492,7 @@ graphql-language-service-interface@2.8.2, graphql-language-service-interface@^2. graphql-language-service-utils "^2.5.1" vscode-languageserver-types "^3.15.1" -graphql-language-service-parser@1.9.0, graphql-language-service-parser@^1.9.0: +graphql-language-service-parser@^1.9.0: version "1.9.0" resolved "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.9.0.tgz#79af21294119a0a7e81b6b994a1af36833bab724" integrity sha512-B5xPZLbBmIp0kHvpY1Z35I5DtPoDK9wGxQVRDIzcBaiIvAmlTrDvjo3bu7vKREdjFbYKvWNgrEWENuprMbF17Q== @@ -25796,11 +25796,16 @@ typescript-json-schema@^0.49.0: typescript "^4.1.3" yargs "^16.2.0" -typescript@^4.0.3, typescript@^4.1.3, typescript@~4.1.3: +typescript@^4.0.3, typescript@^4.1.3: version "4.2.3" resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== +typescript@~4.1.3: + version "4.1.5" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" + integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== + ua-parser-js@^0.7.18: version "0.7.21" resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" @@ -26444,6 +26449,11 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" +wait-for-expect@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463" + integrity sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag== + wait-on@5.3.0: version "5.3.0" resolved "https://registry.npmjs.org/wait-on/-/wait-on-5.3.0.tgz#584e17d4b3fe7b46ac2b9f8e5e102c005c2776c7" From fe84fb2fdcb355ad2e63c83d09add0b8ef9f1bc2 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 14:14:57 +0200 Subject: [PATCH 414/462] Await transactions Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultCatalogProcessingEngine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index c8c49e4bd9..6bee54f153 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -37,7 +37,7 @@ class Connection implements EntityProviderConnection { async applyMutation(mutation: EntityProviderMutation): Promise<void> { const db = this.config.processingDatabase; if (mutation.type === 'full') { - db.transaction(async tx => { + await db.transaction(async tx => { await db.replaceUnprocessedEntities(tx, { sourceKey: this.config.id, type: 'full', @@ -46,7 +46,7 @@ class Connection implements EntityProviderConnection { }); return; } - db.transaction(async tx => { + await db.transaction(async tx => { await db.replaceUnprocessedEntities(tx, { sourceKey: this.config.id, type: 'delta', From e9d61bcbeba2d202be39b456e3ed46640ad1a91c Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 14:30:40 +0200 Subject: [PATCH 415/462] Ensure that processing continues despite errors Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../DefaultCatalogProcessingEngine.test.ts | 61 ++++++++++++ .../next/DefaultCatalogProcessingEngine.ts | 97 +++++++++++-------- 2 files changed, 118 insertions(+), 40 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts index b6363a697d..376af6e748 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.test.ts @@ -97,4 +97,65 @@ describe('DefaultCatalogProcessingEngine', () => { }); await engine.stop(); }); + + it('should process stuff even if the first attempt fail', async () => { + orchestrator.process.mockResolvedValue({ + ok: true, + completedEntity: { + apiVersion: '1', + kind: 'Location', + metadata: { name: 'test' }, + }, + relations: [], + errors: [], + deferredEntities: [], + state: new Map(), + }); + const engine = new DefaultCatalogProcessingEngine( + getVoidLogger(), + [], + db, + orchestrator, + stitcher, + ); + + db.transaction.mockImplementation(cb => cb((() => {}) as any)); + + db.getProcessableEntities + .mockImplementation(async () => { + await engine.stop(); + return { items: [] }; + }) + .mockRejectedValueOnce(new Error('I FAILED')) + .mockResolvedValueOnce({ + items: [ + { + entityRef: 'foo', + id: '1', + unprocessedEntity: { + apiVersion: '1', + kind: 'Location', + metadata: { name: 'test' }, + }, + state: new Map(), + nextUpdateAt: '', + lastDiscoveryAt: '', + }, + ], + }); + + await engine.start(); + await waitForExpect(() => { + expect(orchestrator.process).toBeCalledTimes(1); + expect(orchestrator.process).toBeCalledWith({ + entity: { + apiVersion: '1', + kind: 'Location', + metadata: { name: 'test' }, + }, + state: expect.anything(), + }); + }); + await engine.stop(); + }); }); diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 6bee54f153..877c3075aa 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -83,52 +83,69 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { private async run() { while (this.running) { - const { items } = await this.processingDatabase.transaction(async tx => { - return this.processingDatabase.getProcessableEntities(tx, { - processBatchSize: 1, + try { + // TODO: We want to disconnect the queue popping and message processing + // so that if the queue popping fails we exponentially back off in order to give the DB room to sort itself out. + await this.process(); + } catch (e) { + this.logger.warn('Processing failed with:', e); + // TODO: this can be a little smarter as mentioned in the above comment. + // But for now, if something fails, wait a brief time to pick up the next message. + await this.wait(); + } + } + } + + private async process() { + const { items } = await this.processingDatabase.transaction(async tx => { + return this.processingDatabase.getProcessableEntities(tx, { + processBatchSize: 1, + }); + }); + + if (items.length) { + const { id, state, unprocessedEntity } = items[0]; + + const result = await this.orchestrator.process({ + entity: unprocessedEntity, + state, + }); + for (const error of result.errors) { + this.logger.warn(error.message); + } + if (!result.ok) { + return; + } + + result.completedEntity.metadata.uid = id; + await this.processingDatabase.transaction(async tx => { + await this.processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity: result.completedEntity, + state: result.state, + errors: JSON.stringify(result.errors), + relations: result.relations, + deferredEntities: result.deferredEntities, }); }); - if (items.length) { - const { id, state, unprocessedEntity } = items[0]; - - const result = await this.orchestrator.process({ - entity: unprocessedEntity, - state, - }); - for (const error of result.errors) { - this.logger.warn(error.message); - } - if (!result.ok) { - return; - } - - result.completedEntity.metadata.uid = id; - await this.processingDatabase.transaction(async tx => { - await this.processingDatabase.updateProcessedEntity(tx, { - id, - processedEntity: result.completedEntity, - state: result.state, - errors: JSON.stringify(result.errors), - relations: result.relations, - deferredEntities: result.deferredEntities, - }); - }); - - const setOfThingsToStitch = new Set<string>([ - stringifyEntityRef(result.completedEntity), - ...result.relations.map(relation => - stringifyEntityRef(relation.source), - ), - ]); - await this.stitcher.stitch(setOfThingsToStitch); - } else { - // Wait one second before fetching next item. - await new Promise<void>(resolve => setTimeout(resolve, 1000)); - } + const setOfThingsToStitch = new Set<string>([ + stringifyEntityRef(result.completedEntity), + ...result.relations.map(relation => + stringifyEntityRef(relation.source), + ), + ]); + await this.stitcher.stitch(setOfThingsToStitch); + } else { + // No items to process, wait and try again. + await this.wait(); } } + private async wait() { + await new Promise<void>(resolve => setTimeout(resolve, 1000)); + } + async stop() { this.running = false; } From cd33a8cd26b95182eedc8e274a61686f00fbc9bb Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 14:42:06 +0200 Subject: [PATCH 416/462] Reduce if block Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../next/DefaultCatalogProcessingEngine.ts | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts index 877c3075aa..55cb8e2029 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingEngine.ts @@ -103,43 +103,42 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { }); }); - if (items.length) { - const { id, state, unprocessedEntity } = items[0]; - - const result = await this.orchestrator.process({ - entity: unprocessedEntity, - state, - }); - for (const error of result.errors) { - this.logger.warn(error.message); - } - if (!result.ok) { - return; - } - - result.completedEntity.metadata.uid = id; - await this.processingDatabase.transaction(async tx => { - await this.processingDatabase.updateProcessedEntity(tx, { - id, - processedEntity: result.completedEntity, - state: result.state, - errors: JSON.stringify(result.errors), - relations: result.relations, - deferredEntities: result.deferredEntities, - }); - }); - - const setOfThingsToStitch = new Set<string>([ - stringifyEntityRef(result.completedEntity), - ...result.relations.map(relation => - stringifyEntityRef(relation.source), - ), - ]); - await this.stitcher.stitch(setOfThingsToStitch); - } else { + if (!items.length) { // No items to process, wait and try again. await this.wait(); + return; } + + const { id, state, unprocessedEntity } = items[0]; + + const result = await this.orchestrator.process({ + entity: unprocessedEntity, + state, + }); + for (const error of result.errors) { + this.logger.warn(error.message); + } + if (!result.ok) { + return; + } + + result.completedEntity.metadata.uid = id; + await this.processingDatabase.transaction(async tx => { + await this.processingDatabase.updateProcessedEntity(tx, { + id, + processedEntity: result.completedEntity, + state: result.state, + errors: JSON.stringify(result.errors), + relations: result.relations, + deferredEntities: result.deferredEntities, + }); + }); + + const setOfThingsToStitch = new Set<string>([ + stringifyEntityRef(result.completedEntity), + ...result.relations.map(relation => stringifyEntityRef(relation.source)), + ]); + await this.stitcher.stitch(setOfThingsToStitch); } private async wait() { From cb10731dfa13c558e68ed3a85dc8e107c32a770b Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 14:54:57 +0200 Subject: [PATCH 417/462] Drop references to deleted code Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/NextCatalogBuilder.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index dc09013964..0158cc9fc9 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -251,7 +251,6 @@ export class NextCatalogBuilder { const db = new CommonDatabase(dbClient, logger); const processingDatabase = new DefaultProcessingDatabase(dbClient, logger); - // const stateManager = new DefaultProcessingStateManager(processingDatabase); const integrations = ScmIntegrations.fromConfig(config); const orchestrator = new DefaultCatalogProcessingOrchestrator({ processors, From 641d36b148b1dab696ce144611f9d97466aef4d9 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 15:47:30 +0200 Subject: [PATCH 418/462] chore: delete todo comment Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/database/DefaultProcessingDatabase.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index 984e7776ea..dc5e6036f5 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -87,7 +87,6 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .update({ processed_entity: JSON.stringify(processedEntity), cache: JSON.stringify(state), - // TODO: should this also be JSON stringfy? errors, }) .where('entity_id', id); From bfe77a9dbdea852780b6b1ead6aa1bb0d3e7615b Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 4 May 2021 09:41:06 +0200 Subject: [PATCH 419/462] fix yarn lock Signed-off-by: Johan Haals <johan.haals@gmail.com> --- yarn.lock | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4d3c45ab5e..f778b2d5cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14482,7 +14482,7 @@ graphql-extensions@^0.12.8: apollo-server-env "^3.0.0" apollo-server-types "^0.6.3" -graphql-language-service-interface@^2.8.2: +graphql-language-service-interface@2.8.2, graphql-language-service-interface@^2.8.2: version "2.8.2" resolved "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.8.2.tgz#b3bb2aef7eaf0dff0b4ea419fa412c5f66fa268b" integrity sha512-otbOQmhgkAJU1QJgQkMztNku6SbJLu/uodoFOYOOtJsizTjrMs93vkYaHCcYnLA3oi1Goj27XcHjMnRCYQOZXQ== @@ -14492,7 +14492,7 @@ graphql-language-service-interface@^2.8.2: graphql-language-service-utils "^2.5.1" vscode-languageserver-types "^3.15.1" -graphql-language-service-parser@^1.9.0: +graphql-language-service-parser@1.9.0, graphql-language-service-parser@^1.9.0: version "1.9.0" resolved "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.9.0.tgz#79af21294119a0a7e81b6b994a1af36833bab724" integrity sha512-B5xPZLbBmIp0kHvpY1Z35I5DtPoDK9wGxQVRDIzcBaiIvAmlTrDvjo3bu7vKREdjFbYKvWNgrEWENuprMbF17Q== @@ -25796,16 +25796,11 @@ typescript-json-schema@^0.49.0: typescript "^4.1.3" yargs "^16.2.0" -typescript@^4.0.3, typescript@^4.1.3: +typescript@^4.0.3, typescript@^4.1.3, typescript@~4.1.3: version "4.2.3" resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== -typescript@~4.1.3: - version "4.1.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" - integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== - ua-parser-js@^0.7.18: version "0.7.21" resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" From 4dcab641852281818cabc669c0cb693c975efde2 Mon Sep 17 00:00:00 2001 From: Will Sewell <willsewell@monzo.com> Date: Mon, 3 May 2021 18:49:15 +0100 Subject: [PATCH 420/462] Update test mocks to expect call to `getEntities` Signed-off-by: Will Sewell <willsewell@monzo.com> --- .../ApisCards/ConsumedApisCard.test.tsx | 20 +++++++++++-------- .../components/ApisCards/HasApisCard.test.tsx | 20 +++++++++++-------- .../ApisCards/ProvidedApisCard.test.tsx | 20 +++++++++++-------- .../ConsumingComponentsCard.test.tsx | 20 +++++++++++-------- .../ProvidingComponentsCard.test.tsx | 20 +++++++++++-------- .../HasComponentsCard.test.tsx | 20 +++++++++++-------- .../HasSubcomponentsCard.test.tsx | 20 +++++++++++-------- .../HasSystemsCard/HasSystemsCard.test.tsx | 20 +++++++++++-------- 8 files changed, 96 insertions(+), 64 deletions(-) diff --git a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx index b157e898ca..fa956cd042 100644 --- a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx +++ b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx @@ -96,14 +96,18 @@ describe('<ConsumedApisCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'API', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'API', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx index 5db3ec2b48..e721f6e918 100644 --- a/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx +++ b/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx @@ -96,14 +96,18 @@ describe('<HasApisCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'API', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'API', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx index bb9b2e60d9..67d95605e4 100644 --- a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx +++ b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx @@ -96,14 +96,18 @@ describe('<ProvidedApisCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'API', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'API', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx index 7944b3f90a..104b360ff6 100644 --- a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx +++ b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx @@ -101,14 +101,18 @@ describe('<ConsumingComponentsCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx index ab1751b9ba..c7c6bacc84 100644 --- a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx +++ b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx @@ -101,14 +101,18 @@ describe('<ProvidingComponentsCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx index 58df0a53f8..8e0a61b05a 100644 --- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx +++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx @@ -91,14 +91,18 @@ describe('<HasComponentsCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx index 79b69d35ff..9ad69c9a0c 100644 --- a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx +++ b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx @@ -91,14 +91,18 @@ describe('<HasSubcomponentsCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( diff --git a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx index 08923a59c8..9b7fb0adae 100644 --- a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx +++ b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx @@ -89,14 +89,18 @@ describe('<HasSystemsCard />', () => { }, ], }; - catalogApi.getEntityByName.mockResolvedValue({ - apiVersion: 'v1', - kind: 'System', - metadata: { - name: 'target-name', - namespace: 'my-namespace', - }, - spec: {}, + catalogApi.getEntities.mockResolvedValue({ + items: [ + { + apiVersion: 'v1', + kind: 'System', + metadata: { + name: 'target-name', + namespace: 'my-namespace', + }, + spec: {}, + }, + ], }); const { getByText } = await renderInTestApp( From a1e6ed1fccc2e061ba5e72d5ebfa384cb10b666f Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Mon, 3 May 2021 13:41:27 +0200 Subject: [PATCH 421/462] Refactor LocationStore to transaction from context Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultLocationStore.test.ts | 175 ++++++++++-------- .../src/next/DefaultLocationStore.ts | 117 +++++++----- plugins/catalog-backend/src/next/types.ts | 9 +- 3 files changed, 180 insertions(+), 121 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts index f9bb97477c..2963b4c9df 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -14,17 +14,25 @@ * limitations under the License. */ import { v4 as uuid } from 'uuid'; +import { BackgroundContext, Context, TransactionValue } from './Context'; import { DatabaseManager } from './database/DatabaseManager'; import { DefaultLocationStore } from './DefaultLocationStore'; -/* eslint-disable */ -xdescribe('DefaultLocationStore', () => { +describe('DefaultLocationStore', () => { const createLocationStore = async () => { - const db = await DatabaseManager.createTestDatabase(); + const knex = await DatabaseManager.createTestDatabaseConnection(); + const db = await DatabaseManager.createDatabase(knex); const connection = { applyMutation: jest.fn() }; - const store = new DefaultLocationStore(db); + const store = new DefaultLocationStore(knex); await store.connect(connection); - return { store, connection }; + + const withContext = async (handler: (ctx: Context) => Promise<any>) => { + return await db.transaction(async tx => { + const ctx = TransactionValue.in(new BackgroundContext(), tx as any); + return await handler(ctx); + }); + }; + return { store, connection, db, withContext }; }; it('should do a full sync with the locations on connect', async () => { @@ -38,109 +46,128 @@ xdescribe('DefaultLocationStore', () => { describe('listLocations', () => { it('lists empty locations when there is no locations', async () => { - const { store } = await createLocationStore(); + expect.assertions(1); - expect(await store.listLocations()).toEqual([]); + const { store, withContext } = await createLocationStore(); + await withContext(async ctx => { + expect(await store.listLocations(ctx)).toEqual([]); + }); }); it('lists locations that are added to the db', async () => { - const { store } = await createLocationStore(); + expect.assertions(2); - await store.createLocation({ - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', + const { store, withContext } = await createLocationStore(); + + await withContext(async ctx => { + await store.createLocation(ctx, { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + const listLocations = await store.listLocations(ctx); + expect(listLocations).toHaveLength(1); + expect(listLocations).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }), + ]), + ); }); - - const listLocations = await store.listLocations(); - - expect(listLocations).toHaveLength(1); - expect(listLocations).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }), - ]), - ); }); }); describe('createLocation', () => { it('throws when the location already exists', async () => { - const { store } = await createLocationStore(); + expect.assertions(1); + + const { store, withContext } = await createLocationStore(); const spec = { target: 'https://github.com/backstage/demo/blob/master/catalog-info.yml', type: 'url', }; - await store.createLocation(spec); + await withContext(async ctx => { + await store.createLocation(ctx, spec); - await expect(() => store.createLocation(spec)).rejects.toThrow( - new RegExp(`Location ${spec.type}:${spec.target} already exists`), - ); + await expect(() => store.createLocation(ctx, spec)).rejects.toThrow( + new RegExp(`Location ${spec.type}:${spec.target} already exists`), + ); + }); }); it('calls apply mutation when adding a new location', async () => { - const { store, connection } = await createLocationStore(); + expect.assertions(1); - await store.createLocation({ - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }); + const { store, connection, withContext } = await createLocationStore(); - expect(connection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - removed: [], - added: expect.arrayContaining([ - expect.objectContaining({ - spec: { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }, - }), - ]), + await withContext(async ctx => { + await store.createLocation(ctx, { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + removed: [], + added: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), + }); }); }); }); describe('deleteLocation', () => { it('throws if the location does not exist', async () => { - const { store } = await createLocationStore(); - - const id = uuid(); - - await expect(() => store.deleteLocation(id)).rejects.toThrow( - new RegExp(`Found no location with ID ${id}`), - ); + expect.assertions(1); + const { store, withContext } = await createLocationStore(); + await withContext(async ctx => { + const id = uuid(); + await expect(() => store.deleteLocation(ctx, id)).rejects.toThrow( + new RegExp(`Found no location with ID ${id}`), + ); + }); }); it('calls apply mutation when adding a new location', async () => { - const { store, connection } = await createLocationStore(); + expect.assertions(1); - const location = await store.createLocation({ - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }); + const { store, connection, withContext } = await createLocationStore(); - await store.deleteLocation(location.id); + await withContext(async ctx => { + const location = await store.createLocation(ctx, { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); - expect(connection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - added: [], - removed: expect.arrayContaining([ - expect.objectContaining({ - spec: { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }, - }), - ]), + await store.deleteLocation(ctx, location.id); + + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), + }); }); }); }); diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index f6267df6a5..a11cb9edf1 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -15,7 +15,6 @@ */ import { LocationSpec, Location } from '@backstage/catalog-model'; -import { Database } from '../database'; import { LocationStore, EntityProvider, @@ -23,52 +22,61 @@ import { } from './types'; import { v4 as uuid } from 'uuid'; import { locationSpecToLocationEntity } from './util'; -import { ConflictError } from '@backstage/errors'; +import { ConflictError, NotFoundError } from '@backstage/errors'; +import { BackgroundContext, Context, TransactionValue } from './Context'; +import { Knex } from 'knex'; + +type DbLocationsRow = { + id: string; + type: string; + target: string; +}; export class DefaultLocationStore implements LocationStore, EntityProvider { private _connection: EntityProviderConnection | undefined; - constructor(private readonly db: Database) {} + constructor(private readonly db: Knex) {} getProviderName(): string { return 'DefaultLocationStore'; } - async createLocation(spec: LocationSpec): Promise<Location> { - return this.db.transaction(async tx => { - // Attempt to find a previous location matching the spec - const previousLocations = await this.listLocations(); - const previousLocation = previousLocations.some( - l => spec.type === l.type && spec.target === l.target, + async createLocation(ctx: Context, spec: LocationSpec): Promise<Location> { + const tx = TransactionValue.from(ctx); + + // Attempt to find a previous location matching the spec + const previousLocations = await this.listLocations(ctx); + const previousLocation = previousLocations.some( + l => spec.type === l.type && spec.target === l.target, + ); + + if (previousLocation) { + throw new ConflictError( + `Location ${spec.type}:${spec.target} already exists`, ); + } - if (previousLocation) { - throw new ConflictError( - `Location ${spec.type}:${spec.target} already exists`, - ); - } + const location: DbLocationsRow = { + id: uuid(), + type: spec.type, + target: spec.target, + }; + await tx<DbLocationsRow>('locations').insert(location); - // TODO: id should really be type and target combined and not a uuid. - const location = await this.db.addLocation(tx, { - id: uuid(), - type: spec.type, - target: spec.target, - }); - - await this.connection.applyMutation({ - type: 'delta', - added: [locationSpecToLocationEntity(location)], - removed: [], - }); - - return location; + await this.connection.applyMutation({ + type: 'delta', + added: [locationSpecToLocationEntity(location)], + removed: [], }); + + return location; } - async listLocations(): Promise<Location[]> { - const dbLocations = await this.db.locations(); + async listLocations(ctx: Context): Promise<Location[]> { + const tx = TransactionValue.from(ctx); + const locations = await tx<DbLocationsRow>('locations').select(); return ( - dbLocations + locations // TODO(blam): We should create a mutation to remove this location for everyone // eventually when it's all done and dusted .filter(({ type }) => type !== 'bootstrap') @@ -80,23 +88,38 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { ); } - getLocation(id: string): Promise<Location> { - return this.db.location(id); + async getLocation(ctx: Context, id: string): Promise<Location> { + const tx = TransactionValue.from(ctx); + const items = await tx<DbLocationsRow>('locations').where({ id }).select(); + + if (!items.length) { + throw new NotFoundError(`Found no location with ID ${id}`); + } + return items[0]; } - deleteLocation(id: string): Promise<void> { + async deleteLocation(ctx: Context, id: string): Promise<void> { if (!this.connection) { throw new Error('location store is not initialized'); } - return this.db.transaction(async tx => { - const location = await this.db.location(id); - await this.db.removeLocation(tx, id); - await this.connection.applyMutation({ - type: 'delta', - added: [], - removed: [locationSpecToLocationEntity(location)], - }); + const tx = TransactionValue.from(ctx); + const location = await this.getLocation(ctx, id); + + const locations = await tx<DbLocationsRow>('locations') + .where({ id }) + .select(); + + if (!locations.length) { + throw new NotFoundError(`Found no location with ID ${id}`); + } + + await tx<DbLocationsRow>('locations').where({ id }).del(); + + await this.connection.applyMutation({ + type: 'delta', + added: [], + removed: [locationSpecToLocationEntity(location)], }); } @@ -110,10 +133,18 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; - const locations = await this.listLocations(); + + // TODO: this feels a little weird creating the ctx in multiple places + // Let's work out a better way, maybe. + const locations = await this.db.transaction(tx => { + const ctx = TransactionValue.in(new BackgroundContext(), tx); + return this.listLocations(ctx); + }); + const entities = locations.map(location => { return locationSpecToLocationEntity(location); }); + await this.connection.applyMutation({ type: 'full', entities, diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 410066eafd..9e7d7ced0a 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -21,6 +21,7 @@ import { EntityRelationSpec, } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; +import { Context } from './Context'; export interface LocationService { createLocation( @@ -33,10 +34,10 @@ export interface LocationService { } export interface LocationStore { - createLocation(spec: LocationSpec): Promise<Location>; - listLocations(): Promise<Location[]>; - getLocation(id: string): Promise<Location>; - deleteLocation(id: string): Promise<void>; + createLocation(ctx: Context, spec: LocationSpec): Promise<Location>; + listLocations(ctx: Context): Promise<Location[]>; + getLocation(ctx: Context, id: string): Promise<Location>; + deleteLocation(ctx: Context, id: string): Promise<void>; } export interface CatalogProcessingEngine { From 75c8cec394fff82850d53e5e8f729c5dd1211f40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 May 2021 04:20:01 +0000 Subject: [PATCH 422/462] chore(deps): bump jsonschema from 1.2.7 to 1.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [jsonschema](https://github.com/tdegrunt/jsonschema) from 1.2.7 to 1.4.0. - [Release notes](https://github.com/tdegrunt/jsonschema/releases) - [Commits](https://github.com/tdegrunt/jsonschema/compare/v1.2.7...v1.4.0) Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Fredrik Adelöw <freben@gmail.com> --- .changeset/small-sheep-smoke.md | 5 +++++ .../scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts | 7 ++++--- yarn.lock | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 .changeset/small-sheep-smoke.md diff --git a/.changeset/small-sheep-smoke.md b/.changeset/small-sheep-smoke.md new file mode 100644 index 0000000000..9cff7591ee --- /dev/null +++ b/.changeset/small-sheep-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +bump jsonschema from 1.2.7 to 1.4.0 diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index 9e4deab31a..1d0d5ad3a3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -143,9 +143,10 @@ export class TaskWorker { }); if (action.schema?.input) { - const validateResult = validateJsonSchema(input, action.schema, { - propertyName: 'input', - }); + const validateResult = validateJsonSchema( + input, + action.schema.input, + ); if (!validateResult.valid) { const errors = validateResult.errors.join(', '); throw new InputError( diff --git a/yarn.lock b/yarn.lock index 8cb2ddd221..b7bff9836d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17100,9 +17100,9 @@ jsonpointer@^4.0.1: integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= jsonschema@^1.2.6: - version "1.2.7" - resolved "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.7.tgz#4e6d6dc4d83dc80707055ba22c00ec6152c0e6e9" - integrity sha512-3dFMg9hmI9LdHag/BRIhMefCfbq1hicvYMy8YhZQorAdzOzWz7NjniSpn39yjpzUAMIWtGyyZuH2KNBloH7ZLw== + version "1.4.0" + resolved "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" + integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== jsonwebtoken@^8.5.1: version "8.5.1" From c199090e31bbf2b03c09697725e2a673e1afde05 Mon Sep 17 00:00:00 2001 From: Marco Crivellaro <marco.crive@gmail.com> Date: Tue, 4 May 2021 12:03:52 +0100 Subject: [PATCH 423/462] adding steps to enable plantuml support in github workflow Signed-off-by: Marco Crivellaro <marco.crive@gmail.com> --- docs/features/techdocs/configuring-ci-cd.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/features/techdocs/configuring-ci-cd.md b/docs/features/techdocs/configuring-ci-cd.md index a9844ef528..0dec7ec24e 100644 --- a/docs/features/techdocs/configuring-ci-cd.md +++ b/docs/features/techdocs/configuring-ci-cd.md @@ -148,6 +148,23 @@ jobs: - uses: actions/setup-node@v2 - uses: actions/setup-python@v2 + # the 2 steps below can be removed if you aren't using plantuml in your documentation + - name: setup java + uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: '11' + - name: download, validate, install plantuml and its dependencies + run: | + curl -o plantuml.jar -L http://sourceforge.net/projects/plantuml/files/plantuml.1.2021.4.jar/download + echo "be498123d20eaea95a94b174d770ef94adfdca18 plantuml.jar" | sha1sum -c - + mv plantuml.jar /opt/plantuml.jar + mkdir -p "$HOME/.local/bin" + echo $'#!/bin/sh\n\njava -jar '/opt/plantuml.jar' ${@}' >> "$HOME/.local/bin/plantuml" + chmod +x "$HOME/.local/bin/plantuml" + echo "$HOME/.local/bin" >> $GITHUB_PATH + sudo apt-get install -y graphviz + - name: Install techdocs-cli run: sudo npm install -g @techdocs/cli From 2e05277e0da1978891bc2979bd047303c24b72f6 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Tue, 4 May 2021 14:14:02 +0200 Subject: [PATCH 424/462] Fix navigation in a page using the table of contents Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/techdocs-rich-carrots-collect.md | 5 +++++ plugins/techdocs/src/reader/components/Reader.tsx | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/techdocs-rich-carrots-collect.md diff --git a/.changeset/techdocs-rich-carrots-collect.md b/.changeset/techdocs-rich-carrots-collect.md new file mode 100644 index 0000000000..0a762bdb66 --- /dev/null +++ b/.changeset/techdocs-rich-carrots-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fix navigation in a page using the table of contents. diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index 82b5245cfa..a67443e40f 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -264,10 +264,14 @@ export const Reader = ({ entityId, onReady }: Props) => { ); shadowRoot.appendChild(transformedElement); + // Scroll to top after render + window.scroll({ top: 0 }); + // Post-render transformer(shadowRoot.children[0], [ dom => { setTimeout(() => { + // Scoll to the desired anchor on initial navigation if (window.location.hash) { const hash = window.location.hash.slice(1); shadowRoot?.getElementById(hash)?.scrollIntoView(); @@ -278,14 +282,19 @@ export const Reader = ({ entityId, onReady }: Props) => { addLinkClickListener({ baseUrl: window.location.origin, onClick: (_: MouseEvent, url: string) => { - window.scroll({ top: 0 }); const parsedUrl = new URL(url); if (newerDocsExist && isSynced) { // link navigation will load newer docs setNewerDocsExist(false); } + if (parsedUrl.hash) { navigate(`${parsedUrl.pathname}${parsedUrl.hash}`); + + // Scroll to hash if it's on the current page + shadowRoot + ?.getElementById(parsedUrl.hash.slice(1)) + ?.scrollIntoView(); } else { navigate(parsedUrl.pathname); } From 84d6ee9e867cf3fd30bda8ba35fe2a66bc51d074 Mon Sep 17 00:00:00 2001 From: Ben Lambert <ben@blam.sh> Date: Tue, 4 May 2021 14:33:36 +0200 Subject: [PATCH 425/462] Update small-sheep-smoke.md Signed-off-by: blam <ben@blam.sh> --- .changeset/small-sheep-smoke.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/small-sheep-smoke.md b/.changeset/small-sheep-smoke.md index 9cff7591ee..fd917159d3 100644 --- a/.changeset/small-sheep-smoke.md +++ b/.changeset/small-sheep-smoke.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend': patch --- -bump jsonschema from 1.2.7 to 1.4.0 +bump `jsonschema` from 1.2.7 to 1.4.0 From 86d1d7affac0134400978a254da2b617ad1a21a1 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 4 May 2021 16:16:21 +0200 Subject: [PATCH 426/462] Remove context from LocationStore Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultLocationStore.test.ts | 183 ++++++++---------- .../src/next/DefaultLocationStore.ts | 90 ++++----- .../src/next/NextCatalogBuilder.ts | 2 +- plugins/catalog-backend/src/next/types.ts | 9 +- 4 files changed, 131 insertions(+), 153 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts index 2963b4c9df..820865c350 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -18,23 +18,23 @@ import { BackgroundContext, Context, TransactionValue } from './Context'; import { DatabaseManager } from './database/DatabaseManager'; import { DefaultLocationStore } from './DefaultLocationStore'; -describe('DefaultLocationStore', () => { - const createLocationStore = async () => { - const knex = await DatabaseManager.createTestDatabaseConnection(); - const db = await DatabaseManager.createDatabase(knex); - const connection = { applyMutation: jest.fn() }; - const store = new DefaultLocationStore(knex); - await store.connect(connection); +const createLocationStore = async () => { + const knex = await DatabaseManager.createTestDatabaseConnection(); + const db = await DatabaseManager.createDatabase(knex); + const connection = { applyMutation: jest.fn() }; + const store = new DefaultLocationStore(knex); + await store.connect(connection); - const withContext = async (handler: (ctx: Context) => Promise<any>) => { - return await db.transaction(async tx => { - const ctx = TransactionValue.in(new BackgroundContext(), tx as any); - return await handler(ctx); - }); - }; - return { store, connection, db, withContext }; + const withContext = async (handler: (ctx: Context) => Promise<any>) => { + return await db.transaction(async tx => { + const ctx = TransactionValue.in(new BackgroundContext(), tx as any); + return await handler(ctx); + }); }; + return { store, connection, db, withContext }; +}; +describe('DefaultLocationStore', () => { it('should do a full sync with the locations on connect', async () => { const { connection } = await createLocationStore(); @@ -46,128 +46,105 @@ describe('DefaultLocationStore', () => { describe('listLocations', () => { it('lists empty locations when there is no locations', async () => { - expect.assertions(1); - - const { store, withContext } = await createLocationStore(); - await withContext(async ctx => { - expect(await store.listLocations(ctx)).toEqual([]); - }); + const { store } = await createLocationStore(); + expect(await store.listLocations()).toEqual([]); }); it('lists locations that are added to the db', async () => { - expect.assertions(2); - - const { store, withContext } = await createLocationStore(); - - await withContext(async ctx => { - await store.createLocation(ctx, { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }); - - const listLocations = await store.listLocations(ctx); - expect(listLocations).toHaveLength(1); - expect(listLocations).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }), - ]), - ); + const { store } = await createLocationStore(); + await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', }); + + const listLocations = await store.listLocations(); + expect(listLocations).toHaveLength(1); + expect(listLocations).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }), + ]), + ); }); }); describe('createLocation', () => { it('throws when the location already exists', async () => { - expect.assertions(1); - - const { store, withContext } = await createLocationStore(); + const { store } = await createLocationStore(); const spec = { target: 'https://github.com/backstage/demo/blob/master/catalog-info.yml', type: 'url', }; - await withContext(async ctx => { - await store.createLocation(ctx, spec); - - await expect(() => store.createLocation(ctx, spec)).rejects.toThrow( - new RegExp(`Location ${spec.type}:${spec.target} already exists`), - ); - }); + await store.createLocation(spec); + await expect(() => store.createLocation(spec)).rejects.toThrow( + new RegExp(`Location ${spec.type}:${spec.target} already exists`), + ); }); it('calls apply mutation when adding a new location', async () => { expect.assertions(1); - const { store, connection, withContext } = await createLocationStore(); + const { store, connection } = await createLocationStore(); - await withContext(async ctx => { - await store.createLocation(ctx, { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }); + await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); - expect(connection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - removed: [], - added: expect.arrayContaining([ - expect.objectContaining({ - spec: { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }, - }), - ]), - }); + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + removed: [], + added: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), }); }); }); describe('deleteLocation', () => { it('throws if the location does not exist', async () => { - expect.assertions(1); - const { store, withContext } = await createLocationStore(); - await withContext(async ctx => { - const id = uuid(); - await expect(() => store.deleteLocation(ctx, id)).rejects.toThrow( - new RegExp(`Found no location with ID ${id}`), - ); - }); + const { store } = await createLocationStore(); + const id = uuid(); + await expect(() => store.deleteLocation(id)).rejects.toThrow( + new RegExp(`Found no location with ID ${id}`), + ); }); it('calls apply mutation when adding a new location', async () => { - expect.assertions(1); + const { store, connection } = await createLocationStore(); - const { store, connection, withContext } = await createLocationStore(); + const location = await store.createLocation({ + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }); - await withContext(async ctx => { - const location = await store.createLocation(ctx, { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }); + await store.deleteLocation(location.id); - await store.deleteLocation(ctx, location.id); - - expect(connection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - added: [], - removed: expect.arrayContaining([ - expect.objectContaining({ - spec: { - target: - 'https://github.com/backstage/demo/blob/master/catalog-info.yml', - type: 'url', - }, - }), - ]), - }); + expect(connection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expect.arrayContaining([ + expect.objectContaining({ + spec: { + target: + 'https://github.com/backstage/demo/blob/master/catalog-info.yml', + type: 'url', + }, + }), + ]), }); }); }); diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index a11cb9edf1..116ccb2c8e 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -23,7 +23,6 @@ import { import { v4 as uuid } from 'uuid'; import { locationSpecToLocationEntity } from './util'; import { ConflictError, NotFoundError } from '@backstage/errors'; -import { BackgroundContext, Context, TransactionValue } from './Context'; import { Knex } from 'knex'; type DbLocationsRow = { @@ -41,27 +40,31 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return 'DefaultLocationStore'; } - async createLocation(ctx: Context, spec: LocationSpec): Promise<Location> { - const tx = TransactionValue.from(ctx); - - // Attempt to find a previous location matching the spec - const previousLocations = await this.listLocations(ctx); - const previousLocation = previousLocations.some( - l => spec.type === l.type && spec.target === l.target, - ); - - if (previousLocation) { - throw new ConflictError( - `Location ${spec.type}:${spec.target} already exists`, + async createLocation(spec: LocationSpec): Promise<Location> { + const location = await this.db.transaction(async tx => { + // Attempt to find a previous location matching the spec + const previousLocations = await this.locations(tx); + // TODO: when location id's are a compilation of spec target we can remove this full + // lookup of locations first and just grab the by that instead. + const previousLocation = previousLocations.some( + l => spec.type === l.type && spec.target === l.target, ); - } + if (previousLocation) { + throw new ConflictError( + `Location ${spec.type}:${spec.target} already exists`, + ); + } - const location: DbLocationsRow = { - id: uuid(), - type: spec.type, - target: spec.target, - }; - await tx<DbLocationsRow>('locations').insert(location); + const inner: DbLocationsRow = { + id: uuid(), + type: spec.type, + target: spec.target, + }; + + await tx<DbLocationsRow>('locations').insert(inner); + + return inner; + }); await this.connection.applyMutation({ type: 'delta', @@ -72,9 +75,12 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return location; } - async listLocations(ctx: Context): Promise<Location[]> { - const tx = TransactionValue.from(ctx); - const locations = await tx<DbLocationsRow>('locations').select(); + async listLocations(): Promise<Location[]> { + return await this.locations(this.db); + } + + private async locations(dbOrTx: Knex | Knex.Transaction) { + const locations = await dbOrTx<DbLocationsRow>('locations').select(); return ( locations // TODO(blam): We should create a mutation to remove this location for everyone @@ -88,9 +94,10 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { ); } - async getLocation(ctx: Context, id: string): Promise<Location> { - const tx = TransactionValue.from(ctx); - const items = await tx<DbLocationsRow>('locations').where({ id }).select(); + async getLocation(id: string): Promise<Location> { + const items = await this.db<DbLocationsRow>('locations') + .where({ id }) + .select(); if (!items.length) { throw new NotFoundError(`Found no location with ID ${id}`); @@ -98,28 +105,28 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { return items[0]; } - async deleteLocation(ctx: Context, id: string): Promise<void> { + async deleteLocation(id: string): Promise<void> { if (!this.connection) { throw new Error('location store is not initialized'); } - const tx = TransactionValue.from(ctx); - const location = await this.getLocation(ctx, id); + const deleted = await this.db.transaction(async tx => { + const [location] = await tx<DbLocationsRow>('locations') + .where({ id }) + .select(); - const locations = await tx<DbLocationsRow>('locations') - .where({ id }) - .select(); + if (!location) { + throw new NotFoundError(`Found no location with ID ${id}`); + } - if (!locations.length) { - throw new NotFoundError(`Found no location with ID ${id}`); - } - - await tx<DbLocationsRow>('locations').where({ id }).del(); + await tx<DbLocationsRow>('locations').where({ id }).del(); + return location; + }); await this.connection.applyMutation({ type: 'delta', added: [], - removed: [locationSpecToLocationEntity(location)], + removed: [locationSpecToLocationEntity(deleted)], }); } @@ -134,12 +141,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; - // TODO: this feels a little weird creating the ctx in multiple places - // Let's work out a better way, maybe. - const locations = await this.db.transaction(tx => { - const ctx = TransactionValue.in(new BackgroundContext(), tx); - return this.listLocations(ctx); - }); + const locations = await this.locations(this.db); const entities = locations.map(location => { return locationSpecToLocationEntity(location); diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 0158cc9fc9..92f3822055 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -261,7 +261,7 @@ export class NextCatalogBuilder { }); const entitiesCatalog = new NextEntitiesCatalog(dbClient); - const locationStore = new DefaultLocationStore(db); + const locationStore = new DefaultLocationStore(dbClient); const stitcher = new Stitcher(dbClient, logger); const configLocationProvider = new ConfigLocationEntityProvider(config); const processingEngine = new DefaultCatalogProcessingEngine( diff --git a/plugins/catalog-backend/src/next/types.ts b/plugins/catalog-backend/src/next/types.ts index 9e7d7ced0a..410066eafd 100644 --- a/plugins/catalog-backend/src/next/types.ts +++ b/plugins/catalog-backend/src/next/types.ts @@ -21,7 +21,6 @@ import { EntityRelationSpec, } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/config'; -import { Context } from './Context'; export interface LocationService { createLocation( @@ -34,10 +33,10 @@ export interface LocationService { } export interface LocationStore { - createLocation(ctx: Context, spec: LocationSpec): Promise<Location>; - listLocations(ctx: Context): Promise<Location[]>; - getLocation(ctx: Context, id: string): Promise<Location>; - deleteLocation(ctx: Context, id: string): Promise<void>; + createLocation(spec: LocationSpec): Promise<Location>; + listLocations(): Promise<Location[]>; + getLocation(id: string): Promise<Location>; + deleteLocation(id: string): Promise<void>; } export interface CatalogProcessingEngine { From 3492eccef2a4c0a062d3519f96d813bf9aea1a36 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 4 May 2021 16:19:55 +0200 Subject: [PATCH 427/462] Remove redundant assertion Signed-off-by: Johan Haals <johan.haals@gmail.com> --- plugins/catalog-backend/src/next/DefaultLocationStore.test.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts index 820865c350..5a9da22287 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -87,10 +87,7 @@ describe('DefaultLocationStore', () => { }); it('calls apply mutation when adding a new location', async () => { - expect.assertions(1); - const { store, connection } = await createLocationStore(); - await store.createLocation({ target: 'https://github.com/backstage/demo/blob/master/catalog-info.yml', From ea6af512694bbc167377237ba44d28f989b28cc5 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Tue, 4 May 2021 16:28:39 +0200 Subject: [PATCH 428/462] chore: cleanups Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/DefaultLocationStore.test.ts | 11 ++---- .../src/next/DefaultLocationStore.ts | 34 +++++++++---------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts index 5a9da22287..88806d0ace 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.test.ts @@ -14,24 +14,17 @@ * limitations under the License. */ import { v4 as uuid } from 'uuid'; -import { BackgroundContext, Context, TransactionValue } from './Context'; import { DatabaseManager } from './database/DatabaseManager'; import { DefaultLocationStore } from './DefaultLocationStore'; const createLocationStore = async () => { const knex = await DatabaseManager.createTestDatabaseConnection(); - const db = await DatabaseManager.createDatabase(knex); + await DatabaseManager.createDatabase(knex); const connection = { applyMutation: jest.fn() }; const store = new DefaultLocationStore(knex); await store.connect(connection); - const withContext = async (handler: (ctx: Context) => Promise<any>) => { - return await db.transaction(async tx => { - const ctx = TransactionValue.in(new BackgroundContext(), tx as any); - return await handler(ctx); - }); - }; - return { store, connection, db, withContext }; + return { store, connection }; }; describe('DefaultLocationStore', () => { diff --git a/plugins/catalog-backend/src/next/DefaultLocationStore.ts b/plugins/catalog-backend/src/next/DefaultLocationStore.ts index 116ccb2c8e..fe1eb30467 100644 --- a/plugins/catalog-backend/src/next/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/next/DefaultLocationStore.ts @@ -76,22 +76,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { } async listLocations(): Promise<Location[]> { - return await this.locations(this.db); - } - - private async locations(dbOrTx: Knex | Knex.Transaction) { - const locations = await dbOrTx<DbLocationsRow>('locations').select(); - return ( - locations - // TODO(blam): We should create a mutation to remove this location for everyone - // eventually when it's all done and dusted - .filter(({ type }) => type !== 'bootstrap') - .map(item => ({ - id: item.id, - target: item.target, - type: item.type, - })) - ); + return await this.locations(); } async getLocation(id: string): Promise<Location> { @@ -141,7 +126,7 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { async connect(connection: EntityProviderConnection): Promise<void> { this._connection = connection; - const locations = await this.locations(this.db); + const locations = await this.locations(); const entities = locations.map(location => { return locationSpecToLocationEntity(location); @@ -152,4 +137,19 @@ export class DefaultLocationStore implements LocationStore, EntityProvider { entities, }); } + + private async locations(dbOrTx: Knex.Transaction | Knex = this.db) { + const locations = await dbOrTx<DbLocationsRow>('locations').select(); + return ( + locations + // TODO(blam): We should create a mutation to remove this location for everyone + // eventually when it's all done and dusted + .filter(({ type }) => type !== 'bootstrap') + .map(item => ({ + id: item.id, + target: item.target, + type: item.type, + })) + ); + } } From defaa15e55a49f13a2adfd029c41e7c516c6e334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= <kevin.gomez@voiapp.io> Date: Sun, 25 Apr 2021 23:21:55 +0200 Subject: [PATCH 429/462] Add "Organization" tab with a diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez <kevin.gomez@voiapp.io> --- .../components/ExplorePage/ExploreTabs.tsx | 4 + .../OrganizationDiagram.tsx | 207 ++++++++++++++++++ .../OrganizationExplorerContent.tsx | 30 +++ .../OrganizationExplorerContent/index.ts | 16 ++ 4 files changed, 257 insertions(+) create mode 100644 plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx create mode 100644 plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx create mode 100644 plugins/explore/src/components/OrganizationExplorerContent/index.ts diff --git a/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx b/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx index 0cf28f9f1c..24fbf0039c 100644 --- a/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx +++ b/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx @@ -16,6 +16,7 @@ import { TabbedLayout } from '@backstage/core'; import React from 'react'; import { DomainExplorerContent } from '../DomainExplorerContent'; +import { OrganizationExplorerContent } from '../OrganizationExplorerContent'; import { ToolExplorerContent } from '../ToolExplorerContent'; export const ExploreTabs = () => ( @@ -23,6 +24,9 @@ export const ExploreTabs = () => ( <TabbedLayout.Route path="domains" title="Domains"> <DomainExplorerContent /> </TabbedLayout.Route> + <TabbedLayout.Route path="organization" title="Organization"> + <OrganizationExplorerContent /> + </TabbedLayout.Route> <TabbedLayout.Route path="tools" title="Tools"> <ToolExplorerContent /> </TabbedLayout.Route> diff --git a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx b/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx new file mode 100644 index 0000000000..4e0d3710f3 --- /dev/null +++ b/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx @@ -0,0 +1,207 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + RELATION_CHILD_OF, + stringifyEntityRef, + ENTITY_DEFAULT_NAMESPACE, + parseEntityRef, +} from '@backstage/catalog-model'; +import { + catalogApiRef, + entityRouteRef, + getEntityRelations, +} from '@backstage/plugin-catalog-react'; +import { + DependencyGraph, + DependencyGraphTypes, + Progress, + useApi, + ResponseErrorPanel, + Link, + useRouteRef, + configApiRef, +} from '@backstage/core'; +import { makeStyles, Typography } from '@material-ui/core'; +import ZoomOutMap from '@material-ui/icons/ZoomOutMap'; +import React from 'react'; +import { useAsync } from 'react-use'; +import { BackstageTheme } from '@backstage/theme'; + +const useStyles = makeStyles((theme: BackstageTheme) => ({ + organizationNode: { + fill: 'coral', + stroke: theme.palette.border, + }, + groupNode: { + fill: 'yellowgreen', + stroke: theme.palette.border, + }, +})); + +// Simplifies the diagram output by hiding the default namespace and kind +function readableEntityName( + ref: + | Entity + | { + kind: string; + namespace?: string; + name: string; + }, +): string { + return stringifyEntityRef(ref) + .toLocaleLowerCase('en-US') + .replace(`:${ENTITY_DEFAULT_NAMESPACE}/`, ':') + .split(':')[1]; +} + +function RenderNode(props: DependencyGraphTypes.RenderNodeProps<any>) { + const classes = useStyles(); + const catalogEntityRoute = useRouteRef(entityRouteRef); + + if (props.node.id === 'root') { + return ( + <g> + <rect + width={180} + height={80} + rx={20} + className={classes.organizationNode} + /> + <text + x={90} + y={45} + textAnchor="middle" + alignmentBaseline="baseline" + style={{ fontWeight: 'bold' }} + > + {props.node.name} + </text> + </g> + ); + } + + const ref = parseEntityRef(props.node.id); + + return ( + <g> + <rect width={180} height={80} rx={20} className={classes.groupNode} /> + <Link + to={catalogEntityRoute({ + kind: ref.kind, + namespace: ref.namespace, + name: ref.name, + })} + > + <text + x={90} + y={45} + textAnchor="middle" + alignmentBaseline="baseline" + style={{ fontWeight: 'bold' }} + > + {props.node.name} + </text> + </Link> + </g> + ); +} + +/** + * Dynamically generates a diagram of an organization. + */ +export function OrganizationDiagram() { + const nodes = new Array<{ id: string; kind: string; name: string }>(); + const edges = new Array<{ from: string; to: string; label: string }>(); + + const configApi = useApi(configApiRef); + const catalogApi = useApi(catalogApiRef); + const organizationName = + configApi.getOptionalString('organization.name') ?? 'Backstage'; + const { loading, error, value: catalogResponse } = useAsync(() => { + return catalogApi.getEntities({ + filter: { + kind: ['Group'], + }, + }); + }, [catalogApi]); + + if (loading) { + return <Progress />; + } else if (error) { + return <ResponseErrorPanel error={error} />; + } + + // the root of this diagram is the organization + nodes.push({ + id: 'root', + kind: 'Organization', + name: organizationName, + }); + + for (const catalogItem of catalogResponse?.items || []) { + const currentItemId = stringifyEntityRef(catalogItem); + + nodes.push({ + id: stringifyEntityRef(catalogItem), + kind: catalogItem.kind, + name: readableEntityName(catalogItem), + }); + + // Edge to parent + const catalogItemRelations_childOf = getEntityRelations( + catalogItem, + RELATION_CHILD_OF, + ); + + // if no parent is found, link the node to the root + if (catalogItemRelations_childOf.length === 0) { + edges.push({ + from: currentItemId, + to: 'root', + label: '', + }); + } + + catalogItemRelations_childOf.forEach(relation => { + edges.push({ + from: currentItemId, + to: stringifyEntityRef(relation), + label: '', + }); + }); + } + + return ( + <> + <DependencyGraph + nodes={nodes} + edges={edges} + nodeMargin={10} + direction={DependencyGraphTypes.Direction.RIGHT_LEFT} + renderNode={RenderNode} + /> + <Typography + variant="caption" + style={{ display: 'block', textAlign: 'right' }} + > + <ZoomOutMap style={{ verticalAlign: 'bottom' }} /> Use pinch &amp; zoom + to move around the diagram. + </Typography> + </> + ); +} diff --git a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx b/plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx new file mode 100644 index 0000000000..4e05cc2c6c --- /dev/null +++ b/plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Content, ContentHeader, SupportButton } from '@backstage/core'; +import React from 'react'; +import { OrganizationDiagram } from './OrganizationDiagram'; + +export const OrganizationExplorerContent = () => { + return ( + <Content noPadding> + <ContentHeader title="Organization"> + <SupportButton>Explore your organization.</SupportButton> + </ContentHeader> + + <OrganizationDiagram /> + </Content> + ); +}; diff --git a/plugins/explore/src/components/OrganizationExplorerContent/index.ts b/plugins/explore/src/components/OrganizationExplorerContent/index.ts new file mode 100644 index 0000000000..87b08eba52 --- /dev/null +++ b/plugins/explore/src/components/OrganizationExplorerContent/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { OrganizationExplorerContent } from './OrganizationExplorerContent'; From f37cf4599c6c1e1feafd0d814104a0b2e2f75600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= <kevin.gomez@voiapp.io> Date: Tue, 4 May 2021 23:17:45 +0200 Subject: [PATCH 430/462] Use formatEntityRefTitle to format node titles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez <kevin.gomez@voiapp.io> --- .../OrganizationDiagram.tsx | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx b/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx index 4e0d3710f3..e3a6826835 100644 --- a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx +++ b/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx @@ -15,16 +15,15 @@ */ import { - Entity, RELATION_CHILD_OF, stringifyEntityRef, - ENTITY_DEFAULT_NAMESPACE, parseEntityRef, } from '@backstage/catalog-model'; import { catalogApiRef, entityRouteRef, getEntityRelations, + formatEntityRefTitle, } from '@backstage/plugin-catalog-react'; import { DependencyGraph, @@ -53,22 +52,6 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ }, })); -// Simplifies the diagram output by hiding the default namespace and kind -function readableEntityName( - ref: - | Entity - | { - kind: string; - namespace?: string; - name: string; - }, -): string { - return stringifyEntityRef(ref) - .toLocaleLowerCase('en-US') - .replace(`:${ENTITY_DEFAULT_NAMESPACE}/`, ':') - .split(':')[1]; -} - function RenderNode(props: DependencyGraphTypes.RenderNodeProps<any>) { const classes = useStyles(); const catalogEntityRoute = useRouteRef(entityRouteRef); @@ -159,7 +142,7 @@ export function OrganizationDiagram() { nodes.push({ id: stringifyEntityRef(catalogItem), kind: catalogItem.kind, - name: readableEntityName(catalogItem), + name: formatEntityRefTitle(catalogItem, { defaultKind: 'Group' }), }); // Edge to parent From 0b033d07b7775b9cb792d7246870213ae4228d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= <kevin.gomez@voiapp.io> Date: Tue, 4 May 2021 23:19:30 +0200 Subject: [PATCH 431/462] Add changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez <kevin.gomez@voiapp.io> --- .changeset/breezy-carrots-hunt.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/breezy-carrots-hunt.md diff --git a/.changeset/breezy-carrots-hunt.md b/.changeset/breezy-carrots-hunt.md new file mode 100644 index 0000000000..0075009a2d --- /dev/null +++ b/.changeset/breezy-carrots-hunt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-explore': patch +--- + +Add "Organization" tab with a diagram From c19c97a92caaf67620145a61d43aeecd31f2ef98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 May 2021 04:46:22 +0000 Subject: [PATCH 432/462] chore(deps-dev): bump @types/react-dev-utils from 9.0.4 to 9.0.5 Bumps [@types/react-dev-utils](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dev-utils) from 9.0.4 to 9.0.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dev-utils) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index e2ecf9b7c3..23cf3b2fd2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6601,14 +6601,14 @@ "@types/reactcss" "*" "@types/react-dev-utils@^9.0.4": - version "9.0.4" - resolved "https://registry.npmjs.org/@types/react-dev-utils/-/react-dev-utils-9.0.4.tgz#3e4bee79b7536777cef219427ab1d38adc24f3f2" - integrity sha512-8cv9rAeSP1EmyRQAbZ/i6uYtai1VoKHGSBwDyCLM82wCkqoh3WPjJgI1pfi2kiLc0C5hNU7DLo7/c4hylfHLWg== + version "9.0.5" + resolved "https://registry.npmjs.org/@types/react-dev-utils/-/react-dev-utils-9.0.5.tgz#3265699edaba0078256d91b7793f98c4fb9bf6cf" + integrity sha512-uUsdRdc4LU1WQrfw3htnRIRchyOOsBnmnByK6H3oZMBdjmeyH1f7Cfy64YixQ3T3Dzy5gwGilcJVSDyOFjVBWQ== dependencies: "@types/eslint" "*" "@types/express" "*" "@types/html-webpack-plugin" "*" - "@types/webpack" "*" + "@types/webpack" "^4" "@types/webpack-dev-server" "*" "@types/react-dom@^16.9.8": From d4bc58ef62b23352ef6a8a167edecdbaa5f9b5ca Mon Sep 17 00:00:00 2001 From: Dominik Henneke <dominik.henneke@sda-se.com> Date: Wed, 5 May 2021 11:25:58 +0200 Subject: [PATCH 433/462] Fix typo Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com> --- .changeset/eight-dingos-exist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/eight-dingos-exist.md b/.changeset/eight-dingos-exist.md index da05523a15..9a6553e7e9 100644 --- a/.changeset/eight-dingos-exist.md +++ b/.changeset/eight-dingos-exist.md @@ -48,7 +48,7 @@ To keep the `dockerode` based runtime, use the `DockerContainerRunner` implement + } from '@backstage/backend-common'; - import { runDockerContainer } from '@backstage/backend-common'; -+ const containerRunner: ContainerRUnner = new DockerContainerRunner({dockerClient}); ++ const containerRunner: ContainerRunner = new DockerContainerRunner({dockerClient}); + await containerRunner.runContainer({ - await runDockerContainer({ image: 'docker', From 889d89b6ec2fece63ecb07b04fd1a54bbfb73653 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Wed, 5 May 2021 11:34:27 +0200 Subject: [PATCH 434/462] Fix setting the state with `useQueryParamState` makes inputs lose their focus Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/short-bobcats-mate.md | 6 ++++++ packages/core/src/hooks/useQueryParamState.ts | 14 +++++++++----- .../ApiExplorerTable/ApiExplorerTable.tsx | 1 - 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 .changeset/short-bobcats-mate.md diff --git a/.changeset/short-bobcats-mate.md b/.changeset/short-bobcats-mate.md new file mode 100644 index 0000000000..22aaf11d77 --- /dev/null +++ b/.changeset/short-bobcats-mate.md @@ -0,0 +1,6 @@ +--- +'@backstage/core': patch +'@backstage/plugin-api-docs': patch +--- + +Fix setting the state with `useQueryParamState` makes inputs lose their focus. diff --git a/packages/core/src/hooks/useQueryParamState.ts b/packages/core/src/hooks/useQueryParamState.ts index da303234f5..0a61771eba 100644 --- a/packages/core/src/hooks/useQueryParamState.ts +++ b/packages/core/src/hooks/useQueryParamState.ts @@ -17,7 +17,7 @@ import { isEqual } from 'lodash'; import qs from 'qs'; import { useEffect, useState } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { useDebounce } from 'react-use'; function stringify(queryParams: any): string { @@ -58,9 +58,7 @@ type SetQueryParams<T> = (params: T) => void; export function useQueryParamState<T>( stateName: string, - debounceTime: number = 100, ): [T | undefined, SetQueryParams<T>] { - const navigate = useNavigate(); const location = useLocation(); const [queryParamState, setQueryParamState] = useState<T>( extractState(location.search, stateName), @@ -83,10 +81,16 @@ export function useQueryParamState<T>( ); if (location.search !== queryString) { - navigate({ ...location, search: `?${queryString}` }, { replace: true }); + // We fallback to the history API, as navigate from react-router causes + // input elements to loose focus. + history.replaceState( + undefined, + document.title, + `${location.pathname}?${queryString}`, + ); } }, - debounceTime, + 100, [queryParamState], ); diff --git a/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx b/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx index 39c2caaf1b..5b9808e26d 100644 --- a/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx +++ b/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx @@ -156,7 +156,6 @@ export const ApiExplorerTable = ({ }: ExplorerTableProps) => { const [queryParamState, setQueryParamState] = useQueryParamState<TableState>( 'apiTable', - 500, ); if (error) { From 7b8272fb7d864115b79af17e99ef8d4012f7ce89 Mon Sep 17 00:00:00 2001 From: Mike Lewis <mtlewis@users.noreply.github.com> Date: Wed, 5 May 2021 11:42:05 +0100 Subject: [PATCH 435/462] Remove extra bottom padding in InfoCard content Fixes #5396 by overriding padding-bottom to undefined for MuiCardContent in rootTheme.ts. Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> --- .changeset/khaki-singers-perform.md | 5 +++++ packages/theme/src/baseTheme.ts | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 .changeset/khaki-singers-perform.md diff --git a/.changeset/khaki-singers-perform.md b/.changeset/khaki-singers-perform.md new file mode 100644 index 0000000000..d63c8754a8 --- /dev/null +++ b/.changeset/khaki-singers-perform.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +Remove extra bottom padding in InfoCard content diff --git a/packages/theme/src/baseTheme.ts b/packages/theme/src/baseTheme.ts index e7bb7e58b6..4f5627eec9 100644 --- a/packages/theme/src/baseTheme.ts +++ b/packages/theme/src/baseTheme.ts @@ -257,6 +257,9 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides { // etc) end up at the bottom of the card instead of just below the body // contents. flexGrow: 1, + '&:last-child': { + paddingBottom: undefined, + }, }, }, MuiCardActions: { From d67645ca05676d89134af065c39dcda0a178b5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= <kevin.gomez@voiapp.io> Date: Wed, 5 May 2021 14:22:33 +0200 Subject: [PATCH 436/462] Rename Organization diagram to Groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez <kevin.gomez@voiapp.io> --- .../explore/src/components/ExplorePage/ExploreTabs.tsx | 6 +++--- .../GroupsDiagram.tsx} | 4 ++-- .../GroupsExplorerContent.tsx} | 10 +++++----- .../index.ts | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) rename plugins/explore/src/components/{OrganizationExplorerContent/OrganizationDiagram.tsx => GroupsExplorerContent/GroupsDiagram.tsx} (97%) rename plugins/explore/src/components/{OrganizationExplorerContent/OrganizationExplorerContent.tsx => GroupsExplorerContent/GroupsExplorerContent.tsx} (75%) rename plugins/explore/src/components/{OrganizationExplorerContent => GroupsExplorerContent}/index.ts (88%) diff --git a/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx b/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx index 24fbf0039c..0415dd97ae 100644 --- a/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx +++ b/plugins/explore/src/components/ExplorePage/ExploreTabs.tsx @@ -16,7 +16,7 @@ import { TabbedLayout } from '@backstage/core'; import React from 'react'; import { DomainExplorerContent } from '../DomainExplorerContent'; -import { OrganizationExplorerContent } from '../OrganizationExplorerContent'; +import { GroupsExplorerContent } from '../GroupsExplorerContent'; import { ToolExplorerContent } from '../ToolExplorerContent'; export const ExploreTabs = () => ( @@ -24,8 +24,8 @@ export const ExploreTabs = () => ( <TabbedLayout.Route path="domains" title="Domains"> <DomainExplorerContent /> </TabbedLayout.Route> - <TabbedLayout.Route path="organization" title="Organization"> - <OrganizationExplorerContent /> + <TabbedLayout.Route path="groups" title="Groups"> + <GroupsExplorerContent /> </TabbedLayout.Route> <TabbedLayout.Route path="tools" title="Tools"> <ToolExplorerContent /> diff --git a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx similarity index 97% rename from plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx rename to plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx index e3a6826835..99157b878f 100644 --- a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationDiagram.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.tsx @@ -105,9 +105,9 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps<any>) { } /** - * Dynamically generates a diagram of an organization. + * Dynamically generates a diagram of groups registered in the catalog. */ -export function OrganizationDiagram() { +export function GroupsDiagram() { const nodes = new Array<{ id: string; kind: string; name: string }>(); const edges = new Array<{ from: string; to: string; label: string }>(); diff --git a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx similarity index 75% rename from plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx rename to plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx index 4e05cc2c6c..c4d46206e4 100644 --- a/plugins/explore/src/components/OrganizationExplorerContent/OrganizationExplorerContent.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx @@ -15,16 +15,16 @@ */ import { Content, ContentHeader, SupportButton } from '@backstage/core'; import React from 'react'; -import { OrganizationDiagram } from './OrganizationDiagram'; +import { GroupsDiagram } from './GroupsDiagram'; -export const OrganizationExplorerContent = () => { +export const GroupsExplorerContent = () => { return ( <Content noPadding> - <ContentHeader title="Organization"> - <SupportButton>Explore your organization.</SupportButton> + <ContentHeader title="Groups"> + <SupportButton>Explore your groups.</SupportButton> </ContentHeader> - <OrganizationDiagram /> + <GroupsDiagram /> </Content> ); }; diff --git a/plugins/explore/src/components/OrganizationExplorerContent/index.ts b/plugins/explore/src/components/GroupsExplorerContent/index.ts similarity index 88% rename from plugins/explore/src/components/OrganizationExplorerContent/index.ts rename to plugins/explore/src/components/GroupsExplorerContent/index.ts index 87b08eba52..4d88f40dde 100644 --- a/plugins/explore/src/components/OrganizationExplorerContent/index.ts +++ b/plugins/explore/src/components/GroupsExplorerContent/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { OrganizationExplorerContent } from './OrganizationExplorerContent'; +export { GroupsExplorerContent } from './GroupsExplorerContent'; From 1f1511e7685a9e007c8dfab05b32d08660746803 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Wed, 5 May 2021 16:38:14 +0200 Subject: [PATCH 437/462] catalog/next: Wire API with locationStore, fix filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ben Lambert <ben@blam.sh> Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com> Signed-off-by: Johan Haals <johan.haals@gmail.com> --- packages/backend/src/plugins/catalog.ts | 7 +- .../DefaultCatalogProcessingOrchestrator.ts | 7 +- .../src/next/NextCatalogBuilder.ts | 10 +- .../src/next/NextEntitiesCatalog.ts | 127 ++++++++++++-- .../catalog-backend/src/next/NextRouter.ts | 164 ++++++++++++++++++ plugins/catalog-backend/src/next/Stitcher.ts | 4 +- plugins/catalog-backend/src/next/index.ts | 1 + 7 files changed, 290 insertions(+), 30 deletions(-) create mode 100644 plugins/catalog-backend/src/next/NextRouter.ts diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 7651836e2a..63a3e53c81 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -20,6 +20,7 @@ import { createRouter, NextCatalogBuilder, runPeriodically, + createNextRouter, } from '@backstage/plugin-catalog-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; @@ -36,18 +37,18 @@ export default async function createPlugin( const builder = new NextCatalogBuilder(env); const { entitiesCatalog, - locationsCatalog, locationAnalyzer, processingEngine, + locationService, } = await builder.build(); // TODO(jhaals): run and manage in background. await processingEngine.start(); - return await createRouter({ + return await createNextRouter({ entitiesCatalog, - locationsCatalog, locationAnalyzer, + locationService, logger: env.logger, config: env.config, }); diff --git a/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts index 8fbb19e536..9b2d6550d1 100644 --- a/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts +++ b/plugins/catalog-backend/src/next/DefaultCatalogProcessingOrchestrator.ts @@ -97,11 +97,8 @@ export class DefaultCatalogProcessingOrchestrator async process( request: EntityProcessingRequest, ): Promise<EntityProcessingResult> { - const { entity } = request; - - const result = await this.processSingleEntity(entity); - - return result; + // TODO: implement dryRun/eager + return this.processSingleEntity(request.entity); } private async processSingleEntity( diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts index 0158cc9fc9..fa4539f0be 100644 --- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts @@ -63,11 +63,12 @@ import { } from '../ingestion/processors/PlaceholderProcessor'; import { defaultEntityDataParser } from '../ingestion/processors/util/parse'; import { LocationAnalyzer } from '../ingestion/types'; -import { CatalogProcessingEngine } from '../next/types'; +import { CatalogProcessingEngine, LocationService } from '../next/types'; import { ConfigLocationEntityProvider } from './ConfigLocationEntityProvider'; import { DefaultProcessingDatabase } from './database/DefaultProcessingDatabase'; import { DefaultCatalogProcessingEngine } from './DefaultCatalogProcessingEngine'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; +import { DefaultLocationService } from './DefaultLocationService'; import { DefaultLocationStore } from './DefaultLocationStore'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; import { Stitcher } from './Stitcher'; @@ -233,6 +234,7 @@ export class NextCatalogBuilder { locationsCatalog: LocationsCatalog; locationAnalyzer: LocationAnalyzer; processingEngine: CatalogProcessingEngine; + locationService: LocationService; }> { const { config, database, logger } = this.env; @@ -274,12 +276,16 @@ export class NextCatalogBuilder { const locationsCatalog = new DatabaseLocationsCatalog(db); const locationAnalyzer = new RepoLocationAnalyzer(logger); - + const locationService = new DefaultLocationService( + locationStore, + orchestrator, + ); return { entitiesCatalog, locationsCatalog, locationAnalyzer, processingEngine, + locationService, }; } diff --git a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts index e87bb01e1f..13cbf39c7b 100644 --- a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts @@ -18,37 +18,128 @@ import { Knex } from 'knex'; import { DbFinalEntitiesRow } from './Stitcher'; import { EntitiesCatalog } from '../catalog'; import { EntitiesRequest, EntitiesResponse } from '../catalog/types'; +import { DbRefreshStateRow } from './database/DefaultProcessingDatabase'; +import { + DbEntitiesSearchRow, + DbPageInfo, + EntityPagination, +} from '../database/types'; +import { InputError } from '@backstage/errors'; + +function parsePagination( + input?: EntityPagination, +): { limit?: number; offset?: number } { + if (!input) { + return {}; + } + + let { limit, offset } = input; + + if (input.after !== undefined) { + let cursor; + try { + const json = Buffer.from(input.after, 'base64').toString('utf8'); + cursor = JSON.parse(json); + } catch { + throw new InputError('Malformed after cursor, could not be parsed'); + } + if (cursor.limit !== undefined) { + if (!Number.isInteger(cursor.limit)) { + throw new InputError('Malformed after cursor, limit was not an number'); + } + limit = cursor.limit; + } + if (cursor.offset !== undefined) { + if (!Number.isInteger(cursor.offset)) { + throw new InputError('Malformed after cursor, offset was not a number'); + } + offset = cursor.offset; + } + } + + return { limit, offset }; +} + +function stringifyPagination(input: { limit: number; offset: number }) { + const json = JSON.stringify({ limit: input.limit, offset: input.offset }); + const base64 = Buffer.from(json, 'utf8').toString('base64'); + return base64; +} export class NextEntitiesCatalog implements EntitiesCatalog { constructor(private readonly database: Knex) {} async entities(request?: EntitiesRequest): Promise<EntitiesResponse> { - if (request?.fields) { - throw new Error('Fields extraction is not implemented'); - } - if (request?.pagination) { - throw new Error('Pagination is not implemented'); - } - if (request?.filter) { - throw new Error('Filters are not implemented'); + const db = this.database; + + let entitiesQuery = db<DbFinalEntitiesRow>('final_entities'); + + for (const singleFilter of request?.filter?.anyOf ?? []) { + entitiesQuery = entitiesQuery.orWhere(function singleFilterFn() { + for (const { key, matchValueIn } of singleFilter.allOf) { + // NOTE(freben): This used to be a set of OUTER JOIN, which may seem to + // make a lot of sense. However, it had abysmal performance on sqlite + // when datasets grew large, so we're using IN instead. + const matchQuery = db<DbEntitiesSearchRow>('search') + .select('entity_id') + .where(function keyFilter() { + this.andWhere({ key: key.toLowerCase() }); + if (matchValueIn) { + if (matchValueIn.length === 1) { + this.andWhere({ value: matchValueIn[0].toLowerCase() }); + } else if (matchValueIn.length > 1) { + this.andWhere( + 'value', + 'in', + matchValueIn.map(v => v.toLowerCase()), + ); + } + } + }); + this.andWhere('entity_id', 'in', matchQuery); + } + }); } - const dbResponse = await this.database<DbFinalEntitiesRow>( - 'final_entities', - ).select(); + // TODO: move final_entities to use entity_Ref + entitiesQuery = entitiesQuery + .select('final_entities.*') + .orderBy('entity_id', 'asc'); - const entities = dbResponse.map(e => JSON.parse(e.final_entity)); + const { limit, offset } = parsePagination(request?.pagination); + if (limit !== undefined) { + entitiesQuery = entitiesQuery.limit(limit + 1); + } + if (offset !== undefined) { + entitiesQuery = entitiesQuery.offset(offset); + } + + let rows = await entitiesQuery; + + let pageInfo: DbPageInfo; + if (limit === undefined || rows.length <= limit) { + pageInfo = { hasNextPage: false }; + } else { + rows = rows.slice(0, -1); + pageInfo = { + hasNextPage: true, + endCursor: stringifyPagination({ + limit, + offset: (offset ?? 0) + limit, + }), + }; + } return { - entities, - pageInfo: { - hasNextPage: false, - }, + entities: rows.map(e => JSON.parse(e.final_entity)), + pageInfo, }; } - async removeEntityByUid(_uid: string): Promise<void> { - throw new Error('Not implemented'); + async removeEntityByUid(uid: string): Promise<void> { + await this.database<DbRefreshStateRow>('refresh_state') + .where('entity_id', uid) + .delete(); } async batchAddOrUpdateEntities(): Promise<never> { diff --git a/plugins/catalog-backend/src/next/NextRouter.ts b/plugins/catalog-backend/src/next/NextRouter.ts new file mode 100644 index 0000000000..433abd97e9 --- /dev/null +++ b/plugins/catalog-backend/src/next/NextRouter.ts @@ -0,0 +1,164 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { errorHandler } from '@backstage/backend-common'; +import { + analyzeLocationSchema, + locationSpecSchema, +} from '@backstage/catalog-model'; +import { Config } from '@backstage/config'; +import { NotFoundError } from '@backstage/errors'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; +import yn from 'yn'; +import { EntitiesCatalog } from '../catalog'; +import { LocationAnalyzer } from '../ingestion/types'; +import { + basicEntityFilter, + parseEntityFilterParams, + parseEntityPaginationParams, + parseEntityTransformParams, +} from '../service/request'; +import { LocationService } from './types'; +import { disallowReadonlyMode, validateRequestBody } from '../service/util'; + +export interface RouterOptions { + entitiesCatalog?: EntitiesCatalog; + locationAnalyzer?: LocationAnalyzer; + locationService: LocationService; + logger: Logger; + config: Config; +} + +export async function createNextRouter( + options: RouterOptions, +): Promise<express.Router> { + const { + entitiesCatalog, + locationAnalyzer, + locationService, + config, + logger, + } = options; + + const router = Router(); + router.use(express.json()); + + const readonlyEnabled = + config.getOptionalBoolean('catalog.readonly') || false; + if (readonlyEnabled) { + logger.info('Catalog is running in readonly mode'); + } + + if (entitiesCatalog) { + router + .get('/entities', async (req, res) => { + const { entities, pageInfo } = await entitiesCatalog.entities({ + filter: parseEntityFilterParams(req.query), + fields: parseEntityTransformParams(req.query), + pagination: parseEntityPaginationParams(req.query), + }); + + // Add a Link header to the next page + if (pageInfo.hasNextPage) { + const url = new URL(`http://ignored${req.url}`); + url.searchParams.delete('offset'); + url.searchParams.set('after', pageInfo.endCursor); + res.setHeader('link', `<${url.pathname}${url.search}>; rel="next"`); + } + + // TODO(freben): encode the pageInfo in the response + res.json(entities); + }) + .get('/entities/by-uid/:uid', async (req, res) => { + const { uid } = req.params; + const { entities } = await entitiesCatalog.entities({ + filter: basicEntityFilter({ 'metadata.uid': uid }), + }); + if (!entities.length) { + throw new NotFoundError(`No entity with uid ${uid}`); + } + res.status(200).json(entities[0]); + }) + .delete('/entities/by-uid/:uid', async (req, res) => { + const { uid } = req.params; + await entitiesCatalog.removeEntityByUid(uid); + res.status(204).end(); + }) + .get('/entities/by-name/:kind/:namespace/:name', async (req, res) => { + const { kind, namespace, name } = req.params; + const { entities } = await entitiesCatalog.entities({ + filter: basicEntityFilter({ + kind: kind, + 'metadata.namespace': namespace, + 'metadata.name': name, + }), + }); + if (!entities.length) { + throw new NotFoundError( + `No entity named '${name}' found, with kind '${kind}' in namespace '${namespace}'`, + ); + } + res.status(200).json(entities[0]); + }); + } + + if (locationService) { + router + .post('/locations', async (req, res) => { + const input = await validateRequestBody(req, locationSpecSchema); + const dryRun = yn(req.query.dryRun, { default: false }); + + // when in dryRun addLocation is effectively a read operation so we don't + // need to disallow readonly + if (!dryRun) { + disallowReadonlyMode(readonlyEnabled); + } + + const output = await locationService.createLocation(input, dryRun); + res.status(201).json(output); + }) + .get('/locations', async (_req, res) => { + const output = await locationService.listLocations(); + res.status(200).json(output); + }) + + .get('/locations/:id', async (req, res) => { + const { id } = req.params; + const output = await locationService.getLocation(id); + res.status(200).json(output); + }) + .delete('/locations/:id', async (req, res) => { + disallowReadonlyMode(readonlyEnabled); + + const { id } = req.params; + await locationService.deleteLocation(id); + res.status(204).end(); + }); + } + + if (locationAnalyzer) { + router.post('/analyze-location', async (req, res) => { + const input = await validateRequestBody(req, analyzeLocationSchema); + const output = await locationAnalyzer.analyzeLocation(input); + res.status(200).json(output); + }); + } + + router.use(errorHandler()); + return router; +} diff --git a/plugins/catalog-backend/src/next/Stitcher.ts b/plugins/catalog-backend/src/next/Stitcher.ts index bdc028d923..2bddf41ac9 100644 --- a/plugins/catalog-backend/src/next/Stitcher.ts +++ b/plugins/catalog-backend/src/next/Stitcher.ts @@ -84,14 +84,14 @@ export class Stitcher { relationTarget: 'relations.target_entity_ref', }) .from('refresh_state') - .leftJoin('incoming_references', {}) + .where({ 'refresh_state.entity_ref': entityRef }) + .crossJoin(tx.raw('incoming_references')) .leftOuterJoin('final_entities', { 'final_entities.entity_id': 'refresh_state.entity_id', }) .leftOuterJoin('relations', { 'relations.source_entity_ref': 'refresh_state.entity_ref', }) - .where({ 'refresh_state.entity_ref': entityRef }) .orderBy('relationType', 'asc') .orderBy('relationTarget', 'asc'); diff --git a/plugins/catalog-backend/src/next/index.ts b/plugins/catalog-backend/src/next/index.ts index d4eeca4c81..76867e05c8 100644 --- a/plugins/catalog-backend/src/next/index.ts +++ b/plugins/catalog-backend/src/next/index.ts @@ -15,3 +15,4 @@ */ export { NextCatalogBuilder } from './NextCatalogBuilder'; +export { createNextRouter } from './NextRouter'; From e938fc30cdcc3883a22be5c8fe41745e26095b42 Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Wed, 5 May 2021 10:42:27 -0400 Subject: [PATCH 438/462] Fix typo Signed-off-by: Adam Harvey <adaharve@cisco.com> --- .../catalog-import/src/components/ImportStepper/defaults.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-import/src/components/ImportStepper/defaults.tsx b/plugins/catalog-import/src/components/ImportStepper/defaults.tsx index 354ff6974f..a8c9b41abb 100644 --- a/plugins/catalog-import/src/components/ImportStepper/defaults.tsx +++ b/plugins/catalog-import/src/components/ImportStepper/defaults.tsx @@ -275,7 +275,7 @@ export function defaultGenerateStepper( } /> <FormHelperText> - WARNING: This may fail is no CODEOWNERS file is found at + WARNING: This may fail if no CODEOWNERS file is found at the target location. </FormHelperText> </> From 74f4aa43daef96d6e33fb09747887ee789aa3fbb Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Wed, 5 May 2021 10:43:07 -0400 Subject: [PATCH 439/462] Update wording in dialog Signed-off-by: Adam Harvey <adaharve@cisco.com> --- .../StepPrepareCreatePullRequest.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx index c34d5f374b..d1f8be7065 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx @@ -176,10 +176,9 @@ export const StepPrepareCreatePullRequest = ({ return ( <> <Typography> - You entered a link to a {analyzeResult.integrationType} repository but - we didn't found a <code>catalog-info.yaml</code>. Use this form to - create a Pull Request that creates an initial{' '} - <code>catalog-info.yaml</code>. + You entered a link to a {analyzeResult.integrationType} repository but a{' '} + <code>catalog-info.yaml</code> could not be found. Use this form to open + a Pull Request that creates one. </Typography> <PreparePullRequestForm<FormData> From 8aedbb4afb38ccb87e190dea01f23acca2b95c9b Mon Sep 17 00:00:00 2001 From: Adam Harvey <adaharve@cisco.com> Date: Wed, 5 May 2021 10:44:15 -0400 Subject: [PATCH 440/462] Add changeset Signed-off-by: Adam Harvey <adaharve@cisco.com> --- .changeset/nice-jars-pull.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nice-jars-pull.md diff --git a/.changeset/nice-jars-pull.md b/.changeset/nice-jars-pull.md new file mode 100644 index 0000000000..fde3a41626 --- /dev/null +++ b/.changeset/nice-jars-pull.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-import': patch +--- + +Fixes a typo and minor wording changes to the catalog import UI From 90ba3a3205363dec2cb1f25688263437d3c79c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= <kevin.gomez@voiapp.io> Date: Wed, 5 May 2021 16:56:45 +0200 Subject: [PATCH 441/462] Test the GroupsExplorerContent and GroupsDiagram components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Gomez <kevin.gomez@voiapp.io> --- .../GroupsDiagram.test.tsx | 69 ++++++++++++ .../GroupsExplorerContent.test.tsx | 103 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx create mode 100644 plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx new file mode 100644 index 0000000000..022387faca --- /dev/null +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsDiagram.test.tsx @@ -0,0 +1,69 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { + catalogApiRef, + CatalogApi, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; +import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { GroupsDiagram } from './GroupsDiagram'; + +describe('<GroupsDiagram />', () => { + beforeAll(() => { + Object.defineProperty(window.SVGElement.prototype, 'getBBox', { + value: () => ({ width: 100, height: 100 }), + configurable: true, + }); + }); + + it('shows groups', async () => { + const catalogApi: Partial<CatalogApi> = { + getEntities: () => + Promise.resolve({ + items: [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'group-a', + namespace: 'my-namespace', + }, + spec: { + type: 'organization', + }, + }, + ] as Entity[], + }), + }; + + const { getByText } = await renderInTestApp( + <ApiProvider apis={ApiRegistry.from([[catalogApiRef, catalogApi]])}> + <GroupsDiagram /> + </ApiProvider>, + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect(getByText('my-namespace/group-a')).toBeInTheDocument(); + }); +}); diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx new file mode 100644 index 0000000000..38c4678d5a --- /dev/null +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.test.tsx @@ -0,0 +1,103 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import { waitFor } from '@testing-library/react'; +import React from 'react'; +import { GroupsExplorerContent } from '../GroupsExplorerContent'; + +describe('<GroupsExplorerContent />', () => { + const catalogApi: jest.Mocked<typeof catalogApiRef.T> = { + addLocation: jest.fn(_a => new Promise(() => {})), + getEntities: jest.fn(), + getOriginLocationByEntity: jest.fn(), + getLocationByEntity: jest.fn(), + getLocationById: jest.fn(), + removeLocationById: jest.fn(), + removeEntityByUid: jest.fn(), + getEntityByName: jest.fn(), + }; + + const Wrapper = ({ children }: { children?: React.ReactNode }) => ( + <ApiProvider apis={ApiRegistry.with(catalogApiRef, catalogApi)}> + {children} + </ApiProvider> + ); + + beforeEach(() => { + jest.resetAllMocks(); + + Object.defineProperty(window.SVGElement.prototype, 'getBBox', { + value: () => ({ width: 100, height: 100 }), + configurable: true, + }); + }); + + it('renders a groups diagram', async () => { + const entities: Entity[] = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'group-a', + namespace: 'my-namespace', + }, + spec: { + type: 'organization', + }, + }, + ]; + catalogApi.getEntities.mockResolvedValue({ items: entities }); + + const { getByText } = await renderInTestApp( + <Wrapper> + <GroupsExplorerContent /> + </Wrapper>, + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + await waitFor(() => { + expect(getByText('my-namespace/group-a')).toBeInTheDocument(); + }); + }); + + it('renders a friendly error if it cannot collect domains', async () => { + const catalogError = new Error('Network timeout'); + catalogApi.getEntities.mockRejectedValueOnce(catalogError); + + const { getByText } = await renderInTestApp( + <Wrapper> + <GroupsExplorerContent /> + </Wrapper>, + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + await waitFor(() => + expect(getByText(/Warning: Network timeout/)).toBeInTheDocument(), + ); + }); +}); From e133f76cd153b8d117cd11fa1c1dc51c4a6a1252 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 May 2021 04:12:19 +0000 Subject: [PATCH 442/462] chore(deps): bump ts-node from 8.10.2 to 9.1.1 Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 8.10.2 to 9.1.1. - [Release notes](https://github.com/TypeStrong/ts-node/releases) - [Commits](https://github.com/TypeStrong/ts-node/compare/v8.10.2...v9.1.1) Signed-off-by: dependabot[bot] <support@github.com> --- packages/cli/package.json | 2 +- packages/create-app/package.json | 2 +- packages/docgen/package.json | 2 +- packages/e2e-test/package.json | 2 +- plugins/catalog-graphql/package.json | 2 +- yarn.lock | 11 ----------- 6 files changed, 5 insertions(+), 16 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 46e99b762b..1673c62513 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -143,7 +143,7 @@ "del": "^5.1.0", "mock-fs": "^4.13.0", "nodemon": "^2.0.2", - "ts-node": "^8.6.2" + "ts-node": "^9.1.1" }, "files": [ "asset-types", diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 071a0a5ebd..8129dbf5d4 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -41,7 +41,7 @@ "@types/inquirer": "^7.3.1", "@types/react-dev-utils": "^9.0.4", "@types/recursive-readdir": "^2.2.0", - "ts-node": "^8.6.2" + "ts-node": "^9.1.1" }, "peerDependencies": { "@backstage/backend-common": "*", diff --git a/packages/docgen/package.json b/packages/docgen/package.json index bb00620967..a7d7615e19 100644 --- a/packages/docgen/package.json +++ b/packages/docgen/package.json @@ -30,7 +30,7 @@ "commander": "^6.1.0", "fs-extra": "^9.0.0", "github-slugger": "^1.3.0", - "ts-node": "^8.6.2", + "ts-node": "^9.1.1", "typescript": "^4.0.3" }, "devDependencies": { diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 6cd740c7b7..77a3e3960a 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -34,7 +34,7 @@ "handlebars": "^4.7.3", "pgtools": "^0.3.0", "tree-kill": "^1.2.2", - "ts-node": "^8.6.2", + "ts-node": "^9.1.1", "zombie": "^6.1.4" }, "nodemonConfig": { diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index 3ab6d64dc8..18aac98aa5 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -52,7 +52,7 @@ "eslint-plugin-graphql": "^4.0.0", "msw": "^0.21.2", "supertest": "^6.1.3", - "ts-node": "^8.10.2" + "ts-node": "^9.1.1" }, "files": [ "dist" diff --git a/yarn.lock b/yarn.lock index 23cf3b2fd2..266171ae3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25582,17 +25582,6 @@ ts-log@^2.2.3: resolved "https://registry.npmjs.org/ts-log/-/ts-log-2.2.3.tgz#4da5640fe25a9fb52642cd32391c886721318efb" integrity sha512-XvB+OdKSJ708Dmf9ore4Uf/q62AYDTzFcAdxc8KNML1mmAWywRFVt/dn1KYJH8Agt5UJNujfM3znU5PxgAzA2w== -ts-node@^8.10.2, ts-node@^8.6.2: - version "8.10.2" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" - integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - ts-node@^9, ts-node@^9.1.1: version "9.1.1" resolved "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" From 597f3e132eef11a979973b0e910f0059bfed1f74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 May 2021 04:21:40 +0000 Subject: [PATCH 443/462] chore(deps): bump yaml from 1.10.0 to 1.10.2 Bumps [yaml](https://github.com/eemeli/yaml) from 1.10.0 to 1.10.2. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](https://github.com/eemeli/yaml/compare/v1.10.0...v1.10.2) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 23cf3b2fd2..a471cbb1e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27143,9 +27143,9 @@ yaml-ast-parser@0.0.43, yaml-ast-parser@^0.0.43: integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== yaml@^1.10.0, yaml@^1.7.2, yaml@^1.9.2: - version "1.10.0" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" - integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== + version "1.10.2" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yargs-parser@20.2.4, yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.4" From d397eb470fd73f2c79298f1558132eb7d68ebcc5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Thu, 6 May 2021 08:25:18 +0000 Subject: [PATCH 444/462] Version Packages --- .changeset/bright-bags-hope.md | 56 ------- .../cost-insights-five-baboons-attack.md | 5 - .changeset/eight-dingos-exist.md | 58 ------- .changeset/few-games-collect.md | 61 ------- .changeset/five-knives-flash.md | 10 -- .changeset/flat-keys-happen.md | 6 - .changeset/friendly-readers-promise.md | 5 - .changeset/fuzzy-dancers-complain.md | 6 - .changeset/khaki-rice-accept.md | 5 - .changeset/khaki-singers-perform.md | 5 - .changeset/nice-jars-pull.md | 5 - .changeset/nice-shirts-fetch.md | 5 - .changeset/old-horses-brake.md | 6 - .changeset/silly-tables-build.md | 6 - .changeset/small-sheep-smoke.md | 5 - .changeset/spicy-countries-hope.md | 27 --- .changeset/spotty-pigs-bathe.md | 5 - .changeset/stupid-feet-reply.md | 5 - .changeset/tame-masks-juggle.md | 5 - .changeset/techdocs-rich-carrots-collect.md | 5 - .changeset/ten-cups-relax.md | 5 - .changeset/thick-cobras-switch.md | 5 - .changeset/tough-walls-wash.md | 9 - .changeset/tricky-yaks-melt.md | 6 - .changeset/twenty-peas-deny.md | 5 - .changeset/wild-stingrays-yawn.md | 115 ------------- packages/app/CHANGELOG.md | 31 ++++ packages/app/package.json | 26 +-- packages/backend-common/CHANGELOG.md | 68 ++++++++ packages/backend-common/package.json | 10 +- packages/backend/CHANGELOG.md | 36 ++++ packages/backend/package.json | 42 ++--- packages/catalog-client/CHANGELOG.md | 9 + packages/catalog-client/package.json | 8 +- packages/catalog-model/CHANGELOG.md | 8 + packages/catalog-model/package.json | 6 +- packages/cli/CHANGELOG.md | 11 ++ packages/cli/package.json | 14 +- packages/config-loader/CHANGELOG.md | 8 + packages/config-loader/package.json | 4 +- packages/config/CHANGELOG.md | 6 + packages/config/package.json | 2 +- packages/core/CHANGELOG.md | 11 ++ packages/core/package.json | 8 +- packages/create-app/CHANGELOG.md | 157 ++++++++++++++++++ packages/create-app/package.json | 2 +- packages/integration/CHANGELOG.md | 8 + packages/integration/package.json | 8 +- packages/techdocs-common/CHANGELOG.md | 40 +++++ packages/techdocs-common/package.json | 12 +- packages/theme/CHANGELOG.md | 6 + packages/theme/package.json | 4 +- plugins/api-docs/package.json | 6 +- plugins/app-backend/CHANGELOG.md | 11 ++ plugins/app-backend/package.json | 10 +- plugins/auth-backend/CHANGELOG.md | 13 ++ plugins/auth-backend/package.json | 12 +- plugins/badges-backend/CHANGELOG.md | 13 ++ plugins/badges-backend/package.json | 12 +- plugins/badges/package.json | 6 +- plugins/bitrise/package.json | 6 +- plugins/catalog-backend/CHANGELOG.md | 14 ++ plugins/catalog-backend/package.json | 12 +- plugins/catalog-graphql/CHANGELOG.md | 11 ++ plugins/catalog-graphql/package.json | 10 +- plugins/catalog-import/CHANGELOG.md | 21 +++ plugins/catalog-import/package.json | 16 +- plugins/catalog-react/CHANGELOG.md | 13 ++ plugins/catalog-react/package.json | 10 +- plugins/catalog/package.json | 6 +- plugins/circleci/package.json | 6 +- plugins/cloudbuild/package.json | 6 +- plugins/code-coverage-backend/CHANGELOG.md | 14 ++ plugins/code-coverage-backend/package.json | 14 +- plugins/code-coverage/package.json | 6 +- plugins/config-schema/package.json | 6 +- plugins/cost-insights/CHANGELOG.md | 16 ++ plugins/cost-insights/package.json | 10 +- plugins/explore/package.json | 6 +- plugins/fossa/package.json | 6 +- plugins/gcp-projects/package.json | 6 +- plugins/github-actions/CHANGELOG.md | 17 ++ plugins/github-actions/package.json | 14 +- plugins/github-deployments/package.json | 6 +- plugins/gitops-profiles/package.json | 6 +- plugins/graphiql/package.json | 6 +- plugins/graphql/CHANGELOG.md | 11 ++ plugins/graphql/package.json | 10 +- plugins/jenkins/package.json | 6 +- plugins/kafka-backend/CHANGELOG.md | 11 ++ plugins/kafka-backend/package.json | 10 +- plugins/kafka/package.json | 6 +- plugins/kubernetes-backend/CHANGELOG.md | 12 ++ plugins/kubernetes-backend/package.json | 10 +- plugins/kubernetes/CHANGELOG.md | 16 ++ plugins/kubernetes/package.json | 14 +- plugins/lighthouse/package.json | 6 +- plugins/newrelic/package.json | 6 +- plugins/org/package.json | 6 +- plugins/pagerduty/package.json | 6 +- plugins/proxy-backend/CHANGELOG.md | 11 ++ plugins/proxy-backend/package.json | 8 +- plugins/register-component/package.json | 6 +- plugins/rollbar-backend/CHANGELOG.md | 10 ++ plugins/rollbar-backend/package.json | 8 +- plugins/rollbar/package.json | 6 +- plugins/scaffolder-backend/CHANGELOG.md | 73 ++++++++ plugins/scaffolder-backend/package.json | 14 +- plugins/scaffolder/CHANGELOG.md | 21 +++ plugins/scaffolder/package.json | 18 +- plugins/search-backend-node/package.json | 4 +- plugins/search-backend/CHANGELOG.md | 8 + plugins/search-backend/package.json | 6 +- plugins/search/package.json | 6 +- plugins/sentry/package.json | 6 +- plugins/sonarqube/package.json | 6 +- plugins/splunk-on-call/package.json | 6 +- plugins/tech-radar/CHANGELOG.md | 11 ++ plugins/tech-radar/package.json | 8 +- plugins/techdocs-backend/CHANGELOG.md | 74 +++++++++ plugins/techdocs-backend/package.json | 12 +- plugins/techdocs/CHANGELOG.md | 19 +++ plugins/techdocs/package.json | 16 +- plugins/todo-backend/CHANGELOG.md | 14 ++ plugins/todo-backend/package.json | 14 +- plugins/todo/package.json | 6 +- plugins/user-settings/package.json | 6 +- plugins/welcome/package.json | 6 +- 128 files changed, 1129 insertions(+), 732 deletions(-) delete mode 100644 .changeset/bright-bags-hope.md delete mode 100644 .changeset/cost-insights-five-baboons-attack.md delete mode 100644 .changeset/eight-dingos-exist.md delete mode 100644 .changeset/few-games-collect.md delete mode 100644 .changeset/five-knives-flash.md delete mode 100644 .changeset/flat-keys-happen.md delete mode 100644 .changeset/friendly-readers-promise.md delete mode 100644 .changeset/fuzzy-dancers-complain.md delete mode 100644 .changeset/khaki-rice-accept.md delete mode 100644 .changeset/khaki-singers-perform.md delete mode 100644 .changeset/nice-jars-pull.md delete mode 100644 .changeset/nice-shirts-fetch.md delete mode 100644 .changeset/old-horses-brake.md delete mode 100644 .changeset/silly-tables-build.md delete mode 100644 .changeset/small-sheep-smoke.md delete mode 100644 .changeset/spicy-countries-hope.md delete mode 100644 .changeset/spotty-pigs-bathe.md delete mode 100644 .changeset/stupid-feet-reply.md delete mode 100644 .changeset/tame-masks-juggle.md delete mode 100644 .changeset/techdocs-rich-carrots-collect.md delete mode 100644 .changeset/ten-cups-relax.md delete mode 100644 .changeset/thick-cobras-switch.md delete mode 100644 .changeset/tough-walls-wash.md delete mode 100644 .changeset/tricky-yaks-melt.md delete mode 100644 .changeset/twenty-peas-deny.md delete mode 100644 .changeset/wild-stingrays-yawn.md diff --git a/.changeset/bright-bags-hope.md b/.changeset/bright-bags-hope.md deleted file mode 100644 index 88ef046fb7..0000000000 --- a/.changeset/bright-bags-hope.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. -It also provides the `ContainerRunner` to the individual templaters instead of to the `createRouter` function. - -To apply this change to an existing backend application, add the following to `src/plugins/scaffolder.ts`: - -```diff -- import { SingleHostDiscovery } from '@backstage/backend-common'; -+ import { -+ DockerContainerRunner, -+ SingleHostDiscovery, -+ } from '@backstage/backend-common'; - - - export default async function createPlugin({ - logger, - config, - database, - reader, - }: PluginEnvironment): Promise<Router> { -+ const dockerClient = new Docker(); -+ const containerRunner = new DockerContainerRunner({ dockerClient }); - -+ const cookiecutterTemplater = new CookieCutter({ containerRunner }); -- const cookiecutterTemplater = new CookieCutter(); -+ const craTemplater = new CreateReactAppTemplater({ containerRunner }); -- const craTemplater = new CreateReactAppTemplater(); - const templaters = new Templaters(); - - templaters.register('cookiecutter', cookiecutterTemplater); - templaters.register('cra', craTemplater); - - const preparers = await Preparers.fromConfig(config, { logger }); - const publishers = await Publishers.fromConfig(config, { logger }); - -- const dockerClient = new Docker(); - - const discovery = SingleHostDiscovery.fromConfig(config); - const catalogClient = new CatalogClient({ discoveryApi: discovery }); - - return await createRouter({ - preparers, - templaters, - publishers, - logger, - config, -- dockerClient, - database, - catalogClient, - reader, - }); - } -``` diff --git a/.changeset/cost-insights-five-baboons-attack.md b/.changeset/cost-insights-five-baboons-attack.md deleted file mode 100644 index f2c070acb4..0000000000 --- a/.changeset/cost-insights-five-baboons-attack.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-cost-insights': minor ---- - -make change ratio optional diff --git a/.changeset/eight-dingos-exist.md b/.changeset/eight-dingos-exist.md deleted file mode 100644 index 9a6553e7e9..0000000000 --- a/.changeset/eight-dingos-exist.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -'@backstage/backend-common': minor ---- - -Refactor the `runDockerContainer(…)` function to an interface-based api. -This gives the option to replace the docker runtime in the future. - -Packages and plugins that previously used the `dockerode` as argument should be migrated to use the new `ContainerRunner` interface instead. - -```diff - import { -- runDockerContainer, -+ ContainerRunner, - PluginEndpointDiscovery, - } from '@backstage/backend-common'; -- import Docker from 'dockerode'; - - type RouterOptions = { - // ... -- dockerClient: Docker, -+ containerRunner: ContainerRunner; - }; - - export async function createRouter({ - // ... -- dockerClient, -+ containerRunner, - }: RouterOptions): Promise<express.Router> { - // ... - -+ await containerRunner.runContainer({ -- await runDockerContainer({ - image: 'docker', - // ... -- dockerClient, - }); - - // ... - } -``` - -To keep the `dockerode` based runtime, use the `DockerContainerRunner` implementation: - -```diff -+ import { -+ ContainerRunner, -+ DockerContainerRunner -+ } from '@backstage/backend-common'; -- import { runDockerContainer } from '@backstage/backend-common'; - -+ const containerRunner: ContainerRunner = new DockerContainerRunner({dockerClient}); -+ await containerRunner.runContainer({ -- await runDockerContainer({ - image: 'docker', - // ... -- dockerClient, - }); -``` diff --git a/.changeset/few-games-collect.md b/.changeset/few-games-collect.md deleted file mode 100644 index f6a27f66c7..0000000000 --- a/.changeset/few-games-collect.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': minor ---- - -Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. -It also provides the `ContainerRunner` to the generators instead of to the `createRouter` function. - -To apply this change to an existing backend application, add the following to `src/plugins/techdocs.ts`: - -```diff -+ import { DockerContainerRunner } from '@backstage/backend-common'; - - // ... - - export default async function createPlugin({ - logger, - config, - discovery, - reader, - }: PluginEnvironment): Promise<Router> { - // Preparers are responsible for fetching source files for documentation. - const preparers = await Preparers.fromConfig(config, { - logger, - reader, - }); - -+ // Docker client (conditionally) used by the generators, based on techdocs.generators config. -+ const dockerClient = new Docker(); -+ const containerRunner = new DockerContainerRunner({ dockerClient }); - - // Generators are used for generating documentation sites. - const generators = await Generators.fromConfig(config, { - logger, -+ containerRunner, - }); - - // Publisher is used for - // 1. Publishing generated files to storage - // 2. Fetching files from storage and passing them to TechDocs frontend. - const publisher = await Publisher.fromConfig(config, { - logger, - discovery, - }); - - // checks if the publisher is working and logs the result - await publisher.getReadiness(); - -- // Docker client (conditionally) used by the generators, based on techdocs.generators config. -- const dockerClient = new Docker(); - - return await createRouter({ - preparers, - generators, - publisher, -- dockerClient, - logger, - config, - discovery, - }); - } -``` diff --git a/.changeset/five-knives-flash.md b/.changeset/five-knives-flash.md deleted file mode 100644 index 9076f6f456..0000000000 --- a/.changeset/five-knives-flash.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/create-app': patch -'@backstage/integration': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. diff --git a/.changeset/flat-keys-happen.md b/.changeset/flat-keys-happen.md deleted file mode 100644 index ce01f86bcf..0000000000 --- a/.changeset/flat-keys-happen.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/core': patch ---- - -Fix some transitive dependency warnings in yarn diff --git a/.changeset/friendly-readers-promise.md b/.changeset/friendly-readers-promise.md deleted file mode 100644 index 30607d5db2..0000000000 --- a/.changeset/friendly-readers-promise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -Fetch relations in batches in `useRelatedEntities` diff --git a/.changeset/fuzzy-dancers-complain.md b/.changeset/fuzzy-dancers-complain.md deleted file mode 100644 index a23e6bc3df..0000000000 --- a/.changeset/fuzzy-dancers-complain.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core': patch -'@backstage/plugin-catalog-import': patch ---- - -Bump react-hook-form version to be the same for the entire project. diff --git a/.changeset/khaki-rice-accept.md b/.changeset/khaki-rice-accept.md deleted file mode 100644 index 72f1c635ed..0000000000 --- a/.changeset/khaki-rice-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Expose `BitbucketRepositoryParser` introduced in [#5295](https://github.com/backstage/backstage/pull/5295) diff --git a/.changeset/khaki-singers-perform.md b/.changeset/khaki-singers-perform.md deleted file mode 100644 index d63c8754a8..0000000000 --- a/.changeset/khaki-singers-perform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/theme': patch ---- - -Remove extra bottom padding in InfoCard content diff --git a/.changeset/nice-jars-pull.md b/.changeset/nice-jars-pull.md deleted file mode 100644 index fde3a41626..0000000000 --- a/.changeset/nice-jars-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-import': patch ---- - -Fixes a typo and minor wording changes to the catalog import UI diff --git a/.changeset/nice-shirts-fetch.md b/.changeset/nice-shirts-fetch.md deleted file mode 100644 index e9537e63b3..0000000000 --- a/.changeset/nice-shirts-fetch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added lax option to backstage-cli app:build command diff --git a/.changeset/old-horses-brake.md b/.changeset/old-horses-brake.md deleted file mode 100644 index ea41019b23..0000000000 --- a/.changeset/old-horses-brake.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Fix GithubPR built-in action `credentialsProvider.getCredentials` URL. -Adding Documentation for GitHub PR built-in action. diff --git a/.changeset/silly-tables-build.md b/.changeset/silly-tables-build.md deleted file mode 100644 index cb2fd73950..0000000000 --- a/.changeset/silly-tables-build.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-kubernetes-backend': patch ---- - -Adds @backstage/plugin-kubernetes-common library to share types between kubernetes frontend and backend. diff --git a/.changeset/small-sheep-smoke.md b/.changeset/small-sheep-smoke.md deleted file mode 100644 index fd917159d3..0000000000 --- a/.changeset/small-sheep-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -bump `jsonschema` from 1.2.7 to 1.4.0 diff --git a/.changeset/spicy-countries-hope.md b/.changeset/spicy-countries-hope.md deleted file mode 100644 index 574a117f6e..0000000000 --- a/.changeset/spicy-countries-hope.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -'@backstage/techdocs-common': minor ---- - -Migrate the package to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. -It also no longer provides the `ContainerRunner` as an input to the `GeneratorBase#run(…)` function, but expects it as a constructor parameter instead. - -If you use the `TechdocsGenerator` you need to update the usage: - -```diff -+ const containerRunner = new DockerContainerRunner({ dockerClient }); - -- const generator = new TechdocsGenerator(logger, config); -+ const techdocsGenerator = new TechdocsGenerator({ -+ logger, -+ containerRunner, -+ config, -+ }); - - await this.generator.run({ - inputDir: preparedDir, - outputDir, -- dockerClient: this.dockerClient, - parsedLocationAnnotation, - etag: newEtag, - }); -``` diff --git a/.changeset/spotty-pigs-bathe.md b/.changeset/spotty-pigs-bathe.md deleted file mode 100644 index 0585f335dc..0000000000 --- a/.changeset/spotty-pigs-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-radar': patch ---- - -Update README for composability diff --git a/.changeset/stupid-feet-reply.md b/.changeset/stupid-feet-reply.md deleted file mode 100644 index d7213b1bdc..0000000000 --- a/.changeset/stupid-feet-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Add support for non-organization accounts in GitHub Discovery diff --git a/.changeset/tame-masks-juggle.md b/.changeset/tame-masks-juggle.md deleted file mode 100644 index 91ee43945a..0000000000 --- a/.changeset/tame-masks-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Close eventSource upon completion of a scaffolder task diff --git a/.changeset/techdocs-rich-carrots-collect.md b/.changeset/techdocs-rich-carrots-collect.md deleted file mode 100644 index 0a762bdb66..0000000000 --- a/.changeset/techdocs-rich-carrots-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fix navigation in a page using the table of contents. diff --git a/.changeset/ten-cups-relax.md b/.changeset/ten-cups-relax.md deleted file mode 100644 index 9e32ad3856..0000000000 --- a/.changeset/ten-cups-relax.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Make git config optional for techdocs feedback links diff --git a/.changeset/thick-cobras-switch.md b/.changeset/thick-cobras-switch.md deleted file mode 100644 index 002c724421..0000000000 --- a/.changeset/thick-cobras-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-proxy-backend': patch ---- - -Prefix proxy routes with `/` if not present in configuration diff --git a/.changeset/tough-walls-wash.md b/.changeset/tough-walls-wash.md deleted file mode 100644 index a45adcfbf6..0000000000 --- a/.changeset/tough-walls-wash.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/catalog-model': patch -'@backstage/cli': patch -'@backstage/config-loader': patch -'@backstage/config': patch -'@backstage/plugin-scaffolder': patch ---- - -Bump `json-schema` dependency from `0.2.5` to `0.3.0`. diff --git a/.changeset/tricky-yaks-melt.md b/.changeset/tricky-yaks-melt.md deleted file mode 100644 index 3679e6d1da..0000000000 --- a/.changeset/tricky-yaks-melt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/techdocs-common': patch ---- - -Adding optional config to enable S3-like API for tech-docs using s3ForcePathStyle option. -This allows providers like LocalStack, Minio and Wasabi (+possibly others) to be used to host tech docs. diff --git a/.changeset/twenty-peas-deny.md b/.changeset/twenty-peas-deny.md deleted file mode 100644 index d149a9337c..0000000000 --- a/.changeset/twenty-peas-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-client': patch ---- - -Allow `filter` parameter to be specified multiple times diff --git a/.changeset/wild-stingrays-yawn.md b/.changeset/wild-stingrays-yawn.md deleted file mode 100644 index 6d8538c025..0000000000 --- a/.changeset/wild-stingrays-yawn.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -The `scaffolder-backend` and `techdocs-backend` plugins have been updated. -In order to update, you need to apply the following changes to your existing backend application: - -`@backstage/plugin-techdocs-backend`: - -```diff -// packages/backend/src/plugin/techdocs.ts - -+ import { DockerContainerRunner } from '@backstage/backend-common'; - - // ... - - export default async function createPlugin({ - logger, - config, - discovery, - reader, - }: PluginEnvironment): Promise<Router> { - // Preparers are responsible for fetching source files for documentation. - const preparers = await Preparers.fromConfig(config, { - logger, - reader, - }); - -+ // Docker client (conditionally) used by the generators, based on techdocs.generators config. -+ const dockerClient = new Docker(); -+ const containerRunner = new DockerContainerRunner({ dockerClient }); - - // Generators are used for generating documentation sites. - const generators = await Generators.fromConfig(config, { - logger, -+ containerRunner, - }); - - // Publisher is used for - // 1. Publishing generated files to storage - // 2. Fetching files from storage and passing them to TechDocs frontend. - const publisher = await Publisher.fromConfig(config, { - logger, - discovery, - }); - - // checks if the publisher is working and logs the result - await publisher.getReadiness(); - -- // Docker client (conditionally) used by the generators, based on techdocs.generators config. -- const dockerClient = new Docker(); - - return await createRouter({ - preparers, - generators, - publisher, -- dockerClient, - logger, - config, - discovery, - }); - } -``` - -`@backstage/plugin-scaffolder-backend`: - -```diff -// packages/backend/src/plugin/scaffolder.ts - -- import { SingleHostDiscovery } from '@backstage/backend-common'; -+ import { -+ DockerContainerRunner, -+ SingleHostDiscovery, -+ } from '@backstage/backend-common'; - - - export default async function createPlugin({ - logger, - config, - database, - reader, - }: PluginEnvironment): Promise<Router> { -+ const dockerClient = new Docker(); -+ const containerRunner = new DockerContainerRunner({ dockerClient }); - -+ const cookiecutterTemplater = new CookieCutter({ containerRunner }); -- const cookiecutterTemplater = new CookieCutter(); -+ const craTemplater = new CreateReactAppTemplater({ containerRunner }); -- const craTemplater = new CreateReactAppTemplater(); - const templaters = new Templaters(); - - templaters.register('cookiecutter', cookiecutterTemplater); - templaters.register('cra', craTemplater); - - const preparers = await Preparers.fromConfig(config, { logger }); - const publishers = await Publishers.fromConfig(config, { logger }); - -- const dockerClient = new Docker(); - - const discovery = SingleHostDiscovery.fromConfig(config); - const catalogClient = new CatalogClient({ discoveryApi: discovery }); - - return await createRouter({ - preparers, - templaters, - publishers, - logger, - config, -- dockerClient, - database, - catalogClient, - reader, - }); - } -``` diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index e9d3e63ad0..33ef204f63 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,36 @@ # example-app +## 0.2.27 + +### Patch Changes + +- Updated dependencies [6f1b82b14] +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [8aedbb4af] +- Updated dependencies [fc79a6dd3] +- Updated dependencies [f53fba29f] +- Updated dependencies [b2e2ec753] +- Updated dependencies [9314a8592] +- Updated dependencies [2e05277e0] +- Updated dependencies [4075c6367] +- Updated dependencies [d8b81fd28] + - @backstage/plugin-cost-insights@0.9.0 + - @backstage/plugin-catalog-import@0.5.5 + - @backstage/plugin-github-actions@0.4.5 + - @backstage/cli@0.6.10 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/plugin-kubernetes@0.4.3 + - @backstage/plugin-tech-radar@0.3.10 + - @backstage/plugin-scaffolder@0.9.3 + - @backstage/plugin-techdocs@0.9.1 + - @backstage/catalog-model@0.7.8 + ## 0.2.26 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index fb1ea02699..8ddf249366 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,42 +1,42 @@ { "name": "example-app", - "version": "0.2.26", + "version": "0.2.27", "private": true, "bundled": true, "dependencies": { - "@backstage/catalog-model": "^0.7.7", - "@backstage/cli": "^0.6.9", - "@backstage/core": "^0.7.7", + "@backstage/catalog-model": "^0.7.8", + "@backstage/cli": "^0.6.10", + "@backstage/core": "^0.7.8", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-api-docs": "^0.4.12", "@backstage/plugin-badges": "^0.2.0", "@backstage/plugin-catalog": "^0.5.6", - "@backstage/plugin-catalog-import": "^0.5.4", - "@backstage/plugin-catalog-react": "^0.1.3", + "@backstage/plugin-catalog-import": "^0.5.5", + "@backstage/plugin-catalog-react": "^0.1.5", "@backstage/plugin-circleci": "^0.2.13", "@backstage/plugin-cloudbuild": "^0.2.13", "@backstage/plugin-code-coverage": "^0.1.2", - "@backstage/plugin-cost-insights": "^0.8.5", + "@backstage/plugin-cost-insights": "^0.9.0", "@backstage/plugin-explore": "^0.3.4", "@backstage/plugin-gcp-projects": "^0.2.5", - "@backstage/plugin-github-actions": "^0.4.4", + "@backstage/plugin-github-actions": "^0.4.5", "@backstage/plugin-graphiql": "^0.2.10", "@backstage/plugin-jenkins": "^0.4.2", "@backstage/plugin-kafka": "^0.2.6", - "@backstage/plugin-kubernetes": "^0.4.2", + "@backstage/plugin-kubernetes": "^0.4.3", "@backstage/plugin-lighthouse": "^0.2.15", "@backstage/plugin-newrelic": "^0.2.6", "@backstage/plugin-org": "^0.3.12", "@backstage/plugin-pagerduty": "0.3.3", "@backstage/plugin-rollbar": "^0.3.4", - "@backstage/plugin-scaffolder": "^0.9.2", + "@backstage/plugin-scaffolder": "^0.9.3", "@backstage/plugin-search": "^0.3.5", "@backstage/plugin-sentry": "^0.3.9", - "@backstage/plugin-tech-radar": "^0.3.9", - "@backstage/plugin-techdocs": "^0.9.0", + "@backstage/plugin-tech-radar": "^0.3.10", + "@backstage/plugin-techdocs": "^0.9.1", "@backstage/plugin-todo": "^0.1.0", "@backstage/plugin-user-settings": "^0.2.8", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@octokit/rest": "^18.5.3", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 68fab7d861..3568adf099 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,73 @@ # @backstage/backend-common +## 0.7.0 + +### Minor Changes + +- e0bfd3d44: Refactor the `runDockerContainer(…)` function to an interface-based api. + This gives the option to replace the docker runtime in the future. + + Packages and plugins that previously used the `dockerode` as argument should be migrated to use the new `ContainerRunner` interface instead. + + ```diff + import { + - runDockerContainer, + + ContainerRunner, + PluginEndpointDiscovery, + } from '@backstage/backend-common'; + - import Docker from 'dockerode'; + + type RouterOptions = { + // ... + - dockerClient: Docker, + + containerRunner: ContainerRunner; + }; + + export async function createRouter({ + // ... + - dockerClient, + + containerRunner, + }: RouterOptions): Promise<express.Router> { + // ... + + + await containerRunner.runContainer({ + - await runDockerContainer({ + image: 'docker', + // ... + - dockerClient, + }); + + // ... + } + ``` + + To keep the `dockerode` based runtime, use the `DockerContainerRunner` implementation: + + ```diff + + import { + + ContainerRunner, + + DockerContainerRunner + + } from '@backstage/backend-common'; + - import { runDockerContainer } from '@backstage/backend-common'; + + + const containerRunner: ContainerRunner = new DockerContainerRunner({dockerClient}); + + await containerRunner.runContainer({ + - await runDockerContainer({ + image: 'docker', + // ... + - dockerClient, + }); + ``` + +### Patch Changes + +- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/integration@0.5.2 + - @backstage/config-loader@0.6.1 + - @backstage/config@0.1.5 + ## 0.6.3 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 64e3137f7c..a144f1c23f 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.6.3", + "version": "0.7.0", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -30,10 +30,10 @@ }, "dependencies": { "@backstage/cli-common": "^0.1.1", - "@backstage/config": "^0.1.4", - "@backstage/config-loader": "^0.6.0", + "@backstage/config": "^0.1.5", + "@backstage/config-loader": "^0.6.1", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.1", + "@backstage/integration": "^0.5.2", "@google-cloud/storage": "^5.8.0", "@octokit/rest": "^18.5.3", "@types/cors": "^2.8.6", @@ -73,7 +73,7 @@ } }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/test-utils": "^0.1.10", "@types/archiver": "^5.1.0", "@types/compression": "^1.7.0", diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index ee04e2bb6b..ac65632142 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,41 @@ # example-backend +## 0.2.27 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [e0bfd3d44] +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [b219821a0] +- Updated dependencies [69eefb5ae] +- Updated dependencies [f53fba29f] +- Updated dependencies [75c8cec39] +- Updated dependencies [227439a72] +- Updated dependencies [cdb3426e5] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/plugin-scaffolder-backend@0.11.0 + - @backstage/backend-common@0.7.0 + - @backstage/plugin-techdocs-backend@0.8.0 + - @backstage/plugin-catalog-backend@0.8.2 + - @backstage/plugin-kubernetes-backend@0.3.6 + - @backstage/plugin-proxy-backend@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + - example-app@0.2.27 + - @backstage/plugin-app-backend@0.3.12 + - @backstage/plugin-auth-backend@0.3.9 + - @backstage/plugin-badges-backend@0.1.3 + - @backstage/plugin-code-coverage-backend@0.1.4 + - @backstage/plugin-graphql-backend@0.1.7 + - @backstage/plugin-kafka-backend@0.2.4 + - @backstage/plugin-rollbar-backend@0.1.10 + - @backstage/plugin-search-backend@0.1.4 + - @backstage/plugin-todo-backend@0.1.4 + ## 0.2.25 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 0422088d64..6f70db7b19 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.25", + "version": "0.2.27", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -27,30 +27,30 @@ "migrate:create": "knex migrate:make -x ts" }, "dependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/catalog-client": "^0.3.9", - "@backstage/catalog-model": "^0.7.5", - "@backstage/config": "^0.1.4", - "@backstage/plugin-app-backend": "^0.3.10", - "@backstage/plugin-auth-backend": "^0.3.7", - "@backstage/plugin-badges-backend": "^0.1.1", - "@backstage/plugin-catalog-backend": "^0.8.0", - "@backstage/plugin-code-coverage-backend": "^0.1.2", - "@backstage/plugin-graphql-backend": "^0.1.6", - "@backstage/plugin-kubernetes-backend": "^0.3.5", - "@backstage/plugin-kafka-backend": "^0.2.3", - "@backstage/plugin-proxy-backend": "^0.2.6", - "@backstage/plugin-rollbar-backend": "^0.1.9", - "@backstage/plugin-scaffolder-backend": "^0.10.0", - "@backstage/plugin-search-backend": "^0.1.3", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", + "@backstage/plugin-app-backend": "^0.3.12", + "@backstage/plugin-auth-backend": "^0.3.9", + "@backstage/plugin-badges-backend": "^0.1.3", + "@backstage/plugin-catalog-backend": "^0.8.2", + "@backstage/plugin-code-coverage-backend": "^0.1.4", + "@backstage/plugin-graphql-backend": "^0.1.7", + "@backstage/plugin-kubernetes-backend": "^0.3.6", + "@backstage/plugin-kafka-backend": "^0.2.4", + "@backstage/plugin-proxy-backend": "^0.2.7", + "@backstage/plugin-rollbar-backend": "^0.1.10", + "@backstage/plugin-scaffolder-backend": "^0.11.0", + "@backstage/plugin-search-backend": "^0.1.4", "@backstage/plugin-search-backend-node": "^0.1.3", - "@backstage/plugin-techdocs-backend": "^0.7.0", - "@backstage/plugin-todo-backend": "^0.1.3", + "@backstage/plugin-techdocs-backend": "^0.8.0", + "@backstage/plugin-todo-backend": "^0.1.4", "@gitbeaker/node": "^28.0.2", "@octokit/rest": "^18.5.3", "azure-devops-node-api": "^10.1.1", "dockerode": "^3.2.1", - "example-app": "^0.2.25", + "example-app": "^0.2.27", "express": "^4.17.1", "express-promise-router": "^4.1.0", "knex": "^0.95.1", @@ -60,7 +60,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5" diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index 0076202c64..e5eb166ec2 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/catalog-client +## 0.3.11 + +### Patch Changes + +- d1b1306d9: Allow `filter` parameter to be specified multiple times +- Updated dependencies [d8b81fd28] + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.3.10 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 91845e56ab..f9638dee0d 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-client", - "version": "0.3.10", + "version": "0.3.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,13 +29,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", "cross-fetch": "^3.0.6" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.10", "@types/jest": "^26.0.7", "msw": "^0.21.2" }, diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 445da3afab..e289c5a0b3 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/catalog-model +## 0.7.8 + +### Patch Changes + +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. +- Updated dependencies [d8b81fd28] + - @backstage/config@0.1.5 + ## 0.7.7 ### Patch Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 941877aec5..ac3b046a32 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-model", - "version": "0.7.7", + "version": "0.7.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.3", + "@backstage/config": "^0.1.5", "@types/json-schema": "^7.0.5", "@types/yup": "^0.29.8", "ajv": "^7.0.3", @@ -39,7 +39,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.10", "@types/express": "^4.17.6", "@types/jest": "^26.0.7", "@types/lodash": "^4.14.151", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index af452b3c9d..996513f60e 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/cli +## 0.6.10 + +### Patch Changes + +- f65adcde7: Fix some transitive dependency warnings in yarn +- fc79a6dd3: Added lax option to backstage-cli app:build command +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. +- Updated dependencies [d8b81fd28] + - @backstage/config-loader@0.6.1 + - @backstage/config@0.1.5 + ## 0.6.9 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 46e99b762b..4bed089b98 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.6.9", + "version": "0.6.10", "private": false, "publishConfig": { "access": "public" @@ -31,8 +31,8 @@ "@babel/core": "^7.4.4", "@babel/plugin-transform-modules-commonjs": "^7.4.4", "@backstage/cli-common": "^0.1.1", - "@backstage/config": "^0.1.4", - "@backstage/config-loader": "^0.6.0", + "@backstage/config": "^0.1.5", + "@backstage/config-loader": "^0.6.1", "@hot-loader/react-dom": "^16.13.0", "@lerna/package-graph": "^4.0.0", "@lerna/project": "^4.0.0", @@ -117,12 +117,12 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.6", + "@backstage/backend-common": "^0.7.0", + "@backstage/config": "^0.1.5", + "@backstage/core": "^0.7.8", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@types/diff": "^5.0.0", "@types/express": "^4.17.6", "@types/fs-extra": "^9.0.1", diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index cb8ef123ce..d6b1c9a751 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/config-loader +## 0.6.1 + +### Patch Changes + +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. +- Updated dependencies [d8b81fd28] + - @backstage/config@0.1.5 + ## 0.6.0 ### Minor Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 55d86314af..16d7923d0b 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "0.6.0", + "version": "0.6.1", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ }, "dependencies": { "@backstage/cli-common": "^0.1.1", - "@backstage/config": "^0.1.1", + "@backstage/config": "^0.1.5", "@types/json-schema": "^7.0.6", "ajv": "^7.0.3", "fs-extra": "^9.0.0", diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index c190207547..5cababf94e 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/config +## 0.1.5 + +### Patch Changes + +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. + ## 0.1.4 ### Patch Changes diff --git a/packages/config/package.json b/packages/config/package.json index 8f08a5dcfc..400e4548cd 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config", "description": "Config API used by Backstage core, backend, and CLI", - "version": "0.1.4", + "version": "0.1.5", "private": false, "publishConfig": { "access": "public", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 974dcd3b91..a215c7cb8e 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core +## 0.7.8 + +### Patch Changes + +- f65adcde7: Fix some transitive dependency warnings in yarn +- 80888659b: Bump react-hook-form version to be the same for the entire project. +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/theme@0.2.7 + - @backstage/config@0.1.5 + ## 0.7.7 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 21303d52fc..4da981d064 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core", "description": "Core API used by Backstage plugins and apps", - "version": "0.7.7", + "version": "0.7.8", "private": false, "publishConfig": { "access": "public", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.4", + "@backstage/config": "^0.1.5", "@backstage/core-api": "^0.2.17", "@backstage/errors": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -70,7 +70,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 430e7f003a..50b73983fa 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,162 @@ # @backstage/create-app +## 1.0.0 + +### Patch Changes + +- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. +- e0bfd3d44: The `scaffolder-backend` and `techdocs-backend` plugins have been updated. + In order to update, you need to apply the following changes to your existing backend application: + + `@backstage/plugin-techdocs-backend`: + + ```diff + // packages/backend/src/plugin/techdocs.ts + + + import { DockerContainerRunner } from '@backstage/backend-common'; + + // ... + + export default async function createPlugin({ + logger, + config, + discovery, + reader, + }: PluginEnvironment): Promise<Router> { + // Preparers are responsible for fetching source files for documentation. + const preparers = await Preparers.fromConfig(config, { + logger, + reader, + }); + + + // Docker client (conditionally) used by the generators, based on techdocs.generators config. + + const dockerClient = new Docker(); + + const containerRunner = new DockerContainerRunner({ dockerClient }); + + // Generators are used for generating documentation sites. + const generators = await Generators.fromConfig(config, { + logger, + + containerRunner, + }); + + // Publisher is used for + // 1. Publishing generated files to storage + // 2. Fetching files from storage and passing them to TechDocs frontend. + const publisher = await Publisher.fromConfig(config, { + logger, + discovery, + }); + + // checks if the publisher is working and logs the result + await publisher.getReadiness(); + + - // Docker client (conditionally) used by the generators, based on techdocs.generators config. + - const dockerClient = new Docker(); + + return await createRouter({ + preparers, + generators, + publisher, + - dockerClient, + logger, + config, + discovery, + }); + } + ``` + + `@backstage/plugin-scaffolder-backend`: + + ```diff + // packages/backend/src/plugin/scaffolder.ts + + - import { SingleHostDiscovery } from '@backstage/backend-common'; + + import { + + DockerContainerRunner, + + SingleHostDiscovery, + + } from '@backstage/backend-common'; + + + export default async function createPlugin({ + logger, + config, + database, + reader, + }: PluginEnvironment): Promise<Router> { + + const dockerClient = new Docker(); + + const containerRunner = new DockerContainerRunner({ dockerClient }); + + + const cookiecutterTemplater = new CookieCutter({ containerRunner }); + - const cookiecutterTemplater = new CookieCutter(); + + const craTemplater = new CreateReactAppTemplater({ containerRunner }); + - const craTemplater = new CreateReactAppTemplater(); + const templaters = new Templaters(); + + templaters.register('cookiecutter', cookiecutterTemplater); + templaters.register('cra', craTemplater); + + const preparers = await Preparers.fromConfig(config, { logger }); + const publishers = await Publishers.fromConfig(config, { logger }); + + - const dockerClient = new Docker(); + + const discovery = SingleHostDiscovery.fromConfig(config); + const catalogClient = new CatalogClient({ discoveryApi: discovery }); + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, + - dockerClient, + database, + catalogClient, + reader, + }); + } + ``` + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [e0bfd3d44] +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [80888659b] +- Updated dependencies [b219821a0] +- Updated dependencies [7b8272fb7] +- Updated dependencies [8aedbb4af] +- Updated dependencies [fc79a6dd3] +- Updated dependencies [69eefb5ae] +- Updated dependencies [75c8cec39] +- Updated dependencies [b2e2ec753] +- Updated dependencies [227439a72] +- Updated dependencies [9314a8592] +- Updated dependencies [2e05277e0] +- Updated dependencies [4075c6367] +- Updated dependencies [cdb3426e5] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/plugin-scaffolder-backend@0.11.0 + - @backstage/backend-common@0.7.0 + - @backstage/plugin-techdocs-backend@0.8.0 + - @backstage/plugin-catalog-import@0.5.5 + - @backstage/plugin-github-actions@0.4.5 + - @backstage/cli@0.6.10 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-backend@0.8.2 + - @backstage/theme@0.2.7 + - @backstage/plugin-tech-radar@0.3.10 + - @backstage/plugin-scaffolder@0.9.3 + - @backstage/plugin-techdocs@0.9.1 + - @backstage/plugin-proxy-backend@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + - @backstage/plugin-app-backend@0.3.12 + - @backstage/plugin-auth-backend@0.3.9 + - @backstage/plugin-rollbar-backend@0.1.10 + ## 0.3.20 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 071a0a5ebd..2b30eafa2b 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "0.3.20", + "version": "1.0.0", "private": false, "publishConfig": { "access": "public" diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index 6c65643409..d892523d25 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/integration +## 0.5.2 + +### Patch Changes + +- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. +- Updated dependencies [d8b81fd28] + - @backstage/config@0.1.5 + ## 0.5.1 ### Patch Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index b7c8bee957..441b42e584 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration", - "version": "0.5.1", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", + "@backstage/config": "^0.1.5", "cross-fetch": "^3.0.6", "git-url-parse": "^11.4.4", "@octokit/rest": "^18.5.3", @@ -37,8 +37,8 @@ "luxon": "^1.25.0" }, "devDependencies": { - "@backstage/cli": "^0.6.7", - "@backstage/config-loader": "^0.6.0", + "@backstage/cli": "^0.6.10", + "@backstage/config-loader": "^0.6.1", "@backstage/test-utils": "^0.1.10", "@types/jest": "^26.0.7", "@types/luxon": "^1.25.0", diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md index 1788502e45..644a3ebb5f 100644 --- a/packages/techdocs-common/CHANGELOG.md +++ b/packages/techdocs-common/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/techdocs-common +## 0.6.0 + +### Minor Changes + +- e0bfd3d44: Migrate the package to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. + It also no longer provides the `ContainerRunner` as an input to the `GeneratorBase#run(…)` function, but expects it as a constructor parameter instead. + + If you use the `TechdocsGenerator` you need to update the usage: + + ```diff + + const containerRunner = new DockerContainerRunner({ dockerClient }); + + - const generator = new TechdocsGenerator(logger, config); + + const techdocsGenerator = new TechdocsGenerator({ + + logger, + + containerRunner, + + config, + + }); + + await this.generator.run({ + inputDir: preparedDir, + outputDir, + - dockerClient: this.dockerClient, + parsedLocationAnnotation, + etag: newEtag, + }); + ``` + +### Patch Changes + +- e9e56b01a: Adding optional config to enable S3-like API for tech-docs using s3ForcePathStyle option. + This allows providers like LocalStack, Minio and Wasabi (+possibly others) to be used to host tech docs. +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/integration@0.5.2 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.5.1 ### Patch Changes diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index 1ac46163af..f2d19ba8c5 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/techdocs-common", "description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "0.5.1", + "version": "0.6.0", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -38,11 +38,11 @@ "dependencies": { "@azure/identity": "^1.2.2", "@azure/storage-blob": "^12.4.0", - "@backstage/backend-common": "^0.6.0", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.1", + "@backstage/integration": "^0.5.2", "@google-cloud/storage": "^5.6.0", "@types/express": "^4.17.6", "aws-sdk": "^2.840.0", @@ -60,7 +60,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.10", "@types/fs-extra": "^9.0.5", "@types/git-url-parse": "^9.0.0", "@types/js-yaml": "^4.0.0", diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index 22964d6b25..e70364016d 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/theme +## 0.2.7 + +### Patch Changes + +- 7b8272fb7: Remove extra bottom padding in InfoCard content + ## 0.2.6 ### Patch Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index 87821b6751..f93c793ff8 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.2.6", + "version": "0.2.7", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ "@material-ui/core": "^4.11.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9" + "@backstage/cli": "^0.6.10" }, "files": [ "dist" diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 5c9f9ca7ee..e8e8bb8774 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -31,9 +31,9 @@ "dependencies": { "@asyncapi/react-component": "^0.23.0", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-icons/font": "^1.0.2", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -49,7 +49,7 @@ "swagger-ui-react": "^3.37.2" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 85fab4455d..73fa9fc3b1 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-app-backend +## 0.3.12 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/config-loader@0.6.1 + - @backstage/config@0.1.5 + ## 0.3.11 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index c6a1dd5a6b..84fe743550 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.11", + "version": "0.3.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.2", - "@backstage/config-loader": "^0.6.0", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/config-loader": "^0.6.1", + "@backstage/config": "^0.1.5", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -40,7 +40,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.7", + "@backstage/cli": "^0.6.10", "@types/supertest": "^2.0.8", "msw": "^0.20.5", "supertest": "^6.1.3" diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 47616b68c7..e51942f742 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-auth-backend +## 0.3.9 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/backend-common@0.7.0 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + ## 0.3.8 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 4af8a1736d..41a47c7788 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.3.8", + "version": "0.3.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.2", - "@backstage/catalog-client": "^0.3.9", - "@backstage/catalog-model": "^0.7.6", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", "@backstage/test-utils": "^0.1.10", "@types/express": "^4.17.6", @@ -68,7 +68,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.7", + "@backstage/cli": "^0.6.10", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index 69785a645f..abbc4e70bd 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-badges-backend +## 0.1.3 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/backend-common@0.7.0 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + ## 0.1.2 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index eb2a93fe67..347f8b9219 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-badges-backend", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,10 +30,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.2", - "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.6", - "@backstage/config": "^0.1.3", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", "@types/express": "^4.17.6", "badge-maker": "^3.3.0", @@ -45,7 +45,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.7", + "@backstage/cli": "^0.6.10", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 8f7b5865a1..7078b9627e 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -21,10 +21,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,7 +34,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 950392f732..cd0564dc41 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.2", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -37,7 +37,7 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index ed87e4dbc5..8d40d7c4bb 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend +## 0.8.2 + +### Patch Changes + +- b219821a0: Expose `BitbucketRepositoryParser` introduced in [#5295](https://github.com/backstage/backstage/pull/5295) +- 227439a72: Add support for non-organization accounts in GitHub Discovery +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/integration@0.5.2 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.8.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 99df0acd09..c8e17bb943 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "0.8.1", + "version": "0.8.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,11 +30,11 @@ }, "dependencies": { "@azure/msal-node": "^1.0.0-beta.3", - "@backstage/backend-common": "^0.6.3", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.1", + "@backstage/integration": "^0.5.2", "@backstage/plugin-search-backend-node": "^0.1.4", "@backstage/search-common": "^0.1.1", "@octokit/graphql": "^4.5.8", @@ -63,7 +63,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/test-utils": "^0.1.9", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", diff --git a/plugins/catalog-graphql/CHANGELOG.md b/plugins/catalog-graphql/CHANGELOG.md index 899bf8a406..8140724840 100644 --- a/plugins/catalog-graphql/CHANGELOG.md +++ b/plugins/catalog-graphql/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-graphql +## 0.2.8 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.2.7 ### Patch Changes diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index 3ab6d64dc8..969d4b7df4 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graphql", - "version": "0.2.7", + "version": "0.2.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.0", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@graphql-modules/core": "^0.7.17", "apollo-server": "^2.16.1", "cross-fetch": "^3.0.6", @@ -42,7 +42,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.5", + "@backstage/cli": "^0.6.10", "@backstage/test-utils": "^0.1.9", "@graphql-codegen/cli": "^1.21.3", "@graphql-codegen/typescript": "^1.17.7", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 4b0d264a52..59baabfbc8 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog-import +## 0.5.5 + +### Patch Changes + +- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. +- 80888659b: Bump react-hook-form version to be the same for the entire project. +- 8aedbb4af: Fixes a typo and minor wording changes to the catalog import UI +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/integration@0.5.2 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/catalog-client@0.3.11 + ## 0.5.4 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index ccc2dd24a7..2277604dc2 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.5.4", + "version": "0.5.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,13 +30,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.6", - "@backstage/catalog-client": "^0.3.9", - "@backstage/core": "^0.7.7", - "@backstage/integration": "^0.5.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/catalog-client": "^0.3.11", + "@backstage/core": "^0.7.8", + "@backstage/integration": "^0.5.2", "@backstage/integration-react": "^0.1.1", - "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/plugin-catalog-react": "^0.1.5", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -53,7 +53,7 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 122647a67f..e5a857eca0 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-react +## 0.1.5 + +### Patch Changes + +- 81c54d1f2: Fetch relations in batches in `useRelatedEntities` +- Updated dependencies [f65adcde7] +- Updated dependencies [80888659b] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/core@0.7.8 + - @backstage/catalog-model@0.7.8 + - @backstage/catalog-client@0.3.11 + ## 0.1.4 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 57a9479a3c..1d886478b8 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "0.1.4", + "version": "0.1.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,9 +28,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.3.9", - "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.3", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/core": "^0.7.8", "@material-ui/core": "^4.11.0", "@types/react": "^16.9", "lodash": "^4.17.15", @@ -40,7 +40,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.6", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.9", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 4f54735611..8277c2dcbc 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -32,12 +32,12 @@ "dependencies": { "@backstage/catalog-client": "^0.3.10", "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/errors": "^0.1.1", "@backstage/integration": "^0.5.1", "@backstage/integration-react": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -52,7 +52,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@microsoft/microsoft-graph-types": "^1.25.0", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 20c757eda0..b87fb4bbbf 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -50,7 +50,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index cb2a08fce1..98735f1c42 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -32,8 +32,8 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index d7a0f136f5..18e78c7454 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-code-coverage-backend +## 0.1.4 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/backend-common@0.7.0 + - @backstage/integration@0.5.2 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + ## 0.1.3 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index c2bebbf293..db53096932 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-coverage-backend", - "version": "0.1.3", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,12 +19,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/catalog-client": "^0.3.10", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.1", + "@backstage/integration": "^0.5.2", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "express": "^4.17.1", @@ -36,7 +36,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", "msw": "^0.21.2", diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index f5c36811cc..241b61b296 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -22,10 +22,10 @@ "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/styles": "^4.11.0", @@ -39,7 +39,7 @@ "recharts": "^1.8.5" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index a017529400..7877668065 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/errors": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,7 +34,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index c86a71f8c9..e6a351f2a4 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-cost-insights +## 0.9.0 + +### Minor Changes + +- 6f1b82b14: make change ratio optional + +### Patch Changes + +- Updated dependencies [f65adcde7] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/core@0.7.8 + - @backstage/theme@0.2.7 + - @backstage/config@0.1.5 + ## 0.8.5 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 39e3fe1791..5d780080d1 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-cost-insights", - "version": "0.8.5", + "version": "0.9.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.3", - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/config": "^0.1.5", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -55,7 +55,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/explore/package.json b/plugins/explore/package.json index be61bc1fd9..35a4a97349 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -31,10 +31,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.4", "@backstage/plugin-explore-react": "^0.0.4", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -45,7 +45,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index ba7e1a381e..ee35b94c0b 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -32,10 +32,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 0930c791e4..96102332d9 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 6896a7f877..aa2fec5512 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-github-actions +## 0.4.5 + +### Patch Changes + +- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/integration@0.5.2 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + ## 0.4.4 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 89b569bd95..61de1a1f7d 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-actions", - "version": "0.4.4", + "version": "0.4.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,11 +32,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.5", - "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/core": "^0.7.7", - "@backstage/integration": "^0.5.1", - "@backstage/theme": "^0.2.6", + "@backstage/catalog-model": "^0.7.8", + "@backstage/plugin-catalog-react": "^0.1.5", + "@backstage/core": "^0.7.8", + "@backstage/integration": "^0.5.2", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -50,7 +50,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 049e02de4c..e67df926ea 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -34,7 +34,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index d1897b018c..866ee571c0 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -42,7 +42,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 9ce1603b57..d03a5f39e9 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -43,7 +43,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/graphql/CHANGELOG.md b/plugins/graphql/CHANGELOG.md index dfcddfbcf9..fc31d831dc 100644 --- a/plugins/graphql/CHANGELOG.md +++ b/plugins/graphql/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-graphql-backend +## 0.1.7 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/config@0.1.5 + - @backstage/plugin-catalog-graphql@0.2.8 + ## 0.1.6 ### Patch Changes diff --git a/plugins/graphql/package.json b/plugins/graphql/package.json index b5046e13fc..0df78298d7 100644 --- a/plugins/graphql/package.json +++ b/plugins/graphql/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-graphql-backend", - "version": "0.1.6", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.0", - "@backstage/config": "^0.1.4", - "@backstage/plugin-catalog-graphql": "^0.2.7", + "@backstage/backend-common": "^0.7.0", + "@backstage/config": "^0.1.5", + "@backstage/plugin-catalog-graphql": "^0.2.8", "@graphql-modules/core": "^0.7.17", "@types/express": "^4.17.6", "apollo-server": "^2.16.1", @@ -45,7 +45,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.5", + "@backstage/cli": "^0.6.10", "@types/supertest": "^2.0.8", "eslint-plugin-graphql": "^4.0.0", "msw": "^0.20.5", diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index d1cabd2143..45bd3c4bf8 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index f29fb62a91..ef006a360f 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kafka-backend +## 0.2.4 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.2.3 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index ef64ebfbf5..3e3f22654a 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kafka-backend", - "version": "0.2.3", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.1", - "@backstage/catalog-model": "^0.7.5", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -42,7 +42,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.5", + "@backstage/cli": "^0.6.10", "@types/jest-when": "^2.7.2", "@types/lodash": "^4.14.151", "jest-when": "^3.1.0", diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 0963d3178f..ce3e7561b1 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -21,9 +21,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.4", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -33,7 +33,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 8bcac8a60b..a9893925e2 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-backend +## 0.3.6 + +### Patch Changes + +- f53fba29f: Adds @backstage/plugin-kubernetes-common library to share types between kubernetes frontend and backend. +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.3.5 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 3c8380b661..f73166d5fc 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.3.5", + "version": "0.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/plugin-kubernetes-common": "^0.1.0", "@google-cloud/container": "^2.2.0", "@kubernetes/client-node": "^0.14.0", @@ -53,7 +53,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@types/aws4": "^1.5.1", "supertest": "^6.1.3" }, diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 13f1a03d8e..d78842f351 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-kubernetes +## 0.4.3 + +### Patch Changes + +- f53fba29f: Adds @backstage/plugin-kubernetes-common library to share types between kubernetes frontend and backend. +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.4.2 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 331e121d6c..8028c3a339 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.4.2", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,12 +30,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.4", - "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.7", - "@backstage/plugin-catalog-react": "^0.1.3", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", + "@backstage/core": "^0.7.8", + "@backstage/plugin-catalog-react": "^0.1.5", "@backstage/plugin-kubernetes-common": "^0.1.0", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@kubernetes/client-node": "^0.14.0", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -49,7 +49,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 2fce507756..a6ae0102bf 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -33,9 +33,9 @@ "dependencies": { "@backstage/catalog-model": "^0.7.3", "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.2", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -46,7 +46,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 2dbb2a7eb8..dfe5217f9d 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/org/package.json b/plugins/org/package.json index 9ad4704630..2b802510f4 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -21,10 +21,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.6", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/core-api": "^0.2.16", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -35,7 +35,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 821b89a5b1..0005b9aa3b 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -46,7 +46,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 0fada2e81f..06a96576e6 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-proxy-backend +## 0.2.7 + +### Patch Changes + +- cdb3426e5: Prefix proxy routes with `/` if not present in configuration +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/config@0.1.5 + ## 0.2.6 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 39a6e128bd..2c6fc9e08d 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.2.6", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,8 +28,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.0", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/config": "^0.1.5", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -42,7 +42,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.5", + "@backstage/cli": "^0.6.10", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index bd51a7db0b..5052fd3342 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.5", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -45,7 +45,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index 8e20e93555..9aa0d77e69 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-rollbar-backend +## 0.1.10 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] + - @backstage/backend-common@0.7.0 + - @backstage/config@0.1.5 + ## 0.1.9 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 05b02b2c39..c7eb819dc1 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-rollbar-backend", - "version": "0.1.9", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/config": "^0.1.5", "@types/express": "^4.17.6", "axios": "^0.21.1", "camelcase-keys": "^6.2.2", @@ -47,7 +47,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 64ea010b54..5563ad0e40 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index f591568d44..b4aa856606 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,78 @@ # @backstage/plugin-scaffolder-backend +## 0.11.0 + +### Minor Changes + +- e0bfd3d44: Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. + It also provides the `ContainerRunner` to the individual templaters instead of to the `createRouter` function. + + To apply this change to an existing backend application, add the following to `src/plugins/scaffolder.ts`: + + ```diff + - import { SingleHostDiscovery } from '@backstage/backend-common'; + + import { + + DockerContainerRunner, + + SingleHostDiscovery, + + } from '@backstage/backend-common'; + + + export default async function createPlugin({ + logger, + config, + database, + reader, + }: PluginEnvironment): Promise<Router> { + + const dockerClient = new Docker(); + + const containerRunner = new DockerContainerRunner({ dockerClient }); + + + const cookiecutterTemplater = new CookieCutter({ containerRunner }); + - const cookiecutterTemplater = new CookieCutter(); + + const craTemplater = new CreateReactAppTemplater({ containerRunner }); + - const craTemplater = new CreateReactAppTemplater(); + const templaters = new Templaters(); + + templaters.register('cookiecutter', cookiecutterTemplater); + templaters.register('cra', craTemplater); + + const preparers = await Preparers.fromConfig(config, { logger }); + const publishers = await Publishers.fromConfig(config, { logger }); + + - const dockerClient = new Docker(); + + const discovery = SingleHostDiscovery.fromConfig(config); + const catalogClient = new CatalogClient({ discoveryApi: discovery }); + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, + - dockerClient, + database, + catalogClient, + reader, + }); + } + ``` + +### Patch Changes + +- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. +- 69eefb5ae: Fix GithubPR built-in action `credentialsProvider.getCredentials` URL. + Adding Documentation for GitHub PR built-in action. +- 75c8cec39: bump `jsonschema` from 1.2.7 to 1.4.0 +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/backend-common@0.7.0 + - @backstage/integration@0.5.2 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + ## 0.10.1 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 61dc4e2cbf..9cd951f7d8 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "0.10.1", + "version": "0.11.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,12 +29,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/catalog-client": "^0.3.10", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.1", + "@backstage/integration": "^0.5.2", "@gitbeaker/core": "^28.0.2", "@gitbeaker/node": "^28.0.2", "@octokit/rest": "^18.5.3", @@ -65,7 +65,7 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/test-utils": "^0.1.10", "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 1d0bbcede9..b67740ecc1 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-scaffolder +## 0.9.3 + +### Patch Changes + +- 9314a8592: Close eventSource upon completion of a scaffolder task +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/integration@0.5.2 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + ## 0.9.2 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 32229ccbc6..f2f69c029b 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "0.9.2", + "version": "0.9.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,14 +30,14 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.3.10", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", - "@backstage/core": "^0.7.7", - "@backstage/integration": "^0.5.1", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", + "@backstage/core": "^0.7.8", + "@backstage/integration": "^0.5.2", "@backstage/integration-react": "^0.1.1", - "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/plugin-catalog-react": "^0.1.5", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -59,7 +59,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index e39fbb5579..99077b9b62 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -25,8 +25,8 @@ "@types/lunr": "^2.3.3" }, "devDependencies": { - "@backstage/backend-common": "^0.6.3", - "@backstage/cli": "^0.6.9" + "@backstage/backend-common": "^0.7.0", + "@backstage/cli": "^0.6.10" }, "files": [ "dist" diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 9313e2e83a..fd429aae62 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-backend +## 0.1.4 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] + - @backstage/backend-common@0.7.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index a94fed35b9..4de8ada9bc 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "0.1.3", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,7 +19,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.3", + "@backstage/backend-common": "^0.7.0", "@backstage/search-common": "^0.1.1", "@backstage/plugin-search-backend-node": "^0.1.3", "@types/express": "^4.17.6", @@ -29,7 +29,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/search/package.json b/plugins/search/package.json index 2b9db3444e..b135d184f6 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -29,11 +29,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/catalog-model": "^0.7.3", "@backstage/plugin-catalog-react": "^0.1.2", "@backstage/search-common": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -44,7 +44,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index e34d8bcef9..a5b1ac7d68 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -46,7 +46,7 @@ "timeago.js": "^4.0.2" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index c31b99bac8..648f945e03 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -34,8 +34,8 @@ "dependencies": { "@backstage/catalog-model": "^0.7.7", "@backstage/plugin-catalog-react": "^0.1.3", - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -47,7 +47,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 9e93004bf5..63fb68c0b2 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.4", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -45,7 +45,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 54cefe487f..9f0a5b87c3 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-radar +## 0.3.10 + +### Patch Changes + +- b2e2ec753: Update README for composability +- Updated dependencies [f65adcde7] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] + - @backstage/core@0.7.8 + - @backstage/theme@0.2.7 + ## 0.3.9 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 37ad7d8211..2a2619bbc4 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-radar", - "version": "0.3.9", + "version": "0.3.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,8 +30,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -43,7 +43,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 2923e452a7..59a116f653 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,79 @@ # @backstage/plugin-techdocs-backend +## 0.8.0 + +### Minor Changes + +- e0bfd3d44: Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`. + It also provides the `ContainerRunner` to the generators instead of to the `createRouter` function. + + To apply this change to an existing backend application, add the following to `src/plugins/techdocs.ts`: + + ```diff + + import { DockerContainerRunner } from '@backstage/backend-common'; + + // ... + + export default async function createPlugin({ + logger, + config, + discovery, + reader, + }: PluginEnvironment): Promise<Router> { + // Preparers are responsible for fetching source files for documentation. + const preparers = await Preparers.fromConfig(config, { + logger, + reader, + }); + + + // Docker client (conditionally) used by the generators, based on techdocs.generators config. + + const dockerClient = new Docker(); + + const containerRunner = new DockerContainerRunner({ dockerClient }); + + // Generators are used for generating documentation sites. + const generators = await Generators.fromConfig(config, { + logger, + + containerRunner, + }); + + // Publisher is used for + // 1. Publishing generated files to storage + // 2. Fetching files from storage and passing them to TechDocs frontend. + const publisher = await Publisher.fromConfig(config, { + logger, + discovery, + }); + + // checks if the publisher is working and logs the result + await publisher.getReadiness(); + + - // Docker client (conditionally) used by the generators, based on techdocs.generators config. + - const dockerClient = new Docker(); + + return await createRouter({ + preparers, + generators, + publisher, + - dockerClient, + logger, + config, + discovery, + }); + } + ``` + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [e0bfd3d44] +- Updated dependencies [d8b81fd28] +- Updated dependencies [e9e56b01a] + - @backstage/backend-common@0.7.0 + - @backstage/techdocs-common@0.6.0 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.7.1 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 03d8e9e2ab..1424381f30 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "0.7.1", + "version": "0.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,11 +30,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.0", - "@backstage/catalog-model": "^0.7.7", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", - "@backstage/techdocs-common": "^0.5.0", + "@backstage/techdocs-common": "^0.6.0", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "dockerode": "^3.2.1", @@ -45,7 +45,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.8", + "@backstage/cli": "^0.6.10", "@types/dockerode": "^3.2.1", "supertest": "^6.1.3" }, diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 847121c0cf..69e988a433 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-techdocs +## 0.9.1 + +### Patch Changes + +- 2e05277e0: Fix navigation in a page using the table of contents. +- 4075c6367: Make git config optional for techdocs feedback links +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/integration@0.5.2 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + ## 0.9.0 ### Minor Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 55e5dadb54..380eae2737 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "0.9.0", + "version": "0.9.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,13 +31,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.4", - "@backstage/catalog-model": "^0.7.7", - "@backstage/core": "^0.7.7", - "@backstage/integration": "^0.5.0", + "@backstage/config": "^0.1.5", + "@backstage/catalog-model": "^0.7.8", + "@backstage/core": "^0.7.8", + "@backstage/integration": "^0.5.2", "@backstage/integration-react": "^0.1.1", - "@backstage/plugin-catalog-react": "^0.1.4", - "@backstage/theme": "^0.2.6", + "@backstage/plugin-catalog-react": "^0.1.5", + "@backstage/theme": "^0.2.7", "@backstage/errors": "^0.1.1", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -51,7 +51,7 @@ "sanitize-html": "^2.3.2" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index 8468bcd500..b42f631a98 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-todo-backend +## 0.1.4 + +### Patch Changes + +- Updated dependencies [e0bfd3d44] +- Updated dependencies [38ca05168] +- Updated dependencies [d8b81fd28] +- Updated dependencies [d1b1306d9] + - @backstage/backend-common@0.7.0 + - @backstage/integration@0.5.2 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + - @backstage/catalog-client@0.3.11 + ## 0.1.3 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 2f7348e054..1af9f9b40c 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-todo-backend", - "version": "0.1.3", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,12 +24,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.6.1", - "@backstage/catalog-client": "^0.3.9", - "@backstage/catalog-model": "^0.7.5", - "@backstage/config": "^0.1.4", + "@backstage/backend-common": "^0.7.0", + "@backstage/catalog-client": "^0.3.11", + "@backstage/catalog-model": "^0.7.8", + "@backstage/config": "^0.1.5", "@backstage/errors": "^0.1.1", - "@backstage/integration": "^0.5.0", + "@backstage/integration": "^0.5.2", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "express": "^4.17.1", @@ -39,7 +39,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.6", + "@backstage/cli": "^0.6.10", "@types/supertest": "^2.0.8", "msw": "^0.21.2", "supertest": "^6.1.3" diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 92390857ef..aac15e9ad6 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -27,10 +27,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.7.3", - "@backstage/core": "^0.7.7", + "@backstage/core": "^0.7.8", "@backstage/errors": "^0.1.1", "@backstage/plugin-catalog-react": "^0.1.1", - "@backstage/theme": "^0.2.6", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -39,7 +39,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 08ae87d3ec..3349319442 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index 189b6eeb59..90cdb3dc0f 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -30,8 +30,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.7.7", - "@backstage/theme": "^0.2.6", + "@backstage/core": "^0.7.8", + "@backstage/theme": "^0.2.7", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -41,7 +41,7 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.9", + "@backstage/cli": "^0.6.10", "@backstage/dev-utils": "^0.1.13", "@backstage/test-utils": "^0.1.10", "@testing-library/jest-dom": "^5.10.1", From 3aec82a61d77e00a180d77b7ff8103801b1f06f0 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 6 May 2021 10:14:18 +0200 Subject: [PATCH 445/462] chore: fix create-app version to Patch Signed-off-by: blam <ben@blam.sh> --- packages/create-app/CHANGELOG.md | 2 +- packages/create-app/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 50b73983fa..968c798625 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,6 +1,6 @@ # @backstage/create-app -## 1.0.0 +## 0.3.21 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 2b30eafa2b..169e9a8637 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "1.0.0", + "version": "0.3.21", "private": false, "publishConfig": { "access": "public" From a3b102c827cd7f34525f8f3bfc7004959b4167be Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Wed, 5 May 2021 17:20:03 +0200 Subject: [PATCH 446/462] Use `useSearchParams` in `useQueryParamState` Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- packages/core/src/hooks/useQueryParamState.ts | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/packages/core/src/hooks/useQueryParamState.ts b/packages/core/src/hooks/useQueryParamState.ts index 0a61771eba..023d69bf4f 100644 --- a/packages/core/src/hooks/useQueryParamState.ts +++ b/packages/core/src/hooks/useQueryParamState.ts @@ -17,7 +17,7 @@ import { isEqual } from 'lodash'; import qs from 'qs'; import { useEffect, useState } from 'react'; -import { useLocation } from 'react-router-dom'; +import { useSearchParams } from 'react-router-dom'; import { useDebounce } from 'react-use'; function stringify(queryParams: any): string { @@ -59,39 +59,34 @@ type SetQueryParams<T> = (params: T) => void; export function useQueryParamState<T>( stateName: string, ): [T | undefined, SetQueryParams<T>] { - const location = useLocation(); + const [searchParams, setSearchParams] = useSearchParams(); + const searchParamsString = searchParams.toString(); const [queryParamState, setQueryParamState] = useState<T>( - extractState(location.search, stateName), + extractState(searchParamsString, stateName), ); useEffect(() => { - const newState = extractState(location.search, stateName); + const newState = extractState(searchParamsString, stateName); setQueryParamState(oldState => isEqual(newState, oldState) ? oldState : newState, ); - }, [location, stateName]); + }, [searchParamsString, setQueryParamState, stateName]); useDebounce( () => { const queryString = joinQueryString( - location.search, + searchParamsString, stateName, queryParamState, ); - if (location.search !== queryString) { - // We fallback to the history API, as navigate from react-router causes - // input elements to loose focus. - history.replaceState( - undefined, - document.title, - `${location.pathname}?${queryString}`, - ); + if (searchParamsString !== queryString) { + setSearchParams(queryString, { replace: true }); } }, 100, - [queryParamState], + [setSearchParams, queryParamState, searchParamsString, stateName], ); return [queryParamState, setQueryParamState]; From 42e133b6de6451c7819096c34c72319c7826382d Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 6 May 2021 10:55:48 +0200 Subject: [PATCH 447/462] Fix table toolbar rerendering to often and losing focus Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/short-bobcats-mate.md | 3 +- packages/core/src/components/Table/Table.tsx | 136 +++++++++++-------- 2 files changed, 81 insertions(+), 58 deletions(-) diff --git a/.changeset/short-bobcats-mate.md b/.changeset/short-bobcats-mate.md index 22aaf11d77..d63e7058a9 100644 --- a/.changeset/short-bobcats-mate.md +++ b/.changeset/short-bobcats-mate.md @@ -3,4 +3,5 @@ '@backstage/plugin-api-docs': patch --- -Fix setting the state with `useQueryParamState` makes inputs lose their focus. +Fix state persisted in the URL make search input in the table toolbar lose their +focus. diff --git a/packages/core/src/components/Table/Table.tsx b/packages/core/src/components/Table/Table.tsx index 2251b8304e..1dd09e7ab8 100644 --- a/packages/core/src/components/Table/Table.tsx +++ b/packages/core/src/components/Table/Table.tsx @@ -20,6 +20,7 @@ import { makeStyles, Typography, useTheme, + withStyles, } from '@material-ui/core'; // Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51 import AddBox from '@material-ui/icons/AddBox'; @@ -49,6 +50,7 @@ import MTable, { } from 'material-table'; import React, { forwardRef, + MutableRefObject, ReactNode, useCallback, useEffect, @@ -100,19 +102,20 @@ function extractValueByField(data: any, field: string): any | undefined { return value; } -const useHeaderStyles = makeStyles<BackstageTheme>(theme => ({ +const StyledMTableHeader = withStyles(theme => ({ header: { padding: theme.spacing(1, 2, 1, 2.5), borderTop: `1px solid ${theme.palette.grey.A100}`, borderBottom: `1px solid ${theme.palette.grey.A100}`, - color: theme.palette.textSubtle, + // withStyles hasn't a generic overload for theme + color: (theme as BackstageTheme).palette.textSubtle, fontWeight: theme.typography.fontWeightBold, position: 'static', wordBreak: 'normal', }, -})); +}))(MTableHeader); -const useToolbarStyles = makeStyles<BackstageTheme>(theme => ({ +const StyledMTableToolbar = withStyles(theme => ({ root: { padding: theme.spacing(3, 0, 2.5, 2.5), }, @@ -124,7 +127,7 @@ const useToolbarStyles = makeStyles<BackstageTheme>(theme => ({ searchField: { paddingRight: theme.spacing(2), }, -})); +}))(MTableToolbar); const useFilterStyles = makeStyles<BackstageTheme>(() => ({ root: { @@ -208,6 +211,59 @@ export interface TableProps<T extends object = {}> onStateChange?: (state: TableState) => any; } +export function TableToolbar(toolbarProps: { + toolbarRef: MutableRefObject<any>; + setSearch: (value: string) => void; + onSearchChanged: (value: string) => void; + toggleFilters: () => void; + hasFilters: boolean; + selectedFiltersLength: number; +}) { + const { + toolbarRef, + setSearch, + hasFilters, + selectedFiltersLength, + toggleFilters, + } = toolbarProps; + const filtersClasses = useFilterStyles(); + const onSearchChanged = useCallback( + (searchText: string) => { + toolbarProps.onSearchChanged(searchText); + setSearch(searchText); + }, + [toolbarProps, setSearch], + ); + + if (hasFilters) { + return ( + <div className={filtersClasses.root}> + <div className={filtersClasses.root}> + <IconButton onClick={toggleFilters} aria-label="filter list"> + <FilterList /> + </IconButton> + <Typography className={filtersClasses.title}> + Filters ({selectedFiltersLength}) + </Typography> + </div> + <StyledMTableToolbar + {...toolbarProps} + ref={toolbarRef} + onSearchChanged={onSearchChanged} + /> + </div> + ); + } + + return ( + <StyledMTableToolbar + {...toolbarProps} + ref={toolbarRef} + onSearchChanged={onSearchChanged} + /> + ); +} + export function Table<T extends object = {}>({ columns, options, @@ -219,10 +275,7 @@ export function Table<T extends object = {}>({ onStateChange, ...props }: TableProps<T>) { - const headerClasses = useHeaderStyles(); - const toolbarClasses = useToolbarStyles(); const tableClasses = useTableStyles(); - const filtersClasses = useFilterStyles(); const { data, ...propsWithoutData } = props; @@ -230,9 +283,12 @@ export function Table<T extends object = {}>({ const calculatedInitialState = { ...defaultInitialState, ...initialState }; - const [filtersOpen, toggleFilters] = useState( + const [filtersOpen, setFiltersOpen] = useState( calculatedInitialState.filtersOpen, ); + const toggleFilters = useCallback(() => setFiltersOpen(v => !v), [ + setFiltersOpen, + ]); const [selectedFiltersLength, setSelectedFiltersLength] = useState(0); const [tableData, setTableData] = useState(data as any[]); const [selectedFilters, setSelectedFilters] = useState( @@ -379,64 +435,32 @@ export function Table<T extends object = {}>({ })); }; + const hasFilters = !!filters?.length; const Toolbar = useCallback( toolbarProps => { - const onSearchChanged = (searchText: string) => { - toolbarProps.onSearchChanged(searchText); - setSearch(searchText); - }; - - if (filters?.length) { - return ( - <div className={filtersClasses.root}> - <div className={filtersClasses.root}> - <IconButton - onClick={() => toggleFilters(el => !el)} - aria-label="filter list" - > - <FilterList /> - </IconButton> - <Typography className={filtersClasses.title}> - Filters ({selectedFiltersLength}) - </Typography> - </div> - <MTableToolbar - classes={toolbarClasses} - {...toolbarProps} - ref={toolbarRef} - onSearchChanged={onSearchChanged} - /> - </div> - ); - } - return ( - <MTableToolbar - classes={toolbarClasses} + <TableToolbar + toolbarRef={toolbarRef} + setSearch={setSearch} + hasFilters={hasFilters} + selectedFiltersLength={selectedFiltersLength} + toggleFilters={toggleFilters} {...toolbarProps} - ref={toolbarRef} - onSearchChanged={onSearchChanged} /> ); }, - [ - filters?.length, - selectedFiltersLength, - toggleFilters, - toolbarClasses, - filtersClasses, - setSearch, - toolbarRef, - ], + [toggleFilters, hasFilters, selectedFiltersLength, setSearch, toolbarRef], ); + const hasNoRows = typeof data !== 'function' && data.length === 0; + const columnCount = columns.length; const Body = useCallback( bodyProps => { - if (emptyContent && typeof data !== 'function' && data.length === 0) { + if (emptyContent && hasNoRows) { return ( <tbody> <tr> - <td colSpan={columns.length}>{emptyContent}</td> + <td colSpan={columnCount}>{emptyContent}</td> </tr> </tbody> ); @@ -444,7 +468,7 @@ export function Table<T extends object = {}>({ return <MTableBody {...bodyProps} />; }, - [data, emptyContent, columns], + [hasNoRows, emptyContent, columnCount], ); return ( @@ -458,9 +482,7 @@ export function Table<T extends object = {}>({ )} <MTable<T> components={{ - Header: headerProps => ( - <MTableHeader classes={headerClasses} {...headerProps} /> - ), + Header: StyledMTableHeader, Toolbar, Body, }} From 81ef1d57bf5a23103fed4160c767e52f3e13c55d Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 6 May 2021 17:50:30 +0200 Subject: [PATCH 448/462] Show error on task page if task does not exist Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- .changeset/grumpy-goats-refuse.md | 5 +++++ plugins/scaffolder/package.json | 1 + plugins/scaffolder/src/api.ts | 11 +++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .changeset/grumpy-goats-refuse.md diff --git a/.changeset/grumpy-goats-refuse.md b/.changeset/grumpy-goats-refuse.md new file mode 100644 index 0000000000..8dc2e390fc --- /dev/null +++ b/.changeset/grumpy-goats-refuse.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Show error on task page if task does not exist. diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index f2f69c029b..9cf7c01d02 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -33,6 +33,7 @@ "@backstage/catalog-client": "^0.3.11", "@backstage/catalog-model": "^0.7.8", "@backstage/config": "^0.1.5", + "@backstage/errors": "^0.1.1", "@backstage/core": "^0.7.8", "@backstage/integration": "^0.5.2", "@backstage/integration-react": "^0.1.1", diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 0c5eb2b268..6add205bb6 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -22,6 +22,7 @@ import { IdentityApi, Observable, } from '@backstage/core'; +import { ResponseError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; import ObservableImpl from 'zen-observable'; import { ListActionsResponse, ScaffolderTask, Status } from './types'; @@ -173,9 +174,15 @@ export class ScaffolderClient implements ScaffolderApi { const token = await this.identityApi.getIdToken(); const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`; - return fetch(url, { + const response = await fetch(url, { headers: token ? { Authorization: `Bearer ${token}` } : {}, - }).then(x => x.json()); + }); + + if (!response.ok) { + throw ResponseError.fromResponse(response); + } + + return await response.json(); } streamLogs({ From 15e248a107d9c7de2f88a6b8363785c8f65707c5 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 6 May 2021 18:22:26 +0200 Subject: [PATCH 449/462] Migrate all scaffolder API calls to `ResponseError` Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- plugins/scaffolder/src/api.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 6add205bb6..a603df5fc6 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -129,9 +129,7 @@ export class ScaffolderClient implements ScaffolderApi { }); if (!response.ok) { - throw new Error( - `Failed to fetch template parameter schema, ${await response.text()}`, - ); + throw ResponseError.fromResponse(response); } const schema: TemplateParameterSchema = await response.json(); @@ -161,9 +159,7 @@ export class ScaffolderClient implements ScaffolderApi { }); if (response.status !== 201) { - const status = `${response.status} ${response.statusText}`; - const body = await response.text(); - throw new Error(`Backend request failed, ${status} ${body.trim()}`); + throw ResponseError.fromResponse(response); } const { id } = (await response.json()) as { id: string }; @@ -241,6 +237,11 @@ export class ScaffolderClient implements ScaffolderApi { async listActions(): Promise<ListActionsResponse> { const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); const response = await fetch(`${baseUrl}/v2/actions`); + + if (!response.ok) { + throw ResponseError.fromResponse(response); + } + return await response.json(); } } From d6ee1830543304d339583ce73f895d75f3ce8e11 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Thu, 6 May 2021 18:28:41 +0200 Subject: [PATCH 450/462] Restore for `scaffold()` Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- plugins/scaffolder/src/api.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index a603df5fc6..c7b1594071 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -159,7 +159,9 @@ export class ScaffolderClient implements ScaffolderApi { }); if (response.status !== 201) { - throw ResponseError.fromResponse(response); + const status = `${response.status} ${response.statusText}`; + const body = await response.text(); + throw new Error(`Backend request failed, ${status} ${body.trim()}`); } const { id } = (await response.json()) as { id: string }; From dd3b98138fe637d5b42d0a00c8f0e1ec6cfb5330 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 May 2021 18:50:26 +0000 Subject: [PATCH 451/462] chore(deps): bump property-expr from 2.0.2 to 2.0.4 Bumps [property-expr](https://github.com/jquense/expr) from 2.0.2 to 2.0.4. - [Release notes](https://github.com/jquense/expr/releases) - [Changelog](https://github.com/jquense/expr/blob/master/CHANGELOG.md) - [Commits](https://github.com/jquense/expr/compare/v2.0.2...v2.0.4) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index a471cbb1e2..8cdd10db6e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21585,9 +21585,9 @@ prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, react-is "^16.8.1" property-expr@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/property-expr/-/property-expr-2.0.2.tgz#fff2a43919135553a3bc2fdd94bdb841965b2330" - integrity sha512-bc/5ggaYZxNkFKj374aLbEDqVADdYaLcFo8XBkishUWbaAdjlphaBFns9TvRA2pUseVL/wMFmui9X3IdNDU37g== + version "2.0.4" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910" + integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg== property-information@^5.0.0: version "5.4.0" From 10c008a3a68c810d382cff06349d6d753a44cc04 Mon Sep 17 00:00:00 2001 From: Julian Pearce <julian@aimusic.co.uk> Date: Fri, 7 May 2021 03:24:00 +0100 Subject: [PATCH 452/462] resolves #5586 Signed-off-by: Julian Pearce <git@julian.mp> --- .changeset/cyan-beans-marry.md | 5 +++++ .../catalog-model/src/kinds/TemplateEntityV1beta2.test.ts | 2 +- packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts | 2 +- .../src/schema/kinds/Template.v1beta2.schema.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/cyan-beans-marry.md diff --git a/.changeset/cyan-beans-marry.md b/.changeset/cyan-beans-marry.md new file mode 100644 index 0000000000..99d7ad47ce --- /dev/null +++ b/.changeset/cyan-beans-marry.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-model': patch +--- + +Renamed parameters to input in template schema diff --git a/packages/catalog-model/src/kinds/TemplateEntityV1beta2.test.ts b/packages/catalog-model/src/kinds/TemplateEntityV1beta2.test.ts index 60f3de9e59..958a486687 100644 --- a/packages/catalog-model/src/kinds/TemplateEntityV1beta2.test.ts +++ b/packages/catalog-model/src/kinds/TemplateEntityV1beta2.test.ts @@ -51,7 +51,7 @@ describe('templateEntityV1beta2Validator', () => { id: 'fetch', name: 'Fetch', action: 'fetch:plan', - parameters: { + input: { url: './template', }, }, diff --git a/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts b/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts index c78e7f85d5..1f4e3bcd90 100644 --- a/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts +++ b/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts @@ -38,7 +38,7 @@ export interface TemplateEntityV1beta2 extends Entity { id?: string; name?: string; action: string; - parameters?: JsonObject; + input?: JsonObject; }>; output?: { [name: string]: string }; }; diff --git a/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json b/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json index 1e0b7d0ded..b88b344626 100644 --- a/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json +++ b/packages/catalog-model/src/schema/kinds/Template.v1beta2.schema.json @@ -125,7 +125,7 @@ "type": "string", "description": "The name of the action to execute." }, - "parameters": { + "input": { "type": "object", "description": "A templated object describing the inputs to the action." } From e38d2c73e1a07bcd4a9abc3e57c0362aa60dd8c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 May 2021 04:12:08 +0000 Subject: [PATCH 453/462] chore(deps-dev): bump @graphql-codegen/typescript-resolvers Bumps [@graphql-codegen/typescript-resolvers](https://github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/plugins/typescript/resolvers) from 1.18.2 to 1.19.1. - [Release notes](https://github.com/dotansimha/graphql-code-generator/releases) - [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/plugins/typescript/resolvers/CHANGELOG.md) - [Commits](https://github.com/dotansimha/graphql-code-generator/commits/@graphql-codegen/typescript-resolvers@1.19.1/packages/plugins/typescript/resolvers) Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8cdd10db6e..a435ee5769 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2351,18 +2351,18 @@ tslib "~2.2.0" "@graphql-codegen/typescript-resolvers@^1.17.7": - version "1.18.2" - resolved "https://registry.npmjs.org/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-1.18.2.tgz#7513b92df7c5a0d3c27342c591ada7340696cf8f" - integrity sha512-aWfRR5y1gXCPUNK7zaUiSbmceqidvZ38mNHIBvXmZArRigyz1QZgN26kKpXjJjtFbPvROPnlGsYcZBReybvZXA== + version "1.19.1" + resolved "https://registry.npmjs.org/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-1.19.1.tgz#56677ec56c1ca7174d22a2f236e3fb7f6503e708" + integrity sha512-KdCVfg2u2RMbHu7eV9SOh5rmfnEQaMsQ0k8741bMbBmCESLnrWltujF2RT1OPN7WCn7xJejBtrFg/3UgT0fNug== dependencies: - "@graphql-codegen/plugin-helpers" "^1.18.2" - "@graphql-codegen/typescript" "^1.21.0" - "@graphql-codegen/visitor-plugin-common" "^1.18.3" + "@graphql-codegen/plugin-helpers" "^1.18.5" + "@graphql-codegen/typescript" "^1.22.0" + "@graphql-codegen/visitor-plugin-common" "^1.20.0" "@graphql-tools/utils" "^7.0.0" auto-bind "~4.0.0" - tslib "~2.1.0" + tslib "~2.2.0" -"@graphql-codegen/typescript@^1.17.7", "@graphql-codegen/typescript@^1.21.0": +"@graphql-codegen/typescript@^1.17.7", "@graphql-codegen/typescript@^1.22.0": version "1.22.0" resolved "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-1.22.0.tgz#d05be3a971e5d75a076a43e123b6330f4366a6ab" integrity sha512-YzN/3MBYHrP110m8JgUWQIHt7Ivi3JXiq0RT5XNx/F9mVOSbZz6Ezbaji8YJA3y04Gl2f6ZgtdGazWANUvcOcg== @@ -2372,7 +2372,7 @@ auto-bind "~4.0.0" tslib "~2.2.0" -"@graphql-codegen/visitor-plugin-common@^1.18.3", "@graphql-codegen/visitor-plugin-common@^1.20.0": +"@graphql-codegen/visitor-plugin-common@^1.20.0": version "1.20.0" resolved "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.20.0.tgz#38d829eab7370c79aa5229190788f94adcae8f76" integrity sha512-AYrpy8NA3DpvhDLqYGerQRv44S+YAMPKtwT8x9GNVjzP0gVfmqi3gG1bDWbP5sm6kOZKvDC0kTxGePuBSZerxw== @@ -2664,16 +2664,7 @@ camel-case "4.1.1" tslib "~2.0.1" -"@graphql-tools/utils@^7.0.0", "@graphql-tools/utils@^7.1.0": - version "7.2.6" - resolved "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.2.6.tgz#5d974cbdec5ddf4d7fdc593816335512ee5fe4de" - integrity sha512-/kY7Nb+cCHi/MvU3tjz3KrXzuJNWMlnn7EoWazLmpDvl6b2Qt69hlVoPd5zQtKlGib35zZw9NZ5zs5qTAw8Y9g== - dependencies: - "@ardatan/aggregate-error" "0.0.6" - camel-case "4.1.2" - tslib "~2.1.0" - -"@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.7.0": +"@graphql-tools/utils@^7.0.0", "@graphql-tools/utils@^7.1.0", "@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.7.0": version "7.7.1" resolved "https://registry.npmjs.org/@graphql-tools/utils/-/utils-7.7.1.tgz#81f32cb4819b34b3a378d51ab2cd60935977f0b4" integrity sha512-SFT4/dTfrwWer1wSOLU+jqgv3oa/xTR8q+MiNbE9nCH2FXyMsqIOaXKm9wHfKIWFWHozqBdcnwFkQZrdD7H2TQ== From 3be844496c9c267cd57d8c26687a0c72dcfac6a1 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 7 May 2021 10:09:22 +0200 Subject: [PATCH 454/462] chore(deps): add changeset for ts-node bump Signed-off-by: blam <ben@blam.sh> --- .changeset/calm-insects-melt.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/calm-insects-melt.md diff --git a/.changeset/calm-insects-melt.md b/.changeset/calm-insects-melt.md new file mode 100644 index 0000000000..4b17764c33 --- /dev/null +++ b/.changeset/calm-insects-melt.md @@ -0,0 +1,7 @@ +--- +'@backstage/cli': patch +'@backstage/create-app': patch +'@backstage/plugin-catalog-graphql': patch +--- + +chore: bump `ts-node` versions to 9.1.1 From 0b51bcb0084ff6566e96ceb96ad7562ce1a90bff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 May 2021 09:20:46 +0000 Subject: [PATCH 455/462] chore(deps): bump react-use from 15.3.8 to 17.2.4 Bumps [react-use](https://github.com/streamich/react-use) from 15.3.8 to 17.2.4. - [Release notes](https://github.com/streamich/react-use/releases) - [Changelog](https://github.com/streamich/react-use/blob/master/CHANGELOG.md) - [Commits](https://github.com/streamich/react-use/compare/v15.3.8...v17.2.4) Signed-off-by: dependabot[bot] <support@github.com> --- packages/app/package.json | 2 +- packages/core-api/package.json | 2 +- packages/core/package.json | 2 +- packages/integration-react/package.json | 2 +- plugins/api-docs/package.json | 2 +- plugins/badges/package.json | 2 +- plugins/bitrise/package.json | 2 +- plugins/catalog-import/package.json | 2 +- plugins/catalog-react/package.json | 2 +- plugins/catalog/package.json | 2 +- plugins/circleci/package.json | 2 +- plugins/cloudbuild/package.json | 2 +- plugins/code-coverage/package.json | 2 +- plugins/config-schema/package.json | 2 +- plugins/cost-insights/package.json | 2 +- plugins/explore/package.json | 2 +- plugins/fossa/package.json | 2 +- plugins/gcp-projects/package.json | 2 +- plugins/github-actions/package.json | 2 +- plugins/github-deployments/package.json | 2 +- plugins/gitops-profiles/package.json | 2 +- plugins/graphiql/package.json | 2 +- plugins/jenkins/package.json | 2 +- plugins/kafka/package.json | 2 +- plugins/kubernetes/package.json | 2 +- plugins/lighthouse/package.json | 2 +- plugins/newrelic/package.json | 2 +- plugins/org/package.json | 2 +- plugins/pagerduty/package.json | 2 +- plugins/register-component/package.json | 2 +- plugins/rollbar/package.json | 2 +- plugins/scaffolder/package.json | 2 +- plugins/search/package.json | 2 +- plugins/sentry/package.json | 2 +- plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/package.json | 2 +- plugins/tech-radar/package.json | 2 +- plugins/techdocs/package.json | 2 +- plugins/todo/package.json | 2 +- plugins/user-settings/package.json | 2 +- plugins/welcome/package.json | 2 +- yarn.lock | 75 ++++--------------------- 42 files changed, 51 insertions(+), 106 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index 8ddf249366..e05e520ab5 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -51,7 +51,7 @@ "react-hot-loader": "^4.12.21", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "zen-observable": "^0.8.15" }, "devDependencies": { diff --git a/packages/core-api/package.json b/packages/core-api/package.json index a55df67343..13d7efe77b 100644 --- a/packages/core-api/package.json +++ b/packages/core-api/package.json @@ -38,7 +38,7 @@ "prop-types": "^15.7.2", "react": "^16.12.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "zen-observable": "^0.8.15" }, "devDependencies": { diff --git a/packages/core/package.json b/packages/core/package.json index 4da981d064..f8425c3289 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -65,7 +65,7 @@ "react-sparklines": "^1.7.0", "react-syntax-highlighter": "^15.4.3", "react-text-truncate": "^0.16.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "remark-gfm": "^1.0.0", "zen-observable": "^0.8.15" }, diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 9f33a25ac8..7833952e8e 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -29,7 +29,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.3", diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index e8e8bb8774..9cccb07d56 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -45,7 +45,7 @@ "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "swagger-ui-react": "^3.37.2" }, "devDependencies": { diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 7078b9627e..24660899e2 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -31,7 +31,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index cd0564dc41..45b32a11d1 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -33,7 +33,7 @@ "qs": "^6.9.6", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "recharts": "^1.8.5" }, "devDependencies": { diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 2277604dc2..c5fcdd4d37 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -49,7 +49,7 @@ "react-hook-form": "^6.15.4", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "yaml": "^1.10.0" }, "devDependencies": { diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 1d886478b8..a9092ef75a 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -37,7 +37,7 @@ "react": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 8277c2dcbc..f1a0e6979d 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -49,7 +49,7 @@ "react-helmet": "6.1.0", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index b87fb4bbbf..98af012a49 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -47,7 +47,7 @@ "react-lazylog": "^4.5.2", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 98735f1c42..325dfb4e06 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -44,7 +44,7 @@ "react-lazylog": "^4.5.3", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 241b61b296..9b227c1df1 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -35,7 +35,7 @@ "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "recharts": "^1.8.5" }, "devDependencies": { diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 7877668065..caa03b9ffb 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -31,7 +31,7 @@ "zen-observable": "^0.8.15", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 5d780080d1..3a5601041c 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -49,7 +49,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "recharts": "^1.8.5", "regression": "^2.0.1", "yup": "^0.29.3" diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 35a4a97349..2a25a9db41 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -42,7 +42,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index ee35b94c0b..95762e52d7 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -44,7 +44,7 @@ "p-limit": "^3.0.2", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 96102332d9..fd6048ab2a 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -38,7 +38,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "^6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 61de1a1f7d..95608c3c49 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -47,7 +47,7 @@ "react-lazylog": "^4.5.3", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index e67df926ea..84a0fe1660 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -31,7 +31,7 @@ "luxon": "^1.26.0", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 866ee571c0..c00dbde482 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -39,7 +39,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index d03a5f39e9..ae3c0dfe8f 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -40,7 +40,7 @@ "graphql": "15.5.0", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 45bd3c4bf8..c4ba600d7e 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -44,7 +44,7 @@ "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index ce3e7561b1..e405460262 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -30,7 +30,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 8028c3a339..19865a6fcc 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -46,7 +46,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index a6ae0102bf..f70e29f69b 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -43,7 +43,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index dfe5217f9d..20ee5521f4 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -38,7 +38,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/org/package.json b/plugins/org/package.json index 2b802510f4..012514f1c4 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -32,7 +32,7 @@ "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 0005b9aa3b..53f0ddbb23 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -43,7 +43,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index 5052fd3342..3efb61b982 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -42,7 +42,7 @@ "react-hook-form": "^6.15.4", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 5563ad0e40..8b559e0bf1 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -44,7 +44,7 @@ "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", "react-sparklines": "^1.7.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 9cf7c01d02..1992028157 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -55,7 +55,7 @@ "react-lazylog": "^4.5.2", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "use-immer": "^0.5.1", "zen-observable": "^0.8.15" }, diff --git a/plugins/search/package.json b/plugins/search/package.json index b135d184f6..f503b9a78e 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -41,7 +41,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index a5b1ac7d68..6784debcf9 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -42,7 +42,7 @@ "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", "react-sparklines": "^1.7.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "timeago.js": "^4.0.2" }, "devDependencies": { diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 648f945e03..df5304d746 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -44,7 +44,7 @@ "rc-progress": "^3.0.0", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 63fb68c0b2..020fbc37cd 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -42,7 +42,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 2a2619bbc4..5e33024f87 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -40,7 +40,7 @@ "prop-types": "^15.7.2", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 380eae2737..20fca364da 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -47,7 +47,7 @@ "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3", + "react-use": "^17.2.4", "sanitize-html": "^2.3.2" }, "devDependencies": { diff --git a/plugins/todo/package.json b/plugins/todo/package.json index aac15e9ad6..b7564f7080 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -36,7 +36,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 3349319442..32e232cad4 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -38,7 +38,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index 90cdb3dc0f..72ec24bf71 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -38,7 +38,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^0.6.10", diff --git a/yarn.lock b/yarn.lock index a435ee5769..2cf1551fed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8874,11 +8874,6 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= -bowser@^1.7.3: - version "1.9.4" - resolved "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a" - integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ== - boxen@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" @@ -10811,14 +10806,6 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-tree@^1.0.0-alpha.28: - version "1.0.0-alpha.39" - resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" - integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== - dependencies: - mdn-data "2.0.6" - source-map "^0.6.1" - css-tree@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5" @@ -10973,7 +10960,7 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.5, csstype@^2.5.7, csstype@^2.6.7: +csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.7, csstype@^2.6.7: version "2.6.9" resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== @@ -13195,11 +13182,6 @@ fast-text-encoding@^1.0.0, fast-text-encoding@^1.0.3: resolved "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== -fastest-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-1.0.1.tgz#9122d406d4c9d98bea644a6b6853d5874b87b028" - integrity sha1-kSLUBtTJ2YvqZEpraFPVh0uHsCg= - fastest-stable-stringify@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76" @@ -15427,14 +15409,6 @@ init-package-json@^2.0.2: validate-npm-package-license "^3.0.4" validate-npm-package-name "^3.0.0" -inline-style-prefixer@^4.0.0: - version "4.0.2" - resolved "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-4.0.2.tgz#d390957d26f281255fe101da863158ac6eb60911" - integrity sha512-N8nVhwfYga9MiV9jWlwfdj1UDIaZlBFu4cJSJkIr7tZX7sHpHhGR5su1qdpW+7KPL8ISTvCIkcaFi/JdBknvPg== - dependencies: - bowser "^1.7.3" - css-in-js-utils "^2.0.0" - inline-style-prefixer@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz#f73d5dbf2855733d6b153a4d24b7b47a73e9770b" @@ -18352,11 +18326,6 @@ mdn-data@2.0.4: resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== -mdn-data@2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" - integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== - mdurl@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -19064,21 +19033,7 @@ nan@2.14.1, nan@^2.12.1, nan@^2.14.0: resolved "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== -nano-css@^5.1.0, nano-css@^5.2.1: - version "5.3.0" - resolved "https://registry.npmjs.org/nano-css/-/nano-css-5.3.0.tgz#9d3cd29788d48b6a07f52aa4aec7cf4da427b6b5" - integrity sha512-uM/9NGK9/E9/sTpbIZ/bQ9xOLOIHZwrrb/CRlbDHBU/GFS7Gshl24v/WJhwsVViWkpOXUmiZ66XO7fSB4Wd92Q== - dependencies: - css-tree "^1.0.0-alpha.28" - csstype "^2.5.5" - fastest-stable-stringify "^1.0.1" - inline-style-prefixer "^4.0.0" - rtl-css-js "^1.9.0" - sourcemap-codec "^1.4.1" - stacktrace-js "^2.0.0" - stylis "3.5.0" - -nano-css@^5.3.1: +nano-css@^5.1.0, nano-css@^5.2.1, nano-css@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/nano-css/-/nano-css-5.3.1.tgz#b709383e07ad3be61f64edffacb9d98250b87a1f" integrity sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA== @@ -22426,10 +22381,10 @@ react-use@^15.3.3, react-use@^15.3.6: ts-easing "^0.2.0" tslib "^2.0.0" -react-use@^17.2.1: - version "17.2.1" - resolved "https://registry.npmjs.org/react-use/-/react-use-17.2.1.tgz#c81e12544115ed049c7deba1e3bb3d977dfee9b8" - integrity sha512-9r51/at7/Nr/nEP4CsHz+pl800EAqhIY9R6O68m68kaWc8slDAfx1UrIedQqpsb4ImddFYb+6hF1i5Vj4u4Cnw== +react-use@^17.2.1, react-use@^17.2.4: + version "17.2.4" + resolved "https://registry.npmjs.org/react-use/-/react-use-17.2.4.tgz#1f89be3db0a8237c79253db0a15e12bbe3cfeff1" + integrity sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ== dependencies: "@types/js-cookie" "^2.2.6" "@xobotyi/scrollbar-width" "^1.9.5" @@ -23337,7 +23292,7 @@ rsvp@^4.8.4: resolved "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -rtl-css-js@^1.14.0, rtl-css-js@^1.9.0: +rtl-css-js@^1.14.0: version "1.14.0" resolved "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.14.0.tgz#daa4f192a92509e292a0519f4b255e6e3c076b7d" integrity sha512-Dl5xDTeN3e7scU1cWX8c9b6/Nqz3u/HgR4gePc1kWXYiQWVQbKCEyK6+Hxve9LbcJ5EieHy1J9nJCN3grTtGwg== @@ -23494,12 +23449,7 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -screenfull@^5.0.0: - version "5.0.2" - resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.0.2.tgz#b9acdcf1ec676a948674df5cd0ff66b902b0bed7" - integrity sha512-cCF2b+L/mnEiORLN5xSAz6H3t18i2oHh9BA8+CQlAh5DRw2+NFAGQJOSYbcGw8B2k04g/lVvFcfZ83b3ysH5UQ== - -screenfull@^5.1.0: +screenfull@^5.0.0, screenfull@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8" integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA== @@ -24069,7 +24019,7 @@ source-map@^0.7.3: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -sourcemap-codec@^1.4.1, sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: +sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== @@ -24302,7 +24252,7 @@ stacktrace-gps@^3.0.4: source-map "0.5.6" stackframe "^1.1.1" -stacktrace-js@^2.0.0, stacktrace-js@^2.0.2: +stacktrace-js@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== @@ -24722,11 +24672,6 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -stylis@3.5.0: - version "3.5.0" - resolved "https://registry.npmjs.org/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1" - integrity sha512-pP7yXN6dwMzAR29Q0mBrabPCe0/mNO1MSr93bhay+hcZondvMMTpeGyd8nbhYJdyperNT2DRxONQuUGcJr5iPw== - stylis@^4.0.6: version "4.0.7" resolved "https://registry.npmjs.org/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904" From 4d9a337a4a4d7a35f7673f17afd8174abc291241 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Fri, 7 May 2021 11:54:12 +0200 Subject: [PATCH 456/462] Restore `debounceTime` and mark it as deprecated Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- packages/core/src/hooks/useQueryParamState.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/hooks/useQueryParamState.ts b/packages/core/src/hooks/useQueryParamState.ts index 023d69bf4f..944e73bf39 100644 --- a/packages/core/src/hooks/useQueryParamState.ts +++ b/packages/core/src/hooks/useQueryParamState.ts @@ -58,6 +58,8 @@ type SetQueryParams<T> = (params: T) => void; export function useQueryParamState<T>( stateName: string, + /** @depracated Don't configure a custom debouceTime */ + debounceTime: number = 250, ): [T | undefined, SetQueryParams<T>] { const [searchParams, setSearchParams] = useSearchParams(); const searchParamsString = searchParams.toString(); @@ -85,7 +87,7 @@ export function useQueryParamState<T>( setSearchParams(queryString, { replace: true }); } }, - 100, + debounceTime, [setSearchParams, queryParamState, searchParamsString, stateName], ); From add75e7a5b074b1af1063bdacf369d64ee4e697f Mon Sep 17 00:00:00 2001 From: Julian Pearce <git@julian.mp> Date: Fri, 7 May 2021 11:42:03 +0100 Subject: [PATCH 457/462] generate API report Signed-off-by: Julian Pearce <git@julian.mp> --- packages/catalog-model/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index c37c86b01f..2b56879f48 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -514,7 +514,7 @@ export interface TemplateEntityV1beta2 extends Entity { id?: string; name?: string; action: string; - parameters?: JsonObject; + input?: JsonObject; }>; output?: { [name: string]: string; From 9eabe20696e1c824616501df35fc7c5a4b63280b Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 7 May 2021 13:27:05 +0200 Subject: [PATCH 458/462] chore: new plugins should use later versions of react-use Signed-off-by: blam <ben@blam.sh> --- packages/cli/templates/default-plugin/package.json.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index 49eda9e0eb..1b4f8ea6ab 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -31,7 +31,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-use": "^15.3.3" + "react-use": "^17.2.4" }, "devDependencies": { "@backstage/cli": "^{{version '@backstage/cli'}}", From 675a569a99fffcf313e3d08148a754ec51027276 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 7 May 2021 13:27:29 +0200 Subject: [PATCH 459/462] chore(deps): added changeset for dep bump Signed-off-by: blam <ben@blam.sh> --- .changeset/ten-paws-ring.md | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .changeset/ten-paws-ring.md diff --git a/.changeset/ten-paws-ring.md b/.changeset/ten-paws-ring.md new file mode 100644 index 0000000000..8ed2158f6c --- /dev/null +++ b/.changeset/ten-paws-ring.md @@ -0,0 +1,44 @@ +--- +'@backstage/core': patch +'@backstage/core-api': patch +'@backstage/integration-react': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-badges': patch +'@backstage/plugin-bitrise': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-code-coverage': patch +'@backstage/plugin-config-schema': patch +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-fossa': patch +'@backstage/plugin-gcp-projects': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-github-deployments': patch +'@backstage/plugin-gitops-profiles': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-jenkins': patch +'@backstage/plugin-kafka': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-lighthouse': patch +'@backstage/plugin-newrelic': patch +'@backstage/plugin-org': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-register-component': patch +'@backstage/plugin-rollbar': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-search': patch +'@backstage/plugin-sentry': patch +'@backstage/plugin-sonarqube': patch +'@backstage/plugin-splunk-on-call': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-todo': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-welcome': patch +--- + +chore: bump `react-use` dependency in all packages From e3fc89df6edc43c8b2f7094a6fb6846c24ba65fc Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 7 May 2021 13:28:41 +0200 Subject: [PATCH 460/462] chore: added changeset for cli changes Signed-off-by: blam <ben@blam.sh> --- .changeset/ninety-pots-guess.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/ninety-pots-guess.md diff --git a/.changeset/ninety-pots-guess.md b/.changeset/ninety-pots-guess.md new file mode 100644 index 0000000000..4b9a770c29 --- /dev/null +++ b/.changeset/ninety-pots-guess.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +update plugins created to use react-use 17.2.4 From 3e3d5572fe3062c9592670321d1d79deffd989a0 Mon Sep 17 00:00:00 2001 From: Johan Haals <johan.haals@gmail.com> Date: Fri, 7 May 2021 13:36:59 +0200 Subject: [PATCH 461/462] catalog/next: Fix postgres type error when deleting entries Signed-off-by: Johan Haals <johan.haals@gmail.com> --- .../src/next/database/DefaultProcessingDatabase.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts index dc5e6036f5..140c93929d 100644 --- a/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/next/database/DefaultProcessingDatabase.ts @@ -185,7 +185,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { ), -- All the nodes that can be reached upwards from the descendants ancestors(root_id, via_entity_ref, to_entity_ref) AS ( - SELECT NULL, entity_ref, entity_ref + SELECT CAST(NULL as INT), entity_ref, entity_ref FROM descendants UNION SELECT @@ -235,7 +235,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .withRecursive('ancestors', function ancestors(outer) { return outer .select({ - root_id: tx.raw('NULL', []), + root_id: tx.raw('CAST(NULL as INT)', []), via_entity_ref: 'entity_ref', to_entity_ref: 'entity_ref', }) From 6f57e2df67494f596dcdaed3f401a2e5487ae4c0 Mon Sep 17 00:00:00 2001 From: Oliver Sand <oliver.sand@sda-se.com> Date: Fri, 7 May 2021 15:09:12 +0200 Subject: [PATCH 462/462] Fix typo Signed-off-by: Oliver Sand <oliver.sand@sda-se.com> --- packages/core/src/hooks/useQueryParamState.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/hooks/useQueryParamState.ts b/packages/core/src/hooks/useQueryParamState.ts index 944e73bf39..173993a466 100644 --- a/packages/core/src/hooks/useQueryParamState.ts +++ b/packages/core/src/hooks/useQueryParamState.ts @@ -58,7 +58,7 @@ type SetQueryParams<T> = (params: T) => void; export function useQueryParamState<T>( stateName: string, - /** @depracated Don't configure a custom debouceTime */ + /** @deprecated Don't configure a custom debouceTime */ debounceTime: number = 250, ): [T | undefined, SetQueryParams<T>] { const [searchParams, setSearchParams] = useSearchParams();

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%0Adyv^458nhwg2y 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 VOv|tXk}4dWl!Ux^iRk+;{|7bHqC)@x From 9afcac5af9d579b7252b3c588e81f81da1b4f7cb Mon Sep 17 00:00:00 2001 From: Ilya Lyamkin Date: Fri, 16 Apr 2021 16:59:26 +0200 Subject: [PATCH 038/462] Pass NavLinkProps to SidebarItem Signed-off-by: Ilya Lyamkin --- .changeset/healthy-phones-press.md | 5 +++++ packages/core/src/layout/Sidebar/Items.tsx | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .changeset/healthy-phones-press.md diff --git a/.changeset/healthy-phones-press.md b/.changeset/healthy-phones-press.md new file mode 100644 index 0000000000..c771caefc5 --- /dev/null +++ b/.changeset/healthy-phones-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/core': patch +--- + +Allow passing NavLinkProps to SidebarItem component to use in NavLink diff --git a/packages/core/src/layout/Sidebar/Items.tsx b/packages/core/src/layout/Sidebar/Items.tsx index e41a45a225..7c9c0a901f 100644 --- a/packages/core/src/layout/Sidebar/Items.tsx +++ b/packages/core/src/layout/Sidebar/Items.tsx @@ -32,7 +32,7 @@ import React, { useContext, useState, } from 'react'; -import { NavLink } from 'react-router-dom'; +import { NavLink, NavLinkProps } from 'react-router-dom'; import { sidebarConfig, SidebarContext } from './config'; const useStyles = makeStyles(theme => { @@ -138,7 +138,7 @@ type SidebarItemButtonProps = SidebarItemBaseProps & { type SidebarItemLinkProps = SidebarItemBaseProps & { to: string; onClick?: (ev: React.MouseEvent) => void; -}; +} & NavLinkProps; type SidebarItemProps = SidebarItemButtonProps | SidebarItemLinkProps; @@ -156,6 +156,7 @@ export const SidebarItem = forwardRef((props, ref) => { onClick, children, className, + ...navLinkProps } = props; const classes = useStyles(); // XXX (@koroeskohr): unsure this is optimal. But I just really didn't want to have the item component @@ -216,6 +217,7 @@ export const SidebarItem = forwardRef((props, ref) => { activeClassName={classes.selected} to={props.to} ref={ref} + {...navLinkProps} > {content} From d5b2a057121f9e5c8c7f23b7d2e539b21e3ffe41 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 16 Apr 2021 17:20:33 +0200 Subject: [PATCH 039/462] core-api: remove apiHolder creation check Signed-off-by: Patrik Oldsberg --- packages/core-api/src/app/App.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/core-api/src/app/App.tsx b/packages/core-api/src/app/App.tsx index fdbee075fc..0557f4159c 100644 --- a/packages/core-api/src/app/App.tsx +++ b/packages/core-api/src/app/App.tsx @@ -306,9 +306,6 @@ export class PrivateAppImpl implements BackstageApp { this.verifyPlugins(this.plugins); // Initialize APIs once all plugins are available - if (this.apiHolder) { - throw new Error('Plugin holder was initialized too soon'); - } this.getApiHolder(); return result; From 81ebf298b4718eda67e9976ceaa104cdb37f5fc2 Mon Sep 17 00:00:00 2001 From: Tim Hansen Date: Fri, 16 Apr 2021 10:31:48 -0600 Subject: [PATCH 040/462] Set logo assets to absolute URLs Signed-off-by: Tim Hansen --- docs/overview/logos.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/overview/logos.md b/docs/overview/logos.md index 4c0c345f36..9421b7f31e 100644 --- a/docs/overview/logos.md +++ b/docs/overview/logos.md @@ -6,37 +6,37 @@ description: Guidelines for how to use the Backstage logos and icons --- Guidelines for how to use the Backstage logo and icon can be found -[here](/logo_assets/Backstage_Identity_Assets_Overview.pdf). The assets below -are all in `.svg` format. Other formats are available in the +[here](https://backstage.io/logo_assets/Backstage_Identity_Assets_Overview.pdf). +The assets below are all in `.svg` format. Other formats are available in the [repository](https://github.com/backstage/backstage/tree/master/microsite/static/logo_assets). ## Backstage logo - - + + - - + + - - + + ## Backstage icon

46cFKROJI>NLrT0swc{8bTJT>K|?N|JfI7`%e!77!~1`?NK!tOMouCoMZNEhOZM zXkK-YEG_yn&@tyhYNgLAAGgIfUf|v%CCvDV^I6$Oj^wm7!=~+>QgKU2%_IVq8Q^WwojG$fQ_v=azZ2jlbdZ$8e^$4 zzoaSV<1K<@s`x!tGYS5Swl^VYqIA4yj9HtJKCzM{B`4W2KvFDfIugP%X^OGG&-X*u zY3cN88ptig*a&iC1j*FX5UVA1Xbox6vqyinpeY88u#$#YzJKI6mZ3_>Ca|f$ocqr< z9HmJh)oiv*NuvnllEzpMnJ4`>A+mN-Tye43jtDJ^C(cC%0*S=&NL_buA3%27q%V?2 z+z%P~P5pzAViYi;_5Rw?aYT$AMh#rnctw(dpQi%JIR44WsMr^bCRojmNjvOw67m0!T!-|im5-xZLEwB z9IpW)I!-4BB!PGduX|GsT~4NM2S$c50$b-3FCR0Nld(u_K{%!UU=d-Z{RsUI5NSnZ zANG^!wd6n3_xkIG?e{x~KjfNWl&s>0DQoiP?Je_1LWaS{eON?Ti^0kkmC^NTYdPA|7Up5 z8~*WEHH{)sCbIBnJ!pzX>>(q1$6G-cI30#Emlq#T(ca*Yzw6eU!VkXudExe(&&SVF z;^>}-u7+FAp9_z_lLs{NX+xC>(ZVrF#<!ZSjJ+4Xl*q`4Qe(CKW3=bV1Nz#Ve??3z27lvm%{?_Q#yzOImhyVAzAB&nu z5K@g!i_u7W#WSB2zV}667tgESicermJt(!o!C;lA*XfB*gA z+9A;sAvqYrljD6nFWh>O+u{C)u7!K9Tut}EtgRpW{5|0p-~OR+^>E2t*6HtiUi6Ic zs%JeVTEF(bPlVt7$Y+Xm+BCWT>|goTn4o*zoBowNr|){<*tOI5zwxbq6yAULJ>hvz zygmGfuX=v`%@2R}i{XF$y+7is(d>m>-{1W9ZwgPn{n6nKzy0p;C-+m%t@4KhZjKPAKPJ>J%!OS-%Ya!ZnA204cB^b%X-Wc|A@eO7qs z)1MGe`P>7SWAf`sx7{3WI=2_!yS_XMzwle{4WEDTirnIJo^V_E;n%!i+!#{i5N7Sh#q42$(@K;~)?C{Jx z9}_?R(Dh~b{QZ~1`TgB+$1NAb&SE=UJv<8k;m`b)SM_dz+w=a* z;b(vCJ#ubOV}eekByU8E4IxYQGHRP9dG>`$(V|Sntcso99a+wP4hGdWrL~~qRurJ1 zJsKysh|8aYRBH2aPI96056LY`dV$uDl3lIiEqX;xN^0ZKb(L(qZ(s2Y=zQGIPzUOs zG~WLFRio$kHIb&8I-^*h?oIKPrv6&$zoVKHn^Z>otMrwi6MrMc^zb=UwsOCo7SF`w zLrP|eb8a+|_-TEyMlEuT zuCJsaCK4a%2IgvpAvq>*Q8V_mw zl#Z8+n)o}BEEE4ZC9ie;TZI~}qMWmxYl_+Su>0`2b6dQ=f<|Gfy>&j$k!vw|Kq-%%=w;evo-UGA*Y8 zQv>$;{*h`jix*e&&zg7P=DW;aOGP3yuF4u>RYJ=gb{CKSS&$Z<|CjF@Bn%IKk{9}<|xh?BoK{JfT36NlT zKGyDOhCySlRrDxN$Z0yp(7^~yxbY}^h%i5&dE3%en(4o&32T-Q>Cf0d5;9DaU{EV5 zBg1eFcK;HK=w!dcaZwl3~7*##VMn#yeF2P3)7CK$Rh=;6SAb zCN-@bN|}GDB+Bj4N*0{=HMc)1{EgRqQ&=pv!XJF{v*Fj?|H*LmI^hs_61wxz7sL0z zB3>-x|K{d0!iDKDQr! z@1vgy|Kfe0koJD&owtP_e&q{dGT|Mc__Od^bRX9axgvinggb7z5PslgbRV~b2d-QT zKl@vM7_J=faat_C=Y`J*ul#yWh*7fZfB21e#iU|Z8J@&dkr4aQH@!uIAm8h)m3qoZDF5tiT zx4$ub&0}xngxI~8!`@;$Rv6+q^@qRys^^7gJpQ)uEARejc=w>BmKjrZe-S_u@^ux4u`X)<2a4a z`N~(j$)<`_PKr_cg1(WHVx=Tl|NXMIo;vqR6Ecd}sv{LVa^c3>wMu4GvdZyP*(&c3 z+Ov5klD8YXdum`?`C4{{b#q;-WUSujfOgkN<#F-*=V*w{&@}YHI8DaY>HmDu2F9`Y z9awi$uuL@>Dw?H0?&ADpi~pAFl9ml=#f-jBMF-cH$Kn2iWw?BJ9MQ-g306Xe)z<+f-YOqRT{U6E(%sAM83ZY$9nR+9#=!pXL?3Pa3@I_z`VC1&Ej$azGI?C2iE={%}CMw&dRre}6*0pu%4e5w6m^ zivR!u44*TIF!U4A@b>+tqCq`(zf9-v?`+4haN*oe*xT6-J5*RG{wR_oiX5YfNi~7Y z^J!>``FSf}AGV`!uE>)zQq20tE2Ak!?~_eg>Yj!eHY{FiGSV#>x-s!TQ?jdOm)4s( z8e=7~JIs$QO)ihLoQv3|{gXw8S!C6ezHRCsv)`9%ib>$YBtv}B-9+;x9EU|%Wb?|1 zKXw{S02awa-{;4FX&)m95ThX$5lDsk8pyC3;>*5oHO1(CvguXnE2p+5#h7_Rn4Aca zl8{syqy|!NJl;0)9J2j17!stoEHADfp;IiaFC+WOnl_rqv?Mxg)S^jIR7#dD5_0VN z;c>WnbQG3{q%qIi_|l&(+93ZNNHF?6uaVSU2P*x?Bf*+r1u6odb;QkA7GY!CQTNx3 z6ax|r?^|S8ZC%7XMaSVs(Q}B&>w=?N)*M7KKF`W3Jtp^8PD1sxboF?y(ZYH!BR@Yo z%}0v@;P4h6?-yZjE8QaC+<8#OC(Ytw=QcU`PG5=kx4-S*h=Km!`QWF+ufP9~i}yq{ zh5z+;yd*s4=JVkf-~PeyzR&zcJdXzIkALUO!sBka5Ps_ep9;V6flnnQMgBFU?erhL z;(6g&cit8$=zjUVACnXQ^Kbpem=OEKU)&#G|F^e&ApGk;{X+3Np77|4;dS5nQaSh1 zwZrh=zWJ?k?!OZeVowRb_tCq^o=?qu|8zpKyEl;ct0iL=V00|M^!jSV7O? zN5AtW;jy<|2*30GPlw<9;HQP&%}z!{G5Eu;d~SH=owr9c+poOmV^T=-z2C?Qv3o9E z3AaD$V)(>g+!y}QzkFYY5~B<92r*nFT{|Vje*Yt%32!D;QsvK9Iz9JEj}1Tc%IAms z9=aM)ZIp=knP2~daOL`8oV&SS@IU_Mx4kGl^|7~x*ZJ?yzXLB$&Dn;h?bZmcl=Mk_4(mhPq;n&;#)ru z-uEZd{zA#M*L~NEBkGEhQJ?za1F=P)lM-T|z3)=^AAkK1yJI-EUkKs9{7Z}wd*koD zKYZX%?}-(nw$hI5$6h=ie*Al17SDgfZ@xDstp2@k{`&AuPrEbx{)hiG{EPQ~viN&{ z>G@w1{;lVIO?c6DFkkm4^FBFT; zVoHM1cW4rWZ_C<*5~J~HliRKH;};~SuvPiG4)=EVA!jGl5fe(EmeZNcPj1yU!%kJh z!`=8CWSCEi&1=I=&i?<|dlPWGiYje*-T7uBBoGo3!W>8#GXMb*!VpB6M8FaIvz@x7 z2W(J85l{gYP(kf(?f-LX6%}m;g@7Pa5{5t^L=s3yfD8-?kU2LuxzoA#e^#wpRjX=O z?Opqv8@_;jo(E3W-TR!gckLQht+n3wjaSB+`AqN9s!yW1{nZ9X{8IN??!#`*i@4ck z1zMTP;@Yk*`{`IErW-u+Xq?PC!l4|yuGsa$&LsKCs#K^!b$9L~0p4nxH;wqaG+$aI zf2`7({~qFo$4xaNfj4z_!&*e%JDmLKS}&x_mNG6UCxLWb>#8e%>oEKgI+(jw9_ z4aB%MXe;(3|Q8N6x244rqoUEqLdVm;QN!9P@1T zcMkqDQY<+cFoR3?Z8)0BmJv22pz`$lZPJ;ff$JA2h z%42|mRR036CpT)X79|g=ATCfM!^({Zw}^?g#ZokxW&5Ne9%5};gaj*m79wb!iu8A{ zzr2Q+)EuKEh6;15uT{t{HM26(2pJ`;41%u_Zi{~Cd7y1*<3v)KmTaDXB{EO0gPep5`ES0)aY*wRp9j-4rmQcaaYo~d zpLG#3%6VSeA_q!`xL_yh+j+F*zPVcAzTz1y6DrkP~j7QbJ*b{Dkd=Y%~=z~||PfR-$7QVbjX;@)G zZvKkZ@T*4`WwgF7d=DYSZoKCSczNBHApP4vo-|P<`);1I2<9$ZmCIpn`iZHex0-V5 zxpO}XaQ25PXt==ARO0JoSBljH* z_bpfskG;4`wcms>!xcgd6Jj^q^_03!yI9b8;-n*Uh@<^)?>j;zj(`5pGqCX0bwvB6 zIN*g=Tzwr}eA*GP$MBt0;tXjm4;VEJJ~w@mqTjswk8>0f04t)D=(Qd%UwQx0Fmk6s z@T0%XgQah5RQ=(EgT}&{Q^vv5%U*}yJi16B^M(&>1w0o~jMv@qIIP*cO=x(y6?kJ(gZEFgQjd2#ul21s)f18LkwA;n^v zVG=2}y*0zang>*g97Bq6``Z3M`;#G!^)Pa9s{v-1<9dHmWJ^s1i@^6Z!*r6&_E)0S z@oh$=a4-e!P*BUC?>V`}f3Mc|lVoUPAdc5J-wtU2#fmtJk-S2~)y&_v2uT)oa8QWm zp@0Up$Et2tXEDFo{i^mW%=8(t1@fF>8iY(Yg0D(Dsf-=s9#+VAv)s}52{s~AWMKQV zreV{6C{u(`RHP6(-cS#)lhPh*gh8#O)ynk1=6SIH97tMn&cz~Qg(i<)@AEXmLYiWX z6f^x_)47F^rwaL_wQ~_c=GeIZG<1i$D9p3-{IdQ+g5@D6*x!sLb*%r%`w_hlGy9Y9 zzE1A*e56>&M#K_IbhD-yBbwAZj{{9~VKl=$8=n{N&-l7oqn?u=oaFM6WEo_c@Sn;e znS5ke%zwter}+0}^5h|nG3j69c=pGG8T%S}V`&z3e->=5KHaQe6ecy@WDz@SZx!uB z@-*6F+F~(HF`scK#cvPo?+pTo=us!Qbfh@1FfvSm1GLTY7NxPN_bZgUx3-#xkU=YiEXM!}|Ah zUp}*fi)5qzb2Y@IEH)MfY*fvveQlOgR9KA3qlUIBzMu z^u`9b=)F@F-QKl#Jq{bUc9@Vb-pBVob`tdT^uZT@|Dd@;b?pc51+y2w0=IeSw#>lL zymg0--4#A{{9&;0=> zvmlAK!Rmk12(jNi{v6DG>Gi;NE!=}Ga)yp)ZAj=Hx8V#{@PJT`%*vd<(A!d^cSxqsw|A#i^s;!uYQa47i zU7qGJ*w8!ZAB)=CMTXh&MipZ2`13b6p~^~=%n~E0h@-y@2Y-L`=l**SUVrm_$`eJei)xBV@WrCfV^GjayX7ICQZ7KFSBtH#DJ z!iB_;c)lir3JP#gL2oYk(ro+s?G4b?)2p;v5jnP5>pA+GV&O7|@cN#oA*PUFnqJ3f zh}G%J%#^a<8rvE_o~j|nKb4{(memX+tucO;)fCG^j>R;@d`&TnB&}6bEUnR->*`?S z;1+1X2#9zkSC;GXr=E`(Z)`irG5s9*XM7}BSzCG}F=QC8?-D6yMu0|$85%avcGrW# z5noF4Fg8D!Yb($k)Y}7t{FnGa{*H8Sh(1wjx{L|Dh9cqSf;{2Pv@Y5&XXVYu*1s?k zT0sq!5R$h6X%(C56=nLMmWJH@iELjA7Sp^IdKLK>4*iz?g4iQ5-!D#Zkzi$ej7^&P zbYw+#D7j$AV_ZWl)(NUclm*-k0sJs|+7JT7T(1Dy;eFNeQc2_@Q73WS_oq3@VGziA z|G~jtF3z<6hl>m&BpMcRn!78oedL%e9xT(JefmQgpepRo;)nV(365WDiyG)hVo5X} z@CrGilQwuhBgJI&LV^jXkzy+q^IaGrW;Mfb{8%Iy zT~xXzvY=_yh{)*v#I&!A6vO93NiaLU%Ixp?Q`n9vuNX3n#}g*URDafANAp9zEj@BX zhQ$zMwm-Z10H?jtpZr_b5X(!3&G^{oVD0m9+BW>`k)Quelt%HD`)0vImtOsjMvG1S z;*FYaEL^#+Dno=&w$#`$^kg9o9#Lt|l>l66j+t;Xhyt9c_BdwFdsXI~&S%?dl%bPz z>HDU_nBha?sGpQ_EMw zuOEF*o&PT>I_2clHWh5rc}KCGkkB@|5W{|V?okK8yAK=-vlgv{KhAs6Aj9xEzW4BbR6n`@*%fft z{AGrw5)oqWM}!!Tl}8q+C@dvH1Lj z3ALEUfHg~qSWI4xE`ghTMQucV6@t2~x zB-cYm=5chwR2D~~A@;aNerXLjUJ!V_Hk)}}P{^?|PO2E&(_oZE9b8Gtenc6~uvBd^ zb)K&HmGAA{J<#6O0~@<~prfbPXnLN|IW7AOlwWC82w6E z8!S~bA%+}F)B55{QmGN(7Af3Idfiy_5ANU#u%Vjitx5xsH@Nm2ejV#u)sI@TCcEJU}+2rwTh zCXiu_e2Km1W)jN4Ml`~PYedz4s7NEMpEMjx&BsC;68rd&<_2hPX@Eh^jVdT^X`^gX zUrQks(&@U$6RX8+w3a=MU0++5HN`^jjGU0`K}bVPR-hXu7F{_{LF=sFVaBb}K(qc3 zU$+?-c>SnxrWp=6@WD3fS=W2Vo$K|O34A&^lhiQC@PzSVim!ZT3u2=2MJ)4Z^e7oZ z9vW!~*`i8DB1vY2BL6z%j~1=x@^~JSDfT^i{#@Dljgdd5AL)1kwW|j;3fLh{F=Uq{ zZ86elvT_raS&5S=jQrttW@Hs7Uo28AUsH_TO{ozT90x{I+eIYW{-37N7DE0sLWG6pGdwR38O8{( zGDtA#cjsxX`bganayO(+&GBGG4Jnx{0{eE3zwo^6BB_e#+F8>$9|@MnWD$CPoCM3& z5;Mpvi~M2)n2!X@o8Ln68;k_w_dNd^*Gt^5^SWX8>-2ZhShFY<-ydcqm`r*VYlGS6 z;%dU#c)mo2S%kXYKjmq`dj65WKL1T8#E|~*l>hn;3>ve$Gn5b+R+J2r9~gbqWO&!* z7sJjI#$|>iqQ&m}+$Fh*wdDBQ4tQb;LM&TJLW_)D6kI!|X<>sf7B0(4GM*%H^JykQ z?L+Wn7%SAh{zE50Yg0XZ4XFdSc9d%6fz3^D?FXkR%8D=Ce7~X;q?cVaZKVX=0VcIR zd*VcRdEI9C-n~yMC*@yGnWD7A{`0h@Zn)+=N{C%?o2Mam@Ln))`Rg!q@k(<)*j7VYTVUT2!{E5_dqQ(#9o)NMIo!2y zncAFu+uX+k%CY52mRM!c!J~JDe>m}QSh;pH-1wI#)#l~g$p^r369^$T^Z8d4&EgkN zn+l_b4uqQ?eGZ;lfru+gPUa!Ra33Ibm;8saboDy;>FfpS&!{2x>1l)z``N<_6@uzx z$Bc)m`;UP+FRX%_A72bgs8%7wj)1*)-C1dfEoTieoFp+yr=x&)PZLJ(3XBlrWSReN zkTD9fB?(L1tBuvonu^sF?J$iDv&bb%a^dUnJx9PUEs4PO;mj=hFHQ6Af4b>|6q}>7rpNYr6GpN+%=f|XI&p7Tw0~lu zPGo*dt(DI12K@Ogp4_Sf(&XYK8jl&jg-T7qZ~K#r)<;Gr`SdW>`E-S`Wzq~cJDBVW zCASDmiWP!)6f7_X ziJX~eczz7iY4PtD<(N~C$0|Bwm6)OD5RVDvSGvmf-qzg>ZCw>u*M(?ZY?M&LgrXkQ zA{h-afehObHN^5X!&m^G-+gVcBAfe&j}-GqVGJ1-(h|!njtJ9)WszdlRJw*{j-gEr zFk((=_oaC~f=|rfuT=OENM|Ut;Kd+<(=x=8lG{ znF?e5fsl>+9A0-g;S;m%{NeBSYMgI$d-J-&IS+1MX)C4?O=~GD^W{7ukMlK4jR}8# z^ZQBR@!mS9Q}D+iAqDiwCh9$Hm9OesnkNp@jP2(TJE^y(Zh z&EMtr_xAVc^Qnli*t3$_U`6#mW=$7Ju{2#o?IT_xLpvk5UwhMn=7A4B6# zL!9SUHW?;AeAp*G0+T=g*$j3#4fvama6c_>p~qbq#Z1JVZ!XUa~7+r{h(lqitt$1@2 z{Nbr3YPFv@b~pIsw8LNlQs~WEpgu6LsR6!n<}r$*??(?j4NF$9SAW0gJyT$BM2Ow} z1T0(M=9Gxw1`R7x6hds&F7UfKixhPv|2?VFObfxA3RmCukw`}SD1waek4J25mkFbW z!vUj)!+xWN!I)t~l*SgWeORS3d-2OKWByA9F*afM;qVXBCn*iLH#fIOX-u#`eE*)O z==s#w0Vc$dGEwgN%=6J}bbDtP{9@)pcxlZ>)t;vP>g(Y0vyXvYh75!oXUv6{Hz10w z5B3;71ipC2R9LmK4X(fA2~{!4m69h;*aOZw;sBVpY!%$}==19DpMT#Jr2}`Rmdd_<`^aKgwQ-9}yQAkbpHn`ULz~-yD^z;>)U(*K ztqVFUy=vTAB%Y>S)9q=vzAZ1C?zcrE7+xu-g!<(@K*SsBq!rJ+WrCEUiX*PfjeU=Q zoGO!0d!hnX`+;o!JH6|1gXfD%TSQ0JWIN-O5uzNtsNRlm?)pcIt*C;w+T*cGS65J* z`b~@jp6M}ILnLPBA;EBja*{Zv*=9H0W{0LV4#nor(>zR>H)2``seg~n7wYpBEXoiS z{#?l~<_n%j8Cg|i)50k@__a;bKn)sVB88;4Sb7|q*&=R>&ADIMm$l0w`bufy>G^)E z)*5T;?1pW)Q4;;PS`D!ff{e!xZ(dbVh320sqakKBb+i@%(~27;eTbl-e>B86>E$EC zQjlUXO)-gp+}@gE98?Hth}odD4N|u@)WfJDt?b&||zW`=E*BvUlM*`yi&Jq3B3rs2r*4c}*ut?A|{`R>xusbbBRMuQx~ z=EU=8zO(Jk!Ckt3M#9qZJWVm$uTwGy#~W#k5idROH~0jehosH@nX?liq?n~6i))Pe zbcwRRr)Z1$NU;!f#azFR$IyMdK~U?@xf){eVjx>|po)+M5=?3;`5H?h8y}o->j4o= zNaBL?A3hdFhB3Wf$Y$hHrLO`Fbq$UNbc&`F7mfMaQp8}8)x=iXO;Yn(Akq2$jelpD z3T$#A=07{n-)PzuCmn+{ir&N}k$E(K&`WCYn(?IOSG)djJcd2!Sii_aq$b5nm^MGq zo_WZn7}G`yV};v4=(%D)zwf0gGY?pHz@VMYG6p~a>NUNgDSI*IqAim0^T zSX9Kz$S_`J(Uwea@pXotx2uuH8f&DLX8UtE*{hC=`NZs#HG)1*dYUrb)xOiBfe@`cEnQjF5{t7cMCg1$6) zUitoa!|=ha@cnz|!ZM{RC13f-2^?J4efUIZX{?7UZl4XCwst!jVu}Vp2VZ#defPej z;X}tvP>80VJiJi(*#9z}6JqmV=^Gp2z){2CpQcZShnKtxw>-H-UC;^R_ka%^aUk6K z8lFW_011XgUwq58e#|U1+Q(`0xRC!Xeyg{*zjG{gW9HS8|}8TtvG{5p33(eS~e z4-)(a?1{4I0o&mLu(7>E>Bn(pztjv<*CEP_VwDa}jrDNA$YF5gJ|kh$KBLuI_rQYX zFyonJ>cW-MgMtfAf)|MU83?U;s``K&<}+wtLQP^2!P zX>B@sV2jc`;+KzOF4Ld!J6IDz1^YeQ_TOU7V_9A9`+xqOF=mJsV4x%z&p0t#BzHK- zV%k6lMR0sDLd-lLP2tyHwtp|N_AaYA5kfNcOZ%sGKc~Rk7pcv+897$w-HsOO4KX{* z%tA>i^XwT(rWY*Lj>3J6A;j|fYiR!>kz-icDA{CWpTPc5tEQDr9!2Ja9FZp4hsFHo z?E1m`BuhWl2bcsi<3-aVh7cg;nF*v=QBbkWah{(f@-B7!NdQhcO)KlS$7kf&4%d!Y z7XcLC&$#}xo2;Vyr|Xd#V!qA(vnF}e2r`?5cm3-)62YBsXhL8uVACIR`nTy1N_V6- z1daKwvOp?tzB5cI`tO!rk&+p#A;!y()D+|6DH>vSK5_Ral=O>hyk#}5-1$T9E93n! zek4^}jK2ZdX;3<$qnnYy`QstF{^Go60_uvPdR>zl!5Zt}pB_^ZXFg4CCv>bFCxK^ z9#Y8w2!C1ndvd+X_#Xnv?#{RNO8x!f-&{g$dnUuUnK3DL?u_4LkYW#CdKE0W?XI%p zdWSyWL5Oi>4Qqz^wyE^8nnu2+m_^oTSJN$I_6wT}IL2d@6>etvU#Cw|$eQ0hz6c&e z%_yy<;=H5A3e>}>od&?ao^ljy+SUQr-~EKDG`sZlqm>5PPagU!EO>2=$*l9|Ni)S} z+|N5=JWLxuR_P`E>8~#+Z{|XU5E~Bve&3U@^vz8w6aTfdkAs$`M!5X8+0av|z@?`h z4I_sRhAVEH4T!=)`onLXcf3l7ef73ksv;0808z&a5n{6!zXJa=?|JigRWYcq!{>xW z`;yb9!XCqRg8%!_e0Xlvy25_PNv;Q;T?u#m^+k2QpAh3OLEWaWoPIP6AJPgxo%swb zdTkxtaQ<}Y>8ZdMZ+^&VMx8ZjKRD^&ePH(Dm2lg<7c$yT*xrczzz5I4$iw#B4L*Im zixA_E@yT}|3={X>9cDha0&buGVlF}qp9A*4e>!;*jNhFQVsj87CLjw$VL;Sx!3xSs zA57eH1e|#AUQw32A_{7Jwm+GFi~osaTtUvoj)Whwwul33C26P3;}+930Ho)=;WWU;G=B{K^r zK7B$62^X%!bZIE^GzTml3u_eG%2b!WrMBaRS|brH5~FRvv@rps6_;-NmBX&Kgy1PC z;5m?pF%Blr1+1kQK$1udb#TC%ICPVby4e#VT3*LrW}G zLu_bkBcOIDRfHY@03ZNKL_t(oe7-2JwIcvOh1y75xo?Afi3s9==589&$0Eiga!ex0 zQu?=#48wg4CeQj)^Ni*-9|`6c#gu;#z?VZNhCG*4sNc8=B7p%)QVw5OvJkTci)a7!Hhp`kT{kJA2_|H-cO)_UFgj+8g!}Zo5Cd8xkTT`@HeU0A!&=~WP{wddy=XVy- zhRNejb#u~$<@(tYnaBRQ?1w&5*YCeRq7H3B^0}H~{{DiGOHDCCW+5_~5J(c4XApG) znJ4!@q5X?Qe#F{44?*S@OBrQ5r)t@bqwMgDR>z7BC4XMgC~D+bSEU!)wsk{S1=mVq zN|Nipd_L76!Q|%=3D%_IfYja+8OF)3+;{!F7%3J)hULv`j09sQ5g89*Bu|l_Cy`>f ze<8o#BEu*NMKAW7qXWw}O@MhT5a~pys1Hm;io(5N z(Q9kr$1~^a_7G_gF&nowH^EhBzZ(WLH^PtZp9hQI*q}!Jg{K^$G{pY>zNcU*{;jSK z&NyseIQ7td;lF1;18=r%gD;(aG|XT52K@YC)Xu6?Lf@$SMF}y|dBR2gtVu{aNC`1S zSy^Fgx-{SB2gv9wypR9yp=WaY873IM{sFv?2Ke#)Ps8)CZ&2sQ5@L94{HS4Y!Sujd$opGz#GjV#8My)p;AR|!A$8%{|w>7_Sh9Zed0uT?zK1J|2{~1YM~dR#jgF( zG-zySfU9qRROxyhED~bZ&zPHhL0>oxHN79|<^Ml8!B<>}@!DOfV zy5!8GV9c)!ZzxU}(8Uy?BnN!BW)5~9nUn%ro9UL@z82rQZ z$x3)+=MmK{LI^RlXcq{qn@8#avyvMy zaw0nw?H%1pTMUz6TxwOs*&pNHuI-xQXznC_;^E4DF7 zEz#%@FsTiTHNUI1S+Y)8}(^ATZrnqrm~ zkv9Flh8VYR?C;t3r@vIAA;$eDPS?u_(%3jE9_yhq1~)ap?t@!Oe>j9}0-P4D*8`5*fw_vDmxm3kArrvJIVz%(MPrjhbZ*7S-*v`K%?XI60$UBy?C>7Qz^oyu&HZEvPU`Q5!5N85Ti`F`c1b%xBjB91T25q7$O&twMtNZR^j8Mf+7BDMm;zn|v$M z6qCp={9G4+qD91{nCTM%t+1GI5Nm{4M3_Z}FX0t zL|fng;MNxS`upDvElu_C;|J!!B24ZWr^Py>O^pq3>H83+H4uI`=Q((6*=lv(;MQii z^2}oalU@Jum$~r5+D&R#W04-juY~rQhwlgPIbo{1n>P=X)X&any(4GptwQ$us)n2F}rV?V?y5O=~W|>O14@^D)PCjUFnECulxaFxO z6#P<^YPP~EtGUz*g9o(06=xj_1DhM+2Y;Ch%hqfbn*m0aPXlYKRH#HKieT$X+mW(aUiA z(*hxu(?1U13lU<6!-7}dfS)3=N^61PJNB2O_8A4|AA1O_+O$PcMvmQO2;BJRCt(Fr zCI%|wF3-h!DKyyyF3NP_F*t zBe1oT!PD-*#-t#ghe)W){xDPVwI4isIDGbGLWq551}1^Y$)@3p{bT+aPExL9e3 zAwul0u;5kfhgz#iAonoq^sNscuac06!0PC!SUSeOJ~-vjz2Wpp`@;hZm#fM!q)Yt6 z=CQ@9ViPsQ7$J7)Zy6!RN&5Z@QhQE$Y!4LpIebnyrq#wxb6hi>M$G2QGCs~u zzuffUrcPnlj0S}Wx+sC&a-8=m6|V70J=)axm8(wWpGJBZZMLATSRzdSl1K_waVRu) z@@z$apo5j{+*(>Ix=v~1bz)GMX(>`{ZhuZn(e+Tfn~F%!&Z{h~rTr!HfWIe?vp;lw zOb5)@pQ;hY$VxunciJh4Z0T!cP+9ixJPk3b1Z5#~O#X#!>Tj$Gx1HZj|JA?4cHo^f zPzmXzv`huUoRLqA>|{HpS<271TzgZ$#1}sg*QW8pFW$s(GB;f5nqS#ptA?0C-0{4^ zNlM?Ah_D>ZPcEwA_Uo+lDIL_!i019?F&a#KybN+o1$Fd-TSh~S+uI`Xc>c>niuI3% zm|t<4hZKuxhB0D{G=B&oz~5V~9jYj{n{4_Wi3|&Ah;dM$xvmaI4QWw2BD`Lx(75s6 zVw$=EB)NlRl8B`==8D+*W7laxd&KR?>v#aU6hnT6G{t<4u_C0HT2F*#n6xEAjFV?( ze%Hw|v%YBh?fAM^ZTtJrCl5gucs^?XA?B}`t@Z(8KkMyZLlw=b=ks&I^Npqv_Dj#k z^GFLt&ECqRXWPsh`nYfNd9m}0k5jTtou`;$u$>ER3?}O09CnAfa6Myd4KTbjq%&=8 zYJkD5O-6G^wTsp~vD%)bNu1FP(;8x-3VA%AG`We^oBK0EoecejATmp?_x+Or2#C)TgX;^r$z>v;#@4n zdko#bhP>G4X7@9^KV+SooTRwDFatTPDArlV3iP9-n6;jxPrhnXo@}{40*T(!6Af#Poz@lV@?J7(f2< zH-Qk_d;0Nk!gW_d<4!}8Qb4HpHRqZeV8#7}x~b-M*e5;$M_qnV=A%CyH?^9t+hISW z5@J=p$XS+jJ}z=B^R*>{%I330g+%(qGY{KO1?IbYdf}$W7Q+0O-*kSywXp#(nKNad z-C^b0O>pDAPpV)(dmWhMI&hr&TYytfBl{LD8gDwF7fA&P8GQ`h)|DL&&kkR*l z;q)V5+$ctfZB)OFPUD5|IRf?_F$}hK_drjj7ru7;!}PlVFr>K=zV)FK3_^^9-)B!8 zXOc>{KE2dTN`B_u_la@x!ej;C$4!qcg!!+ou}!IO_x+Q`!AS@0ttP=6?|lMRu5B~t zoO8qhaKiY#;I=292hg^SWhjvfzF_a6g`SFM5ndVr9BA%s|{l22An;-dV8GmbO} zv1eAk>Cj=QiX`2izx@8AVbsvUaLpg*z}n62_LA!AVA#MG_}aP0!kcYdmBY8|-~n*? zA7*PUFL%I(5MtPp2kyQLTyV-H^}U!_n=yZxa?Utti{CQsps{fF5eFy)*>!i$g$-M_ zsrjanh@>rBF!q}tm}am z>pvC=M#8M5&x2cErrQv_0Zp;$TeJ9+sTyMZO(_~;SMv@ni*CrNESEQ`Poet)PjU5Mi#p}mRL}W;Rgn(qy0Bdc5x*g+hvgd>E3AI$?MB+ zZm5F+O@tc5VmC4UW;95Pk?0(3)xTHtfxvN#0E!jY(RW)-G1rz!F;0e={vkBPVq+nS z;3+wH+#(l?*tSWXoTRc2l5$aH$)8rIQ#<;v^ck_zhh(C${frHg@;LFCb8J$DgRS`* zRro#9zsAdFR?FCYF7GZoUr1U>6S^?#hiao7f3DVkQ22Sj=F{`%Vj5zqe+x}9$L7B~ z@6<}Fh)5T?m9a5suMm2kCRBKSw(GOszSuu%d2#X}d zf=u!c?U*KVQU5H92;=WF?a2K`6yei&ruHlHm(6kQH}m(0WfO`td1)Om*Z59Hh#h#& z>2Tb2S7x5^#>Fqd9p_&FhyMMC;m}WhG^6*0A9&@yS@763H&jKV_|chvgh69=cYgPk z`)9$u7ksIxzrC%FANqywIUK@r(!tKH7R4M53SUD^ZPG=BU5ta9Cs#v9 z-n_-p;;HNFg;NgQ7fwHHe--pywP73*r zh0{qx?1z7O5?*+7lbPI(-ggw7|E@!n=kwsA6>u9SxO7lRA;iu*LD9iob}MR#(cnf6 zF-|JoGH*!``H`(eqbPJ;Zy%g;*gnpEtXQ)N*0ybfJ$4yl?qkcgZur%s3t{o9_4GMi zA$IQM0}Mj!p{1`F{HhG*V*=|l(_7iJeKKi?J^ma# z_QI;LR#;3spwb8Rn!CO9dp-Bp&^uSAVSlz9&;y$q;gU0sg5iS)C7w@$g6n4w&WDAstnS`;Hn0V~6jgDtT^tBz7bz?+xYSY#(`0v@zS_F@pPnb@{B71x%HEL@lp+P1xvM}y6yVC{P229r6+k)Nze z(R@gLejc*2zdsj8O4#`zUP(-q!W5LE;7Z)K72dAqN0@Fb8WhW&&lox3R`#VLB$Cfd ztekZ>k?y84PScmwKH1uX$*~?-*HeKCqM_>qt)i&B4E^08#dPwFZ9}`FHN|2yES%J; z?mbo+TTUA(WgU^ouvASeA30W}Es=6OPeW`(OA`zm*z6>y{Qb=KwZq7<8}7?+_{ETUaZJ#GRTUQ(`qH`6wmMc-SjK~-iRN$J1-_bKF(@YoC2pDOxC z+3^}W-{}(tw6_k)T~ymQl#Ho^mWFy5*wP5CjrGvf+@SnF*{!T1 zNyq2qA?y71@ioL^HYLHrbnxc)_3_a45Ym&2;28OtZ_9q+7NzB{C^A{#CqoO@BE^)& zMWcxPt%r`T9@y4dfo+{Vg<9#@UqeW+P`k_LERkW|6+(b90!Y5AIBo&cQA{Hp|DK|0 zg~*|pra8~c5*bEFQ%!9ok}5tDjC1QnellM_(-x;7!Q?!_8d%&;QWJ~sKZFP?gA6OP z9)~o}%I;76d60{&@SU&QB&D=}!R;@RVCmXmf-c|LPg;bkl*JL%lInwH_V<2&en%t3 zijrYnZG>zYGI|ue>xzqE?DT1wISXkHpZ&$n@YH|&v~WJ-6Hd7H3fTYLGcxBteCbuN z+a9_1C^+SieHFTe zc--mL(^rAVm%avfJoBQWsLQ^{jX!YIFgWe-{bB6zp(;?%86DIGTDE3A-15{?Sl^CF zm3kATLiq3JPdO6CjT{dDao>}qA*M%pOJgHkbKW#)X>5RR-#G_XZ`xwE6R08ftq)Q{ z?DAVJnz0CFxPaKeN* zLX3a=lkYwRChfg@6d{(<_c38L=fzcU_?Qt&OKZW)Z@^DyFK~o{nN9?qx8wF71Lqw* zUPb=CfA3sazGkz&epfj8f|Dk~_|dxpQzptuGboznmzH=JAFJXr4y)Mo)i(h2Rsisw zX&9v)>d#0Sa>DqraNPJkl{TGxA;RdXmsSHN4>#!Ng~t&gh6%Bh7k>U%k3OeP{laNS z!d|-$g`Yq43_KIi5aUhFM~^)Sj^2L^JhSq3`1#C*8I7;w#*c;brjA$N`O8@gVE#%( zB4*Q4F@zY8k1@lBz_~|_gE6}dRbxcHke2kexi7%$8!>rpg?~{)?7JVQgjmsQL;E)P z+W$PNlC1nntqd=FzA1?GnxUtsqLN~r-C;`1qI*a?o?5G$<>a?W9J=th(~LA!EF4To zG3w7Gn4QP@oOTa8=2<>c$-l}Nl8Mh_T0c|CS|UkCLe#Vgl<#5WlIgLY#zAfETExj7 zLO#~^i?w|^uhJ|Voc5D%EwBd!P*|Z@PP+Ql=z0siCSnDNi%Z3W$d_!+fo< zB2BT_6;`7mmXb{1@#Q1M$^^0Sng=x0!yY@eR@K1%_$!k%E7A_*3#z$z!@IK}a;zYE zi^;Dt$u9m$A30W4BfpJ5RNeX)o6mgztGs%NRXgF8&Ja!0M$U9#mOo(4N!q9wf5jkq ztwyGyt(8H_fR-ky$I{E!o?$!rxX~=v*P-nJO$`P$*3dxoO`%uJUp2q4zRx1X>3mxh z*IS_=Ht+RK`{)OsV$1o;&?pKT@4R^;jHF5*FhL+z-p9RVQOy;oc(pm2fTA= zPNIHk5tZ3}N^G4E`NiR&YD`nC91<*hi*7_L=3m%(#A*bo@#8SfWIMU<-}%2E^8d;_ z298sh@xp9&`nH@TYG9Xdk^%bZG1E&?GSe0}W|4ViuHT=ZYaLIux_zuEhVT4p$D*r_ z9_a3783h+HD92ql^g$C~atsk+F7m6`c9UT|pBwr=qm|6X)ApUO)zah9UnCNY5n!=* zJYObR@ZV)$vOkxe+wjLk(q8pNrMas0sl0c(UcqJ=un`$nyh>AYiC-2eM#Xh`^IDOg zj71=r1ml;F3@d8iTKlvA49ogM3Xms|cxn6dd@ZpU&iEah5KB#l$Og6LF=sj3p?BVt;rVzxW@jpFd`$#5 zIVbx+Ap2Md0PFTHZD|GkuYRv(=NbvVEO&bQ?dCjCC zy5%6}3L{Q7Tbu6Fw?mb6I36((#r>Qsxg48=_Vvi!P5s@B2b~1qe#w=QY~yu|88#Sp z8Qcnp>RP>VixQ`;rh<}@E%Yvsd1_oH*a|5`8bHRC5nh_=ufoSMKqK9eWA>J=E+x7f zqS484z#IBVe?HE)x0j}s(S*?bUr0JQ5)Kv_MdOt?s>jUB6j7Dg)B`7KprEL0h*3W)W@&YEJfeObdzZ^3{N zDK=Tfm9TQYE9y^gpQv793hOxh$ry<6OFdrF~hZIZElt|GWi)o5skbyNc zeWcj#gIg3;qFsMzo%ijciuvk}TP6$oy!Dr9{d4Ugf>&u;h@yvpjTPrufzBEd)!O_y z|D6%s{P&ohg7oGh88iRsqM81(nYjdmHAYJ&NY{ny8~LF$-r}~Me_4A9=LcKy-lyh^ zVw=yC@9Ot;SPlQ4XJh!S7b@m_W%pH}zRv#L*!=e@-_7{YpU<_Sfs$X!Kc?$5$uMr0 zpr&Is8AbCkkI($$jScnC(pU!rTbiJ?sowN|UsH_xfz?)_??oHubKJl1I)M8ViI^}! zTpjJp(-h-iXRSywUt5gVIWiF>DS-qKSZv*0`eQ zXEfSu$kr6eu?Lr@AtvKZu_Q{0rc@p?LJ0YU{Q>{(Yl?;Z#+ZL6*NZd_*f28yevd4A za)ZvSIY38;_&?g>Q3wLbfyeSE>8g zP`r!%T?&@lBxT5^_z3#v03l5=i4-%)Ad>!~bp+!ZIu6E~Vr*CRI*s4&Ym6adOnYYq zIw}=tg8HfuVc2dG3D(r$+9{e=+&>rrC6Qq%NHErr#rc%9q$D!T&I>$$*krdYLZjka zmB<__MzWJVA$B%=(r%!`JKKYTLPFYXe7P$3{^P#h? zJ@>cYcG)lhIJ|_0Sdpeg(Q!A3?{ZqJu!}(5bCQISW0cC$0_38hiz_c{P0yrM`e{c+ zZ+>y|px`7g64u7enVIAbvcf$cbqWpVFI6JAbxF28jbk0r_>eIu-WrHI%XyeyK@!+kah6!n{RUk3fSYGml(5L2Mggb55db;c)f5z2{rH zFJ}g%2h{09iqQ(Rb#y^Ds>JroD}99e&&Piru}u_@2~KV?GE64Bs!e7U&)@yhNZavC zVj2fFnZx6Qi#I|xu6@iIZ`Ti7M8f@hN6-)pRfw4}TZ6_`%zxm&BOAZO&$4am--Sn-UkD7DBtx}&&F&)t6>d75EGnlM=o`FxEDTBBUegzebTi!MJOsAVQ(U-L74 z{-Uo)uN?O;n1i8qeaZS~lq91wIGBTTbsJLObXQF9UnCB7Tc^z$>$R-kzPSmkVE^uF=(oNU|~_i)Z^aGaFCJz zY;1jbs{f1WAZSM_y7@b~lDir^wK@D?b+CQ?_BL%%geeRi=MNX`urnRn_di9_#13F~ zM+(Q!j&MR#0~ozAq)xXqT(PUO9ZIe9shVPPAF01uCdpJ1rw-8vB4}G+%VMZ%+A_R9 zOaCSrf5A_Mkp20ZRX--dv+zvdxV*3;J=cIq<`}gUi ziIQWbX%%&x0V%pSZ|hd*CEkCa1{i){oem9oGl#n8qi z5cOY8%dWpHX8VXMRSc$!QHrM5Q2W+8ubE^S7Es&i*dW8~e3aD)lbT_S1mp9`AGZU5 zZCVEyS!R)8*e)p=VuZM&al=J%>Ng9JU`3i?793Ef7u$1-G~SB*BSxBX|5e@CLxzQr zVs?JcYVj8P)9-K%u~;(frQ7a;hc3M;`AHMn>uWG_>g4EWkWR62ry;rDiOH}TANw4v zef|YF^+(skz5n#i(hxiNqVE#&LsxtlF@%BpcSbB} zgaKAuV`Yr0C;(_MHvgU8G2?GD-JXrd@pA@QWf3wlq>Lyn5Ofs9?KMCtN9GZJIw!g}<7A!nR+b z<0s!NEeOEoZCxtB>ffJ#{eHWIxc2jqFgTy4>UeCg^Qs8}<-zJho6}^+KyC>2W=f=^%Mizt7# z(lV|MfCyPa%JO^{vn?W?k+n6wYvjE7eYOR2fxj-7dA{t=nfbUx)ks%&1=@RhVM}K> zY^wAcVQWQ;qStL)r_H9?(-6xd#jNy7mN~(&zi=$bdrw7TSe`!{LyA?S zvE(EFd}P?*rg|7XWPqbhD#vHMU)1g&7k3+GuE@?~F~71*Klc3%zkPk=X-fO6bwp3( zCfU$e2R(K4cmKVbb&7+Y6im$Szue*WZjtjr2u{y-FjWgvT>rxmPdUQNaYB4b)Cl86|Ynp{@ z+RtY-#ki;m`#T<|@z2l4+9@+vtcXL=(D~Ic0h=}1IorrKzGDm%rC8d#D$#Wikzj}b z<9^7te9zOgG6*n^x9IqVM23~ow30|Liwu*9u&hR}s{tvBJk_%2t|z{xm1R^QKRKjv z7N6I$nyx8Gu)Oxb>y3?nd=A#XrzBwr3C0L8|2<`1kw`GB=|%U6NU+AhyVMNJ+m|uY z*F}bTesV4ntcz%;uYumRTutmEBeMFd7(v;_qyt-SHL=!>fP|~WJHtp!H zz~;^_MW6XrzGC;AqA$Yp1Sik@P>!7^iYnjV$~*4g-zq{vyGT4=qlzmFEzMgji55z7 zxir6)zBnIQQQQ5Od7L(j+1Q0hwMc#^=S&&fgz z^E+cpeI1P5X@H{-n$Uftr|@{=Vd2{$WLQyu-X7~?3@H{uhWSabTn*h!G*&lNQE70= zMt6{5nue;DB$w0x;Y;z6VkIxpIlY?oFJ9|hw#Ve1AGxc-4Pt<`yOsvp0X~a*V@Rji z+R{iU3r$NIy|kR_omf)K*BHy}FZIMBlS;H)Ynn-&3N2$x^kHfL$6;nSgBjXLC2f=jk-F4N`NFm7+Bi{e$=0dEJTj;}${W?_a|G%ALSue^&pF5dFmF zX)1E0A|;|yEcXf}#mamGYl@k*$?H&CyL({^YK(W1#&`%RX0^irx&#s_FBuj}?yI7D zf#}Nbe{{tmL|AP4Olg<0NVHcKWoUXAOu5TY29sSaRzOr8g#Z#U8%&Dp+#cU4`HAb~@qE zi@s|(ppk=_Ik!nOijZSe8Dnj!QDrN5=s0(J>nv`^N=$EYHko~Oz1hlVGl^*q<~pr0 zpgyNLxp9R1mBT5O#KvjyoMH~X7$;f(4qu=8oW9-|;w|s*wjzw56I0QawGD->;nZgB zAIq_=Ih6T&&1RM>SZuJDIkB-hR7IHJ*p)Uq{C*{CN@Xjzx77f#@O{f^PK!~@_BpJ5 z&6kkvS6n3}!4eU9#-Zc$IUwrWSm~&>u`pTI&}X^OeH+h{TSC)=}H${{zcIh;vW+Dbx7-+%CG`5vP zptTMS;!h(gLN=`pcDIQYbciYlc0NX3#6Cz#df|DN z-h@6Ev-2uaV;W*oQ;ccvEOLox@tETsuRq1c@8Qj@2?}ec$#-5k$;ld3zHK!PxPh}8 zn>MInHMsD5d=C8D`)j-+Ev6Y3s(cMyFVk;vrF^PJ7>^e|Kcs18=Vy&v(&NqqbA{#s zRd%}?2vmtIXeYJJn-M-v4u=sNErQh4blms>Mnlu(Yozj{YG(NAF!# zs`7eL53sef2ex)spbZgZy}gd6nA!|#1TxPk<&a{jNU$Q!-E^dwK}c&PX~^E*nqlad zvwtU%VM;@#uMhSd+zNx58>~jGSl_MY3n7fG-?shy<68aYB7ZZcLFj7|7TKZs68(@S z9pu5|(#CnMyU!k1$d5`NG&b1zk8M7W?d&^1V*{Aa_f)F2DX67_Tk89St*>8df-tiP zYlOsX$vndC#QU#mZL7IV?NwwGG8h0QppE|!vvVr8)#pneuYsl?xE@ z7k2Qd{j5e3^-B)=+x}>fN*OxKxTbtjF||DIJV(tWl!CP03_)bi}riD$w;mB+TGU+O&CX)+OMA0SEzsIA;I{3Muf#|M24xP zn|4f*af9d@v+^J@Pyr{u4D*OaIHT<%$>lnesxj>b@Ut3X{{HiCL_=(QCc~staq5q+ zcamZ+-Z}%8iUe2J<~Bu*h%Zc{9rlS28(p!Di(i0S&ieS!4)JuBK4A5S8pnQe<#n8J}5lij&jtlBnm9COag`-WM}%mVmBtvWtsS$_7W( zBCC>ia>=%jD^my<(+u<3FGPVwQTrCvarvDmeJkYhCuDEd#__|+Dc+ofl2x_c*^c??7&5F#LyRl?-O4jpkUCsh znboi=(in4*Wclq_1Pn;gpve1$m_K0qW4U4)uEyc@GOv=<{6-C$XEpc2SS7!|JjsH{ zB4B&X7iGVoX#Pk&?k4M9&i8c9Ho7kV{18IP%wJv-iZ^w3y`*9!P9oammo1u5MN=v` z9A+I0HTO0|jUoECy8_+F8I|}-)ey7yN3nIR#Kf1HXLW8kh5*ZIh|%ZxykjNqb6q7V|{87@!%-cG7qa}lASaMRws|n!mD4Gt7j^}ou z!2HZY_S}5N)?eh?tma}{m}V^BwyH1L8O`1+jii_z3u`fScdth-M}4ItB(lb|2*8IU!^s9pPvW>}tv816SHK%$eFI*E(dB#Rn-WEjt9(qG1Y zz(wGEPet>!^SnGwt2|_>ouB1?&mzhCwI9U3%!y~&WC9`b1QJcgpNhg`9wMx0KN31F zHN@ocGW!vtOXMPHYJixA7&lLd$*7j+P%ZIGdq+34b@V_-57Ct~O0=w|l`2Np7-svC?fFONODo*NpQoFbS&CUmW-VqP;#m>rc*+yU)KsA;ESXKMtCA8Vtk79{^*H zo&sY}v1l^Z5!?LQ>(JHK)*qL$!+Zy7h{Y-}@+&(S`9mDjKG$-!cJ-X}f{Q*u;|eDS zovy%W(Z>G|6moNa?35FGdl!4t40venF6dXwt+i%|daE4R5qJNwS} z!ALdtda!S`cXYwFO2r^q41KNc_gsmY(qFMcvuqN6M>*d|8q1(MFP{Epwfv%*4UR-L z1T@X3?H@WB#p6mJw{$t0CWn!nOq&z2v&d8T^Pzrck-LP@_3e~-FYkL@q=BvUqyBE` z&RnFJrAtiF6f2wjEkj?G`ukjlNcBhiv%T>?hBh_A=pii*GAxQPH1n-Uat4rOF~8R$ zqr*v2_jnj-k@c73$jNHf-&!@TGPH^%=*g-Xf5H7`EeI&~mm|qDo7@r4hh*)m@{c&_ z)gSMwsK|QIQ7yc;5_uku2MC6NYW63^lH1Y!ZM7QS{5hPb1~p@HtO**M>QvH$gT1&v zmD*tb_+tcxL9hgnV=3BVocs!nZ(ma^&%dyr*Yi;+Bv@G~x$Jxv+=taQKyM#za2e?z z*VJWAF`hTs#&_u__=q8^K}Jj>AsfdL#~ZBXJu?^4I16ctF_J9gXZZ75%)ckCW`XDw zOe6+rsgH-56)Ykz?vG}f6eKdtGFzlGRfG|a>HQ?h|I3NT`PyQLY>MxnEi;aduTX!G zHjQuEKQU6wGOySq8MZUWbNGCP=n^@Fn1&dSQHdxs$W=a=0IidnVs!#B*3(mg_Rb1y z>gZA%s+j*KkzkBuHX3b#cK5$0gaq@o!Sdq6F0#=wL18>DwmwQ^7*fxWR&bWl3!AYB zM8Qd~(0eKpOvM?wcur^}#_n4p!wdpUuM2ETWLRGNasM~{4>eo`vQHw#d?Xkq$C$c@ zwZjaRkD%_!^S?7iG=>R-i;?n>U}YQusTmgIUDXKi9Ifag?dZ2XWg;e`j=B6|7&&!v z&<|Mj-@k*We)zL~OGKS_$4#*FgmLD#n3D0t>#l_T&N)4E4V(-^vfTT=F_Um^J{r7+~0k=*HDrn zJ`075YwUH^zOL|hWwDe=%~bOnayCwwe{q&>Qv3 zwR;m$F0Eh5n2QWk&cbmgoyHn6!#QA2WD?KgTD?77Q87(QeG^i+Cb!!Ps#pM%_YdBST&z#jWK-37t09X zJI+O0I*>i4qG??N8%7ixexMD z4Y2g~yQ`URoX?#5r(eUcgAOo%d*g|x;m(g=08{?;Gcf7G&pPMgv6)}`2DGhuT_wYY z>@ixM`%ZcxLd;ZP@visHaAT`$%oD|F*nCoWbwBP%Y$m6a-4qG@u-2`Z~; z;a19oG*i$?b~RM8nk{+AF%t~-f}FviGPfUB5|u&La8f`oR_6Q7we|AA4*8AOsDg>aFLuvoKH9j zD{ZdSwTrE*DTc>s{vc-wod(OXPxqZ_GpDoF^03G;y5M@~sbGaz4|H^O3k^I?{9y!L zvvx0_fV7~Y^z2x&i~FZvnOS5fRS1U0g&rqTLrf+23pB$N4TPY>2-(@fJd13h&7*5$ zhfw{|>;U4nyB?)iV#eCNKmQ)n6yx=c+BdFw7DgJ_^(0keEL7pj<4bKo0yKs4xZEW3 z3S*P5?)CR)`=uh~edIhLeszT-Z|->=6}GHcCk>UbCW@<(V&^ZHv)!%Svq2((To3pg zCO{xU+|GKzw1mvb@7roVrSVa;zLcA%Me^5-N8Mk2TNJ^VV1_`B^YfAYnJZb@FU_lL z4QVXJkh)yV5YkX#O%*~Wli$Vj<>ts zm5@ensAAa8zj4i7Tu1!**tawDajF&;?{8Ai$MZ~~F*6kyA`h=-F@_8i`xiAI(--pd z;tKb&cBnF*+gI(BG{ZpyR;Be-GB#GLRr)Hx$I^OzTf)&SsSm% zBGKvk?7pU#v~qa=qqK9xeu(XycV@C+q(fQTtV_&@!RwS~D;lyofWa+|@TpVA!#VHX z4@L|f5De=qe|-9gw zJfhE68z4Umn$>*acnkZ>(hmD?v@haUrg+ZKud8Z7F<<8w;cZWCu{?j-BFtz%@2}r> zoVd&hCmb>wuKCoFPG36nio0P$TbEhbxgUh)^U=cw!2ewN9`pH^*R;b&zx9A(HnAFQ z^)Pf`BmCp(2f-ox42RLX3{uAyzq}s)>4%R{k+c_&s#N-*p}|F1Nq^TrKa-pdAh$C6 ztQ_EndX64qNf!IX{Cnx&g^^?K{^U>JI2Cr^#g64OF1rWTZte(bFUMpy001BWNklPnQM`)E^Vm4ALRb4;s?E?4dx@kVu)hDeSKsk+C`dR@_4sEfHl?E1KKG_ zFc}|pkgH-n(GIhEaE6A`rJ{;CT9Ln}X^Lev#5BD=?~_IGLu|fy+b6{Se%}2i*@elm zBR~HcnDB{@1f7#No|p%7uDP*l8pRN0VkjZ@%Kfuo;V*7hREl^_Cti1jqEMWB&5f|& zmp8wY@?miB#ou!!w6^2j$x2KPDsz%c<=vRZPh3MP?je5JMJ)31<1x;Dxydw>3Mn9v zCYj+}7D*~Tt{LR%S1rSQ*e>}nVwHBjhFHKhv0$&VvTW;>ykeKrU0r{Gq*~L85C?R< z;Z&yJs^wUwiCjlp<-57Le8DbGk{PF7C(ojGL^Ch1q5+X*f>JnHfs2B~;Y~+g<-e@N z;5E%|R&;WR{WwW$B7zMpV#mqPsOFyfo_MX8MSkg^l~;+Bha^;wHZxv)MF57~+rOK_ zHhn(~jN@loJMEtB@nty9jicvRu6eX0ojn!O7K@_A(q~9|?zTs8@{D_y)r6!o^N@D< zErzy4Xdp-pF-~qtjhdpX&6_{Uv~LXQ(f>#wJ700KjK_y>b8sP~DTen($y%MH*3KWV zFVrsOHN$+4{xZn1JPoeY_I2AkwG`Zp4re~G$Zh%_-{zo=-9)(>p-yne3#QunAXVdv zo_l`#<}Aqic{Ami`IYKWoc zqb+9I9vWiS{mNFx=Oe@1@iS^r6AWu@iMFiI?BJisw2$umV9&DapPp?QX`!1(1v{8- z(F^|JCzJ-QqY&l#Cn?7%=_FrveWCeH?VNZyaQtO+TqJj7u#Wa8=z#V?9Ts0{Em_kZ z{cQW~pT{gh?HBfMP5U1p%?Ta+TvYKK=nD6XyGk)}n7qhu& zFxJ2Mc%CL+ta7_w+Sl*dk?mLrVPpHKtFc?HKR0scR=D<)$H3GBM<&hGGoDxh|2bnJ zba!K>$s)zneqX=*q7)k(r4#ayW1;qyafYOejGSaD{`1@~+o>}CMG<14=-N1mS2!Zo z!(_+_@8vmIZ#BiTMS3*P`t!4IBR!m?$M=y*tRcq8JiK1s=lDep;pYV~?eNj?%}*ZX zG|B0g-vt}ny9Ld-J?!`2-G>i^TfSx!Vz0cp1wQi4`?-gycRc6kmz)SY4Rkd$m%Y9j z{_fikL?1`yIePIHvp>=6hht;^RkfN_{DrSzxF&))RsG-4jhYdY@t<=w$F#%4_YvBk z+;Po&VbpM&5IgO%Kf~IM9W?%Qe2$9~V#q?iI{$dLLISz|s%&hZUeSLLRUyd?IDv|K zI=gyd{kAUX>1O(EDpKcHSToEnSn@a_!>9-qUm;Kf7Xi!TlDSDDfoP7inzkWZwuveV ztl?#~(Dclr5n*O*dN%K07-_|}To3)EKKXNWo!CwW6oCG=Nb+XepZ*fp9HV&+=@F@S z0x<0%`}fkuo@AgerURW`HJ!X_8nE(#id3nQ_q_&Q`x|qFdW2K>0qY~>0}dp zR+j<^F4j=Rt$=Q1DramZ0QEo$zlcRnPz6iA1`k!n*h;Ek#ka|XvzC*s46GLS-G_8% zs^TF2?%%JZ|0AcmD5#?sH93praunz0CUhlaI#+b&XMGO-404Tu+}{>Si2SU) zuEyV~;*qYemiInYbYQ=SZGJD4RP&vb)TBNq6N@;*Ywc&%e7;mj(?eV{y(`a0(x(1K zmE5>KV&x|uXWKo_mEe4wY=dNCcY(Dnv^!AfmI?Pw&0oszqVC6)slLsB@2__b%BIrN z$>ORM_sAl7`*(fhO>?MHK2(Gfy6!Dq6{R7$v8w`=N^i(b7VdN^a?I7BD1!{+BvKg- zu^3XU7A>(|TN`1-pjK7sjq4x#%e)TqJmK3?!Veh;rVc73ty zHS+@pad|$-u}RZa@6W{foCNcahirAdef26?#>dfb=3stL9UW)e`qRX`kZc;B_Ch|E}=E&m9Ll4~{3-L&235Z?wUee)brw-`rs}iUOKqCTN<#L}Du4b@8S2 zM+|}?C(^_8heqREAj4AP8K%f37+!FhFM_qE2ANG48Dp9-{X+W}z8%sOLsnd0TdatY z0yWBgjWJ4sxf)_I+kT$b3A95*tn(JY&Y`!4@8LF z^0iaV=P@Dn;cwl?Iau|6{XZN7#~wT?(@M{&>}?FlzWf(>Cw>%H6Q8tkz_GDWk!;~My#XD8> z2OkOMBd8@pI=FAuML#qS+$_D14C?{_O#4cWu-vexDC$-+EL9-EWE_P31NqL#unCJ4 zo{>5C?(;8DNHBbjK57yr!cLi{{=-BVzy5gU$E!xBC0*eEqmvH4=zGbP0ep!?l?2>L z9r`*^0T@H7I2r4JKr8>g2{yh}Z6+!L3kScxCQgnyi=XjYJ(BPKzK_&Ge0g8qH3*neEnze&``s~gwMlK?5981O9Si|>boW4eXE$^uX^X{KntfzgwaK$kP=v3$KaqEtF;k+l zxEf6$e|@RWww3%`xlfyLQ)-!;iCEKdU=Z$0eK-!1!Hh#XV@byc9VH=7*ukz%+kSXxA?==L?l_!?q=H$F&+2HU5_ zjuf*Pzh57ZYg@6O5gSKzHN#sPVdUV}vdvfid@m^MyXzs~Raxy6+rBjra|BECW3)7G zut6fj7$FvWH?vm(a;$7amn(`$*Yfa@9nvm)jn4T+(|lkbRjmG5ChQZ&G8D~krmyMw zE>tW~G#~rNx2J!XvM;fH(nX4;KHuhsdbs_H_rgA-c5*(lM(t^}?#tfC z35R77Vy9hp7i`?x?Ig8g$i~*D2AH`2E{3mnTXzMXd2y||42%~%aQ&Ik(v0Ps^t$TT zPr|HcR;xJq*3OEh(G2)~xyc0GFHlpgzCk0wM3I(icZn2Jwk@{deY=!H@Ylzb^-m(b zLvwf@bH$&ojw8fUpQVp9XKk(2&-+L*v}<`OB$1~rrjm8Nq%XE%Yj-Z4E7KxkvWeq0 zhW;<7c-dTYZ?P7aj|`Ld+aE|URji!Yh`z>ELoYz39su8Q+{KV#u_6zd)Z*)q8g5e4 zjW1Cm@nq5_qz%SMF#p{or9_b}et)${FkUMXn=yJ?3@PR((d2W$FUw=jO7%ndqGIu- zw|znk(O@Th=SmnjdUx{xWU>nrRL5R^5$t!)>A?qt$g+7q{HaN5`6uD`AM@3V9NjQJ zhv^d04rz$t-+S7&sKncn+wM}=@#r--*4m$TsLvntZ{IPRDp)znuwp_YAf1ZUY+)NG z=WHcdOei*mi$AU*#;|RgRA@4@oUajDn?N!xRtat%Mwv|yYk+aqNK}^cCOS`(2R#?! zgr-V$duU)h>LzA@5myS&#E=dsa<(zelv@@#`h;OEE)1*Vg*$T>erRfMdI9XCl= zo&3tRwR4Bgr20N#OXM1g6Zv-e>*eGaBL>rLMqXfY4OjnArI)Py!g1hhq8OSDfmr0{ z$Vpn?4j~(ja5EB@}C1Sm+8>3i`GYi&Nu9Y6LN7yID7oWF zM!Hr1&I852zO-aoeh|8R(SRE!@i&$3CedoR(GbjPyitWJ1B_YwAZxSWcdF)LE$1=f zllxatGg4@%sCmWF(6sXh&2!b*Vg6$qBudZ_6R~slf6V3hUtcz;Qp5Q%WLO9(7AvZf z$Pl&O>+8XJh39#T+@>m@&Dfz?XKWA-8FY6;$tcGG7d5qV$rK?BLDsJjV zA{tl0bgCv{cz~)Pu%=NYWSF%viN-;GPM*c=LTz55 zxvR8%tF?2J42-W5nr*6m6KtW8$d&Hg-qqUtIZl$HO+k0+3BHX-4D*V{w#4jOklvzY<&`v%Em_f0A7 zkcSjYNj3X%7HQ{e?&{>3*_T)iG4uiDWdwbiZItvCw-85-YzS>)(xScLlAY85fMW z)yNvssLf|i329p0ah018JN+wvRvKd1e`6ZR)L%(^Thc1V0=1Y{LPW4)#8USX))+IN z7qo}8-N_p3 zXk$N>%K7dGT{1zKoC@aHTEgFv5mpW?qE$ClK`E3Igc2HJHnv?tL(HQ)p@lYg3dr)X!>ep&rbmW*=x1)pz&R&i$~wY>>hWi=9FHYLRvfkjCz(}y%dtXvkwO;XwZ zs5Rj1w|h^(y)#CJnYPS9irMR>`$&1^RsOLPz)7(rIwDTuDCZCR3;?+T7Kz@a{K%+N(d2V|kT=X1sYCZPjW{q<5R@G%2&m zIUD@7v=XTu%-ns!3X*@i+1`!~EsNpAX8~^6o;Fy;76O6h-;SVbkxd zzs8m1oJ6U<71KZI`_r-UgH_{*9HZnIQbE&igfzsmnqhPvzshQg+5S)8AZ-p#a1uC< z6tg|b*ASETfQCBQbLW97ZNPN7Zc;0y*e*^BZiBK+2S+g-6U^5!9#ylZ*}v6s&sKDz zmK|KNgmXXVzgKHJ!5kgDHpPK4TL-t*edwY#4&wMW{@n!0bx^We+Yh=kn>qizl&vem zS#y^(f+$#~=&p^Xheg_v#z(p1a{b6uFb6gKY_NxF#H>H8KJVK?C75X%!y2PmP0XVC z%sIis4=FfiLsYhQ4?F#Xs~08B_@`{RHOe`qGAOV?5K!AqJjl% z^!j*@SMPiO-+b7ppCclN&f)Ts9-zxBM`y?1wZcIM1E=lj0aLK_^u>o74k;0Lew z@o68!ike1gE6t+)w^cz}$H?t|&9C(YGt?^PP3{HQ=#tey|97b?XE_ z+<8OTY{P!gt#cKO{rwA2yBd2;{D&7Qo3o4u(AI|IzFFUBTXhUxbZl$N%5UQuVJH)EJHA*(%!O?M4KYlJIS4W8FKjs`uDM&+O8DVU8|da(wYmu&d}%Ihv0*>h ze1m?X?;gJUMtc9sx+b{qxetUr`}39X$~z0J2hg)?73{kCAQ(2dHw;^+H#9dFVCLNA z@b;W#Fm2XiKwpC96T#lfpn+73zQc&MVB~szV57mkVDK8r@6R5JE?J?A1M|=3Cxv;!ez7L{}RJYuGqkiz64f|{R{m)mz3p3|inqsK)H+s}S z@w-C@_Y!04yd|q))@Lh3o2(K^Ms~Zc0BIUxqRrKMuxGbw*kg-LC37vSxW zmcxv>%iy*57C~bplKvW)mkn*X)Bu?1E)w7`lcPf;}f?rX(f{@@(zdwnC^#cgZya|#T?{+ilmn-S{pwcSo3?1)AXS(B8elxLdY-z z`pWTwBn)K(aDT%^hS87uG{SJ+HQ^!!+Mxcg)|+WaF&$SHMZ2a$WihiEMz&-(DyBW% zbH3FOD@7}2e8=IF{|!^l9VZZ8sN=Qc#b?7hdydv;wbZPFnRnj{Z`^v9_?s_rmiIC- z8TRx^=LiZ!{Jv?o++`)iFcCKU!3hEthS#*~_+Ja{vDYrY5oY}5-n>8el|FvsvExNh z(;!c54K56dV#NVfhBmj6t>{=3XESl_A_s3}IaYkjMWSnSVM%upnY2yixIB;SjIGOA z96C=`cF>|zFB(m$ltB#nNl-&s1^sukXpzCpm`T>hP3uDuweK)gpQg4WjLv-;JdQ1a>a1mQ-4z0J6hw-wh0MFL3px56_BC*8i7PeBy@UF zJFF~wYay2i(G=KH2RE8!s>8DmZdZncDv>=woy=Zk1a0l-6t7XGIjTv^E$xA)@GM9g z1%-sr!DWVwNYe=8bPNHcqg&aQ)X1?lbc_a%Ut`C+pS>@kML2IBw}MUwnW)l|(RkAD z$^L4Pmt>RXL}*JDVYFXrT*>zf1BELanqYMkI`35BW^Y5t*suQI!|zM!G=K=%dhcq8GQdLzX#@g+99vX4LkP|WU46lSu`~9@aN`rtii_JV*A7Txas03q`{EB9h zf{E>Er#zKAzY)7YZCJPV*Q}TF^$;Pnq=~NgV(Q~htWWD?k})kC(YFUTuC(Ymq}9CLLkT_ znZj`^1iEXR;=VLy51c;)5{CK1bf0E?&bMEzn;9iSGf11-*R?6hMg9MavN1_kUe*Sf zRHLMrn>6#;r2S$l|1k+?f{lECh$ zWQFO^O2bHxFRg8G)NVuJg2Qa>c|32~$_BXkl$~M3x_$L`UiYu*@Z_{lbljk#vJ4)% zbPRN=G!%DN-8&7Qe(O_#$V5bCb$JE+`_lcOOEs1!NFC50T=68-)HcDys}2&32l&B6 zz-9Nm0oR|f1FY4jTOzK63A1s3djn?7U81XL={@RJT?MBfvKj2XrAcn_FTne~F+IMaMpFeQ%~Y~X*|_c(#eP~tOs-da8e#`r^cXB( z)vWJ}9A2NFJg84sxc`#9brVVru}N^^zQf_@eK$^xB|h@XT)67q>B|3TgPleUfC~=W z68iP>Yvp}7zXpE!`JHfAhvZYtAj4tHAbCfJn+IC9X%ue^QO~xgl#uoOW)5$e|im`dGm8U@9n+SVEE->TR@L4INBsX znEd(M)3f1^PrRoYLGV3sHN+4hws=*8=4->}wew~J;ljhWfd0K~I#l|V59ZatnYX?t|3{xfJVZQ4pL>q0h{AC`WEhQq1 zG{Ok+725Ll^{sOf{V0lZN%elcAn`Mi6d4A00+#7aNihgt7b&LWEdT2WG13tGbmA0v z?!3zcT5HIjyNJY?OQXmWXIqawF-W7BHfwx3X$m}d?q%YT9WOi+I`!%SPn~=&^xtGC zRQK#*Q7)Asi%JBNWP9H>w87ETSS*%UfUM_ti(ZCQgz^%N?69foxm>2sD z`1jFwxRrbI@5S=46{Go*eK)>urL$M&<=k zv&nKD?jnuj#t+$z(wH?m3K=bLj`?4_vOJ}DNhIBKB-w=@y#N3p07*naRP){OBUhuQ z9qc#?F0#zBV~fMoarCpUciOINkMWZeKiEP3v9&Js&-boQ93`{p?_?7a%wGu~s*tz; zPFIjeYBg5&ocp}*n1PnW|Fu6#PPhjs5%4liE!1E|7`jQSvL;tT(s z2Pf_`0!}_~r2hNl8K1*t|9D*?&q1KEu0Lrf>#84n?PIv%fwweW=;j-)0XLkuqdsQF zoF#D9A6^pspJ55Hr8V{9d;9hX>nS2y?5OJ|Su8I-yLE!w&)7AghvsX_$6lQa*WLe? z9$rRm&>wDQ39-kgehi2h>f>AkCd5{(B4nJ+Y(q(a5S5kd|G3x1#{+NDfYXC{#y3+0 zMB}wvv|?+B;qUX+lg~d3b;FQ`*vfjNA%+h&v>qAQH<=JS?23tS!hR#75@OffJ6&Ab z5qk`UlMgceGIYI|ME%8WufVL&SC~WE00#E!3U~ctSLoBjpG@Q5H-G7BIO&GxVR218 z9J15;aL!>{=-qF=zZg!r=|x$jt^Bj@U8>;mtM-FRg#Q8vy1xT|^#n9x_7eb3``$=6 zVy~f5Z~E^Z{xAIX>DjtHT@A4@zj^|etZdNxkKAi0oO*CXyVNwmnZJ7l-uslbi@G9S zY#4Qs&Osa$5PLrNzpy`wqH`=}YipCt08SAZzJWFMO|W8h3m}MrBgM@7*anEY%;KVQ zkzrJQkBA|mOU5*LWA4X|SH^0Cg}$2*YP3J^dKHse1_2f~@A2cYsDsw;`WhmTV5Av_ z%sMeeW9I&3(HMQu5B(xPu0~s$jn^gKYOHHh*XfHBW%<#e{dC_tj{S8>h~bSP8tjdm z?u40ty$?`3Y}C<*!gtO%!Ftx1ID7f>8w8CZ9ph3h`Z@i^x z8z+!p_`#%D-{C`H&~{rvzv06yy2VK+p96CzJ^w}ayD#LohL0UDUM?}nYR+PAlMrFJ z@>Ns}GP*2o8*WD za`GtytT4g~0$v$m*{ZUUCYP8>Lu{w4N>`()Bik!!tBN~S*+#S^rlJ%8{SH%Es_0*k z=0!^M@B&<~9io-eQ>nTSJz%T$B~o%RnTsfcoO|`;tj=?7UvOAgVp8Rwa;`K|Bhn5A z&*=Fx%@=VU%&vfPKrD{6r3z*D?_@jsO|XU0X^M(TiD0v08;r(FRH!LBE(!^z#)tU@s5(SCCKXR6JRVlFblzFt-V?cog1s?bT>?}pu$Ln`TZ zBTXz?U! zV7vY9r0>G+TMX8I`s1&E4Cnmmm5lL2w*OP(#t6DN`uz5x|G=G3zX$8B(G4CScYyx; zin>Pl(G^b$W*l6v9kKhyaP;1rSh1YXm(;-#*G<$2F-)o*&ZrT8|L9Ek*9#wr^&Cft z(U%~#+{-iPi&(&JTMULBh8v^}9&_$pufXf?Eff@XNb7k1;akE!Tdk|F;rX}c!PBpQ zB2Xl#d9}xugRLYRp8p!2UkS5hAd%|DO+f65M z@$Y|p{9SnG)8(+<8r@;PZP$gZH(pcshnaJi!3oz-v5;1m9lZ_g{++e;F>@BIf_tBR zA7+161KVu828`KZJy>r|^FAQD>*Bj#hi;uK;jt_CgKAaGf_@HaoGq!Thf35EZ)<}C zwp|A-oEDR3sksf0I9e=iZtp=psjNHW0>azn(r9 z``}NmoCF`us}b$*(-2#_szLZ$Lk9MMe_XJK)h>5Uco$}Vyc~wC)dTk5Ze7@BlQr~r zzddIu9CPgyo$R3g;nNT!O)>1^S~HSpmX-fXNbx)j1!>x18X2aTXDrQj#T3!d(gF<) z1z1woB-&Iae^}g6#a}|}Rld%0HNs;2J&Z3_DUC20=QB)J6i?wuF=~8DVr!Z{6{sW| zkzz!5$k+2Be@xy-nTmtT^&`D^Cf=)xoU|sdjnpT^mPX=dXxxRg!9qwdYEPd=7}o?# z*9hafI4a<(X*g406@jYxIL)xEnvyt8F&$S^*Guo4(G)Yt`A|ILe_lfj(O|odzr@lG zTmH^$c;$*4b@B@LueIHlmQ(S;0~28OgO6!M7a_a`I>#-2ceYMsVFGQlqYj0U#~db5 zUn|~yUu%N-G{m$6qLOArulR*zs=lBf+2qV?6EOGCPv_MP6P)fG8AQPeRe_@`T-6Vn zV5hkPmr^%NVcPO^K-S;Uu`G)D|=|Wk>8t>1( z_c>3n!`6(@EGYW2HBw3aMQgmM;2PO7IH}H8iyzZp?c}z0%JthM_w(cy-EQXmk&)DL z&oAxB)BbPsx3Br$5K@d{o8tWtG$~1%%$WAa?nQKMzT_gWeC0uVx-Lp)xwe?c#XKUD zYQ_#%a<{)Vli%R_cOhiA4|y!-PvhTlDNr$+C;l5HsVm z5w@rC$kh-V(5(~n?Sh1f_{riP$oCXt+tbflxwr% zvydhUM~a!*B|Yh$cYJf74)>SE(^bhX5*Zb@!y3eE2VyU}kL6siSl&}sck?2}GDMh_ z!Q}g$u(V6>96eP$+w3u+27IvyZfnk;rf5ikVp%q8RJJ#0{r=`-C&zx zCW-Lqt8?JIKTj3wjfXDY7lsb%rMvryH&2F-=B*U-$#o~}1mD@n1lj4J!>@W87Okik ztJ&Mm7!AYL?yb*1{F;fdVA*P6bA%Y$sCjnPeQ)YxG01-VnY+P;1A6Me-S+5Axc>#I zE4BIh{o%%w4dvl8(?5eN{`rPAypCG0AKY~6&iZ^r_59*?sjKE9#Kbt*+6H$%{tird zbuQF4gmuGm0~egd4~`GAs8)Kou7;TQC)E#;W*ZHMv~H#w%hD8c{b~GuqGcpMHO)rH zX1C4PhRcrG#v1y@T=W>MsB6{^YuG;q7}T#T{Oi{?W#VC1Ow!*spidWg;L?4x{rTcL z`0?cvt>3%pw4Gqz%==>9kwA!D_&6+HE|H73jonEn0w~pNjwq?n}6Rv+A zrhmA^YTq;?lyt>&LYiXK9}ww1DTwPWUO>$rp{TaWHM$jycFdk3V1Gsn}b?c|bkE1(r;J|M+#M;|} zk>_KgYMZgg!|wyVS`}urW^6m%XSpLE99}1FR!ml*N=*8DN+o8Q)&L?cpd4EY7HbVHLI~v(?u3a*qQp<{L zqbVWZw@|V!RN0~b?z|uLUdQZ5=aF-Ahit4=qe>+_UR18B_T}^%UKo8+Do#8fbavf} zeY1G7E5{R+cwxq)JV}a<`hJsibKBJf zRe5D)9-0J`%n?x}QAI%S2lh97Zuk+%J7Jst9O~~e{ZncV5K_AI+t9pc{hg3iG(UQf zRy5DKNCe)&i)(K~GbY_!=Yh1}$)R!Oj)R6?nlvnoCXYLxN{tKu z`%aFfK~BrR7|kCW`5mp@s*vMavsDxUA;KIHkV zm^9AC(3Ql@pIjqWKObGpVvw$~$cpT6kx~ZxU7*m|MxMJxSva56x3ofiO92{MTA{9` z05RHOq#+#h-h?WLv)Z|D*J>EhwK_gxneD4)$iTO0eLdZw=?}XeHj2R+1EXN-o;(}|Q#k}YIe#q|)ok#m~Z7JEF zwxxBDsNE>;dHXbDW7}68M@6EleYw9CVis|kK@9Us$Mj=LrfDRrO0H4=@FmSc$+Ym_ zWpL5#m$pf^NxR+ts0tE4ec6Gqc7LP2g-M+o9-W~XONc4P=U3b{b~J3i$p9VCdE$*v z;G93cBH{^W9ykh49J8t3cgw$Lz~7&n1xQu+$ff%WZ7}TTpD(S0brs6&>U*cbq_;kU z?p>?kp^NvEi3R}pVBShN>88m-TMUaVU4+=Fw>}R@^{D5M);2hPzY*}0-G}MlN1dP2tD88v3~tZhQ_toWC-mG4_YCyIM)PBd>i1P`_%_`u!}*MEsGv9)Ab^ z@$76daar@NVo))}lF4-|A;t81))SY=^Sp!OQkoVj#jzCg53c`O+T=PAw?02QG>;UR zrWnSjcG+|QTz=ekR@@H}Vk>H!#e9v+4XnnZ;%~C)fe!551@6DZB)mvNjQs6^y*tAL zm+q^-UnaybVJ5%0b5%J^y7oYsM+ATu-kuNV-!(NsgTK?J17Q4#Mo(|jo1eiYe|ba1 z+0Hy|6ztt~*elhe@{mFL)f9TUxE_AG&rg zIDGew^l`I3T>M1Wz^3zJ`D<2Fkh4EG}vj1XY%RwvhVkqt3#X=(yLl|df)AJyLsGOUBtgHmX| z^B{TM_1^zHLhQi5-v+N-expb_A+~5u_FC;+nMJ%@tY_K2 zAiW55IeF?tVI2)>A_H$KCur=a;0+Zz5)A{dI4Tt~$=qcM=X;8%08f(9;4bLvM37Z} zyU`GFTcWt06hex*L6(@H3nI!yOqdlKs6u~6T47&jsB)Q(YWMyEh@_cJjsdiB8xe3= zS*nt17**93EP11}birArCC+0?RKa9S(xN?8(n}6$w%y^L>>Daz& zOcyZh*Z#W-^$%Y=e;NHZ^ekNMGoP*JoHEp|F*+*lceX+q5{FxVzU|b} z@ZFInCNyE{TsR+5UVy}Y^7zp9kxR!2S~dD0t>Nzt% zk9z`YY9&&K)-#9fus)oA@Mikj9({E#-1y*I!oK>r9bnsy4W;7y^Hz!^fcsgaS7(bh z@q$0T3a`GqAb}7=r11|feG=*zGAtHYsh^z~^?7D7fV zRI2&RZ*!W@V#a5_Zt`h}jk)kKSh3n@h;e@!e~-VHehslKgc$1J$?;~ykUntdS-a}T ziyC2wM07vcUWoFd&%2*2hvTlDEWYNtlXiq1H#L3csH>la_mPrNXi%zANYm7sB6E!( zE(3VvvV8=_BYrR$anOZN!m`>1*nNw&;fmu7rR41s-i1Ft`JO039KK#}_|q@VwPVui zJWN`t^`!1UPP~N2oBlm+Ul`C={w{vTT=+OFSn}zjOHn-vMdsDLfvLU|F9uEl?3}3>58&qOGz+Bvwqi%G7u#98dqT{!hkcDWVW&!X~a{+V8W~!b;NyDqBxVuAN!27)NiyCp}D-q0@-{7n5aa zwye~a&j%}%HI0l2XCaIE{+R@nIQd(+H5|#7WS^b;(5#MTrO^}nl1QnqHZfB{T zMisTKLYP*Jdjg@wY%v}>Hfhw*(u2ihU5e%`+gGro`?LC9Zl{jV&UmdWwCFzD+MuDS z1!@|wLXjag14z7%L@@cZ>rCadL`-p8LRro8NwNa2moP&v_a1UsQWXAkot`g4h5=bQwhV=i0QWrTvy|3*YlK z7x_b39Q#@Ob0hdd$S{wFm>#FdpCjZYvk3}M<4&=52vRSR(=_hLq7a`g-$%3GZ)eYY zW(`p~8e_g##{hF}a|<*#x5CPng78UPWEi(&G$e4b&nt+1c9*J3*q}ECvCQ}yrdL)$ z8=X{kZP`j@e72E!Cis|+q;rvVG09#R(Z^{kvyx}@{b@yP2Kg_?(PC|1B8jd~v>ik4 zQlEF%2<6NtI%&`ANLTflBPGN^N()p{-Q?n+208 zxFv(lN&mv7=TFl0XO9~(mF>y?Zs?bZPL`7BuI*>6khF}ZKS-Ns@9_89)Y{4*b!Cz( zWRo@z?I+u}rS=p_F4f-W9PmR&`tNI9 zB>V!T6nyHf&-8guUv>ZtQs}ehmICZ})`M{59vkaK)n6yQ2Qxle2G^Y^^`GW1t%D=R zPl8|ka0}Rf8>5MI+;5+Qx$|qh2r=xEdz|-g**>`5Q~5wV|Cc}dj=nFE5PRS)f$;q2 z1$)7oy}RZPKaIa{Iy^b;V;DK4zl9J(#L`jMJtNjpJUJrc0V<_P{uWCy67q#oj%W+@ z3H6~Qmqw5&tR8;wo2SHeJ#fk1x-a9o`~OO6 zpa~7sLYvTx^KCg|`qYCqg`e(ekcrpaGaVj&%P zwp$l|&9ucHc>W`}_W%AP`k4=Tq}MshKlEyd{ptx=TGIdrZND!3>WHmkn!-8;+vT8( zp48fiw9~i#qx?MA7!y?Z3L!@GF515P$*V0E(hxHYA5u#mk0WFm+1TFb-z}?aggT^A zWK1C;zn%Mgh=il#s*v{2!>B=Y*pepQq|LD%Dp1!}vBfeBl<^6B10u zr{a)ce7zzNV+sr~d|(f_>bPxSB zu?@IQ#o4q?Lxi>4|1hGcN>_vzkT_)wZUZaZ)ewu*6pPagV-twDK3yWA9+dGbl1wq7 z_{-NOA%+7DqQNGgH%@4NAu?;Hi_U@#4;f<(P&{$gW6%KDdhCgbV|=3?Cc>uOe5cSH z!|&eb_t(H$+ie9eD19(I2md~3+wVaC;lp6Py+%Wy5e9}n>Ev^?7Fq65^(%bB#$&J5 zSLasBXI*yg%Ai1Hhi|b-zpaDI>JM(ErhwCuQ>8Na>D<-v!2}B4`8BN=GD$6Fh-T6( zev_5EnC#NIVhu5p#sKQi~n-e5bRC_ZOd zUzbx#NeeXnJe(@T5Hid-N%=I|@b@a(Or;;U1-*hue#s4B{$_CAYC@gLIpM zSS}49w?h>&u4Y(_hL{i8Bi>V8xn?xQ@E#K5hodoJVDw7(UeFQBPu}q`Q}Vt_LH-AY%t zee=vmv6brlisOQ`=6UG$SN&D8HmG^rseGm1agj=X+sxqUnr&H&kQ8V={X{#*i#+dJ zrhgak=QJ|jqiLm+ede%kephR5puNI|)VfsCr!2 z(KVCQay6}NJ5THVuO4eU7*Z-CT~RHf$P{|47!9!`Qp~(BRTbqhtS=QlX7;#}Y9s_= z0Q$kvez!lT_HRAAQh#-kkNIrgi`qLLcl7+{_W0QLrL2iQUO`{PTiRFX>%hwZde z-%{TM7J>@u3vx8Yiqbp|F^QzVA0ec>5BVtkKQ%sodHuOeB*o0L^xGT>mbFH6kzw3M zB-N!y+H`h5yy8ii{n-kA4L*d}q2FB}F8--Owcx?uANM%So>!x(4lnrO7Vy(OHrC&B z$}Lmir@Ie>oi>$-G_+rvy$D{u;SilzJM^lj;Fh270&Dh>h?aRv>)^=olO&zHdOjQ> zhRKS(E_g&E!{mGjupcJGez=AH?MJ81g&Q9Hk0?&M^K4sR>^~nZ0i^lM`k+48 zLhL4{K{n%~B{2537qd?H?w7q+Ce30#lnkR|b<#|AT;1PQu-(-Vqj`tk8cv5VzcWj7 z*JirF-=iX7-}PgAkKTL`Tyc!uS6qY`-o9R!D*8lmHEjR`*XRoOUt~1IK0`{uD5aE85!TTH#E1xxp%xG`tv;(?g{IyX}}2I|Me5FXhnlu z-l}A*SpKQv0V(2bYgeJB-QO>i=t%s${@!9Z`wuU}6IbmI-MdtYzfGIH2u{2CCB5F> zd#k}Pj_I#Wc;#cb;va9OG8J)(LktmOqqi6Y<4-W}K2ke=vZyw*8#Xi-;1|Dt z#d};V5{yoE=Wk*P;zff*uZZVhF<^`>lTGpy^3Qylp_Cj$9l&L)n_+cxi;OqXcPY&_ zbNxoH0NdRp^-S~RSzoso3C5F(cm*zUiTnvpzli;oBf~Zs&;zF2cmVY3M!L1~URKsM z!Omw+fDaa|(#g<}W*8>JFzH3fFWl0H{+_gDTn*P3yvRj!oze?WMUHX=Py+{jo5yCz zzRb>@^MG$P#Bw%RF^6w<)M2pY*b@?Hu*v6+gH`hu2;|m|7o82ghns2xOq|Vra00x2 z_r2m6Ol0*RK2#*Ks(N-8dSQqFTk_6qp)EG=)oJ25{0#g4{;<{969t_jQX?Yj3qL*$ zF}fd~G%MyFzslzfJ^dQV6;JP$(&{ougMiivRRmCFuC`0bX-5d810C(2G@8J~&F0w5~%OR{mLe86U@?5%{*q|dn&ZYO` zxhYJJQKbVpn+Y3{Pgq%`oJrJ*LylhI6qbX~kVD(8n4v{-jAjL|Xz_B2x0OLbC7*CB z5LVFY-zqL~O3o0sc$zJegeuV95nD`}@$0v2a?-{9k){{D&)DuVC`kRA+okB|*q=j4 zl^E>|sS#+9K`zpg_M0TKT$Gg5R!*R+8Rp}B)|zw*xg;x%l-7pQ{2&|0RgGL!2(w&T z6VCY>nd&S)@*pvg>O=%L6+$l!ffQ4D*>UHGke1=fcrS&L8nFDd4}_33NHMLUqUMJ* z%_oCoG8If&8X!e!9%LY#e8^}*a%63N*W*5SN(xXVEZMTX?L|@^dX1!pSctZe6cYTj zl3#Q`&BJjXqiKj0ouWccX&{m<-gkUY)&4Zwj4SeZvc-7i881WqFio4LLRDf?B{11} zw^`3CPy2={1=Gf*Qp|hYFVq|g%5QYAcO^~Y*lP)cbfIvF35u&Am8PR=pWTEN#Vx2m z)&g}cZGhBSvGYz^dynkjJ(s^t{ssjRLYi_(q;4#7zxd*#5Yt6krK@}W9XFrmKoTK> zN)>~V-|5=)cdZ?(i@Wk^B4<6n((Y&LNin}0#*RG5_;zVYtMOb{>?>vhLXdhjU<8wa zVl3!D4N@P1-?WQa*T?wvrih9VF)>^J^C(L6nn8(319?F2u0qqRb0@^6%MVf)o`3gL zqamf%Bed?owd=nw+6Oim&{LoD;er}CWZV;CT&Lr{vtd8@^Dj&S;GSn^!9hE20Np!R ziDEQFj5W5j!X0Br!*+_o5K&`C?zxHn-uqwp0B(D9rt|~U`}Fix2Z{9sesFHy^ZbW3 zU7{!jX>Efs+YJ#&Gx{JEiix+8G%WWBq9AayT zP5)pqoPGPtHqRfW?{smIA)hQjt45B=7%xW(5@OJ7Lr5`;7BRp8Ld*ks{2iC+hSvK! zd8Uvvq%D@EN$CI?LFT^G5IgYV$6;AblSWpNhL}j^IK{pLdv}HVFEI%*MC2WI)g*OX z84T#v$)h1QQ9a)>7`$c|xbH%9{^bA6gA4!kIzy;qJRseVzT((zVYe;T)_rE|Z7;!V z?=I3zGj#r5TMmZd>-EvcJ@nEXp*u(W|8&l-FnnFPAN|lP|Mn(ae3U_Hjr;2x@c3(= z>XLyC2K0b?F4|Ln-+w+_0w><^e8SJ@*|i#u*%y<~GMO-c>1z1DDd`$w>-O&k_g`w- z<=N@;;QT*M^@_9e;^VaSnr0wMY0or`F^&|A)fD6F30e;b1ei*e;JiY%)FdXR8yhJm z<{#&}S2eW2(%L2wtE0FZUB7Reh5Sdq50PMna(he2FiB(R7J1knu112XKl?OCL&f59 zJtdJ~0;Hg9t`YX&uXcldx08rP_w(dypTho^JtMTh$S(^a!gw-_C&ywCVOj5^yFYhz ze3XWmx_g}n@H3I z)=hW9jKAC`l3TvS86Nz>0~28G#3``!-Pt}X^8GNHVPwl7uG@d8A6goND5R=1*$64dH3#uqIHxu5|E52NHLuc+ch5I3 zNDd)V-2oivTGjxU*l$0NwDGS6EB+f>prJ+7pfMzzT%Co2a)$m!%>$}J)dZ!Jnku<( zqlgo-`ZJ9qtQgt)l|18H-tiERCt5$A#LeUMr3D2;$gw;~u&gG}YF{5xEbBWva=#C8 zo?JBfkzww0vD?@0^=D~>n*H*w6P5goj#ca@Tm4+B&AyMnw;kEO?ssz}jjOp7qLEAb zA^v2j`7JYF#LO>#KTLjGGKm{b>VA>!SnO|g^!P={O4+}pKUiOA6Z1!Xa~sqbT122T zTQkfqHXG5mn?fj?_E&F62PP4dtsIA(_iHH@`^?&Z9-HrF>Aqi3-TiwW=T-YA4h*aP z7jMtMB`hZEkW0=ZexdKIeg1L!Ix-z8=FZoYgfK`klaz?j&q~wRqT8kKDW+@WdH;&} zel_X~2m7RbN5Clujk3PxU(bI4SKT*VtV4LackfaGH=n!&WY#6@K8)_Z<$WeNX;=Lt~4ToIB&T7vY_c zms;x;7a_LC1&<_}V2q0pdvz|{@DL)z+Tf?VZw$xnYiJ^GefVv7@Wl@k-D}e!{op$r z_7{IIYXx}l)sLXIt~sG0CK6(Qcq#QU@ZOm>IEe_d);27*sL)6``52+gxH~1WNC;|LQKjd zOdNjzbgshkPJqQL>)}V^o)$=N{=uZcp`$kxXhnSgX3bj(FaKA929Di(6F6>+=`)YM z`Y~K}&vZ?@hVy)v>PmQM+&&svgGt|g&wm_NH(&{#Z0{fLvOb*sqs{ftE??CMeR^~f zc6~z&?04Z4(AZQE{xBvhaH^Vo!$DA0DWhNb_d_mu8a`jPS{HTU-+#8(FgW#lo9gfV z`^5L*)`w>bJES3oG>^|-f1qiX6%FwHOP=z!%VE38cEQj4pRa@$W-LfB&7{5n&Q4pl zCBG&!A;t0{!RR^gq*zvb5)()@tD9iS>SlcxlpLdR8j*n^H^SF0K4ej@_M>>9I*GSK z+V61$8rKlR@r~>S_Z|*C9dsCdCnk3{KJEc)JjPyuSViau>zZiKKGB1xil@+h1>(}(;|LX~{eQp~MFJFFxMuY8o z?XRKhAR~NQ_xXHyN^G(r>{lXE7Uce_2D{EX9`ak!_^ zu<^yY<`QO_BpkUyl^g_5MZ_3Z`e5k*R_1Y=XuxQ{YwP5gkIb4#X#-oTRHKTwkWGKL zw#4zPu2*yZ5<*CG087M`;RJSUl{}y%0^eq?sU2FnAWa=5(Nq#uR1}IJpVStk3Jrlw zR0uJ-U)p?2**Fsvl#_`?mk_YUbEnD~hGg;vqdgisf-aJfWgs=uT+KAyeu4e5@dx@| zI^KRhu7)1b-I-v!NJ>}8zauh|G{*4ngq)4AuEW${O zLve=t#xuo3q589V!My#OaYBpz9y^o-)*6x6KI(mJY%V}eLzC8Y%2WAUI;4}-mLg7l zY}Yi~$HDJ%@>9X8dH2lxBAt4_ovk5ekV>VkTu*Xjm-_odNE(i$AS8#;@Q|8dE;7t# z<9vga^E$Z2gpE-vfsl7%p{t%ZRr2C|h~to{?Bz&TNsA}vGa3iU{$jV4I9}m6Lr5v6 zc_rp2A#~5QD;>KyPI%M)@_c{gp61+F`-ROk!z`N>CQEdaWzBfP{orv&Yy*evv_T@q_{S&T zg&QB9A^e+>>-B+uoVQovn58xK@V!f)f~smnO_(Chi4H;x6Jm1xVeWg(wl+eHG{kWF z@6)3*{NXqq|Ry+OH7sPtq)eysk*e~vQ zS+3KGV4)n5a&1saG%E8)q6DKJInEb+%4;%?cF#WDaUYY~fKQIGY3i3Ve+Nlc0et#q!xZ@E0 zJ!kyxC73pQvGCK^>e~hWalxL@t+PZ@;yIW6`3-pHtxLk#cX)bEXiBlk8kI1jxz2d@7Y zwo9wHFKm}He>e&b-pRDfX}7#2#syr?$P}6UP?0U!p(0ZJyH7)m5MeGdERVLBrbkpA ziWhx{kYOQBF+wcUw!X0$Y8qN#S$#8*Mpz!rSZpwf3?u$mlf-e6VQ6DJ;d@6PV)&x= z5bH};B+cm%X?*AL7OoMdf*}FOp$P-g_TL9(gFNzxS^2=n*Fi zYDT17oHuov*!NBO3_WAK5#cJqP5Y86X3{VesFY*#Qlzr7BJDh=FUiupO5Q@2=!V>H z1}V~{kV21A`BhzzvXeqtQl-OWL2MX+?`FH)*AvBtj~ADqiszbm}qK@A6)g?d~TV zlVcgV*2I3gCVpO90YuVFf6_#LLhaoSO$5`vvfrn*w?rDMWVNQRBRhmdayj9X$glk4 zM{JL##k*l)ARog7Jr%N&mrb_&g<={>Of$?}wb?J7c!tcwajmrtRy8(3Q%jp(Oz(o5jEE$7suO$h={;hEi$UKaYlrn~2s|SaJ=qux416rdViyG8qQ#-DY^kNDv#_mQzkq%6%E(M@zxPR;{a?Va2&Z`{>%i$R9z zsg2Qn>L(~@4^7kL(L~7Ipw0<#ns_D=z>#_QRip{T+c(>P&e#57CIyoWLR!U!LYt`m zu4Q^PS=!3jJo8Ct{^&(Tm`@Pi2>bLSJ-e%YuaKni^ z0aCB!`Fyf)6`XYI6ruGcnJsK4i|>vY0KYqJm&8||bkh`=`rbl7>`ZleIZVFxdx_tE z@Wqed*Z+6}I#-lKr|NQnWWny}BE3`fy@0~%s&|BG$;R)m`J!CK#Ixvvz_b5);6z(SWF-LXnqa+?CNJ>P(MFHjE0qjhS-ui`0-^E zb8dnIP(Vv-G#@^ zSx^J>maYbTe+WT^e@FD$DK|e4Gv_SV^oHagUv=Deu0T*Eic0K*^4!DPrTc0 zZP2Y#75wAEJzxO4_PT}^_|Jz+VeK`#S=wfJ&XgJR;ru&a6|OV>3u%bqv7M?b;Qub( z%lhucD;nV4PnScds&d$JqcyB{d3(-MIPTi#V;-M%jEe}PooVBp9;4YSz>#5?nha@* z;rhkhPjrki3`+Xq9S0wiW2>49u)MAb>RMV;>G6HnUkZ(|JdN)n(Fh5quT8~6xrW%o z7w-=HZtJH^d}8XS@ck>E6Uk=L&jlikw8CtgeuHasKlbRSU3cq{qkUZAh& zQ5^HFhFEeovDYtOi-Z{U2Sj&GIag8?B8}p%<1c}=w%by7CO2`0Nvu)F9F~e0qmz;T zaN13G!mI}$6PjZ?UU(*K^n(N7waaf52(fSKXCu@QV_B@!O11#)oEUUdD%J>@l4nbm z$da?!Xd=0`?|0J{9eL;v?MnI5YK!?aD54fi5f!3bLnKq}NCPEnOGq+XGle+5`F+P~U5E;{0wS%9rWx6#-fEf$`aQ~};+BGi z<*Gt1Nj2_Lk6VZ(Q|N0~y6Q>TgT%|~Cqbm1O2S%|O)S|J(#S|w+9?`Eg)GsFdu9`o z6X{8GvP@|zWZC*U^zl>~D3fd^+2h)*f{@Y0`m}a186cDBa!cc#vBR2(y5dD$AGh&* z3y~JlAKWBd*053E*dnyW5LuWP*^za89(q7i`IAKA`H@Ot`UYR%%pg4oDP}bGFgT0- z2sOEc`>Ab2KFY;1AsRz=UWDTpe!K^1?2eB#PSD?d^bUDw6!~+YV7+W#g{TbnXAfe9 zki1{!Hf4Mxq_07)#%ms8I~$~z91n3^!skE(02i{B!;IW-h8@>V77wJ+P}oWQSY%S1 zwp%n!2t&RarUExeY}@VCdM(BIX+<7ky4if}DO!_KAt|!_W9<)Vx^q)xBI(aVMJIB+ zbH}F`ttG0?!Fjr|P!P$nrse|F63}*rs4FHAQO>q&bvZnH&A~!9j6TgR z1=#tQ4?%5XK_7q1&%X=1ZEiH0@YqvteI8zVcY*j`L}Vb!rb~4NOu6>^2@Ns9@F0rY zB(s87L+pY7$mtf>Ar<9t>H#C+;GH(Gqz~L1$9LnFhi1UPU;Ri``j^3GL;AsQPx-Ds zR3gM)638-QaxsVmlTM|wKthDM$S^{XNhXb?mRLw@%!d@qT7U5UmS!0FS1JBn0`aez zcnnj3L9~^_E+f~1%a7eYs!#EQKAc|zM~;8iix4v!VgLhrbxvrAA*G@yJ`-^`xtv zPovnUA*PYV6kk)td)|1Pqb-JhT1{OeEM46Ks3pshVm#hKT498U3vH?B36WufflFv) z%5@7zhT${Giesc9N5jk&w45q~jn?W0FaP$y1Z`qXT@!rw%n2}aK@GTC@*Ejf3=%9) z|M14Q2@&Wd*MjS-C=D^2iNGMka>#$=aC3&nLuu+Fhs%_VN|K z6?BC|_S{A2i@7w4@83T`>x*IXY|!>wLHD%>LeIg2#1=nz{`^CLj0Bq`7ul9q6k95;Z$F0!nfm=8J(Rp412v3k zj}ATtD^c3YCHFce({xfzCAloyL!Xp~qr4Qik`~-S1er#XsSEQz?%cCq5La#9e{$-b z_g{HM`Z_$ea7w9wmy%J+)&k$E@dP|yFTPdMuoMlez9Y2~j3v!Dy_`)4(6QrRs1UlP zr4{Os`l`7Qbn5M3PFOR{t>h_T^9BpmL;ad3!K9OI)0uUQE$Kr!f<^w0amHz0Ni8OE z7VEaAm7xPoM^?12_45RS^^jk3BwqYIP;!XQaM&Bw8jcp@Du=DxIh_`hBg61{`YJH< z_b2%rsmerOznaG_TO-@(x@}$X_*N?Z$UK$(A*5#Zua|Cqad|wF^m+L-5wfqnv`4sz zJ4%XaO$RmKQLHw2hWs24$^ndcWjJ3(zsr0F>9ik408#|4Tj32)|A|&mxgzp}8mv z)#vVa=Rc0j^o?&e@;mvSxJ(J{)kJhhn^1r9rF&z&+2+f@j`B84mSiRWjeTaooH5xE)}ht=84IFztiI zaO@4wF+?=Lp}TAd=O4C}J_hOFc0c!FXly}$(Vowz-})mfA-2~Ak66W!_$3Jqv8i+6 zh6n$XXvWRg?+>RPG!ix#&{KaW9fUe(_dfRlOnp!4NKp)Rv-SHY5@J~zVp-3R6J%r^ zEA~4t83n=V?=c!;lCDwS79~Z|uR@z^PUFwvQcyVBMWyZ;iGGSO&=@!vv3)X4{ofPJ=ECxJ*r>dZ%9{uuuL%q*xOy(lX@CFhAP zHtG*ZW4O_vUWq>Q>br~J_YeOUW`DjSsL@_sQ320fe*jcg5FtIl-A~MdJ0E}7Fe@+w z4P8H8`zZ%*3j1xlP9klziwyt(AOJ~3K~!0>vaSjK`t&ULzbPLHbQ+(oLKZBM-C zr+sfE?7PiiZzAO3mp+ESPMQsv6p8tGEhEB z6ewUgw)M*TW>~tq*?J|B7O_wck{+>$4^N5~ak`aL!Sk~;uBg8dQfz|(-Ql|9w}p}G z_Z2_?_MByK?p?3Je;2IsXoV$_VoeGOhIEP47qW_F;)(-3^!Rc>{8HneK212T(MAKU zixAZDIS7eFXO}%^FCD zrEJc+VY&9~opk9BEjvm-(5(RTFUH-)dD13&!|Y&67E(;`+X+n+S;V@%qt-d>k#s> z7`ni$O0qnfOM1~kv@k3vD!xbAI#`=wljfri)~kL*w(uVW5)~_n&Gbo?#ZpsDCUwyN z;I^oM7X8j>B*xk8>#vy_da8my3i0UCqzobNTqIt)?bi@9tHPw_tE&O)qgmuZR535| zMY^io(~I^`HbpjBwn>7C;uZ0I zroDZ(I1F!B9Z$B=q%p~NLg?%HL(kXBZ)Zs@F)!q`T|^!`-_>N3>m4e}@gpB40%pib}ITv#xGI*b+DMlK{ zNd#6NZLyYC0F+yJfRto%ferkF_*sOuoart;@7dB)q{3~zRP#c0qIQwW#Skk60k zf@!|z%r3Iu$@zuWvF13JCNwSnBC9w0_o{}C*6t&G>IKVI!zYVtRWd2Pe^c=dCbWhQ z?g?x4>Iw^1tcFh(*23z>7V&-rnV-taM8fH@EB3RJX+It}5k6T|tLYW97<^DSZNs&D ziM}&;ehn;M*$9Zdr1#Efc+2^mm=mbTRJsf1`OtoB|FwE`fei=u6l;|QOR!z)ps}SO zzlQ~eQ34J%^2nb;pCwIGjFPN6+3I1?%0g1PNv}{lY33i*pIuuN?I~nftcIA29OD{) zP0g*ad{rZ?z?c;qAL)AOxky{dEifdQd_V>nhW(!8NT|tOf6gSm<@b>-X%XZ7V~OaJ znqWj{=pw*ejWBNG`Bmj*qOgn3r){a`0XLaewC!cu&@F6(UIIl>u7+5grdXV2m;tVl zW|*rX7A{T=txvud2{C#^8y_-8B*rRxbk{@C@^@y#D_7hYq*3I_EKHCseRnpj`fNV* z7%Wj@-3Je{l3;ZF3+Ig!^ojVJxc#PnhMs;+(YGE#f(2f=q(nwavP>^k5<-Yc`hSH_THZjwyD6ADR&Hh;bpgvX$)ah8p<8oNl(dk@LuGoA+} z&Gc->-WTy@q4U$8lYhi8Ni(@WWSjRZTumHKUa3h~T|!n}Xmco}e2cN%0s=iZvD_Z4M=~60s-MkLjoL?r%?j&CAJ-zm-)T-k$5RE5nU5 zN8=SOrd*qXbv$_O2CH3Un7qy}M?*}%tt#22HAqBqO9oA%a?^%gG;w^)bBLKurN)=6 z^_8K4q%DzNX1`z4N*>{AR@s_)S(CY$R@3{z5xBq^z{keV5B>U{V9%$(JWU|d&f26fHUZ?OYm?ovqCjTK8iPxpF z0;;RaMKL9Q((aZcL&ZGiCc(+}Y-u79$Wu)I7xCe_aC3V6^J#4>6G;=KTf|S6hL|kg zHadr#PFlWYgrL!HtEFKjwB(s4EFr}(sSz_A1=oMrzK*WA881?0)6{+EqgD1HLA5*u z*RU4{hS%?Yf6Hhl%JwE(`qkKen{Cuj^h-?Q9=YdG*lL)eC7tonQaI_x7u42zR|{@ys^}(eY|Aby z(=c;_n-|*T;GvIKc4-T9W#zaj+$Ec~q{(Az^Y|*gT}=;eOQ$t|@*yTkL6e|Zq?Wta zD{YAkO5eH~NN%NZs8Y#P5c-`eTa$uM8dQm4=yzmghOC^DOEath!%7d=Hb}kJLaX2~ z*OiYd2=Cfi8dkCUEiEgi$&&SVT^UwD&ULDgD}z?Yj=hfLaTF{j?K2ZRb^%&>DlYAy zj;WN91C>dplmwaQS-i`Bsp#PZ7qqG1)PJY_Y)jWeNJ>K=XKOl9kh8t}lR;DYJNS27 zL(GqeqIP!Q7qqF8-L3RX>RR}NDegGJgCv|@#~_zH+Da@~kBjU?rLnpJy@(IkE~oSA zre;{(B&+xH^vh!5@!`ds8Nb3vu;e0xvd(@wEK})E!9|HwGVN>V#z<4g-cS9(hxEv! znVDK?Nfo$(EzNiIdznZluALB}#YObBR9P9MvyF-EIk8yryq#oJmK}xAa^8n5F7l%H zi}}w~pi>2=L3&7pEzLisQd7;N$jOfmj(QHbpKNUBGG)74dQZ*Y6)l=RUfN+`7zr*U8yQa@m8 zdc{H;G#3y7Z<2jF0Fyz#lGVPY-S4kdHqSkK-p+bIefvX5y<+=$T#`mVKn1yT?7R&d zLXO2a5;4(g`TW8xCJ413*S8qR!K9Z!>N6Yt54n!j)G*366B79sgbd?0 zJ~z@1%hD9{tDMssm((uz-ex$vr{7LuyGa8)~FF{QyjO!R=m~Got zU?itNewR8f5l*IbOpL@B5CkcY#ss_w&X| ze{uUO@XE}EEIDb@{CWF9P;4O?)$sQti5!d3nZ)&CTCT!IiXr``M2^X=UsFsz|2S>2 zkpCvu-z=WxYK+l+6OzlPF~*T%MiXAHPqJ*u(2(p0=$F;hx4@EG)LO$hvMf5I-}f># zXpL@J83`=`Hw%bu=A;Ab47D9yi{*FEXJ>q51l2g%IPf0@5h%I{p&qJ$$JCGa|rVzWfH5{m|p$Zj*DyQ7v^bL}9j9Urnf0kinOCEZ+^u?sUqQoRX@NPUJRCyNagY9Z> z1t%xX2{)#hbv*<}$H_W$cd>P+dJOfhX()K@Y@;eHDG6n7lSw*%3x}?sU$2LCP}7AG zZJ0n#I2`e@Yk3ae&nmqAV#caiBpA`3nxrV>!BOvlj)n+ZYA=~PHc2t*)S4u7(#Cra zY54FUgWE>FN!SG4Y|W`JrhW7NN-WaSleN$Tq(7*Ibe^a!R@Yp}ofOM^7sVX!tF+^b zAD$GG<5|aO()i{x*&ih`$xTwm1h=xB!w_;TZIO|?jlIroV3nHt%S(Sk%;jnXo|BAo z+uLs6z&FzXucQ15I;ST@*S0$#Rc_Pa+EzcOE4zJ_+@){6+}}w3-bEt#-iL7Tl#&HD zO@_IcBC@SoHN>95lNw?M8CJaJS?*?wK7o>8)V^s+GHhQ|zNlt?Mw*QmftAO2JRVo6 zY~0cZ_vb-=WBc~&)){(ssS*P%C4qI&Pto^CJ}4EWQ_KqDc%fa!=YLruE9eyqZDPyU zBBA7gJAb>!>DSW8@B7yStg>Gefut^dc5E^wjUwcsTZc$;+eAjWQ*j!?hq;{9ch;p+MrGF z`zmd@G+QH2&GV7Z!T7&rg5JCow!8uJebO#(ZG%>!DOUzNQCXLElX@-4PmMW`42h^C3T40*51KPQiRQ$tPJ9`si&rJUuF8@1Xk^^qlGo(vV|fj1csMZDLEwF|-Rr3mUQ2{*ZdU+QuR~g>((QibylLqOKWM zHb`%ge>w^g7U~YzSYVQ!v_-mUGqi3|)QHQ~nV^2uXD8BvYf9k{-CePN}YczE3)dTu& zG7NgGGZ0pNI$wOnviD}g=dVuFT495>-4b@V@GR&vVi;hO?4HpFiv-y>^|QfgSIb4I z9t71Qi4BUlmY_-+!;Om^x@Fp#(~CmoyqQI!bOtRa(Sol^*tMJlvNRCV_tQ(FxrIe= zJ-Hb5Y0x0jO(uop@vcq6xhRn4|LkG82W#!P^)+)9wt*ua5 z?z8bYyk5CKT$$unF7ftGBE#HD3vu5b4Kaev^L7yx^MzJGA$44A8M{nqW+7rs?^g&i zvO^W>deNb^AdEJZ)PnHXLNtK1AyA(}E(qPNsJu}~FkN93vgz-73s7DGDM&J$YWCy0Dmupq{)k{ ziAf^Z_m^K2VfcVP;yJv(V7X3aP|(0%nG&ygDCe1E@=AU$eM}{}M$)MY#gI*vfi99% z{~bBIJsLJt;bH5nu5gq z5U?rfC6av%nM?Oi$la{{K4h<@fyguwMKVhvZ+%D(o$Lx|Cb|{)S(?|${p3fHW;P|w zjOGz(zLb?o)f|~*!~RjBlWA>jsOe)=bwZ2`Zj#GA&X)v}MQ|o57P6^`j`nk#*4yM^ z(>j}M8W*zcPz*CYzL6FGF!2?+o>ud!0cPp=OQ_hVy0RR)s4>@zpkPTadQUVRqVESO zo9A4Rr77lUh?$gg7#T*MhepgptEDNH#pL25VYs$YrUWSYq2U^RvN>;ZI-5(JfAe?q*gK7dVL$v45K0rD&m&+X={%0 zWTs9(sCWrqpS$r&$(*G$-&m4ck0%rtb+&2i#2AgSwD(2Qe@X-(x>OgcgmjQlpI(**hAsbev4S_>o|wK~2c7kUerh zPq_NHtzpy#eZ}LNIcGWi^3K=b{YAAxD=g-HD8+hTYrm=fmfQAfhIurat*QsrLjzgl zIL)vu2xlxZ%+(N6bckwx;>D`I^|fF^88Bdgx2WRll;A-c#horX3pPAtjCEUx7@K+b zy)ff167?1O;Q2%L+!;3h!2z(=c3bJgCY^kaPLzF}+AGh!Y;anXDRbQehij^J842SR81fO}OzAyPk$ply9#h!5*q0V8Wfc-YJc9 zKMOl$?h5alf+fbOm%$S~aYrH_LP!Sj4A`VDY*r~1W4q76H<{SSuwM`l$YXO3a}uYa zFL7-zVobMCK%_?D@n9{>VyM3|P`Qpglcp5cD+dn)*k{f^q5Chd^z zE_Ucz_}@eCLU9^bc?5iU4@p+^bNWA`hoK-M4;q^OOv3KeUbb*?vNF-^ciTmGmkiA- zJnq7Sw-<+B@$XlI!-@~N<5qG9PcG>W^S;R6HEZ{m3Ofb}^b4Gbd$hPGq-aaYw{f-ezgmh#&-eKd3HT&WDB* zo@`l+MDr!>H^oa?#Y+0Rg_ei$$2d|<%`kcqA8PO7S}yLaEdMTczb~mqS3pTMW6NY% ztevGHwnmRG(7luLO4FeAx|2H&W?WNwk7_EkLILR&TXEZJp~%d5Y);J@PqLU7c%>_S zYu5TCYk%^_%=i`34D)G-nfWgnOf@t``NpTDW?0tw_T2=>5A9zt_C=NqpzfK5{0()d zT(MB6{gTw!Rmm-Nx*6|SpivbFw&S%c`qVTH%2@xc zJ(@syFFbbsGjy>2{%qx%a;~q_`ZM}6ovSLKQ&qWIN85LpXm1M{Ci|(IBuggEoN8wF z6K?y+T}l6o$5-;K5aj!BJO@k$aLq93KN}4(ugzk&;(VqV=4y!9SMT19iF*+;FVFe} zzfB;)67h@pUYT6~#-A&W6km{BFPi7$Ur#3J7F9q)J|CHcsjjGi%E~fmXex*rBKh&R zch-J$x*Om!w97f~+&a9y?HGGLfeGlxH8RwaYq964B+a#oRLP$vWnVEHNaZl4A>tv5{HN~iyoNI<{I-m!<_}c@a zS2yHHFrSrmO|awGN8#OtwTjl!UN5@f3pz816jKN2{mO3;w%gvieIqo(-1Ros2rRA{ zgJ-$z>Dn~!aU__F4D%ty=m*n~V{}Z?fBu?lh^0M4M0f3Y(b*P_B0qlN)M?OEQwvMq znJxZ2aQiI*lVOMkb3ZSfHx6b!_*jX%%>Ulk4LS8Hf#5NfFAC8^$e!SqIBnJO9?oRc zCL@iptgT;@jDomWK_!DFvJ%U--6TO8+>!==o|JPdU1`vAkz{F=0tw9?hpwk+jS@!- z#aD^oM_?F)k!de#H-iY{beNhhfcd=M{p3`(l|iAb4JsJ&%C%iY4I$zL60f{mSN6C_ zl>~A{AuTC_1Mmz86`sHoMe2gT;((8#*UlGy%S>h|<~U$Giq6IX+95aL&#$nX>8lJwrhKzLn_iS zpbeL&LbKGGOZ0tQ1IR4$WYUz9ROAo&kzk-S!OZcbDM82EHX_cDL4b}A+2smhM*FjE zVkU66#6;lR4(ioS1Z2}<{<`QwjW>C1VyZAfC0R*K!xw44ppEYi(ko*1vCtsHYGRhe zj`6G7NAHq7Z@BA%JpI^x&s@za8)-`OX8Kmne{w+g_3P4IuR(VE$BT3=7q9=ERj4fJ z7nOFeD8P(Iu=3{;s@#s&_6SvSMU9I>`R_yx?3tS*0~zBfjC2moTn+t-OB%yJ+ zsjUsF1tKiDb>o~qWEdj8DitCWHNhUfaCg{myLG&i*b`Gfh5avkCNsW~=lQkAzw;*3 zVkWEzzk-SSiWkEm!`h=6mgSHosN$rSwkigW*}CodjX;RGz12sf7@LYhn#9TH{^lEx z45Ri!gqVwL@V&IL?Tg3x>IQMproWSOkgz?@rMqYiWs37$U!G$*{ZUrZD=G1*Q~!Zc zCC`C{_yNu+IdLhEXQ+W3n|@6&9&WNgKjNC zPN?Xq9P_1i*t-3Cz?u7Q8*DgqpniGJvyr2?`+P#S{d2s3i=d@)E_AZhvH6@83c?iE z6N)=aRP2;fQouY=UE!u4OnPNc=CUj}8wQa`YJ>>UmxyGcaAwe{VeoopOU(~Tb|sU- zS>wlXyN-e*M~@VT{dLMr_~Ycab2l=t6clSi)}Eq*%CTcBsPbJ%`1$yddVHJ{K`{@# zqIhm%QA6|;ASwV?H8+ceHdRXEb>=~S<-0G|Z`FxzP$exX){)~EzyGv*$`b_2+cq6? ze4b<(U4UE4+#wg{|I$z;x4m|-X_}4mZEINhG{rn^pf*T>JWIn6r`)W_&hCu%us=r$Z*k!K8**SaAKzXkS+YQx|(EIz+ZB!*5azC~lMHhGL5 zKXiXcNq%L;RGj@CGX3Ov;QDsud(pAMGJm^~V2W<%kbp|7Od3$~AZAM}8gw3~px135 zpr+5-PgM5ht!2OAH$4CQnK0UWJpOi!K*!qDhvkV>w1;2S?gJcI!~v*I6V{!uX+rQDyy|Ihp3*Ass_YZ*%;*JyatdQc~` z0@`AR9+Q%6E>g_BBiDhj_ZQO!{2M~g$GmUZ8q;~7f&2Su=ZBDF98nfSr$|XMcbl1% zbo?(@ikH(7$Mom=rUERjYl7NFsV~OYVa2o~CCzZ_`($Zc3A$84a}KclzMnu(2OUP= z`RSrs7;^0WzGWC=a`7{bxXG*NVi~Kd!ewI7J=8F@6w`q1JST({bCYO3EwQZiU)FxQ z^iX{18<`NpMnUA)CWnlHk;fheT?Y+}dc+?-_!zu#(;cvC-h!y(zX=Def9h3I;{z*~ zsj`POhN$vVI0KFoL5pbp&MN2MwNomn43fgGFpmAZ)?8A~ih;4pK{qv-M&!>Fyw$?P zrm`oil7}NGjE0vC7Kdyf62{P(8SODw>ma1T@YTd1 z$8J~NBawt24KZ0Vr-GP)gxIh*08o_Hg>tn}RtzlPDE~uy~oGspOO+z!(7YdfP7-`?obMo7g z_SIi9drnq+>g&y~sgrj7@;Z%XOZ#lY zHm2PvSu-d6Z~45LEi`;1Y@z8ZHHFJibBt*Q7i-gby4}_H25nXR7t}^(`$G&5#s9rb zaZOP&FWdGd)l5=OCf&%ETlrupsTFH$`aX4j646u!Whz-Eg0`qBqG$jun`tPAm@tZO zKSqO>?3mO6y;~hbRp*szJgurMht8FiP*H{LkwnIb-w~R5vi%S-!fmgp8PBY+_>q`5 zX#GN3I1CX+5duPnxte0J8e;BoTuY3YXAA?4V)kGfV#06qXo^XMkI}dyEu+}^gpY6O z>lHuK1@=1^0cMc8(pz(FA1$TNe~T%GXs@=I_8U|@QM4QD55eb4_pOSFW35aby@KzYqz=kzraT*ngGOug!xH%dH{CX&80;y0Qg}rU`X^O>Zh8f_RJYFZc)P2M-#kdS)-`Ip0kBD!4$QbCp_COf4-B!@4XAe!OxNz#5 zLR)O^#3?ZE)oI@*!aQk&^-sOJ=)7MjrWTCBg(zvgNi&snQAiLmaH`3b`(jyjMrk*f zg^VMoSRbdn9oIInU!s>&j*Chb6pH}Kszh@4hbmuwy4?skd9Rd&*hll>jC-CbdHZH{ ztYS0~Mhxl)w;z|05WD;z83-|d5A|t?QB|Vof032S8u_T!MpVZlg8S$kYNU;FzFB3J zNOq;zL^F`pw%+|wL2z61Ks%i*_*ZOycCRUK|ISyrErWNYQHH;bHYLI6TKM=eW{VBr z-0y8?UFP_Qr@~`zeH7K)d6FcdWCnQ!VNJMnPJVn|!~stb}Hkz;8Z6ruKwp~Z-L*hL&v3eAinezxdSbYUnx z&46a2)_75p1mZkD8$#mmMPHl;sqCNslJARLjKy)n8x1k88D{ZqL;`Bbr7TI2A*Tqj~1q?SJFK z%nHf*IO* zCJvha9=~{xRLaByE_=p8i1GD{n1XfEUtU?Xowh(W9l$|?MQDnBt06X^xVOEC7yR2( zzJ4vR?kQJlEhk=CqY+608B}g6F5Adfg`Fgb>0uBvE~hiu zm{g#kh^|;v!CBXq$PJ^}!EKilH?JK+dbpM7KBNmdRR;MXgGzjojSV^;v3+(z?DT(3 z5|af6U6770O|uEdNW57~zAp{}@7P7T?i{_XbnSUZ8JRLD>McYLls?UO3ekK5pPNAC%n4_VXd zTW`%>1ZVx_8Lh$M{!SXwAX(vwh&o&}5Ms>GwQzbPT!hf#qM*iGZu|PP+rRbrr_V2S zfA(m{sd1yBr2sWeEskbO95=M7ph~_kE?u0Yqr^&MS^0{K&+>NKA$l9PvP=7{gp8u` zLL;SQr7WkH=qOtw1k~>(=EW3F?wE=-LMFM$Jh|AnkxF^!Ad^T^nzvorLK}Hps>$z*nTYhB{dk}_mZ8}&U(M1Zwa+K(YqLpT}k&sNHO%& zTsxuRL5O&!QOS!Sav`l%#dYV(a#*uRS5e@TN1`BsJXPbSMw({Wc{Id0Qp`mrxj~`O z`UMkX_?t+vh;5BYvT*NnyDiE&UR~Bxi`cfC|#$fix1FZWzlA3@6V<) z3#Te#NmbeNvHayc<7{a~qr`j21|&{F=w+lRqJPB9bJ_EZ2@dCBc8H;2Gzc^QbBM04 z3B8y(2B`LHuf=KgrTtFafJ&1N3z9~>AlMhWb}EOe@^XVja{N@TAy&qaV{HPm@6!~k z0B9?S4njygS3}ITslTbOQ$?alZ81Z)hshNaha!YoNi@co>;V<4CN!;R+;iSPAM!ZO zALC3GM5mcY+nXoL@OOL+L3!SHpT?L;f(4RXOmocE6tma2`udoLm^%+7o}ULHmv%pC zh(b5j=L;I8`HQ~e-6Ap46qDPKrkII?Q2ay3K`4Ie*~UCapQaeb=kWdVX^7E!RBMhY zO)=Njh%!fG%nd-2mRK6H%#EAk_}185fMu(jVd?5ds4%M1R`QFGVOZp45^A;#M#w+r z$gm{Sg_&oDuhku1x#_?JZDLJb6YO~A1o-d#nlB9@7JB}<=fkM^FEpRzn_pc2-nQeA zV=>xcE;5YflW!4XU%wpH7kWoSPCCdd%Nc`0c2JN8hP$rJP{O=+PZCVD3<>f8ZV4HN&k2vm{o#+9Pr6rE!WuohiaFT($?0EEC3ip)BDye~t|jk!fEPNe8VeDl zG)XfX@!HbTDyS7ni!AMS^&H_K$MW{sB`fCNA?=;# z0(B>Jc#BJ!h0mZOaL2c_@j35!oGL?5WVZ+*#e50DB7Y*6KOCE0bv4IKySqrR0F8C= zH`Bf|alEfW8pU!bN2*&@Oy=AA$9G2c6ASZ5xnlVh#rH&6ysEUtiij&=F+?sTm~$^d zrXDqJXylyFF2TG&h`3@qg&)b3XZ~~NIXVobz=)G zscnL~CKD$JX@kW+TYMg|(=C4ICIfoFbth~Kqt@>$e&X#p%ix?lUxWWHSQR}g1(9Lx ztq!!#4|%w;EmNA~vNYO!+F>}r;@|O;N0K#bR-il5a!CUQe2Wk(&13#%e#?+ku9O;L zs`6PldD>P%R$;e_pet2)AoD)AHTSTtq*0Tkc16QNrbGjmtfbT~r~2JEnMxFMm8bdlAl0i zFih|BU;CW1&pG$Jdv19%nEY3`Yt4GI-!1Rnb5GrSf8Tdi0EF1BA5Hb>{M|G6iGGLf zmpUb+J)%r^awc+{I~nxyv}MMd&Sx6*`{ZT&BE(L3Y7C!biBXXzQ)G?^jJWdHqq^5w>{ERmQd=QbkN*!?JOb0^0(*Zh)NPeKEXWr{Nd z8Ru};ZOkkq#ERrB_dv8zCYsC~67>yjmKi8$AeoT3!6EO+WTVNi!5J>EFEa2<+dqTV zhJbQvgqfOQWIufV(QsP-&TJ6aTUg5Gb}cj0nEl{t1OI4G~F zfr^?ssHmw?izW>LC*Lc}M8(Cqc#keN)-%#T!12mvM^A=r8jW?$gnUFKo-gFzE zn`KPO$#O&>G8Hn6k7u0TjmDQy$QErJx1HxVj@vZESaOTdEb%JuU>aen9}9!bQ~d>B z4AOjqIUEdIUzC_@UNb0X+ChBov8(~9f1~} zXPNU-qehgIuyLLjHU83kQ>;g%CXQxP`4W>ythSr>2iFKj1O|VPUUr;z|7>08_B?do zvft&`SL>37+FT=;F*{JdK(^Z_(JtZfxZlO5b|7iXMLiB{yNx4^NkObXSpD#@ah*bp z6}VnuHkBjYe}M5U*!ZZ%Z+^Vp<{GeSKiTdYun~xl)Qj<&-aDc#@q2n6r%gc(wLauQ z4!h0!#l~2lhml7Ji|7e@ymYEMG{k6~VbGOJW&$zKGBjL??pl4;3ym;fiK6&@eH=iO zgm_3vLRBN>M0TuSTr|blJRSWdw8{0K{6hMPBobMUZ~Qs9(_PJ|DM{7#87O(oKzix( zX*Z2AT|>;FDdut=T5szbW2OcoA;V0KDtB8iZ>J`;n={{(<#5s}YRC)r3bbqvkxt^Z zehz|245TflX?&7DfRbI;}c?{Jrn&${jcg{$pG{wkv*A&y& zFNzs~&(D$m(Jj=ZNmFBLA6ysWT!GmFL?=y(D7zM+0O)-2g157gxaE(rT7ugqxWZt&(wPK*nUpGCtiB$R`IG^CToLiy{KaHpnH&fD?J-0_D+>zS0C6PX9~ z?7=m~nJhSA>3B`h+}XKlPs|#xhwb2a_0Pm~i;&aR{WLykzaM2HBE)X{XezsGSWbBJ zc)B;Q$iB0psrO^k6w?tHVGv?6^-WeTZw`J6mZ^*z9yC)F&ytENxagG$P*h&UB|I!! zV`zwZA;sM1EYZ$Vz5im9PL{ktK?br_@Qjih&`HOUt4^et(wI=?%gfO$Z@Xq#MO7^n zSJ$wBmyZ0f^&f6U9HxBDMWt-RM&h>pZ3f+=+Jh4brh+;2KDaYhJ6^X@cOLs+GnnPb zoHWZfyzNAOJD<_4UuJm+$uy@$iE_U4MMs$TY%6)c@y^yhqQ-Mgz}L*|Gc}X!Hh+&{ zG{gKv5Nw)aUP#iQ$kL#-+3PsVnn@cU6-PfI+X(4~2T^cKuMc{?Am=9a4{pv*)A?z0 zhH^|ecdyYFUtbTkS_e)xl`kHT`(r`wHb(hcGtI@tZSBunvyHbu+M>rlZ_O~h{^z76 zLsn|C{ZV6@Uo=9Be89qwx;=}gu^cPJ{;=hX&KX9pSjTA=F<2_+BR(2q(U0PS1T#g< zJVnh6O)Jqst0Y8?sX`<(%I9yOZ9WSHBk6l-iw4h_7Z^m3AK_}_I4QD?^-o#9#r|0A zhzJtMcV)5ZIQ>(W84^)w6C4aW=yt%W8q;B6`e#EfA%l0uy^lORJQpu27FVJ;vgv@ULq@G zea88+NO}w``s26>)qhd&z->OJJF{*3Ig%?nh^G20!2~0|kW4Vb=0Ujdnqt&@vw4fi ziE-`Eea1gGBvzRDn;ry-r5%Msf<-?e|9z1p&zMAnW|$BSw(VE57I`R|Z+@C$CSnZB)ut&HBseCMhA3ttg6gt8S%U78 z-kJ>{Aw^TQ=QZmy&YKPtSHj-1sz9$rry0i+{QLv@{27n8jeqpxd_QNVQpdY9i^$dz zR8x%RVT?}Hs35Zb2G9&M{mq9p#113G0=1sQ2f3C&yPHu%%s`${1{Zy=W#;P0BTh@k zGqgCsN@PZgObk;iOSh#{oRB82$dG7GVl&giEmOjagH(?!v%%d(t4d}-2`wwK^-s#A z;2hhSawQN8h8-y5A_R?zL{Rv0$*Z8jmB;vNh!H}J1`WSVadQ6JBK0y;zP27B@e!!6 zt%vyd2-JGmbR7Gn=cD6=-Md9L{QX964KYH9$sm--%p`=E?URk}a+S_AGaH(jW;@?A z(_SSO@#^E3fMM>JnNcF+*MZ2<=nb^*B?q*ewhQ{mN)NuxO`YIxJ3(oUHtL{mMQzi-RD7CN+RnwU!S}f zKApGP(OtyH1Ju?6&}W3G^u?#D?*x6}?Le`2s`^IGaE0`6Y7yw=9F}9*s~>jbpbw)# zs4Vj}xUDq4sQmHz3BpH+ z2pw)~no)>kl3ekcMxM+(qzuIWz^53e!_*JA_u!;qwDCp7HleZwwcKeGRJq$Y!-Ld6 zzsx+Z{caiyJjhHMVItGfV!NG>nW<|2!}~L|vA*dYjJL)nd1pwIliT!rx~MBYpPTk! z7$kZ_wJO5ACmRwk$hc_~oeKw7chs>r)kd~CFoWPcDK{|;WX}@{BST)4tyw*VC z(R5Gk4~`7e0E4a?%Cdc7d9&acA_Z&NR13ApT=*Llzi;9)(pr6wJ}q z&~nv}#whrHO3tF>A#T%#3^d#henme*CQAOIG1ZUB{z4?>nRZZ3G4J`Ref=9`9_%$=<#hVO zA0U$^owl5Riv6a>7$K)6(-e)zBKg9`6yug$Y41W1rly$9)-}cA;;~3K^yaJwrPp{T!F> z6Ra@)3-kRPMu>&!-3}icRRSGvdB!mbZj2(*C-saTPS7w=*C#o5sjYeF6q{3FHCc9M zriH(6-nz5XQebGOR*;*K2F;r`f$G{?*jG{x`${Tc&942h^*{-u2M8SWqRz)Pavu#> z?bad-y0&NrIcceo-LwfL!~^Uru7G_dWw7U9DJnLZnFTpbQy?d`31l^G0@-QFP+3z4`-{t9e`z`F zD=vo}g(a}3sLYk)S7uq%0@TNocAKI#V;W+ua^N2~cm>4j;ds;#3p5DGrKttW$oF?| ziSH;AveHr@D>a2tOca+_L1AeH>@TT+rCal%ptL;DV$v@|E$Dlu<8sqep?h8?bZFiT zS~g3C-G!wvb>$YwFDiFjiX(scW;&U=sB_7s-E&)f4I zSKre3<*YV?ph1#5 zOwBMt>NQ03Gsx5Y|8$HkQ{K6_buO0FB%G3b+=E`^6riA(x08VSTXGuMY?VoFIz@gx zq+{?m9ISlRJVY;dKi8(}KX`CSM|u(BtD&DdGR#kFAb6?7eq>POqZuTVnqo}52PK#Q z03ZNKL_t*0T_G{6kyg~OF|C7oTg)^@8;_$;^X>^jl$o3WS!v0TgjpX!w=kL8{uB>U zzZw*XCdUWQ*`1ojPwd*6)V(^9B+u zOgY%*M-o{>NFh+IWBF>G1TjWRv|e}Jg18fL#s%LGJRbc1UW{uigLUc z>uX$h`?}R!%25CP0JTsaa~`Oeog~3pu`_z<;!_~AX%qGi z%|$^$NjZ%Abeg0&I<{+Txa8;~;K+_G1&x*at6#Z&A58gWBaB_V7OHCNS;mwb2fx&i z68p)fV47}sY>@@S2XuvFySIbZS?Qj2?qFF3{IGHhOj^1ge%@7}f*CRj;LH?1rAIrs z^4PxYn&j-sPETP0KigJXSqfS+#f}Igxtg< z-}{!mf6{VsjP4pT48K3JZ4R6}usaOt(h73YQ$2qV>-hTJ2VnmC9q`%wH7xi?oYz$U zZ5-IN|F4&x1X*dk?wVUcSq0qt(GL!qPYh!H;lv~0q~0AEGE?6k9P=YgU$b34o*JC_ z92V`4IT>*N;O;Q2N9zD}uo9-N*bLwOyaj&VzL(J^FikRzUe8yETFxpRvu-u14v_jP zg?j@a-t3&`PED~Bd$olpFF8RL-*s8JKYcO-ept0#1~tq~ zOPj50jA|<=7u1V+JZt;&a^A5>)>E@ z4MS_l_CXpJG6PMGKa}}LobOIsP1faNR<4GlIjs4jSwS(mhNjpgZJ}vL(@FYibT!8N z2%AZ4BJ*q+SMEqK;q;Z6piUc~hrdUS6P_Vboi=IY(DM^QiQA;1LqVx%n`cB4vWc{c zqHSL9oLWX4LVC#yHN|U+{L1?T^MgJ*flxF%y|5 zlRJ#{iJE2@nmjU-T+I(C=_A^w5wLy8;e|9-`Q6KYMC@m_s2@Bqh8h`l>^q#dk|vte zRuJP;thQTfwTTSVZT9=rk5MMSnb{v$Q`1C-#cFercA`~e(|4PVOzD&)XduHVnC3S9 zv?0MvWSD77O{sF=LG5^`udfAlJhvl}=ufncd@cp_S2k}q?YCqaEU%}&b`&ZH0rTGxk zwpQ~iu64~d&z0u2&_E~cKGHDCnFliOt=Whmbk@HK^0>;DX?qq&(1}}n#6J6Ka zhNjr#e;5pHTcp9%g*#x(59H5J>)vbN0tJQAAoCJ5DJ_yb_vRkO<-d<1y&rFyNi?`*wc9OcY zOl4M4@P+>rqNi>+u|J$Wpc~-iE9~~|&l}*y$v;7H1?SjxE8hzTcZX4D9Ub=4uE#Ij zz>#Ba+t5yVaPQeiLz`^xfS%Wllvh>5*GtyJD^nJ+38?u%9dnw&m|K6>D9?h9g%h6o z$TwFQgCN(R+#inV)+VOkt*WktFMnDK@6A~Og~b(Yl1zysOh{X^@ds$i`Q<$qKyHS6 z;4QzX49u`g#yieg=C+CfurWHNA(~8WzmW-O=7r+A zy12R;DyuP{E#&5vDJWk;XwjCCH=zzE8d<3sCY+z9CW2}6pr>=PZU$dWWEhpVsbS@3 zdufQ-oXYZTx&(QGE)HTYRF4yb%`c+cOBhagrJ=;H<8G_^9!68lrWt1TAO9&0F~9kp zEpygeb4g`VV#X^5v#{RbMm7eyC?l4FWH#Fj_Ie>Dqsv>(&&(hrwJ!=f9*X*FUNfq^ zMXnPaXG5-1d1DW1BA3XSLf7!OBg`3^o0bAilM{rdq$my1{>}a%v@J8Cg(j<)?SV`( zyMMDh{q~#XY1U^QDTdcJH7BUN8KNK{QaY?A5C)?#7>Eu#q#H*HA^e}U884)m>_qs$ zLdYjy8BnhSQ=vJSpejm#Ete1MEJ_7aH;AXS&dszaJdhoLS)+0UIX2KtS+ml`H z*-sWhQ8|t}I_$vXeHa~tt-O__U$Fko4KN~`Zv*RlfLiW(NOD3P;2%1zqc+`f6ZnUs z=VQDaqn*{Hxl8+tl?WQMxdwc}cvu)s zvFQFb0DMM2$rwMlpCW7t=t+VWIR^2YkN@E)XxpMGOj)=cKK@~YM!!h&3!eO;p2Ap9 zdO_*1>~thk&<3QHhmM#IT%GmvHKr@}bv;1$cFo|b)4DVB`7ukOr~+~M^t>9-JAz45 zi0oJMV?Rx?K|ONejth=p7rW_&nM{rV=XW|%$t@U0zi%SJqLE=dm?iI*G{z{WS+~hw zf&N;J&M>xeR6#vDzpSzb@{6mWunPNY_bsUAwZ1;-(<&WizkDthz1f?;=l z1*>-#J4kzFa=AD#X4?xnW>yf{ApDSGely-!-iA8Ih73~`gm)i!9Bzz}!pGLV;9f{Q zS!Xq-3;fR1_&yvEYuG#fpFg|xO;15$TpZ)L*FPyUihYk6Oi%}yu~c18w#Zzn=NcL^ zlSyWfyJdz2*RtRlqAGLTY18-4&u{Mfy=Opd#NWojE0>=N13Kl!^xkoxd28xo_+aiY zp5&;ylaMl9kM7tK9{>Hxke=e~c*EWZ(%3yVZYKP+X}6KN%LmsH1G~eha~dxocI)UV z9DyXf0~okEu4`*}=Ax4!DKP|%j>m)kxN-|T{Mk&XMNV%`W2{rlOc--ZV+O>=Kpko~ z2o7W%?3pcuEiWG218zTaP)xx}^YJhM`_LydVEK-HYO-%;jB57yyM}wzT^wFu zFBk?V_vz?aZCF5T&5kIN#nFt}@G>`^8+?U$L| zGE<%p-jtCf=^5lCOJuGEv`^~M7S0^l8JZ>~u|XIqAe)A4YtMZ-55_Ovz%>zt^ZV>0 zJHh?Kj|tmMVdaw7A*>IotB8sn2CxdJ zmOyXK=_~pNY=0`q(YX7=YKWOgeN#w28p+Qy{uQ!6n2pU8`vuG_$Mba?=_|Q&OVgYb z$PUU3r+PvfAJnhdZ2TTyK}}69yEX>N@SaIyvmx^-UGqmG^+d8uRDUOs5mHl;Y%$NH z@}+XO*(Q@hsPd=khUJWi4ORV|bp5CajQuf695EIVg#?lPNPzwt5nVJPq4i2o+vJDD zASc!vIX{jF?PBpM%UjrfHpC5As znAd(pd{O!K>zoaLyl?>P&2D>rChRLM7f7<;<42hJMNIP*Nc#Q~$tO-hQF@)5**!;xZKGfZl)Yhuc-nqqPBP+!Lpf_9BJ$WB+%_0BDob z1ZFJT4WG^2zz{+XjWMao6&o_v_8i0{g3~mwatpE)Cixe+{w4`u76gh;KJD8n3+}zR zKRf)6SLeX~l1dr$!sEkgj8S>vc}Mqb0k;q52(cSqm|;bTdA(m36aM?o8Up7H z>d`2_MHfN1_cP;W!?!E8$idr|NjzcH2oHo- z>)^kp!q40HNdacf3+7CH3QCtqLc9jOl!EaCL?{D^i81k23T7l_G)aQjulX%>$;*uC z9quVCg$rK#()HZ2cb^X}Gwqb4UO%{DcOl&N?i47htdcaYI>)t~_z9t9buB$3(Xx67+*p|rY&2MWYS&O+N+p@Lwnza;uCenp$Jo_(L zAFs);-{jDS9P>hgg?$D;PIkBY9QHRF^Y{SltBOtqwR|ub!H~NO0j49t@Ouh^xzYcq zOmPw9_eIh;H3w+Clig&U$`tlxRa`F&D(o540`f9U4U3$se& zS5wYYDrYmu+ptV+vm9mrWGP^CziHF>CpBq=(}H59dJqj~Wit36G$-7gj&8S-*(3>a zo2EEWVKLQ-Ft3Szz)VaJ@xy+3v3{ec4H+hB_9$3Mw0oLOnqqFWMx@z>zi(=dg?K#6 zp<01aravOd1cD6vwAxxuyNG{o$go&7#2S3>M*Z;YuLG~L+;Kh)zE?g$2rdF8f6#`s z2-9ErH6;2mXAL*UYbU*w(^qz=H9dlqzZWtL5oEMqM}`HtuJagP?)^LGzAYpyW}%VJ``lgrVsD z^adGRX_UVYh6uB~^&sUYO zFDeyX(mK65zgLr4#JkGs)rq|eukvO?9SI_ z10s*42DawE&?}^4Jd}@zL0`SzM&PI(&0P^LaO>!)(s|fE zvnhOh+xdZlDyU0VQB@61nJt!08qu70Kwq}qv@c@{VW&fv^` zWcV>~`jMSo?;e9*y9-O%zTJf-?0@X9*6%KWod-%`&F%wQB9qGO>(we7y5(g;tE{H% z_`Iw%Xw|GKyAB56Y)G`p%QnK3U(EGDhLP5x%4BkKVn?L&7W+5KBxXni*+26Rm~7cE z6URL{^Nq~sSj)E|=jliULL|s`K-!Ghxz=WK~3>MIM%8^SLEJ6eVuV+N}sgO<1 z{kGKuCK9vEeJp=Li>z#_zlt`8*JEY#`2=zKYZ?z88Uub>cwx)iR=x}oBQy)VH05H` z5L5FfT{FxK>QJUBEe1)`3fm6`)pQ%b(}P%;TaEW^2BR8k>%m-!^d#h^Kz`EqLHE;f zggn-5(sm^+kXUUujaWCN6=_cJaaL(ikgdD9Y;=t@P(=sn^q?q>18Te=npGMvg4l97 z9pTp_XBIwhi_|1&mYVz@)lBeekAw_kP9f4F(wuV&86Y%CEJ11IZ1U3(ivrktWF%WM zk;$1wnd8ECO>(ela1l~c^O8x88PZzt(GkkKbHBj^uA$pFkjNLoXpd`+7) z&2%K09qGY;#zf{d)MmwDDc>j;EK>7feZXWYfedrAiT6@Ew*)grSldkukUcM>{uA>x zFB|(~fe14-V(I(Fn`Z<=wy0zgrv|TGQ=B8h`2IN2uhc_*J$_H^#c5OUi}w55ydP7} zNM63CMl{-V|NT2>YXPyDP*_^YnJQ#|VJ5XW?ZzwjXssWaOeXsa;ZGrCi=dMePbul; z+-);dp`sqqp<3>2mtzsNd+~*&TNQRnQUW9+>{V>4yy+W!-yFGz$T38a5hBd2&o&KY zxBdhXU_pal?&lNBtf+Ug|1fM_nM2#urdS43!a8@{OLPDF$k6L;sg4yGCA zms1iH8Aib~(i9VP`chL&)3UY5HyjR#1#sLRKEz%EZEt?snOf&jSj?BD!BnF-`27@` zO!TFV5>-puklH%pzPvd2y(kmi9t)i+E4Jms?t>+4;B1kR27TJ)LP{dKg1oog2a4gM zH@}1mgzn1wb!vun%E^F#-f#}2B`11b3>SAh3W{LuuKjEfZ=c-^+T~>UQWCD(u^+B| z_Zz8Eh1Wqk!{GwyL{s24Sxuo+i!AFs6qZ)N^6mL-zdl)BzpDV=nZAri_>p4bHv{0x zd2cG}?zkLb2i%QsUv`kNh zd(R%~sGk^oKV2JB%BRE6 z;gh8sPVNU+pX98k&yJf56P9dL!kw1>gnl~+#WNjy?tsp4|M^Z@#Sea54u7Bav#X|< zO%sTM1^Rydg}Y~_MNg(}DRT-L#d`+RwmJnw|3=P8<&08JMOpqnnqff_rs$a~YwG|J zW92nG*UjVzx7ltPVzN#}A@Kq=DUX9xj~T0m7^}BJLeZo>SK?Vm~Nk6elp z%Mk;zu7QUgKiLh@L@*0IHccz_ekgf{JI6>9NOAV#@0pzBcAH-}jAoc>m+Jj_2Th`p zN^Sz{w*I1_HQPMjh6JPI{PtJX*FzH0vH-B)8`?;Ria{-M@&~s$%^%XxA%fI9Q<>kP zmxdViU#4bQW7glW@1rsLH^2K&OGtq1rpeGGDd7+X!(5#1+;uIS4L15OlMbw5^kC#H zl1Y1n^ddSen=LfL+%(#VP28N%#cG=_3mJqL>@}>NP^LJ$Ul&``^EDbO#{zF;?X@w1f+?~Gv1d@L&nyp;sSVG`F_N@ z)pI}h-OEk*@>P-)?WfFsW=A;9J24l?EDxcjV(!NmAsV(VxMJ>?qlFLhn37Os`3dK| zvbj@OY7R1FG`}6(hz`sR5QqD*JQ-W0R!Q{rc#!>qXvB3s2X$O<#5RA!U>faL^EnFc z<1&^$dETIDo_V~^mH3183K43$;fnL2*{CK;@ww5Mii2{5orOX!@J z4y|(1VEf(@Shf8CtlVAz#icb-$Q&wvbRzcck^_Uf=0bLQ3Z$ndGUx67qDol2As-g6 z-^ct7di%&qPl6Nsv}Wt?@$+)gio?Obn`yoB!G9a^SCUQR0P$S;L8+Y4dM)`L)7F3>IFf}L8X zL+_5afI6`N49~KYiuJjh5*f(?6$VdZ8_ zKIMLa!98;!uUQjVy9>*v2%0xbhJKxLplj<4$V^X$O*@NV#nuC`a#Mj^p!8^;3BB89 zLbrC!SX;_JSOGJC-USt@igRR)`Ttle4&tF|71Eqh8>Qn|UE zJ)}Jw6Bew>hdqU5(4l2h=-ob>X@jLC#ly~hrR>=juHpVO+J+sG2RZ4is)R*r^I_SB{ZN6yJyy?o&`Z}4 z!+=q`oTvE(9g(|$-XC2!#}-4^2mj)Sg}jI^JUBJI6K=slR!u&20+ z`C`2^+-aVnYluyJ_!Ljd#Iv8ACX&aT>qXo8(TWrkPbK$@2^q8LiDl9gm2UveFrp`S z?chTfrRNEUHN+aXJP%*(zpw;a-SiYg9uTsCGBFuVm6nNt<}NG%03ZNKL_t(3HNph< zy>4UX1aZ*@{bZRkOyi;+5-4*<*bG`1HAtIVivg3Gs)AF zli<1&`obm0aIs3S?Y-&C;LRVFh|GDFnMN5??_Ylo^lH=GdWnka8hB~)e3-U!D->2# zN@pA{f}5r!!ab)AhO-BB^Sp=W#?OXv%Qi?ZW|ql2kL3BRp4La0J{f&trY2@uCdb9Y7k8cyEqsDn zi#P6u=f9Z`TlN(>5N24;!@9PD2ZtXES!pSr@9CQ*>)^>R=ZOp>g`}i4$^?&qm|s0K z_hUfpht=Cz`~Bw)XF|`mIi7X!m5B>s+Amw6sIpp?8#)iunA3 zLd#BSnknb8pQcw8BDI;e7S|?YK{B)j%^2M`&0Cem7_aq>ZOfpTU(hn>{#sBPVmME& zMNKhHvnGJeG{h)FS!fGD#0DCNQ$R1$CgCrX|t+60*B-?CA9$ ztq(bUFdxUwAX-#Vtu6v_afra7>*=;Y%*g%Rrl1#p9_kMpWz0R%D;jt@+u=~65cC4CWa-O3DA1v}7wt4&!9kbax zY}zC`85--)TVJn)rC5K&by0%i;VX}VmRU`px~2{u9la2C7nD1K!|n5$vU(gJAAyCd z^Wm*;R?2bvxf_m#oQ!1ndd_AjDyxD^PwD2Gzr#OsWVhyU=kUHPxO~&gGvKTt?cu@`yRdm9Zf{Ij2@BWkg~zWR z3~h7MVCuphFy@DK0-0F{_gvT?`gYES$@90t;&u6O_wW0$1Raw`@b&R4*mGa@o33!$ z;C8OGRW$;6$&+v19(6pc z|1W&L46@Ra;o38Mx}Lva)n0h(>s3%wgMJKv2QC=^Jvz9{H{kof=D8nba4I_^1@613 zAGFD}Cs(i7SO71NUBMDWnZGqkLu@8gRMko?SjE6X%mv)<;5V;x(-cGhES`r!v{*F7 zh^a^}B-o49f<9!s$Qj6_0Uvpt%9=WsG`_2(%EdoyM~?Ms*%ao!a&8oDVo_-o47=-V z_+?j7pmOso*T&p$Ly}n$dx12>D9eWzv_gjYn%Qf zyrTqKBV}SEZ`cO7&^X`x7Eu}-NK~7)X)c*aG5npN0kN+ZuZ1VRo@;Q|@>wD|e{MYC zNVxvwBRxx|prjnmdHHjwt*wosX*i*KTlmYRr&`ZPgxUR{{s^n~6nOr|RmXS-vksJ2 zhV#hu^e~5 zn$PZq5OcfUmi!`Ev~ee_*;N3mcNW0r{YB6uF#%d;q(XjaIm;GAy|=$yaf(MBEP?;~ z_(xcWRDmjS)iDXjlP^EEH{5#qQP%5V9UT6`IH;<@-2Z6gksmTi-_M=BNKc^j_S7WJ zxkzWU2*#MIGIsz5ba%8%O?E-Of`N;62;fw)Y>_5Kil`zwdv%JFSJJo1#@QIu%8Gw*|!iMD&`3?#s-i^uJ&G z5tR8`ifFOw8sE7rgf4j;Ff_hWv_cHRerE=zI^sOC|V` zL6NR>#W<8z4H)#ta|mgyBQ;H?g}n3>Mv-_(HZLTCjcw_W+(@vC((TfFp&*QDQ!t;9 zV!F+=+bBpt+HEd2dq3KKvO^V%$mEyaaJQ1x!e?4bQbARDsZQt-C^#ciGK*B^&je}}CH=JAa? z{y9Aa=MC)ydD&@@ot_N6J7%+={%O^2sI1`{dw-w2O19ur`nQIwPwT~|TAOwi!J@T$ zVb8$|Xq%G?!}_#_+-4~(@ci0@<*;yFzHDbH2@!bo%AwGvc^X?UuG(?{Fo3nKpbVO) zCc&^it)O#jo=`e&)<*bZ&L-)q?9w^|9=l>N+qZH{0rc*W%}^(+w-!KobsZelH3tTE z=g#~k>+>0EEIBbAzF)Efw(KotvIK*==R&{EJoym=3onlQ+5MGx4V&VO3y*t^}drx=#3&4>J=N@$av3PXFh zl=bKBuUEq2b^B!Z(mpp09=sd_UU9H_S1~;M@e(#S#n+Xb5XS;$SpItsl*1FF7qI{c zjUN~gYo3wJ_O-}r!jOE6*YAgoI}SpVifyzkR^ z0``{O#SEFm@4E>c-6s#4i+caoSHHmGb^FCcBLe-qWWya7@PODqC#{BC&g;Xjf$Q_V z2P)wGDXU@awjy}^>OmqPwjIX&utEOx-6Q(4fY`>JMbNHAQ-*r`Y4u*%vbO}9XQaRx zgWEyV)I|2YKW`|2Aw6?p-S$FQw01unD6NFnSxw-#gWExBaso>@e(e24uz7EZ41QzV zccN9gXRG6kBO^c)^e0l0XX-V_Ru;z4KmY{RDZL2FH~38F%ZDJ zlUK9*OG=7|KVNYav}uvXkbA4Q9DsG(i(yw`DVv`i+ovUTZo~VGFK29makDpz`r_0O zyZOagfHEaGzVr19|1`Bt>AAvaiiI8j^yV78KWLmI%PMOi|6nB?sIIZDr%a?+&%AW_ z>kUJoZzn!3EZ;ec4sw|MwC*Ak$BSm;HH2mK+N%D6=IqmXDa)1I`1$T@4b z`E`jCT)|i|^Lp~#7g=?f=;6O#u@N2`JCiNy(D_czEj*txu_-hA&Qk_?QUu~P?;A4( zrmx=_g=~56nzI=FqHVk7{YkKB%U-^qbkP8kPU;B2zpg(AdbYNseE#(BA7S#!&62(e z6Breu0Rkb!Zv5AG4$T%*!zCv*87AI$v1co~^Mh|;?xx+0E1xZvg-=k~oYLa6ThC|c zBeyO8U>W@3oo^W8jm@$t6(ABYee_5??W5obRJ(@Yy@BjfM50P?c9 z7L?nzbn_m#^}{JpTf-OrdWH=l-)J)3Dk}~Cb<;UkJt;P!`DqP2^VI^8Y0Qyx(4&n<9sFcEOkIgol}dxc;e4@hgiB#}mkf1#e_cXHoQL6l5SeG;{E6mXZXoUHe<;+Dg%XVleFXcc;SYT?HDl zgV#HS^q>qaqLEZKM~)~Y86io?d8?2qihhzi@wu~|oc8od=bN?{LIn|zgun~>>4|ir z3{T2LbhRT8hguUX106L2)FPImUXtDf-*YWMd2J1pAevE>mr2iO+6n>Ut=XoKOKN<< zcB^Ypn3@M(no&VA@*0vk=A~(6A_+}o7>##C`$slugsJh65R!@mp0`Vl6J8=871AUc zX+@f(*pKq@9T#nk{>!kjK2v+3;FQhg?ObUQdLyv>GbDoqCxamJ+>m%Rkq9Jc{ah?I zISuhTcs|+md%DdvVM%j>G-ACqD6l_d2wxxCHNX9oNh-C1NYg=RLb&ahnb{&^*=95C zq5#*ci;F;# zEMVezVLNCLiKf-2AtvuzEvUk3h?&Q`WfIeP;ie(Rv{VEgBF)!yCo;}qaXyT5QA}oH z!85E+e$o<$Y(LRL(rB%{FE+pMu(kDNgEc)&XBY*)C{y2NljfNVy`mr8V#C{S^nBQy zAG^<&`E1SX&)oYru|5<@9ZEBd&(G|(Q!~s9*~{y*n8{0jK^&ll*u57HVB_NLZ_I?k zk_y%Wsoanz@%ihIh18@3n6hXad^l|_*KHF0H)?0ydTw7B&^4FQpWXKQ3`S3g`v-N) zg}a7xE$S!6EQGZ?4m#G2*!Mnq#SrM2mkz&dDu8D{TO#)}gxD2B_;`(|ny*&Cyj6R& z`EWhldqICVvMcu~V8G*%4;R3m!V2EbL{i&*7YzVJCn2r>&3~KW@WW7pl*thiDJE#6 zh25fA6L|iHV*u|LX&PVrVi}ZF)aaspaMj7(I7$ZqUY)Q4=C9rZsfme@kih5595JnG z1R=v5nqqMj1PeYdJ0#j-k!TGu>Ay03(zISz>mH?Hg-OH6?DO<>LjZNwFj)ETA2tAL z;gP0QLVP^jbaqeZ*QGfNfZYAoT&St3Wo{09FTd&E1};0LD|_!>&E5>-=WSu_;mT9G z!HNA_F`C<_KUo5scbBkW2VXBm;Mp67GK3gz`Gpnm;%CbszXK$+zL65LVCw%t{(y^$qDfNq8;$*59>LVo+tX7(xt_ev8X$SO9L!_v>Nq$~{a=oGOlv5c_D_TIp|N2r&#sL;%)rKM1dkT>&NK zi1gw00_i#*xoVKCf8YJI4aQ7cFE!G!+`F{OfQPOe$O`0>Y3pF}Pus?{M&8EGWtZMc6{u^MLa23XdYvrZ`AL3pMV--NPVg!d65?NuHW}%#r({eC9ryH zp~KIFG3LkqFbEJG_{-)4@Z85s*?xu)>)rxxAHjo){tVXU27nU==rjf&R-8|5z~l1+#*_RZ%GxDp`=Ynrm@DH$2MdS=mlI3V>hy~LW3#J*SiNLacM*7*ri&UeBohiojzZ?#Tx%;vYe;cp_8iEk>%S(^i z@2=Y?xXGPPZk_&1PeRl)UAYiEr*FV52tw@gHz&aAz56wKLUJloqf>U%qy(5a>Jkp$ zwrohf`0&`7a?r=gV8`qX`0V!K)^irD+X1(IG*w#;x_45vm^i6>TX_C5JJM(Rsx5He zr$5TY2wjcNN0gZ#LhP0gzhkGFnZ(p7Wu>OTw}12wi0vpSh9}0&gvHyOe9E?hAmkTi zy1LmaD8{0E(7SCeyf^YJYuVyN#UCLC(7Uxa^&-aRfPde4p1lsP z-wC&W@V(MLAPoc(38XVcg*c%{8+iWm-&n6VW7SspsrxoL6|ym{Sk9r|?`6nkpiTv)rSz^aMh_OPhO_w1!7I)Y&v zb{~M7|2YMUD+DjR%ZcVBOAlt~vIjcSMj_|;1-WhSugv`l>4HHso-xKJo&5b!a)BP? z!QetP-5Y-^jB}q&F6kY)*dnM!cT7PpS)B}uald+O+mAGgrPVc1q3NFJ8OE{>8AuvG zO`TZphrb`LK}F?j+RpMekz!8gwHfR(kzxEkqcyBdO)D>rEBE^4FI?+JUr6_RD9hJ; zH>ReT`zW9X-qOg(#B-V^CqRqz6iAHc_;y>6PF-Knxrr|tw77SKN8I0!UF61g zykCiW@3;5>f8d8M)wE38it(P`BxEP8IXAO1rY_7(1leEQL(DkDmphZ4j1Iyd9hPd9KyR(OA z*eR)!?6~?ksEgFG^f?G#;+SaU$fKoYDprpmgsruiQVDMA??|@54<;zBahg+3KKy&66uQHbcZtrwP$)_ zcfK`KjCTOtT4%tY5g`@1bAWOFi1^F zgxM>0!&?)7Vb?`84F(PEXfeD2UFFE$L)zxcGTDfdYeewVO+$>!H*iK5l5s#=u4h87 zSM-PW9_-jx3Xgxdh`nzXQ`f7Q@C}#jai3xkq<^^N#Jv z_B}IZF|6N-$JN8tc;Ee6vHO1XUkf=ky)mAor6j_W*9~SmV57fV3)9$rN1$JqY`E(J zuGx)``{)Nh!M6OeDF2p1h#_U-dZ{5s2r;DR{nNWYu^=zM7Eijv?b+*xK#R;KEU0zw z+w&QfFC|6MdwAidVUV4X1k)DpfDfl2B_lv?W(qug{SYQ2^43=?VgBm93RtZr?Voo{ z2N-@rCnzYcg8SZ_EA_oojG1!dnPZtlCmne?bX?;+)+!gYc`C! zPz1zYoz3o_HXI+XIHfC`Hl!WzGybuFCn_1om_q;Jrj(A7) z$b~yD;L3Yf^RFg9t7`D%)ZaZzfHc@5B>18n2&G?CGj)pbx%QVDxXs@S?p z52E2OQ!=zUf7WdisbochiAM>%-wQb=E7)NTF*6xG+UEWW+71WA8n;dT&s{BV23lMwj`upaW>{a(fEa3s5kidU>4*znw`V~;DU`3S_z9$+a8Z=BhNM=T#R@v}g0EC#1a6v5;Hd(HZKux3`66z!H zhvWLdEvMOO0P~AV;oKL-vdq^Y_l5PSckAZx{>^qeNGzXAUmFjb@{1&QJY|{%p-elIj{L zudRhzA*kzylrfPT%2t|g{5(P~MI-J^1YSdscwx%X4e{g^T%}BZTYWIU4^lszNIVrJ zFoOuOus>0-go1}eD`~TX+;7nSn$;sYe-Y0A05;3;B*X-1$=GZSp=6u4)Wk&~K|7A@ zFrP%Lhu6XL$R^r6gr5R=-M|GR# zUy5#%k~UNlmzmUo<*Fxn_}hH`sF2hODe35cBXNLwVdz+skaU^q?nJ&fcKd4V>&31i zM$To04C4}OrX5UMjEc|H48!{)={BVyMl{ob+X~Kk(^i0&5P|3vFZ4 za3fpOJXTI~oVO?~Wc_O=wq!%+5#i1ct|_i-`o+}$ zYwH`1M2$?2Yowc!~b10kWGXi9sLudm@|<|{kt@WQ6u`Zb=@6r&VYiVYS;TGe+`rV z63LMCoUh-09HVQSyJ`=-K4FEHH0jjb&B;h%XrP+vde~i9#wHdRq`=@qQbHUgAhJei zg_+1OsU=35VwTTXwZ*(N#`yY~uQMcq-DZpRsjSB?H2wNK>6z<}hMZ=}@a3#cFmb`w zsP{vFscTQ`0mF{SgH5}N;i-=oJJ#W8P2%B^D+fbPdNM;Zp`KS-lSEjwb|1X?)h~|a zJk2vGAjYmYX0bwQ8uL#?KE8MhqW|Jx;=HZ!#mtQ?c=_D*Lm{VG3XGe%3BFmdRUz={ z`Nby&&W`Jg_gw@}e#8-ugb>3ULoKbhzggwb7>g7BfG4gV%yhD*E!+X4T{Oft>?ndK zM=yd1iz0K!MqOV7M2OA$c^CX+ z(i%RLX(&}b7$ON?j~-E6o1m4e7#nqmy8Ch8Xj#{y}L ziS;{{KRcdm1xS>2ocd4tf^5D2(yEK>Pbrv=^`pG126i8;graI>RQmsGzUy|sR;@5w zkS!2aUzD)SmT;kKY%t_M7;-F@^`G?nG=P10iDAS+^`a8b>mZ#=0!$XjZEc+ z{X+EFLAb(gndZ9F&AeYf%ET8Z&4Z5?*w8iZnMy~sYXR?EYY%c@|M8n=M?(>cak9*g z2)umBZ{WC|?XAUj$G;}Sy1hkmzloG_4PcBow^0Cc zKie+{Khh8z)*J3Pjq{VcZKxrJ2r(5ztA|7(oQ%iQV*JSw$HQrTI|r@~I2f(ku@9DQ z-3u#rKE3@s=+vT_^|~*AvjE1-Tg~%s#Y6x*^Kb4O z;Y;^<-{@&DV=d1P^V?py{A4(;hYJ3f$KUn-R9L&G&?@|_rz%tZeCnd(VL+#r)}Oxa z&2QkBT?e$xbKV|QCVDWN79X;_jY+wic9@wN?-c%4ns|?n7zSq^sp{~9V`jkjtG4uN02IW7*+*@HB{zuM-OF>HH1bW_pLs9)`N&Gu*Z z9~As@>sMG%Ge*rYdcataQs^|`>M|Nlc7TpARt+&7Dc0Z@W7H42Z4B1ouvJ%!PbLs% z^&DNss7V88P|&^EG$vxXcg|cvTE^a=>iV|%Sde}yXalm;AWQjDR*|EcG?2FPzo7Ys zdZqn3HNHX31q%*H#(u=PUUd{lWL=nqL(Q&^MHk(5IE-MaV$e`@^0*!`>DZliG&0u{31%sd zq{KLQ?Y86DyIQlo5DE@f%H&A%l-A8tS?~sF?rwW^R@4={wQUCX{=Pq><-^ytudsq4 z&Tx(6HeQg1*t8`(;3K3H)UK$4e*DYF|1cQv_fZS$t*=+IWY;(DI-c!Yv(0(m&ZM_` zXx%)G1!pQMYvIUg!yO@pZmO%1Ulpl|0KSiE*0 zyf)q$@MG1rz8)U9kO!>#Z?1;1AV(>!#x-FW7Zw7&4!}VYC)f=+94q`@dCM7DbTigQ)t&b724#c z!x5b_rA8SB(MP>8hcgU;T|-RDP-qRE#(g{!>7^UAc@0kux^Uy1Y+E-SD5``#rBzTN zl4re;U}3d2t;jGhBv^p?nzP@d@-cgW#woX;SJAb>>LLJMHeQo4xQXM)4qLuKHN_4i z#Dc!X!^gRnK}85 zJ3jmtW^LHXGQt=nJWg?vlZ~1al;Vk+5$OpD@Z&>Qc-Eeg?|#Gd!0J?5O;N!X)B7QB7knULN9=gQ6l#js%g zPMEuX2h88J2TCgySF|4|JPta210ckPK0aD$hDCTeFlUj55c~X&^PpXGd*JHnakF9k zk_|GLW<%-_l8*L2cgcxxQtuAd*Z#?zRq)c}pBx%*h%Ea0Uhja|)_n)z;#Vg?HD=)9 z^H9bvWgKfrE6jlV{Lb^BZO*S-2cP_6HcVK$L6$dWikiqU()!RR>1^@gqB+>8a|uD) zHMmnAyn5Yl<@-7H$xorAiceC#G|O;*MrtxldFUc}?j7$=g#{aTduSfGYa+PycN~eQ zG{gv*hbd2p&?Cen1$)S*k57oiLrr}xyAO7MWQ$K; z-VulwnY0WUESz41+%@e;J=Y;r$X;dRwaTh$ptMHOTJS3>XM00!3T{aRwSf%!PiCOm zG{x|HsR=0VS0V)j?I_wfj&h_kKc3Ovhz#j4woQpxvVjodo7h1Fq(Zg#XpJ6@Y|&^w zwQ*WPG63&H=%rI$Nm@GYi+0U`wP}bEU7j{U`n5I0 z81h4Cd{~kGn%0?)?2?(>lHQEhYx#b}ywA_}3YJmQmDR~Ynp}wV!Sc7*6!aqJ7OsOM znzmk0n~u{zas5nm%Cx?=*=oL`f@gU%Xlj@AH3XpH zrhe8I5W^rAY85?xm7P_?);C`J;xwp6&B8QWPH1DI2!#DTc>BTnruZngRxs!frRdG?VF{^%ELmc>a?gE`m*aO8ERh zCT;K*t!s#l5ePB-{_YX|n1N8%SBirL(O+)Oa7iU6wC3;tQxl>ZS{^_PArszb8R+N9b zwX-nVVkVs;vnfo=f+J4b)DSb1$fD<;{Jrz_P(V%B2mq&1tb$!7l`a~)!I^sw#r*fs zXohJG-xVn)YMPmKE$m>LVSZUPL6Kn;JmbgHJekTR2;K7GfLPdG{P6LP5+H<_U$N+! zzjSOc_cE#&o3odCL$;Pi{PQviJk8V91y5?oE{jW}15$3huwx}?J(Xz}$$0o;luM~Z8l8Nm8H8sWD+8-ggSWBn}pkNj~qiIu+i}u@W z`rb<;%+w6?wMCFj)$eGe(tomiEo&xOUF=9EzPMq6-xM^HNOm67qWVrjFw>?Vk&7hJ zubH;HH;SL_r6DGI+$hbkU$g!O)etl3FQYUNB5}~FX$sRQY0Uc%8WfYgm87R}ak`Te zUDOBOiz+8Oy$>hSwPBgDLCaU&zW_JTc&yDQWT?WNZy3(`u+IJH@k+Y_MI%hjFgFb` z>kT?J#lmQW`D(rz8e`_OSo;s7d_5n}#rJ~!4qgI-PFP1VSAu<~AiK2BP^l~J-`Q0t*f1~OWCv{!5@fb}~IVb_6j*jZ2ty9>(U zf?*xuykk2@A;dbjLdryi5Zjht%Ev6NKk4Oy5Hriyh7iN=QxfcQ2dlOeKv8)$w8>3{ zXRkSi{q`GQ{Q`4W?{G>Y!1Bp|*% zanlfE^oU};qHBoRG{s1BOt$$D{ds0u5Y#t;Y`8;ch~4+*JSZqZ4KPA5E3BHSAx2Ru(hxHd zV!DRd{TKI#?(H&R&dNRTkBO_{>+|$l!k?+mGHx& z9f9UUoA;E!&zlO^`ydUmkEX1LDT~p^7rh3;cy9&!-M}8UXEv$g^hqZ_Ej_<^R==Z!nSImmyDW*T23~GrlP1_A=>N;GR*$=V+96&<5glxd`t>d>i zUq|AVme;`UBBW77W-oq2=KPRrj8T0Lra5gziiu~I`-NkQ*?NUw-@DKi@)|EX2(19= zc-r5H%rIt6m%%Yv9{>;`rYdwa63j$~xgo{q`~dESD1WqC|M9CF4v4vSQHQ?_S^_Ob zJ^?0|I5{Qgdzq4y;e?Q>(GpbRqu zqBTIgoX%r!8x9?EGp$AX__&$y)zbCMnUWkI2eTi(DroUH+Hs%FUkT4mTA*<%i%iVA zdbsx3BLW4)7_))J3936qhjwZS_n$k=6JZtR!7wm3Zs8hu@w-J(jiRLqTB;PL+i3O? zd0FuOP3KxKkCcgs5Obtj8R9mGRGItem7YuvSH3X;R_`uUnM#zgBr}&pMz>*Kf5H)P zP0p&(xg26R6M4m#r@!*+i{t<|aLz|B;gcPe2 zn0*;6)9ljPT1J(D&M`TKbRZF<=?nRLR+(b--u*uP#=FMY@28Cwhc{v}6~z4oD9=nRJ9iLm2imuC5O1;^G($A_l`^vFjsok}fe)Uk5>K zI4CPQDVQM4c?I@s_*}R#q#07-;(QJNRTK{(MPNw`_7Hu_ z_9w2dw+A~Dg`oZZ)sX(AorOtO*w1J-n-_%B+H*gi=J_OTsF2EpG`4Aoh3W4(Jszjc z>)SaS?i+C=M{K+?3-*^*NUb>3nttof6Coujo@o$G`+0|^F=+N5(e_^j3Ty9ya(M3Z z#jvliGV1){!#cw7V>`n>bZ);rTkc2t#mBE4%TKEy~+oF9dHM_)qv~>-!yI!9I#pTt`^`i)mnHpjo z$z2EcT-cwrOALs;I&Qf`LyVAOEFeY*u}N#>L{%cm>gwRnS8;v5AD8Wf558T?mMv!u zZVMNl+!cySs^QKzW@}J6?!2cUiT|}@&nsynQax9}FE&^xv=>S(9*AKe2 z%5Ic8G#nb+Dv84QbYU~{Na`6U7F%0dL2Y4?Sn&y@%*rY90hu z!8W&Gr|B#?3`GT@Ae_uk-!dA1;z8D8_==h%696E;jzN z;B@$)7X|Go=;ao);&Tm+F62-a#38!24e1f(d~u<{^-F4^TMmZ&ifvUEP3LW&F2quV zen`5o`^_XJDKsu7&S;|}Gq-69WTkS{dt)NQLYIN9JMwy6p?{?DPjExtnVNVC@hr5v zw9Mil>lpTKG|e%xT@r2O14b36pd~dm#N2EreWa64QcoIkL-fnO+(3Q>(LDBgJ5f$9 zFS=|$HXdU?{cccX66@<(aEzB8&Jl1trSI^1v5bEXhKev3uw{|BeQzsdOZ#)}pAT{Q zhH9ljy7Ry<*nI{XjSxePE!A=#yqJK_GX9`3~Jo<)@->B#A`ir+A1!n} z6@w@*+%ODsnkB=Mb@}kpI4rARTT(&OGNqA!35u{ODB@V%iScGrl$G9bn^#LNy1fC6IJF8}e( zY6ox}=kNG)ZW?0!x@N=O7xZISy#Jkf3~^;{Sd?aEjwt=Q2!FftSaxs!{$V3boWF(rCQBZmAP!#h ztX^Pg8$2p3Nnsp69lAD zEG({s9i>$^w*RQ_RkEHFIVSrL5iIl4KJ?cK35pc^b>D{#DP{)IbZs$KuLEen245dK zM-N%$ zY_=_^hR1(5>SD;vNVC3?3tt@z8}=1CG{kUXp=*laXhd2$lwteby_Z1qj8yA&|NO;t z7{6=-)5<|jpZSmcf$28BqSjs`R6@n41!CC^|n6d_bWET z{r{e!AmCKM`}_=CuLSqe__~6GexvNshQ$q+cZ;{CYkshYPV?D#KkdW77KzSQp>PwBYZ!e zPr)ghO~EZfdeL=l2+;<8Pg-=2`H|u}_seV}X?Hp<7MuDdGpJ^A?)%%k-O&~sGEB`6 zcoL3jt9B6tAxZrv&A)6m&DZcaQzKEgY5r!;=fc`vLz<+71kyB0 zWxp$Y2-MCgvpKwmm>o$b>m_^72rMFmmeZC9ezBiM57}=E*B`SRfZPqMDdy&+AtWga z3%O~A(KsQ3V>Zn;IS)C+nqrP*rznXErD?>gqt<@>Z1(v0K5=}CW7+=9nS&QPRt%B*xceIRP^TVHL(D{oDJLVJhxF}|1NV;Lnne^4 zGed*XHfQvp?Sf&Q;QZq{G4n6~UJAc#KH%7oFXp)3En(z2e4UGWO^BxB^sBtZsi3*A z<@m>KyoZ#eIOc2N;;;hRVSF~Gwiu^FkSw* zt*EYr`~SXxQTX9=9NnuWT#xr%5AgWtg|JoJw`{j{^$f{`fw_eEIQVMzX83aM7S^zJ z4KYM8A@wGQ--`Mm+MkIKqy0=nOd!Nw8^1z8x13oLf4sQA(h!@p#>w0xuCHr|A;J?M z4CiQ1UN;!>vQuFZL!hk?T5Yt>;pKka={?}MeytdFS}y*B~3tfACNC{%6&yw`%R$Rl91Rb8f?D?tS`scCWMN+BL4V-uIp1d4SY2ts%z2!iP8S zFyjjEf8riX=wqjdd;{yE{qPs-YU}is%NEebPkDwx?`_yTX>`aie|^@ISJJzGR}f+q z4Kdf>`F7Y3Z87u@IoieC{)&SoWwe@qmT6S^?kRr!wuu>9`{)kZWavx1KcN>!gI=yP zH=1H@1yU6(No47T8e(OdV%>cYH!j(Z)d$Bs<5bSSHIEQ0YF+aOrAnX|gjkGoRXbTq zIs3USHo^K+c|N@|#6PE$F54(HbzK6~lU&93uLe>Lr~Y_a)&1!Wd#urW&Ln&yjLiwb9TF7q6d z1CL~tNkY~3?@&i7g&KWq>!6vh?^UO*54yP{+@f86L2w|ozm6m;tIhSJI1@DGWL7d` zwczYjXO^~2PSf@|&=(Wut1s`+28{;FA2w(-VZ%Ae2>CqW)ppG!}ivnAt7NAuDO_#v#r-oQq=B>(CvFG^up@PJP zNU&UamLkXObS5HU=bb$!S%b^fQe?4h)~Z&^Os)|Oh$*`X8Rn`&gsQ{pyP8`ig6@t^ zO0QoOlfq+G-lYp%-T&r3a71N9=aL_==PvY-lVmM?-X*uv)xTO#)6=uGVXM&4@x1b^ zlb=OTT)CJSZFA1Wx6)5V#SSKmXnr znjqP|>$lP;zjYlww0Vc=&)Bzd^g+AR8;(23=sfWspZm7IyWEJdaGePeV$cxN!K*{} zT}J==^+%b{b@~^sH1`dITSp$Sg5KXFLTqegkpB9#-=bX>kJ04REdBEZH_t#{f; z{2Xt4`QZi~wtmA7`qQ(2LfaG~sk!gCL>scNCQ* zRmEJPHIJcb97l$QNU=I{49@*)gd+$Q5b^MWYucC)G2x{rTy_eD%uY0`{=yOZm-;i14oBFak&ZR z{pHuMqucM>f7j{O;YB|myFRf58j<#fBb=FEWZ4@`|0e}x4LpfKk$1y1>+l{GGq>!RMO*BO^jT`Hk!8ku4LF~Yp6|8IMo6{mg7=nZfut+(KgH@_RL8J~GCorqAbJ53;GgKIp!ZR!h*)5=Lm)in~D zGL0`jy%{0)@&CAj{{6b!oPax=z)hMGdn{f+7oPF@#?Si3fBX*JyzXH~s($Wize9)b zvwQNKKmE7w)A`rm;WCFbeWc59PQXh;+6%|&44OlWaB~^ovmH9+*r#LzVnB#F4FRP= z0F45EPP3l}kAV&icLr&SW-Ipez^wTl+s!|Su1ImF%nXSArPE$cPkrLb866AkEIqQf~Y4*FBG3 z{&dm*y5gpL=o>$}nf~O}zeTH-OK=N+x3Aq`{(In_%PYUH+pvZH?BA}W6Q6ge(;@rb z&wfQ8`PL81GV@vcik&B}d|}tOPB_|X)KzRxik&6ADal+;Y2@^h8I{W9$s*a1DB2mI zfq{-s9EHu<(*qr+A;yB)-Y(a|nV6ZO?Nc*mkul41JF`Ty-Dv8BNW?zWXCSl^5H*2BgSXv1Z#n}r zhqTlC;S_5_`&z0AR&pHAlK{FvMZei$WWqH{^98}JP(v)VG0%42$7(+1?8PIj6}EuJ z*b`gYQDij5ioc^m0BAa%810?}qf_Cl_P=}Nqg*!}Pg3KHuh%N*rjTvT^*%aHiU6$= zNIs1Ob4d*eWNCn`Lj6efd%T~=3or#}+c}Z#{!$xB1ZKVr1`TMG!M5*#=X2{rTYuf} zJHrNIkP)MHJ{o5jfo3Y+OYAoNjY(3m^&gr3sjWHA(D9NuG5I-XSo6^{1YrK`5a+dZ zc6Hr7JJX@Tp#j?YTcW`sGAwnix*MlGmiG%FSt8u_#28_NC@A0Yu_5}qw;yXzT4v2+ z(SL9GtE_%a@4mQ_i`)ilpO4r=}Anm`$Qil*b^D950 zJ0ILqOAxAkXXjl*cdgxG`r(-7r_+i?e-WwQOa(Z~ z56@btvoka>IMnqvsxg+)76WpOw_f8>f@AFO;Q9#UnD@8XWWk8PqCx7LL}wa_P8VN$Z=IaJLv+j$jF$8oVg^lYk;aUI{M&aO*t#Rs4(`>)It|xx!6v1hihiK=7X5`~Vku=3so(opmpxVjLIfDM^;`%XBTPC8cjrDK0*fBzTs538@uN*(aIKvH1#90s-A ztU7FvZEai8-Sv@~?cnR>{YDHa`Jbo%t_yxK>TAikUnKCOvL@JDi3GpC#CENC_Y& zuto4Gr27hO31(?zZ_~4LMkfcg@Yk)4^J3fBVx1>dJEmu7+tf78aHly(f3@+jg&=({ zxP?ca%gnwu^?8npu+?Ql=k`>GXhb0p*mglO&b%aT`ydzB4<0#q%WffU^Q0Y!uar|B z4_()ItG-T7^Q@`-TNTV49gOl0HJD;ShBQZf9Qo=Wx#!iG>R&t(EJTKd!QPT0OCmGu z$-VAJa6!Z+257~?F7lHlJ+sz9yN^LVMVM$Mj7IPKI=b zF6fG+Fa%vQHl8OHw2kfO-@^G}eZE+Yk%rf=^cx0QDnX%CXjSiba|nghtKC0n)W!P~ z4-n2*?JUkcfs7B;^@jv=jaagw&jJl2zdL_Nv$aUSusw!-Qf+@A)?tEJs)ANn>9Q$R zflsRtsaMi(x?@^o_P4rj)g}$G6uqMP-7rVYnD)l)t3*>wHy7PMce^6sAo%#`Fumq^`_oYe?Ph|C z+9!SEog3)8KfaTGr4U}M6ZNb^R+@JIm)~IY*G6F-4E~rp@l7v1*!;>tkuR{`mkNk6 zo#GE~Tt}~a!2$G?C#|sKf?VXm4cqDR>+Yk~*D}4O|I_{@4%q$Pu}`8S58jP-;pbL= z{M_I9;hl8*+D#P~`%@0smEQYm@uhs=AAdv}w@yfK6oqMf?zD#35$0JLN%xuW+)x?c zQ3MqYF^dp$k7oN1AjB^J+5L3Rn%h9c;pkTn*>@S8_<{orN{vxj_}jW;idO&h9=hn7 z`wVhZ|AhguSUpc6#Bl792d$u2KW~3x`a|w-INX}ZPA z;c@d@n;a}Pe~TrJZrd?MYd22N=E>^oxO?FJu%RiF z)({IbGqrQOSt9}WH;W?0@s7wpYj^P=bIIwiZ`2Uu?1|t0)Ys|3&D+iK$V6$<5c~Su z{}&y+*RIL$e%+l9&?#U3p38_~r^T@c?MAWgB?MCcJBjrQB}_rXAQCUyeu6M``NG8(Wzg$Aenf;gZ6um zKbrR2eW~N5mc_RWmHbUU^o`3+nezWldD^I)qqQ`)1h>w6XLFfed&fFD?MoL_kxDiw z!e!8e5aatjNk)hf((Md7gxIqW*n>WE%F7zt^P4|=KK9*h_}>svphN4E>7I-YOo*eHGUwa=|-i|Gr! z_~T!vP1`3_a1o1SuTceLMO7or@0aokY|fOk2rbGc1v zk|BjwG{B$*CR;bf0}{^t5O^uWtbm+d`O@CmZn{gCfh9;YuFzYjrc7YW`lwuTfE*v8 zu|!Y{OZOH*u2vb=h1ccGR?Z3KNqr0{<}+W#ISYG=~z8LZ1ZKev6<3VSZvttNw z6NIvpW8SZA?k@~-%kJlXW5NWXWHQY*@8_Tv2d~Dg%|R_7zIfYR|4@EjlV%%thD5O%4u3vgS3ABCBN5gaasqOq6#?{?(YU6f_lf!eIT#6 z-i0$$O*h}l^#0YE`0Z#*dGMJ!i-u^-&S_Mn_oC2o-D4- zJlWEr8YELP$Rn;FkF>JoZjX20rDk)GNqsjHbcz={m=mzy)9~2u3uXoPy}6&3`4P5` znIX)CwzgRhSWU&4W>|<68jcPi)>BH8d5VbIH+ zZy&Sm{%WFes2LUpamqBryyOiutm2wgUh}G4)5@%m5froQX||2i-mbUZep4^xc;1it zE&Ygzn8}vsCWePLDZ$hjJ1}f?ap|V`?+6*;JRL$xX@-He%Z$(I@xuiF?1HjuO)-Cg zsD@D+jVm8y?9kFhW3=~*MKm!vL+c*dYUlx*kOCYGVdpm^sUFy{)gifDQr6%g9kAz8 zqu=zvhHVO2Wxuy;e{6Ge z(*&*CxPzt@<+%4BVRZ2GAg3u7Xo%_Zh0~r9G3)~wX8rX{#cV{9B@h+}j+uFyS)W!l z#b8IZ#W24#?UA*^z1F;=fd+#LX!~t_Ub=9^pbfWAP1E{Ew$t`WM)FuTNQIzGw?{kQ zLHn_OBfpLqpilh4vuU?o#_0SX-9_KN@-Fj!i^oT3uiY0Kf6SfhwwPc~m^2YX9;1FN zT{ud6@4k?>PfpW=kL)npnwvl~Vuad$srIPCX%1oT%GV-r-TKZ=D5BZ0o=Ju^hk3mW zZ7@OP+TqLw#l&W`=AOGQprs4P=)ny;=+P}Z3>~PWYexSTDR1~6L(N>LDQ4=0tj`V7 z+9H*pDJJFZ{Ymfx4G;4(Eu!*W?QWtw7j4Kb^2=`_Wf*VkO` z^8vBnxDeIOeWBgn_VFT(1kuKjU>N>FJEu9}GAykVQQLe?nT*-Fti6f0+1bSR2l4%gdn{elSb$&o!S(dFYpz!JNh2$ce!}kb#kZx=NPMHuU-C2h+~wDyS251k zg~P+N`a>tykR|%TKJe9x>9Skyak;J92_N$bzwgD*pf@KFO;`WwetO&4g7AtVV@^4y zIUsiD`bX*2pZ*VX+pzr6A^!D=FQns-NNZ!g?Ti0KSKaww<^HJ;@y_Fpq_-ZI4jird z#U1paZ+^dm48yf@2r)kHgirh{J+zgx=jwy7Om;go&fn;dPoza-Bgy)5{@oV8O^Red~{2Rioe27r*?*yXb@ea#l*7I2iY#a^*(=^&a8238{Z(``_iN6%`b?f>aPCPT6+7JR!8B^_zo$$ zBUhdQGBuT{9*f<{HN4Y4eEb(5wlDpklU`W+)(z{SSv6kQ^& znUhTE#vX zq6;eR^z!8;PPBg6;kzVrSS$>n==Bo5msEAim3L)-oBHdfQ4I@L^TGZ86jIF3#{|(5 z+Rlk>5ihQPu(s34qUk>N>cd+GkBKDr5sK6m3si}JS}!07NGaezP; z5;09Ni6$W^#>_Fge6@y{agy5gi${!ECL9}d=5axuGOr;PYKm3nA8q;%Ri8PC)5{;X zbx!CtXgb>Iv|ZAtNK%3ouXXY9izkz(O~ zXt@GOi4O>-1oK=4nqi7rVXl#Usr8flF1GynIO&h;$gmhv4Cgl?$I|1U4Vs~RSFKvr zTW^}JW%CF8CYQjjZ~d4PI!C4pG8{u&BbK}t1!ryx*Rmj-W=RlR9`WQg!5nbGwRH%w z#{nvNm!Aie$jHyuyM97wg@T|qv^XszD&lB4M@FMMia^Zw^cuA|RhcAd*G_L-~}IXT;*rQ@UYcW*kLj@*A$ z$S%w>)<=TxSD?Q>vbkG${?9Q$J4PIgf7!r`UjsGjsBv# z1)>b~xea%8wVx8C^oZZM@@D#nH9xb6S8=X;1Z=(f@&30T|8zR> zxrbB&jo-ZTX8Mcse`>C+C%vI_J?#!l2dTo~RjeL2ae$}F4gIF08?uXy&~D0vEzX2; z3NsgPnbof#TZHX}PVhdiFgO`7a}H-%3L$=d^(pTEu}&f|at#%5?@dd4{GC8*TA z1yZFS+i3d^v}K~2G6me*CCJPsO--*!=YutEG{v|(M-az@ss z80xpvX!8Ac+x-TiWP@Q|6H0<(;rDOSJPox{LS#}iaw&u+itXw3JnImznK&3F$UeV~ z(Q&4bOeI=#{X#x=qlp)vKgPA65afcdI!F7_v>){fi$G|~p?`vn#daO3Dc=L-i|+$_ zbZCfHEnPs1$8gXjI{*M607*naR7NB(p${LzE!w-$Oza~Pvm0%(?lr_hL|Qxg&z zM8f3e_m%x6{d__bCq#aQNU|6*3>o!~4%;$Qm>`SMV6mDcfd&x1L#T09YKO?NZV;tF zj=C+F35vJz^&ih)W9vfvjtu|M#_zpk<~xM3oj=#+dp*<-gIKW6cb-=n+D1#)$n!1@ zg>MAt_HV`W;~;rVBbhuhEKdK|O>uZ+ zSap1?&*MBDWL1mUGg;{0wWecg-BL3DG)YW@1BP~RZZyS)XqIUe1EiSN5(7fhjn@%P zb%Qi>8e(ZpF~i)VG~S&iUVtQv1#{329kLq0CxwLJa%W1t-IjWUSgL+EA;MzJ4vmN~ zr77O1`K{`A^!^&jlxctA`jBl#hSmKS;*1BwiZ8zqN#>EMwQQA$H>XOcjPEagP2b)_ zB&_dOJTs6aS8KbZzlg3UG8%bZuO}1Nbx7A>f64QEWSe5LGT&cjgYdt2+xlf9>z8mn zQ?tRig>_HL4w$(@rmoQ5wqu&sZrnke7;*U+j29^+S(4(bNJGq)xNYzr8J5Tqi6yOg zH&!#xa+pjMbUbb5%VGJ?BgB4_qg6ZM-FAEH$NPR4Lv!R44P8vbMSuYl50GN9$z5qC z6~DyAr@uan5W~y)CDSva}PwAo??uvec6${7d&Cfl8-gN8{No3G3?^#c8 z_`-kEh;h*?-?H`C^cN!n#>l!iuz=oj~{ zH`hI8|5fzaQ(xW~9OOXM1vkXAlYpx_e6QW;pZ?(GjxRZO!T){UWpu#}cUf&Et087G zy*hO8s^#>r?|D^YoqcH2Hu~aaKc^e+e~2F4GGPQwS1nmYKl~M=p?t5sY{3|vf5z|8 z!UmKW--v^KpIP%WC$_4Q2)iyGr@#6A9fm zsY?CYzuTfQTCsTCQ0o~dnsTaf@H9q`_*e$Ja{X_eF0twqapyZHb#tD1xF+}KcZbvT zbfZG67}}Um0LiQEl!jQSF(&;%kD6jO6Wk$#8tfRoVMuqFqCZ4=x*)s#p;sHpad7s+ z7N?>Q>I3K&YKS%2{D_7QO=Vt(8ev`Aw!&33!%Q$+f`&j&gh((TQ*ubK_WR|7)W(-Y zl8{G6%JU{|gZKcjutUs_XX-Ii_W@~U=P@PYTW%c$>S{uP3IPHNHGa7$teeUVwq1i3<74zbz{ieKa{RS^Yib*3?UP!74#}BPRiSY&Z zi>)u)eUETHAAX;@&2?~Wc*syj%Kf>fWOzOucEe8qLDO#L;Vf6+w8iQS33w-s)QbU6 z8fQ-_qzZh_28tCxiCav^Vo0Pm2(c`X%?8^-x=YAp07+H>A{Pe9rNhc0jhgqzfHPU2 zzbaq7E^JZk?ojQg?CyN2&t7xa+k8E3S=jr zlWCrATx@>r0eZmDDDI$b6@;X`jGKoSMVX`7A}XkqLyGO(0&HU1;N(FRV93DH5ACp6 z|E%ABJ|MPp>%wo`-FACxT|-Q3iV26cOv1Di&S&~aC!MnO;1NTL$y~CUX(6^~BKiGR zBgqcd!f7uV<~aY-GnzHT!jH!RsY`FXlh$tBN;{^eO)%}~{r04%?0etz7vFrhog{N+BecgP$iVjRJY|3S^AnHDy;5yI2XRh2`yw~R{I_?#iVj@0 zJb4{1lW$*h3w`a%8|l~UH&MsVNqMt$bd+BC^aJQ!Cme0Gs8W9$wrr=D|J65X$24mU z)id^XT{K3Q{Bc?fDs^3cwr8Drj!dd;1}P(J-t^qV=>4yFR<>*&-n^YIyWvi{?~yIE zZF15e2cNvxuJpVo?~_DL;i5aHX6P-SJD+ZQV1uEH651$eqlkUM8Ly?4yQJwpKfoGd zx7=%k%c9Zcw1VvW#Oza^cLcrXP~bAZq&u3EmBj{f6woD%^EHOz&8-1M1(zJIgRC);j)W?2romD=wX({{}s z+T5QG4|34FY}*SmFO}))GRzX12*$Z+ojRf+mA8f70Gd;le$ZBUAf8bFL(PMny<@gR zTPLTC&SS{I52PcUVxgT1mh|O!v@h1un(Yv4YMFW)+KgPXh;3+YvCZ|7Ghq2V*uH*1 zBLVd!ZOgds_p?1U+o2IReoN4agH(Kd?zp)B8@1ziXmkDG{d_!vQ!!g>DDmVRl7aV9uBHFOZCEi%j@<1DRTKai0?VuCg?Wkd6h zkJB1>p^bi~s);AT%(P}+eLudN-iii^IQgVJ)3!M#;iUE&Fh1#n>5lhUG)_wvj`jr+ z7SlvaX^0giMa+?gf}Zb1$2X;!0gY0JL`OSw^oLfz~hPR@%Wf*sd8i{Qa!9p1WUnwnHeW41Z{ZnQ_;y$BdI+Yr<+f&@^-N zS*$}~xrkG3M zUGhm|avj*3i9sXVunu+SS!8|A_KXvP)Nit-y~?c0tVfJipJ*S%bl>QE9-7cT9uF`2RPL8{2GCXKOB zbBvjx%zb%0nX#Ikc3tC;&(I1szx(xiT2oB?lh7EG@1Qj4vCg&qQxk&BA&@cuQu85? zyi!Q`81fFuMiI@n9Kx$RjVtdzc4yCp) zF;{+V_jgy`5&BY>-J(z`p`1*D&ok5zE7KG!(+mrF$6XSFeO?cS@yV%88r>$yJWrXJ zbM?;eZz_Ra5Mo))6zimPj>v?@mC3ZU&N2)#;zW?&G3nOFd1o`UL5S9T@b!&Bg?`qA zv#LDTjH-$~2M5I7e)dI9v+V^3?MaYIm$Mn@7-y}f?3qv=PC7T#FI5a?)e)#pYY|(hDqLYBw*%i`ybgqB-`WMiP zpOV%`YjvZ@!5{tR74+?&{mSeKHG$CSul{g8Aa?1^X@pqn8To!p=XmTP`}F!6(erN5D=|x|N48y~6dpLB}u5{et`_gCDT<3x& z*q`I@id~z z)tQ}$Tx!x>GUac}8>#!Sc|74iL3%)7y=voq5ClU;Wz2S&+SVzr?Ium0lxA31-c886 zP_wPHE|(k^mM?-&I2S>%&_-~Gk52`+fM7+?3)d*uaC4;;$xU{(u`=G*%Ns#T(0_Vc zt`OQKrPlp1TyOSRFiI%}kU5_#`S9^lNJo#Hk@;E^ zGR!3*+5RNdv}>WDV;;Z$`ZZCJP-LWTYX||fDljeu_G6+MW&rKWPix45ZVq2=$x?SPV$f@E9`xXY}Pg7 zK9%PY7HI~+56?k?u*;kB3%^#r}|6uju_L z&9K<~BBV=nHLmaTx$^IWU=LS}k)c5&y^suwVP$86X81lcCV1@2)dv;jh-Mo|Uav9c zHA|zdwI7;Ry1S1-!4j4Kgl9a#=%L?u?*_X0u196|qJSsqHsfz7-JQ2FUp8$Mv#i{3 zRG~`^HN8tG2=@DhNbyMdMkSX5P3}rDwwPb^iX`(0FnOP_J>vW5qqH#xt>b$ zo&G-fUO?_?+xKo*Z_10yI>wJDjdmhP;vrNaaw$52>8(5O;p}#`%>%N0>BLCA{rcT} zQ#-HPw0(;1-?)ReOo`-zD}NhgtJzIKUH1SvWLRXs3M%$cbkS4iHN^T|qVv~#+?Bxc zKR7FjZ~~2hWGeBbBIK|Z=bSq(Lc7&QTSPDJeIy+kFK`0aHD7Rl-mW?04ULqESKfLr z9dqy#dj1Ai{px=D!*f^D1ZVB2%sH9NzZN&|HKA^Xt(dHsvBL9uRL z_6wK(%uo}?w8Pko3#8CTUUdxp?z0YQbqfxNJ>$%?9fD3TJ{FG+)92oD0zGx#m94H> za`0C!zn(sQ@wE!M2LxYrd*O%j0kO+(zE@4|>vRvECQlYou$PUG(dYl*rS#;z`&$Qp zblZLO-g7Q7`fzaGBXiqnOjsu|kP{9;6KGO&gG3Uo!ng)m_&b7U_+8tqf!K6^9fXMm zt3pox+TyYcaUDn3WP@sY(i{s4rQqls^y0vLn{67&>)B$!8sjw}t3fp#WD`1=aQr}~ zGw5PMJ548p%wm&~tmtE!?C|>v@>zncpsO*+B+k%hL=`*pBipIYEKN?&($+~3<4eEGOs*pEPIk*Y}sx zGuM3@3C&~cBrK}eU1&rhYE+^bR`HT1oHCk*DW_@WGUqX$OCZM_(k!tb{f^gwjL;{B zbc(Q3NU@rh7?4#VQmmbpSXqBu){mQ@m2ukJ`412&#;#{Zw?TCDQ#+$E0SHiz zEU^fZ4m%ws*^1Yl(6XB~6JK%vvNn)MDm4WYtHf8Hp3x#v9>*GDKs3d-Rc4;%aXYT1 ziSLqHzo2|w(oO0^DrA_a!?Q>`+b@(L!E)ov@bI8vw-_88ve~kO{m~d>B%aX}lWnCv z0`aPlVtPFTBrlT6z_ftx;Wfsjy0Xpw7_Vt1c1(k-P6JpEwo8AYkVQ9Q= zt$m+T4Y6=uR=YovNV%OiAkjm5Qor8xNwd;#Kw}KZv3U7czDICh?dPc_)mSDL1aE;9 z)67>*^%{sU_xzFhf397)?;Ik>G(s#yhV@bVsyj_91kb_}t$Ni`L9J@9uGj^&C`y17 z>*shFYd7p;S-){R-Mx8YPPN67T4A~Vxsg}Ymb)8B)c2`GoqN#~D?^SI&65){AM*&Y z60h|9G076x^{pSvW}^1H_)4@g(wWbC@>`ANUvhdgLhOBCT}?+naZh^Fu}|sxm9D$< z0ebt{7t%JS^i#nwPs>%EobzBdK0HK!@!A*C3lDo@*Z0*YvUb_~{`FFtWO8?v2^1z4 zIE2Uy(P4Y)ztCx?#su`T%@#r6N(W*Xf<*6&-F7S zSmyhWbP%nIg*;FRw#s{KTq-cN#PjOY*~6Ktm8 zlOPu|GP#FC&`S%id%8ApYD!O-o}Z-NDV51xQtoZaX|9fqXS&9naOq$^oWIp%4*$&M zPS3>h*j>uc+v>=$Sf+fKC>xezDv{Rrr{WBY*-R_C+oEx!6^6eM$=0O#5(dREp6LFr zv_Fjn5$omep0bTwyl@rmN~nVDo2z>3KS=d9CyT03ujf2U}?l(X6Ghf^I++NPjEb{n3BtPN#V!8k6aiiJ&>c^7->X_s+XaY&6FUeOO^2jlnm-_FwbM0QnD;ZzX z<5~Cn{rK+duMJwd`XDzR9U7z|BT{eon+LKKG8GN6F#RW9;xQyph{S8^Cv@#F#}#?& z6|h$YC%Wm6%8+2`E62ZQ9VzDNMxj9{>vr95w4J3%dD;E}W!JJ0V)M@$)Vcu~7MmZn zd4$sT;EuD^(kCS;zJDvHA@r72%`iz$5sfhk+Qw{7Dnyb6g8p?|R_=bk*sj;COo+V3 zV!Tws@(Yi8yzh78V`7%tW1KV~CokOzg)e{-1k|6@PG+%ftW&w9d>3g&+OkTg|+58K|}>+c+Kg zesVrw#pO27Hh~ zl(wI?&r15-DJRgPvC*RYb3p8EU%tp8w%nYPkzxlwf!_I&XEbVxmE2_GwjFfdl{eC7 zFTKubti&?7{USp$hn6oKqc6Yp74)P%mX+LwLWEci8DTS5Uv=bx^!67YNqa6^Ty)*o zLD$@|j{fF?pVBYyf7t0Sdk$)$r3>xVA9`J5-F^Sr7t{A|xzA+$8zhO<1j6KqkxxdW z%1)Lz^Aw9eXbbT7JLx%x(y7PwS_f~VPhN19c{gM@Ic)-);Z(C3iNl%%pnbz4I<&jU zkZ#WWLG=aVCvQto%^%M;7S;T{%~aCT$8rA%WRan{w>H;T&B-t4`~FSpbEp{xnpppR zkzvT+djwi>RzoCZn+(PV4Y6(zU?Cz*+q^hs&h_xR&{D(iO~T;_4x@Z~v1=1@>qO!E zn{prY8Y69O1b@*VP0r5J)YJ@ZoSb&_aNQ!kdO2@uc9up57^x)v1MJC;{9dv}<~xoT zTQtV_{8BsC9;f&^76HcltM(u<@(%lXu{TLoTM$+QG^sSXvYC^8);dDwnxl`h&QBA3 zfVM!8xu%gz-D!w<4*q^=i0MU%v=xtRsn%~FoRaZM^;b$m$!h?G`$fB=R3ixWAIGO` z{@wM9KwyFY&S}|Mv8XO=ApJwlFcCVJ`A1s~F^7;*npS%*9;aOvjnUZfkb>U&=T2#V zb^E(>2HR|sl)batRmuG-nqffxs0?WDw5U4i>P~$G%i+XN+0~#rG{jUjt7y1FQ_LV< zF+Uq1nr1|x(hvjkwU!iN=X2rwPTQ_s^r#^gYmaU|Y1?bohQWDGX6yyHTw6CG6ZGycCq!`M}`5S`%n$OcgtxzL5v>Op+ zidNBlmXuwouTn1!^3x*i4H2E4XCY`4CZE^qdnun{gT|QB5Hm>|ZoO#BUA2FsF~2hbSfaUhnIB;Qy1A-!L(M|i&vlGTyLUV{>}`_*m9e%4s? zwEaHnYv>$}zbUpKNvYVM2)a2sNZDUY$_eRdgOsT@G3d5I+oIzm)$frl6LjCk9mE>s zsqb0|#)HlpG>dKR6jB$CrYJ(pevd>{w@foEmjqCX472pW_IVwBeqd|nhmaX$9wFAX z+j{;)E&(9KN=idAojezAE^{`#W{%SukPc*;n?x@g`qgMq*QF|sWZr+t>CFML_n&(a zt+|zTm^$?2mCNb)`Qfei(3gL39bJ3R`b5yick)_8tgb=Pp#>u& z^yc3>oL=_S1L%NNWfX?@Z`e#<|Iv-~t!r+h%@dQ!PZc7$V)lxq3+RMHpJ+6*j@o~f z5;m@1)&;~GD#wxg?oO|M#=-RBr##7USeN|qcfID0`{~=)+)5YTcsET>3${VlCZ4n$ zHaL~dK&d#E8TIsnL-(PV9=;zP^W=SK!6=6=;(z=dkN$tZQl*y+77>{AGFt5Sjy{-v z=ct3|(7jhQmJ#m8)RkA?v6jAi#SQeMJJ!}v%{b1DP4)*2wrl>MOhD}1i|LXZ@2$i@ zOUk-(jGZ-bxxML_!{}vCds1;7T>A*u!JFt?SA})Za#Leb!IL&Sxp9*?*l-pHHlDGj zDP||{Zodnb)sbSDMu{`tzjaEp4MzY`rZZMrmuq59(Zm_fr=UMYCRohQYi5SJ0Y>a|!JaLf`TZ1Z)=O(3Xqc1qJNhJeAfnl!{PepKggK#=vfelH&z zrrj2g(|BgS)CM`|YFME8GM5^2wNfb+ZBXNLL^P|vg{`hud%QxV1KOWx4th;7Jzn!| z`1*`E^~nFa<_t8(Fz*ZP(D_nP6*Di86LBfixYF&!_fF6#ajn5>mUL%_A2OLqZ|g(R z>m__Iu8n)(h50E21~l4j>Tl@nbq^5GnuQboM%tp3Td!>Vs3ZI2{nOvKx*S4wO zb{^4$3=5HBG31zY0`f$?`haQRR`LUfG;%?$3p>D4TSJBIC1o8dAKuLJoGt%HyEpwd z@1NzQS$6K@B}048y1K{Fg7>Gv5b~2 z8l&Zl1Ua^D;}%-CVGG^AaSPr3$Y%QG{g2QLb6j)gpe0O(2q=pAj1aoJC={w5v9L z*V`C}E<2KUT{2F)jE&Lq#pASKnDwQICa0$9p{*0tE^L| zmZ@wJL55o2vPbAlG&C?zS0fE>)slsD?7@4}zPl}@WsApY`J!=Cyj=g*KDw3GKC*@G zeRL~bfA4y`$O8wr=k^y3JDX93%qqoMZN4*SFfrm}W>zxX&`-3qab8bbXojJ`s%VHI z<2J7K*3^H6^i^m#AqRgGC%>Z?3MxpYURlkFVHzZ^(M?-NFJ!+@&MwJhYLh9e@5dRH zj0^&@t;q)M*X{S}f921%>cX>ELc?-Si^ zvP!QFv7}?QUi8%Zz1!b)`!_C48w8N83Z5&Zjs(yUJX2Z06*|D~=3nj3N?{{H_pd+B zCpAh93AG*3&e~{xHjOL%B;zBN?v0Z%8TkbSSZbR@ig_(DgCtYhVr(1#3pB-oEs_gk znqrI))*55b5Q_mfLOR)~wwRwi)WT0bsnM2yWc+JGn;YxjTQx_Gv?@SYhFYhXH{*As z!KRS<&YxxHW8RizCO_}~p>67O*goeGV(muw`J;mp*!9%2`d%i+nW*8#cJknyl?aw8`mxj?8#*!Z zurXvoJ|K1xU3|+u_7d^TB|VtAjETaam(Cyykz(<|B3|^#OiFt=CRbv5dJtRLoXB#y0Lb4J>i`teRuzr2N2nr|RDLWjzLZRilZ6`^Mi|Q)XvPXVY zGsAK?s#N*wb`rLy8}4*yIG;{5-1}n=^Q&2sJj43Ut z9*?t+;rf%nHos?*m2&htu8ssqrdCg$LQ+H@(D9y$R!gLxO0}D|{a5KbG?s7maie&u zZZ*Vwew@lyhmn6&{x?@5FQDy}uJ1-W$oA*Z4gwPfYXG}H8)z$Si;vxLrO2_cL-5I$TFi`T zhX)32|K>EQY%4Tn(lmpwmV#fu`th@uaw-kJr0#*>X}8Z%)wvoB`^p``z@>L$Ey zaZE6AO)x$(Hm^?vF3 zsiaJobgPj5rr(X&qVWa|H=b^LrV-QIDB44p1TZ^G4?a3UcWv5Us4W&iA06~5M2fYq zlf9hbf@St1p{5wdas4|V+9p{!r7?!*PB9D32gG{$vh(NCuBU!9sUZeBAc;+QdLUC7 zod%E{Y!Y^CFs>uU7|kzSpQ>?($i>>_cyC)?qq#HLbq+E`wA7=Pe_x zayF21Oc@F>lgP1)yu3??&5^AJ~|TOL2m0j__`^QS^EFppMTJYwX_?9h%k*x+ z^b4>V5y?nMZFBwL>liH}Rj+`UH1)@2HbMi-a^epR83ZZs#}@sNwz+>oKUKO-Wkl-V zd&zjhB#FP9(O$8^G-$SQH52IvuYnM^y`*A&vQ%G=!Kr{2RAyHf4f4FAHHY#D?d=vZ zwtcFOwC$zbI7kD{ExrzH*4RR@hWE40TLg8qZ4gvyKQbqU&d!&2&c^%z=LTIzLaeQZ*zyIVwEL0;G&(e3=7oB3%(io0G%_kw$B%xDlhC|F@J!pi^h^2iS7~!J zBm+c|%n0U0G{k@igYPV+*#@K!h?J$GvR|x)^?KMKB9sya^R#Qw6 zT#hltu0Pt^Zk?l$VU3z%3JHc}C9m;fkz-vT#o|maRSh!NZoudO&7q7P1__;p7}hxv zO);JTKvStJ%`oupMz$5rFxE1QX^4fIVi9|mnQx#u)~9W%e{HuO@pR>~9;w5QX8~}S(1FPL!H?Hn~SOtqJgH3OIB6u>u|kYv7JU~K8doI@nd{s*yyc! zS~5$O;>6FPzhQrOdK?y6<}}4*T@}|9LvY2@ElRKw0M=U!7Rv`x^-Fyx5; zi`Q?ip4j!Gw$1v^jh|p#@%}Tjo>cQ|jchXCJ)_mFHOFGXeNU%a)gWs`lr_Y>;TLnk zNJW8DGB3*`!J0M3%sN|Xh#5bmnxE9l4_b){4Ll^Ji?()NL#%{BBJ`Vj|EF9(W#ji= zx2S)*|G>K4ug|Ofi(bE{`Zu$@;PzvZMxi+-*C`27p*~|i<(Va9epPD6kkqbUO|+Nf z{)YOoeR77@KDwPAo|tab7E2+)eE%j5JZVQY#jxlr%kmF3#L6_q$~42m>@w%KvHn9J z6e~v>&j-ZjgIYb6KraZfwvqi>CbxBVn%D`1r|sZjoOSFpvve5zk|rpp_J^Hu4k7kl z))2dy5n`HUG?%-QLXwH|h6m9mWLO+2mgtmRik$3kTfUBy*k0cGf(&Ahe6VcB`>;58 zrjyD-%KKdD^i=ucq{${VMhDHrs|qKE4T8D!AaKanb922$66hOb66-Tbsy2dO2$F@i zqv5f^l2j&68;;>z`SvvvGX*56Ja9$>A*qSrK1iZ{HRVpn+kT@dItVw3K@bd!&cJrZxmugUy7~Q8%`o&QvfnR; z6_U&b^WE1d&$S>;n{5t(d6)Bd|40C;#qSJG2awlp; zxugipCxS(xOYVWzqjF-T`nTDE0UE4iv9}!oQ^)J^B|V;qaJ&4~kz#`E@|ta-U0$u1 zj1AL@MdP%1!D#tO!I3%5U5y+|)sL=k-pz?QplXomEgvB>9q;Bj3eO40kCd%5pKVT; zxr5da3&$tdM>fnixHw{(V_JjE2#DM9LZ(CF95BU}vaPm@+n=G$@~x#e4Y9D;OUu_W z6M)$O$i^5^L|;~Kr4=N`?o`TL;d+_ECvHDK4mDqL<4v3989q(hw=v^iL~~3dWF0-6 zy||-?)AZ{$NZ^A35;REKDpTKFwp24L>_8(3vQlJldiOWKxo)l5F0=JzHh3=)WI|yqBzGbh>B08uSL$dic6hmHBHN&_r zW4)r+mzaNarzz$~{7?f~+fACg(mmGa$2nkbY1h?{~wJ-lfL z-M4XqwsW?Erbr7bND>(q(G;845S!N!>qq1HpL&hOr+kz~1_x+rwo}={+0Va^s!aGv z&P-RC{G8b>i!_g%XvHzyK!@ft8U#k1%W(L979n;Kt-ks08mE8AiQ6p=A2OQt)^pTL z@GRu4XN{Us&OEe1mRwK<$S63goNY6`^0s8|bFhqqVc~Z#vW+&2&`M1bYwLI$$N+4S zX{5KvghD1L?0#%@W)s&-WRj-fsTtR(YNCUQE}2t_PfC-o zoU`0(xOvSn(R54Mf?P5=ie^v`GXul&?Pqz%v9E-3?*%$A4)SwGdPzOd z=WC5hc@H3&Jkl%IK0{ie^85Ytf_G5p=NgdE9qF?iCbW6Vo`Z(MF`k+R4 z`%~kT*X*>KfHqkG&VM)0bjbpNrkF)A`B-fg`Q_(}9s#DN2ce`%qa7m0Tz?8Cg%Zt< zOy+)*c33x>VHL!`UASpPfYbT`JyxhK;?{qbL8Oc4mrVRPb3%+^q_)0nps}pZr=b}J z4Xm_=m_ztlWR$iU@#UE)cpT5$&=w506{Hv=!)TU_R#<8~N64_8Hdz$;QNnWAg6=#u z|A=Wu$LekJxEAz?{TerVxlY;mXF~?)uLFA5XpmXa;+5_9w9=336-%DWGsb_h*IeYa~W^n1vbDdbx zA}8Sfjb-ZSj1JzPqf8Wp*xiZOD9Jo7Avup{`iT=8w37ic$PyD2X&G7VVv5AlY4Id!uA|;^{0e<@jz}71tk@u!d*r4J*H~(J`d!2R zqpZKE3)rXH)7+GDyQ}6BSKD2UkIv;XrdXLhjTaWNu}O24-b-j<-J}$YnuMlUy#DA+ z(%v*~Qi~{;QK+2G?aQ_IGpd<=QcowRXNPHSLR64%okrqwJu$YEeN^=0EhW#rSkJGM;$7q-{jr#c4Rzs|hw>FpR zy8m`g+G>!@J5|wJsr@a5)%)_U3HF$xc}FHFfamKg(%)QEUC}&$U27*7?8<3Z;n_pv zQO{)_Ov4+?xg_Y)BhWCn-gWyC1O_5DX1n#8pC8Nm4K}ZO+^G$l7RIjNK1CsDp( z5X2I16iIibdey$v@9Y9A@`2k{!qkMjMX)T?602*7AqnO2g`7yOr;37NHJna;Hq!?n zTJzUz_(pthAFPIdr9-1bLo_%j?M?@K4ZR_fCp3JgMSW_E#0oE68hlATk{*wN=4$cy zT6)cn@1Aa6#(N1`B6+jQtROV<@KuJ~xh}_uKJb$#JxK57+n1<~3lOkW2kQgtd9@ z+gk2-A}R_R{z80*Ve@^QOle?Ow=AXTrLyKTy*-^XUBMM@(K^Z3#&`aN?zXtOON zfbr*91YIf!sgs;HZl9w2H*BX((_EQT4#oKQ>35msuGezRcNs($BeVFr?EKO;FMjZT$Z!emSmuihGTFsa z%yx8IR`bOmwSwbQ!7Jy~Lr^WHDdq(3a~cV4GGgU9U9gO-))s^z(q zm?hXU$x<0&$Vg3bl&jIqFG>{>DYGAg64&3U&Mb|X$*}~VrWn~qgKi5=rS`}V&`+k2 zD&hXLEgDZk6PnvPj%s9}Sq^d_v}7$XgK{r)nf68ZzvUhRE>#504x(sb}h zAzMBHl5{SRrS(ZrHCPsAQZ;2(`JOXe_US&AgG! z-Vd!MjJINYO~g_=rg6mm10#v~{dm8&`TKDHi~T%qaDVN?3O-XA8e-j)cdzv|q_NaC zmyQsWQP$3-oriz9abQ_rrN2-@`joy7@j$ z<;&O8!Cbr8s+C#&V&CSWFwaQ8Nt8 zAqx2qgjlE{=8$83LW;TX*-|siX_}$F)sP={zVG(uk^Ejm$s&ZDrqTdGV+@*ORm~;4 ze+ct8%RdcGFr^{p=51CR%u>$~w8C=sTxg0xqs%!~tyY=XM1wf@dD#Xpm!EuN{46v)#-19ggd)X~=77#~=ZJ7RI@X zCM5@{Jz|a5-&%8TdREqFNRo0vso4R$&aTeS%sS1i1M3>dPIbUWnL}FxI;5Yr+VpCD z5^9KfrVB|{4H-OQOa;9%RJ1{qWf7*$5?>;E8$h?4G;*8 zme7c5VxlQwGHIhF)MM{H}R9&Qg_ zLst5;x-IPr>kruN zdo9xp%VjNsvjx;srV-#@4PFY_8=^UQw0!9cR8>RDr(CWNh2TQYtv5gH_-E&>LvwE{l_I@Sbxnq&2tPTgd6IcsLwX zCY6b)BKM~8HrN%8*LrSMRrp)RoK$(%ka%{Ca>pm^$lSu+19J|)IJBLVbM;qk1j!H# zYl|fF&J)X3Zje$^fQGv~)U0Z-!%WODmyH*fJjr!IT1SVH8gwmkOVJO4UX7nG#Tg!R zs-Qf>$4}vUa2y8t7{zeghToQh+q|RVu$KG9Gx@7Xy{Z$cxc=H;h-*C!9P8ntE>*s% z@@|4)%%tr!>Sr$+ynbeW$8)$^M`izd-@=z7xI?&TDAGN z@~6w!<~H>=hV+p7>@^Y0Ge?}j`6tmwC=Pz5A;w39obQ;tV}S6%gjr(hgpE_vro92F z4hZuM-0cW-1wH=UqfD1kznC;B8NoE?{8M*3Hy(*K8G5F*bfaI(HykeU4e#}8CwEP zuyFh<*{`Piws`6qVwfMBK0;}XHDXBs`eE2vAin!9ZfudauUiJG~hu4{-@+e3bT8u#3n@~w3kiPwpB=LHXt zntzAM8GgK~)AB`=W;n=XphXhhF#T%BCl9(uQ<^$)jh*f_DP!%a^>0l`yn^y=eLr(T z+Z90iczJw}9YCylpP%Np5|EA!a?)cBXvDAoH@$eE)0 znQ4u4vA*u5yjz!XX8d;L-!$LQ?aTTHjH54++!U@KOKnXviJk!KlPx=@>4A+qX#Ms{ zyI}G?nhWCMi9&z#yoT63LacSenLojmz`|2LQb&H#02$gn1ifI}Erb`PbMDYENhXsx z@2iAA3-oUQBpR3&mqMA=$wma^-XsLDrp^7cG4oPNT*w{?}XlWl~TSl-=Db!c5T=a;f?r-IY6cFF=0r_kkU!si==Hz1GiuoL^GT-5{63 zdJ-bZ;^kk>Ovd*OX%$OpDx9<126yAguilVgIiy|+Db`f(Z8FQ7>Nnc0A0GudsqLZR zA=+!<811@bfl*KCKx5M&l>`~)mau{C`UM;iXo!WHU~^$3C??}omvpt(`QV(;g|^cG z0o`1nL6+NZ<_8XmEp(@B!xs|TDW(d{hcW-13!BFgJTLl#Q1h&2TZRD4pD-Va*-j&u z5nQ(6diraR+=?N?{CcK}9CMl47Aa;BIYuK|kWwzA9CiXJmP3-cq_o8O;r=4q#4J4h zI9KmxyEhFnZbx9kKzRa*(P%5p-HHaUDPN_@t86&)-FyjjzL?Jic51$Y^K<)C$T5dJ zNomDF)3pUMES#r1E$IU0kRnKDej4I7{DhZ#)7AI0LkTo^t8WD z!;1MpR8vf8-)Rjo*2HUz6w4joX1pI78l<5?h4{jA@;cu#DTvlt6%hi41@6aF>(2Cg zRo00>n&~85o*#hOg4-c%uBMnj=xy3vSr3nNW;!%rAcKBAuaif)KWv(R&9JtyVkqJE zURmFnpjMhDvCVghA=ElEvotU?NU?2+KM2TC4vGPJ#Qlj0l38XEFcpbi*A#0CI@Mw> zT_MUFSn;~JUMantFt1px&VZ>Wmc*T+8}v*=)%PgvX5HL4NS@^1Q*t|Pp0731HN}kZ z82|pzmPxvA!*<%vi59BerjTPv+Uz0?F*kuX6~rUMdeICkMUGX+nRyMd`2f{pRsxHe zGO^Ep6(kvJbP&<7>g*iMzo1hNJNr~71pj`;hu@e*h^=-SV)0xRKS=x36A0UOW#-A4BGa?@|D3leJ-)=SEG6aKw3zJeE0>>LR=)8?KahE;EuJDof|Y5u<-UjP&uJp)AXM0Y z?Y?k~c3V77qa*#*3HwcIf64BsDQKoLTT78FrL8O1JGxrqkWwBA#*bC$HxzM%`8~Jh z5BB4kd(sq3L8&Sa6xS3hp}DG;zc@jCc~|Z7o~!#~8DZSE z-SqAFrgAPV--d@N>u){Qs*3zVt58TVSD$6Y;gVkM`X)uk7zSrJF<9mmOvlYZI_V9O ztN^5#w8ttFPOGvHkX}vmy4ZE2=&=?L07P1gQ_P|6ISukk&66xLi|aZ1Z$YA0*Zbzn zb(BV%rkmB8V-E2ae?s<;2{teBrz)7BHLFhh3PLOrbjg)VuSl@m^>g*XyuEtv(qy)h z4>UYVyB-h>M%A~LRGvi1UDb{kH;ruKCa?Ev~N<*ysA?<>WF z4xDi4oY-8h%s~!LcgvNYwe4{{SR|2nHb~}zhOiw13ji4_C}|U=8KK3`XX=?nYQg66 zK!zY^HgSeiXybRig@%^nY=+RaP4zYVO_a!L)>zw=)6f86e@-(j#<3hC-l{ea(p z)*34@q1RLfh-+s_Er>j)b3T~kkw)mxBw^@N~MfW4Q2p)Nqvtt@oAyNql43xLfLi+O6w$`w!YKHk>RUEn0 zot9f^y={YBiXrjJG{d|GQ2cl}*_x4Ipxu=EE8ml!A2u{$F*mHzS@%cNwPb#zwJk=V z9cMLxQa1mN^NcoV!j5a=`F5mfOZ0pM^+9LwuUs%nyDlE51*5}?#@Pl5Ofynm8Xixq zhM1ds1Hz3TYIa>Cqa-7GE;PkT+e5#O>qavyttn>v6h+@FnbDz!PFq_e`U^GmG8$qC zMwod>N<%E62?j)1N;9l!e=L(2^B+UUs5J5%GRZnOVLRlVbt{J&$Ib>Kc`h`@oQ9aJ zA8YG0H!o_|5c66=m|uDgWM;0werSWWwPQg@H%|bvD=1&@}* z*sD3tI;q87pzN44F{KGq(U6uC9nF+&5NTVYr+$AXni@hG8iHV9kSkoMCOD5RJ{ zdPe;%RgK_~xdMzK2AQPf7xaQ0gnn2t3IQ4I5Yk{gQkv*Znp=$Q!*gI=D>lXf z394beE_9RLX5?NCnd+E9tj1;%AtdW!1g*S(&ojTIm=&;Y??r2>8$Zcory-{Nc}^qU z`lc2XhqvsYbsHz?(aEXW z_!o|cp0?2qsMYm}tOBci#fdD(P(!RtQ>;ug%x9BX?OP-vIL$CGI}!R3y+6F#KhFom z=Hp#Gl|U~Du@t=3t@#5@pcEd~wMFKZ0XCS%P4(;Y3%Z6Hwx(vH^OkboOL{ zvHMgQZ5vR&Q_hT+~pLD`rd3r>gPhoVbqO&c~Q?l5>q5 z@DYyfrqT`DBQH)k2hdVnEeJMdI&1EK=l%gMBLOV5{h%=^2qsfam zZV&wZc=5MmYL+%lP1Q83LJg~&-K?@x{Vr`d<=vRmMMh@(+8}4-G=Zew@ZSUWpdIi; z(@N@9UQ^5Z?A~8eT(a%{YWN3RjI;p3y zF+M|cNz-B?nFh~UuGuDMgvZC6&91BhYv4v(Lu% zH(En1R=-_8qBO-sd&O&vwXxm0!p2-dUx*lN)HdzaI;E{9WsIJxNdwFUJ=FXwcYKK8 zpPuQ^FfZ8bA8Z`wY`ac@ZPqDF2ha48Cb>_(3+Ty=GZR{ymM)WTVS@hF`P#G}-Kj^K z$OD$yCi~EQP&wY(Rz9F+o0=nctZE#GHjnr0l=sXe-nP%@_Q!2cw`j*lN59zS{XG4s z55n2e%?3A7ekO>j%D=>}Fa;QArW)`Z1Jp>J3t!_b{@KLHJC6XFkS?N4n&kfr-$)NfnfYuAe)#X{tmv2mQ*8bp~2mgQ`pp_0nH#P9Jf5J?`n zR7EJI+#N9_Qw`Y!It1&)V|oPE2t)Zo8!Tn_lHnIRkE$6+f{6575Y?FD0b~4rJ(1^;U^Fd|n zB-ff;3dx4^!{dE_X}Qi_CZBI7p!ekV#YoQ>f)tsLnp2=L^xgRs* zp3PKr=>f zbQ@I-F)XS*5^S3L6RtN1hFFbBSAY6sYorn*o5JhIkW4@@HEqM|#_SZ5$wB4=O*;HO zYq;J!BwL`ft2WmeP3{-hYV*NG1Oeh(AQeRWt;xw=Qm<0yx6x>G-^n5!OU7@#7=`AN z>tC%CcKPTqtyr>vmW~bA258m{8(`!=*At5b8{mv^W&7s<0y~Zj=mp``F9cb?$B}+q z4~y&Ydz$e=(f5TKT%P_)W|1DLB>h*ZrkG2@u^PLf##n4WG{abv*Ys;nLyWb~gb5?1 zA?7mX6B=SV7{r>aT2l-R8qjKG+aXjF$gGn6#>t8G2asODdZZK?7TzzkeR+yDaw{7e za`?VVQ?9BZ28}KReR|Un9}Cc)pDZG&8GHN|>8-u34Q(j#b` z(hNheY`Q}OtYMAwy0B^3A~sA^)HEb=T6rb5N&2+OU5*LG+a^e7Cn`9ui5UY<>lE`# zulv2z+iUlEdd(_*zYFTcoW2S`=lfHcSC`oy2^-Z6!@M63n$V7DilyicQ<`CzFJXVb zY@Sk$40#PPnP(1CxSitl?cgBAwk6uwQ!}&nKEf0;HA6HsBz^!{Uqd4q>+QOoLV|fe zNf^CUAGl#cm-D;v{w5?-$vB_#Z>6pqYPCUo-fM~rlZm!@9p=}QvVPNcRimvw4{PJ` zt);YAG{5S|@e==EsKMUWmf$Wl!XZ}>*Zd5hryrW^n1^c3`lfj;k^qo|)|jN3!VtLr zu2~b$)C1SurM2&TvQ@K2UfbjJI;f<*l&oJiPfXJT8@AJf6Vqj4bVbD8h_R)h-TlxK zD?^UWYlyY!k>-!>YY8kq`6HFcwr;d8ZzJF&&pkj2$<$5IETth9%cS;^^=hVd?s;u& zIY@<4-6-h(>@2b=NEQp`Xyk;vPhwJQA2f#qE8XwPI}!xzK${EwU|_f57%nT{UXN;K zyBEzb$*|0E@~2bd;?Fo2^%+4flh3+FcB<^Z_^rL^ z%MfU!YGjyYlQ%vePbcR!#(*623Y{vrta{@RITrF%v@T-v z4^8vBwzJ4NsZQP0XZ?L_57rFHY5S&rJ{}^;!tpVMeDlaikMuIY5QY58*=Dw(XgyO- zzs5R~ae79POKmG*3R>NRmKcI)^`s!5G~{Lgk0o*y#J}a4PI5`-ZT92g&|l9}Chmj^@SA*##V4Ox(@3dmrU;DMXU=<$-cSRn z$wsC}NPiY)isbe;WvoDR37Pjg)1RN8GpoVboU#X1M$PQt0L5(luD8gD;N$ss(PZ;N zrTktgj%|N@S_1_S!&pE};3AGU`O zVN%{+#2E|CF+tvlEtzbvdCM8YCIeY%h=Gm-$VgA2kMAM%5sTK8hDt7I0?ud72yz;3 z_IbG6n>e9+)m$pcps6m(WipxmUd`Xf4bDpQ#k2!8Y6HL_$R(jeOzlrW{oLhEb+ws` zO2f-%%1Q7fWzPjSdAL+9MUurd@ajliuR$rAR?W85Uva_!xfI&rWZlj>@OChFEzu@Z}b0?qoE?D#;Eh4KdJ0DKD9$9fj6{r4Iy8Vs3w14Y8=E zmmJ%>z(Kg6%^rT+~5bFdA9 zStE7r{L{>bmA@inLP}}4W4)udapn%ceisHI+z%RKUc(*8BqVjF>^gGJGb70R0`cm{ z``CIiTwi*k2alL-LTKgYW11Ec{X-KImU-@Az1l|ex>R$w>R(cHu}Z_3`#m7T;z+R+ z|Dj#M6a>9IBNhXL;S3~U)%EmvESrq)lPV~MQ`~?MWdqWmNBG^43g4WfIiDLvOq&D zg)HFT(b+f-c&nij+Aiqj1W-M)CjRU)tJaH8|9sU+W_bS2=7iSwZwgAJz7c|7*q^dp zkW2-`a88IEoBJvl=E`<&S2cP>I|)wnP$NX@o24nR^&>{7IH;hAb!0+2B#Uu`g&J)T zlC%XKPM+)aU2*QW{5UyI>$nC}RZ}cY(_kHY5h2<--G|I(avEYOBuH%0XG0fGlf<=w zM0tn(O$-?u7H|4_r2k55BnJD9Mk1V%)d~=5h{YzwEkCc2}kp2Paew&9LW z)bBP()He0E78Jug+9oM9(S@`tU*BKlG{i6&1QbHs{BF}$>k*3^4t9HFo&U8MA#PRm>kbG+D97=u{OvhS7#JQIRD1M7;uQUE7$tbp=MZU2at1kLLf9TqZqe1j#5te70@{N~I9m(asW#B`RV3%WrprIKI<{j|BnY)&beL8y8mASD$HiS{9#GZ2 z-l05QSNpc}PXxD8nsd4FtCygbf5{lq1$(nttwPb8?us-V|B8{ywmz7rPq4nY`9^|g zqI7@#&2l0ak^SbyocGsedDtu47tn}H|8*p|)h|1Imt=VdYaJP9nEI2wJ-Rpby0U zz>d8q=AkI3Ztco^)*^FVzXLnAO*tcNa%RqX+|z!`u#!qjb=uuXQgytIbZEJ z$%F>OWiBB>Ax?r|7cRH&0n<*g(DF`NOBZMBv!A~p$XneXA|v_uVW#19npVCKY!l21 z$LmneLEB)mfeb{9;U=XGRyz9S5M@<=Nmaub8e)!Kv!Q;ZG?#c@7t;*$>%r#zItgF< zYh3+G$PL8iG5j3jXH1t~I6mdZuU_}#eweStkTm?>5*c6xpsOX7+l zgxojjK@+dEUMG($onE$@-*@kiw5951gw^$b1NgzdV4L~)quZxw?S^f%aZ-C*dM?q* z1#x@6SAUs}_Yp4SlT???ZicD3=7&s3Rn zGH8UE{c%oDuv9_Y%4Y&p>9wkpGB;-oCUJ4iBsk5R2ZL@nM|EaIhD?*fX;c8;NTATr|k5gmd-$SNIVFm zyUCEW1GG=Q)tOd!erOyul`kggK2uSGggLupvX4oAh}7ioUe{a_?sT6qld|!9`>k8V z8>fWO6iWRNduX7eIMWBL9p55@Z>A&r+2&vteix(|kar{f%jdl_IqC zaWVSH7~NqGuAZk$tkWrq#+>wPj9_ZA9TE!tU!bWHOP=W7*-`JmBUwqFTbb0Ki_}b)HH3Io~6mz85^uY(8eQ`xV%CnlkTTd$fdYul@EF$ zIMcM{aSxhSd>m}}kOYzBkxEFiaoT4Vp_bF6X}iA!!4yL(Iqe^l>E;nj8oA^VRn3U0 zFoPH8g};PekQ5z93aTP4i9Vk`*?*EPg^f1A<}!*fF`OlyRN znqevJny{bInqsB>o4bFYJr-)1IeVr~7Tqdjm;}!}%{w&195M`uum)sU8_m;F&0en=X4h{B8e%=?Y};=o>`o7wVMa?Q zp%Dfxv7)Vt3PCH|t%oC;VlfTv@c2-3yJWxC91Huq98xT;A=X9{%m>5TX^46HRe5e7 z9dYYkp;mCnFnDad23|X)SV~i@6lvD>e16{1;UUAk66A9LzmPU$Ikz`84&}qhb z&9AnaVd3$hLqyQ8$)25=rNJQ{Z)`Bq+9((7Z?ZWn&dI>2^G)!~PLN#vi`WB(smm_# zXJ!eualg6mSJew#`Gq@CYv zJ|Ol#EriwI_g!c;#QJ&F7!qMvIrUw}68c1?p_FElt|GzOAPeH})*SiQLAKJMS1L0% zhlFX1++ZXDmnZ&!EPx#o&NOsj5iK#migTGz{i+`^Bu;G*FtZK>WvZD=J`)9*GqH^1 zT*i25Dv5V0YR$S-rfbRIk*eSQDqqkgHctX&P%R1S@^i)OZ(XxZGTO?%2Ri}$B2SzG zbsLjdp&_i&NW^U)OqBg$d83?5`wx9zKS`G7N&P`X4Eswo#rpOAOWIeezsUu|(m}Pl zW>}LZo^C&S5|1+QLANThS2Ei?+l?>ZYCA3AlrJssZji-t?fUp4?Z_v0giel|Lnavv}IXwExPW#nfGQ>sG&d<`VU-ihVqb#IHQe z)Mee_YOZR|viB@!Ki$L!**;bhh9lFlv(((&Nuv{>4`1Ovn^Sde7 zK5@M}JC$HG1qJi@DmFQfBR%4b7N7NAZRFToE!Um$#rd;S#GGkHCk1wnTzGZC)An2C zj%u#vXC9+=_uSr0a}4&#dPCb&&1on%22-idXoro{DSp8H zaIJZ?8Ul_v=?7H0k)Fq)p(!S0V30?zGLurT+|LK5UfIk*H+AA)j-7w;;x7IBPoAY8J-f5!vW{C96C6VLL>KRPFU@W+3ZBlM&ZLR_7+T%$-o?8sq_MW1F6IL#NDQ0Ss? z&srv$aV!~!(azcymzU|5G?Fea((R-Tfyt4KK#%;QNsJ+BIMV}}xyW?s**+tN?wc|h zk*R}>%xL#A!TKD)HO}zJ5$@@>h&G{TJ0u@qtO%kh(u${`hP0_8_o#g!h-8{pJj?br zGEHdzUIw-==k{Wm-N-CK{Q_K=8I#gpyEgWtOcTnqLB&oq-9;d+;5?N_m?SM<`0tF<=SSAyp|?j3z3J(Es#$&n|?RV6rQb= z>=MGTg+wdw-_s^RaLtfm5h=#iy-SzrN?#YZXLeiVUNW~=w|H{VBtt&3SIpZ=0}?pk z`TH~uc&{my5j~&-f;LgbZuNs+gAT}>($;76jb`qb_N#H6TmNC>MRu}K#w3y>oRBYn z=JvgmZJVU8B_q(@EVzzLSI~wqQjq@)SsHC~6Vd*Z!FWd;*N)RV+P#cyFZAk|lkzt^z;PxzZVvfU~ zka*W_nk$L;>19gkCL=is@y5YH)v}zlNBbM>cbzWMOQOvX`t6!czoQ+~{x#bp*sjtc zz4Nh$>Fvii>H7XX?!Q4F2m0EIUD90Q6jupjys&rt6mq4WZJtDP5mrf=}8D8n+dVWzabC8df~}G)*h9 zp)rQ>gzOwJ*ZCIPC1hAcidB(gHO;W7Ddy%AQA2E{Ddv!BBZ!LLJVL)4Al>D?=zK&F zLU})Eij{(vj(ry0qtR3gUATMzidgO1K{KqydrdF0rYTnFK*xhzHja;IgY_6qeED&j zI#S`$%Up2|Yf_8wz?P9;p+Dj&pdj zw7*!^_vjbM`{j0-Cjm>%uoALuEK_FGu&r7YKsUQ@`IP!v|H2=D#l(r?iX=ht9Pbm7bcuQhG`HO!Nm_kGfb*@ z>68!1u^@pKXOBAOpIo!e-hWwW9$p^M(~6DtLevm*^8p^$ZGNz{my8QrG~UYhE1HOo z{-~zWhUT;gHXd2OO`uWyoNM;X2Negzt#&JDCQW2Lep`|X`YX^I*X$Wh*V+E9iqy5~ zN*y6x>+dEJo9k8IQd6w;Oc9Btw!E8#t@mq-f~Kz=0Ny|$ze&ELaid9klJuBql##2d z{gu(APQMG)L|ZeP*!b8+qWN{?mg}$P>*0H=j)(I70U2ig5uQJ@KcTt7xen^qFsNHS(*A{n(ulJ7HZp#&whUd5fDK{jFOM%FEYWfaWJ{?42u4q9ty z0lMVCoIHx4mzDGSQ0VBT+=Bt&PvxXe)A)vsa!qo?>k3JaC^vtneK3CAZtc5Fvlq)Z z+t7N%_X-KYVZZGLACMN=2h>Z$%PcdFb`AnB?NVkxYa;S}n?~Z& z#_x9gQghKu8e+12?=q#kLFu36q64X&mbu5}Y|ms&BD1cP*;vc$8~I%k*nx9?28maC z--Hy)bc(wjYgJY<`Tg&3>hRiZiA=JjkZlN;mj^;5nPwOxJAuEsxI3a94 zG9Khbc>{Sjg2Y4pefq5j=@XA`(!&S$U6R5+9SCA74|qZS@qmr}{Ql_wIEltGuMwo? zegsama=+4=2lV?1npdzU0-p!=*cQm~(f9H??6+M*Y#s^b2p>kKBRX!ZGFw;un`w%z zG|-gEf!oW7rWhp&W<;p$51YONogV_}GpWHCHN{q%IM5Cg?VT-JVp}!H^f+2)(e>vm@uF#7fcv>wO=0``u!{Xzyr!e8v4tcIJX(T!RdOTf9`udd$@~%5SMBkJ`q%z^gf!9kdDY*MHPtRtODn8Z4$U^drTx8TSaIDd z>rG1@Tn1xigESE-rmt_Y{;X+=t&^qW`fkIG|92V2Bt@8 z|J8Ci>vV4=I)qZnl}%Fk4l?bA8w3!GVeU*Nm!kY5cLc8!C2p3Up`I( zYWA^T+=XNwEVhz~6oY56zL%Om%giOqFs|i}mG8W#xzu(dE(Il#;ZVxVG0yV3aAxTa zr!z}raMz5hhRyAjIs2FU8&Z!KH%P5HdemHLmRS&BTuaPre8o(|W7}u%__3gw^+&Z# z)82KK<)gXi>-S?Capg=ua`tji42y6~@)$8`^nPqZ;}Gq64rd1>l|5Zg1&i8cX>niD zgqf?;)9j64HTs_%)Xd1yzOZs{a#-TzA3;*Q+!2i;Qz`cTTAcSWk-B%TQu$USQ*Ay% zbb$9=Mm+50){tS8JEydOE@(?ZTGTHE553(NpYrpKHnIh1Z9LBw&9*J|eyU?UG7Leu znzOC0A%-BqGB|4YI6kiY#>4yRlOKDS-nt>B)e^FJsiBDpQmwy;(b7~mvLD9L&6c&$k?E*QSn_OS8Gk6Xte z{Y$-vBEEu#Sc}duBk~$_hp}Ae_kqr^h9vO7wB{QN?V~w=oU8b%fHmWIB<~bq9b9TN@{(;Ga#ucJC?X5pokubrk)7_+P7n+O5^NMn<%2Tib&P%ROJy?+={l*AaW20!7$M6@b*FwQmk3A)#m%M*0|4P*@vHGT`t8NkPD_9dYHsNZ0hkZnM;A@gQ!lh%jN%t7!A89g<7Lb6L}1=N{! zMb|Tp5kjnyjo?|nA7oTyEfTSbv4{pMdHxzFaS1VocBJ%flIhyA>AE>{R^uVjS3!7%oj2P4T_%Yj%ExbP?zliqH+jtI?bA9ssjrOMuU7Gjc z56CqnGw}Qk+FU^5uWfEeR^GP95dApceVV69vJl-*&8FXxaZLNe{?y}}^zlbG=~o}! zOlgFfhK-A&j%2x(WHO;WKsI2kCi+8%F zA%<_`Dj_AjhNx;@j zGXaa#H~ZrdLS*F6Xpky0_N)-UK>AkYAC^gcejO6mA2r&-QgE!S(Kf<_V)fuP#GUogG1TaRG;;GYZ`<~6D5vx3d_6g9`rqaik)D-(A2qXB~{l$yB^lv|Yntt@0yot5?<@(lS z%@uNNrv68fVI1t$d95%DMZ2Xr_$DCsOVAi!=Ucr0|NIZ9an-)lR;E7%OQL3&2FFC$ z+G|em{uI38AXZ)qh)us^Dg|M8+}WB#R6e5Wt(TD#t;`Gbb~TNw)#MndpyUwGuy(nb zg3UN#D{tCaLdyotSih_H0Zw8$J&<9zTnj0t^?S*PGW;P3HfnoBS-gJn6*+HAo(y6Z zLH(lG&XtLsjvbh0I7Pb9AL&0sa$VX62=^R3)njw|=Z1qgdHByX^ zpdbw`&fL_sqakKNti$U4m$bi1$g|phr_c^7WuW`_-_v;W<(azKAuSbVF2SU_joKa2 z6l3}TAM9>r%FkrZk7i1iGVt`94H{Ry`t5&fHoh#8U~A2=CZ{-Mc{)w2xR`8lz(-E_ z7Dsw6#>0DDARImu-Qw%z-2$pG4~N-z%R zG$a`RQn&fMT&}HaN+UEP`4HsNzEp!>RwpgSov0xbYqF*>GwO8m^lRKdmoq!jZai{~ z_GisDqj6+pAO{8TH*RzNQ!wmPkFV3)j~}Fmf(To?#pUc(Xp4J)@RH-F*9f`P$}Fz+ zZ$rVZV?N5oU^LkL?R76w^AXId-A*j;;rwGckf`__{YA-Mv~Rgz?w^Y+FM7+PIPLM~ z<<5v3m=b|n&fm_dA=Z6=mHwjlIE(U%@2ggyQ}1JDeyq!ka{XF^2<3_#D<<#t(ZY$X>mHSij*Sr_d0SQ&xj!q1^iE zo~GETI^MzawCa2G1rJ`zcC#5iU%u|a;q_8ZU*PsAHY32uhkhaRxe!zdI7Q9jai(5ZJ zGt4x^MDwah=dZI9q5Ch}lw=9IY2IV4DRx%Py{XEZ-?`?GgT@kThMDG4O+$=>SYw)D zSVz{7Vjh{-W2$K(#q^Da_4TWse^Sn$`rRand1dFMeA$oo_x36$ZY-JB7%@ioA5A_! z-+uq~)92~?KYNy*kqpYfU(Fw&hf03}4e1gxtb`P^`Ai)rjD6Pq?;8!Vfmiotm(d!y z|3`nRP@#6FQk*W^phlf-aS}L7!teH1=V2a2OcO~n`x+V+Et;uTWW0_bd!oq+A}?0C4;+&WE#{Y0g{a}k5Tu6`k(#8L_tGIX$&T$8?FPTs>{9z0)1YB(9nr3dm3BsIQik1yAx3~O1F{%4 zY0zC>IZkfTcmTAR5Q(JuLmGC7f|K?gH0_Sv(sig_Gfjse^-O!jGP613(1Nx#`q3Ue z#+LHhIMkz81adTg&sc1RjDC6_&v*Ou^lq2?6#CA~+EqX*&25*+FhVYo2BjclbARS- zLhLfK2}mm-gS7u4&C`rL7lhWJy;aiyNGse|Z##1xg;+~gNko#3Xof|k7#1fr&9L~p z(k@Fdkj{t29_}aFr_Rhq|BdsO`g5Awyz}@$`uL;kbaQPQVIv4*4GQ2pcl?f{nqox_ zvLZbrBWd+-cmkwx4g&-FhEmw4=*)M~~h&B9QCXAE!m^ zYwgsgqlUC9(HRx{>mxL9A~Gp50Tg+K!$cGsnu-(?S^8p(Te?gn${@Sbq+MckTh1%5L09r5Md`qhV>9+qsXytGR2_wkVhs|kz(Wr z5ayAoEf9n>?~(bW`T;67s6Vj(xoxjOrbwGBzTfgZAN1uDOfQn`T1r|iC(G6lERbOc z<;wKK!6*uTMGZV{SJIxl?dOR8@Rais8o{aFN}A~9_XA|uatjSH3Z4;CjBG-NAsP*Y zSkrdMBLu6|8&^p>K!01(q#UJhr+Gt3BMh2hB~58Uj?(%`HKY&w)M7%KnJ?G+Y1UFD z4LH)4WO{$=U!uL%Mr*CB)i2~UJHhCKt$km|A;3nNLWcYRa=)tW7VH@<+lUN{h%uL) zUet(>NHN%8dRf{sPeX8PYK!qgf?hg)M0;{vapTFzdSe^25t5J3yM2Cpm;Uo7&(rtc zf6m!#(oq;PYz7H7i_|MKat!$~D$G)E5MrZ|pEvszYvBGL{nab4nVbS19KkJkJ=B()p4C~syGZGt%N~b~ zt!n*9wtmzYD+Ocbk$3Yo?vE%95;mz5O)AM$%IzgWtHg$u!j`RtbU|Ojzmzgvy#yVC zPdJ_uEGP&y!m?D;oS3Q2G7`f1+$1=LU*i4h@#1T$+4*Po@3yy$5J(P*+livkJ?qkq=^ zMjniQrwlgJ#H(|JXGEwvfjOg=?3UzX4JkGfT$-(WAFRZ&UCp1)MMmy(duE-_fwdlP zOJ=1a#G8{-bg72}xZtE7fh(qjV>cXod)`nCU)#j(;gXPasF5JLbG%xGzi{!oK) z)0$$n`j4sFyx#~n`$+xHw(;5ht3a!YmY*LN>l$K=AhZ4%$gyQk_v8Eb1QGTy-J?#% z(dMZ}pJ*jjZOJGvX@*&5v}NknG{f}mZq%e1J|6Vb&?r-3bnaK-%uqTy7gVEb)R5N0 z*FV+sNwe4c@wQ8?uOY!kzot>3Pdp#1_;%d@03ZNKL_t*A1Nw<*>v+e@7aRX%eu8#_ z`A5ml@5Aj6+bh*{?_ZFvK<4NBA}5U|X_!5u8P?Mf)A#evnp=69W{#WdxmyUZ(W~N$ zX93QR+~8SnfKT4*FO?@>KM0=iYA{14#AcsHBd4^!oNEEH_ZBGNrVF(W>UkV$E6+6@ zV_icGt5j%-)$Fo{SnNNjkLBRe7^0%~^ok^_bx@tU_Unf&uf->4_~R`JhX*)I^5&!+ z(8g2$OF=Nu>S~gjIH_AU(+hGE8<;HC-y7)o*TH}-&-=O^(?j|*lgoPkxzt)3p_2r{ z&bC`L#m>84J;U1>8ApyDz{dT@JuT209j^{`!njkjPf>$EdjCcGx1T&qKfmp3iuagf zFkkZP**q^RXe`%z`SSjF)*7?Wn}FCUTEj>99E1>qb_hACb2vaXqj;HC;&>f(Qbngj zIcTtinQ}%4WpW_HqHG&yF_(Ld9pe3q8aIcF%XA^yH&nhSD15LlU8)q7muxsmQBGS3 zv(x^gHfIiVePeP_%Oo{qn`!RkppwFZW%5w4GrU^02-sP@vc-wbb9r!5_ceAv6UO(w z6#TT#3$RvhUp*Li2{{HN2@qpI4%KWz4iVyqf)~)RD%n5+DFR85K{dOCNLnJCSc}XM zPi-5)G;%61@{WUR^t;w4Vg_zdq3;OHfS?;K*`~Qfbd#JJ1B9D$^cONOhmd4W10nYZ z1smlGV| zVk(Db7&(!7lDyOmD`|*vyNjA(Ya6tP$F$SYOyZh`m<7|$p&x20xSPeY6}!fu>~ z7;MlM5-sKpG>%AnRkY$>q?8^c*3x9{I6@$Avs;>-Kmz(L-S3OU2toSY+aJ4smEL*$ zF#X!&Yeoc0=C5ko6l@^wFrVCNN8}!mqcnfZi`o4B@q9Ddy0nmaWn>btazniO4BH-3 zY_{C*&-7F>j}VPb+)vLbTnuWND3dvrTS2hK{z%%u;<~0GratKky)}FzkuKYkKG^xx zw+(qu^W*FklUqS@>+t=To?*lPS8&=9L3!LaThEw8R)kjanrO(U}(K`!mrbRuf>-&?i8Mvp_% z(l$+<8Z>Am!+%WU#n?XAG@;ynWyPwRe&!KC&{V=1FkM^M;a!SWXtt^9kvo%CKMwqQ;kwi6(Hk`-T^Njzcb{}2_fzCH(BbVK3H1==B{%)0ZSE1uBPXNli){*9T zWe3EP8?STrQ_U{WAY0O`%s^ayjgANB*snFer#az&{N!2s-p`*GkYY2MV%x?O4RXmu zY%ObKLEu_@eiIP;2nVxH@#x1O#Na%(MJYRvYxYcLu|~re0;1*2iMe_hjqIEAw5%y+ z88jKTF5cH1B-^o*go14xbklBVP-KDkZ)vub$`KsXt4VMS=h5Jq*9a3XVst(^anofk z_42sp>b|sh{e38HW~N)?$r=R{^5hRfvf{L*MQ@~MsM{i3o@>~0bEAgU+BRX^JcVk| z6ZoJ`)(@3GAQIG8#&rJWob_Eo)*wh`+pU@i`o+rRGTJ501O(C0-j{aCDVJ$2Rg;i| zXC*`!uHMqXqf9*tZXqY8WN+0BGrCoK`4@+abRhJo(>Uwdt1qU4l+^uPdH(J@HU&cv zR5pz_c^}Hb&+U?ejc{V+_Fu3m2&Tv|aqhJ=#76s%B5jrQZ`#tV8`jhIBqT#jCG8%5euaLfnI z$fkP2Uk#}Ynntc)q3;d#jdS!g+dlp9CVlepb^4V@bSL86USK~;*amwa3uI(F<=RljB*=6>Hdt^nezGtpq+_$&Ft!s|) z?TrN4Q2TXcSgSqb_0-yXX5S!fYG{W!4Ke?Fi&jCK871*$t#oN-(GJadruu70u;u*0 zdQ9(cp?x@qM<#IMr|_C#e!T-tu~M*$k}L2=yk=ENBdlFM^YkD5zP`SqwCcOo-x*>oY9v}a{y=KKHGah5b#y#gJ;>|~qqe_8V9LNZI=87NApqx3o3GQr@quhA(2X+q@`97Co)5M^Xj zy+cC>^&2^t*P1)L2+2^Q450wTt7k8uVD32ky~kZ_2r_W+Lj#5~q!_6OnkmW@qKs;v zK~&2u*_shi(rD{(eb+P*&c_Ly1o;FG?FJG`f(kVCr_BEQS@TCU#KbA9bUeuHm2%Ul zlkd;bL*?eOqKguGPYEVidnUvUBSl&o2^k4T2oyp1ENs#+BcvY63)&84?s^4W;xjq< zRx?cKb8+>%1=fxJx(4Ica&;E40CNkOf@mxHk7%C?5fd}T>AZd%=xMkaQj?t}(Ke(e z2cdz;1d=amwZ-veZCj>1f{rCkzo;>SWB^41pyyficTJ5BAWRQAko5d^pMJjET6w;w-9j~|i(CDXwbw{XUy+&O1!nXV&RN<;j|nrtA8 z-i1Bp^z6~m7@e#kxkfa{B66%{11Sb4VaYzY_t zosmvPpO};8^7@476wO|1iJ`rhw6;o`$4Dxg-RAQbG{maOe6qgkX@HgQdwYMqShvqe zg-m@%<#qkh{dFVA<;2f(2V0}BI@j+d|A8`XxOtp16UcX_qYLP4OF?A^ctEhR7KDy| z8Q#CrpGBly5*kB?3uvD$g!ek7{(1{yxO8A zR?`rh)C`O3;t370Q)>SryO5Ek0=gL4<|K@=f4jy6LG9!}fATE->rb9a#g8D3dlQ2( ziZm;I`Ms!okZnM zy{2WwP90t)Sf^jM*QtriJE|e|6nQtX=&RK)IRSyB=_A$J$g1A)rAc;a@`6mp8f}4o z|6!3f_J!8>T5Gl#Jz-qrtQI|zS>=OVO8;~0jh*3m`~D0$)l4@LSaZ+C)QOWF_}5kji-(yS#CO?3Q25mL0i=aahziKCS|(|zs#)&)E&J>E8Z^Uj z`Nw;y}E z*b0Wr9Wc;8zSgrKa!WQNrdzy=A~LLJ<9ZP}HWFml?^BRsD_iFqf~*H}@Klm`Z?Cd_onk>`QGCE4j+(yZ-sSke!k9ZbF92RLRxz+rz=J} z#7Mgs+qac-{}PdqezsBip70*1%}1mde}EIy724IwALMIKE`v(z{V-i=o5cmE(aZxW z#>geeX&8N(t*_ZHk?DPhlJabXULuvI?mot}7q(vE2&CQI-3;vAX&;-D4;qq|(YrZt zm%qHbOn!eeyVqA2HXq~u1NOkWW!NEZ-^&(F@GUR&{pYtCE%t-ww|e-9*0pDf$$lWo z58(NVlY=?Z*1i~s%6Hy*XR`a;QY~+e`LNc&)gOLsrIE7KOySH_WX@Y-#-Jz2m)$uB?lJ8bF3oG;D1IVf4Y(ot2`8?90q@hCB^_nUzBn&iFYLRwKs!(3C%NlJ< z%{K2mzJIt#w-<**TOh91c1rgT9W>at}daA6q|m>b)or2nO=wj1NniNESywpn`6IT9(LIVLXXO+-B7#7 zai}-+8>2SbziLs4CQi;=&QT_Ahot$1ehWdUo~_zv5>$zH*5aDTaB5}Nb&*d%1ZE@_ z*V`JIX_|=Cf6yOm;u#%)w@o9==o*me4?3Ed5DX1L8Xve{M!z3yMOsOD(Wd(|r*BCE zuT;OP$sylcEi*E=uZ0F7w*%88Y}gK|iTa+&Ow{%(?+uxI+z;7!0-N7IYf?VFy-QE` zhxFu*v<%p%?h`XSQVE)3px-NLh;cuGKSL&Quxxv#`!N}kH4U-s3>BxSBBKR4;cbkM z2*!=rwD{oDb9=8L!E!Ky=$fV8$)-$N>aTaAaYZ)%mh%&6pxXDq1I*gyV2SPDwoO~L z1@V1+|6cmkqnq@Jw;rT>_byEeaZ7^hVBQT8Akm-p2IY2Ia<=PneLg#4;}X^ zHZr!C+oguC*BG10K(+CP+iT4})%bAA^DK~I7*`x}(43kaOshHhOLVi`UzO=(+lWc- z=X4$+{hl%?AXujNi{P1Lbh`|0)eH+7V!EDkNfM@6CWvOygu!?WZJ3%}8n^ZOm^VmJ z3BjRNxvcB7T-SNLuDd&fP4|uU%VK=PJgI;T$J0it^1k2uXIlm&qaDOgH24oF_T{X?GIFC@|WCckU%QY!S_J?y&wHZ}I zPBgm3=^D!wDI(>HJb{z;?vO6-+50nOiX@rbu+5VHBI*32B67TEN^tP5&SSeCfR;;A#>< z6UhqZu^Q5~S00d+m~Sc))-hMqm?}0fSLnPPbl30;_3TZWXY$URza_uJVE@NYpQeBP z$+MgcJD;04iVWjmnKB+oe-iDM|K*K_*oQSz^@^VB@{j&hXLtPnO|s7PRfBCq{$0_h1LCB=Wx{Cwf?Szps)3B zQ8MSK8|oe0o6dS?tq#y(xawWwi1O9#RoZWC?>7Ef`;E*B)?Ul=i;?ou?B6nt#VMDA zKKy-TC!Hjj%Oj&)NgDU;RZn;S47wV`9|Y} zM~Z>Y>c}K7YxEFva$70X@l`tDd5xX5=FSn_+5Dlk=HpZ9dmqg7RmU~M_|*0N`Swd1 zVtk|p+1j=ZL#8ptM?|~t+^6cwzAGP9h#yqx0|PRwpc$s$n$tw~>lt4@{W^SaqE2rc zPv}{=U0blAtZBtTQ0&jOXY;q^y2>hGcD>^FUw>~xBdy=3(_#ysvEIQ4h!lJ6$G>A5 z)9Y|-XZ+Us$M_-ZkvP9tey-LbBAJHAS*$W@$S^*OpT8|_{=l+7MK2hr3OtjA^l&_p zb9WeRpEPmeck=Y*F8#-kpQe9*`jUHU@kQ%pr2etqDFVk-?F!o^l7NGe2uj8+f@k=>X5)9iy`O2(Qf?=pNAp`>|4oF+0*TNL zKGZbYVsNs?$zG%Vi@$qKpd4%%6uHt2yr7weB z(Rap~?fZ0(khz^Lk}r_Kh;{;`9@-K8?$*dtczn_jgA)c@&OGPwhWcqjW|?N9(S=0h zmDQhQG*58W&$i>*`$iD0w6#o94zks34n|0lhzmZfd0^TzrQ00^#daAn=8am60(x3}y!qaibLe$2C2i|rtqY&QRjzb`f0us_!) z>Lmu#RO1y|ua&JPH#sC;bf&kQ>mvxf-*|YFK2928Z#}GQgVi*{dRk%w-yNa@F%$D> zt(pO^Sk0-^(-J#ndCNIe(-g2ZyCknkHxZEsr?PAF#_bwnKIx6tJJ1w6-`0>~OGH?c zPAUYeM!u(-cGwn8G0ZP=Pz@Q$E&8jC_p9`XmE$*M&W~iqFMLjGZJipD8|@Luv4|AI z0vO1!rj4W-Ajw+DFiMI^wEmOr5gKAM+B*?BR5+Ys!6?*Yct0mXR^)LD<-d%`FAahr7*^SK<`uM-T&@!? z($&QwYl$&}%xpr20Z9g=7^dAyyD9G#w%@j9-ZALXVu%=7ca#z9%vdvWd=D8`^S`wG zM!oCSkYd~oSWvpwEwt))owQr`;~d*<4Ie);?rj0~3?`q%82T|j^cqsE)!o;%0U6=# z!472``;BcE<8f_#KI3=|rYnr+uurkA`z!5x|KTs5r|-S@EIp^S_fg|dd3+h8Tjk{I z*iXC(h#m9wy*V~r{=t}r*i2Q`IyH0Z3k{Gu^~ISFdLYLkPlzxCV~~kW_Y#p}Gxvws z{TR@9?X)J^1PY49pqFwi?>K0tnWaL%p~ARo^PSW<-ZgR_7L63NH1eah4;Wnc84*K4 zr`;i4U0Kj1+L=C1=v{ElB3o8wM-@2&w>lXv-`sEu2(FmG&p*S@F<{- z)Stz>qLa~J`@y`%l~`mwndf8M=IlOxnGoIcSW35qfOCFmnL z78NzxKr4wLVa>@JCo}f_FEt%vP0b)DYDlr!+IPS~P5xN+SF5{RA@z9ix6Hf*J#lT3 z7bk~NGYm*QAisEjXq50hMU8>kXFq0tS~x!;ow2)pdPyB&&Me~~j(&?Lw&Cs8>ts4Z zlScALG5l`YVbHcRdRGMFXp8zcl1NKTM{=1m(4Z}NP0?Y zcF=@`?Y#jtAW9~;Dg62M>uTcD>nxqd*sQjg&J~rp!$Ser7hcXY%?_<_cl#-DR@Ldqr>Gzx{%2@ zAqZfXw$#ZIq79Q}6=s&na>=IaGHst|0XU7FRpyM`hXxh(zJ$7Z!sh1#(#)P0&#hW& zQV+0mJqaBqYqYU#h%nPgpnA;+04XOsJAVcF2D_wTm60`q$U`}_lX@CTzWiE{5OhAY zXV4;9`({KW+B1-DHCr_uq}_O%>xtWe-EZ4An$R`fT%_f(!Gzl_m;t?J7}a-ALo8~z z5ltnu*sxVi8qtD-?K2ty&9UI5xaT#q(cQ7qGYGLl#a^8M*wHg1OJgP*(=Jj+mbG03 zDduesT0|tC(K8@=BYa5!03ZNKL_t)jfnZCd1q9c+A!3nHCv>plh0ioaLb<`3YfBrN z0zjIzG}^q=p7v9&_@LP~qbU`y@9mKcK1>SH@0M+CMM9SbO_qJ8gG6wRf^cmc^c|M5 zXTdNFu7mcL?;ndO(@4w<0HNRU$UZFoe9)HOvuOe`GR!#o83~6BOCaKEb}JLJ#@%lk zc+eOWL2K0pu z5rT2Y+xNu_K;tl#lTC|#a?%l_<$dRj&RTFZzoPk6Msm`)#rv5i(VR`k(cgc2>p}W; z3WPnlc3Mplv19ayk(r>#Q~)hU&?Xja^gAof$AC;Pl@p?t#z}Ps1Ss=X4Y8PX5c`i2 z4KdR|B6NmkPg zLw_``A?7s2YVFx+mg;vP?RTq9$DzN_eoFfNo*gyARvKa$KhB^bw$dgO?KJ&e?aP!k zt6?i5o%=OIsJCrh_sH=jO|hskRb_wa95&up@Y+)DZ6{BWYO)Ko2zk`mPvr{`7;8^bi@mRA% zFc-nEG&t@BHCTV;YLJi_Rk2?(&iJ4yo`3< zPx@W^-UI=LWNa=8cKnI!wXLKpwtkACqYz5Cvi^!^ah!R7XN$?pBgNhX#6FsFtkXSpK!|xCG@SjoSVVpy_=R%V*e}`$f>{u)PFJFl zU~zgy8we%}zRhXU^hmO;oHM>^HV4ZP98;Qu97Mz2LU?x>w6d4iCcUj8?P~8sGrcf~ z$Yj`pXt)o%gRBGVDiA@jMexwIwo@X<$a#k#S-wP`)RW+@WHO1JwZkxJ5&B9B#!>sE zMJt@uEn38pK>?FWJnq`&%rUKhq1}nLr{h787xk8Pqg|rbniF@nJ&$(g=$Jlo@=wji zIwdD5S$hBwZsA+$G?($&(Lh@%w&w~GPup{t;5!XbysU-$It(|%;WB@rP z9gHDYsNdpXGc(KZdJn-Y8;_Ye!Q34^yT7`PPnwZ#SZ=nU%x7%R!$`8wKD6I<8kJz` z;rcY@p0y3cOlfN)%yAlGW9#b=YW=rr^_}mpjFh(VgU7#MyYYliFG)gOO)LJccz=5z zO}o0F08xhHA3j@uG2Y?C^(t;3zkA!-uW5>N`(D~>@6~bZl`-U)y`QlWySD#$-5s+h zCIA21dr#B%e)c@y?i&rUV`}rwu^(s+-2VPwIF8kFrZqYBkXde9&NxQqJ3If7ac3O; zssZx~IQtPKscBpJ-w`~?^n)~sk_;$h?}3-zT=$R~PB!?vSv(xnLw7AqHO@2stRoymXOXrb8k^ zB-2D=1fI|QLQn4?ZLvlGGOvc9YW>dl2gC$|RGgW; zg~J;4U#jmJ?T(&?N$LExOtz8dD4q`)zOrQ~7SkFd6VrGmEHjfcEjb3>qhl42X8QT< zF70>w^o05m(xlAu2t$HJ+vXEIZo`h-h;*p!x8-;0kI@hJwypEW@$Z=N5WzF_Yq05a zCgdspdfJF>Z6!nQEomoh9Qov<>-4F|57MtZy6(;^Yux`W4OrDuZ6L#Xntuo`AFUat z&I)njE$p#H>T%)l{h^Ca;>S%N&O@aX@o0CgJqzZ>BuAZ^xsCpw{cREvFuIy8}008`i{$(o_@u zNwI&L=-^74O$ches_n$>p1eO^*54QntG0|d9;&n6USMxM@TSF$T>0?jY&RfW^sJXjgyzABfv?i}ZhH-YdCnR0g{&7iu z=XoD9?YWhtzx6yDN8*l(9M^jfDc1Tne){xfdiRG<(@*d2D&taZJXucQX6hw=M{f{f zQ?rLRJI5N>|NhrDRSGRy@E0=)5gfBct7%kaZswUqrf6Foi%habDQHUUu|fM+%iOc) zlbnnY9P>di>a2Dou$sMtyuaCe&6-WWBdEu8iu{LQnMZQ@mj+sxT79E@%eK}yJW{H5 z{Y?!kaAvP*&z72Qqk{v{l&m$}`2DC5cIAe9^?Pi4rcT}HC)e#WA~k#U-7ClaDxF#3 zd+Z@;C@2Li8((h(2{x8H4-R;1&r8ntv9l}@3CvN?f9hnb*jw8zj+=2#>OCoaUms~! zzQ20rB^FE7)w4otWOC|)V#^>I2dRwCVXYyS>2!%^*CD}5@9Wq)_Q#j%yTuuQ%4?6D zYl+NTE{=S#%;-$^37R7`IlN00ETTpGnwDWntDvo^xyTr~=UBg`&$|@#DxG@-i9vz% zC%b({jnM?bNgnEa0p~6w!E9bZ>cQf#Rm2Inw>xTnzIiFKsh z>rybHCFZ%=XW!?k_rJNkOz*sPlRo+QL3(g=Z!y0c_hq&-T}Q|H_I}#oOH{p(=~~N_ zKXs)|oNvo`GI9FT@7nc}yS2FvngROb?yBuFu~Dto`*nd5LBj<7OD`w}+N#pLx`%@} zzS3&|BthH0P^z{l*E#yH>1PS;qv^DrjKK~xr|H|B3IgldYb{{BN9;#C#>V?v`=9wt zYj=H;`kuML`L}oWBU(W;eM12$cJ`ZUU0~+Lzp@)`d>5Ul&NBG23~pUqT&2Tdmv{?C zi)cq${V`kLZ7Ik=OhFEd(|jF{!DLHy4BP(VXhpeJ4>DM1!PhWS=G z-4d;9I9X)LC!_QI3eSwyza>eIFkg(UN6xA_*3uA*NNV+$+WZ*FXq+@*>lq|bXcCaq z2-~C?hUxN3)6r=R(saW=&)GBwt?~BW-%L^_ofXNpswpVMUURk~$2{{+TceFTVv`pT zSsB$pi#FFm)C8Yp5 zlq_xG)Rl5u{MjJJK`zehqjHZNvkYn0RN0b|ZCvp6jBq+HU6+D!*dI1+iR+%cV|1U< zCZyA?AcGiTWc!nM$J^!vTxQ0%;JK`+Vw}${yW~8+e{hJfi$iMJEsd*E&}A%02E>=s zJjj!nrHvL&2r+23(PYSMt_KADJS`(>)Dgl6845A-uSh#V%4m?#A)n~HIIgD|Mp|Kp zaJ$SJdDoXfyw&YB0xfEU@pFu5h=G2NCvkNRF|Xl<=T_~898BZuQTyiLn%UG|4SB%9 zmMzGHkwN>u<7nslXO4CXmYF8oKL1{`vHz*IM$alpMQCGoeY!be$ZugoYc9L(v9D zJk>KY|M30PGXc5Z2VE)MM+r$eQjXwOTtwD5_M;|{N6z(-ZKid?nqNITYk|@CCK@Fa zL_;tQ$g`Hs8f|v`oQ9iejFsLqYvl3!T#tXI;YRyCxud|?j#qm5&yYz-UKv5Q)({d~ zf3InX<>a6o#A|Da)sWGx{+NPeOuxz6Gc_dG%fmjAW+uwXevsck-&XDxuwFbaSjp2&6ZcukASvv8XwA8ci{1m;p(CtX)E+=lPWMPs#+~ z5D4B0v=o}>5b3;zSSy&mOzP_*!$k9|i4+^q#M`PFHi8^e1US}l(8#ITvM$nfpIawk zy+m8kB&ueaAdQc;WxC73chxMaC0m;2iy~V^wiU>sK$~Y{K-DZ`VkV_aHdj371pKVR zMdJ-glcK%nHIPBOuE~$8p(Xx2(FFDyp`!@o;r;Zx7VYAi?Sg8meWw0H{+`XBxU|>( zpY>Ppr|@#r==^8xHIfxt%%%wzHNw;u4ZfNUn*1%A(W~_$7=GONQ5_#@nvM;P$9O&T zD|6$cF^gzYat@+7jYMG{DS<5Fd{~2|GLPWkmyPc>UuF%rWqq&TU%T8Ga_D`PH1Q(B z68@H&R=Xv=E;an1IS5TW(;&3{KwnDRQaP!Q_djj^?cm;@PBQ_SdCYeD>v9761KpZi?;-QWG)^!d+!ekj89o$q`n z{lh=}L;CJ_zdN-5M{TFwAABu4$w&Tr$dg`qrti7rpp{38(Q(=B<&Y{G`3)Lk5h>O~ zj*W8c<9gU1PA&w|yj{xJ#qsCVtSLqIDL4ki*(j2z6a>Tl_v*J-UTa5mT>1VilM;g& zkb1DWb6+BUYIcO%&T#P3Q^!-%G%y$?_G7m;B&r)h-o zFE!gE$1s2CYq%^mdgA_(t|DrPA-DyOcGx-CtHCXYEFYvPrSpvZ!CCs*#}CrSAK#>3 zeR#u~Kk_%q*>C+vUn8upA;#}@hLgXgA%^}7L3Mp5rztQ}N5|~b%iJ8LkHLBTJjD0E z^t;(S-qq}>=jlSR=8$1i*B;n;b$bCBR;%BZW|*>s$@P1hV7>DA7+cpbI8W_(j})`f zq}@Nw_HXf7s+rx={jg@rT0;!oQw!K)&s*mC7%HD>zv{dW6Z+U7qV1egeFWI(4N33S zU7sw+<1x*Y_I$0^o?G*~mIha(C)75&(&SGp5h1A~g&r8Hkwm_$a-TxjqM zL9p5F+#N0VUd_Wp_oDr?{JyZAFMH7+$Nsv4=pE{RKiKKPF;zQs?6&c5tsw?vnDA8* zgh8)w<2}EaF)kWHMw<%p;UZj_#Q8utu4KvxlcOP8N+FY&rE@iBsK7o8{X;js; zs}xBl+E%6sC7N)8AhAqF%Oo7R-{4&b8f4NR z9d=o>tY(j9&>|@8k*yKwiXfTSbc6O=Y3uv1JoXDR74&b^?kO|M+cpU@WNy|pR0P!W z_f~tRU?YN#*hcL3OlnQwyB%;QJ2PsrgOGx&xwIg!~f!2}zR z?D=Zr-%{hzoa#RK*rKb*lmAMlUDS|6@RpEmv_SaTjsjzcbi3Q-`3b(;wYDkGSI+tS zO}b1k(msuB{eASf`1cnV>GE($*kb?qJKN--BLQRV&o=619ZX{y(@_mE-p}S=k1wy% zZ+`4y`t?WG>Cw%-fLyZv!;nt0*pu}oJwd%F{K1S#j(H>5qAr_IR!`fj8ifORS8oC7?B}wTO zXu!0P`<4WT^~w_Y+M_RD#V!z|$N(crKD!j!EwK>{)Acu@k1HD9BfonZ-C9r!zyH!~ zl}Vwzj%YPLuJ_}Z6?*HESROUQrpLjChS)mkMtbi}^SJZ8pVqvshFm&jI~ZG^BbYYx z<=8xR85C6ai%Ex9XiQ7m|5ZRoDb^xiY`;#jXAiGUbUBL3;0{^>9( ztQNo`wAkPN?cZif#W#Ok1Ee7qHNcLon^Darb4u5PW>NbK_try(^`2og^OE-KPkxL( zF*_P~HLRKOT{tQ@c;%)`b433<$JFoDRZ7H0MO$2l?E6Gt;VyD){r2j=Ri0_lgg%j+ zeA$U3c5bsYc~JWpPJW$+2F;zAnYp}MU;kM%DI-J7NfK?pIH_^xj=W#&(?epm%HfnI zXF4X!*YTDQ4d zNzEqH=0F2M7VnB&9kjjkfAOALnXYj<(fc@FLHX?Wm%o8mh-_O`K@He40`YkT^;x?F z>bZt=^vFi^8?&<@TzdxDQM%um^-C`ZRx7vOs*N0*ePuNyLeYso=}g7F#L;*59vA!1 z_>}a(W7Z|37c4(jZGKd$-w&$&7TfebrHBk0MT)J@*J}aidp{O*RtJ~X13u{0yP6M*_4X}(M-Bl#b$qAWK{5)E zybF7|8`$z=DzVel?6oX+zgZNMX^iS#g-~WF8M}MFB%xChy-~R32 zPDHO5|0pQ-jcu-4HzrROZGBT zzKrZZkg&)4L$b6u-+P?!DEC3K94r$JHT_*|3Yy)L;H0ym=>li3 z*LZquh<3&yWjxw#~+TN#q{{0l&9^%ZGzc}pDO#w*;XDotl(Kh5CBhkEO zn`yMwH3q4@-n+U?cRSM}j5gXaz9Va&tl>ZiBSr2A!U*kwgTY*$k)?{9GXx_A8Csc2 zUgKk|f42J>Mc{cPn`)m3cl^?3q;a`_VzBYQ}%CZE}xby#)_3i{{H*q~~}0bi3cB zU))mv<28b;9cR;<05QZ+uz8 ziYZnpKe&qmMLW}h^E^=w>oA{Hz7F^q>=_bk~qz?)L>U49Q1s z*|oae1rlfs(KVV0AA{*NTZ0XX6oYddnYhtzBgvG`U4q41?b3G@kzrk1<{gS415yk~ zvI=s{g67cFVy6zq|IzZMa~8-Wbt1Y<@dYxBL+rU+10a4^J{xvLCT^& zL8By^FNUmzrXY~DY@bAnW^o?VeBtNn+gH#6bKCtcC6bJSa|||bF~49Q(eF+Yg$&;U_$b$^=~|1u=(@SHl$_U3GZ}ED%#MaOi79y+QPK) zL9_$ce)D+XkXPD2A*1c6Y*e001BWNklOg^!>{UEi@CU+3f zsbA-u9YeMw5X$t!4hLb5Ri_!;xETAGGqwF*+v=ng}X-oA#^q7p4BA1a~jB`xb|F zM(j8`EZmPrlIGvKnVB`s1MO5)gafp5WeqVGYyc7i!4l~wRQR680r@@DO$591*k1rChds!qAU8Y1fyf2o*zC*wA=5oFVwZzg z`0itW+|zLEm9Of(9pOYlw`~r(s{@$3z z4E+};AMkv|>YHu+MI>0+uDAb|h9&3@wdWKXM7_8SIM573aI0m{`Y`<4__h02>7BPo zAM8PTaGz*td3YW{e!1>Vk)ufN@W?O?9!M``NHFJ|&Q1oi87WpSr+HXJj#)x$K(?$j zc1%-;gWyqPXRWz2qd?Nr1nZU8<`>%9DoDtvA?Bx_`8~Psduog zsA$XlO=)kW0YzISFZhFWqE9Z0g%8$$&=F}FD=2m?opK}z=*TI_6VZNE<4L(^bmM(7 zb-Yksbf(IFIwAE@NbA35Gc(HS|}MEdQ3w9!7(X~NQPqqvi8qtNSp zRIR>y^^5lXs_Xj{^NZDdxhLX1T3*T~2o+pqegQI`#Zs6!oVEhUA_HF;AZNauRa@^H-u3vb4@c-b0*-J^yrt3qoiO(7BMRg1y zqf7LNHlA}(tY)u=Hw&U|c`X_&bK^UbmNCAoT!>ttZnqGZCmLU7+VkiKw58%sbWHhi zYV94Zd|f`TDQ543zl@4qb#S303iGv62X&&l8aYiIPfAIz2qM$@Fy6)S&)Yplr`h?2 z-~TM*-$+Gm-KX>YX>-x>uC59D!}njLfBE5)47|Z#3n`6#*7f}n(h#G7)>ps!)y3 z$AaT(_A*FTGp^PxgOx|b28@>ZVzLjkJ zj;;1@gyhVcWn&tAhFD|7%Gx%s7ngh6kZe8V8{Ju z{#=o0;yaEu?H7Y*B|6UF>=A+gK! z#GH8gNbUKi;Qkq-klf@GOaQ!@F{ zzpZR&fk6{bY(;7oY#M(fUFk74-Dh@pDpJ}sVXa>-E39a+F=)b+f?ApMR^|;zcHrkU zq){z%QV~BYB*ebyn08_tJXiAwp=owg)W^nL#;of z`{B%Tqc5)7@}jl;RoaeT8S^i=<6tAm2~EG14TP*{{Mq-&ntE#+nae02M~-oSVf(|* zNDS>ipy4ChfvV{rzC#_&C9{~CRe=m!)@R@Rb2rg|;; zbW6E+5-I|$rYRywvFh~~lF}JUhY&TxO6%2a>%BqE*%A_F zND~O!I=IffmRO99uVdv7ii==;=|vu+i5E5UUN^gjL|?r(1g8x7MZqm=PZqo)#K(b{ zm}niBlY8qyFh!*04g&oqotMrRkYp}7NW&*Vi~5-FXvPoYuhXU#58>cemV7NMZs_+3 zM0>+2+>Uu#xD>(Lt#rj_JMIj~yQnGF)zWNeh^@!ZKK=dB>))h7R%RBMp&33$bM7%e z%*aI4lKjtc-!_hNy^=5E-5)$j?-E+fjW2IB#3~(7q)MC(hT*iOpx7JgM6R9NFVzuZ zTY`nuIU(qU<6*-oH}kR8G{m;tn?ELJYRMltx2}aw5sMtqE9MLe1kEs6YXre)@~w+l zOuBUu%onspFzmI{4EN@pY4|NJqTrlEd31iZD0O?z)MM*;%keGbQk;}cO}1Pv9>0Ha znyfO%mxFLEle-lpsSVPl_Dt``Bkw%YkLlQ$)=b}Tu&bGhazI?`u?fsbm4Q7+q6rd=aCP!4**W|~m4U&UXmzP+RX)}6h~^;6$7^%I_c z!w2mn&7%*RA=m}vS*ac4UQdZ6jnBWRUoUVkK`!r9&d2sDcx!o_IOxZ-q?aL@S_;hn z{BEBU0?Ol`&}$N9qeF_tFFxs+pH+FyD~brJ!Q3jyjiZQ)TBbE1QL^N&_$ zWpDA0TkL6C)tD7Z^n3dKk4*Fz&eXB*SM?j*R1{zL)XyRghsl?@+;Mx@J)5 zrQ(m@<;eV~)l7QrH^*%bb+gheP{XSd2=cw*N|bo1<**jHeep+ zZN0T(g_`>M{Pa1_?l;#%o}Zm2IB?WGtPb8jzK;hF)=05P?u^@NBEfnO-l<=Y$?2Vn zr_*cX*vN6C`;@=GW%8!2_qV^NQKp{J`_}zh^=&WIA(4!7=maQ;dhR_xpiY@kl%95gWK+=)I>e)AxSxB>ntuH$5MT z^Suu(W#Zd!znzg_{_hx6R|#!K$g%g{d+!5pUmxTR+8{0Q2 zCCU;<`Axb=FB1LE<@6l%Jg`BBNX{-G1}L)y$HQ3}?NY`!f>M-8PZ{-adV2dR(b;+7yv_CoBnNF61K-_Nd-g>r2S^#;$?GCJp)(#bEB|&>a zgyrvk&;2cHYw`Z~sh=YRZ?fZ~ea;M6aE)V2nc$Q`9&P;2TglMQ{R3lJ7ztsTJKm=D z%RWDIVn=)J!$5r)=YFm)6M4z+^V-p{Mw>M>ITIb4h*aLW66Wlbw?&P)_zI9^6mwJi1B0`uIV*xd-f6TVp4?k(|az%=D|Qw@2J<44O&O0!`9Y9-2kre!XY%v~f@2swA zPW3dYdgX1+su9k9Kc3Vwg*B61f;Bz6nqk~PB3KY!R_m3ZyE^}*yk^fhDXhKN_~L1$ zWAacjsIK=L??2chLB?KCtWcicqpRPh?U02rsce)PVG%TlL4+aOzK#Z9&)L-8F5Sd1 zBE>Z6Og{XYea`u_CKoI;xZHfp(<>@+X%s1D4QP!F6Qq%{s7QqO=4i+-A#2CS{G>;3`N7=#A8Y7IgIENX(aZI3i9C8Hn+=8<5GI5T9J zw>j&}%8>=8?YNZ{eJo{A&=<5NHgvO%M zhu4@AOojlmA4?_$Ti+kE4vFpcsP?;R&!&|XwXyI%dzzWca?wPT^@!2(+I*LZ0EA%$ z$n7q&o6n2-sW+@?I$qxk0)3r^^Y5(U(PtyPT=`)2oWBq~gW@J6`p$&+A@rz%~`d|1X zdcznXn++sU0E_}-_#+*%Z++`qv#0q`?f>G-f03Om^heGea^~Ovf^PVu<7e#na%MEc;Ebcm9Q}C>F}e>puh&5@T$O`esu?E1FK^Fr z^e>;Lrzz%r0NGg^G~c`?P@Dtl;!m9NuzQ*`GsuJzk_m#N&{)d!exd$b&V?aogH~gE z+1b?)TWJ=F1e%<`HRpU4^_$zQNmVH_0@vQgS!|j+be>U8@sd-~2hn_xEC#`FzcWZN zI);L86m)|o8@0En3D(mTi%!~}CZYdAx7Dv`v&f118e+>n!GgR-Te?hzvs4|>ni~BP zPeRv7$t7~qIJJ$Qg%@#V^Ih2_SKGS=L3q(jld|4oF!teF+HZ|EpjW>o=aBa91Z zrup|RncJw}mh-HA)q3d`%_Vw27*F26+vkKE3XWl3f%k{28WN0usoVVBaJjaSfCTHh zIT!oaG{rDK%YB?^w&RM?F4f+z+`CGjdVG^U{^%w>J^~Fk3hawWG3!4{nm|hqcwGd^ zgVb%Ve=F~6SRlE^`V$NCqW?nBSL;z4@~G4JnEgOMhI*c|Gm;w42Zy8_ERTvXb(tfJ?6c)V_Ytn zAR3bx-&J!G!D^J}6D~C=_5Q$z>VjH!{UyC$Eof!qVfp>V@zRjxn)8x((HxlUC6o0P zfb3Xr=|G|qteU^>=i3?-bCPr!0VU@hEqBBrRiNXtf3x{9JNw!;=v6a)rhF%g%&*#9 zqqcw9hLcOj25~OJ9xX3r%+on~^S6<5&wLQ)7hYqxG=HP>uQhkAzROGsPIG6$l%S)4 zs&Yjpg{YCY-!VP2&X>hmsP&C<^dl&j30e*kWsTS~X@>PCRxQ4_b#?GBCxxc9Z?Lz1 zsv#ZY{Gw&og5JgLpUtX*L~U7jDu z`7)BS@~7^SP+N8>S;*SQasG^rRXcQ8Z~a&<)H&r0 zZ)Zaj0OhbrW6W!Um24o$7zuZ&8YE;B((dKOAzdFXy4z9h6400VEjeRH5eo>OsYX@i zx+W(qXZqJP!)h8kJ|m`wOoHas%(kZa)3&I@jGY$;$xLFK23rK-YA|{l^r1}`w=o(C ztu-v-S+k0fl02z2Et{H#P5eDO9U4f-=Y;enTwgG`wmyoCzq04a8*6ZfS&h z!2=N3&F*1{=oa!|ras*LK^o$i=yyEY0wvYxDw5YJ9=LCTq zm6Pr74@l^^#eExnBnM-oJ*uU)Wj`AyZJaiQHV4n3sihipqOqm#SL)SgUYC)hYkIjJ zyAbG7wGwpfRUNlqQGK*`O z#IIb72byEq32hpP&H5MzHiu2_s(p;;)Zw?+Jb6kVzZhnk%Y5?l2l_=_r?digy zd8hR)8h47|m7o^BGX%k2sV(vi)KBH>!*&{k+Mb*BOUn((^mm$bx&JF@&~Xr*`$F5u^l!2faG{vAXR&ozU zO|jKLrg{tFz7HB=7IcPl{ruZ0n(>n%prhzw%`VV~HvF>7n7|nF_1yEGEt*SFQ+5XV z8krU%14B=14oR83UR>7bI_cvWTHjG-g>j~Ys#beQ0z0ODd+nvhbWzpNoFMAeq>@)c zOi*DENf+te_ufzc>&MR=vxX%Ctrae9E(<7%T2D=yZ%I6hYMhf=4IHdF- z)92bY1~o?S8TQ96C4$0^>#3BtQ z1rafBWm-%@TH|-?%|L&(bh@J)&iK*iouLoYd&rBO(JSzx2Yip`BLCGE_bW>^gw_NfQg>64Fd(yu?dNjLXtv^o7> zoDa^7e?1yA+--?Q=u}U#r9GeO+MCW(S)8iV(hG*W%uE3aEhJ;CH(Jh;*7sG{q~v{1 zp(PT(kC@uMskSyBG}11%_HUbSs&rtkrkaLWYyiqD#8IWG_cqsmjXqP-6(l< zN?^-KyI3R7Pw{>9-q&c2^M0q$N;zl$JW|i&-(Rl<9Pxg10F?I=20#rWDN=0it82aW z*niKp0NMNO7ua-H)q`TYs3FBNfbht6e$Mt?dcaqS2IcA0NJy{rjk znem|at7(eq;2;QxS-X|VqZt>_f|Cqik60q46$QnR8SCwgFmb`Miv#UvLA08U-$%AS zqaXE%U{u`}&as@iO>`B)jp}TEf1tB4x+K#$VBb>RUTPqCq!`~HA)FW~2Kyyxf~{=q zcbTZ1+Vh_HRxa75?+$KF{{HYCnuZvDZy}DZalQ@P76N93vme1O)!vd|JlTZMq96fl zs|jK^)9f-`AZw?w&2)nj+;=uDDuDE&@|GQuVbP{Z?o~RZouiwInP6lSqAViDM(r77 z7?5`*n#CAQLnb_sd1O;2Drgr8ImR5{Jl>DmwzxAo2l_7X94JQ+j_jQv??9&?g(YI-c83L}R zA@(cRSLu@vuhS>rdYIn2;a1yA5?U<^K`#c4t08UCDPU$FfCXn3y2YApl4oUNjbBjGmdM{ zl`<`ld0}Uq1>?z0VU=E~a80I=@=<%~#DWuJsTpSNq)juu<{@)It74Qh1hvk<&zRdw zO+zee7rFA5h8U7IoVL?4<9V$?8RyGmwhJ<#dNdYjnnrngC-<8XFddtbGnl_EHL6B6 z2x}ShxMR$hTS&1{I>lbb`g}Qp3O$X(mgb>D^cDNJQH`*+W>|0iGE=`A#DeD4N~>sz zFpY@Qli1J*gC>&K4AW$&pcxkFXsh(J77Jf%h%IB~z48@}qWk{x-9dm6U#ONGRGpuEk6AHmFBuIIi&&Pj)B$>SpMx5E_!9lc|O~D~TLLrkX z2Ui4UL7!Q6mW$AE{X*9TXiaPb@h?&Gadwu=U%ze<$+5Q}SG8;%Gd>;s6yQAx%+}rdU`j1o8D}rSRs(~KXBa`Oqcl({) zinERCh5o!vleOFZA=5!}u+?lHM+`aUgIU@?$T$ULSpGJJ784p)BQ`rd>whLp>@;3v z_ZBiwzu`$_*w)(4nrjH2iqnnSAqCC!UUE>!#`he=a2;}9WPvVGgD)59{oOu2-!W>8 zj-h!_4H*_S#AYg*& za3VU*LEKJJgHZOXX%I$D!k+De2Bjp1YLY;$J;Y!rP%hYitGz(W2x>F13jkE749?h58N>{4?oss zCJ59ICs9Tl;|P*04f(_Sw`}qU;Sc_yQ`t++JS6d&h@+P0`sMXTe!ik@NfYpo8H0?C z_v~-8Ct$z8X!-G@=_@_M=x|z!5!ME@SNH(0`+Rv-6}6nGz_1XfOHF%)P_O%o>3&-N zZgJtJTW0m%H>YKX^aA_w;2*75Io~h!M3RQ5@p$ z9F&Pf!RRRz&(w@w>(jpXd;h(wp;6Wt0R5q4>Pzs8CU+xRCQ;i29}|9u^D5KhAp>_% z>*MNhk#-k{)Y}pgiI8sDNx3_udsj=F5M;>gr*dy&QigIx&d7dRzB{D*gha#fVr$TA z$J#EjKD2XHFuqIK9dMUa&=$}%F2kk0P@OImFuEw>R(Aa0jy$9&u=5m zRMVEE8SSS#_DKISo5>9)$i}0ku{u&Y~Lm9 zfh`_af(9+5B_r|;IXR;}+K0H#X_?ab=(~*?Wh4FGX#aA${T%&rh4$T#Bk-No=yWw0 zwm>4A*0FuBtWCGl+>;a3zE{=Uqju?nTks2ri0{fzU_mZEt~P#yTJD1@=LEmn{7dVX z2_>2ud=xYzFC!$5Vdw9izGno*oF?N!)3Bg9h$K5hs&k9jt~ofXQ8>Oo2gNuU*@9?o z8{-)Ex1ciz*;+P&V2q5hpjh9g?_ihjlmBSGT(Ykm@(1H9zM~Jo&OtBGy+dZ9VuP7Q zk;ZbrN7#8_u_&d`4a*P1SsT3niXQ(M&Anqa`*3{z{sft+nx*CYH4Qn*&6f^ZgI}+} zhTK4oTd(eS`FbL~{}LG%kzz4uZ|jvMQqRVds3981lVZ6;%p-~3+PBFXWQ|p5B09MP zKM&ke?g@CUJ(iJ|y>dLCeIDp1Fdi&5C}Xk%*7LPwiDmg9(}k}TXKsr8V#={=b5JUZ95qawR)(m`i!#z5uGRJb6Yxh*_?2ITg zM3z@yd73y#g}=C8kM6+-z399+ADxH(UdZ{qedDf2<*;coLAo~&Tz$e`EgE&sXE|6~ z+uQoMc5vtNf^afC`Q6hb-q}6vF$BwSO$5o%u3OuvVb#*KqB8o6L9f#W!A@7>?KAaq z|LYk^h799LRXtb+T0#V0QX+yj>OZN!d~pDhjJH6F#YM!aYh*-w3BfYHU%qerMf=qE z=aFKbZn5Qjr63uCb1w;*CqXX?YI!?qiqX9rz13-+q{Vq3gJ5*U+9KvOchf%$uJ5;? zSH_ltVtE|G_pkPnn;*+}qU5CD*t6Xs*ZBL~55loGLD z3$JdEEs_rF-Uu1SaHTCXF~{n=LdO%4EjnNi2(7=mYOG!fw`-Z^E`z^93pJ{xqHQi9 z^=8L=|9)nYnwGRmW8cfkUr8mixHqqJK%c5I7w)yEXms*tdYw<$`%HcL>+l>K?zfgH zJ`@zKIM1SU$i5cS49&lV`(0#i$5`p4MqBK+Ptv|;29T}op+*%@;=>&gGbo?k2!9hnH&a#oa#r?;pIMzW+XXM)^J3D_{9a`uyiVujlyYH@}&_^{sCmb^50pknQ^TSt#d;Qk40+O=BJGkHn}TWVjNRv8 z8wK6eK3t~f7o^q2nF9H_gl4K{6O9ov^pK&g8GDpLl=g`bC2{*A?bD6>y<|T;aFC5M z?&100gy^4nv%W-p-mc(q~g}iSCb{ z6PjUkKh$f{;7aEs`||2C?H%F`c4_-`w@;6*F4JMZPtaT=ZLpS2h&2kPs76}>!Pe6Z zqjJ)2GWs~s$no~+{*WGBGQAujurN6{O){qO!tV&?l#Q=kmrcTM98^n9QlR;06Ucp zL=q5X=$DsU37$zR5q%dqn1<9M&@77WHN~RF80?4?qxu2T7__$~`+)?@fD|j)&vP)% zf`;g?4f$ElXg($KpoS=;pcw^gP!8K~y@nW#Yu?6pkMR!3Fs4y7jj)~#Uy%=%-R@cI zje=D4ySHiJpz(mp>5qa?K#IYp`h%ueDKqSt`W;4;$#+Q2`O>bc&gVQRYXW znLbuSjQXfgzx6PE{NZ)_#N!7-v*i{=A+vRrxhnm-x*Vb%H4(BCb{UL1-Y(JTEHfzQ zohWiV5GhWxsD_k@$eEt)#J4o%RFin5-Z_|RnYm5dWftpVQ13rz!W1=71~V&Hnqf-~ zG1E{HEdu$@RI5Pjl7`p_5_YS`QcZKo&qL_?Elr@930wOfY<|1Ugth*o9&8+;*;~w? zJG6hZu9EGu3y_eVaJ4!U#F%~1(fzeT0!`%VF?%9MD-p6fKip81bdAtM`=$O4NV`0a z73`c@4sDm9$#x79y^Js%qhrk92Q;m)p79!2tNu*R3mU1Srs1-GiZqgao9kKo^9B!k zzJC|QLeL7)i&5KxT}$NI`F=-$1=kZh&^Pw`FB1t>)>Ih~wEhNd9UtBI$L+&sTwsYp!3@AawOD-xt=8 zwej$*^$cVO5S=xd2s!*(twrq zW9&~vv+uq4U#9Q=;1}uT?x6nF53PpS+i$Z91le4D%Xd*dP0On~taRf-@WUgU~N*Du-qY9RoV0 zdY$&2(aYtc?a$A-wxRuzgJ&6L&%v$R3wFBGae3k*!7p!n4VRe7-^=VDtzXoI*Z82v z*zGw8R$9~5)|NeuHeX)T6p6GM%liYYm{XJ~7{>I97iquapcw_d5R~g{TCJUMxL&Wm z;mpMT(e}tTnnb@KZ6%^#lEDOa3BiPOBG?5RL99`Gw(lqf(PqvO>-!iDkrx!Kc5YX* z>ASaJnY9nr2#a>Deu*f8_J^hw9T)36YFN!`T9puJGxd4;eaHK^rH0r#G`)8`+xz?f z|32q*oVH4xYA3+RK&2r-wYk_%CX#9<9Iq694fHVC8?v z!!l78Se{#xKR+jzS7kaXT&$R7KE4kh1OB~ZKh9Hz`3x{(JYb*Uj#o^oY-aZZ?_T zhiTfcSG{v8F5mMbsSQ^2pFX|$BNj*AoZ!xJpfvre4)^s)&;FZ;Tei&(9hc_Lqqa!s zJ(|Aj)NPd5$g}UG{~C=rruKUan@GW&$_B#O*XpX>k=^&7j#hWw(W*e3aQ|e~F7msU zyZkbfG}sN8D*R=}%kjC}chKb~WS{rx;GFyfrHk*>!dU5WoKj;czCKSF_!YbeG^A6XGq6oa@>CeN%pSYl(Krqt} z+j7A(O$O5L;Xv|C7%BNmW>(oskOrkRgLq;PyDg4#2TwAX(c9ZPd4)sfua@|gpWJxV zddKb0bAt~rOUgWb!hg@Y+*IM}>yv++-|nWgl!9R8pD|6!f#>e?KluCBE0Z@j3We_7 z5B=xgf9~HWu@g$8M-L|>BkQ&n+0VBZSUAKUf)*DsN!r_=ZCNZ`Xph|Xptn05JaXO$ zZpi%HdOlB>rX;WPDk)EqAb4@A$HMhNl9Mdy-r;j4QAJ8>p5w}?C+Sn5a*9~H;%mHth>@PJP-A}K}q>`-S6r~gMyZ% zgZ}hOY%U6$W}3P@AECt4SqmbI(vBb+@6?Tobh%zB4rlv>^MRlBHAUb#DiQaB4$srx z$m9C6E0%A}e#P$S7tVwg*L3CuY!}EXM4o(P7S+9UGgBex0@v}kZ3#RgZxSXpr8WW_jWHO zJL|oGFWkq!HkjO;pfGJWy8S*sYyNDO6@o2$cJf<7Wb&_91mtc) zNB=74D>xUu7i5ZY$-=;GP!&9Kkn~KL7h~QI5D5dM2DjVoGi3mo!S9NCyt0z05L}N7 zU32IvHU#OUkYZo;);=C7)A%dhX2nfJpkQAl_m*#>iIBN_)vFkiAAy!ofIZQ5*X+kVZx&XTZB zLoBb_yan9-$ex<>lsoHZvlavTt*GY}1U%M%7N@&CX|xSLA$OSd(I+Nr9!8KSHtJ&-+F~=Wd|ZYpQ7_fU{@1Hsct_RT1qW> zDu6}ilQ;~Rr!hD$RInsk)!+5Jfy;%zitsq>!WN{1v8vm+Q$*EwRZS=+t~cGK*|c|g zRJHm2{5HbAKY|#UALv{mO-0CUs>qgI+fOmm{Wv`sjosQ)Z}GI4ZOvs(bm^Qq4bQ&u zkx9;_yxWl9@~4Iz7wz@|vt!OKOYQ+Q+;hR0Y^J9=q3I~oCLjk}Obx;* zXU3{)`pNmPMR3GvFpOvd1h*fv7`x(DYP>a$yb>ALaTFvWht*H$_#M~ei*IsCoFR;1 zJ2=e$K8KWX)9wzy(9;5L5g}X5DrzH(^EB_F}HET6LhM;>`+}Pz<>RD z@ca{exgW5pw>9B427IYVHRkQVR|y``9ss^8Yaip2?nF!= zKYP_yycrK=YDe$!dgc+Hkb#;I(^8-@M&1CiA&9FytMP zo-=7Q6V({!=)c>W&zgn0HU3-$l5DQVuFT0(6dkkHKMaW%%$Wu7a5(@vpwQ0t(- zC4{3|z;6}olNE64(I;hl1(y}}OQrR%O^4=dM5>j*mafqzd8JIZeVoQfv=(h{u{Oji zYv6_VU<=d>GVem?9&eDMv2##-sNGvr-3u!PNde!qkm|U=T{m(?0Nvz%l89OTi)Pu1ri9SHQCLO+TR9B&50 z+Y2{Q8Xom?wI>Nx3pwn;)D|z-!iD(5)=0@i$3mW9q+4B|HeqX)2+X|bvhWXwiPrr` z#DfGKH|5TVz}I2+4vRLmMe(i27uS;(SQI4?Z^LiS{&r4Whpu=_;jOt8vc>ig#?98U zPAMbL+v4WkmCo}ZRxGDo4DPCJYH?W9X&^7p-9d3`>q4(YR&P)9Pxr2{v`x5-nP$vb zXe!;37ZS6b|Dx+80zA}t_I-3Vw-=*!LCK1ytJo`Qx%N+JvRCb@mbg#`%&XH0+q^J; z@JW;cORJZp$f38Ps^i>k(|qbF1@7O~N_Kddlb-C!vRFXb45VZaG5af3^>e_9n{dTn zo!?I@3GMrbZ!Itrr=K9AA1_f}NvG(3LCN1Hz;4ov2RHepPGD+3lfg2l`!l6p27+ui zX6gVYyBNTjcWwCx^J2LcaPsU9sUY(9Dt|i|Jf!#h`Gy^*V3lE`aTPSQRflWxFp@96 zD-Y9%p3PA9JN^l9bclM!wd(dpD(!P99S+V#atiw4*crKe>BV$RjM&8y{;5^qZDL7Gk+4h-ZS*KMeH- z0h>MRn}E{ zHM>`{D|YXkAKeuMz`GFY#gPR`dI;90ZLY9qsmMr%zfJB%-17aAYSom23>UxWnz!?X zgDfsjd3xAqMT4BU-(f?_utS1T^7-dg$fKM^pN%>AEmD@x`Ra9yW`#3bK;tVx(2}@k zk@p!iE8tu4K!!-TDTAyE!ROYVgTk z`J-QdI+V_B&$Pn3RO3&)O7>#-%=6OuWV!U1+vy@FDcuheeU7Co$YoF%eVQapXe z>H!3;CK+85oS1Edd1uxLdXQIHw%F3ePJX8TrK+F8N6`JwehTFF^*!P-MY%-Z zLX!S%jEuMVqmZWiE6$ep4MrZX2KhYe>t2K~6GgwD4WCkIAqUm4;lT9W-C9U;bXi!@ zZv^2c9DL`EK3Vsf537JEtidIZqfMcfZ&F3$VTdT?pHK3EyT`u%1-?WnojmDqY(h_- z-rBzbvIByvD1vUbt-%8Cg|?#GVU08-_4u*2Aqgfe-Fw}r4sIR2IOul$eLfuRX}th%yGf% zVd&q29^(X+`Kcy;zoDpLOBEN}XT@q`m%74krTE#2IxBXsvHE%dbFAAiHmjj!BlBqj zm+Cbj;Zi-*1|mv)40CFQ4S)w4F%;eJH07g9k2+y=@=dV%dpupE@D8)x`xxG!ska); z2aH;ZcZ%kUZo~HWl~{3~;?j#JB7gdvqTLAEt~ljdH(#h0Y`lr9i}wery>4jBxRZO7 zeYZrUdHefwt@GXUgEuv3QVt);n}fnFHrkplpV43UPbZh9eKyM3NQ*E9>bHNTLXGvvUDXL zXxa8gh6jX;@F3%TIp|#kIGE9OXn9MPVySreWYW+w=ZbV$Ax!BaZt~2vDKGYCQRovt zJLT;E!H@^zpR#)~9d}X+1YDQ>&tsnQT)1X0+fQKFnyRdL8`U}B?6P1WvekK2+bmc& z+J6B0L^bzf+-p^oJn@Hmr9kYU*hM@RM=2U3{M5`hL?L+^*_8rO3SDSXZ$E*iU#WB5 z8Q~r2`a^S&IHT8?27Ak;%L|v*RH%P9>dn3GvN?yX=Gg=O7pzj|;tYR967a0J(-?vZ z)(w-%@bg=Ba5k!sN<@gj@|Cx2D~=*cqOyp9`Q>U1X?sFvW`FwQuh2CU4|pe7VWAXi zNGb&gkIeylDz4G%NX9E734OCBS zmE<;jGXiL?@w8*S*fux@{4MaEZZ_LfAYv_-)#^IE;I3JR)2TC2iy8uuQatr6`6nkz zXf~hZD`ytVKz*qluN%B-=hM#Bu^k{TnR<=1DJ9$@a1=j(MPqU7?y)Plx*5B`w>Sap zuUItL6!q>p`8jkG%YC;?!HOjs3f@^HuLuw9&E6rITk`7|osj3Y8?>+Gvyn(1xxD+J zyefdRMF`l}^04_i`yk=>u0@_=Nm$|Qo{ZsW18@H#y2RR)QrNxX#jz=lZC=?rTNUP` zWD%2$g#s_bjMxq**bor&4rOr-mYMIL(oGC|dLsVttQhRc(%-j1PJZ*4a_L^G-$k(L zV0|a2>}1!{pU9yNNVSCMhEOL(y-R$}fS$I=Nq;!mWla+IR`L+D+Jt)FM?C6pllyF2 zMfzFg{bZ|(v$k>YD`QY^jal*cHywK1Dmlc_JhZcZ7`xx4rT*mbbGA^-q7pf#^p5o8 z6w6oP6zqLl&#r`y|3u5&Vh1U!hq8wOn*8|d0o|1vAvCKRyfF?IRJ3xP!MHMpvLf!EYzQVSwZy1*X~g#2;7f zKw5n+EAa7+k3Mx;#jNI``+%_~cB?M>b2SxHLg!8k$On1L zD7!2w;bqCZHati=`^9^jpK^&`W-x4X+phyav^5e_D=D;=7yc60+FxXCZmMProvlmC zlqc>-vWs@jmL&Hu>`sQO?HmJp7CaSoI^;FB7%>q|>nv|cpl1#>GWEv3; z*iM3jM9^7V(*}LX!cjJI1)2xeKWnDb;!S*8!MZDZvGM=)0x&)tA>ZYxPTmIe#&wz@ zXF5K$Ih0D8VjL`00V93UlA0F3?o3e_U2V)M`^fEKk*!)0$N5RQ`~l!_c|m79S*%nP zmjZnjd_j1!tU;P|pO#08US8g-I8|H|W(Lrp;%3NJzk{c3l7}Z_b?C094GEGnb~?35 z7u^RMJK!}9Jg+BRElc_W_@B#0eyhejP34!LMX_|fLYxyE*kTvBjfpiB@RjSOpkk#7)HC^G5P95lBrt< z7|87o11UDC4T}kan-mD>me&Zd{?aXF;DOR$S7q$QR27jW|I=L`+B3G)%Hx$g5tGtR8ytu zxW#eS`B6`2MaX6agW=Y}V8CB13-iUF_yVlhF`cxH_Hr1xp_y}ErjJChyHGk4^wOrF zuk@&@6m0P8F9YQ{>L-!@#Y2k;U|-DP8kw z8`@!7`l0jBZakq*Ah`inb_>v}dxG5|(e!Ho104-=RDN;=e{dE-!w11!{Z>?Cg-bvQ zxcZR-glkAYkSxiv9AQ{;w zINy1F+mR-{Ly2&DQ9EtzMdavk&DIgD{C&&L{kW;#)wO4JP~)wSc}pdQU=-39!)Atb z#vgx!iVN!3+a*Aav@c{=28oLD7`Ap`5Hy~u=rk*I_NJT^FH?fL_CNsVM{l+=eZH0b zY>ry+RCneR@xe+Nc>lO~eXgX%Wpe}D;`RJGN%!}5{@qLd8Q%VTMAMDFkE;9ret~;v|Qmk?LMU#RzCQFW1<438_QfgLS z$HXeJ)^}sprt-Igii4{xRC$5ttPpw2EuaS@(`4M<*!uWU^UrR1+LMY?d_aKfO5N|c zNp-_b23oKit+@^mt7QB;{S4)f6sPt<{etd)@!wAW@ZeG2M-wmKydAUNeSDZ4mc=_AD)5h{6NL*0P4UM{iGu!$4 zVKp0n03>FHgSvnGZRU~Zd?(5J#_MKCOC~D^bJF_wjEZ}Qoww%+!;^v*jNJ_Kq?eo= z(+1*vRR4t$A8Mp^?iI)Js@T4&!etWmBeT$&KKTInoTdZ)#ZrC+KZPs%0w@FxoL3nF!fSi0}1*>;=;6@CfkYBR?RXRNx1St@Yi= zwI&`^U`l_tY+6Ly!6C?k=-l|{gC-F}!>~Psw@or2;}cb=*e0zor;H@50W&lQ4txp^ z9;|AqR+gK#q6$rvLwk7f^C2TCH=FjSZL<2GJzF{hrRvfOYSkRGaPL^7P#;-;MG-jy zzDhLOCOKfP2fXa;T$+@+z4PG)S5FG4CC#*T*PO@Pre*r+$9?EIGXm?pJS-wCUs;gx zPnVvK<{M{{-vSNnM5VjpF>dE7I9LZPAi~vCj%Moqej4gq5nRk#sK`aZ41?!KGa<>T zVI_tr`5mkRw?VoRM!nQt?Nf$jL6F&?a~-vMM)lXx}f6 zs|Z27xGL^0cYwUl_2>D7dK@_9nR~LP-E2mTO+l)U4R)6G4H}w1Zzw(R+By(n8(bJ3 zo>LiE5v2wy3?C-)bw^Jwl)Za9U59g>u6^Jy93)}wB@V$9p56IbS8_;hu}W^3dLk;4 zabIxcHtg)}ku-i%?BApPadp?xq`$`2zO~qU{G5GSlCg9ArBOp}p#I6n*BN;D)4p9V zH}A79PR2wwanpr9JTW&_EWL7R9d2ZXP)&_`^(zDB?R^R!Tc!e{iUF|SdDwtlac>JOj3@D#!Zk2 z)p~AAz~Lcd=yS97i{eEk&Oyz&X$9%!sCb(UXO_#*m#Y;a&5Icx&4|lpQ_})Iy@v{j zutG!gO$|>^mFoVZI+^(nj0~FckXMBZhB7Y>K_~`^3@`!kW4f;Rb{$nXEH4`%{VvP| z6dgM;Z0jY|671*Eu)B7DS3Y(6*<1+h0>BvlmlD-{N9^m@QgeU=^X9znnV8>&M znQV%3x*>~~`td#aps$BF1soJ=PbNq8{Hnu78i-@}TBew^CeuwNV9r6rv}~9y4)bZX zJ^@Gi<6GX9&w={H%)mCq?X{Iy1`fPiZxNQh-}Ku}i|QerzJ+7{TJ&g&m&pRv<|IKl4O?HG$!n_(J)WbEpb= zd&nvQ!`cr!iOBGN`5$@vWGfVO-|P^iOq()3U9d-}>p=ND#Y8Fk7YJVn)=_&Ekf^hG zuvROPH*Mun$wqhZTUwUEyzZ<@55t0j3w~e3*FD|P){bzzx~d@$5HF{*_rOheQ&qKBRD#NTTXInRNDIu6^s}`JjCvtaA(gThPe6F@ zSx=HD_|MlAhz!}xmNv+zw`BNAyfEHs(;4ak6y?aV=dP^w-m1vXRIMxk;5V)l!HMl+ zVL)>!nAl_MkxVZvlS`=d7!IsFmC+0jKlw&yV>P(*EVdCLu8Ma(xL@}_GwPs$Og~B= zX%k$l`$DXfP*9ZOv;k>BTp3Kc@O$b0uoL!fN&(jKJ!qqWHZD~Y51dNi>NdZ=@o;8z z6<`_FrCwH4E2nQZDT*wtOc-2(%k`Sl{?O?bYjo&h;jcz+i=9u28eUKl`XV1$5E)?- z8H74j8cU(kC3N+Ldo+eF6?86+{GQreKCH2*UH8$@tK*b4$t#`f^=Da9XBs#`h+f(F z=cQ*3z~eQ*p{oWqI$)QiF#6yPKj`m7XKn40)vr3VoJ=J-lg5bTww9RnL$rTz5r3^b z)j6~~W@lE=&s+wQJPCf=kNbi7!wIMfC%Nym(FYtS0!O(TxC$KfJixz*%YK>@IyvY? zgXW_;Mut0isWh%8a{sM@&aVtrNhAM~pGp{n5hJgT^`KT?BBabRD)v-a5f#<2nIfuQ zRI2QgAIEE(CSsn9qP@2h&pmc3YZVJ zN~8*?oh}6Q>&LBL^+9{CAfPsjE3H%$gh*$(kZa{UfdS8=!JgPe4QYW)>pM1J@c}xv zS*c-FJg)g+wK6q;q0lz7tzMf|P&fB5njp z6~6RCbsuL!)mo+x$eGMoysk}nU0;1>t9RsF}Q*agT=Dmr?|IoY_+c>x4RnE)4^z`i>-OI5vNZ)dDfFz z{yzmi`%_?GU&mUjM&{fP|!^&dAqQT5JD(k;Q!+_O(e`Y%TZk_Gs z>(Dm%6#HAnR${4mo06l3g5?FhcJnS?6%YXgd}{Do)}H!YnOF)nZP1Oh?&>m#w71gI z*4cIfU`e)#od`gUX?>%8@^JI30P8)O;1P)m&H z=+KqY;y5$#JAG%ip0;+l^ehEE&lWLGuVI62v{^d=+XoS0Sn_>dl~Ofx zTxthqmax!$1=w+m@-eY>H7h%NC0fxvkc%qX577_p=0I8c#H&sv(;R&!y*m%(*(CbL zr?SVPyCIX~ZOvOh7yCq3o<0SxR!j^Fj&m10cY}y?T;nB&&Vti26Z2OI@{l{;mt6Nd zC0g(@Yt{&^IiuU*7&Ov~IBphsnz-G`*6vd9Ggq_XU_^t5!(*O2ye!yLImroCbf^&6 z^P|7Jj5$Wz>6hwaCpDadsc;(-Clp_Y(FF+<+rEO?Pp)<=gzxGff0Sn~mhJ374b9VZ z>O|#XrVb^9*^2DanyuW}uVQ@N6_*;pfo9T{IJ^rL!+`*I*D?eSV}x6LS51Zea~pgB zE$*S+MYd*hJO=1zabU8$wkb6No8ln&c8B7~b>^cc1ImsRX!9vh+pxd$qE>xZZJZPH zt<8uZz7YxJwW%0!qw@`)dW#9p*v+Hnxv=3VxX1vhRk94rsXZ5C8yE8F*d-?3wxqVX zucJLxSl^LuKk6j>Q6ORm+f(JDf z*5A(&w;PCzW>FA8y2JpoAfp?BH5u43)q`!fCd@8GnikLG8VZRfdTw^AZSHLM zLeOiMMC67{Z=0s)>l=NGSbcNDxS-L+a^+A*tjtk7qQB>1$kX7tXImOZSBTkH_^8H!3@3hv#hzqYe)CFlYAW2 zl~n35q7gK$v2G9NZX&yhC|{h8c4j~1Nf8EPCJDU^UpjiD7nekLANuGZW6|sD)+Uhv zuJv%x%WhzK>zTzZo9f)T5bpyIT4 zV;+A9Z()8AXx_IS22TH&j>-5gW;%}UNM8$no(@Gq=7<+b3o5&YpPyNK;1WNUW{on1 z^FzKrHN|!Wv%AmyTM15Zj6JcletjmRL~odM$YZEM`ImKq*=WzAK; zS{(*(Q);t|)7JW-)Ia9d?l~-6=unw8Cj@E5`sP|0B!ntR{^#8;8K>EnLtZV+QirXW zx*m$Qnc(b7)t%Kfm~S4sNmtIyuCC7g8$TNB%SY}%;~3Z0KBAk59DiPn>s>qY=kXS~ zdpg5g^{oZ%(jE}!0C_8kOi42MO{iC`bSl07(ea$as?dczvWoxAP)_V4al0>n{VfQ6C?lLO`3j^BNH}qAcgC)$0b7LK0u++l(lC z?(3HGH11A*xFI)9GsP6;4$V;nJcX|jMMHXh`*LW7a`=o=u02NuT2 zZ!ONZIFv0b9A(g8Fb&}{%+}u5Fp#O!ikIok_|S)e^(Qa?4e@m=u+1&}^BdQa%;P7? zk#;djO2tHB2U)Jc=To69OyhAaG9;yl{4V=aG;W&LhT9FS8kpjLSeWtD#&kU{Fbp&+ zx8Oj}n;z}?qZmwLo*ja8+hbYQ%->8_u{Gh$K*g`UUiBKs>x)M*NQ?!(IGnrO&|)Nr zB`)b)rPaPdKwjeAscvUYF|-O%CLr5?3(xx6Uta5pfUBY89l@yzxNQyL-`_)$Y`(QV zT+@gaEjIS5=okbW74G(a;x8PRN+7>UJYamJG^~Y+^^NcLWJ#_Woo6)@%t~wAgTn}M zK@+s?Rl>oW#^wxnaG_}Dm337EQ8vWWEGZ=)8S zjkK#cvoaeT{VStefMvW52otT)T^fcM1WV{0=EH5@@C13TIlIBnt~hCB>s6w`Tj8j1 z_-NHCE@xWkL#*bjhyGBr3F?f70?oPg<(wxYU+t?+iH`lh@w*8!aolw-q-BD`{YKg{{!Xvd z%dScusQ#gb-SF%_F{fty} z5^8j12+6ap-&mQDG)bTQ3{?e?lRZFCXRh9}?0D=pt=2#EZZjssr{ad%N`Y9YDZr0h zaJk0bqgpgbFDqILNM8HdAd=zBl>;uk4Hhu(!zYRt!T6GvWtrQ~!j@y$?T~HtqyjOY z+RhQQQg)skQDftL%7UwD$HBtYjE;4;3F~d7sM=}gsypY{La6`km3%<*+R;kW`%)N4_&%OFCne7KQWg5^CtAqE=oqyCe5~%H0#<^7FyS~a4T)yDqib_r=E6N!B=^L z++$a@b9(RPHS>wFOk9Dt5L1|`y=y%;r2a#T8b|!4Jx#l)y!cMhk?|&IonzH5Ci zq7vC2!gkBzR^ZfK4VD~Qpx=L!M1(KTGm=L>v zXKU>6wb12nBHg4P_Q&{rQBIeaJ!XOBY97?#Cfj=)r62>Z2KH{~CnwT|0lCV2K^i!R95Y&$<-QH|*@&Fs^hf85oI2;y%;i>j459|qwY%e5eu zcnk)$X$qPN1X8&aAFNiEE})FFLG^d;N3PVc{0M5cbFeu0s&X~e_llKm27@!lZr*ey z)Jra14Z@X?KIh2w%eTOH)JLZ}f{#f*$7Dy7E=;~K1xT$p*!d-MUAkkKckn}iAh(U= zj@935KyPcOAK6FJhJ$WP&Rj~6&)D*5Z9vI`oJfaP1)fx{hr7m} zkO$s6W{BZd$kK*g&8e+-Cv$%LMnP=}Hy!p4Mss-?(pQTDqh3to`*--uq!WWB?tK)1 zbYu`g2gSqHW4nEB1;rp)=^jC_TgYAl7AihWtE)hu*6Qbs8mlSU0&#(z%EtD5&U+cd zJ&%z?FOjuhH#gfMiq1ODI!qh0*}I9J8DTtUufMod^QC<=ntUgP;^wp_Ngtl^f4}4Q zcxU)1y??>AlkCp#*KnKm8tc$(o@3UjdMX3+HdCu384$MfD03(`V!?py#TR(sP7f>@ejCwIq8cf=J6&5Wa*v%)sm?*c>E~cAU#SygrZ*dO|PSbrt zp$t=2d?L#qonE?@Gy~`Hy=D)_-*AZOjuj%hG!k)7F9Ks=?6&&=G6vDh`Pf+mAD~2euG+tlq zx3#d6AX#b?m;No%*RB85sO!l2)S!W*xR!>5YC2>o6r)PiMqt4HxK4#ibD5-jTW!-# zma$vFe5yi`E&p#(IZA~_KoomCr=5v^5y?acZFy z{Q}#-F6vP(bDSMSZu#jLA-%GRC#=q`dJ9|DBFu|D4HCKs*ghlr28SLO4FZ8=48jzt zR;ZVxAgxxMEYY))q>Qv(5_haq`qo_tQ6{Q9%`2Ss^JehYJDR9l0viY`cJ^`-I_s>qZ5`o%f9ODTj;#PYA}fwA)Cn2s{O0Ql9=U7i zke|9cvySg!kvZx<9Ji<`)fB%&j>f+gRpYN3P&Px#_>}53g#3y%ksOaA+OhpUIllGdYgEyF|E8N?gNQKT&AX*QUHAj!c}ky zLDogDlb)oa9CHw$*W5%3Q~t+15%Cnh7d$xT03H4T1D}&b7GOtV zKG8VPof^5paxI+*K8W#`CfXN@Pa_iTuo12tE?na*%I2R}4Wb-UAP)p!&pYlh;V5oB~W|1OZR_-1t>=#amsu&>8 z)nP?Gec&Sz< zlpmRfZ@O7o0A{U6+syQT;2{zT?8-Y2EAH-rHfa!O)qI{0szN}-Bi8Fj86z6Eiash< zCFv@K@iBhkj-Wv!`HqQuCM`O3ZsC!XU#9ikf^E6hgX`3sD&GA^1ib7NDjI%Sli{