diff --git a/.changeset/dependabot-cb942df.md b/.changeset/dependabot-cb942df.md deleted file mode 100644 index 569b403924..0000000000 --- a/.changeset/dependabot-cb942df.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -chore(deps): bump `@material-table/core` from 3.1.0 to 4.3.19 diff --git a/.changeset/dependabot-eda489b.md b/.changeset/dependabot-eda489b.md new file mode 100644 index 0000000000..f82428e14b --- /dev/null +++ b/.changeset/dependabot-eda489b.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-components': patch +'@backstage/plugin-sonarqube': patch +--- + +chore(deps): bump `rc-progress` from 3.1.4 to 3.2.4 diff --git a/.changeset/dependabot-f3a4fa1.md b/.changeset/dependabot-f3a4fa1.md new file mode 100644 index 0000000000..0c735ac93c --- /dev/null +++ b/.changeset/dependabot-f3a4fa1.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +chore(deps): bump `@gitbeaker/node` from 34.6.0 to 35.1.0 diff --git a/.changeset/famous-walls-yell.md b/.changeset/famous-walls-yell.md new file mode 100644 index 0000000000..8a4e988f5b --- /dev/null +++ b/.changeset/famous-walls-yell.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fix issue where component types are not recognized causing the `MobileSidebar` to not render as intended. diff --git a/.changeset/metal-bottles-lay.md b/.changeset/metal-bottles-lay.md new file mode 100644 index 0000000000..706ebd3528 --- /dev/null +++ b/.changeset/metal-bottles-lay.md @@ -0,0 +1,63 @@ +--- +'@backstage/create-app': patch +--- + +Replaced EntitySystemDiagramCard with EntityCatalogGraphCard + +To make this change to an existing app: + +Add `@backstage/catalog-graph-plugin` as a `dependency` in `packages/app/package.json` + +Apply the following changes to the `packages/app/src/components/catalog/EntityPage.tsx` file: + +```diff ++ import { ++ Direction, ++ EntityCatalogGraphCard, ++ } from '@backstage/plugin-catalog-graph'; ++ import { ++ RELATION_API_CONSUMED_BY, ++ RELATION_API_PROVIDED_BY, ++ RELATION_CONSUMES_API, ++ RELATION_DEPENDENCY_OF, ++ RELATION_DEPENDS_ON, ++ RELATION_HAS_PART, ++ RELATION_PART_OF, ++ RELATION_PROVIDES_API, ++ } from '@backstage/catalog-model'; +``` + +```diff + +- ++ + +``` + +```diff +const cicdContent = ( + + + ++ ++ ++ +``` + +Add the above component in `overviewContent`, `apiPage` , `systemPage` and domainPage` as well. diff --git a/.changeset/rude-clouds-chew.md b/.changeset/rude-clouds-chew.md new file mode 100644 index 0000000000..f39a7bdaac --- /dev/null +++ b/.changeset/rude-clouds-chew.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Expose a new option to provide additional template filters via `@backstage/scaffolder-backend`'s `createRouter()` function. diff --git a/.changeset/smooth-ghosts-trade.md b/.changeset/smooth-ghosts-trade.md new file mode 100644 index 0000000000..64be2bd8c9 --- /dev/null +++ b/.changeset/smooth-ghosts-trade.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Deprecated `EntitySystemDiagramCard` +`EntitySystemDiagramCard` is replaced by `EntityCatalogGraphCard` which is imported from `@backstage/plugin-catalog-graph`. This component will be removed in an upcoming release diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 2a6f4808fa..ed97cf05f1 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -15,6 +15,7 @@ jobs: with: fetch-depth: 2 ref: ${{ github.head_ref }} + token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - name: Configure Git run: | git config --global user.email noreply@backstage.io @@ -30,7 +31,9 @@ jobs: const names = []; for (const file of files) { const data = JSON.parse(await fs.readFile(file, 'utf8')); - names.push(data.name); + if (!data.private) { + names.push(data.name); + } } return names; } @@ -60,12 +63,12 @@ jobs: .filter(file => file !== 'package.json') // skip root package.json .filter(file => file.includes('package.json')); - if (!files.length) { - console.log('No package.json changes, skipping'); + const packageNames = await getPackagesNames(files); + if (!packageNames.length) { + console.log('No package.json changes to published packages, skipping'); return; } - const packageNames = await getPackagesNames(files); const { stdout: shortHash } = await exec.getExecOutput('git rev-parse --short HEAD'); const fileName = `.changeset/dependabot-${shortHash.trim()}.md`; const { stdout: commitMessage } = await exec.getExecOutput('git show --pretty=format:%s -s HEAD'); diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index a564200bfe..2bb8a0b554 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -9,7 +9,7 @@ by writing custom actions which can be used along side our [built-in actions](./builtin-actions.md). > Note: When adding custom actions, the actions array will **replace the -> built-in actions too**. To ensure you can continue to include he builtin +> built-in actions too**. To ensure you can continue to include the builtin > actions, see below to include them during registration of your action. ### Writing your Custom Action diff --git a/package.json b/package.json index f9ddc9ab94..d30453add0 100644 --- a/package.json +++ b/package.json @@ -52,9 +52,9 @@ "version": "1.0.0", "dependencies": { "@manypkg/get-packages": "^1.1.3", - "@microsoft/api-documenter": "^7.13.77", - "@microsoft/api-extractor": "^7.19.2", - "@microsoft/api-extractor-model": "^7.15.1", + "@microsoft/api-documenter": "^7.15.0", + "@microsoft/api-extractor": "^7.19.4", + "@microsoft/api-extractor-model": "^7.15.3", "@microsoft/tsdoc": "^0.13.2" }, "devDependencies": { diff --git a/packages/backend/package.json b/packages/backend/package.json index d986377d33..7e0c54d103 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -56,7 +56,7 @@ "@backstage/plugin-tech-insights-node": "^0.2.0", "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.6", "@backstage/plugin-todo-backend": "^0.1.19", - "@gitbeaker/node": "^34.6.0", + "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^18.5.3", "azure-devops-node-api": "^11.0.1", "dockerode": "^3.3.1", diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 4d09b5d08a..943b17a4ae 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -33,7 +33,7 @@ "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/theme": "^0.2.14", - "@material-table/core": "^4.3.19", + "@material-table/core": "^3.1.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -51,7 +51,7 @@ "pluralize": "^8.0.0", "prop-types": "^15.7.2", "qs": "^6.9.4", - "rc-progress": "3.1.4", + "rc-progress": "3.2.4", "react-helmet": "6.1.0", "react-hook-form": "^7.12.2", "react-markdown": "^7.0.1", diff --git a/packages/core-components/src/layout/Sidebar/Items.tsx b/packages/core-components/src/layout/Sidebar/Items.tsx index b16c9ad302..fc97fdc0ce 100644 --- a/packages/core-components/src/layout/Sidebar/Items.tsx +++ b/packages/core-components/src/layout/Sidebar/Items.tsx @@ -284,6 +284,8 @@ function isButtonItem( return (props as SidebarItemLinkProps).to === undefined; } +const sidebarSubmenuType = React.createElement(SidebarSubmenu).type; + // TODO(Rugvip): Remove this once NavLink is updated in react-router-dom. // This is needed because react-router doesn't handle the path comparison // properly yet, matching for example /foobar with /foo. @@ -486,7 +488,11 @@ const SidebarItemWithSubmenu = ({ export const SidebarItem = forwardRef((props, ref) => { // Filter children for SidebarSubmenu components const [submenu] = useElementFilter(props.children, elements => - elements.getElements().filter(child => child.type === SidebarSubmenu), + // Directly comparing child.type with SidebarSubmenu will not work with in + // combination with react-hot-loader + // + // https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-456569720 + elements.getElements().filter(child => child.type === sidebarSubmenuType), ); if (submenu) { diff --git a/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx b/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx index 3819f21a02..95947f9274 100644 --- a/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx +++ b/packages/core-components/src/layout/Sidebar/MobileSidebar.tsx @@ -102,6 +102,8 @@ const sortSidebarGroupsForPriority = (children: React.ReactElement[]) => 'desc', ); +const sidebarGroupType = React.createElement(SidebarGroup).type; + const OverlayMenu = ({ children, label = 'Menu', @@ -162,8 +164,13 @@ export const MobileSidebar = (props: MobileSidebarProps) => { }, [location.pathname]); // Filter children for SidebarGroups + // + // Directly comparing child.type with SidebarSubmenu will not work with in + // combination with react-hot-loader + // + // https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-456569720 let sidebarGroups = useElementFilter(children, elements => - elements.getElements().filter(child => child.type === SidebarGroup), + elements.getElements().filter(child => child.type === sidebarGroupType), ); if (!children) { diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 2a3e35988a..63fc3b1c2c 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -63,6 +63,7 @@ "@backstage/plugin-auth-backend": "", "@backstage/plugin-catalog": "", "@backstage/plugin-catalog-backend": "", + "@backstage/plugin-catalog-graph": "", "@backstage/plugin-catalog-import": "", "@backstage/plugin-explore": "", "@backstage/plugin-github-actions": "", diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index f89ff7f391..34d016ebde 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -51,6 +51,7 @@ import { version as pluginAuthBackend } from '../../../../plugins/auth-backend/p import { version as pluginCatalog } from '../../../../plugins/catalog/package.json'; import { version as pluginCatalogReact } from '../../../../plugins/catalog-react/package.json'; import { version as pluginCatalogBackend } from '../../../../plugins/catalog-backend/package.json'; +import { version as pluginCatalogGraph } from '../../../../plugins/catalog-graph/package.json'; import { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json'; import { version as pluginCircleci } from '../../../../plugins/circleci/package.json'; import { version as pluginExplore } from '../../../../plugins/explore/package.json'; @@ -90,6 +91,7 @@ export const packageVersions = { '@backstage/plugin-catalog': pluginCatalog, '@backstage/plugin-catalog-react': pluginCatalogReact, '@backstage/plugin-catalog-backend': pluginCatalogBackend, + '@backstage/plugin-catalog-graph': pluginCatalogGraph, '@backstage/plugin-catalog-import': pluginCatalogImport, '@backstage/plugin-circleci': pluginCircleci, '@backstage/plugin-explore': pluginExplore, diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs index f968a076d7..23c45d3f9d 100644 --- a/packages/create-app/templates/default-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs @@ -13,6 +13,7 @@ "@backstage/integration-react": "^{{version '@backstage/integration-react'}}", "@backstage/plugin-api-docs": "^{{version '@backstage/plugin-api-docs'}}", "@backstage/plugin-catalog": "^{{version '@backstage/plugin-catalog'}}", + "@backstage/plugin-catalog-graph": "^{{version '@backstage/plugin-catalog-graph'}}", "@backstage/plugin-catalog-import": "^{{version '@backstage/plugin-catalog-import'}}", "@backstage/plugin-catalog-react": "^{{version '@backstage/plugin-catalog-react'}}", "@backstage/plugin-github-actions": "^{{version '@backstage/plugin-github-actions'}}", 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 d3b4b786a0..84d094410b 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 @@ -27,7 +27,6 @@ import { EntityAboutCard, EntityDependsOnComponentsCard, EntityDependsOnResourcesCard, - EntitySystemDiagramCard, EntityHasComponentsCard, EntityHasResourcesCard, EntityHasSubcomponentsCard, @@ -54,6 +53,20 @@ import { } from '@backstage/plugin-org'; import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; import { EmptyState } from '@backstage/core-components'; +import { + Direction, + EntityCatalogGraphCard, +} from '@backstage/plugin-catalog-graph'; +import { + RELATION_API_CONSUMED_BY, + RELATION_API_PROVIDED_BY, + RELATION_CONSUMES_API, + RELATION_DEPENDENCY_OF, + RELATION_DEPENDS_ON, + RELATION_HAS_PART, + RELATION_PART_OF, + RELATION_PROVIDES_API, +} from '@backstage/catalog-model'; const cicdContent = ( // This is an example of how you can implement your company's logic in entity page. @@ -108,6 +121,10 @@ const overviewContent = ( + + + + @@ -223,6 +240,9 @@ const apiPage = ( + + + @@ -290,6 +310,9 @@ const systemPage = ( + + + @@ -302,7 +325,23 @@ const systemPage = ( - + ); @@ -315,6 +354,9 @@ const domainPage = ( + + + diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 56f0865db2..9142446cb0 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -35,7 +35,7 @@ "fs-extra": "9.1.0", "handlebars": "^4.7.3", "pgtools": "^0.3.0", - "puppeteer": "^10.4.0", + "puppeteer": "^13.1.1", "tree-kill": "^1.2.2", "ts-node": "^10.0.0" }, diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index 23771d3ec9..ad391b594f 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -391,7 +391,7 @@ export const EntitySwitch: { // Warning: (ae-forgotten-export) The symbol "SystemDiagramCard" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "EntitySystemDiagramCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const EntitySystemDiagramCard: SystemDiagramCard; // Warning: (ae-missing-release-tag) "FilterContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog/src/plugin.ts b/plugins/catalog/src/plugin.ts index 03806a2aa2..5a94cd2a09 100644 --- a/plugins/catalog/src/plugin.ts +++ b/plugins/catalog/src/plugin.ts @@ -177,6 +177,10 @@ export const EntityDependsOnResourcesCard = catalogPlugin.provide( }), ); +/** + * @deprecated This component is replaced by EntityCatalogGraphCard which is imported from `@backstage/plugin-catalog-graph`. This component will be removed in an + * upcoming release + */ export const EntitySystemDiagramCard = catalogPlugin.provide( createComponentExtension({ name: 'EntitySystemDiagramCard', diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 12b29cae39..c33aa91bee 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -76,6 +76,7 @@ export const createBuiltinActions: (options: { catalogClient: CatalogApi; containerRunner?: ContainerRunner; config: Config; + additionalTemplateFilters?: Record; }) => TemplateAction[]; // Warning: (ae-missing-release-tag) "createCatalogRegisterAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -112,6 +113,7 @@ export function createFetchPlainAction(options: { export function createFetchTemplateAction(options: { reader: UrlReader; integrations: ScmIntegrations; + additionalTemplateFilters?: Record; }): TemplateAction; // Warning: (ae-missing-release-tag) "createFilesystemDeleteAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -219,6 +221,7 @@ export type CreateWorkerOptions = { integrations: ScmIntegrations; workingDirectory: string; logger: Logger_2; + additionalTemplateFilters?: Record; }; // @public @@ -304,6 +307,8 @@ export interface RouterOptions { // (undocumented) actions?: TemplateAction[]; // (undocumented) + additionalTemplateFilters?: Record; + // (undocumented) catalogClient: CatalogApi; // (undocumented) config: Config; @@ -545,5 +550,10 @@ export class TemplateActionRegistry { ): void; } +// Warning: (ae-missing-release-tag) "TemplateFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined; + export { TemplateMetadata }; ``` diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 91319344a0..e9c932a211 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -42,7 +42,7 @@ "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.9", "@backstage/types": "^0.1.1", "@gitbeaker/core": "^34.6.0", - "@gitbeaker/node": "^34.6.0", + "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^18.5.3", "@octokit/webhooks": "^9.14.1", "@types/express": "^4.17.6", diff --git a/plugins/scaffolder-backend/src/index.ts b/plugins/scaffolder-backend/src/index.ts index 76cda63eef..5978b6389b 100644 --- a/plugins/scaffolder-backend/src/index.ts +++ b/plugins/scaffolder-backend/src/index.ts @@ -22,5 +22,5 @@ export * from './scaffolder'; export * from './service/router'; -export * from './lib/catalog'; +export * from './lib'; export * from './processor'; diff --git a/plugins/scaffolder-backend/src/lib/index.ts b/plugins/scaffolder-backend/src/lib/index.ts new file mode 100644 index 0000000000..dbb4348a2c --- /dev/null +++ b/plugins/scaffolder-backend/src/lib/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 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. + */ + +export * from './catalog'; +export * from './templating'; diff --git a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.test.ts b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.test.ts index 134b877efe..8b8d7847ac 100644 --- a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.test.ts +++ b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.test.ts @@ -99,6 +99,52 @@ describe('SecureTemplater', () => { ]); }); + it('should make additional filters available when requested', async () => { + const mockFilter1 = jest.fn(() => 'filtered text'); + const mockFilter2 = jest.fn((var1, var2) => `${var1} ${var2}`); + const mockFilter3 = jest.fn((var1, var2) => ({ var1, var2 })); + const renderWith = await SecureTemplater.loadRenderer({ + additionalTemplateFilters: { mockFilter1, mockFilter2, mockFilter3 }, + }); + const renderWithout = await SecureTemplater.loadRenderer(); + + const ctx = { inputValue: 'the input value' }; + + expect(renderWith('${{ inputValue | mockFilter1 }}', ctx)).toBe( + 'filtered text', + ); + expect( + renderWith('${{ inputValue | mockFilter2("extra arg") }}', ctx), + ).toBe('the input value extra arg'); + expect( + renderWith( + '${{ inputValue | mockFilter3("another extra arg") | dump }}', + ctx, + ), + ).toBe( + JSON.stringify({ + var1: 'the input value', + var2: 'another extra arg', + }), + ); + + expect(() => renderWithout('${{ inputValue | mockFilter1 }}', ctx)).toThrow( + /Error: filter not found: mockFilter1/, + ); + expect(() => + renderWithout('${{ inputValue | mockFilter2("extra arg") }}', ctx), + ).toThrow(/Error: filter not found: mockFilter2/); + expect(() => + renderWithout('${{ inputValue | mockFilter3("extra arg") }}', ctx), + ).toThrow(/Error: filter not found: mockFilter3/); + + expect(mockFilter1.mock.calls).toEqual([['the input value']]); + expect(mockFilter2.mock.calls).toEqual([['the input value', 'extra arg']]); + expect(mockFilter3.mock.calls).toEqual([ + ['the input value', 'another extra arg'], + ]); + }); + it('should not allow helpers to be rewritten', async () => { const render = await SecureTemplater.loadRenderer({ parseRepoUrl: () => ({ diff --git a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts index 54c9166020..6d3ce6f556 100644 --- a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts +++ b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts @@ -17,8 +17,10 @@ import { VM } from 'vm2'; import { resolvePackagePath } from '@backstage/backend-common'; import fs from 'fs-extra'; +import { JsonValue } from '@backstage/types'; import { RepoSpec } from '../../scaffolder/actions/builtin/publish/util'; +// language=JavaScript const mkScript = (nunjucksSource: string) => ` const { render, renderCompat } = (() => { const module = {}; @@ -56,6 +58,12 @@ const { render, renderCompat } = (() => { }); } + if (typeof additionalTemplateFilters !== 'undefined') { + for (const [filterName, filterFn] of Object.entries(additionalTemplateFilters)) { + env.addFilter(filterName, (...args) => JSON.parse(filterFn(...args))); + } + } + let uninstallCompat = undefined; function render(str, values) { @@ -87,12 +95,17 @@ const { render, renderCompat } = (() => { })(); `; +export type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined; + export interface SecureTemplaterOptions { /* Optional implementation of the parseRepoUrl filter */ parseRepoUrl?(repoUrl: string): RepoSpec; /* Enables jinja compatibility and the "jsonify" filter */ cookiecutterCompat?: boolean; + + /* Extra user-provided nunjucks filters */ + additionalTemplateFilters?: Record; } export type SecureTemplateRenderer = ( @@ -102,13 +115,23 @@ export type SecureTemplateRenderer = ( export class SecureTemplater { static async loadRenderer(options: SecureTemplaterOptions = {}) { - const { parseRepoUrl, cookiecutterCompat } = options; - let sandbox = undefined; + const { parseRepoUrl, cookiecutterCompat, additionalTemplateFilters } = + options; + const sandbox: Record = {}; if (parseRepoUrl) { - sandbox = { - parseRepoUrl: (url: string) => JSON.stringify(parseRepoUrl(url)), - }; + sandbox.parseRepoUrl = (url: string) => JSON.stringify(parseRepoUrl(url)); + } + + if (additionalTemplateFilters) { + sandbox.additionalTemplateFilters = Object.fromEntries( + Object.entries(additionalTemplateFilters) + .filter(([_, filterFunction]) => !!filterFunction) + .map(([filterName, filterFunction]) => [ + filterName, + (...args: JsonValue[]) => JSON.stringify(filterFunction(...args)), + ]), + ); } const vm = new VM({ sandbox }); diff --git a/plugins/scaffolder-backend/src/lib/templating/index.ts b/plugins/scaffolder-backend/src/lib/templating/index.ts new file mode 100644 index 0000000000..29d77291a1 --- /dev/null +++ b/plugins/scaffolder-backend/src/lib/templating/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export type { TemplateFilter } from './SecureTemplater'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index ce1e2a7f49..481ab894ec 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -46,6 +46,7 @@ import { createGithubActionsDispatchAction, createGithubWebhookAction, } from './github'; +import { TemplateFilter } from '../../../lib'; export const createBuiltinActions = (options: { reader: UrlReader; @@ -53,9 +54,16 @@ export const createBuiltinActions = (options: { catalogClient: CatalogApi; containerRunner?: ContainerRunner; config: Config; + additionalTemplateFilters?: Record; }) => { - const { reader, integrations, containerRunner, catalogClient, config } = - options; + const { + reader, + integrations, + containerRunner, + catalogClient, + config, + additionalTemplateFilters, + } = options; const githubCredentialsProvider: GithubCredentialsProvider = DefaultGithubCredentialsProvider.fromIntegrations(integrations); @@ -67,6 +75,7 @@ export const createBuiltinActions = (options: { createFetchTemplateAction({ integrations, reader, + additionalTemplateFilters, }), createPublishGithubAction({ integrations, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts index 2e25547e61..32a3a84070 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts @@ -23,7 +23,10 @@ import { createTemplateAction } from '../../createTemplateAction'; import globby from 'globby'; import fs from 'fs-extra'; import { isBinaryFile } from 'isbinaryfile'; -import { SecureTemplater } from '../../../../lib/templating/SecureTemplater'; +import { + TemplateFilter, + SecureTemplater, +} from '../../../../lib/templating/SecureTemplater'; type CookieCompatInput = { copyWithoutRender?: string[]; @@ -44,8 +47,9 @@ export type FetchTemplateInput = { export function createFetchTemplateAction(options: { reader: UrlReader; integrations: ScmIntegrations; + additionalTemplateFilters?: Record; }) { - const { reader, integrations } = options; + const { reader, integrations, additionalTemplateFilters } = options; return createTemplateAction({ id: 'fetch:template', @@ -182,6 +186,7 @@ export function createFetchTemplateAction(options: { const renderTemplate = await SecureTemplater.loadRenderer({ cookiecutterCompat: ctx.input.cookiecutterCompat, + additionalTemplateFilters, }); for (const location of allEntriesInTemplate) { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 46f87c1d00..5089998834 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -35,6 +35,7 @@ import { validate as validateJsonSchema } from 'jsonschema'; import { parseRepoUrl } from '../actions/builtin/publish/util'; import { TemplateActionRegistry } from '../actions'; import { + TemplateFilter, SecureTemplater, SecureTemplateRenderer, } from '../../lib/templating/SecureTemplater'; @@ -44,6 +45,7 @@ type NunjucksWorkflowRunnerOptions = { actionRegistry: TemplateActionRegistry; integrations: ScmIntegrations; logger: winston.Logger; + additionalTemplateFilters?: Record; }; type TemplateContext = { @@ -190,6 +192,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { parseRepoUrl(url: string) { return parseRepoUrl(url, integrations); }, + additionalTemplateFilters: this.options.additionalTemplateFilters, }); try { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index 8d89735361..8de9359806 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -21,6 +21,7 @@ import { Logger } from 'winston'; import { TemplateActionRegistry } from '../actions'; import { ScmIntegrations } from '@backstage/integration'; import { assertError } from '@backstage/errors'; +import { TemplateFilter } from '../../lib/templating/SecureTemplater'; /** * TaskWorkerOptions @@ -46,6 +47,7 @@ export type CreateWorkerOptions = { integrations: ScmIntegrations; workingDirectory: string; logger: Logger; + additionalTemplateFilters?: Record; }; /** @@ -63,6 +65,7 @@ export class TaskWorker { actionRegistry, integrations, workingDirectory, + additionalTemplateFilters, } = options; const legacyWorkflowRunner = new HandlebarsWorkflowRunner({ @@ -77,6 +80,7 @@ export class TaskWorker { integrations, logger, workingDirectory, + additionalTemplateFilters, }); return new TaskWorker({ diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index f4f7398c8a..85ed8a60ab 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -29,7 +29,7 @@ import express from 'express'; import Router from 'express-promise-router'; import { validate } from 'jsonschema'; import { Logger } from 'winston'; -import { CatalogEntityClient } from '../lib/catalog'; +import { CatalogEntityClient, TemplateFilter } from '../lib'; import { createBuiltinActions, DatabaseTaskStore, @@ -57,6 +57,7 @@ export interface RouterOptions { taskWorkers?: number; containerRunner?: ContainerRunner; taskBroker?: TaskBroker; + additionalTemplateFilters?: Record; } function isSupportedTemplate( @@ -83,6 +84,7 @@ export async function createRouter( actions, containerRunner, taskWorkers, + additionalTemplateFilters, } = options; const logger = parentLogger.child({ plugin: 'scaffolder' }); @@ -110,6 +112,7 @@ export async function createRouter( integrations, logger, workingDirectory, + additionalTemplateFilters, }); workers.push(worker); } @@ -122,6 +125,7 @@ export async function createRouter( containerRunner, reader, config, + additionalTemplateFilters, }); actionsToRegister.forEach(action => actionRegistry.register(action)); diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 54fe597a80..a8a10c2fc5 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -43,7 +43,7 @@ "@material-ui/lab": "4.0.0-alpha.57", "@material-ui/styles": "^4.10.0", "cross-fetch": "^3.0.6", - "rc-progress": "3.1.4", + "rc-progress": "3.2.4", "react-use": "^17.2.4" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index 023335f8ab..effdc62535 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1539,7 +1539,14 @@ core-js-pure "^3.20.2" 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.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@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.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@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.16.3" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3": version "7.16.7" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== @@ -2121,13 +2128,25 @@ query-string "^7.0.0" xcase "^2.0.1" -"@gitbeaker/node@^34.6.0": - version "34.6.0" - resolved "https://registry.npmjs.org/@gitbeaker/node/-/node-34.6.0.tgz#104f122433b65ceb45b0e645001d15cbcc9b1280" - integrity sha512-gVV4Wuev43Jbyoy1fszC885+bkvWH4zWiUhtIu0PSAm628j/OxO7idLIqUEMV0hDf6wm/PE/vOSP6PhjE0N+fA== +"@gitbeaker/core@^35.1.0": + version "35.1.0" + resolved "https://registry.npmjs.org/@gitbeaker/core/-/core-35.1.0.tgz#57f294886451b5ab2bccf0fc5fd8f6507473cd3a" + integrity sha512-DM9w3wgrS8GoXMLJb0DL2VSxTvP3yoaGDfX2d8n3wMGSjZbCknh3YnbVG/OfnaPbh9PH71kGll3SY5rJgz7XJg== dependencies: - "@gitbeaker/core" "^34.6.0" - "@gitbeaker/requester-utils" "^34.6.0" + "@gitbeaker/requester-utils" "^35.1.0" + form-data "^4.0.0" + li "^1.3.0" + mime "^3.0.0" + query-string "^7.0.0" + xcase "^2.0.1" + +"@gitbeaker/node@^35.1.0": + version "35.1.0" + resolved "https://registry.npmjs.org/@gitbeaker/node/-/node-35.1.0.tgz#a3b2d96534b54d8e3a3c8130da82ebc8802257d8" + integrity sha512-t0lXqSuY93jVffo6WMeo4tvZtkMQXPKuGb1qNh3HOuW4+KyEqmrdQnorGyyRYH7uRTmQeHEe33BL1Ttc5F5YrA== + dependencies: + "@gitbeaker/core" "^35.1.0" + "@gitbeaker/requester-utils" "^35.1.0" delay "^5.0.0" got "^11.8.2" xcase "^2.0.1" @@ -2141,6 +2160,15 @@ qs "^6.10.1" xcase "^2.0.1" +"@gitbeaker/requester-utils@^35.1.0": + version "35.1.0" + resolved "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-35.1.0.tgz#98c049d6b4e3f5ce222d7376b605e15c59d7bc93" + integrity sha512-00aQYCxs3wBHrD5HGWh0l1FRsX1NYJ1GEq4Reyo1NpVgjwzO/T1jjMFy3jikjJ+UGeg0sfqV9h91mwtCQ4SmRA== + dependencies: + form-data "^4.0.0" + qs "^6.10.1" + xcase "^2.0.1" + "@google-cloud/common@^3.7.0": version "3.7.0" resolved "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.0.tgz#ee3fba75aeaa614978aebf8740380670026592aa" @@ -3801,14 +3829,13 @@ semver "^7.3.4" tar "^6.1.0" -"@material-table/core@^4.3.19": - version "4.3.19" - resolved "https://registry.npmjs.org/@material-table/core/-/core-4.3.19.tgz#393c04248455eac7cd21ac2609a36776c42604c0" - integrity sha512-3dcbFuxPF09oNYpeec22WURANAJBytZGwSGU7vUotwc5a+aWj6AxcJRbClh0QAMBLyfR/7fCXmYzZdWDrtdWzw== +"@material-table/core@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@material-table/core/-/core-3.1.0.tgz#4fc3bd1553359e628413437a4102d8469852c253" + integrity sha512-46vpm1q9v2B5t/VgaEq2JmnftTBYle1yNAX3cfdQsTRZ1iWkpG34qBkNHx/hbOauQPsm5hmeUo1KJJZdwtGL1g== dependencies: "@babel/runtime" "^7.12.5" "@date-io/date-fns" "^1.3.13" - "@material-ui/icons" "^4.11.2" "@material-ui/pickers" "^3.2.10" "@material-ui/styles" "^4.11.4" classnames "^2.2.6" @@ -3818,7 +3845,6 @@ prop-types "^15.7.2" react-beautiful-dnd "^13.0.0" react-double-scrollbar "0.0.15" - uuid "^3.4.0" "@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2": version "4.12.3" @@ -3925,39 +3951,39 @@ prop-types "^15.7.2" react-is "^16.8.0 || ^17.0.0" -"@microsoft/api-documenter@^7.13.77": - version "7.13.77" - resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.13.77.tgz#9760b42553679695620b578436ce14c357454e88" - integrity sha512-kot4VJlQUd7i0mFSM7IjyOhF0WWyVrmN9x3sXmd72imgCg9w795QHSkphJ7Qc6ZjhHcolaJvBByEPTKG4exZmA== +"@microsoft/api-documenter@^7.15.0": + version "7.15.0" + resolved "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.15.0.tgz#e6cf24fc0e2f18a71dcf4c5c8100cc083167a81e" + integrity sha512-0KvwFamTIGZk6VE71F5gdDLxszLet0A1PEeb87RTdxr4KC0/yVFQvDyj+ck+HVr5+Exf6RyzIHfou0sgJl9SDA== dependencies: - "@microsoft/api-extractor-model" "7.15.1" + "@microsoft/api-extractor-model" "7.15.3" "@microsoft/tsdoc" "0.13.2" - "@rushstack/node-core-library" "3.44.2" - "@rushstack/ts-command-line" "4.10.5" + "@rushstack/node-core-library" "3.45.0" + "@rushstack/ts-command-line" "4.10.6" colors "~1.2.1" js-yaml "~3.13.1" resolve "~1.17.0" -"@microsoft/api-extractor-model@7.15.1", "@microsoft/api-extractor-model@^7.15.1": - version "7.15.1" - resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.15.1.tgz#e52d68676e846d8b86e3b18e2654af39fba6e4a1" - integrity sha512-DWfS1o3oMY0mzdO3OuQbD/9vzn80jwM6tFd7XbiYnkpxwhD83LMGXz7NZWwSh+IaA+9w3LF4w62fT31Qq+dAMw== +"@microsoft/api-extractor-model@7.15.3", "@microsoft/api-extractor-model@^7.15.3": + version "7.15.3" + resolved "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.15.3.tgz#cf76deeeb2733d974da678f530c2dbaceb18a065" + integrity sha512-NkSjolmSI7NGvbdz0Y7kjQfdpD+j9E5CwXTxEyjDqxd10MI7GXV8DnAsQ57GFJcgHKgTjf2aUnYfMJ9w3aMicw== dependencies: "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.44.2" + "@rushstack/node-core-library" "3.45.0" -"@microsoft/api-extractor@^7.19.2": - version "7.19.2" - resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.19.2.tgz#8c546003523163c1432f6e19506065f790d6182c" - integrity sha512-LxSa9lwp7eYtM4i5y/1n79QpotPKlmpCrVQbkb0LAHE1sCRHpZDTb6p3cMJthDhYPMjAYKOLfq639GwtZrg23Q== +"@microsoft/api-extractor@^7.19.4": + version "7.19.4" + resolved "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.19.4.tgz#95d43d410a1dfb28a02062c4693bcb9c52afe9eb" + integrity sha512-iehC6YA3DGJvxTUaK7HUtQmP6hAQU07+Q/OR8TG4dVR6KpqCi9UPEVk8AgCvQkiK+6FbVEFQTx0qLuYk4EeuHg== dependencies: - "@microsoft/api-extractor-model" "7.15.1" + "@microsoft/api-extractor-model" "7.15.3" "@microsoft/tsdoc" "0.13.2" "@microsoft/tsdoc-config" "~0.15.2" - "@rushstack/node-core-library" "3.44.2" - "@rushstack/rig-package" "0.3.6" - "@rushstack/ts-command-line" "4.10.5" + "@rushstack/node-core-library" "3.45.0" + "@rushstack/rig-package" "0.3.7" + "@rushstack/ts-command-line" "4.10.6" colors "~1.2.1" lodash "~4.17.15" resolve "~1.17.0" @@ -4694,10 +4720,10 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@rushstack/node-core-library@3.44.2": - version "3.44.2" - resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.44.2.tgz#4fcd8f76887ae5968f2796f633a7e48f5ebd2271" - integrity sha512-lQ8Ct267UKkNSJSDxpBWn7SyyITWQ9l3Xqww0V+YY0rMt02r9eiGvwwPaU1ugJW7IMVo6r/HXvgbmpOSPyzGyg== +"@rushstack/node-core-library@3.45.0": + version "3.45.0" + resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.0.tgz#8c86b39271b6d84260b1e70db87e1e265b54f620" + integrity sha512-YMuIJl19vQT1+g/OU9mLY6T5ZBT9uDlmeXExDQACpGuxTJW+LHNbk/lRX+eCApQI2eLBlaL4U68r3kZlqwbdmw== dependencies: "@types/node" "12.20.24" colors "~1.2.1" @@ -4709,18 +4735,18 @@ timsort "~0.3.0" z-schema "~5.0.2" -"@rushstack/rig-package@0.3.6": - version "0.3.6" - resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.6.tgz#a57b53db59106fb93bcda36cad4f8602f508ebc6" - integrity sha512-H/uFsAT6cD4JCYrlQXYMZg+wPVECByFoJLGqfGRiTwSS5ngQw9QxnFV2mPG2LrxFUsMjLQ2lsrYr523700XzfA== +"@rushstack/rig-package@0.3.7": + version "0.3.7" + resolved "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.7.tgz#3fa564b1d129d28689dd4309502792b15e84bf81" + integrity sha512-pzMsTSeTC8IiZ6EJLr53gGMvhT4oLWH+hxD7907cHyWuIUlEXFtu/2pK25vUQT13nKp5DJCWxXyYoGRk/h6rtA== dependencies: resolve "~1.17.0" strip-json-comments "~3.1.1" -"@rushstack/ts-command-line@4.10.5": - version "4.10.5" - resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.5.tgz#a31a44ddd24fe3a594e4ad91c22f3ea7668b43a9" - integrity sha512-5fVlTDbKsJ5WyT6L7NrnOlLG3uoITKxoqTPP2j0QZEi95kPbVT4+VPZaXXDJtkrao9qrIyig8pLK9WABY1bb3w== +"@rushstack/ts-command-line@4.10.6": + version "4.10.6" + resolved "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.6.tgz#5669e481e4339ceb4e1428183eb0937d3bc3841b" + integrity sha512-Y3GkUag39sTIlukDg9mUp8MCHrrlJ27POrBNRQGc/uF+VVgX8M7zMzHch5zP6O1QVquWgD7Engdpn2piPYaS/g== dependencies: "@types/argparse" "1.0.38" argparse "~1.0.9" @@ -5674,10 +5700,10 @@ "@types/http-proxy" "*" "@types/node" "*" -"@types/http-proxy@*", "@types/http-proxy@^1.17.4", "@types/http-proxy@^1.17.5": - version "1.17.7" - resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f" - integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w== +"@types/http-proxy@*", "@types/http-proxy@^1.17.4", "@types/http-proxy@^1.17.8": + version "1.17.8" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== dependencies: "@types/node" "*" @@ -10549,10 +10575,10 @@ detect-port-alt@^1.1.6: address "^1.0.1" debug "^2.6.0" -devtools-protocol@0.0.901419: - version "0.0.901419" - resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.901419.tgz#79b5459c48fe7e1c5563c02bd72f8fec3e0cebcd" - integrity sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ== +devtools-protocol@0.0.948846: + version "0.0.948846" + resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.948846.tgz#bff47e2d1dba060130fa40ed2e5f78b916ba285f" + integrity sha512-5fGyt9xmMqUl2VI7+rnUkKCiAQIpLns8sfQtTENy5L70ktbNw0Z3TFJ1JoFNYdx/jffz4YXU45VF75wKZD7sZQ== dezalgo@1.0.3, dezalgo@^1.0.0: version "1.0.3" @@ -13599,11 +13625,11 @@ http-proxy-agent@^5.0.0: debug "4" http-proxy-middleware@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" - integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== + version "2.0.2" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.2.tgz#94d7593790aad6b3de48164f13792262f656c332" + integrity sha512-XtmDN5w+vdFTBZaYhdJAbMqn0DP/EhkUaAeo963mojwpKMMbw6nivtFKw07D7DDOH745L5k0VL0P8KRYNEVF/g== dependencies: - "@types/http-proxy" "^1.17.5" + "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" is-glob "^4.0.1" is-plain-obj "^3.0.0" @@ -17388,11 +17414,11 @@ min-indent@^1.0.0: integrity sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY= mini-css-extract-plugin@^2.4.2: - version "2.4.2" - resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.4.2.tgz#b3508191ea479388a4715018c99dd3e6dd40d2d2" - integrity sha512-ZmqShkn79D36uerdED+9qdo1ZYG8C1YsWvXu0UMJxurZnSdgz7gQKO2EGv8T55MhDqG3DYmGtizZNpM/UbTlcA== + version "2.5.2" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.5.2.tgz#b3b9b98320c2c054d92c16f6a94ddfdbbba13755" + integrity sha512-Lwgq9qLNyBK6yNLgzssXnq4r2+mB9Mz3cJWlM8kseysHIvTicFhDNimFgY94jjqlwhNzLPsq8wv4X+vOHtMdYA== dependencies: - schema-utils "^3.1.0" + schema-utils "^4.0.0" minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" @@ -17862,6 +17888,13 @@ node-fetch@2.6.1: resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@2.6.5: + version "2.6.5" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" + integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + dependencies: + whatwg-url "^5.0.0" + node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.5: version "2.6.7" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -19839,10 +19872,10 @@ process@^0.11.10: resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" - integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== +progress@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== prom-client@^13.2.0: version "13.2.0" @@ -20061,23 +20094,23 @@ pupa@^2.0.1: dependencies: escape-goat "^2.0.0" -puppeteer@^10.4.0: - version "10.4.0" - resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-10.4.0.tgz#a6465ff97fda0576c4ac29601406f67e6fea3dc7" - integrity sha512-2cP8mBoqnu5gzAVpbZ0fRaobBWZM8GEUF4I1F6WbgHrKV/rz7SX8PG2wMymZgD0wo0UBlg2FBPNxlF/xlqW6+w== +puppeteer@^13.1.1: + version "13.1.1" + resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-13.1.1.tgz#63771eb744202aa91918c49123f846e1747da121" + integrity sha512-GwdFy1JQ43Hhxj6MraXme+XfCX2CKe18MuwToXTMEAk0txg6vUEgwqBnzErTTqDVZ7sWYrDtDaRCfD2y7ZwgGw== dependencies: - debug "4.3.1" - devtools-protocol "0.0.901419" + debug "4.3.2" + devtools-protocol "0.0.948846" extract-zip "2.0.1" https-proxy-agent "5.0.0" - node-fetch "2.6.1" + node-fetch "2.6.5" pkg-dir "4.2.0" - progress "2.0.1" + progress "2.0.3" proxy-from-env "1.1.0" rimraf "3.0.2" - tar-fs "2.0.0" - unbzip2-stream "1.3.3" - ws "7.4.6" + tar-fs "2.1.1" + unbzip2-stream "1.4.3" + ws "8.2.3" q@^1.1.2, q@^1.5.1: version "1.5.1" @@ -20218,13 +20251,23 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" -rc-progress@3.1.4: - version "3.1.4" - resolved "https://registry.npmjs.org/rc-progress/-/rc-progress-3.1.4.tgz#66040d0fae7d8ced2b38588378eccb2864bad615" - integrity sha512-XBAif08eunHssGeIdxMXOmRQRULdHaDdIFENQ578CMb4dyewahmmfJRyab+hw4KH4XssEzzYOkAInTLS7JJG+Q== +rc-progress@3.2.4: + version "3.2.4" + resolved "https://registry.npmjs.org/rc-progress/-/rc-progress-3.2.4.tgz#4036acdae2566438545bc4df2203248babaf7549" + integrity sha512-M9WWutRaoVkPUPIrTpRIDpX0SPSrVHzxHdCRCbeoBFrd9UFWTYNWRlHsruJM5FH1AZI+BwB4wOJUNNylg/uFSw== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.6" + rc-util "^5.16.1" + +rc-util@^5.16.1: + version "5.16.1" + resolved "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz#374db7cb735512f05165ddc3d6b2c61c21b8b4e3" + integrity sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ== + dependencies: + "@babel/runtime" "^7.12.5" + react-is "^16.12.0" + shallowequal "^1.1.0" rc@^1.2.7, rc@^1.2.8: version "1.2.8" @@ -20386,7 +20429,7 @@ react-inspector@^5.1.1: is-dom "^1.0.0" prop-types "^15.0.0" -react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -20451,14 +20494,6 @@ react-router-dom@6.0.0-beta.0: prop-types "^15.7.2" react-router "6.0.0-beta.0" -react-router-dom@^6.0.0-beta.0: - version "6.2.1" - resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz#32ec81829152fbb8a7b045bf593a22eadf019bec" - integrity sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA== - dependencies: - history "^5.2.0" - react-router "6.2.1" - react-router@6.0.0-beta.0: version "6.0.0-beta.0" resolved "https://registry.npmjs.org/react-router/-/react-router-6.0.0-beta.0.tgz#3e11f39b6ded4412c2fed9e4f989dd4c8156724d" @@ -20466,7 +20501,7 @@ react-router@6.0.0-beta.0: dependencies: prop-types "^15.7.2" -react-router@6.2.1, react-router@^6.0.0-beta.0: +react-router@^6.0.0-beta.0: version "6.2.1" resolved "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz#be2a97a6006ce1d9123c28934e604faef51448a3" integrity sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg== @@ -21887,7 +21922,7 @@ shell-quote@^1.7.3: resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== -shelljs@^0.8.3, shelljs@^0.8.4: +shelljs@^0.8.3, shelljs@^0.8.4, shelljs@^0.8.5: version "0.8.5" resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== @@ -21902,12 +21937,12 @@ shellwords@^0.1.1: integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== shx@^0.3.2: - version "0.3.3" - resolved "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz#681a88c7c10db15abe18525349ed474f0f1e7b9f" - integrity sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA== + version "0.3.4" + resolved "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz#74289230b4b663979167f94e1935901406e40f02" + integrity sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g== dependencies: minimist "^1.2.3" - shelljs "^0.8.4" + shelljs "^0.8.5" side-channel@^1.0.4: version "1.0.4" @@ -23065,17 +23100,7 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== -tar-fs@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad" - integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== - dependencies: - chownr "^1.1.1" - mkdirp "^0.5.1" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-fs@^2.1.1: +tar-fs@2.1.1, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -23896,10 +23921,10 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" -unbzip2-stream@1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a" - integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg== +unbzip2-stream@1.4.3: + version "1.4.3" + resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== dependencies: buffer "^5.2.1" through "^2.3.8" @@ -24989,25 +25014,20 @@ ws@7.4.5: resolved "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== -ws@7.4.6: - version "7.4.6" - resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@8.2.3: + version "8.2.3" + resolved "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== -ws@8.3.0, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.4.6, ws@^8.3.0: +ws@8.3.0, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.2.3, ws@^7.3.1, ws@^7.4.6, ws@^8.3.0: version "7.5.6" resolved "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== -ws@^7.2.3, ws@^7.3.1: - version "7.5.0" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz#0033bafea031fb9df041b2026fc72a571ca44691" - integrity sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw== - ws@^8.1.0: - version "8.2.3" - resolved "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + version "8.4.2" + resolved "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b" + integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA== xcase@^2.0.1: version "2.0.1"