From d25840218685017458d456747b341938aac870bd Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 30 Nov 2022 11:32:56 +0000 Subject: [PATCH] Typescript updates (#9658) * Typescript updates * Update @types/node * Fix more types --- package.json | 4 ++-- src/@types/global.d.ts | 4 ---- src/DecryptionFailureTracker.ts | 4 ++-- src/LegacyCallHandler.tsx | 2 +- src/Lifecycle.ts | 4 ++-- src/NodeAnimator.tsx | 2 +- src/PasswordReset.ts | 2 +- src/audio/PlaybackClock.ts | 2 +- src/autocomplete/Autocompleter.ts | 2 +- src/autocomplete/EmojiProvider.tsx | 10 +++++----- src/components/structures/InteractiveAuth.tsx | 2 +- src/components/structures/MatrixChat.tsx | 2 +- src/components/structures/ScrollPanel.tsx | 4 ++-- src/components/views/dialogs/InviteDialog.tsx | 2 +- .../views/dialogs/SlidingSyncOptionsDialog.tsx | 2 +- .../dialogs/devtools/VerificationExplorer.tsx | 2 +- .../views/dialogs/spotlight/SpotlightDialog.tsx | 2 +- .../elements/DesktopCapturerSourcePicker.tsx | 4 ++-- .../views/elements/UseCaseSelection.tsx | 2 +- src/components/views/emojipicker/EmojiPicker.tsx | 2 +- src/components/views/emojipicker/Search.tsx | 4 ++-- src/components/views/messages/MImageBody.tsx | 2 +- src/components/views/messages/TextualBody.tsx | 2 +- src/components/views/rooms/Autocomplete.tsx | 2 +- src/components/views/rooms/MessageComposer.tsx | 4 ++-- src/components/views/rooms/RoomBreadcrumbs.tsx | 2 +- .../rooms/wysiwyg_composer/hooks/useIsFocused.ts | 2 +- .../views/rooms/wysiwyg_composer/hooks/utils.ts | 2 +- .../views/settings/ThemeChoicePanel.tsx | 2 +- .../settings/tabs/user/SessionManagerTab.tsx | 2 +- .../views/toasts/VerificationRequestToast.tsx | 2 +- .../views/user-onboarding/UserOnboardingPage.tsx | 2 +- src/components/views/voip/CallDuration.tsx | 2 +- src/dispatcher/dispatcher.ts | 2 +- src/hooks/spotlight/useDebouncedCallback.ts | 2 +- src/hooks/useTimeout.ts | 4 ++-- src/hooks/useTimeoutToggle.ts | 2 +- src/hooks/useUserOnboardingContext.ts | 2 +- src/models/Call.ts | 6 +++--- src/rageshake/rageshake.ts | 2 +- src/stores/OwnBeaconStore.ts | 2 +- src/stores/room-list/RoomListStore.ts | 2 +- src/theme.ts | 2 +- src/utils/MultiInviter.ts | 2 +- src/utils/Timer.ts | 4 ++-- src/utils/WidgetUtils.ts | 4 ++-- src/utils/exportUtils/exportJS.js | 2 +- src/utils/image-media.ts | 6 +++--- src/utils/local-room.ts | 4 ++-- src/utils/membership.ts | 2 +- src/utils/promise.ts | 2 +- test/ContentMessages-test.ts | 2 +- .../views/location/LocationShareMenu-test.tsx | 2 +- .../views/settings/Notifications-test.tsx | 2 +- test/setup/setupManualMocks.ts | 2 +- test/test-utils/beacon.ts | 2 +- test/test-utils/utilities.ts | 6 +++--- .../startNewVoiceBroadcastRecording-test.ts | 2 +- yarn.lock | 16 ++++++++-------- 59 files changed, 86 insertions(+), 90 deletions(-) diff --git a/package.json b/package.json index f9733e7890..b54ee741b0 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,7 @@ "@types/katex": "^0.14.0", "@types/lodash": "^4.14.168", "@types/modernizr": "^3.5.3", - "@types/node": "^14.18.28", + "@types/node": "^16", "@types/pako": "^1.0.1", "@types/parse5": "^6.0.0", "@types/qrcode": "^1.3.5", @@ -212,7 +212,7 @@ "stylelint": "^14.9.1", "stylelint-config-standard": "^26.0.0", "stylelint-scss": "^4.2.0", - "typescript": "4.8.4", + "typescript": "4.9.3", "walk": "^2.3.14" }, "jest": { diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index c4971d24f1..99d963ac9b 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -149,14 +149,10 @@ declare global { // https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas interface OffscreenCanvas { - height: number; - width: number; - getContext: HTMLCanvasElement["getContext"]; convertToBlob(opts?: { type?: string; quality?: number; }): Promise; - transferToImageBitmap(): ImageBitmap; } interface HTMLAudioElement { diff --git a/src/DecryptionFailureTracker.ts b/src/DecryptionFailureTracker.ts index b0d9b7ef58..1b01b906b5 100644 --- a/src/DecryptionFailureTracker.ts +++ b/src/DecryptionFailureTracker.ts @@ -174,12 +174,12 @@ export class DecryptionFailureTracker { * Start checking for and tracking failures. */ public start(): void { - this.checkInterval = setInterval( + this.checkInterval = window.setInterval( () => this.checkFailures(Date.now()), DecryptionFailureTracker.CHECK_INTERVAL_MS, ); - this.trackInterval = setInterval( + this.trackInterval = window.setInterval( () => this.trackFailures(), DecryptionFailureTracker.TRACK_INTERVAL_MS, ); diff --git a/src/LegacyCallHandler.tsx b/src/LegacyCallHandler.tsx index 41098dcb4d..e13b0ec85c 100644 --- a/src/LegacyCallHandler.tsx +++ b/src/LegacyCallHandler.tsx @@ -254,7 +254,7 @@ export default class LegacyCallHandler extends EventEmitter { logger.log("Failed to check for protocol support and no retries remain: assuming no support", e); } else { logger.log("Failed to check for protocol support: will retry", e); - setTimeout(() => { + window.setTimeout(() => { this.checkProtocols(maxTries - 1); }, 10000); } diff --git a/src/Lifecycle.ts b/src/Lifecycle.ts index 9351e91ae4..1c075e8c2c 100644 --- a/src/Lifecycle.ts +++ b/src/Lifecycle.ts @@ -584,7 +584,7 @@ async function doSetLoggedIn( // later than MatrixChat might assume. // // we fire it *synchronously* to make sure it fires before on_logged_in. - // (dis.dispatch uses `setTimeout`, which does not guarantee ordering.) + // (dis.dispatch uses `window.setTimeout`, which does not guarantee ordering.) dis.dispatch({ action: 'on_logging_in' }, true); if (clearStorageEnabled) { @@ -865,7 +865,7 @@ export async function onLoggedOut(): Promise { if (SdkConfig.get().logout_redirect_url) { logger.log("Redirecting to external provider to finish logout"); // XXX: Defer this so that it doesn't race with MatrixChat unmounting the world by going to /#/login - setTimeout(() => { + window.setTimeout(() => { window.location.href = SdkConfig.get().logout_redirect_url; }, 100); } diff --git a/src/NodeAnimator.tsx b/src/NodeAnimator.tsx index 77ab976347..a0d655be9b 100644 --- a/src/NodeAnimator.tsx +++ b/src/NodeAnimator.tsx @@ -119,7 +119,7 @@ export default class NodeAnimator extends React.Component { } // and then we animate to the resting state - setTimeout(() => { + window.setTimeout(() => { this.applyStyles(domNode as HTMLElement, restingStyle); }, 0); } diff --git a/src/PasswordReset.ts b/src/PasswordReset.ts index 8f3c9bd91e..1f2c541270 100644 --- a/src/PasswordReset.ts +++ b/src/PasswordReset.ts @@ -119,7 +119,7 @@ export default class PasswordReset { this.checkEmailLinkClicked() .then(() => resolve()) .catch(() => { - setTimeout( + window.setTimeout( () => this.tryCheckEmailLinkClicked(resolve), CHECK_EMAIL_VERIFIED_POLL_INTERVAL, ); diff --git a/src/audio/PlaybackClock.ts b/src/audio/PlaybackClock.ts index f38be9d134..c3fbb4a3f4 100644 --- a/src/audio/PlaybackClock.ts +++ b/src/audio/PlaybackClock.ts @@ -127,7 +127,7 @@ export class PlaybackClock implements IDestroyable { // cast to number because the types are wrong // 100ms interval to make sure the time is as accurate as possible without // being overly insane - this.timerId = setInterval(this.checkTime, 100); + this.timerId = window.setInterval(this.checkTime, 100); } } diff --git a/src/autocomplete/Autocompleter.ts b/src/autocomplete/Autocompleter.ts index 0c7ef1afb2..7f124213c7 100644 --- a/src/autocomplete/Autocompleter.ts +++ b/src/autocomplete/Autocompleter.ts @@ -35,7 +35,7 @@ export interface ISelectionRange { } export interface ICompletion { - type: "at-room" | "command" | "community" | "room" | "user"; + type?: "at-room" | "command" | "community" | "room" | "user"; completion: string; completionId?: string; component?: ReactElement; diff --git a/src/autocomplete/EmojiProvider.tsx b/src/autocomplete/EmojiProvider.tsx index 4a2c37988a..38cb092a96 100644 --- a/src/autocomplete/EmojiProvider.tsx +++ b/src/autocomplete/EmojiProvider.tsx @@ -103,7 +103,7 @@ export default class EmojiProvider extends AutocompleteProvider { return []; // don't give any suggestions if the user doesn't want them } - let completions = []; + let completions: ISortedEmoji[] = []; const { command, range } = this.getCurrentCommand(query, selection); if (command && command[0].length > 2) { @@ -132,7 +132,7 @@ export default class EmojiProvider extends AutocompleteProvider { } // Finally, sort by original ordering sorters.push(c => c._orderBy); - completions = sortBy(uniq(completions), sorters); + completions = sortBy(uniq(completions), sorters); completions = completions.slice(0, LIMIT); @@ -141,9 +141,9 @@ export default class EmojiProvider extends AutocompleteProvider { this.recentlyUsed.forEach(emoji => { sorters.push(c => score(emoji.shortcodes[0], c.emoji.shortcodes[0])); }); - completions = sortBy(uniq(completions), sorters); + completions = sortBy(uniq(completions), sorters); - completions = completions.map(c => ({ + return completions.map(c => ({ completion: c.emoji.unicode, component: ( @@ -153,7 +153,7 @@ export default class EmojiProvider extends AutocompleteProvider { range, })); } - return completions; + return []; } getName() { diff --git a/src/components/structures/InteractiveAuth.tsx b/src/components/structures/InteractiveAuth.tsx index b33fb73791..8152aae251 100644 --- a/src/components/structures/InteractiveAuth.tsx +++ b/src/components/structures/InteractiveAuth.tsx @@ -127,7 +127,7 @@ export default class InteractiveAuthComponent extends React.Component { + this.intervalId = window.setInterval(() => { this.authLogic.poll(); }, 2000); } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 04fb4a0fae..9327a45ea2 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1965,7 +1965,7 @@ export default class MatrixChat extends React.PureComponent { this.accountPassword = password; // self-destruct the password after 5mins if (this.accountPasswordTimer !== null) clearTimeout(this.accountPasswordTimer); - this.accountPasswordTimer = setTimeout(() => { + this.accountPasswordTimer = window.setTimeout(() => { this.accountPassword = null; this.accountPasswordTimer = null; }, 60 * 5 * 1000); diff --git a/src/components/structures/ScrollPanel.tsx b/src/components/structures/ScrollPanel.tsx index e902599b0f..b8b6f53a5f 100644 --- a/src/components/structures/ScrollPanel.tsx +++ b/src/components/structures/ScrollPanel.tsx @@ -459,7 +459,7 @@ export default class ScrollPanel extends React.Component { if (this.unfillDebouncer) { clearTimeout(this.unfillDebouncer); } - this.unfillDebouncer = setTimeout(() => { + this.unfillDebouncer = window.setTimeout(() => { this.unfillDebouncer = null; debuglog("unfilling now", { backwards, origExcessHeight }); this.props.onUnfillRequest?.(backwards, markerScrollToken!); @@ -485,7 +485,7 @@ export default class ScrollPanel extends React.Component { // this will block the scroll event handler for +700ms // if messages are already cached in memory, // This would cause jumping to happen on Chrome/macOS. - return new Promise(resolve => setTimeout(resolve, 1)).then(() => { + return new Promise(resolve => window.setTimeout(resolve, 1)).then(() => { return this.props.onFillRequest(backwards); }).finally(() => { this.pendingFillRequests[dir] = false; diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 30c1f4d154..7a495393cf 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -697,7 +697,7 @@ export default class InviteDialog extends React.PureComponent { + this.debounceTimer = window.setTimeout(() => { this.updateSuggestions(term); }, 150); // 150ms debounce (human reaction time + some) }; diff --git a/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx b/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx index ea5c77d7f7..f1f818313e 100644 --- a/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx +++ b/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx @@ -48,7 +48,7 @@ async function syncHealthCheck(cli: MatrixClient): Promise { */ async function proxyHealthCheck(endpoint: string, hsUrl?: string): Promise { const controller = new AbortController(); - const id = setTimeout(() => controller.abort(), 10 * 1000); // 10s + const id = window.setTimeout(() => controller.abort(), 10 * 1000); // 10s const res = await fetch(endpoint + "/client/server.json", { signal: controller.signal, }); diff --git a/src/components/views/dialogs/devtools/VerificationExplorer.tsx b/src/components/views/dialogs/devtools/VerificationExplorer.tsx index 6d3fe36245..6673c4ca04 100644 --- a/src/components/views/dialogs/devtools/VerificationExplorer.tsx +++ b/src/components/views/dialogs/devtools/VerificationExplorer.tsx @@ -51,7 +51,7 @@ const VerificationRequestExplorer: React.FC<{ if (request.timeout == 0) return; /* Note that request.timeout is a getter, so its value changes */ - const id = setInterval(() => { + const id = window.setInterval(() => { setRequestTimeout(request.timeout); }, 500); diff --git a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx index f000d3bf4b..085dd540b0 100644 --- a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx +++ b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx @@ -228,7 +228,7 @@ export const useWebSearchMetrics = (numResults: number, queryLength: number, via if (!queryLength) return; // send metrics after a 1s debounce - const timeoutId = setTimeout(() => { + const timeoutId = window.setTimeout(() => { PosthogAnalytics.instance.trackEvent({ eventName: "WebSearch", viaSpotlight, diff --git a/src/components/views/elements/DesktopCapturerSourcePicker.tsx b/src/components/views/elements/DesktopCapturerSourcePicker.tsx index f355cc2a5e..eb9bac2876 100644 --- a/src/components/views/elements/DesktopCapturerSourcePicker.tsx +++ b/src/components/views/elements/DesktopCapturerSourcePicker.tsx @@ -106,7 +106,7 @@ export default class DesktopCapturerSourcePicker extends React.Component< } async componentDidMount() { - // setInterval() first waits and then executes, therefore + // window.setInterval() first waits and then executes, therefore // we call getDesktopCapturerSources() here without any delay. // Otherwise the dialog would be left empty for some time. this.setState({ @@ -114,7 +114,7 @@ export default class DesktopCapturerSourcePicker extends React.Component< }); // We update the sources every 500ms to get newer thumbnails - this.interval = setInterval(async () => { + this.interval = window.setInterval(async () => { this.setState({ sources: await getDesktopCapturerSources(), }); diff --git a/src/components/views/elements/UseCaseSelection.tsx b/src/components/views/elements/UseCaseSelection.tsx index eaa0a9d3cf..cea0a232c1 100644 --- a/src/components/views/elements/UseCaseSelection.tsx +++ b/src/components/views/elements/UseCaseSelection.tsx @@ -35,7 +35,7 @@ export function UseCaseSelection({ onFinished }: Props) { // Call onFinished 1.5s after `selection` becomes truthy, to give time for the animation to run useEffect(() => { if (selection) { - let handler: number | null = setTimeout(() => { + let handler: number | null = window.setTimeout(() => { handler = null; onFinished(selection); }, TIMEOUT); diff --git a/src/components/views/emojipicker/EmojiPicker.tsx b/src/components/views/emojipicker/EmojiPicker.tsx index 95e0e24ae1..571665ef20 100644 --- a/src/components/views/emojipicker/EmojiPicker.tsx +++ b/src/components/views/emojipicker/EmojiPicker.tsx @@ -191,7 +191,7 @@ class EmojiPicker extends React.Component { this.setState({ filter }); // Header underlines need to be updated, but updating requires knowing // where the categories are, so we wait for a tick. - setTimeout(this.updateVisibility, 0); + window.setTimeout(this.updateVisibility, 0); }; private emojiMatchesFilter = (emoji: IEmoji, filter: string): boolean => { diff --git a/src/components/views/emojipicker/Search.tsx b/src/components/views/emojipicker/Search.tsx index de09421010..54a15e509e 100644 --- a/src/components/views/emojipicker/Search.tsx +++ b/src/components/views/emojipicker/Search.tsx @@ -31,8 +31,8 @@ class Search extends React.PureComponent { private inputRef = React.createRef(); componentDidMount() { - // For some reason, neither the autoFocus nor just calling focus() here worked, so here's a setTimeout - setTimeout(() => this.inputRef.current.focus(), 0); + // For some reason, neither the autoFocus nor just calling focus() here worked, so here's a window.setTimeout + window.setTimeout(() => this.inputRef.current.focus(), 0); } private onKeyDown = (ev: React.KeyboardEvent) => { diff --git a/src/components/views/messages/MImageBody.tsx b/src/components/views/messages/MImageBody.tsx index 43adf41d8c..7af72bae70 100644 --- a/src/components/views/messages/MImageBody.tsx +++ b/src/components/views/messages/MImageBody.tsx @@ -335,7 +335,7 @@ export default class MImageBody extends React.Component { // Add a 150ms timer for blurhash to first appear. if (this.props.mxEvent.getContent().info?.[BLURHASH_FIELD]) { this.clearBlurhashTimeout(); - this.timeout = setTimeout(() => { + this.timeout = window.setTimeout(() => { if (!this.state.imgLoaded || !this.state.imgError) { this.setState({ placeholder: Placeholder.Blurhash, diff --git a/src/components/views/messages/TextualBody.tsx b/src/components/views/messages/TextualBody.tsx index ab9c27f7fb..941e3496c3 100644 --- a/src/components/views/messages/TextualBody.tsx +++ b/src/components/views/messages/TextualBody.tsx @@ -130,7 +130,7 @@ export default class TextualBody extends React.Component { if (codes.length > 0) { // Do this asynchronously: parsing code takes time and we don't // need to block the DOM update on it. - setTimeout(() => { + window.setTimeout(() => { if (this.unmounted) return; for (let i = 0; i < codes.length; i++) { this.highlightCode(codes[i]); diff --git a/src/components/views/rooms/Autocomplete.tsx b/src/components/views/rooms/Autocomplete.tsx index 58a659f537..25c526d4ef 100644 --- a/src/components/views/rooms/Autocomplete.tsx +++ b/src/components/views/rooms/Autocomplete.tsx @@ -127,7 +127,7 @@ export default class Autocomplete extends React.PureComponent { } return new Promise((resolve) => { - this.debounceCompletionsRequest = setTimeout(() => { + this.debounceCompletionsRequest = window.setTimeout(() => { resolve(this.processQuery(query, selection)); }, autocompleteDelay); }); diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index 6fe5923a29..cb996d8d34 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -199,7 +199,7 @@ export class MessageComposer extends React.Component { // that the ScrollPanel listening to the resizeNotifier can // correctly measure it's new height and scroll down to keep // at the bottom if it already is - setTimeout(() => { + window.setTimeout(() => { this.props.resizeNotifier.notifyTimelineHeightChanged(); }, 100); } @@ -395,7 +395,7 @@ export class MessageComposer extends React.Component { private onRecordingEndingSoon = ({ secondsLeft }) => { this.setState({ recordingTimeLeftSeconds: secondsLeft }); - setTimeout(() => this.setState({ recordingTimeLeftSeconds: null }), 3000); + window.setTimeout(() => this.setState({ recordingTimeLeftSeconds: null }), 3000); }; private setStickerPickerOpen = (isStickerPickerOpen: boolean) => { diff --git a/src/components/views/rooms/RoomBreadcrumbs.tsx b/src/components/views/rooms/RoomBreadcrumbs.tsx index 0ed34e9476..b6383bf83c 100644 --- a/src/components/views/rooms/RoomBreadcrumbs.tsx +++ b/src/components/views/rooms/RoomBreadcrumbs.tsx @@ -99,7 +99,7 @@ export default class RoomBreadcrumbs extends React.PureComponent // again and this time we want to show the newest breadcrumb because it'll be hidden // off screen for the animation. this.setState({ doAnimation: false, skipFirst: true }); - setTimeout(() => this.setState({ doAnimation: true, skipFirst: false }), 0); + window.setTimeout(() => this.setState({ doAnimation: true, skipFirst: false }), 0); }; private viewRoom = (room: Room, index: number, viaKeyboard = false) => { diff --git a/src/components/views/rooms/wysiwyg_composer/hooks/useIsFocused.ts b/src/components/views/rooms/wysiwyg_composer/hooks/useIsFocused.ts index 99e6dbd9c8..b7c99b2786 100644 --- a/src/components/views/rooms/wysiwyg_composer/hooks/useIsFocused.ts +++ b/src/components/views/rooms/wysiwyg_composer/hooks/useIsFocused.ts @@ -28,7 +28,7 @@ export function useIsFocused() { } else { // To avoid a blink when we switch mode between plain text and rich text mode // We delay the unfocused action - timeoutIDRef.current = setTimeout(() => setIsFocused(false), 100); + timeoutIDRef.current = window.setTimeout(() => setIsFocused(false), 100); } }, [setIsFocused, timeoutIDRef]); diff --git a/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts b/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts index 5b76703820..4d1dcaf2f1 100644 --- a/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts +++ b/src/components/views/rooms/wysiwyg_composer/hooks/utils.ts @@ -37,7 +37,7 @@ export function focusComposer( if (timeoutId.current) { clearTimeout(timeoutId.current); } - timeoutId.current = setTimeout( + timeoutId.current = window.setTimeout( () => composerElement.current?.focus(), 200, ); diff --git a/src/components/views/settings/ThemeChoicePanel.tsx b/src/components/views/settings/ThemeChoicePanel.tsx index cc4545e9ea..4d1343da08 100644 --- a/src/components/views/settings/ThemeChoicePanel.tsx +++ b/src/components/views/settings/ThemeChoicePanel.tsx @@ -150,7 +150,7 @@ export default class ThemeChoicePanel extends React.Component { await SettingsStore.setValue("custom_themes", null, SettingLevel.ACCOUNT, currentThemes); this.setState({ customThemeUrl: "", customThemeMessage: { text: _t("Theme added!"), isError: false } }); - this.themeTimer = setTimeout(() => { + this.themeTimer = window.setTimeout(() => { this.setState({ customThemeMessage: { text: "", isError: false } }); }, 3000); }; diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index 07a08ec9c4..a266820189 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -127,7 +127,7 @@ const SessionManagerTab: React.FC = () => { const [expandedDeviceIds, setExpandedDeviceIds] = useState([]); const [selectedDeviceIds, setSelectedDeviceIds] = useState([]); const filteredDeviceListRef = useRef(null); - const scrollIntoViewTimeoutRef = useRef>(); + const scrollIntoViewTimeoutRef = useRef(); const matrixClient = useContext(MatrixClientContext); const userId = matrixClient.getUserId(); diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 3b2e5c89a8..92d8b71582 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -57,7 +57,7 @@ export default class VerificationRequestToast extends React.PureComponent 0) { - this.intervalHandle = setInterval(() => { + this.intervalHandle = window.setInterval(() => { let { counter } = this.state; counter = Math.max(0, counter - 1); this.setState({ counter }); diff --git a/src/components/views/user-onboarding/UserOnboardingPage.tsx b/src/components/views/user-onboarding/UserOnboardingPage.tsx index cc90a3d09d..ab973a8bf9 100644 --- a/src/components/views/user-onboarding/UserOnboardingPage.tsx +++ b/src/components/views/user-onboarding/UserOnboardingPage.tsx @@ -55,7 +55,7 @@ export function UserOnboardingPage({ justRegistered = false }: Props) { const [showList, setShowList] = useState(false); useEffect(() => { if (initialSyncComplete) { - let handler: number | null = setTimeout(() => { + let handler: number | null = window.setTimeout(() => { handler = null; setShowList(true); }, ANIMATION_DURATION); diff --git a/src/components/views/voip/CallDuration.tsx b/src/components/views/voip/CallDuration.tsx index df59ba05d9..a3e44ab740 100644 --- a/src/components/views/voip/CallDuration.tsx +++ b/src/components/views/voip/CallDuration.tsx @@ -43,7 +43,7 @@ interface GroupCallDurationProps { export const GroupCallDuration: FC = ({ groupCall }) => { const [now, setNow] = useState(() => Date.now()); useEffect(() => { - const timer = setInterval(() => setNow(Date.now()), 1000); + const timer = window.setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(timer); }, []); diff --git a/src/dispatcher/dispatcher.ts b/src/dispatcher/dispatcher.ts index 4d4f83d4de..970a9ab140 100644 --- a/src/dispatcher/dispatcher.ts +++ b/src/dispatcher/dispatcher.ts @@ -49,7 +49,7 @@ export class MatrixDispatcher extends Dispatcher { // if you dispatch from within a dispatch, so rather than action // handlers having to worry about not calling anything that might // then dispatch, we just do dispatches asynchronously. - setTimeout(super.dispatch.bind(this, payload), 0); + window.setTimeout(super.dispatch.bind(this, payload), 0); } } diff --git a/src/hooks/spotlight/useDebouncedCallback.ts b/src/hooks/spotlight/useDebouncedCallback.ts index 9548ce5e0c..c703595a18 100644 --- a/src/hooks/spotlight/useDebouncedCallback.ts +++ b/src/hooks/spotlight/useDebouncedCallback.ts @@ -30,7 +30,7 @@ export function useDebouncedCallback( callback(...params); }; if (enabled !== false) { - handle = setTimeout(doSearch, DEBOUNCE_TIMEOUT); + handle = window.setTimeout(doSearch, DEBOUNCE_TIMEOUT); return () => { if (handle) { clearTimeout(handle); diff --git a/src/hooks/useTimeout.ts b/src/hooks/useTimeout.ts index 07301a367a..91e2d7d7be 100644 --- a/src/hooks/useTimeout.ts +++ b/src/hooks/useTimeout.ts @@ -30,7 +30,7 @@ export const useTimeout = (handler: Handler, timeoutMs: number) => { // Set up timer useEffect(() => { - const timeoutID = setTimeout(() => { + const timeoutID = window.setTimeout(() => { savedHandler.current(); }, timeoutMs); return () => clearTimeout(timeoutID); @@ -49,7 +49,7 @@ export const useInterval = (handler: Handler, intervalMs: number) => { // Set up timer useEffect(() => { - const intervalID = setInterval(() => { + const intervalID = window.setInterval(() => { savedHandler.current(); }, intervalMs); return () => clearInterval(intervalID); diff --git a/src/hooks/useTimeoutToggle.ts b/src/hooks/useTimeoutToggle.ts index 0bdfe714a0..d7cd1be049 100644 --- a/src/hooks/useTimeoutToggle.ts +++ b/src/hooks/useTimeoutToggle.ts @@ -28,7 +28,7 @@ export const useTimeoutToggle = (defaultValue: boolean, timeoutMs: number) => { const toggle = () => { setValue(!defaultValue); - timeoutId.current = setTimeout(() => setValue(defaultValue), timeoutMs); + timeoutId.current = window.setTimeout(() => setValue(defaultValue), timeoutMs); }; useEffect(() => { diff --git a/src/hooks/useUserOnboardingContext.ts b/src/hooks/useUserOnboardingContext.ts index 90d1eb09c6..29c4fce6ea 100644 --- a/src/hooks/useUserOnboardingContext.ts +++ b/src/hooks/useUserOnboardingContext.ts @@ -68,7 +68,7 @@ function useUserOnboardingContextValue(defaultValue: T, callback: (cli: Matri } setValue(await handler(cli)); if (enabled) { - handle = setTimeout(repeater, USER_ONBOARDING_CONTEXT_INTERVAL); + handle = window.setTimeout(repeater, USER_ONBOARDING_CONTEXT_INTERVAL); } }; repeater().catch(err => logger.warn("could not update user onboarding context", err)); diff --git a/src/models/Call.ts b/src/models/Call.ts index 0e20c331fb..9d8d727f27 100644 --- a/src/models/Call.ts +++ b/src/models/Call.ts @@ -377,7 +377,7 @@ export class JitsiCall extends Call { this.participants = participants; if (allExpireAt < Infinity) { - this.participantsExpirationTimer = setTimeout(() => this.updateParticipants(), allExpireAt - now); + this.participantsExpirationTimer = window.setTimeout(() => this.updateParticipants(), allExpireAt - now); } } @@ -553,7 +553,7 @@ export class JitsiCall extends Call { // Tell others that we're connected, by adding our device to room state await this.addOurDevice(); // Re-add this device every so often so our video member event doesn't become stale - this.resendDevicesTimer = setInterval(async () => { + this.resendDevicesTimer = window.setInterval(async () => { logger.log(`Resending video member event for ${this.roomId}`); await this.addOurDevice(); }, (this.STUCK_DEVICE_TIMEOUT_MS * 3) / 4); @@ -814,7 +814,7 @@ export class ElementCall extends Call { // randomly between 2 and 8 seconds before terminating the call, to // probabilistically reduce event spam. If someone else beats us to it, // this timer will be automatically cleared upon the call's destruction. - this.terminationTimer = setTimeout( + this.terminationTimer = window.setTimeout( () => this.groupCall.terminate(), Math.random() * 6000 + 2000, ); diff --git a/src/rageshake/rageshake.ts b/src/rageshake/rageshake.ts index e8461eef76..d6d6665d6d 100644 --- a/src/rageshake/rageshake.ts +++ b/src/rageshake/rageshake.ts @@ -154,7 +154,7 @@ export class IndexedDBLogStore { // @ts-ignore this.db = event.target.result; // Periodically flush logs to local storage / indexeddb - setInterval(this.flush.bind(this), FLUSH_RATE_MS); + window.setInterval(this.flush.bind(this), FLUSH_RATE_MS); resolve(); }; diff --git a/src/stores/OwnBeaconStore.ts b/src/stores/OwnBeaconStore.ts index 846b7cac68..b03a8a1f21 100644 --- a/src/stores/OwnBeaconStore.ts +++ b/src/stores/OwnBeaconStore.ts @@ -437,7 +437,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient { return; } - this.locationInterval = setInterval(() => { + this.locationInterval = window.setInterval(() => { if (!this.lastPublishedPositionTimestamp) { return; } diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index 73d6bdbd51..abdbff0ffe 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -228,7 +228,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient implements if (!room) { logger.warn(`Live timeline event ${eventPayload.event.getId()} received without associated room`); logger.warn(`Queuing failed room update for retry as a result.`); - setTimeout(async () => { + window.setTimeout(async () => { const updatedRoom = this.matrixClient.getRoom(roomId); await tryUpdate(updatedRoom); }, 100); // 100ms should be enough for the room to show up diff --git a/src/theme.ts b/src/theme.ts index 84455dd6d6..114da50cf9 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -298,7 +298,7 @@ export async function setTheme(theme?: string): Promise { // In case of theme toggling (white => black => white) // Chrome doesn't fire the `load` event when the white theme is selected the second times - const intervalId = setInterval(() => { + const intervalId = window.setInterval(() => { if (isStyleSheetLoaded()) { clearInterval(intervalId); styleSheet.onload = undefined; diff --git a/src/utils/MultiInviter.ts b/src/utils/MultiInviter.ts index 3c539f7bf0..7208326a2b 100644 --- a/src/utils/MultiInviter.ts +++ b/src/utils/MultiInviter.ts @@ -241,7 +241,7 @@ export default class MultiInviter { break; case "M_LIMIT_EXCEEDED": // we're being throttled so wait a bit & try again - setTimeout(() => { + window.setTimeout(() => { this.doInvite(address, ignoreProfile).then(resolve, reject); }, 5000); return; diff --git a/src/utils/Timer.ts b/src/utils/Timer.ts index 38703c1299..f17745029e 100644 --- a/src/utils/Timer.ts +++ b/src/utils/Timer.ts @@ -55,7 +55,7 @@ export default class Timer { this.setNotStarted(); } else { const delta = this.timeout - elapsed; - this.timerHandle = setTimeout(this.onTimeout, delta); + this.timerHandle = window.setTimeout(this.onTimeout, delta); } }; @@ -78,7 +78,7 @@ export default class Timer { start() { if (!this.isRunning()) { this.startTs = Date.now(); - this.timerHandle = setTimeout(this.onTimeout, this.timeout); + this.timerHandle = window.setTimeout(this.onTimeout, this.timeout); } return this; } diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index 964d795576..e6f75bb025 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -166,7 +166,7 @@ export default class WidgetUtils { resolve(); } } - const timerId = setTimeout(() => { + const timerId = window.setTimeout(() => { MatrixClientPeg.get().removeListener(ClientEvent.AccountData, onAccountData); reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear")); }, WIDGET_WAIT_TIME); @@ -221,7 +221,7 @@ export default class WidgetUtils { resolve(); } } - const timerId = setTimeout(() => { + const timerId = window.setTimeout(() => { MatrixClientPeg.get().removeListener(RoomStateEvent.Events, onRoomStateEvents); reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear")); }, WIDGET_WAIT_TIME); diff --git a/src/utils/exportUtils/exportJS.js b/src/utils/exportUtils/exportJS.js index e082f88d98..6e309292da 100644 --- a/src/utils/exportUtils/exportJS.js +++ b/src/utils/exportUtils/exportJS.js @@ -27,7 +27,7 @@ function showToast(text) { const el = document.getElementById("snackbar"); el.innerHTML = text; el.className = "mx_show"; - setTimeout(() => { + window.setTimeout(() => { el.className = el.className.replace("mx_show", ""); }, 2000); } diff --git a/src/utils/image-media.ts b/src/utils/image-media.ts index c3320627d0..58558f7a25 100644 --- a/src/utils/image-media.ts +++ b/src/utils/image-media.ts @@ -77,10 +77,10 @@ export async function createThumbnail( } let canvas: HTMLCanvasElement | OffscreenCanvas; - let context: CanvasRenderingContext2D; + let context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; try { canvas = new window.OffscreenCanvas(targetWidth, targetHeight); - context = canvas.getContext("2d"); + context = canvas.getContext("2d") as OffscreenCanvasRenderingContext2D; } catch (e) { // Fallback support for other browsers (Safari and Firefox for now) canvas = document.createElement("canvas"); @@ -92,7 +92,7 @@ export async function createThumbnail( context.drawImage(element, 0, 0, targetWidth, targetHeight); let thumbnailPromise: Promise; - if (window.OffscreenCanvas && canvas instanceof window.OffscreenCanvas) { + if (window.OffscreenCanvas && canvas instanceof OffscreenCanvas) { thumbnailPromise = canvas.convertToBlob({ type: mimeType }); } else { thumbnailPromise = new Promise(resolve => (canvas as HTMLCanvasElement).toBlob(resolve, mimeType)); diff --git a/src/utils/local-room.ts b/src/utils/local-room.ts index 8b1a2e6379..b85bb7de9d 100644 --- a/src/utils/local-room.ts +++ b/src/utils/local-room.ts @@ -102,10 +102,10 @@ export async function waitForRoomReadyAndApplyAfterCreateCallbacks( finish(); }; - const checkRoomStateIntervalHandle = setInterval(() => { + const checkRoomStateIntervalHandle = window.setInterval(() => { if (isRoomReady(client, localRoom)) finish(); }, 500); - const stopgapTimeoutHandle = setTimeout(stopgapFinish, 5000); + const stopgapTimeoutHandle = window.setTimeout(stopgapFinish, 5000); }); } diff --git a/src/utils/membership.ts b/src/utils/membership.ts index 1a48f1261c..a101142511 100644 --- a/src/utils/membership.ts +++ b/src/utils/membership.ts @@ -97,7 +97,7 @@ export async function waitForMember(client: MatrixClient, roomId: string, userId /* We don't want to hang if this goes wrong, so we proceed and hope the other user is already in the megolm session */ - setTimeout(resolve, timeout, false); + window.setTimeout(resolve, timeout, false); }).finally(() => { client.removeListener(RoomStateEvent.NewMember, handler); }); diff --git a/src/utils/promise.ts b/src/utils/promise.ts index 04a9ac8818..e478409eb3 100644 --- a/src/utils/promise.ts +++ b/src/utils/promise.ts @@ -18,7 +18,7 @@ limitations under the License. // or when the timeout of ms is reached with the value of given timeoutValue export async function timeout(promise: Promise, timeoutValue: Y, ms: number): Promise { const timeoutPromise = new Promise((resolve) => { - const timeoutId = setTimeout(resolve, ms, timeoutValue); + const timeoutId = window.setTimeout(resolve, ms, timeoutValue); promise.then(() => { clearTimeout(timeoutId); }); diff --git a/test/ContentMessages-test.ts b/test/ContentMessages-test.ts index 3d812cbbee..e0fb6c0a32 100644 --- a/test/ContentMessages-test.ts +++ b/test/ContentMessages-test.ts @@ -91,7 +91,7 @@ describe("ContentMessages", () => { Object.defineProperty(global.Image.prototype, 'src', { // Define the property setter set(src) { - setTimeout(() => this.onload()); + window.setTimeout(() => this.onload()); }, }); Object.defineProperty(global.Image.prototype, 'height', { diff --git a/test/components/views/location/LocationShareMenu-test.tsx b/test/components/views/location/LocationShareMenu-test.tsx index f590bcdd7c..7624f6ff86 100644 --- a/test/components/views/location/LocationShareMenu-test.tsx +++ b/test/components/views/location/LocationShareMenu-test.tsx @@ -352,7 +352,7 @@ describe('', () => { // @ts-ignore mocked(SettingsStore.watchSetting).mockImplementation((featureName, roomId, callback) => { callback(featureName, roomId, SettingLevel.DEVICE, '', ''); - setTimeout(() => { + window.setTimeout(() => { callback(featureName, roomId, SettingLevel.DEVICE, '', ''); }, 1000); }); diff --git a/test/components/views/settings/Notifications-test.tsx b/test/components/views/settings/Notifications-test.tsx index da2bc9f3f8..df2a5f4b61 100644 --- a/test/components/views/settings/Notifications-test.tsx +++ b/test/components/views/settings/Notifications-test.tsx @@ -54,7 +54,7 @@ const encryptedGroupRule = { "conditions": [{ "kind": "event_match", "key": "typ // eslint-disable-next-line max-len const pushRules: IPushRules = { "global": { "underride": [{ "conditions": [{ "kind": "event_match", "key": "type", "pattern": "m.call.invite" }], "actions": ["notify", { "set_tweak": "sound", "value": "ring" }, { "set_tweak": "highlight", "value": false }], "rule_id": ".m.rule.call", "default": true, "enabled": true }, oneToOneRule, encryptedOneToOneRule, { "conditions": [{ "kind": "event_match", "key": "type", "pattern": "m.room.message" }], "actions": ["notify", { "set_tweak": "sound", "value": "default" }, { "set_tweak": "highlight", "value": false }], "rule_id": ".m.rule.message", "default": true, "enabled": true }, encryptedGroupRule, { "conditions": [{ "kind": "event_match", "key": "type", "pattern": "im.vector.modular.widgets" }, { "kind": "event_match", "key": "content.type", "pattern": "jitsi" }, { "kind": "event_match", "key": "state_key", "pattern": "*" }], "actions": ["notify", { "set_tweak": "highlight", "value": false }], "rule_id": ".im.vector.jitsi", "default": true, "enabled": true }], "sender": [], "room": [{ "actions": ["dont_notify"], "rule_id": "!zJPyWqpMorfCcWObge:matrix.org", "default": false, "enabled": true }], "content": [{ "actions": ["notify", { "set_tweak": "highlight", "value": false }], "pattern": "banana", "rule_id": "banana", "default": false, "enabled": true }, { "actions": ["notify", { "set_tweak": "sound", "value": "default" }, { "set_tweak": "highlight" }], "pattern": "kadev1", "rule_id": ".m.rule.contains_user_name", "default": true, "enabled": true }], "override": [{ "conditions": [], "actions": ["dont_notify"], "rule_id": ".m.rule.master", "default": true, "enabled": false }, { "conditions": [{ "kind": "event_match", "key": "content.msgtype", "pattern": "m.notice" }], "actions": ["dont_notify"], "rule_id": ".m.rule.suppress_notices", "default": true, "enabled": true }, { "conditions": [{ "kind": "event_match", "key": "type", "pattern": "m.room.member" }, { "kind": "event_match", "key": "content.membership", "pattern": "invite" }, { "kind": "event_match", "key": "state_key", "pattern": "@kadev1:matrix.org" }], "actions": ["notify", { "set_tweak": "sound", "value": "default" }, { "set_tweak": "highlight", "value": false }], "rule_id": ".m.rule.invite_for_me", "default": true, "enabled": true }, { "conditions": [{ "kind": "event_match", "key": "type", "pattern": "m.room.member" }], "actions": ["dont_notify"], "rule_id": ".m.rule.member_event", "default": true, "enabled": true }, { "conditions": [{ "kind": "contains_display_name" }], "actions": ["notify", { "set_tweak": "sound", "value": "default" }, { "set_tweak": "highlight" }], "rule_id": ".m.rule.contains_display_name", "default": true, "enabled": true }, { "conditions": [{ "kind": "event_match", "key": "content.body", "pattern": "@room" }, { "kind": "sender_notification_permission", "key": "room" }], "actions": ["notify", { "set_tweak": "highlight", "value": true }], "rule_id": ".m.rule.roomnotif", "default": true, "enabled": true }, { "conditions": [{ "kind": "event_match", "key": "type", "pattern": "m.room.tombstone" }, { "kind": "event_match", "key": "state_key", "pattern": "" }], "actions": ["notify", { "set_tweak": "highlight", "value": true }], "rule_id": ".m.rule.tombstone", "default": true, "enabled": true }, { "conditions": [{ "kind": "event_match", "key": "type", "pattern": "m.reaction" }], "actions": ["dont_notify"], "rule_id": ".m.rule.reaction", "default": true, "enabled": true }] }, "device": {} } as IPushRules; -const flushPromises = async () => await new Promise(resolve => setTimeout(resolve)); +const flushPromises = async () => await new Promise(resolve => window.setTimeout(resolve)); describe('', () => { const getComponent = () => render(); diff --git a/test/setup/setupManualMocks.ts b/test/setup/setupManualMocks.ts index ada613feb9..8ee7750c9c 100644 --- a/test/setup/setupManualMocks.ts +++ b/test/setup/setupManualMocks.ts @@ -21,7 +21,7 @@ import fetch from 'node-fetch'; // jest 27 removes setImmediate from jsdom // polyfill until setImmediate use in client can be removed // @ts-ignore - we know the contract is wrong. That's why we're stubbing it. -global.setImmediate = callback => setTimeout(callback, 0); +global.setImmediate = callback => window.setTimeout(callback, 0); // Stub ResizeObserver // @ts-ignore - we know it's a duplicate (that's why we're stubbing it) diff --git a/test/test-utils/beacon.ts b/test/test-utils/beacon.ts index a58be78151..7ca5741bd5 100644 --- a/test/test-utils/beacon.ts +++ b/test/test-utils/beacon.ts @@ -179,7 +179,7 @@ export const watchPositionMockImplementation = (delays: number[], errorCodes: nu let totalDelay = 0; delays.map((delayMs, index) => { totalDelay += delayMs; - const timeout = setTimeout(() => { + const timeout = window.setTimeout(() => { if (errorCodes[index]) { error(getMockGeolocationPositionError(errorCodes[index], 'error message')); } else { diff --git a/test/test-utils/utilities.ts b/test/test-utils/utilities.ts index 76859da263..0f22ed8467 100644 --- a/test/test-utils/utilities.ts +++ b/test/test-utils/utilities.ts @@ -48,7 +48,7 @@ export function untilDispatch( let timeoutId; // set a timeout handler if needed if (timeout > 0) { - timeoutId = setTimeout(() => { + timeoutId = window.setTimeout(() => { if (!fulfilled) { reject(new Error(`untilDispatch: timed out at ${callerLine}`)); fulfilled = true; @@ -92,7 +92,7 @@ export function untilEmission( let timeoutId; // set a timeout handler if needed if (timeout > 0) { - timeoutId = setTimeout(() => { + timeoutId = window.setTimeout(() => { if (!fulfilled) { reject(new Error(`untilEmission: timed out at ${callerLine}`)); fulfilled = true; @@ -134,7 +134,7 @@ const findByTagAndAttr = (attr: string) => export const findByTagAndTestId = findByTagAndAttr('data-test-id'); -export const flushPromises = async () => await new Promise(resolve => setTimeout(resolve)); +export const flushPromises = async () => await new Promise(resolve => window.setTimeout(resolve)); // with jest's modern fake timers process.nextTick is also mocked, // flushing promises in the normal way then waits for some advancement diff --git a/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts b/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts index 448a18a746..5eac6ef803 100644 --- a/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts +++ b/test/voice-broadcast/utils/startNewVoiceBroadcastRecording-test.ts @@ -130,7 +130,7 @@ describe("startNewVoiceBroadcastRecording", () => { _content: any, _stateKey = "", ): Promise => { - setTimeout(() => { + window.setTimeout(() => { // emit state events after resolving the promise room.currentState.setStateEvents([otherEvent]); room.currentState.setStateEvents([infoEvent]); diff --git a/yarn.lock b/yarn.lock index 67badcfde4..26d02df663 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2451,10 +2451,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.26.tgz#239e19f8b4ea1a9eb710528061c1d733dc561996" integrity sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA== -"@types/node@^14.18.28": - version "14.18.28" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.28.tgz#ddb82da2fff476a8e827e8773c84c19d9c235278" - integrity sha512-CK2fnrQlIgKlCV3N2kM+Gznb5USlwA1KFX3rJVHmgVk6NJxFPuQ86pAcvKnu37IA4BGlSRz7sEE1lHL1aLZ/eQ== +"@types/node@^16": + version "16.18.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.3.tgz#d7f7ba828ad9e540270f01ce00d391c54e6e0abc" + integrity sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -9469,10 +9469,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@4.8.4: - version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== +typescript@4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" + integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== ua-parser-js@^0.7.30: version "0.7.31"