diff --git a/.changeset/analytics-millenial-whoop.md b/.changeset/analytics-millenial-whoop.md new file mode 100644 index 0000000000..265e0072ce --- /dev/null +++ b/.changeset/analytics-millenial-whoop.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +Fixed a bug that could cause `navigate` analytics events to be misattributed to the plugin mounted on the root route (e.g. the `home` plugin at `/`) when the route that was navigated to wasn't associated with a routable extension. diff --git a/.changeset/large-experts-poke.md b/.changeset/large-experts-poke.md new file mode 100644 index 0000000000..9f6ca640b6 --- /dev/null +++ b/.changeset/large-experts-poke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-linguist-backend': patch +--- + +Fixed bug in LinguistBackendClient.ts file where if the linguistJsOptions is specified and sent over to the linguist-js package it would get changed (another attribute would be added) causing future entities of the batch to fail with an error diff --git a/.changeset/rude-feet-sparkle.md b/.changeset/rude-feet-sparkle.md new file mode 100644 index 0000000000..fabc83bb0b --- /dev/null +++ b/.changeset/rude-feet-sparkle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-analytics-module-newrelic-browser': patch +--- + +Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-newrelic-browser) for more details! diff --git a/.changeset/ten-otters-appear.md b/.changeset/ten-otters-appear.md new file mode 100644 index 0000000000..4cb3d301ae --- /dev/null +++ b/.changeset/ten-otters-appear.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Fixed bug in Workflow component by passing a prop `templateName` down to Stepper component. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 82a9eb499d..5c957807cf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,91 +4,91 @@ # The last matching pattern takes precedence. # https://help.github.com/articles/about-codeowners/ -* @backstage/maintainers -yarn.lock @backstage/maintainers @backstage-service -*/yarn.lock @backstage/maintainers @backstage-service -/.changeset/*.md -/cypress/src/integration/plugins/techdocs.spec.ts @backstage/techdocs-maintainers -/docs/assets/search @backstage/discoverability-maintainers -/docs/features/search @backstage/discoverability-maintainers -/docs/features/techdocs @backstage/techdocs-maintainers -/docs/plugins/integrating-search-into-plugins.md @backstage/discoverability-maintainers -/packages/cli/src/commands/onboard @backstage/sharks -/packages/techdocs-cli @backstage/techdocs-maintainers -/packages/techdocs-cli-embedded-app @backstage/techdocs-maintainers -/plugins/adr @backstage/maintainers @kuangp -/plugins/adr-* @backstage/maintainers @kuangp -/plugins/allure @backstage/maintainers @deepak-bhardwaj-ps -/plugins/apache-airflow @backstage/maintainers @cmpadden -/plugins/api-docs @backstage/maintainers @backstage/sda-se-reviewers -/plugins/azure-devops @backstage/maintainers @marleypowell @awanlin -/plugins/azure-devops-backend @backstage/maintainers @marleypowell @awanlin -/plugins/azure-devops-common @backstage/maintainers @marleypowell @awanlin -/plugins/bitbucket-cloud-common @backstage/maintainers @pjungermann -/plugins/bitrise @backstage/maintainers @backstage/sda-se-reviewers -/plugins/catalog @backstage/maintainers @backstage/catalog-maintainers -/plugins/catalog-* @backstage/maintainers @backstage/catalog-maintainers -/plugins/catalog-backend-module-aws @backstage/maintainers @backstage/catalog-maintainers @pjungermann -/plugins/catalog-backend-module-bitbucket-cloud @backstage/maintainers @backstage/catalog-maintainers @pjungermann -/plugins/catalog-backend-module-msgraph @backstage/maintainers @backstage/catalog-maintainers @pjungermann -/plugins/catalog-backend-module-puppetdb @backstage/maintainers @backstage/catalog-maintainers @tdabasinskas -/plugins/catalog-graph @backstage/maintainers @backstage/catalog-maintainers @backstage/sda-se-reviewers -/plugins/circleci @backstage/maintainers @adamdmharvey -/plugins/cloudbuild @backstage/maintainers @trivago/ebarrios -/plugins/code-coverage @backstage/maintainers @alde @nissayeva -/plugins/code-coverage-backend @backstage/maintainers @alde @nissayeva -/plugins/cost-insights @backstage/maintainers @backstage/silver-lining -/plugins/cost-insights-* @backstage/maintainers @backstage/silver-lining -/plugins/devtools @backstage/maintainers @awanlin -/plugins/devtools-backend @backstage/maintainers @awanlin -/plugins/devtools-common @backstage/maintainers @awanlin -/plugins/entity-feedback @backstage/maintainers @kuangp -/plugins/entity-feedback-* @backstage/maintainers @kuangp -/plugins/events-backend @backstage/maintainers @pjungermann -/plugins/events-backend-module-aws-sqs @backstage/maintainers @pjungermann -/plugins/events-backend-module-azure @backstage/maintainers @pjungermann -/plugins/events-backend-module-bitbucket-cloud @backstage/maintainers @pjungermann -/plugins/events-backend-module-gerrit @backstage/maintainers @pjungermann -/plugins/events-backend-module-github @backstage/maintainers @pjungermann -/plugins/events-backend-module-gitlab @backstage/maintainers @pjungermann -/plugins/events-backend-test-utils @backstage/maintainers @pjungermann -/plugins/events-node @backstage/maintainers @pjungermann -/plugins/explore @backstage/maintainers @backstage/sda-se-reviewers -/plugins/explore-react @backstage/maintainers @backstage/sda-se-reviewers -/plugins/fossa @backstage/maintainers @backstage/sda-se-reviewers -/plugins/gcalendar @backstage/maintainers @szubster @ptychu @kielosz @alexrybch -/plugins/git-release-manager @backstage/maintainers @erikengervall -/plugins/home @backstage/discoverability-maintainers -/plugins/home-* @backstage/discoverability-maintainers -/plugins/ilert @backstage/maintainers @yacut -/plugins/jenkins @backstage/maintainers @timja -/plugins/jenkins-backend @backstage/maintainers @timja -/plugins/kafka @backstage/maintainers @nirga @andrewthauer -/plugins/kafka-backend @backstage/maintainers @nirga @andrewthauer -/plugins/kubernetes @backstage/maintainers @backstage/kubernetes-maintainers -/plugins/kubernetes-* @backstage/maintainers @backstage/kubernetes-maintainers -/plugins/linguist @backstage/maintainers @awanlin -/plugins/linguist-backend @backstage/maintainers @awanlin -/plugins/linguist-common @backstage/maintainers @awanlin -/plugins/microsoft-calendar @backstage/maintainers @abhay-soni-developer @NishkarshRaj -/plugins/newrelic-dashboard @backstage/maintainers @mufaddal7 -/plugins/permission-* @backstage/permission-maintainers -/plugins/playlist @backstage/maintainers @kuangp -/plugins/playlist-* @backstage/maintainers @kuangp -/plugins/puppetdb @backstage/maintainers @tdabasinskas -/plugins/rollbar @backstage/maintainers @andrewthauer -/plugins/rollbar-backend @backstage/maintainers @andrewthauer -/plugins/scaffolder-backend-module-rails @backstage/maintainers @angeliski -/plugins/scaffolder-backend-module-yeoman @backstage/maintainers @pawelmitka -/plugins/search @backstage/discoverability-maintainers -/plugins/search-* @backstage/discoverability-maintainers -/plugins/sonarqube @backstage/maintainers @backstage/sda-se-reviewers -/plugins/stack-overflow @backstage/discoverability-maintainers -/plugins/stack-overflow-backend @backstage/discoverability-maintainers -/plugins/techdocs @backstage/techdocs-maintainers -/plugins/techdocs-* @backstage/techdocs-maintainers -/plugins/user-settings-backend @backstage/maintainers @backstage/sda-se-reviewers -/tech-insights-backend @backstage/maintainers @xantier @iain-b -/tech-insights-backend-module-jsonfc @backstage/maintainers @xantier @iain-b -/tech-insights-tech-insights-common @backstage/maintainers @xantier @iain-b -/tech-insights-tech-insights-node @backstage/maintainers @xantier @iain-b +* @backstage/maintainers +*/yarn.lock @backstage/maintainers @backstage-service +/cypress/src/integration/plugins/techdocs.spec.ts @backstage/techdocs-maintainers +/docs/assets/search @backstage/discoverability-maintainers +/docs/features/search @backstage/discoverability-maintainers +/docs/features/techdocs @backstage/techdocs-maintainers +/docs/plugins/integrating-search-into-plugins.md @backstage/discoverability-maintainers +/packages/cli/src/commands/onboard @backstage/sharks +/packages/techdocs-cli @backstage/techdocs-maintainers +/packages/techdocs-cli-embedded-app @backstage/techdocs-maintainers +/plugins/adr @backstage/maintainers @kuangp +/plugins/adr-* @backstage/maintainers @kuangp +/plugins/allure @backstage/maintainers @deepak-bhardwaj-ps +/plugins/analytics-module-newrelic-browser @backstage/maintainers @jmezach +/plugins/apache-airflow @backstage/maintainers @cmpadden +/plugins/api-docs @backstage/maintainers @backstage/sda-se-reviewers +/plugins/azure-devops @backstage/maintainers @marleypowell @awanlin +/plugins/azure-devops-backend @backstage/maintainers @marleypowell @awanlin +/plugins/azure-devops-common @backstage/maintainers @marleypowell @awanlin +/plugins/bitbucket-cloud-common @backstage/maintainers @pjungermann +/plugins/bitrise @backstage/maintainers @backstage/sda-se-reviewers +/plugins/catalog @backstage/maintainers @backstage/catalog-maintainers +/plugins/catalog-* @backstage/maintainers @backstage/catalog-maintainers +/plugins/catalog-backend-module-aws @backstage/maintainers @backstage/catalog-maintainers @pjungermann +/plugins/catalog-backend-module-bitbucket-cloud @backstage/maintainers @backstage/catalog-maintainers @pjungermann +/plugins/catalog-backend-module-msgraph @backstage/maintainers @backstage/catalog-maintainers @pjungermann +/plugins/catalog-backend-module-puppetdb @backstage/maintainers @backstage/catalog-maintainers @tdabasinskas +/plugins/catalog-graph @backstage/maintainers @backstage/catalog-maintainers @backstage/sda-se-reviewers +/plugins/circleci @backstage/maintainers @adamdmharvey +/plugins/cloudbuild @backstage/maintainers @trivago/ebarrios +/plugins/code-coverage @backstage/maintainers @alde @nissayeva +/plugins/code-coverage-backend @backstage/maintainers @alde @nissayeva +/plugins/cost-insights @backstage/maintainers @backstage/silver-lining +/plugins/cost-insights-* @backstage/maintainers @backstage/silver-lining +/plugins/devtools @backstage/maintainers @awanlin +/plugins/devtools-backend @backstage/maintainers @awanlin +/plugins/devtools-common @backstage/maintainers @awanlin +/plugins/entity-feedback @backstage/maintainers @kuangp +/plugins/entity-feedback-* @backstage/maintainers @kuangp +/plugins/events-backend @backstage/maintainers @pjungermann +/plugins/events-backend-module-aws-sqs @backstage/maintainers @pjungermann +/plugins/events-backend-module-azure @backstage/maintainers @pjungermann +/plugins/events-backend-module-bitbucket-cloud @backstage/maintainers @pjungermann +/plugins/events-backend-module-gerrit @backstage/maintainers @pjungermann +/plugins/events-backend-module-github @backstage/maintainers @pjungermann +/plugins/events-backend-module-gitlab @backstage/maintainers @pjungermann +/plugins/events-backend-test-utils @backstage/maintainers @pjungermann +/plugins/events-node @backstage/maintainers @pjungermann +/plugins/explore @backstage/maintainers @backstage/sda-se-reviewers +/plugins/explore-react @backstage/maintainers @backstage/sda-se-reviewers +/plugins/fossa @backstage/maintainers @backstage/sda-se-reviewers +/plugins/gcalendar @backstage/maintainers @szubster @ptychu @kielosz @alexrybch +/plugins/git-release-manager @backstage/maintainers @erikengervall +/plugins/home @backstage/discoverability-maintainers +/plugins/home-* @backstage/discoverability-maintainers +/plugins/ilert @backstage/maintainers @yacut +/plugins/jenkins @backstage/maintainers @timja +/plugins/jenkins-backend @backstage/maintainers @timja +/plugins/kafka @backstage/maintainers @nirga @andrewthauer +/plugins/kafka-backend @backstage/maintainers @nirga @andrewthauer +/plugins/kubernetes @backstage/maintainers @backstage/kubernetes-maintainers +/plugins/kubernetes-* @backstage/maintainers @backstage/kubernetes-maintainers +/plugins/linguist @backstage/maintainers @awanlin +/plugins/linguist-backend @backstage/maintainers @awanlin +/plugins/linguist-common @backstage/maintainers @awanlin +/plugins/microsoft-calendar @backstage/maintainers @abhay-soni-developer @NishkarshRaj +/plugins/newrelic-dashboard @backstage/maintainers @mufaddal7 +/plugins/permission-* @backstage/permission-maintainers +/plugins/playlist @backstage/maintainers @kuangp +/plugins/playlist-* @backstage/maintainers @kuangp +/plugins/puppetdb @backstage/maintainers @tdabasinskas +/plugins/rollbar @backstage/maintainers @andrewthauer +/plugins/rollbar-backend @backstage/maintainers @andrewthauer +/plugins/scaffolder-backend-module-rails @backstage/maintainers @angeliski +/plugins/scaffolder-backend-module-yeoman @backstage/maintainers @pawelmitka +/plugins/search @backstage/discoverability-maintainers +/plugins/search-* @backstage/discoverability-maintainers +/plugins/sonarqube @backstage/maintainers @backstage/sda-se-reviewers +/plugins/stack-overflow @backstage/discoverability-maintainers +/plugins/stack-overflow-backend @backstage/discoverability-maintainers +/plugins/techdocs @backstage/techdocs-maintainers +/plugins/techdocs-* @backstage/techdocs-maintainers +/plugins/user-settings-backend @backstage/maintainers @backstage/sda-se-reviewers +/tech-insights-backend @backstage/maintainers @xantier @iain-b +/tech-insights-backend-module-jsonfc @backstage/maintainers @xantier @iain-b +/tech-insights-tech-insights-common @backstage/maintainers @xantier @iain-b +/tech-insights-tech-insights-node @backstage/maintainers @xantier @iain-b +yarn.lock @backstage/maintainers @backstage-service diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index efd6186405..ed09c73c91 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -213,6 +213,7 @@ middleware minikube Minikube Minio +misattributed misconfiguration misconfigured mkdocs diff --git a/docs/plugins/analytics.md b/docs/plugins/analytics.md index 3e782b4460..c8f1c9b006 100644 --- a/docs/plugins/analytics.md +++ b/docs/plugins/analytics.md @@ -34,10 +34,11 @@ is a concrete implementation of [AnalyticsApi][analytics-api-type], common integrations are packaged and provided as plugins. Find your analytics tool of choice below. -| Analytics Tool | Support Status | -| ------------------------- | -------------- | -| [Google Analytics][ga] | Yes ✅ | -| [Google Analytics 4][ga4] | Yes ✅ | +| Analytics Tool | Support Status | +| ------------------------------------- | -------------- | +| [Google Analytics][ga] | Yes ✅ | +| [Google Analytics 4][ga4] | Yes ✅ | +| [New Relic Browser][newrelic-browser] | Community ✅ | To suggest an integration, please [open an issue][add-tool] for the analytics tool your organization uses. Or jump to [Writing Integrations][int-howto] to @@ -45,6 +46,7 @@ learn how to contribute the integration yourself! [ga]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md [ga4]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga4/README.md +[newrelic-browser]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-newrelic-browser/README.md [add-tool]: https://github.com/backstage/backstage/issues/new?assignees=&labels=plugin&template=plugin_template.md&title=%5BAnalytics+Module%5D+THE+ANALYTICS+TOOL+TO+INTEGRATE [int-howto]: #writing-integrations [analytics-api-type]: https://backstage.io/docs/reference/core-plugin-api.analyticsapi diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index e78626e37c..23438762cc 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -177,7 +177,7 @@ module.exports = { position: 'left', }, { - to: 'docs/releases/v1.15.0', + to: 'docs/releases/v1.16.0', label: 'Releases', position: 'left', }, diff --git a/packages/core-app-api/src/routing/RouteTracker.test.tsx b/packages/core-app-api/src/routing/RouteTracker.test.tsx index 6bf58a117e..25d5cfbcfb 100644 --- a/packages/core-app-api/src/routing/RouteTracker.test.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.test.tsx @@ -25,30 +25,46 @@ import { createPlugin, createRouteRef, } from '@backstage/core-plugin-api'; +import { MATCH_ALL_ROUTE } from './collectors'; describe('RouteTracker', () => { + const routeRef0 = createRouteRef({ + id: 'home:root', + }); const routeRef1 = createRouteRef({ id: 'route1', }); const routeRef2 = createRouteRef({ id: 'route2', }); + const plugin0 = createPlugin({ id: 'home' }); const plugin1 = createPlugin({ id: 'plugin1' }); + const plugin2 = createPlugin({ id: 'plugin2' }); const routeObjects: BackstageRouteObject[] = [ + { + path: '', + element:
home page
, + routeRefs: new Set([routeRef0]), + plugins: new Set([plugin0]), + caseSensitive: false, + children: [MATCH_ALL_ROUTE], + }, { path: '/path/:p1/:p2', element: go, routeRefs: new Set([routeRef1]), plugins: new Set([plugin1]), caseSensitive: false, + children: [MATCH_ALL_ROUTE], }, { path: '/path2/:param', element:
hi there
, routeRefs: new Set([routeRef2]), - plugins: new Set(), + plugins: new Set([plugin2]), caseSensitive: false, + children: [MATCH_ALL_ROUTE], }, ]; @@ -92,8 +108,8 @@ describe('RouteTracker', () => { - {routeObjects.map(({ routeRefs, ...props }) => ( - + {routeObjects.map(({ path, element }) => ( + ))} @@ -109,11 +125,110 @@ describe('RouteTracker', () => { }, context: { extension: 'App', - pluginId: 'root', + pluginId: 'plugin2', routeRef: 'route2', }, subject: '/path2/hello', value: undefined, }); }); + + it('should capture path query and hash', async () => { + render( + + + + + , + ); + + expect(mockedAnalytics.captureEvent).toHaveBeenCalledWith({ + action: 'navigate', + attributes: { + p1: 'foo', + p2: 'bar', + }, + context: { + extension: 'App', + pluginId: 'plugin1', + routeRef: 'route1', + }, + subject: '/path/foo/bar?q=1#header-1', + value: undefined, + }); + }); + + it('should match the root path and send relevant context', async () => { + render( + + + + + , + ); + + expect(mockedAnalytics.captureEvent).toHaveBeenCalledWith({ + action: 'navigate', + attributes: {}, + context: { + extension: 'App', + pluginId: 'home', + routeRef: 'home:root', + }, + subject: '/', + value: undefined, + }); + }); + + it('should return default context when it would have otherwise matched on the root path', async () => { + render( + + + + + Non-extension} + /> + + + , + ); + + expect(mockedAnalytics.captureEvent).toHaveBeenCalledWith({ + action: 'navigate', + attributes: {}, + context: { + extension: 'App', + pluginId: 'root', + routeRef: 'unknown', + }, + subject: '/not-routable-extension', + value: undefined, + }); + }); + + it('should return parent route context on navigating to a sub-route', async () => { + render( + + + + + , + ); + + expect(mockedAnalytics.captureEvent).toHaveBeenCalledWith({ + action: 'navigate', + attributes: { + param: 'param-value', + }, + context: { + extension: 'App', + pluginId: 'plugin2', + routeRef: 'route2', + }, + subject: '/path2/param-value/sub-route', + value: undefined, + }); + }); }); diff --git a/packages/core-app-api/src/routing/RouteTracker.tsx b/packages/core-app-api/src/routing/RouteTracker.tsx index f1910728e3..69903268ac 100644 --- a/packages/core-app-api/src/routing/RouteTracker.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.tsx @@ -38,12 +38,11 @@ const getExtensionContext = ( const matches = matchRoutes(routes, { pathname }); // Of the matching routes, get the last (e.g. most specific) instance of - // the BackstageRouteObject. - + // the BackstageRouteObject that contains a routeRef. Filtering by routeRef + // ensures subRouteRefs are aligned to their parent routes' context. const routeMatch = matches ?.filter(match => match?.route.routeRefs?.size > 0) .pop(); - const routeObject = routeMatch?.route; // If there is no route object, then allow inheritance of default context. @@ -51,6 +50,12 @@ const getExtensionContext = ( return undefined; } + // If the matched route is the root route (no path), and the pathname is + // not the path of the homepage, then inherit from the default context. + if (routeObject.path === '' && pathname !== '/') { + return undefined; + } + // If there is a single route ref, use it. let routeRef: RouteRef | undefined; if (routeObject.routeRefs.size === 1) { @@ -66,7 +71,7 @@ const getExtensionContext = ( const params = Object.entries( routeMatch?.params || {}, ).reduce((acc, [key, value]) => { - if (value !== undefined) { + if (value !== undefined && key !== '*') { acc[key] = value; } return acc; diff --git a/plugins/analytics-module-newrelic-browser/.eslintrc.js b/plugins/analytics-module-newrelic-browser/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/analytics-module-newrelic-browser/README.md b/plugins/analytics-module-newrelic-browser/README.md new file mode 100644 index 0000000000..2fe3956d2d --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/README.md @@ -0,0 +1,135 @@ +# Analytics Module: New Relic Browser + +This plugin provides an opinionated implementation of the Backstage Analytics API for New Relic Browser. Once installed and configured, analytics events will be sent to New Relic as your users navigate and use your Backstage instance. + +This plugin contains no other functionality. + +## Installation + +1. Install the plugin package in your Backstage app: + +```sh +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-analytics-module-newrelic-browser +``` + +2. Wire up the API implementation to your App: + +```tsx +// packages/app/src/apis.ts +import { + analyticsApiRef, + configApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { NewRelicBrowser } from '@backstage/plugin-analytics-module-newrelic-browser'; + +export const apis: AnyApiFactory[] = [ + // Instantiate and register the New Relic Browser API Implementation. + createApiFactory({ + api: analyticsApiRef, + deps: { configApi: configApiRef, identityApi: identityApiRef }, + factory: ({ configApi, identityApi }) => + NewRelicBrowser.fromConfig(configApi, { + identityApi, + }), + }), +]; +``` + +3. Configure the plugin in your `app-config.yaml`: + +The following is the minimum configuration required to start sending analytics +events to New Relic Browser. You find this information when creating a new application +in New Relic Browser using the Copy/Paste method. + +```yaml +# app-config.yaml +app: + analytics: + newRelic: + endpoint: 'bam.nr-data.net', + accountId: '1234567' + applicationId: '987654321' + licenseKey: 'NRJS-12a3456bc78de9123f4' +``` + +> Note: Depending on New Relic's data center you are using you'll want to change the `endpoint` to `bam.eu01.nr-data.net` for the EU data center. Refer to [this document](https://docs.newrelic.com/docs/new-relic-solutions/get-started/networks/#data-ingest) for available endpoints. + +## Configuration + +By default the distributed tracing and cookies features are disabled. You can enable them by adding the following to your `app-config.yaml`: + +```yaml +# app-config.yaml +app: + analytics: + newRelic: + ... + distributedTracing: true + cookiesEnabled: true +``` + +### User IDs + +This plugin supports sending user context to New Relic Browser by providing a User ID. This requires instantiating the `NewRelicBrowser` instance with an `identityApi` instance passed to it, but this is optional. If omitted the plugin will not send user context to New Relic Browser. + +By default the user ID is calculated as a SHA-256 hash of the current user's `userEntityRef` as returned by the `identityApi`. To set a +different value, provide a `userIdTransform` function alongside `identityApi` when you instantiate `NewRelicBrowser`. This function will be passed the `userEntityRef` as an argument and should resolve to the value you wish to set as the user ID. For example: + +```typescript +import { + analyticsApiRef, + configApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { GoogleAnalytics } from '@backstage/plugin-analytics-module-newrelic-browser'; + +export const apis: AnyApiFactory[] = [ + createApiFactory({ + api: analyticsApiRef, + deps: { configApi: configApiRef, identityApi: identityApiRef }, + factory: ({ configApi, identityApi }) => + NewRelicBrowser.fromConfig(configApi, { + identityApi, + userIdTransform: async (userEntityRef: string): Promise => { + return customHashingFunction(userEntityRef); + }, + }), + }), +]; +``` + +## Development + +If you would like to contribute improvements to this plugin, the easiest way to +make and test changes is to do the following: + +1. Clone the main Backstage monorepo `git clone git@github.com:backstage/backstage.git` +2. Install all dependencies `yarn install` +3. If one does not exist, create an `app-config.local.yaml` file in the root of + the monorepo and add config for this plugin (see below) +4. Enter this plugin's working directory: `cd plugins/analytics-provider-newrelic-browser` +5. Start the plugin in isolation: `yarn start` +6. Navigate to the playground page at `http://localhost:3000/newrelic` +7. Open the web console to see events fire when you navigate or when you + interact with instrumented components. + +Code for the isolated version of the plugin can be found inside the [/dev](./dev) +directory. Changes to the plugin are hot-reloaded. + +#### Recommended Dev Config + +Paste this into your `app-config.local.yaml` while developing this plugin: + +```yaml +app: + analytics: + newRelic: + accountId: '1234567' + applicationId: '987654321' + licenseKey: 'NRJS-12a3456bc78de9123f4' + distributedTracingEnabled: true + cookiesEnabled: true + useEuEndpoint: false +``` diff --git a/plugins/analytics-module-newrelic-browser/api-report.md b/plugins/analytics-module-newrelic-browser/api-report.md new file mode 100644 index 0000000000..7556bae317 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/api-report.md @@ -0,0 +1,28 @@ +## API Report File for "@backstage/plugin-analytics-module-newrelic-browser" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AnalyticsApi } from '@backstage/core-plugin-api'; +import { AnalyticsEvent } from '@backstage/core-plugin-api'; +import { Config } from '@backstage/config'; +import { IdentityApi } from '@backstage/core-plugin-api'; + +// @public +export class NewRelicBrowser implements AnalyticsApi { + // (undocumented) + captureEvent(event: AnalyticsEvent): void; + // (undocumented) + static fromConfig( + config: Config, + options: { + identityApi?: IdentityApi; + userIdTransform?: + | 'sha-256' + | ((userEntityRef: string) => Promise); + }, + ): NewRelicBrowser; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/analytics-module-newrelic-browser/config.d.ts b/plugins/analytics-module-newrelic-browser/config.d.ts new file mode 100644 index 0000000000..e653f3af7d --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/config.d.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2023 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 interface Config { + app: { + analytics?: { + newRelic: { + /** + * Data ingestion endpoint to use, either bam.eu01.nr-data.net (EU) or bam.nr-data.net (US) + * @visibility frontend + */ + endpoint: 'bam.eu01.nr-data.net' | 'bam.nr-data.net'; + + /** + * New Relic Account ID, e.g. 1234567 + * @visibility frontend + */ + accountId: string; + + /** + * New Relic Application ID, e.g. 987654321 + * @visibility frontend + */ + applicationId: string; + + /** + * New Relic License Key, e.g. NRJS-12a3456bc78de9123f4 + * @visibility frontend + */ + licenseKey: string; + + /** + * Whether to enabled distributed tracing, defaults to false + * @visibility frontend + */ + distributedTracingEnabled: boolean; + + /** + * Whether to enabled tracing of cookies, defaults to false + * @visibility frontend + */ + cookiesEnabled: boolean; + }; + }; + }; +} diff --git a/plugins/analytics-module-newrelic-browser/dev/Playground.tsx b/plugins/analytics-module-newrelic-browser/dev/Playground.tsx new file mode 100644 index 0000000000..cf21aadacc --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/dev/Playground.tsx @@ -0,0 +1,26 @@ +/* + * Copyright 2021 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. + */ + +import React from 'react'; +import { Link } from '@backstage/core-components'; + +export const Playground = () => { + return ( + <> + Click Here + + ); +}; diff --git a/plugins/analytics-module-newrelic-browser/dev/index.tsx b/plugins/analytics-module-newrelic-browser/dev/index.tsx new file mode 100644 index 0000000000..15caacfe61 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/dev/index.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2023 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. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { + analyticsApiRef, + configApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { Playground } from './Playground'; +import { NewRelicBrowser } from '../src'; + +createDevApp() + .registerApi({ + api: analyticsApiRef, + deps: { configApi: configApiRef, identityApi: identityApiRef }, + factory: ({ configApi, identityApi }) => + NewRelicBrowser.fromConfig(configApi, { + identityApi, + }), + }) + .addPage({ + path: '/newrelic', + title: 'New Relic Playground', + element: , + }) + .render(); diff --git a/plugins/analytics-module-newrelic-browser/package.json b/plugins/analytics-module-newrelic-browser/package.json new file mode 100644 index 0000000000..f9243817f4 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/package.json @@ -0,0 +1,50 @@ +{ + "name": "@backstage/plugin-analytics-module-newrelic-browser", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/config": "workspace:^", + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@newrelic/browser-agent": "^1.236.0", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/node": "*", + "msw": "^1.0.0" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts" +} diff --git a/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts new file mode 100644 index 0000000000..f2f35b5765 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -0,0 +1,176 @@ +/* + * Copyright 2023 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. + */ +import { Config } from '@backstage/config'; +import { + AnalyticsApi, + IdentityApi, + AnalyticsEvent, +} from '@backstage/core-plugin-api'; +import { BrowserAgent } from '@newrelic/browser-agent/loaders/browser-agent'; +import type { setAPI } from '@newrelic/browser-agent/loaders/api/api'; + +type NewRelicAPI = ReturnType; + +type NewRelicBrowserOptions = { + endpoint: string; + accountId: string; + applicationId: string; + licenseKey: string; + distributedTracingEnabled: boolean; + cookiesEnabled: boolean; +}; + +/** + * New Relic Browser API provider for the Backstage Analytics API. + * @public + */ +export class NewRelicBrowser implements AnalyticsApi { + private readonly agent: NewRelicAPI; + + private constructor( + options: NewRelicBrowserOptions, + identityApi?: IdentityApi, + userIdTransform?: 'sha-256' | ((userEntityRef: string) => Promise), + ) { + // Configure the New Relic Browser agent + const agentOptions = { + init: { + distributed_tracing: { + enabled: options.distributedTracingEnabled, + }, + privacy: { + cookies_enabled: options.cookiesEnabled, + }, + ajax: { + deny_list: [options.endpoint], + }, + }, + info: { + beacon: options.endpoint, + errorBeacon: options.endpoint, + licenseKey: options.licenseKey, + applicationID: options.applicationId, + sa: 1, + }, + loader_config: { + accountID: options.accountId, + trustKey: options.accountId, + agentID: options.applicationId, + licenseKey: options.licenseKey, + applicationID: options.applicationId, + }, + }; + + // Initialize the agent + this.agent = new BrowserAgent(agentOptions) as unknown as NewRelicAPI; + + // Check if identity has been provided + if (identityApi) { + identityApi.getBackstageIdentity().then(identity => { + if (typeof userIdTransform === 'function') { + userIdTransform(identity.userEntityRef).then(userId => { + this.agent.setUserId(userId); + }); + } else { + this.hash(identity.userEntityRef).then(userId => { + this.agent.setUserId(userId); + }); + } + }); + } + } + + static fromConfig( + config: Config, + options: { + identityApi?: IdentityApi; + userIdTransform?: + | 'sha-256' + | ((userEntityRef: string) => Promise); + }, + ) { + const newRelicBrowserConfig = config.getConfig('app.analytics.newRelic'); + const browserOptions: NewRelicBrowserOptions = { + endpoint: newRelicBrowserConfig.getString('endpoint'), + accountId: newRelicBrowserConfig.getString('accountId'), + applicationId: newRelicBrowserConfig.getString('applicationId'), + licenseKey: newRelicBrowserConfig.getString('licenseKey'), + distributedTracingEnabled: + newRelicBrowserConfig.getOptionalBoolean('distributedTracingEnabled') ?? + false, + cookiesEnabled: + newRelicBrowserConfig.getOptionalBoolean('cookiesEnabled') ?? false, + }; + return new NewRelicBrowser( + browserOptions, + options.identityApi, + options.userIdTransform, + ); + } + + captureEvent(event: AnalyticsEvent) { + const { context, action, subject, value, attributes } = event; + if (action === 'navigate' && context.extension === 'App') { + const interaction = this.agent.interaction(); + interaction.setName(subject); + if (value) { + interaction.setAttribute('value', value); + } + Object.keys(context).forEach(key => { + if (context[key]) { + interaction.setAttribute(`context.${key}`, context[key]); + } + }); + if (attributes) { + Object.keys(attributes).forEach(key => { + interaction.setAttribute(`attributes.${key}`, attributes[key]); + }); + } + } else { + const customAttributes: { + [x: string]: string | number | boolean | undefined; + } = {}; + if (value) { + customAttributes.value = value; + } + Object.keys(context).forEach(key => { + if (context[key]) { + customAttributes[`context.${key}`] = context[key]; + } + }); + if (attributes) { + Object.keys(attributes).forEach(key => { + customAttributes[`attributes.${key}`] = attributes[key]; + }); + } + + this.agent.addPageAction(action, customAttributes); + } + } + + /** + * Simple hash function; relies on web cryptography + the sha-256 algorithm. + * @param value value to be hashed + */ + private async hash(value: string): Promise { + const digest = await window.crypto.subtle.digest( + 'sha-256', + new TextEncoder().encode(value), + ); + const hashArray = Array.from(new Uint8Array(digest)); + return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + } +} diff --git a/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/index.ts b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/index.ts new file mode 100644 index 0000000000..6300381cfd --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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 { NewRelicBrowser } from './NewRelicBrowser'; diff --git a/plugins/analytics-module-newrelic-browser/src/index.ts b/plugins/analytics-module-newrelic-browser/src/index.ts new file mode 100644 index 0000000000..0adf114679 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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 './apis/implementations/AnalyticsApi'; diff --git a/plugins/analytics-module-newrelic-browser/src/setupTests.ts b/plugins/analytics-module-newrelic-browser/src/setupTests.ts new file mode 100644 index 0000000000..865308e634 --- /dev/null +++ b/plugins/analytics-module-newrelic-browser/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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. + */ +import '@testing-library/jest-dom'; diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 0d1b4181d8..aab9e81721 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -27,8 +27,8 @@ "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", - "@backstage/types": "workspace:^", "@backstage/theme": "workspace:^", + "@backstage/types": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", diff --git a/plugins/linguist-backend/src/api/LinguistBackendClient.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.ts index 53da0bee22..1be4a7d288 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendClient.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.ts @@ -261,7 +261,7 @@ export class LinguistBackendClient implements LinguistBackendApi { /** @internal */ async getLinguistResults(dir: string): Promise { - const results = await linguist(dir, this.linguistJsOptions); + const results = await linguist(dir, { ...this.linguistJsOptions }); return results; } } diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx index f6ff12e3a3..228f5cefd9 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx @@ -102,7 +102,7 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { noPadding titleTypographyProps={{ component: 'h2' }} > - + )} diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 61d8548dc0..61718c7a2f 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -10177,11 +10177,11 @@ __metadata: linkType: hard "semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.6.0": - version: 5.7.1 - resolution: "semver@npm:5.7.1" + version: 5.7.2 + resolution: "semver@npm:5.7.2" bin: - semver: ./bin/semver - checksum: 57fd0acfd0bac382ee87cd52cd0aaa5af086a7dc8d60379dfe65fea491fb2489b6016400813930ecd61fd0952dae75c115287a1b16c234b1550887117744dfaf + semver: bin/semver + checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 05be39bde2..4b55c6d0a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -102,8 +102,8 @@ __metadata: linkType: hard "@apollo/client@npm:^3.0.0": - version: 3.7.16 - resolution: "@apollo/client@npm:3.7.16" + version: 3.7.17 + resolution: "@apollo/client@npm:3.7.17" dependencies: "@graphql-typed-document-node/core": ^3.1.1 "@wry/context": ^0.7.0 @@ -133,7 +133,7 @@ __metadata: optional: true subscriptions-transport-ws: optional: true - checksum: 6c0035634a15a92d547f06d9a943e9025bef1929775f3c53eea22bcee86aa0916722a196bb9bed6a51d27a2b6ba587ef00bed3831a29be89ced9b8b63f45cbe7 + checksum: d25e955f3c409885185405ca5876cb74538becafa202257a27483c07d7faa9ce83b34d4cab4b7fd9ad217f80d768e651881292c406dbbca221c91013917890d7 languageName: node linkType: hard @@ -199,8 +199,8 @@ __metadata: linkType: hard "@apollo/server@npm:^4.0.0": - version: 4.7.5 - resolution: "@apollo/server@npm:4.7.5" + version: 4.8.1 + resolution: "@apollo/server@npm:4.8.1" dependencies: "@apollo/cache-control-types": ^1.0.3 "@apollo/server-gateway-interface": ^1.1.1 @@ -230,7 +230,7 @@ __metadata: whatwg-mimetype: ^3.0.0 peerDependencies: graphql: ^16.6.0 - checksum: a0b5fd4a7e0750f84d6fb5717921a316f99a2982488146115278847f75cfe620684263f8ed6dbd2517d9a1c943504e70845cc609cb87d942b691c31ad5842cbb + checksum: b59c60b23b90aed9e2f74de1d16f4ac7582f16e2f98d830c85e1339525867786ab17a9295aadf53cdcfdfd0540f81273706e013aae9148ebc3e55e86c820b21c languageName: node linkType: hard @@ -3592,7 +3592,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.1.5, @backstage/catalog-model@^1.4.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.1.5, @backstage/catalog-model@^1.4.0, @backstage/catalog-model@^1.4.1, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -3886,7 +3886,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@^0.13.2, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@^0.13.2, @backstage/core-components@^0.13.3, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: @@ -4010,7 +4010,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-plugin-api@^1.3.0, @backstage/core-plugin-api@^1.5.0, @backstage/core-plugin-api@^1.5.2, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.3.0, @backstage/core-plugin-api@^1.5.0, @backstage/core-plugin-api@^1.5.2, @backstage/core-plugin-api@^1.5.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4414,6 +4414,29 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-newrelic-browser": + version: 0.0.0-use.local + resolution: "@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-newrelic-browser" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@newrelic/browser-agent": ^1.236.0 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + msw: ^1.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-apache-airflow@workspace:^, @backstage/plugin-apache-airflow@workspace:plugins/apache-airflow": version: 0.0.0-use.local resolution: "@backstage/plugin-apache-airflow@workspace:plugins/apache-airflow" @@ -5480,7 +5503,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@^1.2.4, @backstage/plugin-catalog-react@^1.7.0, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@^1.2.4, @backstage/plugin-catalog-react@^1.7.0, @backstage/plugin-catalog-react@^1.8.0, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -9478,7 +9501,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.4.0, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.4.0, @backstage/theme@^0.4.1, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -9835,11 +9858,11 @@ __metadata: linkType: hard "@codemirror/legacy-modes@npm:^6.1.0": - version: 6.3.2 - resolution: "@codemirror/legacy-modes@npm:6.3.2" + version: 6.3.3 + resolution: "@codemirror/legacy-modes@npm:6.3.3" dependencies: "@codemirror/language": ^6.0.0 - checksum: fa5f5477fb9e19267251e2ecd3de8c1a4c2512813555bb60111dce3951f2c3f6080a2985a573b7542534ba1d2c34115f7e39ee23fdf8f6f81db6f8ce447c1efc + checksum: 3cd32b0f011b0a193e0948e5901b625f38aa6d9a8b24344531d6e142eb6fbb3e6cb5969429102044f3d04fbe53c4deaebd9f659c05067a0b18d17766290c9e05 languageName: node linkType: hard @@ -9885,13 +9908,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0": - version: 6.14.0 - resolution: "@codemirror/view@npm:6.14.0" + version: 6.15.3 + resolution: "@codemirror/view@npm:6.15.3" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: f8fbb8e8cf1bc23de8cd64b1e645112d13f72cd2f1609fb9047d616908c2189ff518b89f21484371e7a37ba1804288452558e96488791f0c850f62b8e28dc163 + checksum: 048949b1b493a962904a7f77661a939f7c1893a7381022756a135f5dd8daf667f498be1b81da9c37c0e8de85b078ad987c2f75318385c520ed83c95da6313e95 languageName: node linkType: hard @@ -10232,9 +10255,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/android-arm64@npm:0.18.13" +"@esbuild/android-arm64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/android-arm64@npm:0.18.16" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -10253,9 +10276,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/android-arm@npm:0.18.13" +"@esbuild/android-arm@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/android-arm@npm:0.18.16" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -10267,9 +10290,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/android-x64@npm:0.18.13" +"@esbuild/android-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/android-x64@npm:0.18.16" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -10281,9 +10304,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/darwin-arm64@npm:0.18.13" +"@esbuild/darwin-arm64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/darwin-arm64@npm:0.18.16" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -10295,9 +10318,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/darwin-x64@npm:0.18.13" +"@esbuild/darwin-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/darwin-x64@npm:0.18.16" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -10309,9 +10332,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/freebsd-arm64@npm:0.18.13" +"@esbuild/freebsd-arm64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/freebsd-arm64@npm:0.18.16" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -10323,9 +10346,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/freebsd-x64@npm:0.18.13" +"@esbuild/freebsd-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/freebsd-x64@npm:0.18.16" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -10337,9 +10360,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-arm64@npm:0.18.13" +"@esbuild/linux-arm64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-arm64@npm:0.18.16" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -10351,9 +10374,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-arm@npm:0.18.13" +"@esbuild/linux-arm@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-arm@npm:0.18.16" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -10365,9 +10388,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-ia32@npm:0.18.13" +"@esbuild/linux-ia32@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-ia32@npm:0.18.16" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -10386,9 +10409,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-loong64@npm:0.18.13" +"@esbuild/linux-loong64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-loong64@npm:0.18.16" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -10400,9 +10423,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-mips64el@npm:0.18.13" +"@esbuild/linux-mips64el@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-mips64el@npm:0.18.16" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -10414,9 +10437,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-ppc64@npm:0.18.13" +"@esbuild/linux-ppc64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-ppc64@npm:0.18.16" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -10428,9 +10451,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-riscv64@npm:0.18.13" +"@esbuild/linux-riscv64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-riscv64@npm:0.18.16" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -10442,9 +10465,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-s390x@npm:0.18.13" +"@esbuild/linux-s390x@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-s390x@npm:0.18.16" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -10456,9 +10479,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-x64@npm:0.18.13" +"@esbuild/linux-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/linux-x64@npm:0.18.16" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -10470,9 +10493,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/netbsd-x64@npm:0.18.13" +"@esbuild/netbsd-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/netbsd-x64@npm:0.18.16" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -10484,9 +10507,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/openbsd-x64@npm:0.18.13" +"@esbuild/openbsd-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/openbsd-x64@npm:0.18.16" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -10498,9 +10521,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/sunos-x64@npm:0.18.13" +"@esbuild/sunos-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/sunos-x64@npm:0.18.16" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -10512,9 +10535,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/win32-arm64@npm:0.18.13" +"@esbuild/win32-arm64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/win32-arm64@npm:0.18.16" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -10526,9 +10549,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/win32-ia32@npm:0.18.13" +"@esbuild/win32-ia32@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/win32-ia32@npm:0.18.16" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -10540,9 +10563,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/win32-x64@npm:0.18.13" +"@esbuild/win32-x64@npm:0.18.16": + version: 0.18.16 + resolution: "@esbuild/win32-x64@npm:0.18.16" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -13006,6 +13029,18 @@ __metadata: languageName: node linkType: hard +"@newrelic/browser-agent@npm:^1.236.0": + version: 1.236.0 + resolution: "@newrelic/browser-agent@npm:1.236.0" + dependencies: + core-js: ^3.26.0 + fflate: ^0.7.4 + rrweb: ^2.0.0-alpha.8 + web-vitals: ^3.1.0 + checksum: 79a96c8f8421bed13e0e9eaf08c9bb8ac2785da3199e2304366c5cf98eb976713e393bd26a7efe998837eba5facfe7a54a6d58ba5c948c7ecc8de49e477b5836 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -14117,14 +14152,14 @@ __metadata: linkType: hard "@roadiehq/backstage-plugin-buildkite@npm:^2.0.8": - version: 2.1.12 - resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.12" + version: 2.1.13 + resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.13" dependencies: - "@backstage/catalog-model": ^1.4.0 - "@backstage/core-components": ^0.13.2 - "@backstage/core-plugin-api": ^1.5.2 - "@backstage/plugin-catalog-react": ^1.7.0 - "@backstage/theme": ^0.4.0 + "@backstage/catalog-model": ^1.4.1 + "@backstage/core-components": ^0.13.3 + "@backstage/core-plugin-api": ^1.5.3 + "@backstage/plugin-catalog-react": ^1.8.0 + "@backstage/theme": ^0.4.1 "@material-ui/core": ^4.12.1 "@material-ui/icons": ^4.11.2 "@material-ui/lab": 4.0.0-alpha.57 @@ -14136,7 +14171,7 @@ __metadata: react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 2fd97ea027f5de8b1e0fe4f6abb463efdd819d54a2d5442017cac431598ed7b637107701ea2e7886a9c4e9e50718cecf5938db5684c670b6f214714999b99ced + checksum: 03945723ee9f71717f7ea1ac0a240fb516b33740b86a11c0be0f22021bb0cfa5eec541b3cadc5e77efa9ef432c4e978885cd0124b8eabc74f410b6fbc7d55f91 languageName: node linkType: hard @@ -14327,6 +14362,15 @@ __metadata: languageName: node linkType: hard +"@rrweb/types@npm:^2.0.0-alpha.9": + version: 2.0.0-alpha.9 + resolution: "@rrweb/types@npm:2.0.0-alpha.9" + dependencies: + rrweb-snapshot: ^2.0.0-alpha.9 + checksum: adc6bc7a6e45294ae7b85a137ae6774a822f103f0a29ecf8d59b72c88b6ddfaedc5a16d71971c08a2ab25e3e3af89f9582d8508bcf6b33d97fc326cdf91a09b2 + languageName: node + linkType: hard + "@rushstack/node-core-library@npm:3.53.3": version: 3.53.3 resolution: "@rushstack/node-core-library@npm:3.53.3" @@ -16525,6 +16569,13 @@ __metadata: languageName: node linkType: hard +"@types/css-font-loading-module@npm:0.0.7": + version: 0.0.7 + resolution: "@types/css-font-loading-module@npm:0.0.7" + checksum: a074d3b824b2232160f2353daf1cc62937e4a24154d13607f14f93feaaac6abcf069c8ae02c1396840950fa02c1b3f19ce0f119321f9735905bfb3cd4b9b2021 + languageName: node + linkType: hard + "@types/d3-array@npm:^3.0.3": version: 3.0.4 resolution: "@types/d3-array@npm:3.0.4" @@ -17310,9 +17361,9 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": - version: 20.4.2 - resolution: "@types/node@npm:20.4.2" - checksum: 99e544ea7560d51f01f95627fc40394c24a13da8f041121a0da13e4ef0a2aa332932eaf9a5e8d0e30d1c07106e96a183be392cbba62e8cf0bf6a085d5c0f4149 + version: 20.4.4 + resolution: "@types/node@npm:20.4.4" + checksum: 43f3c4a8acc38ae753e15a0e79bae0447d255b3742fa87f8e065d7b9d20ecb0e03d6c5b46c00d5d26f4552160381a00255f49205595a8ee48c2423e00263c930 languageName: node linkType: hard @@ -17331,9 +17382,9 @@ __metadata: linkType: hard "@types/node@npm:^14.14.31": - version: 14.18.53 - resolution: "@types/node@npm:14.18.53" - checksum: 3acbcf4e38cdc5999c824db5c6689ca8f4a185562aad5c0263d9859381d8590a16e6a72343aeb30d48ff9a7ac9b6ae259bcb8c2d594703a30d12277904524704 + version: 14.18.54 + resolution: "@types/node@npm:14.18.54" + checksum: 9fd66f91fcd8e9b25067f784a9c60bd710ef86a89c838c131ab2b1921398adc53b1c70d741bceed48bb2403b75c434b1bbbb255240773819cde36295c4b6abf1 languageName: node linkType: hard @@ -17345,16 +17396,16 @@ __metadata: linkType: hard "@types/node@npm:^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.9.2": - version: 16.18.38 - resolution: "@types/node@npm:16.18.38" - checksum: a3baa141e49ce94486f083eea1240cf38479a73ba663e1bf3f52f85b466125821b6e3ea85ded38fde3901530aca4601291395a50eefcea533a4f3b45171bda28 + version: 16.18.39 + resolution: "@types/node@npm:16.18.39" + checksum: eac9b202b76013256cb517ca8d3e3f61df206edb1615ca8d8df4c80616e92879fe4d3f8570a11d60f4216a82724a3265d5888b24c6994c80b057a0423c9ff1d2 languageName: node linkType: hard "@types/node@npm:^18.11.17": - version: 18.16.8 - resolution: "@types/node@npm:18.16.8" - checksum: d2ec9b61abd260b0fa1e33e4eca8f0089ebb6f6ec1ad2f036a4d01af11dba4f1dbff95b2a1f5dbe9eab3a6f38ed4bd8bf95eb2de9ad96b1caa1f67671e623c1d + version: 18.17.0 + resolution: "@types/node@npm:18.17.0" + checksum: 3a43c5c5541342751b514485144818a515fac5427f663066068eaacbe8a108cbe1207aae75ec89d34c3b32414c334aad84e9083cf7fcf3ebfd970adc871314a4 languageName: node linkType: hard @@ -18670,6 +18721,13 @@ __metadata: languageName: node linkType: hard +"@xstate/fsm@npm:^1.4.0": + version: 1.6.5 + resolution: "@xstate/fsm@npm:1.6.5" + checksum: da24fa4f40479223da34714640cea64ec894bbfeb2281a0a870af68882ae1d6fb6d724d6e5c0d4e6929728c699b92858f7389ef7d6a5d00ac66ba8cde3934eed + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -19887,6 +19945,13 @@ __metadata: languageName: node linkType: hard +"base64-arraybuffer@npm:^1.0.1": + version: 1.0.2 + resolution: "base64-arraybuffer@npm:1.0.2" + checksum: 15e6400d2d028bf18be4ed97702b11418f8f8779fb8c743251c863b726638d52f69571d4cc1843224da7838abef0949c670bde46936663c45ad078e89fee5c62 + languageName: node + linkType: hard + "base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -21871,7 +21936,7 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^3.6.5": +"core-js@npm:^3.26.0, core-js@npm:^3.6.5": version: 3.31.0 resolution: "core-js@npm:3.31.0" checksum: f7cf9b3010f7ca99c026d95b61743baca1a85512742ed2b67e8f65a72ac4f4fe0b90b00057783e886bdd39d3a295f42f845d33e7cba3973ed263df978343ab79 @@ -24085,31 +24150,31 @@ __metadata: linkType: hard "esbuild@npm:^0.18.0": - version: 0.18.13 - resolution: "esbuild@npm:0.18.13" + version: 0.18.16 + resolution: "esbuild@npm:0.18.16" dependencies: - "@esbuild/android-arm": 0.18.13 - "@esbuild/android-arm64": 0.18.13 - "@esbuild/android-x64": 0.18.13 - "@esbuild/darwin-arm64": 0.18.13 - "@esbuild/darwin-x64": 0.18.13 - "@esbuild/freebsd-arm64": 0.18.13 - "@esbuild/freebsd-x64": 0.18.13 - "@esbuild/linux-arm": 0.18.13 - "@esbuild/linux-arm64": 0.18.13 - "@esbuild/linux-ia32": 0.18.13 - "@esbuild/linux-loong64": 0.18.13 - "@esbuild/linux-mips64el": 0.18.13 - "@esbuild/linux-ppc64": 0.18.13 - "@esbuild/linux-riscv64": 0.18.13 - "@esbuild/linux-s390x": 0.18.13 - "@esbuild/linux-x64": 0.18.13 - "@esbuild/netbsd-x64": 0.18.13 - "@esbuild/openbsd-x64": 0.18.13 - "@esbuild/sunos-x64": 0.18.13 - "@esbuild/win32-arm64": 0.18.13 - "@esbuild/win32-ia32": 0.18.13 - "@esbuild/win32-x64": 0.18.13 + "@esbuild/android-arm": 0.18.16 + "@esbuild/android-arm64": 0.18.16 + "@esbuild/android-x64": 0.18.16 + "@esbuild/darwin-arm64": 0.18.16 + "@esbuild/darwin-x64": 0.18.16 + "@esbuild/freebsd-arm64": 0.18.16 + "@esbuild/freebsd-x64": 0.18.16 + "@esbuild/linux-arm": 0.18.16 + "@esbuild/linux-arm64": 0.18.16 + "@esbuild/linux-ia32": 0.18.16 + "@esbuild/linux-loong64": 0.18.16 + "@esbuild/linux-mips64el": 0.18.16 + "@esbuild/linux-ppc64": 0.18.16 + "@esbuild/linux-riscv64": 0.18.16 + "@esbuild/linux-s390x": 0.18.16 + "@esbuild/linux-x64": 0.18.16 + "@esbuild/netbsd-x64": 0.18.16 + "@esbuild/openbsd-x64": 0.18.16 + "@esbuild/sunos-x64": 0.18.16 + "@esbuild/win32-arm64": 0.18.16 + "@esbuild/win32-ia32": 0.18.16 + "@esbuild/win32-x64": 0.18.16 dependenciesMeta: "@esbuild/android-arm": optional: true @@ -24157,7 +24222,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 6512b7e186cffb4546f3508f1e2d1dd27eb43a8a8a79d4ea7eb34ae3dbdc647679ae96b29c54a4951c355ee3168e8ad9c128cbfc033154b0849e269276d5bc9c + checksum: 8b04f7087d4e95cffd43c37663c57a9f42e183cd3d02fe3cefee7e1534a84d5cec181f42187715471b4b3f5478e2e110530df7d3a8b12053cbc8cc35145363ab languageName: node linkType: hard @@ -25558,6 +25623,20 @@ __metadata: languageName: node linkType: hard +"fflate@npm:^0.4.4": + version: 0.4.8 + resolution: "fflate@npm:0.4.8" + checksum: 29d8cbe44d5e7f53e7f5a160ac7f9cc025480c7b3bfd85c5f898cbe20dfa2dad4732daa534982664bf30b35896a90af44ea33ede5d94c5ffd1b8b0c0a0a56ca2 + languageName: node + linkType: hard + +"fflate@npm:^0.7.4": + version: 0.7.4 + resolution: "fflate@npm:0.7.4" + checksum: b812ab26047432db70ff4c73eb45ad53bd0774575b4818b9c61c2921e89ec65d1259f06ec1618f2ac55e6a2f2e29b6dc09173d213b46580bc69efae5344bf8f1 + languageName: node + linkType: hard + "figures@npm:^3.0.0, figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -32468,6 +32547,13 @@ __metadata: languageName: node linkType: hard +"mitt@npm:^3.0.0": + version: 3.0.0 + resolution: "mitt@npm:3.0.0" + checksum: f7be5049d27d18b1dbe9408452d66376fa60ae4a79fe9319869d1b90ae8cbaedadc7e9dab30b32d781411256d468be5538996bb7368941c09009ef6bbfa6bfc7 + languageName: node + linkType: hard + "mixme@npm:^0.5.1": version: 0.5.4 resolution: "mixme@npm:0.5.4" @@ -37900,6 +37986,38 @@ __metadata: languageName: unknown linkType: soft +"rrdom@npm:^2.0.0-alpha.9": + version: 2.0.0-alpha.9 + resolution: "rrdom@npm:2.0.0-alpha.9" + dependencies: + rrweb-snapshot: ^2.0.0-alpha.9 + checksum: d56df9acc0348f4226a2d195692a422a431498c889a40046242f5643437d3388840de90078fb26488378fc250049a9d25ee5394a089f435e2f88668276bf17d4 + languageName: node + linkType: hard + +"rrweb-snapshot@npm:^2.0.0-alpha.9": + version: 2.0.0-alpha.9 + resolution: "rrweb-snapshot@npm:2.0.0-alpha.9" + checksum: 987f3ce493178dcc6782e959adef3e3f39e711bc8d5ac7dba5dfaf2fd01477aa2d3cd959598fa4e54cf15f2c397e95cf8323180a420857ca2a4d76abaec0a552 + languageName: node + linkType: hard + +"rrweb@npm:^2.0.0-alpha.8": + version: 2.0.0-alpha.9 + resolution: "rrweb@npm:2.0.0-alpha.9" + dependencies: + "@rrweb/types": ^2.0.0-alpha.9 + "@types/css-font-loading-module": 0.0.7 + "@xstate/fsm": ^1.4.0 + base64-arraybuffer: ^1.0.1 + fflate: ^0.4.4 + mitt: ^3.0.0 + rrdom: ^2.0.0-alpha.9 + rrweb-snapshot: ^2.0.0-alpha.9 + checksum: b87ec509dff99eef90496bc5685c57f6ec7868fb12c6b49a8d824a41e1a812aaa6b4aa792b50cdfdd68ec49287d51bba48ea764dfce149f3d9ce2363327328ff + languageName: node + linkType: hard + "rtl-css-js@npm:^1.14.0": version: 1.14.0 resolution: "rtl-css-js@npm:1.14.0" @@ -41817,6 +41935,13 @@ __metadata: languageName: node linkType: hard +"web-vitals@npm:^3.1.0": + version: 3.3.2 + resolution: "web-vitals@npm:3.3.2" + checksum: 76e832341d213d5de6f6767fef7f8c02163ab94326912a6355bbf6e194d930196ca5094b0d0d493b4c194acaaabcc96f0adc87870b913a7b9a51b225807abccf + languageName: node + linkType: hard + "webcrypto-core@npm:^1.7.4": version: 1.7.5 resolution: "webcrypto-core@npm:1.7.5"