From d3fea4ae0ac411fed3b22143a2e13536c6968f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 22 Nov 2022 15:36:22 +0100 Subject: [PATCH] avoid globals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/eight-spiders-know.md | 15 ++ .eslintrc.js | 174 ++++++++++++++++++ .github/vale/Vocab/Backstage/accept.txt | 1 + packages/backend-common/src/scm/git.ts | 2 +- .../IdentityApi/AppIdentityProxy.test.ts | 2 +- .../IdentityApi/AppIdentityProxy.ts | 2 +- .../lib/AuthConnector/DefaultAuthConnector.ts | 2 +- .../HorizontalScrollGrid.tsx | 4 +- .../version-bridge/src/lib/globalObject.ts | 2 + .../AnalyticsApi/GoogleAnalytics.ts | 2 +- .../EntityContextMenu/EntityContextMenu.tsx | 2 +- .../WorkflowRunDetails/WorkflowRunDetails.tsx | 1 + .../ProjectDetailsPage/ProjectDetailsPage.tsx | 4 +- .../WorkflowRunDetails/WorkflowRunDetails.tsx | 4 +- .../WorkflowRunLogs/WorkflowRunLogs.tsx | 2 - .../graphiql/src/lib/storage/StorageBucket.ts | 2 +- .../src/TextSize/TextSize.test.tsx | 8 +- .../transformers/copyToClipboard.test.ts | 2 +- .../reader/transformers/copyToClipboard.tsx | 2 +- 19 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 .changeset/eight-spiders-know.md diff --git a/.changeset/eight-spiders-know.md b/.changeset/eight-spiders-know.md new file mode 100644 index 0000000000..2e3e54dc0f --- /dev/null +++ b/.changeset/eight-spiders-know.md @@ -0,0 +1,15 @@ +--- +'@backstage/backend-common': patch +'@backstage/core-app-api': patch +'@backstage/core-components': patch +'@backstage/version-bridge': patch +'@backstage/plugin-analytics-module-ga': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-gcp-projects': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-techdocs': patch +--- + +Internal fixes to avoid implicit usage of globals diff --git a/.eslintrc.js b/.eslintrc.js index 6d07fab291..0257a2af1e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,5 +50,179 @@ module.exports = { 'testing-library/no-await-sync-query': 'error', 'testing-library/prefer-wait-for': 'error', 'testing-library/no-dom-import': 'error', + 'no-restricted-globals': [ + 'error', + 'postMessage', + 'blur', + 'focus', + 'close', + 'frames', + 'self', + 'parent', + 'opener', + 'top', + 'length', + 'closed', + 'location', + 'origin', + 'name', + 'locationbar', + 'menubar', + 'personalbar', + 'scrollbars', + 'statusbar', + 'toolbar', + 'status', + 'frameElement', + 'navigator', + 'customElements', + 'external', + 'screen', + 'innerWidth', + 'innerHeight', + 'scrollX', + 'pageXOffset', + 'scrollY', + 'pageYOffset', + 'screenX', + 'screenY', + 'outerWidth', + 'outerHeight', + 'devicePixelRatio', + 'clientInformation', + 'screenLeft', + 'screenTop', + 'defaultStatus', + 'defaultstatus', + 'styleMedia', + 'onanimationend', + 'onanimationiteration', + 'onanimationstart', + 'onsearch', + 'ontransitionend', + 'onwebkitanimationend', + 'onwebkitanimationiteration', + 'onwebkitanimationstart', + 'onwebkittransitionend', + 'isSecureContext', + 'onabort', + 'onblur', + 'oncancel', + 'oncanplay', + 'oncanplaythrough', + 'onchange', + 'onclick', + 'onclose', + 'oncontextmenu', + 'oncuechange', + 'ondblclick', + 'ondrag', + 'ondragend', + 'ondragenter', + 'ondragleave', + 'ondragover', + 'ondragstart', + 'ondrop', + 'ondurationchange', + 'onemptied', + 'onended', + 'onerror', + 'onfocus', + 'oninput', + 'oninvalid', + 'onkeydown', + 'onkeypress', + 'onkeyup', + 'onload', + 'onloadeddata', + 'onloadedmetadata', + 'onloadstart', + 'onmousedown', + 'onmouseenter', + 'onmouseleave', + 'onmousemove', + 'onmouseout', + 'onmouseover', + 'onmouseup', + 'onmousewheel', + 'onpause', + 'onplay', + 'onplaying', + 'onprogress', + 'onratechange', + 'onreset', + 'onresize', + 'onscroll', + 'onseeked', + 'onseeking', + 'onselect', + 'onstalled', + 'onsubmit', + 'onsuspend', + 'ontimeupdate', + 'ontoggle', + 'onvolumechange', + 'onwaiting', + 'onwheel', + 'onauxclick', + 'ongotpointercapture', + 'onlostpointercapture', + 'onpointerdown', + 'onpointermove', + 'onpointerup', + 'onpointercancel', + 'onpointerover', + 'onpointerout', + 'onpointerenter', + 'onpointerleave', + 'onafterprint', + 'onbeforeprint', + 'onbeforeunload', + 'onhashchange', + 'onlanguagechange', + 'onmessage', + 'onmessageerror', + 'onoffline', + 'ononline', + 'onpagehide', + 'onpageshow', + 'onpopstate', + 'onrejectionhandled', + 'onstorage', + 'onunhandledrejection', + 'onunload', + 'performance', + 'stop', + 'open', + 'print', + 'captureEvents', + 'releaseEvents', + 'getComputedStyle', + 'matchMedia', + 'moveTo', + 'moveBy', + 'resizeTo', + 'resizeBy', + 'getSelection', + 'find', + 'createImageBitmap', + 'scroll', + 'scrollTo', + 'scrollBy', + 'onappinstalled', + 'onbeforeinstallprompt', + 'crypto', + 'ondevicemotion', + 'ondeviceorientation', + 'ondeviceorientationabsolute', + 'indexedDB', + 'webkitStorageInfo', + 'chrome', + 'visualViewport', + 'speechSynthesis', + 'webkitRequestFileSystem', + 'webkitResolveLocalFileSystemURL', + 'openDatabase', + ], }, }; diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index f2b3ac0b09..620432376d 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -126,6 +126,7 @@ github Gitiles gitlab GitLab +globals Gource Grafana graphql diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts index 0c9252cb64..ea28ffb9b2 100644 --- a/packages/backend-common/src/scm/git.ts +++ b/packages/backend-common/src/scm/git.ts @@ -179,7 +179,7 @@ export class Git { }); } catch (ex) { this.config.logger?.error( - `Failed to fetch repo {dir=${dir},origin=${origin}}`, + `Failed to fetch repo {dir=${dir},remote=${remote}}`, ); if (ex.data) { throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); diff --git a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts index 6fa46db7c9..5993543c33 100644 --- a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts +++ b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts @@ -89,6 +89,6 @@ describe('AppIdentityProxy', () => { }); await proxy.signOut(); - expect(location.href).toBe('/foo'); + expect(window.location.href).toBe('/foo'); }); }); diff --git a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts index 2df351bc18..4a51444879 100644 --- a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts +++ b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts @@ -124,6 +124,6 @@ export class AppIdentityProxy implements IdentityApi { async signOut(): Promise { await this.waitForTarget.then(target => target.signOut()); - location.href = this.signOutTargetUrl; + window.location.href = this.signOutTargetUrl; } } diff --git a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts index a467957063..988c9f17b1 100644 --- a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts +++ b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts @@ -154,7 +154,7 @@ export class DefaultAuthConnector const scope = this.joinScopesFunc(scopes); const popupUrl = await this.buildUrl('/start', { scope, - origin: location.origin, + origin: window.location.origin, }); const payload = await showLoginPopup({ diff --git a/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx b/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx index 8c5dc4d530..4ab49596fe 100644 --- a/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx +++ b/packages/core-components/src/components/HorizontalScrollGrid/HorizontalScrollGrid.tsx @@ -155,7 +155,7 @@ function useScrollDistance( return [scrollLeft, scrollRight]; } -// Used to animate scrolling. Returns a single setScrollTarger function, when called with e.g. 200, +// Used to animate scrolling. Returns a single setScrollTarget function, when called with e.g. 200, // the element pointer to by the ref will be scrolled 200px forwards over time. function useSmoothScroll( ref: React.MutableRefObject, @@ -169,7 +169,7 @@ function useSmoothScroll( return; } - const startTime = performance.now(); + const startTime = window.performance.now(); const id = requestAnimationFrame(frameTime => { if (!ref.current) { return; diff --git a/packages/version-bridge/src/lib/globalObject.ts b/packages/version-bridge/src/lib/globalObject.ts index b29e81e4a0..19b6b73ccf 100644 --- a/packages/version-bridge/src/lib/globalObject.ts +++ b/packages/version-bridge/src/lib/globalObject.ts @@ -19,7 +19,9 @@ function getGlobalObject() { if (typeof window !== 'undefined' && window.Math === Math) { return window; } + // eslint-disable-next-line no-restricted-globals if (typeof self !== 'undefined' && self.Math === Math) { + // eslint-disable-next-line no-restricted-globals return self; } // eslint-disable-next-line no-new-func diff --git a/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts index ad7205983c..498b118d0d 100644 --- a/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts +++ b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts @@ -241,7 +241,7 @@ export class GoogleAnalytics implements AnalyticsApi { * Simple hash function; relies on web cryptography + the sha-256 algorithm. */ private async hash(value: string): Promise { - const digest = await crypto.subtle.digest( + const digest = await window.crypto.subtle.digest( 'sha-256', new TextEncoder().encode(value), ); diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx index 49952bdffe..f7a329c7be 100644 --- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx @@ -89,7 +89,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) { const alertApi = useApi(alertApiRef); const copyToClipboard = useCallback(() => { - navigator.clipboard + window.navigator.clipboard .writeText(window.location.toString()) .then(() => alertApi.post({ message: 'Copied!', severity: 'info' })); }, [alertApi]); diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index aacb437e7b..a35d9b6f6c 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { Box, diff --git a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx index b900b81695..364033ce73 100644 --- a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx +++ b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx @@ -61,7 +61,9 @@ const DetailsPage = () => { const classes = useStyles(); const [{ status, result: details, error }, { execute }] = useAsync(async () => - api.getProject(decodeURIComponent(location.search.split('projectId=')[1])), + api.getProject( + decodeURIComponent(window.location.search.split('projectId=')[1]), + ), ); useMountEffect(execute); diff --git a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index f05ea692f5..a2c87772d5 100644 --- a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { readGithubIntegrationConfigs } from '@backstage/integration'; import { @@ -43,7 +44,6 @@ import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { useWorkflowRunJobs } from './useWorkflowRunJobs'; import { useWorkflowRunsDetails } from './useWorkflowRunsDetails'; import { WorkflowRunLogs } from '../WorkflowRunLogs'; - import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { Breadcrumbs, Link } from '@backstage/core-components'; @@ -116,8 +116,6 @@ const JobListItem = ({ } - aria-controls={`panel-${name}-content`} - id={`panel-${name}-header`} IconButtonProps={{ className: classes.button, }} diff --git a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx index 075b73dd98..2c9d41398a 100644 --- a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx +++ b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx @@ -105,8 +105,6 @@ export const WorkflowRunLogs = ({ } - aria-controls={`panel-${name}-content`} - id={`panel-${name}-header`} IconButtonProps={{ className: classes.button, }} diff --git a/plugins/graphiql/src/lib/storage/StorageBucket.ts b/plugins/graphiql/src/lib/storage/StorageBucket.ts index a2b87238a6..dc2c0d4f85 100644 --- a/plugins/graphiql/src/lib/storage/StorageBucket.ts +++ b/plugins/graphiql/src/lib/storage/StorageBucket.ts @@ -47,7 +47,7 @@ export class StorageBucket implements Storage { private readonly bucket: string, ) {} - [name: string]: any; + [itemName: string]: any; get length(): number { throw new Error('Method not implemented.'); diff --git a/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx b/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx index 6b4a055c2a..081c718c2f 100644 --- a/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx +++ b/plugins/techdocs-module-addons-contrib/src/TextSize/TextSize.test.tsx @@ -59,7 +59,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('115%'); - let style = getComputedStyle(getByText('TEST_CONTENT')); + let style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('18.4px'); @@ -73,7 +73,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('100%'); - style = getComputedStyle(getByText('TEST_CONTENT')); + style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('16px'); }); @@ -105,7 +105,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('115%'); - let style = getComputedStyle(getByText('TEST_CONTENT')); + let style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('18.4px'); @@ -117,7 +117,7 @@ describe('TextSize', () => { expect(slider).toHaveTextContent('100%'); - style = getComputedStyle(getByText('TEST_CONTENT')); + style = window.getComputedStyle(getByText('TEST_CONTENT')); expect(style.getPropertyValue('--md-typeset-font-size')).toBe('16px'); }); diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts index 4613df374d..9c4ee08346 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts @@ -20,7 +20,7 @@ import { lightTheme } from '@backstage/theme'; import { waitFor } from '@testing-library/react'; const clipboardSpy = jest.fn(); -Object.defineProperty(navigator, 'clipboard', { +Object.defineProperty(window.navigator, 'clipboard', { value: { writeText: clipboardSpy, }, diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx index 25a1d67f65..6adb4252d3 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx @@ -49,7 +49,7 @@ const CopyToClipboardButton = ({ text }: CopyToClipboardButtonProps) => { const [open, setOpen] = useState(false); const handleClick = useCallback(() => { - navigator.clipboard.writeText(text); + window.navigator.clipboard.writeText(text); setOpen(true); }, [text]);