Merge pull request #18537 from rr-wfm/feature/nr-analytics-plugin
New Relic Browser Analytics plugin
This commit is contained in:
@@ -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!
|
||||
+88
-88
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
||||
@@ -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<string> => {
|
||||
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
|
||||
```
|
||||
@@ -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<string>);
|
||||
},
|
||||
): NewRelicBrowser;
|
||||
}
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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 (
|
||||
<>
|
||||
<Link to="#clicked">Click Here</Link>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -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: <Playground />,
|
||||
})
|
||||
.render();
|
||||
@@ -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"
|
||||
}
|
||||
+176
@@ -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<typeof setAPI>;
|
||||
|
||||
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<string>),
|
||||
) {
|
||||
// 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<string>);
|
||||
},
|
||||
) {
|
||||
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<string> {
|
||||
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('');
|
||||
}
|
||||
}
|
||||
+16
@@ -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';
|
||||
@@ -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';
|
||||
@@ -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';
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user