From a4b364ec146a9d19fb65780bbd2b79678fcbf17d Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 14:32:14 +0200 Subject: [PATCH 01/39] Add some initial code Signed-off-by: Jonathan Mezach --- .github/CODEOWNERS | 176 +++++++++--------- packages/app/package.json | 1 + plugins/analytics-module-nr/.eslintrc.js | 1 + plugins/analytics-module-nr/README.md | 13 ++ plugins/analytics-module-nr/config.d.ts | 59 ++++++ .../analytics-module-nr/dev/Playground.tsx | 26 +++ plugins/analytics-module-nr/dev/index.tsx | 51 +++++ plugins/analytics-module-nr/package.json | 55 ++++++ .../AnalyticsApi/NewRelicBrowser.ts | 110 +++++++++++ .../implementations/AnalyticsApi/index.ts | 16 ++ plugins/analytics-module-nr/src/index.ts | 16 ++ plugins/analytics-module-nr/src/setupTests.ts | 16 ++ yarn.lock | 132 ++++++++++++- 13 files changed, 583 insertions(+), 89 deletions(-) create mode 100644 plugins/analytics-module-nr/.eslintrc.js create mode 100644 plugins/analytics-module-nr/README.md create mode 100644 plugins/analytics-module-nr/config.d.ts create mode 100644 plugins/analytics-module-nr/dev/Playground.tsx create mode 100644 plugins/analytics-module-nr/dev/index.tsx create mode 100644 plugins/analytics-module-nr/package.json create mode 100644 plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts create mode 100644 plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/index.ts create mode 100644 plugins/analytics-module-nr/src/index.ts create mode 100644 plugins/analytics-module-nr/src/setupTests.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 82a9eb499d..ea5b656bf7 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-nr @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/packages/app/package.json b/packages/app/package.json index 0f3a65c26a..10482ffeb4 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -85,6 +85,7 @@ "@roadiehq/backstage-plugin-github-insights": "^2.0.5", "@roadiehq/backstage-plugin-github-pull-requests": "^2.2.7", "@roadiehq/backstage-plugin-travis-ci": "^2.0.5", + "backstage-plugin-analytics-module-nr": "^0.0.0", "history": "^5.0.0", "prop-types": "^15.7.2", "react": "^17.0.2", diff --git a/plugins/analytics-module-nr/.eslintrc.js b/plugins/analytics-module-nr/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/analytics-module-nr/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/analytics-module-nr/README.md b/plugins/analytics-module-nr/README.md new file mode 100644 index 0000000000..131a7d9c63 --- /dev/null +++ b/plugins/analytics-module-nr/README.md @@ -0,0 +1,13 @@ +# 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. + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/analytics-module-nr](http://localhost:3000/analytics-module-nr). + +You can also serve the plugin in isolation by running `yarn start` in the plugin directory. +This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. +It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/analytics-module-nr/config.d.ts b/plugins/analytics-module-nr/config.d.ts new file mode 100644 index 0000000000..e9c1b3ebca --- /dev/null +++ b/plugins/analytics-module-nr/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?: { + nr: { + /** + * 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; + + /** + * Whether to use New Relic's EU Datacenter endpoints, defaults to false + * @visibility frontend + */ + useEuEndpoint: boolean; + }; + }; + }; +} diff --git a/plugins/analytics-module-nr/dev/Playground.tsx b/plugins/analytics-module-nr/dev/Playground.tsx new file mode 100644 index 0000000000..cf21aadacc --- /dev/null +++ b/plugins/analytics-module-nr/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-nr/dev/index.tsx b/plugins/analytics-module-nr/dev/index.tsx new file mode 100644 index 0000000000..796bade4a9 --- /dev/null +++ b/plugins/analytics-module-nr/dev/index.tsx @@ -0,0 +1,51 @@ +/* + * 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, + createPlugin, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { Playground } from '../../analytics-module-nr/dev/Playground'; +import { NewRelicBrowser } from '../src'; + +/** + * @deprecated Importing and including this plugin in an app has no effect. + * This will be removed in a future release. + * + * @public + */ +export const analyticsModuleNR = createPlugin({ + id: 'analytics-provider-nr', +}); +createDevApp() + .registerPlugin(analyticsModuleNR) + .registerApi({ + api: analyticsApiRef, + deps: { configApi: configApiRef, identityApi: identityApiRef }, + factory: ({ configApi, identityApi }) => + NewRelicBrowser.fromConfig(configApi, { + identityApi, + }), + }) + .addPage({ + path: '/nr', + title: 'New Relic Playground', + element: , + }) + .render(); diff --git a/plugins/analytics-module-nr/package.json b/plugins/analytics-module-nr/package.json new file mode 100644 index 0000000000..3cc446150a --- /dev/null +++ b/plugins/analytics-module-nr/package.json @@ -0,0 +1,55 @@ +{ + "name": "backstage-plugin-analytics-module-nr", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": true, + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "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:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.60", + "@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-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts b/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts new file mode 100644 index 0000000000..5270dce156 --- /dev/null +++ b/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -0,0 +1,110 @@ +/* + * 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; + +export type NewRelicBrowserOptions = { + accountId: string; + applicationId: string; + licenseKey: string; + distributedTracingEnabled: boolean; + cookiesEnabled: boolean; + useEuEndpoint: boolean; +}; + +// Implementation that optionally initializes with a userId. +export class NewRelicBrowser implements AnalyticsApi { + private readonly agent: NewRelicAPI; + + private constructor( + options: NewRelicBrowserOptions, + identityApi?: IdentityApi, + ) { + // Configure the New Relic Browser agent + const agentOptions = { + init: { + distributed_tracing: { + enabled: options.distributedTracingEnabled, + }, + privacy: { + cookies_enabled: options.cookiesEnabled, + }, + ajax: { + deny_list: [ + options.useEuEndpoint ? 'bam.eu01.nr-data.net' : 'bam.nr-data.net', + ], + }, + }, + info: { + beacon: options.useEuEndpoint + ? 'bam.eu01.nr-data.net' + : 'bam.nr-data.net', + errorBeacon: options.useEuEndpoint + ? 'bam.eu01.nr-data.net' + : 'bam.nr-data.net', + 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; + + if (identityApi) { + identityApi.getBackstageIdentity().then(identity => { + this.agent.setUserId(identity.userEntityRef); + }); + } + } + + static fromConfig(config: Config, options: { identityApi?: IdentityApi }) { + const browserOptions: NewRelicBrowserOptions = { + accountId: config.getString('app.analytics.nr.accountId'), + applicationId: config.getString('app.analytics.nr.applicationId'), + licenseKey: config.getString('app.analytics.nr.licenseKey'), + distributedTracingEnabled: + config.getOptionalBoolean( + 'app.analytics.nr.distributedTracingEnabled', + ) ?? false, + cookiesEnabled: + config.getOptionalBoolean('app.analytics.nr.cookiesEnabled') ?? false, + useEuEndpoint: + config.getOptionalBoolean('app.analytics.nr.useEuEndpoint') ?? false, + }; + return new NewRelicBrowser(browserOptions, options.identityApi); + } + + captureEvent(event: AnalyticsEvent) { + const { action, ...rest } = event; + this.agent.addPageAction(action, rest); + } +} diff --git a/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/index.ts b/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/index.ts new file mode 100644 index 0000000000..6300381cfd --- /dev/null +++ b/plugins/analytics-module-nr/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-nr/src/index.ts b/plugins/analytics-module-nr/src/index.ts new file mode 100644 index 0000000000..0adf114679 --- /dev/null +++ b/plugins/analytics-module-nr/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-nr/src/setupTests.ts b/plugins/analytics-module-nr/src/setupTests.ts new file mode 100644 index 0000000000..865308e634 --- /dev/null +++ b/plugins/analytics-module-nr/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/yarn.lock b/yarn.lock index c801c6440b..96b1aefaea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13535,6 +13535,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" @@ -14856,6 +14868,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" @@ -16592,6 +16613,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" @@ -18728,6 +18756,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" @@ -19893,6 +19928,33 @@ __metadata: languageName: node linkType: hard +"backstage-plugin-analytics-module-nr@^0.0.0, backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr": + version: 0.0.0-use.local + resolution: "backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr" + 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:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.60 + "@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 + "badge-maker@npm:^3.3.0": version: 3.3.1 resolution: "badge-maker@npm:3.3.1" @@ -19926,6 +19988,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" @@ -21898,7 +21967,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 @@ -24923,6 +24992,7 @@ __metadata: "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 + backstage-plugin-analytics-module-nr: ^0.0.0 cross-env: ^7.0.0 cypress: ^10.0.0 eslint-plugin-cypress: ^2.10.3 @@ -25554,6 +25624,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" @@ -32437,6 +32521,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" @@ -37756,6 +37847,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" @@ -41673,6 +41796,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" From 8ee279896ecace33df71d939033e0766e5dc9c02 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 14:33:24 +0200 Subject: [PATCH 02/39] Remove deprecated stuff Signed-off-by: Jonathan Mezach --- plugins/analytics-module-nr/dev/index.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/plugins/analytics-module-nr/dev/index.tsx b/plugins/analytics-module-nr/dev/index.tsx index 796bade4a9..bb57fb898f 100644 --- a/plugins/analytics-module-nr/dev/index.tsx +++ b/plugins/analytics-module-nr/dev/index.tsx @@ -24,17 +24,7 @@ import { import { Playground } from '../../analytics-module-nr/dev/Playground'; import { NewRelicBrowser } from '../src'; -/** - * @deprecated Importing and including this plugin in an app has no effect. - * This will be removed in a future release. - * - * @public - */ -export const analyticsModuleNR = createPlugin({ - id: 'analytics-provider-nr', -}); createDevApp() - .registerPlugin(analyticsModuleNR) .registerApi({ api: analyticsApiRef, deps: { configApi: configApiRef, identityApi: identityApiRef }, From 4decf61d8ba4a6db047a8c0a08527756a3393a58 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 14:47:08 +0200 Subject: [PATCH 03/39] Add some docs Signed-off-by: Jonathan Mezach --- plugins/analytics-module-nr/README.md | 100 ++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/plugins/analytics-module-nr/README.md b/plugins/analytics-module-nr/README.md index 131a7d9c63..ada06c991d 100644 --- a/plugins/analytics-module-nr/README.md +++ b/plugins/analytics-module-nr/README.md @@ -4,10 +4,100 @@ This plugin provides an opinionated implementation of the Backstage Analytics AP This plugin contains no other functionality. -## Getting started +## Installation -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/analytics-module-nr](http://localhost:3000/analytics-module-nr). +1. Install the plugin package in your Backstage app: -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. +```sh +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-analytics-module-nr +``` + +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-nr'; + +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: + nr: + accountId: '1234567' + applicationId: '987654321' + licenseKey: 'NRJS-12a3456bc78de9123f4' + useEuEndpoint: false # Set this to true if you're using New Relic's EU data center +``` + +## 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: + nr: + ... + distributedTracing: true + cookiesEnabled: true +``` + +## 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-nr` +5. Start the plugin in isolation: `yarn start` +6. Navigate to the playground page at `http://localhost:3000/nr` +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: + nr: + accountId: '1234567' + applicationId: '987654321' + licenseKey: 'NRJS-12a3456bc78de9123f4' + distributedTracingEnabled: true + cookiesEnabled: true + useEuEndpoint: false +``` From ec73572588530e02d7b0ee945148ddd8f079d8a5 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 14:52:09 +0200 Subject: [PATCH 04/39] Add changeset Signed-off-by: Jonathan Mezach --- .changeset/rude-feet-sparkle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rude-feet-sparkle.md diff --git a/.changeset/rude-feet-sparkle.md b/.changeset/rude-feet-sparkle.md new file mode 100644 index 0000000000..09007bd663 --- /dev/null +++ b/.changeset/rude-feet-sparkle.md @@ -0,0 +1,5 @@ +--- +'backstage-plugin-analytics-module-nr': patch +--- + +Initial release From 8a398634d6688a193a6071f8d424b48eeaf032c8 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 15:12:34 +0200 Subject: [PATCH 05/39] Remove unused import Signed-off-by: Jonathan Mezach --- plugins/analytics-module-nr/dev/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/analytics-module-nr/dev/index.tsx b/plugins/analytics-module-nr/dev/index.tsx index bb57fb898f..ba492ae7ba 100644 --- a/plugins/analytics-module-nr/dev/index.tsx +++ b/plugins/analytics-module-nr/dev/index.tsx @@ -18,7 +18,6 @@ import { createDevApp } from '@backstage/dev-utils'; import { analyticsApiRef, configApiRef, - createPlugin, identityApiRef, } from '@backstage/core-plugin-api'; import { Playground } from '../../analytics-module-nr/dev/Playground'; From 122a48610b0a3ef6e23e63f2cdb4ccd9e44c4aec Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 15:18:39 +0200 Subject: [PATCH 06/39] Undo unnecessary change to example app Signed-off-by: Jonathan Mezach --- packages/app/package.json | 1 - yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index 10482ffeb4..0f3a65c26a 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -85,7 +85,6 @@ "@roadiehq/backstage-plugin-github-insights": "^2.0.5", "@roadiehq/backstage-plugin-github-pull-requests": "^2.2.7", "@roadiehq/backstage-plugin-travis-ci": "^2.0.5", - "backstage-plugin-analytics-module-nr": "^0.0.0", "history": "^5.0.0", "prop-types": "^15.7.2", "react": "^17.0.2", diff --git a/yarn.lock b/yarn.lock index 96b1aefaea..1655772dbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19928,7 +19928,7 @@ __metadata: languageName: node linkType: hard -"backstage-plugin-analytics-module-nr@^0.0.0, backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr": +"backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr": version: 0.0.0-use.local resolution: "backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr" dependencies: @@ -24992,7 +24992,6 @@ __metadata: "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 - backstage-plugin-analytics-module-nr: ^0.0.0 cross-env: ^7.0.0 cypress: ^10.0.0 eslint-plugin-cypress: ^2.10.3 From 03bdc4380a1f484914b588d0e432f200b17336ed Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 15:45:08 +0200 Subject: [PATCH 07/39] Fix api report Signed-off-by: Jonathan Mezach --- plugins/analytics-module-nr/api-report.md | 25 +++++++++++++++++++ .../AnalyticsApi/NewRelicBrowser.ts | 7 ++++-- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 plugins/analytics-module-nr/api-report.md diff --git a/plugins/analytics-module-nr/api-report.md b/plugins/analytics-module-nr/api-report.md new file mode 100644 index 0000000000..56c3d166d0 --- /dev/null +++ b/plugins/analytics-module-nr/api-report.md @@ -0,0 +1,25 @@ +## API Report File for "backstage-plugin-analytics-module-nr" + +> 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; + }, + ): NewRelicBrowser; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts b/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts index 5270dce156..35be8cc8a0 100644 --- a/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts +++ b/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -24,7 +24,7 @@ import type { setAPI } from '@newrelic/browser-agent/loaders/api/api'; type NewRelicAPI = ReturnType; -export type NewRelicBrowserOptions = { +type NewRelicBrowserOptions = { accountId: string; applicationId: string; licenseKey: string; @@ -33,7 +33,10 @@ export type NewRelicBrowserOptions = { useEuEndpoint: boolean; }; -// Implementation that optionally initializes with a userId. +/** + * New Relic Browser API provider for the Backstage Analytics API. + * @public + */ export class NewRelicBrowser implements AnalyticsApi { private readonly agent: NewRelicAPI; From 65596b0cf4a01cb7e6d15d75f809276f53e0d1ec Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 16:40:43 +0200 Subject: [PATCH 08/39] Respond to comments Signed-off-by: Jonathan Mezach --- .changeset/rude-feet-sparkle.md | 4 +- .github/CODEOWNERS | 2 +- plugins/analytics-module-nr/package.json | 6 +-- yarn.lock | 50 +++++++++++------------- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/.changeset/rude-feet-sparkle.md b/.changeset/rude-feet-sparkle.md index 09007bd663..96397af1e2 100644 --- a/.changeset/rude-feet-sparkle.md +++ b/.changeset/rude-feet-sparkle.md @@ -1,5 +1,5 @@ --- -'backstage-plugin-analytics-module-nr': patch +'@backstage/plugin-analytics-module-newrelic-browser': patch --- -Initial release +Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-nr) for more details! diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ea5b656bf7..a2d5f4988a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -17,7 +17,7 @@ /plugins/adr @backstage/maintainers @kuangp /plugins/adr-* @backstage/maintainers @kuangp /plugins/allure @backstage/maintainers @deepak-bhardwaj-ps -/plugins/analytics-module-nr @jmezach +/plugins/analytics-module-nr @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 diff --git a/plugins/analytics-module-nr/package.json b/plugins/analytics-module-nr/package.json index 3cc446150a..6438855070 100644 --- a/plugins/analytics-module-nr/package.json +++ b/plugins/analytics-module-nr/package.json @@ -1,5 +1,5 @@ { - "name": "backstage-plugin-analytics-module-nr", + "name": "@backstage/plugin-analytics-module-newrelic-browser", "version": "0.0.0", "main": "src/index.ts", "types": "src/index.ts", @@ -26,10 +26,6 @@ "@backstage/config": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", - "@backstage/theme": "workspace:^", - "@material-ui/core": "^4.9.13", - "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "^4.0.0-alpha.60", "@newrelic/browser-agent": "^1.236.0", "react-use": "^17.2.4" }, diff --git a/yarn.lock b/yarn.lock index 1655772dbc..f9fd557d64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4794,6 +4794,29 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-nr": + version: 0.0.0-use.local + resolution: "@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-nr" + 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" @@ -19928,33 +19951,6 @@ __metadata: languageName: node linkType: hard -"backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr": - version: 0.0.0-use.local - resolution: "backstage-plugin-analytics-module-nr@workspace:plugins/analytics-module-nr" - 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:^" - "@backstage/theme": "workspace:^" - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": ^4.0.0-alpha.60 - "@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 - "badge-maker@npm:^3.3.0": version: 3.3.1 resolution: "badge-maker@npm:3.3.1" From cb72eb6370d850451ae2a3821953741b2e43b5e8 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Tue, 4 Jul 2023 18:29:28 +0200 Subject: [PATCH 09/39] Fix API report Signed-off-by: Jonathan Mezach --- plugins/analytics-module-nr/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/analytics-module-nr/api-report.md b/plugins/analytics-module-nr/api-report.md index 56c3d166d0..26b478f64d 100644 --- a/plugins/analytics-module-nr/api-report.md +++ b/plugins/analytics-module-nr/api-report.md @@ -1,4 +1,4 @@ -## API Report File for "backstage-plugin-analytics-module-nr" +## 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/). From 4100ef10014cbe06bcf14c3cd153579237ebd4ff Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 5 Jul 2023 11:02:21 +0200 Subject: [PATCH 10/39] Renamed folder to reflect new name Signed-off-by: Jonathan Mezach --- .../.eslintrc.js | 0 .../README.md | 0 .../api-report.md | 0 .../config.d.ts | 0 .../dev/Playground.tsx | 0 .../dev/index.tsx | 2 +- .../package.json | 0 .../src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts | 0 .../src/apis/implementations/AnalyticsApi/index.ts | 0 .../src/index.ts | 0 .../src/setupTests.ts | 0 yarn.lock | 4 ++-- 12 files changed, 3 insertions(+), 3 deletions(-) rename plugins/{analytics-module-nr => analytics-module-new-relic}/.eslintrc.js (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/README.md (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/api-report.md (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/config.d.ts (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/dev/Playground.tsx (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/dev/index.tsx (94%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/package.json (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/src/apis/implementations/AnalyticsApi/index.ts (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/src/index.ts (100%) rename plugins/{analytics-module-nr => analytics-module-new-relic}/src/setupTests.ts (100%) diff --git a/plugins/analytics-module-nr/.eslintrc.js b/plugins/analytics-module-new-relic/.eslintrc.js similarity index 100% rename from plugins/analytics-module-nr/.eslintrc.js rename to plugins/analytics-module-new-relic/.eslintrc.js diff --git a/plugins/analytics-module-nr/README.md b/plugins/analytics-module-new-relic/README.md similarity index 100% rename from plugins/analytics-module-nr/README.md rename to plugins/analytics-module-new-relic/README.md diff --git a/plugins/analytics-module-nr/api-report.md b/plugins/analytics-module-new-relic/api-report.md similarity index 100% rename from plugins/analytics-module-nr/api-report.md rename to plugins/analytics-module-new-relic/api-report.md diff --git a/plugins/analytics-module-nr/config.d.ts b/plugins/analytics-module-new-relic/config.d.ts similarity index 100% rename from plugins/analytics-module-nr/config.d.ts rename to plugins/analytics-module-new-relic/config.d.ts diff --git a/plugins/analytics-module-nr/dev/Playground.tsx b/plugins/analytics-module-new-relic/dev/Playground.tsx similarity index 100% rename from plugins/analytics-module-nr/dev/Playground.tsx rename to plugins/analytics-module-new-relic/dev/Playground.tsx diff --git a/plugins/analytics-module-nr/dev/index.tsx b/plugins/analytics-module-new-relic/dev/index.tsx similarity index 94% rename from plugins/analytics-module-nr/dev/index.tsx rename to plugins/analytics-module-new-relic/dev/index.tsx index ba492ae7ba..5524a48b68 100644 --- a/plugins/analytics-module-nr/dev/index.tsx +++ b/plugins/analytics-module-new-relic/dev/index.tsx @@ -20,7 +20,7 @@ import { configApiRef, identityApiRef, } from '@backstage/core-plugin-api'; -import { Playground } from '../../analytics-module-nr/dev/Playground'; +import { Playground } from './Playground'; import { NewRelicBrowser } from '../src'; createDevApp() diff --git a/plugins/analytics-module-nr/package.json b/plugins/analytics-module-new-relic/package.json similarity index 100% rename from plugins/analytics-module-nr/package.json rename to plugins/analytics-module-new-relic/package.json diff --git a/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts b/plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts similarity index 100% rename from plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts rename to plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts diff --git a/plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/index.ts b/plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/index.ts similarity index 100% rename from plugins/analytics-module-nr/src/apis/implementations/AnalyticsApi/index.ts rename to plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/index.ts diff --git a/plugins/analytics-module-nr/src/index.ts b/plugins/analytics-module-new-relic/src/index.ts similarity index 100% rename from plugins/analytics-module-nr/src/index.ts rename to plugins/analytics-module-new-relic/src/index.ts diff --git a/plugins/analytics-module-nr/src/setupTests.ts b/plugins/analytics-module-new-relic/src/setupTests.ts similarity index 100% rename from plugins/analytics-module-nr/src/setupTests.ts rename to plugins/analytics-module-new-relic/src/setupTests.ts diff --git a/yarn.lock b/yarn.lock index f9fd557d64..89a006567c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4794,9 +4794,9 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-nr": +"@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-new-relic": version: 0.0.0-use.local - resolution: "@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-nr" + resolution: "@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-new-relic" dependencies: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" From 2f4872d44cafa39a85da2281c8133a05b1f47443 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 5 Jul 2023 11:25:10 +0200 Subject: [PATCH 11/39] Fix broken link Signed-off-by: Jonathan Mezach --- .changeset/rude-feet-sparkle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rude-feet-sparkle.md b/.changeset/rude-feet-sparkle.md index 96397af1e2..12cb5fd1f6 100644 --- a/.changeset/rude-feet-sparkle.md +++ b/.changeset/rude-feet-sparkle.md @@ -2,4 +2,4 @@ '@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-nr) for more details! +Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-new-relic) for more details! From 14c6729ec4cff70a344c5423c32e88684476ab87 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Fri, 7 Jul 2023 08:55:43 +0200 Subject: [PATCH 12/39] Changed package role Signed-off-by: Jonathan Mezach --- plugins/analytics-module-new-relic/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/analytics-module-new-relic/package.json b/plugins/analytics-module-new-relic/package.json index 6438855070..9364899003 100644 --- a/plugins/analytics-module-new-relic/package.json +++ b/plugins/analytics-module-new-relic/package.json @@ -11,7 +11,7 @@ "types": "dist/index.d.ts" }, "backstage": { - "role": "frontend-plugin" + "role": "frontend-plugin-module" }, "scripts": { "start": "backstage-cli package start", From bbd52b2669bcedb4e929a03b05721b4865b6ecf2 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Fri, 7 Jul 2023 12:20:55 +0200 Subject: [PATCH 13/39] Add section about User IDs to README Signed-off-by: Jonathan Mezach --- plugins/analytics-module-new-relic/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/analytics-module-new-relic/README.md b/plugins/analytics-module-new-relic/README.md index ada06c991d..d278597c93 100644 --- a/plugins/analytics-module-new-relic/README.md +++ b/plugins/analytics-module-new-relic/README.md @@ -68,6 +68,10 @@ app: 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. + ## Development If you would like to contribute improvements to this plugin, the easiest way to From 7352d05fde6ce44af4e9ad762d6361ad24daeee7 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Mon, 10 Jul 2023 13:33:55 +0200 Subject: [PATCH 14/39] Fix a docs issue Signed-off-by: Jonathan Mezach --- plugins/analytics-module-new-relic/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/analytics-module-new-relic/README.md b/plugins/analytics-module-new-relic/README.md index d278597c93..98f17eae20 100644 --- a/plugins/analytics-module-new-relic/README.md +++ b/plugins/analytics-module-new-relic/README.md @@ -22,7 +22,7 @@ import { configApiRef, identityApiRef, } from '@backstage/core-plugin-api'; -import { NewRelicBrowser } from '@backstage/plugin-analytics-module-nr'; +import { NewRelicBrowser } from '@backstage/plugin-analytics-module-newrelic-browser'; export const apis: AnyApiFactory[] = [ // Instantiate and register the New Relic Browser API Implementation. From bc438208993272319baef6ec079fcc225ee5f130 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 11:30:17 +0200 Subject: [PATCH 15/39] Rename again to match module name Signed-off-by: Jonathan Mezach --- .../.eslintrc.js | 0 .../README.md | 0 .../api-report.md | 0 .../config.d.ts | 0 .../dev/Playground.tsx | 0 .../dev/index.tsx | 0 .../package.json | 0 .../AnalyticsApi/NewRelicBrowser.ts | 33 +++++++++++++++++-- .../implementations/AnalyticsApi/index.ts | 0 .../src/index.ts | 0 .../src/setupTests.ts | 0 yarn.lock | 4 +-- 12 files changed, 33 insertions(+), 4 deletions(-) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/.eslintrc.js (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/README.md (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/api-report.md (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/config.d.ts (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/dev/Playground.tsx (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/dev/index.tsx (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/package.json (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts (76%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/src/apis/implementations/AnalyticsApi/index.ts (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/src/index.ts (100%) rename plugins/{analytics-module-new-relic => analytics-module-newrelic-browser}/src/setupTests.ts (100%) diff --git a/plugins/analytics-module-new-relic/.eslintrc.js b/plugins/analytics-module-newrelic-browser/.eslintrc.js similarity index 100% rename from plugins/analytics-module-new-relic/.eslintrc.js rename to plugins/analytics-module-newrelic-browser/.eslintrc.js diff --git a/plugins/analytics-module-new-relic/README.md b/plugins/analytics-module-newrelic-browser/README.md similarity index 100% rename from plugins/analytics-module-new-relic/README.md rename to plugins/analytics-module-newrelic-browser/README.md diff --git a/plugins/analytics-module-new-relic/api-report.md b/plugins/analytics-module-newrelic-browser/api-report.md similarity index 100% rename from plugins/analytics-module-new-relic/api-report.md rename to plugins/analytics-module-newrelic-browser/api-report.md diff --git a/plugins/analytics-module-new-relic/config.d.ts b/plugins/analytics-module-newrelic-browser/config.d.ts similarity index 100% rename from plugins/analytics-module-new-relic/config.d.ts rename to plugins/analytics-module-newrelic-browser/config.d.ts diff --git a/plugins/analytics-module-new-relic/dev/Playground.tsx b/plugins/analytics-module-newrelic-browser/dev/Playground.tsx similarity index 100% rename from plugins/analytics-module-new-relic/dev/Playground.tsx rename to plugins/analytics-module-newrelic-browser/dev/Playground.tsx diff --git a/plugins/analytics-module-new-relic/dev/index.tsx b/plugins/analytics-module-newrelic-browser/dev/index.tsx similarity index 100% rename from plugins/analytics-module-new-relic/dev/index.tsx rename to plugins/analytics-module-newrelic-browser/dev/index.tsx diff --git a/plugins/analytics-module-new-relic/package.json b/plugins/analytics-module-newrelic-browser/package.json similarity index 100% rename from plugins/analytics-module-new-relic/package.json rename to plugins/analytics-module-newrelic-browser/package.json diff --git a/plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts similarity index 76% rename from plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts rename to plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts index 35be8cc8a0..d2c46d1394 100644 --- a/plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -107,7 +107,36 @@ export class NewRelicBrowser implements AnalyticsApi { } captureEvent(event: AnalyticsEvent) { - const { action, ...rest } = event; - this.agent.addPageAction(action, rest); + const { context, action, subject, value, attributes } = event; + if (action === 'navigate' && context.extension === 'App') { + const interaction = this.agent.interaction(); + interaction.setName(subject); + 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; + } = {}; + 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); + } } } diff --git a/plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/index.ts b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/index.ts similarity index 100% rename from plugins/analytics-module-new-relic/src/apis/implementations/AnalyticsApi/index.ts rename to plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/index.ts diff --git a/plugins/analytics-module-new-relic/src/index.ts b/plugins/analytics-module-newrelic-browser/src/index.ts similarity index 100% rename from plugins/analytics-module-new-relic/src/index.ts rename to plugins/analytics-module-newrelic-browser/src/index.ts diff --git a/plugins/analytics-module-new-relic/src/setupTests.ts b/plugins/analytics-module-newrelic-browser/src/setupTests.ts similarity index 100% rename from plugins/analytics-module-new-relic/src/setupTests.ts rename to plugins/analytics-module-newrelic-browser/src/setupTests.ts diff --git a/yarn.lock b/yarn.lock index 89a006567c..c081af575d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4794,9 +4794,9 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-new-relic": +"@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-new-relic" + resolution: "@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-newrelic-browser" dependencies: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" From 9910289122d9db70c052911d4ae313dae7a1ea96 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 16:29:37 +0200 Subject: [PATCH 16/39] Remove private flag Signed-off-by: Jonathan Mezach --- plugins/analytics-module-newrelic-browser/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/analytics-module-newrelic-browser/package.json b/plugins/analytics-module-newrelic-browser/package.json index 9364899003..f9243817f4 100644 --- a/plugins/analytics-module-newrelic-browser/package.json +++ b/plugins/analytics-module-newrelic-browser/package.json @@ -4,7 +4,6 @@ "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", - "private": true, "publishConfig": { "access": "public", "main": "dist/index.esm.js", From 8d47ae541e2a466484d089725519f69006b7523b Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 16:29:49 +0200 Subject: [PATCH 17/39] Send value to NR Browser as well Signed-off-by: Jonathan Mezach --- .../apis/implementations/AnalyticsApi/NewRelicBrowser.ts | 6 ++++++ 1 file changed, 6 insertions(+) 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 index d2c46d1394..274089d429 100644 --- a/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -111,6 +111,9 @@ export class NewRelicBrowser implements AnalyticsApi { 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]); @@ -125,6 +128,9 @@ export class NewRelicBrowser implements AnalyticsApi { 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]; From 541418c1ff79762493ee28f993328bef7a9e64a0 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 16:36:04 +0200 Subject: [PATCH 18/39] Explicitly configure endpoints Signed-off-by: Jonathan Mezach --- .../analytics-module-newrelic-browser/README.md | 4 +++- .../config.d.ts | 12 ++++++------ .../AnalyticsApi/NewRelicBrowser.ts | 17 +++++------------ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/plugins/analytics-module-newrelic-browser/README.md b/plugins/analytics-module-newrelic-browser/README.md index 98f17eae20..e31496505d 100644 --- a/plugins/analytics-module-newrelic-browser/README.md +++ b/plugins/analytics-module-newrelic-browser/README.md @@ -48,12 +48,14 @@ in New Relic Browser using the Copy/Paste method. app: analytics: nr: + endpoint: 'bam.nr-data.net', accountId: '1234567' applicationId: '987654321' licenseKey: 'NRJS-12a3456bc78de9123f4' - useEuEndpoint: false # Set this to true if you're using New Relic's EU data center ``` +> 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`: diff --git a/plugins/analytics-module-newrelic-browser/config.d.ts b/plugins/analytics-module-newrelic-browser/config.d.ts index e9c1b3ebca..22e99f3a15 100644 --- a/plugins/analytics-module-newrelic-browser/config.d.ts +++ b/plugins/analytics-module-newrelic-browser/config.d.ts @@ -18,6 +18,12 @@ export interface Config { app: { analytics?: { nr: { + /** + * Whether to use New Relic's EU Datacenter endpoints, defaults to false + * @visibility frontend + */ + endpoint: 'bam.eu01.nr-data.net' | 'bam.nr-data.net'; + /** * New Relic Account ID, e.g. 1234567 * @visibility frontend @@ -47,12 +53,6 @@ export interface Config { * @visibility frontend */ cookiesEnabled: boolean; - - /** - * Whether to use New Relic's EU Datacenter endpoints, defaults to false - * @visibility frontend - */ - useEuEndpoint: boolean; }; }; }; 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 index 274089d429..291d5eba68 100644 --- a/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -25,12 +25,12 @@ 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; - useEuEndpoint: boolean; }; /** @@ -54,18 +54,12 @@ export class NewRelicBrowser implements AnalyticsApi { cookies_enabled: options.cookiesEnabled, }, ajax: { - deny_list: [ - options.useEuEndpoint ? 'bam.eu01.nr-data.net' : 'bam.nr-data.net', - ], + deny_list: [options.endpoint], }, }, info: { - beacon: options.useEuEndpoint - ? 'bam.eu01.nr-data.net' - : 'bam.nr-data.net', - errorBeacon: options.useEuEndpoint - ? 'bam.eu01.nr-data.net' - : 'bam.nr-data.net', + beacon: options.endpoint, + errorBeacon: options.endpoint, licenseKey: options.licenseKey, applicationID: options.applicationId, sa: 1, @@ -91,6 +85,7 @@ export class NewRelicBrowser implements AnalyticsApi { static fromConfig(config: Config, options: { identityApi?: IdentityApi }) { const browserOptions: NewRelicBrowserOptions = { + endpoint: config.getString('app.analytics.nr.endpoint'), accountId: config.getString('app.analytics.nr.accountId'), applicationId: config.getString('app.analytics.nr.applicationId'), licenseKey: config.getString('app.analytics.nr.licenseKey'), @@ -100,8 +95,6 @@ export class NewRelicBrowser implements AnalyticsApi { ) ?? false, cookiesEnabled: config.getOptionalBoolean('app.analytics.nr.cookiesEnabled') ?? false, - useEuEndpoint: - config.getOptionalBoolean('app.analytics.nr.useEuEndpoint') ?? false, }; return new NewRelicBrowser(browserOptions, options.identityApi); } From 9c87feae32c0e02b245f1f7bf9635eedc6e04c23 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 16:52:33 +0200 Subject: [PATCH 19/39] Add hashing of user ID's by default Signed-off-by: Jonathan Mezach --- .../README.md | 26 ++++++++++++ .../AnalyticsApi/NewRelicBrowser.ts | 41 +++++++++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/plugins/analytics-module-newrelic-browser/README.md b/plugins/analytics-module-newrelic-browser/README.md index e31496505d..a94a60575e 100644 --- a/plugins/analytics-module-newrelic-browser/README.md +++ b/plugins/analytics-module-newrelic-browser/README.md @@ -74,6 +74,32 @@ app: 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 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 index 291d5eba68..293c0a9b45 100644 --- a/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -43,6 +43,7 @@ export class NewRelicBrowser implements AnalyticsApi { private constructor( options: NewRelicBrowserOptions, identityApi?: IdentityApi, + userIdTransform?: 'sha-256' | ((userEntityRef: string) => Promise), ) { // Configure the New Relic Browser agent const agentOptions = { @@ -76,14 +77,31 @@ export class NewRelicBrowser implements AnalyticsApi { // Initialize the agent this.agent = new BrowserAgent(agentOptions) as unknown as NewRelicAPI; + // Check if identity has been provided if (identityApi) { identityApi.getBackstageIdentity().then(identity => { - this.agent.setUserId(identity.userEntityRef); + 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 }) { + static fromConfig( + config: Config, + options: { + identityApi?: IdentityApi; + userIdTransform?: + | 'sha-256' + | ((userEntityRef: string) => Promise); + }, + ) { const browserOptions: NewRelicBrowserOptions = { endpoint: config.getString('app.analytics.nr.endpoint'), accountId: config.getString('app.analytics.nr.accountId'), @@ -96,7 +114,11 @@ export class NewRelicBrowser implements AnalyticsApi { cookiesEnabled: config.getOptionalBoolean('app.analytics.nr.cookiesEnabled') ?? false, }; - return new NewRelicBrowser(browserOptions, options.identityApi); + return new NewRelicBrowser( + browserOptions, + options.identityApi, + options.userIdTransform, + ); } captureEvent(event: AnalyticsEvent) { @@ -138,4 +160,17 @@ export class NewRelicBrowser implements AnalyticsApi { 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(''); + } } From 82b8fc5bcf6e8bdba68f8149ff6c854a63fe1fbe Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 16:55:35 +0200 Subject: [PATCH 20/39] Add plugin to doc Signed-off-by: Jonathan Mezach --- docs/plugins/analytics.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 From 44fa2407236025e76e78fa18ce5a528f64a05917 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 19:03:32 +0200 Subject: [PATCH 21/39] Fix up API doc Signed-off-by: Jonathan Mezach --- plugins/analytics-module-newrelic-browser/api-report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/analytics-module-newrelic-browser/api-report.md b/plugins/analytics-module-newrelic-browser/api-report.md index 26b478f64d..7556bae317 100644 --- a/plugins/analytics-module-newrelic-browser/api-report.md +++ b/plugins/analytics-module-newrelic-browser/api-report.md @@ -17,6 +17,9 @@ export class NewRelicBrowser implements AnalyticsApi { config: Config, options: { identityApi?: IdentityApi; + userIdTransform?: + | 'sha-256' + | ((userEntityRef: string) => Promise); }, ): NewRelicBrowser; } From 369b0948c9d823ec98e1d362ec46abe678dac21b Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 19:24:01 +0200 Subject: [PATCH 22/39] Fix reference to plugin in changeset Signed-off-by: Jonathan Mezach --- .changeset/rude-feet-sparkle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rude-feet-sparkle.md b/.changeset/rude-feet-sparkle.md index 12cb5fd1f6..fabc83bb0b 100644 --- a/.changeset/rude-feet-sparkle.md +++ b/.changeset/rude-feet-sparkle.md @@ -2,4 +2,4 @@ '@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-new-relic) for more details! +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! From 8944880a2dd95012b80a319138d7f24a142e771c Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Wed, 12 Jul 2023 20:09:49 +0200 Subject: [PATCH 23/39] Process comments Signed-off-by: Jonathan Mezach --- .github/CODEOWNERS | 2 +- plugins/analytics-module-newrelic-browser/README.md | 2 +- plugins/analytics-module-newrelic-browser/config.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a2d5f4988a..5c957807cf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -17,7 +17,7 @@ /plugins/adr @backstage/maintainers @kuangp /plugins/adr-* @backstage/maintainers @kuangp /plugins/allure @backstage/maintainers @deepak-bhardwaj-ps -/plugins/analytics-module-nr @backstage/maintainers @jmezach +/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 diff --git a/plugins/analytics-module-newrelic-browser/README.md b/plugins/analytics-module-newrelic-browser/README.md index a94a60575e..37c335d295 100644 --- a/plugins/analytics-module-newrelic-browser/README.md +++ b/plugins/analytics-module-newrelic-browser/README.md @@ -10,7 +10,7 @@ This plugin contains no other functionality. ```sh # From your Backstage root directory -yarn add --cwd packages/app @backstage/plugin-analytics-module-nr +yarn add --cwd packages/app @backstage/plugin-analytics-module-newrelic-browser ``` 2. Wire up the API implementation to your App: diff --git a/plugins/analytics-module-newrelic-browser/config.d.ts b/plugins/analytics-module-newrelic-browser/config.d.ts index 22e99f3a15..9f90e1cd8f 100644 --- a/plugins/analytics-module-newrelic-browser/config.d.ts +++ b/plugins/analytics-module-newrelic-browser/config.d.ts @@ -19,7 +19,7 @@ export interface Config { analytics?: { nr: { /** - * Whether to use New Relic's EU Datacenter endpoints, defaults to false + * 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'; From 9ae4e7e638364b1278179c68775da718b9b00bfc Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Wed, 19 Jul 2023 13:09:48 +0200 Subject: [PATCH 24/39] Fix greedy home matching bug Signed-off-by: Eric Peterson --- .changeset/analytics-millenial-whoop.md | 5 + .github/vale/Vocab/Backstage/accept.txt | 1 + .../src/routing/RouteTracker.test.tsx | 94 ++++++++++++++++++- .../core-app-api/src/routing/RouteTracker.tsx | 7 +- 4 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 .changeset/analytics-millenial-whoop.md 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/.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/packages/core-app-api/src/routing/RouteTracker.test.tsx b/packages/core-app-api/src/routing/RouteTracker.test.tsx index 6bf58a117e..695e5bbf38 100644 --- a/packages/core-app-api/src/routing/RouteTracker.test.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.test.tsx @@ -25,23 +25,37 @@ 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 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', @@ -49,6 +63,7 @@ describe('RouteTracker', () => { routeRefs: new Set([routeRef2]), plugins: new Set(), caseSensitive: false, + children: [MATCH_ALL_ROUTE], }, ]; @@ -92,8 +107,8 @@ describe('RouteTracker', () => { - {routeObjects.map(({ routeRefs, ...props }) => ( - + {routeObjects.map(({ path, element }) => ( + ))} @@ -116,4 +131,79 @@ describe('RouteTracker', () => { 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 no plugin/routeRef is on the route', async () => { + render( + + + + + Non-extension} + /> + + + , + ); + + expect(mockedAnalytics.captureEvent).toHaveBeenCalledWith({ + action: 'navigate', + attributes: {}, + context: { + extension: 'App', + pluginId: 'root', + routeRef: 'unknown', + }, + subject: '/not-routable-extension', + value: undefined, + }); + }); }); diff --git a/packages/core-app-api/src/routing/RouteTracker.tsx b/packages/core-app-api/src/routing/RouteTracker.tsx index f1910728e3..bed72b6134 100644 --- a/packages/core-app-api/src/routing/RouteTracker.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.tsx @@ -39,10 +39,7 @@ const getExtensionContext = ( // Of the matching routes, get the last (e.g. most specific) instance of // the BackstageRouteObject. - - const routeMatch = matches - ?.filter(match => match?.route.routeRefs?.size > 0) - .pop(); + const routeMatch = matches?.pop(); const routeObject = routeMatch?.route; @@ -66,7 +63,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; From 0ed86cc838fc9b49ce83014130086e8ff31129bc Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Wed, 19 Jul 2023 17:56:17 +0200 Subject: [PATCH 25/39] Account for sub-route context inheritance Signed-off-by: Eric Peterson --- .../src/routing/RouteTracker.test.tsx | 31 +++++++++++++++++-- .../core-app-api/src/routing/RouteTracker.tsx | 14 +++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/core-app-api/src/routing/RouteTracker.test.tsx b/packages/core-app-api/src/routing/RouteTracker.test.tsx index 695e5bbf38..25d5cfbcfb 100644 --- a/packages/core-app-api/src/routing/RouteTracker.test.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.test.tsx @@ -39,6 +39,7 @@ describe('RouteTracker', () => { }); const plugin0 = createPlugin({ id: 'home' }); const plugin1 = createPlugin({ id: 'plugin1' }); + const plugin2 = createPlugin({ id: 'plugin2' }); const routeObjects: BackstageRouteObject[] = [ { @@ -61,7 +62,7 @@ describe('RouteTracker', () => { path: '/path2/:param', element:
hi there
, routeRefs: new Set([routeRef2]), - plugins: new Set(), + plugins: new Set([plugin2]), caseSensitive: false, children: [MATCH_ALL_ROUTE], }, @@ -124,7 +125,7 @@ describe('RouteTracker', () => { }, context: { extension: 'App', - pluginId: 'root', + pluginId: 'plugin2', routeRef: 'route2', }, subject: '/path2/hello', @@ -179,7 +180,7 @@ describe('RouteTracker', () => { }); }); - it('should return default context when no plugin/routeRef is on the route', async () => { + it('should return default context when it would have otherwise matched on the root path', async () => { render( @@ -206,4 +207,28 @@ describe('RouteTracker', () => { 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 bed72b6134..69903268ac 100644 --- a/packages/core-app-api/src/routing/RouteTracker.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.tsx @@ -38,9 +38,11 @@ const getExtensionContext = ( const matches = matchRoutes(routes, { pathname }); // Of the matching routes, get the last (e.g. most specific) instance of - // the BackstageRouteObject. - const routeMatch = matches?.pop(); - + // 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. @@ -48,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) { From 5bbee4c954ded498f2ef7351ff295afc26760d77 Mon Sep 17 00:00:00 2001 From: Jonathan Mezach Date: Thu, 20 Jul 2023 14:54:06 +0200 Subject: [PATCH 26/39] Renamed config settings Signed-off-by: Jonathan Mezach --- .../analytics-module-newrelic-browser/README.md | 10 +++++----- .../config.d.ts | 2 +- .../dev/index.tsx | 2 +- .../AnalyticsApi/NewRelicBrowser.ts | 16 ++++++++-------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/analytics-module-newrelic-browser/README.md b/plugins/analytics-module-newrelic-browser/README.md index 37c335d295..2fe3956d2d 100644 --- a/plugins/analytics-module-newrelic-browser/README.md +++ b/plugins/analytics-module-newrelic-browser/README.md @@ -47,7 +47,7 @@ in New Relic Browser using the Copy/Paste method. # app-config.yaml app: analytics: - nr: + newRelic: endpoint: 'bam.nr-data.net', accountId: '1234567' applicationId: '987654321' @@ -64,7 +64,7 @@ By default the distributed tracing and cookies features are disabled. You can en # app-config.yaml app: analytics: - nr: + newRelic: ... distributedTracing: true cookiesEnabled: true @@ -109,9 +109,9 @@ make and test changes is to do the following: 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-nr` +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/nr` +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. @@ -125,7 +125,7 @@ Paste this into your `app-config.local.yaml` while developing this plugin: ```yaml app: analytics: - nr: + newRelic: accountId: '1234567' applicationId: '987654321' licenseKey: 'NRJS-12a3456bc78de9123f4' diff --git a/plugins/analytics-module-newrelic-browser/config.d.ts b/plugins/analytics-module-newrelic-browser/config.d.ts index 9f90e1cd8f..e653f3af7d 100644 --- a/plugins/analytics-module-newrelic-browser/config.d.ts +++ b/plugins/analytics-module-newrelic-browser/config.d.ts @@ -17,7 +17,7 @@ export interface Config { app: { analytics?: { - nr: { + newRelic: { /** * Data ingestion endpoint to use, either bam.eu01.nr-data.net (EU) or bam.nr-data.net (US) * @visibility frontend diff --git a/plugins/analytics-module-newrelic-browser/dev/index.tsx b/plugins/analytics-module-newrelic-browser/dev/index.tsx index 5524a48b68..15caacfe61 100644 --- a/plugins/analytics-module-newrelic-browser/dev/index.tsx +++ b/plugins/analytics-module-newrelic-browser/dev/index.tsx @@ -33,7 +33,7 @@ createDevApp() }), }) .addPage({ - path: '/nr', + path: '/newrelic', title: 'New Relic Playground', element: , }) 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 index 293c0a9b45..f2f35b5765 100644 --- a/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts +++ b/plugins/analytics-module-newrelic-browser/src/apis/implementations/AnalyticsApi/NewRelicBrowser.ts @@ -102,17 +102,17 @@ export class NewRelicBrowser implements AnalyticsApi { | ((userEntityRef: string) => Promise); }, ) { + const newRelicBrowserConfig = config.getConfig('app.analytics.newRelic'); const browserOptions: NewRelicBrowserOptions = { - endpoint: config.getString('app.analytics.nr.endpoint'), - accountId: config.getString('app.analytics.nr.accountId'), - applicationId: config.getString('app.analytics.nr.applicationId'), - licenseKey: config.getString('app.analytics.nr.licenseKey'), + endpoint: newRelicBrowserConfig.getString('endpoint'), + accountId: newRelicBrowserConfig.getString('accountId'), + applicationId: newRelicBrowserConfig.getString('applicationId'), + licenseKey: newRelicBrowserConfig.getString('licenseKey'), distributedTracingEnabled: - config.getOptionalBoolean( - 'app.analytics.nr.distributedTracingEnabled', - ) ?? false, + newRelicBrowserConfig.getOptionalBoolean('distributedTracingEnabled') ?? + false, cookiesEnabled: - config.getOptionalBoolean('app.analytics.nr.cookiesEnabled') ?? false, + newRelicBrowserConfig.getOptionalBoolean('cookiesEnabled') ?? false, }; return new NewRelicBrowser( browserOptions, From 78a3acd9652db39eecb9910cebaad1007d4cb3aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 13:03:17 +0000 Subject: [PATCH 27/39] Bump semver from 5.7.1 to 5.7.2 in /storybook Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] --- storybook/yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 From bd62c30b059784dc8176d766f4c38ee73f03c059 Mon Sep 17 00:00:00 2001 From: Moyeong Lee Date: Fri, 21 Jul 2023 18:27:26 +0200 Subject: [PATCH 28/39] Pass missing templateName prop down to Stepper in Workflow Signed-off-by: Moyeong Lee --- .../scaffolder-react/src/next/components/Workflow/Workflow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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' }} > - + )} From ba9ee98a37bd7b4e7249c7e74c1fd623f9ee0033 Mon Sep 17 00:00:00 2001 From: Moyeong Lee Date: Fri, 21 Jul 2023 18:28:25 +0200 Subject: [PATCH 29/39] Add changeset Signed-off-by: Moyeong Lee --- .changeset/ten-otters-appear.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/ten-otters-appear.md diff --git a/.changeset/ten-otters-appear.md b/.changeset/ten-otters-appear.md new file mode 100644 index 0000000000..6b3f8e1f05 --- /dev/null +++ b/.changeset/ten-otters-appear.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': minor +--- + +Fixed bug in Workflow component by passing a prop `templateName` down to Stepper component. From 70cc6c458e08fdd07314ecfd8e5019ca9cf303e7 Mon Sep 17 00:00:00 2001 From: Antonio Ereiz Date: Fri, 21 Jul 2023 20:53:38 +0200 Subject: [PATCH 30/39] send copy of options instead of original Signed-off-by: Antonio Ereiz --- plugins/linguist-backend/src/api/LinguistBackendClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } } From ca5e591cb86aacc98f16cdcbd40831de72533325 Mon Sep 17 00:00:00 2001 From: Antonio Ereiz Date: Fri, 21 Jul 2023 21:02:06 +0200 Subject: [PATCH 31/39] changeset Signed-off-by: Antonio Ereiz --- .changeset/large-experts-poke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/large-experts-poke.md 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 From f66ceed16e4fe54c286e593d241f39a89f2a35c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 23 Jul 2023 07:17:39 +0000 Subject: [PATCH 32/39] chore(deps): update dependency esbuild to v0.18.16 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 182 +++++++++++++++++++++++++++--------------------------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/yarn.lock b/yarn.lock index 05be39bde2..8ac04d89aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10232,9 +10232,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 +10253,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 +10267,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 +10281,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 +10295,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 +10309,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 +10323,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 +10337,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 +10351,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 +10365,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 +10386,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 +10400,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 +10414,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 +10428,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 +10442,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 +10456,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 +10470,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 +10484,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 +10498,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 +10512,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 +10526,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 +10540,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 @@ -24085,31 +24085,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 +24157,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 6512b7e186cffb4546f3508f1e2d1dd27eb43a8a8a79d4ea7eb34ae3dbdc647679ae96b29c54a4951c355ee3168e8ad9c128cbfc033154b0849e269276d5bc9c + checksum: 8b04f7087d4e95cffd43c37663c57a9f42e183cd3d02fe3cefee7e1534a84d5cec181f42187715471b4b3f5478e2e110530df7d3a8b12053cbc8cc35145363ab languageName: node linkType: hard From 1eb92c06417eab96111c01ead62389986b5d6b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 24 Jul 2023 10:05:54 +0200 Subject: [PATCH 33/39] sort package.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/catalog-graph/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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", From bf7c59981e23dcfb74f41652917d86360f8ac1ac Mon Sep 17 00:00:00 2001 From: Raffi Tamizian <3493656+raffitamizian@users.noreply.github.com> Date: Mon, 24 Jul 2023 09:17:06 +0100 Subject: [PATCH 34/39] Update microsite navbar releases link Signed-off-by: Raffi Tamizian <3493656+raffitamizian@users.noreply.github.com> --- microsite/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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', }, From ee1f642b5fc95862b3805e27594ca71a850babaa Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Mon, 24 Jul 2023 10:25:50 +0200 Subject: [PATCH 35/39] Update ten-otters-appear.md Signed-off-by: Ben Lambert --- .changeset/ten-otters-appear.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/ten-otters-appear.md b/.changeset/ten-otters-appear.md index 6b3f8e1f05..4cb3d301ae 100644 --- a/.changeset/ten-otters-appear.md +++ b/.changeset/ten-otters-appear.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder-react': patch --- Fixed bug in Workflow component by passing a prop `templateName` down to Stepper component. From b94229377c567f7495bddd88ad31b7630715f77e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 12:27:31 +0000 Subject: [PATCH 36/39] chore(deps): update dependency @types/node to v20.4.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3f27184eb5..916ce09ac7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17361,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 @@ -17382,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 @@ -17396,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 From 6d030f0e502d3e79022a3050008fa48b56f1f7bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 14:50:38 +0000 Subject: [PATCH 37/39] fix(deps): update apollo graphql packages Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 916ce09ac7..1e30679b5d 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 From 635a59ea724af88e1ba901eca6551c097ca92718 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 14:51:08 +0000 Subject: [PATCH 38/39] fix(deps): update codemirror Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 916ce09ac7..a457cb8709 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9858,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 @@ -9908,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 From 22c56ea37e2e08b1a29d6d8777ac961826c35770 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 16:02:31 +0000 Subject: [PATCH 39/39] fix(deps): update dependency @roadiehq/backstage-plugin-buildkite to v2.1.13 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 31d06e00d7..4b55c6d0a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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: @@ -5503,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: @@ -9501,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: @@ -14152,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 @@ -14171,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