Merge remote-tracking branch 'upstream/master' into feature/show-catalog-errors

Signed-off-by: Nicolas Torres <nicolast@backbase.com>
This commit is contained in:
Nicolas Torres
2021-07-28 09:43:46 +02:00
48 changed files with 392 additions and 787 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
chore: set the lifecycle as beta logo
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/core-components': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-react': patch
---
Improve accessibility of core & catalog components by adjusting them with non-breaking changes.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-ldap': patch
---
chore(deps): bump `@types/ldapjs` from 1.0.10 to 2.2.0
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-api-docs': patch
---
Add explicit import for `isomorphic-form-data` needed for `swagger-ui-react`
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-kubernetes-common': patch
'@backstage/plugin-kubernetes': patch
---
chore(deps): bump `@kubernetes/client-node` from 0.14.3 to 0.15.0
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Fix `EntityListProvider` to not update url if unmounted
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
TechDocs now uses a "safe by default" sanitization library, rather than relying on its own, hard-coded list of allowable tags and attributes.
+1
View File
@@ -1,5 +1,6 @@
abc
accessors
Anddddd
Apdex
api
Api
+1 -1
View File
@@ -5,7 +5,7 @@ image](https://backstage.io/docs/getting-started/deployment-docker); this
tutorial shows how to deploy that Docker image to AWS using Elastic Container
Registry (ECR) and Elastic Kubernetes Service (EKS). Amazon also supports
deployments with Helm, covered in the [Helm
Kubernetes](../kubernetes/basic_kubernetes_example_with_helm) example.
Kubernetes](../../kubernetes/basic_kubernetes_example_with_helm) example.
The basic workflow for this method is to build a Backstage Docker image, upload
the new version to a container registry, and update a Kubernetes deployment with
@@ -0,0 +1,68 @@
---
title: Software Templates is now in Beta
author: Ben Lambert, Spotify
authorURL: https://github.com/benjdlambert
authorImageURL: https://avatars.githubusercontent.com/u/3645856?v=4
---
![Software Templates in Beta](assets/21-07-26/backstage-software-templates-beta.gif)
**TLDR**; At a high level, Backstage performs three main jobs: [Create, Manage, and Explore](https://backstage.io/blog/2021/05/20/adopting-backstage#three-jobs-create-manage-explore). Throughout the year, weve been focussed on improving the stability and scalability of these areas while enhancing the feature sets based upon requests from the community. Software Templates — which enable push-button deployments with all your standards and best practices built-in — is our first feature-complete release candidate to graduate to beta. Read on to learn how this release improves template customization and flexibility, as well as performance.
<!--truncate-->
Lets rewind a little bit, around a year in fact. Backstage had been open sourced, and we released our first version of Software Templates and our Scaffolder plugin.
In case you missed it, [Software Templates](https://backstage.io/blog/2020/08/05/announcing-backstage-software-templates) are part of the Create feature set, where you can set up Backstage to give your engineers the ability to spin up a new microservice, website, or any other software component with your organizations best practices built-in, right from the start.
Back when we released the first version of these templates, with the `apiVersion` `backstage.io/v1alpha1`, they were a little restrictive in what they could do. The generated repository could only have one template source and it was restricted to only being [cookiecutter](https://github.com/cookiecutter/cookiecutter) templates. And it had to fit into the three stages of templating which was `Prepare`, `Template`, and `Publish`.
We [opened up for feedback](https://github.com/backstage/backstage/issues/2771) from the community knowing that this wasnt going to be the final version, but something of a stepping stone to where we want to be in the future.
And now we come to today…
## Anddddd… Action(s)! 🎬
Following the removal of the previously deprecated `backstage.io/v1alpha1` templates, today were officially announcing the beta version of Software Templates, or `backstage.io/v1beta2`.
With it comes an entirely new architecture to the Software Templates functionality, and a load of new exciting features, which Ill dig into a little deeper.
### Template actions
Weve totally opened up the ability to compose your own workflows for each Template that you have registered in Software Templates. This means no restrictions on where your template skeleton is kept, and no restrictions on what your workflow should look like.
Template Actions are customizable JavaScript functions that allow you to extend the capabilities of the Software Templates by adding your own business logic or reusing some of our Built-In actions.
![New template syntax with actions](assets/21-07-26/example-template-code.png)
_An example of the new template syntax with steps and parameters_
The workflow for Software Templates are now step-based, and each Software Template can have a customizable amount of steps which will in turn call these new actions.
![New steps being rendered in the frontend](assets/21-07-26/steps-running.gif)
_An example of a Template with customizable steps_
These actions are very heavily inspired by GitHub Actions and GitHub Workflows, and weve given back a lot of control to the template authors so they can build the boilerplate and push the code however they want.
### Custom UI extensions
A large part of the Software Templates feature is the form that we use to collect user input which is then passed on to these new actions. Sometimes, it makes sense that Template Authors want to provide their own React components which can be rendered in the frontend to maybe do some more complex things like calling internal APIs to provide autocomplete.
This is now possible with the new `ScaffolderFieldExtensions`.
![Custom UI extensions](assets/21-07-26/custom-components.gif)
_An example of `ScaffolderFieldExtension` is the `OwnerPicker` component which can automatically add options and suggest typeahead with data from an async API request_
Template Authors can create their own components to provide data to the custom actions in any way you see fit, and even override our own built in ones too like the `RepoUrlPicker`.
### Horizontal scalability
The Scaffolder Service and Software Templates are now horizontally scalable, coordinating work between your deployed backend machines. This means now that the number of instances of the `@backstage/plugin-scaffolder-backend` plugin you have, is the same amount of jobs that you can have in parallel. This ensures that your tasks are handled quickly and reliably, while providing great feedback in the process.
## Try out the new templates
Were still on the journey to making the Software Templates a great user experience for both authors and developers — but were not done yet, so watch this space for new exciting features to come!
In the meantime, make sure to visit the documentation for [building templates](https://backstage.io/docs/features/software-templates/adding-templates) or creating your own [custom actions](https://backstage.io/docs/features/software-templates/writing-custom-actions).
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

+3 -3
View File
@@ -212,9 +212,9 @@ class Index extends React.Component {
Backstage Software Templates{' '}
<a
title="Submit feedback for this feature. Click to learn more about this release."
href="https://backstage.io/blog/2020/08/05/announcing-backstage-software-templates"
href="https://backstage.io/blog/2021/07/26/software-templates-are-now-in-beta"
>
(alpha)
(beta)
</a>
</Block.Subtitle>
<Block.Title small>Standards can set you free</Block.Title>
@@ -292,7 +292,7 @@ class Index extends React.Component {
Build your own software templates
</ActionBlock.Title>
<ActionBlock.Link
href={`https://github.com/backstage/backstage/blob/master/docs/features/software-templates/index.md`}
href={`https://backstage.io/docs/features/software-templates`}
>
Contribute
</ActionBlock.Link>
@@ -69,6 +69,7 @@ export const StatusOK = (props: PropsWithChildren<{}>) => {
<span
className={classNames(classes.status, classes.ok)}
aria-label="Status ok"
aria-hidden="true"
{...props}
/>
);
@@ -80,6 +81,7 @@ export const StatusWarning = (props: PropsWithChildren<{}>) => {
<span
className={classNames(classes.status, classes.warning)}
aria-label="Status warning"
aria-hidden="true"
{...props}
/>
);
@@ -91,6 +93,7 @@ export const StatusError = (props: PropsWithChildren<{}>) => {
<span
className={classNames(classes.status, classes.error)}
aria-label="Status error"
aria-hidden="true"
{...props}
/>
);
@@ -102,6 +105,7 @@ export const StatusPending = (props: PropsWithChildren<{}>) => {
<span
className={classNames(classes.status, classes.pending)}
aria-label="Status pending"
aria-hidden="true"
{...props}
/>
);
@@ -113,6 +117,7 @@ export const StatusRunning = (props: PropsWithChildren<{}>) => {
<span
className={classNames(classes.status, classes.running)}
aria-label="Status running"
aria-hidden="true"
{...props}
/>
);
@@ -124,6 +129,7 @@ export const StatusAborted = (props: PropsWithChildren<{}>) => {
<span
className={classNames(classes.status, classes.aborted)}
aria-label="Status aborted"
aria-hidden="true"
{...props}
/>
);
@@ -491,7 +491,9 @@ export function Table<T extends object = {}>({
icons={tableIcons}
title={
<>
<Typography variant="h5">{title}</Typography>
<Typography variant="h5" component="h3">
{title}
</Typography>
{subtitle && (
<Typography color="textSecondary" variant="body1">
{subtitle}
@@ -20,6 +20,7 @@ import { BackstageTheme } from '@backstage/theme';
interface StyledTabsProps {
value: number | boolean;
selectionFollowsFocus: boolean;
onChange: (event: React.ChangeEvent<{}>, newValue: number) => void;
}
@@ -107,7 +107,11 @@ export const Tabs = ({ tabs }: TabsProps) => {
<div className={classes.root}>
<AppBar ref={wrapper} className={classes.appbar} position="static">
<div>
<StyledTabs value={currentIndex} onChange={handleChange}>
<StyledTabs
value={currentIndex}
onChange={handleChange}
selectionFollowsFocus
>
{navIndex !== 0 && (
<StyledIcon
onClick={navigateToPrevChunk}
@@ -15,13 +15,7 @@
*/
import React from 'react';
import {
ListItem,
ListItemIcon,
Divider,
ListItemText,
makeStyles,
} from '@material-ui/core';
import { Divider, Typography, makeStyles } from '@material-ui/core';
import ArrowIcon from '@material-ui/icons/ArrowForward';
import { BackstageTheme } from '@backstage/theme';
import Box from '@material-ui/core/Box';
@@ -54,16 +48,14 @@ export const BottomLink = ({ link, title, onClick }: BottomLinkProps) => {
<div>
<Divider />
<Link to={link} onClick={onClick} underline="none">
<ListItem className={classes.root}>
<ListItemText>
<Box display="flex" alignItems="center" className={classes.root}>
<Typography>
<Box className={classes.boxTitle} fontWeight="fontWeightBold" m={1}>
{title}
</Box>
</ListItemText>
<ListItemIcon>
<ArrowIcon className={classes.arrow} />
</ListItemIcon>
</ListItem>
</Typography>
<ArrowIcon className={classes.arrow} />
</Box>
</Link>
</div>
);
@@ -28,7 +28,6 @@ const useStyles = makeStyles<BackstageTheme>(theme => ({
header: {
gridArea: 'pageHeader',
padding: theme.spacing(3),
height: 'fit-content',
minHeight: minHeaderHeight,
width: '100%',
boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)',
@@ -73,6 +73,7 @@ export const HeaderTabs = ({
return (
<div className={styles.tabsWrapper}>
<Tabs
selectionFollowsFocus
indicatorColor="primary"
textColor="inherit"
variant="scrollable"
@@ -27,24 +27,26 @@ describe('<ItemCardGrid />', () => {
<Card>Hello!</Card>
</ItemCardGrid>,
);
expect(screen.getByRole('grid')).toBeInTheDocument();
expect(screen.getByText('Hello!')).toBeInTheDocument();
});
it('renders custom styles', async () => {
await renderInTestApp(
<>
<ItemCardGrid>
<ItemCardGrid data-testid="cards-hello">
<Card>Hello!</Card>
</ItemCardGrid>
<ItemCardGrid classes={{ root: 'my-css-class' }}>
<ItemCardGrid
data-testid="cards-goodbye"
classes={{ root: 'my-css-class' }}
>
<Card>Goodbye!</Card>
</ItemCardGrid>
</>,
);
expect(screen.getAllByRole('grid')[0]).toHaveStyle({
expect(screen.getByTestId('cards-hello')).toHaveStyle({
gridTemplateColumns: 'repeat(auto-fill, minmax(22em, 1fr))',
});
expect(screen.getAllByRole('grid')[1]).toHaveClass('my-css-class');
expect(screen.getByTestId('cards-goodbye')).toHaveClass('my-css-class');
});
});
@@ -55,7 +55,7 @@ export const ItemCardGrid = (props: ItemCardGridProps) => {
const { children, ...otherProps } = props;
const classes = useStyles(otherProps);
return (
<div role="grid" className={classes.root} {...otherProps}>
<div className={classes.root} {...otherProps}>
{children}
</div>
);
@@ -23,7 +23,7 @@ const useStyles = makeStyles(() => ({
display: 'grid',
gridTemplateAreas:
"'pageHeader pageHeader pageHeader' 'pageSubheader pageSubheader pageSubheader' 'pageNav pageContent pageSidebar'",
gridTemplateRows: 'auto auto 1fr',
gridTemplateRows: 'max-content auto 1fr',
gridTemplateColumns: 'auto 1fr auto',
height: '100vh',
overflowY: 'auto',
@@ -204,7 +204,7 @@ export const SidebarItem = forwardRef<any, SidebarItemProps>((props, ref) => {
if (isButtonItem(props)) {
return (
<button {...childProps} ref={ref}>
<button aria-label={text} {...childProps} ref={ref}>
{content}
</button>
);
@@ -216,6 +216,7 @@ export const SidebarItem = forwardRef<any, SidebarItemProps>((props, ref) => {
activeClassName={classes.selected}
to={props.to}
ref={ref}
aria-label={text ? text : props.to}
{...navLinkProps}
>
{content}
@@ -44,7 +44,7 @@ const handleSearch = (input: string) => {
export const SampleSidebar = () => (
<Sidebar>
<SidebarSearchField onSearch={handleSearch} />
<SidebarSearchField onSearch={handleSearch} to="/search" />
<SidebarDivider />
<SidebarItem icon={HomeOutlinedIcon} to="#" text="Home" />
<SidebarItem icon={HomeOutlinedIcon} to="#" text="Plugins" />
+1
View File
@@ -7,6 +7,7 @@ module.exports = {
'../../../plugins/**/src/**/*.stories.tsx',
],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addon-storysource',
+1
View File
@@ -19,6 +19,7 @@
"react-dom": "^16.12.0"
},
"devDependencies": {
"@storybook/addon-a11y": "^6.3.4",
"@storybook/addon-actions": "^6.1.11",
"@storybook/addon-links": "^6.1.11",
"@storybook/addon-storysource": "^6.1.11",
+1
View File
@@ -43,6 +43,7 @@
"@types/react": "^16.9",
"graphiql": "^1.0.0-alpha.10",
"graphql": "^15.3.0",
"isomorphic-form-data": "^2.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router": "6.0.0-beta.0",
@@ -31,7 +31,7 @@
"@backstage/catalog-model": "^0.9.0",
"@backstage/config": "^0.1.5",
"@backstage/plugin-catalog-backend": "^0.13.0",
"@types/ldapjs": "^1.0.10",
"@types/ldapjs": "^2.2.0",
"ldapjs": "^2.2.0",
"lodash": "^4.17.15",
"winston": "^3.2.1"
@@ -76,6 +76,7 @@ export const EntityLifecyclePicker = () => {
<Box pb={1} pt={1}>
<Typography variant="button">Lifecycle</Typography>
<Autocomplete<string>
aria-label="Lifecycle"
multiple
options={availableLifecycles}
value={selectedLifecycles}
@@ -81,6 +81,7 @@ export const EntityOwnerPicker = () => {
<Typography variant="button">Owner</Typography>
<Autocomplete<string>
multiple
aria-label="Owner"
options={availableOwners}
value={selectedOwners}
onChange={(_: object, value: string[]) => setSelectedOwners(value)}
@@ -73,6 +73,7 @@ export const EntityTagPicker = () => {
<Typography variant="button">Tags</Typography>
<Autocomplete<string>
multiple
aria-label="Tags"
options={availableTags}
value={selectedTags}
onChange={(_: object, value: string[]) => setSelectedTags(value)}
@@ -25,7 +25,7 @@ import React, {
useState,
} from 'react';
import { useSearchParams } from 'react-router-dom';
import { useAsyncFn, useDebounce } from 'react-use';
import { useAsyncFn, useDebounce, useMountedState } from 'react-use';
import { catalogApiRef } from '../api';
import {
EntityKindFilter,
@@ -102,6 +102,7 @@ type OutputState<EntityFilters extends DefaultEntityFilters> = {
export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>({
children,
}: PropsWithChildren<{}>) => {
const isMounted = useMountedState();
const catalogApi = useApi(catalogApiRef);
const [searchParams, setSearchParams] = useSearchParams();
const allQueryParams = qs.parse(searchParams.toString());
@@ -164,12 +165,14 @@ export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>({
});
}
setSearchParams(
qs.stringify({ ...allQueryParams, filters: queryParams }),
{
replace: true,
},
);
if (isMounted()) {
setSearchParams(
qs.stringify({ ...allQueryParams, filters: queryParams }),
{
replace: true,
},
);
}
},
[catalogApi, requestedFilters, outputState],
{ loading: true },
@@ -80,7 +80,7 @@ export const CatalogTable = ({ columns, actions }: CatalogTableProps) => {
({ entity }) => {
const url = getEntityMetadataViewUrl(entity);
return {
icon: () => <OpenInNew fontSize="small" />,
icon: () => <OpenInNew aria-label="View" fontSize="small" />,
tooltip: 'View',
disabled: !url,
onClick: () => {
@@ -92,7 +92,7 @@ export const CatalogTable = ({ columns, actions }: CatalogTableProps) => {
({ entity }) => {
const url = getEntityMetadataEditUrl(entity);
return {
icon: () => <Edit fontSize="small" />,
icon: () => <Edit aria-label="Edit" fontSize="small" />,
tooltip: 'Edit',
disabled: !url,
onClick: () => {
+1 -1
View File
@@ -36,7 +36,7 @@
"@backstage/config": "^0.1.5",
"@backstage/plugin-kubernetes-common": "^0.1.2",
"@google-cloud/container": "^2.2.0",
"@kubernetes/client-node": "^0.14.0",
"@kubernetes/client-node": "^0.15.0",
"@types/express": "^4.17.6",
"aws-sdk": "^2.840.0",
"aws4": "^1.11.0",
+1 -1
View File
@@ -36,7 +36,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.9.0",
"@kubernetes/client-node": "^0.14.0"
"@kubernetes/client-node": "^0.15.0"
},
"devDependencies": {
"@backstage/cli": "^0.7.0"
+1 -1
View File
@@ -37,7 +37,7 @@
"@backstage/plugin-catalog-react": "^0.3.0",
"@backstage/plugin-kubernetes-common": "^0.1.2",
"@backstage/theme": "^0.2.8",
"@kubernetes/client-node": "^0.14.0",
"@kubernetes/client-node": "^0.15.0",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
+34 -9
View File
@@ -35,34 +35,59 @@ If you need help with this plugin, please reach out on the [Backstage Discord se
### Install the plugin
Install the plugin via a CLI:
The file paths mentioned in the following steps are relative to your app's root directory — for example, the directory created by following the [Getting Started](https://backstage.io/docs/getting-started/) guide and creating your app with `npx @backstage/create-app`.
First, install the PagerDuty plugin via a CLI:
```bash
# From your Backstage root directory
# From your Backstage app root directory
cd packages/app
yarn add @backstage/plugin-pagerduty
```
Next, add the plugin to `EntityPage.tsx` by adding the following code snippet where appropriate:
Next, add the plugin to `EntityPage.tsx` in `packages/app/src/components/catalog` by adding the following code snippets.
Add the following imports to the top of the file:
```ts
import {
isPluginApplicableToEntity as isPagerDutyAvailable,
EntityPagerDutyCard,
} from '@backstage/plugin-pagerduty';
// add to code
{
isPagerDutyAvailable(entity) && (
```
Find `const overviewContent` in `EntityPage.tsx`, and add the following snippet inside the outermost `Grid` defined there, just before the closing `</Grid>` tag:
```ts
<EntitySwitch>
<EntitySwitch.Case if={isPagerDutyAvailable}>
<Grid item md={6}>
<EntityPagerDutyCard />
</Grid>
);
}
</EntitySwitch.Case>
</EntitySwitch>
```
When you're done, the `overviewContent` definition should look something like this:
```ts
const overviewContent = (
<Grid ...>
...
<EntitySwitch>
<EntitySwitch.Case if={isPagerDutyAvailable}>
<Grid item md={6}>
<EntityPagerDutyCard />
</Grid>
</EntitySwitch.Case>
</EntitySwitch>
</Grid>
);
```
### Configure the plugin
First, annotate the appropriate entity with the PagerDuty integration key:
First, [annotate](https://backstage.io/docs/features/software-catalog/descriptor-format#annotations-optional) the appropriate entity with the PagerDuty integration key in its `.yaml` configuration file:
```yaml
annotations:
@@ -57,7 +57,7 @@ export const ScaffolderPageContents = () => {
pageTitleOverride="Create a New Component"
title={
<>
Create a New Component <Lifecycle alpha shorthand />
Create a New Component <Lifecycle shorthand />
</>
}
subtitle="Create new software components using standard templates"
@@ -160,7 +160,7 @@ export const TemplatePage = ({
pageTitleOverride="Create a New Component"
title={
<>
Create a New Component <Lifecycle alpha shorthand />
Create a New Component <Lifecycle shorthand />
</>
}
subtitle="Create new software components using standard templates"
+3 -2
View File
@@ -44,6 +44,7 @@
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@material-ui/styles": "^4.10.0",
"dompurify": "^2.2.9",
"eventsource": "^1.1.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
@@ -51,8 +52,7 @@
"react-router": "6.0.0-beta.0",
"react-router-dom": "6.0.0-beta.0",
"react-use": "^17.2.4",
"react-text-truncate": "^0.16.0",
"sanitize-html": "^2.3.2"
"react-text-truncate": "^0.16.0"
},
"devDependencies": {
"@backstage/cli": "^0.7.5",
@@ -63,6 +63,7 @@
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^3.4.2",
"@testing-library/user-event": "^13.1.8",
"@types/dompurify": "^2.2.2",
"@types/eventsource": "^1.1.5",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
@@ -14,9 +14,9 @@
* limitations under the License.
*/
import { createTestShadowDom, FIXTURES } from '../../../test-utils';
import { Transformer } from '../index';
import { sanitizeDOM } from './index';
import { createTestShadowDom, FIXTURES } from '../../test-utils';
import { Transformer } from './index';
import { sanitizeDOM } from './sanitizeDOM';
const injectMaliciousLink = (): Transformer => dom => {
const link = document.createElement('a');
@@ -14,23 +14,16 @@
* limitations under the License.
*/
// @ts-ignore
import sanitizeHtml from 'sanitize-html';
import type { Transformer } from '../transformer';
import { TECHDOCS_ALLOWED_TAGS } from './tags';
import { TECHDOCS_ALLOWED_ATTRIBUTES } from './attributes';
// TODO(freben): move all of this out of index
import DOMPurify from 'dompurify';
import type { Transformer } from './transformer';
export const sanitizeDOM = (): Transformer => {
return dom => {
const sanitizedHtml = sanitizeHtml(dom.innerHTML, {
allowedTags: TECHDOCS_ALLOWED_TAGS,
allowedAttributes: TECHDOCS_ALLOWED_ATTRIBUTES,
allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'data', 'blob'],
return DOMPurify.sanitize(dom.innerHTML, {
ADD_TAGS: ['link'],
FORBID_TAGS: ['style'],
WHOLE_DOCUMENT: true,
RETURN_DOM: true,
});
return new DOMParser().parseFromString(sanitizedHtml, 'text/html')
.documentElement;
};
};
@@ -1,386 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* 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.
*/
/**
* This is the source of truth of what attributes we support in TechDocs.
*/
export const html = [
'accept',
'action',
'align',
'alt',
'autocapitalize',
'autocomplete',
'autopictureinpicture',
'autoplay',
'background',
'bgcolor',
'border',
'capture',
'cellpadding',
'cellspacing',
'checked',
'cite',
'class',
'clear',
'color',
'cols',
'colspan',
'controls',
'controlslist',
'coords',
'crossorigin',
'datetime',
'decoding',
'default',
'dir',
'disabled',
'disablepictureinpicture',
'disableremoteplayback',
'download',
'draggable',
'enctype',
'enterkeyhint',
'face',
'for',
'headers',
'height',
'hidden',
'high',
'href',
'hreflang',
'id',
'inputmode',
'integrity',
'ismap',
'kind',
'label',
'lang',
'list',
'loading',
'loop',
'low',
'max',
'maxlength',
'media',
'method',
'min',
'minlength',
'multiple',
'muted',
'name',
'noshade',
'novalidate',
'nowrap',
'open',
'optimum',
'pattern',
'placeholder',
'playsinline',
'poster',
'preload',
'pubdate',
'radiogroup',
'readonly',
'rel',
'required',
'rev',
'reversed',
'role',
'rows',
'rowspan',
'spellcheck',
'scope',
'selected',
'shape',
'size',
'sizes',
'span',
'srclang',
'start',
'src',
'srcset',
'step',
'style',
'summary',
'tabindex',
'title',
'translate',
'type',
'usemap',
'valign',
'value',
'width',
'xmlns',
];
export const svg = [
'accent-height',
'accumulate',
'additive',
'alignment-baseline',
'ascent',
'attributename',
'attributetype',
'azimuth',
'basefrequency',
'baseline-shift',
'begin',
'bias',
'by',
'class',
'clip',
'clip-path',
'clip-rule',
'color',
'color-interpolation',
'color-interpolation-filters',
'color-profile',
'color-rendering',
'cx',
'cy',
'd',
'dx',
'dy',
'data',
'diffuseconstant',
'direction',
'display',
'divisor',
'dur',
'edgemode',
'elevation',
'end',
'fill',
'fill-opacity',
'fill-rule',
'filter',
'filterunits',
'flood-color',
'flood-opacity',
'font-family',
'font-size',
'font-size-adjust',
'font-stretch',
'font-style',
'font-variant',
'font-weight',
'fx',
'fy',
'g1',
'g2',
'glyph-name',
'glyphref',
'gradientunits',
'gradienttransform',
'height',
'href',
'id',
'image-rendering',
'in',
'in2',
'k',
'k1',
'k2',
'k3',
'k4',
'kerning',
'keypoints',
'keysplines',
'keytimes',
'lang',
'lengthadjust',
'letter-spacing',
'kernelmatrix',
'kernelunitlength',
'lighting-color',
'local',
'marker-end',
'marker-mid',
'marker-start',
'markerheight',
'markerunits',
'markerwidth',
'maskcontentunits',
'maskunits',
'max',
'mask',
'media',
'method',
'mode',
'min',
'name',
'numoctaves',
'offset',
'operator',
'opacity',
'order',
'orient',
'orientation',
'origin',
'overflow',
'paint-order',
'path',
'pathlength',
'patterncontentunits',
'patterntransform',
'patternunits',
'points',
'preservealpha',
'preserveaspectratio',
'primitiveunits',
'r',
'rx',
'ry',
'radius',
'refx',
'refy',
'repeatcount',
'repeatdur',
'restart',
'result',
'rotate',
'scale',
'seed',
'shape-rendering',
'specularconstant',
'specularexponent',
'spreadmethod',
'startoffset',
'stddeviation',
'stitchtiles',
'stop-color',
'stop-opacity',
'stroke-dasharray',
'stroke-dashoffset',
'stroke-linecap',
'stroke-linejoin',
'stroke-miterlimit',
'stroke-opacity',
'stroke',
'stroke-width',
'style',
'surfacescale',
'tabindex',
'targetx',
'targety',
'transform',
'text-anchor',
'text-decoration',
'text-rendering',
'textlength',
'type',
'u1',
'u2',
'unicode',
'values',
'viewbox',
'visibility',
'version',
'vert-adv-y',
'vert-origin-x',
'vert-origin-y',
'width',
'word-spacing',
'wrap',
'writing-mode',
'xchannelselector',
'ychannelselector',
'x',
'x1',
'x2',
'xmlns',
'y',
'y1',
'y2',
'z',
'zoomandpan',
];
export const mathMl = [
'accent',
'accentunder',
'align',
'bevelled',
'close',
'columnsalign',
'columnlines',
'columnspan',
'denomalign',
'depth',
'dir',
'display',
'displaystyle',
'encoding',
'fence',
'frame',
'height',
'href',
'id',
'largeop',
'length',
'linethickness',
'lspace',
'lquote',
'mathbackground',
'mathcolor',
'mathsize',
'mathvariant',
'maxsize',
'minsize',
'movablelimits',
'notation',
'numalign',
'open',
'rowalign',
'rowlines',
'rowspacing',
'rowspan',
'rspace',
'rquote',
'scriptlevel',
'scriptminsize',
'scriptsizemultiplier',
'selection',
'separator',
'separators',
'stretchy',
'subscriptshift',
'supscriptshift',
'symmetric',
'voffset',
'width',
'xmlns',
];
export const xml = [
'xlink:href',
'xml:id',
'xlink:title',
'xml:space',
'xmlns:xlink',
];
/**
* Anything in here will be supported as HTML attributes from TechDocs.
*
* @note Be conscious about what you add here. It can affect the TechDocs experience. For
* some review before making a PR, reach out in the #docs-like-code channel in Discord first.
*/
export const TECHDOCS_ALLOWED_ATTRIBUTES = {
'*': [...html, ...svg, ...mathMl, ...xml, 'data-*'],
};
@@ -1,248 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* 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.
*/
/**
* This is the source of truth for what HTML tags we support in TechDocs.
*/
// prettier-ignore
export const html = [
'a', 'abbr', 'acronym',
'address', 'area', 'article',
'aside', 'audio', 'b', 'bdi',
'bdo', 'big',
'blink', 'blockquote',
'body',
'br', 'button',
'canvas', 'caption', 'center', 'cite', 'code',
'col', 'colgroup',
'content',
'data',
'datalist',
'dd',
'decorator',
'del',
'details',
'dfn',
'dir',
'div',
'dl',
'dt',
'element',
'em',
'fieldset',
'figcaption',
'figure',
'font',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'head',
'header',
'hgroup',
'hr',
'html',
'i',
'img',
'input',
'ins',
'kbd',
'label',
'legend',
'li',
'link',
'main',
'map',
'mark',
'marquee',
'menu',
'menuitem',
'meter',
'nav',
'nobr',
'ol',
'optgroup',
'option',
'output',
'p',
'picture',
'pre',
'progress',
'q',
'rp',
'rt',
'ruby',
's',
'samp',
'section',
'select',
'shadow',
'small',
'source',
'spacer',
'span',
'strike',
'strong',
'sub',
'summary',
'sup',
'table',
'tbody',
'td',
'template',
'textarea',
'tfoot',
'th',
'thead',
'time',
'tr',
'track',
'tt',
'u',
'ul',
'var',
'video',
'wbr',
];
// SVG
export const svg = [
'svg',
'a',
'altglyph',
'altglyphdef',
'altglyphitem',
'animatecolor',
'animatemotion',
'animatetransform',
'audio',
'canvas',
'circle',
'clippath',
'defs',
'desc',
'ellipse',
'filter',
'font',
'g',
'glyph',
'glyphref',
'hkern',
'image',
'line',
'lineargradient',
'marker',
'mask',
'metadata',
'mpath',
'path',
'pattern',
'polygon',
'polyline',
'radialgradient',
'rect',
'stop',
'switch',
'symbol',
'text',
'textpath',
'title',
'tref',
'tspan',
'video',
'view',
'vkern',
];
export const svgFilters = [
'feBlend',
'feColorMatrix',
'feComponentTransfer',
'feComposite',
'feConvolveMatrix',
'feDiffuseLighting',
'feDisplacementMap',
'feDistantLight',
'feFlood',
'feFuncA',
'feFuncB',
'feFuncG',
'feFuncR',
'feGaussianBlur',
'feMerge',
'feMergeNode',
'feMorphology',
'feOffset',
'fePointLight',
'feSpecularLighting',
'feSpotLight',
'feTile',
'feTurbulence',
];
export const mathMl = [
'math',
'menclose',
'merror',
'mfenced',
'mfrac',
'mglyph',
'mi',
'mlabeledtr',
'mmultiscripts',
'mn',
'mo',
'mover',
'mpadded',
'mphantom',
'mroot',
'mrow',
'ms',
'mspace',
'msqrt',
'mstyle',
'msub',
'msup',
'msubsup',
'mtable',
'mtd',
'mtext',
'mtr',
'munder',
'munderover',
];
export const text = ['#text'];
/**
* Anything in here will be executed as HTML tags from TechDocs.
*
* @note Be conscious about what you add here. It can affect the TechDocs experience. For
* some review before making a PR, reach out in the #docs-like-code channel in Discord first.
*/
export const TECHDOCS_ALLOWED_TAGS = [
...html,
...svg,
...svgFilters,
...mathMl,
...text,
'iframe',
];
+175 -80
View File
@@ -2708,10 +2708,10 @@
resolved "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
"@kubernetes/client-node@^0.14.0":
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==
"@kubernetes/client-node@^0.15.0":
version "0.15.0"
resolved "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.15.0.tgz#aa5cfcfa9ba3055fe0b510c430d19bbda715d8e7"
integrity sha512-AnEcsWWadl5IWOzzvO/gWpTnJb1d1CzA/rbV/qK1c0fD1SOxTDPj6jFllyQ9icGDfCgNw3TafZftmuepm6z9JA==
dependencies:
"@types/js-yaml" "^3.12.1"
"@types/node" "^10.12.0"
@@ -2721,14 +2721,14 @@
"@types/underscore" "^1.8.9"
"@types/ws" "^6.0.1"
byline "^5.0.0"
execa "1.0.0"
execa "5.0.0"
isomorphic-ws "^4.0.1"
js-yaml "^3.13.1"
jsonpath-plus "^0.19.0"
openid-client "^4.1.1"
request "^2.88.0"
rfc4648 "^1.3.0"
shelljs "^0.8.2"
shelljs "^0.8.4"
stream-buffers "^3.0.2"
tar "^6.0.2"
tmp-promise "^3.0.2"
@@ -4087,9 +4087,9 @@
react-use "^17.2.4"
"@roadiehq/backstage-plugin-github-insights@^1.1.20":
version "1.1.20"
resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-insights/-/backstage-plugin-github-insights-1.1.20.tgz#5e58124b4da2a60c0d4e6563cd94cdd7702fa341"
integrity sha512-bhYe9o1MpIGxSqXa2HK1E8P/uzTL7zJvUleLTp9C5q4CmPCroNTE/Ce8Apzlrb9o9baSQEhQLoPqe0xs+chS7A==
version "1.1.21"
resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-insights/-/backstage-plugin-github-insights-1.1.21.tgz#d43de9bc384c7a6e3d8ef13c77f4842e2ca69794"
integrity sha512-PctbxHscDmFK8jaM3MPUhoDw90TTQEydxTjiTQ+1+yY2KnlrEbxu5i8RgDk3UfRfZQIJw6JFDkEYGaTJIAv3Tw==
dependencies:
"@backstage/catalog-model" "^0.9.0"
"@backstage/core-app-api" "^0.1.3"
@@ -4343,6 +4343,28 @@
resolved "https://registry.npmjs.org/@spotify/prettier-config/-/prettier-config-10.0.0.tgz#fa076d98d2e7e6c53dd3d86a696307a7010bd056"
integrity sha512-VYOdo8P7lIScAkl02nB9KpUAuOYMManryBIBuKJkAw5D3aVtLobfmdIKvdV6MqEmGMEQPbn7w/UpnjJYhUH+IA==
"@storybook/addon-a11y@^6.3.4":
version "6.3.4"
resolved "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.3.4.tgz#056c3c0e3b2d66d8aa2f02dc84374c948d07df91"
integrity sha512-ABG1dvwDdlNVvW+P+oRtDdiyw40ddc+maSwKbwxTiw9Ibq7TrasWE9ub0r7yNoFLXEZa3pBjPrGKdh+WIYToSQ==
dependencies:
"@storybook/addons" "6.3.4"
"@storybook/api" "6.3.4"
"@storybook/channels" "6.3.4"
"@storybook/client-api" "6.3.4"
"@storybook/client-logger" "6.3.4"
"@storybook/components" "6.3.4"
"@storybook/core-events" "6.3.4"
"@storybook/theming" "6.3.4"
axe-core "^4.2.0"
core-js "^3.8.2"
global "^4.4.0"
lodash "^4.17.20"
react-sizeme "^3.0.1"
regenerator-runtime "^0.13.7"
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/addon-actions@^6.1.11":
version "6.3.0"
resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.3.0.tgz#e5a24c69d70da9aa98560f19d10c06a50495ca2e"
@@ -4593,6 +4615,19 @@
qs "^6.10.0"
telejson "^5.3.2"
"@storybook/channel-postmessage@6.3.4":
version "6.3.4"
resolved "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.3.4.tgz#1a0000aefc9494d5585a1d2c7bdb75f540965f70"
integrity sha512-UIHNrMD9ZaT249nkKXibqRjKEoqfeFJk5HKW2W17/Z/imVcKG9THBnRJ7cb+r7LqS8Yoh+Q87ycRqcPVLRJ/Xw==
dependencies:
"@storybook/channels" "6.3.4"
"@storybook/client-logger" "6.3.4"
"@storybook/core-events" "6.3.4"
core-js "^3.8.2"
global "^4.4.0"
qs "^6.10.0"
telejson "^5.3.2"
"@storybook/channels@6.1.15":
version "6.1.15"
resolved "https://registry.npmjs.org/@storybook/channels/-/channels-6.1.15.tgz#22bb06a671a5ae09d2537bcf63aaf90d7f6b9f6b"
@@ -4677,6 +4712,30 @@
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/client-api@6.3.4":
version "6.3.4"
resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.3.4.tgz#7dd6dda0126012ed37fa885642973cc75366b5a8"
integrity sha512-lOrfz8ic3+nHZzqIdNH2I7Q3Wp0kS/Ic0PD/3QKvI2f6iVIapIjjWW1xAuor80Dl7rMhOn8zxgXta+7G7Pn2yQ==
dependencies:
"@storybook/addons" "6.3.4"
"@storybook/channel-postmessage" "6.3.4"
"@storybook/channels" "6.3.4"
"@storybook/client-logger" "6.3.4"
"@storybook/core-events" "6.3.4"
"@storybook/csf" "0.0.1"
"@types/qs" "^6.9.5"
"@types/webpack-env" "^1.16.0"
core-js "^3.8.2"
global "^4.4.0"
lodash "^4.17.20"
memoizerific "^1.11.3"
qs "^6.10.0"
regenerator-runtime "^0.13.7"
stable "^0.1.8"
store2 "^2.12.0"
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/client-logger@6.1.15":
version "6.1.15"
resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.1.15.tgz#b558d6ecbee82c038d684717d8c598eaa4a9324d"
@@ -4795,6 +4854,36 @@
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/components@6.3.4":
version "6.3.4"
resolved "https://registry.npmjs.org/@storybook/components/-/components-6.3.4.tgz#c872ec267edf315eaada505be8595c70eb6db09b"
integrity sha512-0hBKTkkQbW+daaA6nRedkviPr2bEzy1kwq0H5eaLKI1zYeXN3U5Z8fVhO137PPqH5LmLietrmTPkqiljUBk9ug==
dependencies:
"@popperjs/core" "^2.6.0"
"@storybook/client-logger" "6.3.4"
"@storybook/csf" "0.0.1"
"@storybook/theming" "6.3.4"
"@types/color-convert" "^2.0.0"
"@types/overlayscrollbars" "^1.12.0"
"@types/react-syntax-highlighter" "11.0.5"
color-convert "^2.0.1"
core-js "^3.8.2"
fast-deep-equal "^3.1.3"
global "^4.4.0"
lodash "^4.17.20"
markdown-to-jsx "^7.1.3"
memoizerific "^1.11.3"
overlayscrollbars "^1.13.1"
polished "^4.0.5"
prop-types "^15.7.2"
react-colorful "^5.1.2"
react-popper-tooltip "^3.1.1"
react-syntax-highlighter "^13.5.3"
react-textarea-autosize "^8.3.0"
regenerator-runtime "^0.13.7"
ts-dedent "^2.0.0"
util-deprecate "^1.0.2"
"@storybook/core-events@6.1.15":
version "6.1.15"
resolved "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.1.15.tgz#f66e30cbed8afdb8df2254d2aa47fe139e641c60"
@@ -5700,6 +5789,13 @@
dependencies:
"@types/node" "*"
"@types/dompurify@^2.2.2":
version "2.2.3"
resolved "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.2.3.tgz#6e89677a07902ac1b6821c345f34bd85da239b08"
integrity sha512-CLtc2mZK8+axmrz1JqtpklO/Kvn38arGc8o1l3UVopZaXXuer9ONdZwJ/9f226GrhRLtUmLr9WrvZsRSNpS8og==
dependencies:
"@types/trusted-types" "*"
"@types/eslint@*":
version "6.1.8"
resolved "https://registry.npmjs.org/@types/eslint/-/eslint-6.1.8.tgz#7e868f89bc1e520323d405940e49cb912ede5bba"
@@ -6051,10 +6147,10 @@
"@types/koa-compose" "*"
"@types/node" "*"
"@types/ldapjs@^1.0.10":
version "1.0.10"
resolved "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-1.0.10.tgz#bac705c9e154b97d69496b5213cc28dbe9715a37"
integrity sha512-AMkMxkK/wjYtWebNH2O+rARfo7scBpW3T23g6zmGCwDgbyDbR79XWpcSqhPWdU+fChaF+I3dVyl9X2dT1CyI9w==
"@types/ldapjs@^2.2.0":
version "2.2.0"
resolved "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-2.2.0.tgz#43ff78668c420b69a61b93e0acde71ddc0c7766d"
integrity sha512-L6ObSryRGOw0qYmN9B4w4s8UkoyRbxoWh7C1vc/Z6O/VXJQJqGBSyZPXRDmgKF+TZVGq/F7H37t0Cxrm+hLiRA==
dependencies:
"@types/node" "*"
@@ -6658,6 +6754,11 @@
resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d"
integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==
"@types/trusted-types@*":
version "2.0.2"
resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==
"@types/tunnel@^0.0.1":
version "0.0.1"
resolved "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.1.tgz#0d72774768b73df26f25df9184273a42da72b19c"
@@ -7960,6 +8061,11 @@ axe-core@^4.0.2:
resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.1.3.tgz#64a4c85509e0991f5168340edc4bedd1ceea6966"
integrity sha512-vwPpH4Aj4122EW38mxO/fxhGKtwWTMLDIJfZ1He0Edbtjcfna/R3YB67yVhezUMzqc3Jr3+Ii50KRntlENL4xQ==
axe-core@^4.2.0:
version "4.3.1"
resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.3.1.tgz#0c6a076e4a1c3e0544ba6a9479158f9be7a7928e"
integrity sha512-3WVgVPs/7OnKU3s+lqMtkv3wQlg3WxK1YifmpJSDO0E1aPBrZWlrrTO6cxRqCXLuX2aYgCljqXIQd0VnRidV0g==
axios@^0.20.0:
version "0.20.0"
resolved "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
@@ -11556,6 +11662,11 @@ dompurify@^2.0.12, dompurify@^2.1.1, dompurify@^2.2.8:
resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.2.8.tgz#ce88e395f6d00b6dc53f80d6b2a6fdf5446873c6"
integrity sha512-9H0UL59EkDLgY3dUFjLV6IEUaHm5qp3mxSqWw7Yyx4Zhk2Jn2cmLe+CNPP3xy13zl8Bqg+0NehQzkdMoVhGRww==
dompurify@^2.2.9:
version "2.3.0"
resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.3.0.tgz#07bb39515e491588e5756b1d3e8375b5964814e2"
integrity sha512-VV5C6Kr53YVHGOBKO/F86OYX6/iLTw2yVSI721gKetxpHCK/V5TaLEf9ODjRgl1KLSWRMY6cUhAbv/c+IUnwQw==
domutils@1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
@@ -11572,7 +11683,7 @@ domutils@^1.5.1, domutils@^1.7.0:
dom-serializer "0"
domelementtype "1"
domutils@^2.0.0, domutils@^2.4.4:
domutils@^2.0.0:
version "2.4.4"
resolved "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3"
integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==
@@ -11742,6 +11853,13 @@ element-resize-detector@^1.2.1:
dependencies:
batch-processor "1.0.0"
element-resize-detector@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.3.tgz#5078d9b99398fe4c589f8c8df94ff99e5d413ff3"
integrity sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ==
dependencies:
batch-processor "1.0.0"
elliptic@^6.0.0:
version "6.5.4"
resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@@ -12451,19 +12569,6 @@ exec-sh@^0.3.2:
resolved "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5"
integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==
execa@1.0.0, execa@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
dependencies:
cross-spawn "^6.0.0"
get-stream "^4.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
execa@3.4.0:
version "3.4.0"
resolved "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89"
@@ -12495,20 +12600,7 @@ execa@4.1.0, execa@^4.0.0, execa@^4.0.1:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
execa@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
dependencies:
cross-spawn "^5.0.1"
get-stream "^3.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
execa@^5.0.0:
execa@5.0.0, execa@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
@@ -12523,6 +12615,32 @@ execa@^5.0.0:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
execa@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
dependencies:
cross-spawn "^5.0.1"
get-stream "^3.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
dependencies:
cross-spawn "^6.0.0"
get-stream "^4.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
executable@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c"
@@ -14571,16 +14689,6 @@ htmlparser2@^4.0:
domutils "^2.0.0"
entities "^2.0.0"
htmlparser2@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.0.tgz#c2da005030390908ca4c91e5629e418e0665ac01"
integrity sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.0.0"
domutils "^2.4.4"
entities "^2.0.0"
http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
@@ -15796,7 +15904,7 @@ isomorphic-fetch@^3.0.0:
node-fetch "^2.6.1"
whatwg-fetch "^3.4.1"
isomorphic-form-data@~2.0.0:
isomorphic-form-data@^2.0.0, isomorphic-form-data@~2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-2.0.0.tgz#9f6adf1c4c61ae3aefd8f110ab60fb9b143d6cec"
integrity sha512-TYgVnXWeESVmQSg4GLVbalmQ+B4NPi/H4eWxqALKj63KsUrcu301YDjBqaOw3h+cbak7Na4Xyps3BiptHtxTfg==
@@ -17007,11 +17115,6 @@ kleur@^3.0.3:
resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
klona@^2.0.3:
version "2.0.4"
resolved "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==
knex@^0.95.1:
version "0.95.6"
resolved "https://registry.npmjs.org/knex/-/knex-0.95.6.tgz#5fc60ffc2935567bf122925526b1b06b8dbca785"
@@ -19919,11 +20022,6 @@ parse-path@^4.0.0:
is-ssh "^1.3.0"
protocols "^1.4.0"
parse-srcset@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1"
integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=
parse-url@^5.0.0:
version "5.0.1"
resolved "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz#99c4084fc11be14141efa41b3d117a96fcb9527f"
@@ -20875,7 +20973,7 @@ 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, postcss@^8.1.0, postcss@^8.2.15:
postcss@^8.1.0, postcss@^8.2.15:
version "8.3.5"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709"
integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==
@@ -21829,6 +21927,16 @@ react-sizeme@^2.6.7:
shallowequal "^1.1.0"
throttle-debounce "^2.1.0"
react-sizeme@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/react-sizeme/-/react-sizeme-3.0.1.tgz#4d12f4244e0e6a0fb97253e7af0314dc7c83a5a0"
integrity sha512-9Hf1NLgSbny1bha77l9HwvwwxQUJxFUqi44Ih+y3evA+PezBpGdCGlnvye6avss2cIgs9PgdYgMnfuzJWn/RUw==
dependencies:
element-resize-detector "^1.2.2"
invariant "^2.2.4"
shallowequal "^1.1.0"
throttle-debounce "^3.0.1"
react-smooth@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-1.0.5.tgz#94ae161d7951cdd893ccb7099d031d342cb762ad"
@@ -22945,19 +23053,6 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"
sanitize-html@^2.3.2:
version "2.4.0"
resolved "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.4.0.tgz#8da7524332eb210d968971621b068b53f17ab5a3"
integrity sha512-Y1OgkUiTPMqwZNRLPERSEi39iOebn2XJLbeiGOBhaJD/yLqtLGu6GE5w7evx177LeGgSE+4p4e107LMiydOf6A==
dependencies:
deepmerge "^4.2.2"
escape-string-regexp "^4.0.0"
htmlparser2 "^6.0.0"
is-plain-object "^5.0.0"
klona "^2.0.3"
parse-srcset "^1.0.2"
postcss "^8.0.2"
sax@1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
@@ -23040,9 +23135,9 @@ select@^1.1.2:
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
selfsigned@^1.10.7:
version "1.10.8"
resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
version "1.10.11"
resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9"
integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==
dependencies:
node-forge "^0.10.0"
@@ -23280,7 +23375,7 @@ shell-quote@1.7.2:
resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
shelljs@^0.8.2, shelljs@^0.8.3, shelljs@^0.8.4:
shelljs@^0.8.3, shelljs@^0.8.4:
version "0.8.4"
resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==