From caa53e35564ac1ca101b135ba0ab1f93c5523b15 Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Mon, 6 Feb 2023 13:21:58 +0100 Subject: [PATCH] feat: add patch to add generic types to eventemitter2 EventEmitter2 has types, but they're very basic and not very type safe. I created this patch, because my improved types haven't been merged into the official package. Signed-off-by: Tilman Vatteroth --- .../eventemitter2-npm-6.4.9-ba37798a18.patch | 401 ++++++++++++++++++ backend/src/events.ts | 5 + backend/src/notes/notes.service.ts | 4 +- .../src/permissions/permissions.service.ts | 4 +- .../realtime/realtime-note/realtime-note.ts | 9 +- .../test-utils/mock-realtime-note.ts | 4 +- .../hooks/use-load-note-from-server.ts | 2 +- .../app-bar/help-button/cheatsheet-line.tsx | 12 +- .../base/markdown-renderer-extension.ts | 2 +- .../hooks/use-extension-event-emitter.tsx | 2 +- .../render-page/iframe-markdown-renderer.tsx | 6 +- .../window-post-message-communicator.ts | 2 +- frontend/src/extensions/base/app-extension.ts | 2 +- .../task-list-checkbox-app-extension.ts | 2 +- package.json | 3 +- yarn.lock | 7 + 16 files changed, 445 insertions(+), 22 deletions(-) create mode 100644 .yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch diff --git a/.yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch b/.yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch new file mode 100644 index 000000000..6c73b623e --- /dev/null +++ b/.yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch @@ -0,0 +1,401 @@ +diff --git a/eventemitter2.d.ts b/eventemitter2.d.ts +index 230825bc353849ffbc46a886099558bed9d42113..19405bde859cf454333ed08d0a2a7543291e9258 100644 +--- a/eventemitter2.d.ts ++++ b/eventemitter2.d.ts +@@ -1,27 +1,24 @@ +-export type event = (symbol|string); +-export type eventNS = string|event[]; +- + export interface ConstructorOptions { + /** + * @default false + * @description set this to `true` to use wildcards. + */ +- wildcard?: boolean, ++ wildcard?: boolean + /** + * @default '.' + * @description the delimiter used to segment namespaces. + */ +- delimiter?: string, ++ delimiter?: string + /** + * @default false + * @description set this to `true` if you want to emit the newListener events. + */ +- newListener?: boolean, ++ newListener?: boolean + /** + * @default false + * @description set this to `true` if you want to emit the removeListener events. + */ +- removeListener?: boolean, ++ removeListener?: boolean + /** + * @default 10 + * @description the maximum amount of listeners that can be assigned to an event. +@@ -38,39 +35,61 @@ export interface ConstructorOptions { + */ + ignoreErrors?: boolean + } +-export interface ListenerFn { +- (...values: any[]): void; +-} +-export interface EventAndListener { +- (event: string | string[], ...values: any[]): void; ++ ++export type event = symbol | string ++export type eventNS = string | event[] ++ ++export type EventMap = Record void> ++ ++export type ListenerFn< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> = Events[EventName] ++ ++export interface EventAndListener< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> { ++ ( ++ event: EventName, ++ ...values: ListenerFunctionParameters ++ ): void + } + +-export interface WaitForFilter { (...values: any[]): boolean } ++export interface WaitForFilter< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> { ++ (...values: ListenerFunctionParameters): boolean ++} + +-export interface WaitForOptions { ++export interface WaitForOptions< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> { + /** + * @default 0 + */ +- timeout: number, ++ timeout: number + /** + * @default null + */ +- filter: WaitForFilter, ++ filter: WaitForFilter + /** + * @default false + */ +- handleError: boolean, ++ handleError: boolean + /** + * @default Promise + */ +- Promise: Function, ++ Promise: () => void + /** + * @default false + */ + overload: boolean + } + +-export interface CancelablePromise extends Promise{ ++export interface CancelablePromise extends Promise { + cancel(reason: string): undefined + } + +@@ -78,79 +97,236 @@ export interface OnceOptions { + /** + * @default 0 + */ +- timeout: number, ++ timeout: number + /** + * @default Promise + */ +- Promise: Function, ++ Promise: () => void + /** + * @default false + */ + overload: boolean + } + +-export interface ListenToOptions { +- on?: { (event: event | eventNS, handler: ListenerFn): void }, +- off?: { (event: event | eventNS, handler: ListenerFn): void }, +- reducers: Function | Object ++export interface ListenToOptions< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> { ++ on?: { ++ (event: EventName | eventNS, handler: ListenerFn): void ++ } ++ off?: { ++ (event: EventName | eventNS, handler: ListenerFn): void ++ } ++ reducers: () => void | Record + } + +-export interface GeneralEventEmitter{ +- addEventListener(event: event, handler: ListenerFn): this, +- removeEventListener(event: event, handler: ListenerFn): this, +- addListener?(event: event, handler: ListenerFn): this, +- removeListener?(event: event, handler: ListenerFn): this, +- on?(event: event, handler: ListenerFn): this, +- off?(event: event, handler: ListenerFn): this ++export interface GeneralEventEmitter< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> { ++ addEventListener( ++ event: EventName, ++ handler: ListenerFn ++ ): this ++ ++ removeEventListener( ++ event: EventName, ++ handler: ListenerFn ++ ): this ++ ++ addListener?(event: EventName, handler: ListenerFn): this ++ ++ removeListener?( ++ event: EventName, ++ handler: ListenerFn ++ ): this ++ ++ on?(event: EventName, handler: ListenerFn): this ++ ++ off?(event: EventName, handler: ListenerFn): this + } + + export interface OnOptions { +- async?: boolean, +- promisify?: boolean, +- nextTick?: boolean, ++ async?: boolean ++ promisify?: boolean ++ nextTick?: boolean + objectify?: boolean + } + +-export interface Listener { +- emitter: EventEmitter2; +- event: event|eventNS; +- listener: ListenerFn; +- off(): this; ++export interface Listener< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> { ++ emitter: EventEmitter2 ++ event: EventName | eventNS ++ listener: ListenerFn ++ ++ off(): this + } + +-export declare class EventEmitter2 { ++export type ListenerFunctionParameters< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++> = Parameters ++ ++export class EventEmitter2 { + constructor(options?: ConstructorOptions) +- emit(event: event | eventNS, ...values: any[]): boolean; +- emitAsync(event: event | eventNS, ...values: any[]): Promise; +- addListener(event: event | eventNS, listener: ListenerFn): this|Listener; +- on(event: event | eventNS, listener: ListenerFn, options?: boolean|OnOptions): this|Listener; +- prependListener(event: event | eventNS, listener: ListenerFn, options?: boolean|OnOptions): this|Listener; +- once(event: event | eventNS, listener: ListenerFn, options?: true|OnOptions): this|Listener; +- prependOnceListener(event: event | eventNS, listener: ListenerFn, options?: boolean|OnOptions): this|Listener; +- many(event: event | eventNS, timesToListen: number, listener: ListenerFn, options?: boolean|OnOptions): this|Listener; +- prependMany(event: event | eventNS, timesToListen: number, listener: ListenerFn, options?: boolean|OnOptions): this|Listener; +- onAny(listener: EventAndListener): this; +- prependAny(listener: EventAndListener): this; +- offAny(listener: ListenerFn): this; +- removeListener(event: event | eventNS, listener: ListenerFn): this; +- off(event: event | eventNS, listener: ListenerFn): this; +- removeAllListeners(event?: event | eventNS): this; +- setMaxListeners(n: number): void; +- getMaxListeners(): number; +- eventNames(nsAsArray?: boolean): (event|eventNS)[]; +- listenerCount(event?: event | eventNS): number +- listeners(event?: event | eventNS): ListenerFn[] +- listenersAny(): ListenerFn[] +- waitFor(event: event | eventNS, timeout?: number): CancelablePromise +- waitFor(event: event | eventNS, filter?: WaitForFilter): CancelablePromise +- waitFor(event: event | eventNS, options?: WaitForOptions): CancelablePromise +- listenTo(target: GeneralEventEmitter, events: event | eventNS, options?: ListenToOptions): this; +- listenTo(target: GeneralEventEmitter, events: event[], options?: ListenToOptions): this; +- listenTo(target: GeneralEventEmitter, events: Object, options?: ListenToOptions): this; +- stopListeningTo(target?: GeneralEventEmitter, event?: event | eventNS): Boolean; +- hasListeners(event?: String): Boolean +- static once(emitter: EventEmitter2, event: event | eventNS, options?: OnceOptions): CancelablePromise; +- static defaultMaxListeners: number; ++ ++ emit( ++ event: EventName, ++ ...values: ListenerFunctionParameters ++ ): boolean ++ ++ emit(event: eventNS, ...values: unknown[]): boolean ++ ++ emitAsync( ++ event: EventName | eventNS, ++ ...values: ListenerFunctionParameters ++ ): Promise>[]> ++ ++ addListener( ++ event: EventName | eventNS, ++ listener: ListenerFn ++ ): this | Listener ++ ++ on( ++ event: EventName, ++ listener: ListenerFn, ++ options?: boolean | OnOptions ++ ): this | Listener ++ ++ on( ++ event: eventNS, ++ listener: () => void, ++ options?: boolean | OnOptions ++ ): this | Listener ++ ++ prependListener( ++ event: EventName | eventNS, ++ listener: ListenerFn, ++ options?: boolean | OnOptions ++ ): this | Listener ++ ++ once( ++ event: EventName | eventNS, ++ listener: ListenerFn, ++ options?: true | OnOptions ++ ): this | Listener ++ ++ prependOnceListener( ++ event: EventName | eventNS, ++ listener: ListenerFn, ++ options?: boolean | OnOptions ++ ): this | Listener ++ ++ many( ++ event: EventName | eventNS, ++ timesToListen: number, ++ listener: ListenerFn, ++ options?: boolean | OnOptions ++ ): this | Listener ++ ++ prependMany( ++ event: EventName | eventNS, ++ timesToListen: number, ++ listener: ListenerFn, ++ options?: boolean | OnOptions ++ ): this | Listener ++ ++ onAny( ++ listener: EventAndListener ++ ): this ++ ++ prependAny( ++ listener: EventAndListener ++ ): this ++ ++ offAny( ++ listener: ListenerFn ++ ): this ++ ++ removeListener( ++ event: EventName | eventNS, ++ listener: ListenerFn ++ ): this ++ ++ off( ++ event: EventName | eventNS, ++ listener: ListenerFn ++ ): this ++ ++ removeAllListeners( ++ event?: EventName | eventNS ++ ): this ++ ++ setMaxListeners(numberOfListeners: number): void ++ ++ getMaxListeners(): number ++ ++ eventNames( ++ nsAsArray?: boolean ++ ): (EventName | eventNS)[] ++ ++ listenerCount( ++ event?: EventName | eventNS ++ ): number ++ ++ listeners( ++ event?: EventName | eventNS ++ ): ListenerFn[] ++ ++ listenersAny(): ListenerFn< ++ EventName, ++ Events ++ >[] ++ ++ waitFor( ++ event: EventName | eventNS, ++ timeout?: number ++ ): CancelablePromise> ++ waitFor( ++ event: EventName | eventNS, ++ filter?: WaitForFilter ++ ): CancelablePromise> ++ waitFor( ++ event: EventName | eventNS, ++ options?: WaitForOptions ++ ): CancelablePromise> ++ ++ listenTo( ++ target: GeneralEventEmitter, ++ events: EventName | eventNS, ++ options?: ListenToOptions ++ ): this ++ listenTo( ++ target: GeneralEventEmitter, ++ events: EventName[], ++ options?: ListenToOptions ++ ): this ++ listenTo( ++ target: GeneralEventEmitter, ++ events: Record, ++ options?: ListenToOptions ++ ): this ++ ++ stopListeningTo( ++ target?: GeneralEventEmitter, ++ event?: EventName | eventNS ++ ): boolean ++ ++ hasListeners(event?: EventName): boolean ++ ++ static once< ++ EventName extends keyof Events = event, ++ Events extends EventMap = EventMap ++ >( ++ emitter: EventEmitter2, ++ event: EventName | eventNS, ++ options?: OnceOptions ++ ): CancelablePromise> ++ ++ static defaultMaxListeners: number + } + + export default EventEmitter2; +\ No newline at end of file diff --git a/backend/src/events.ts b/backend/src/events.ts index c6cf9d986..78baa3724 100644 --- a/backend/src/events.ts +++ b/backend/src/events.ts @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ +import { EventMap } from 'eventemitter2'; export const eventModuleConfig = { wildcard: false, @@ -18,3 +19,7 @@ export enum NoteEvent { PERMISSION_CHANGE = 'note.permission_change' /** noteId: The id of the [@link Note], which permissions are changed. **/, DELETION = 'note.deletion' /** noteId: The id of the [@link Note], which is being deleted. **/, } + +export interface NoteEventMap extends EventMap { + [NoteEvent.PERMISSION_CHANGE]: (noteId: number) => void; +} diff --git a/backend/src/notes/notes.service.ts b/backend/src/notes/notes.service.ts index 60df45400..db6b08b0f 100644 --- a/backend/src/notes/notes.service.ts +++ b/backend/src/notes/notes.service.ts @@ -17,7 +17,7 @@ import { MaximumDocumentLengthExceededError, NotInDBError, } from '../errors/errors'; -import { NoteEvent } from '../events'; +import { NoteEvent, NoteEventMap } from '../events'; import { Group } from '../groups/group.entity'; import { GroupsService } from '../groups/groups.service'; import { HistoryEntry } from '../history/history-entry.entity'; @@ -54,7 +54,7 @@ export class NotesService { @Inject(forwardRef(() => AliasService)) private aliasService: AliasService, private realtimeNoteService: RealtimeNoteService, private realtimeNoteStore: RealtimeNoteStore, - private eventEmitter: EventEmitter2, + private eventEmitter: EventEmitter2, ) { this.logger.setContext(NotesService.name); } diff --git a/backend/src/permissions/permissions.service.ts b/backend/src/permissions/permissions.service.ts index b383bcadd..644590ce4 100644 --- a/backend/src/permissions/permissions.service.ts +++ b/backend/src/permissions/permissions.service.ts @@ -14,7 +14,7 @@ import { } from '../config/guest_access.enum'; import noteConfiguration, { NoteConfig } from '../config/note.config'; import { PermissionsUpdateInconsistentError } from '../errors/errors'; -import { NoteEvent } from '../events'; +import { NoteEvent, NoteEventMap } from '../events'; import { Group } from '../groups/group.entity'; import { GroupsService } from '../groups/groups.service'; import { SpecialGroup } from '../groups/groups.special'; @@ -36,7 +36,7 @@ export class PermissionsService { private readonly logger: ConsoleLoggerService, @Inject(noteConfiguration.KEY) private noteConfig: NoteConfig, - private eventEmitter: EventEmitter2, + private eventEmitter: EventEmitter2, ) {} /** diff --git a/backend/src/realtime/realtime-note/realtime-note.ts b/backend/src/realtime/realtime-note/realtime-note.ts index 6ef212364..fb535368b 100644 --- a/backend/src/realtime/realtime-note/realtime-note.ts +++ b/backend/src/realtime/realtime-note/realtime-note.ts @@ -8,7 +8,7 @@ import { encodeMetadataUpdatedMessage, } from '@hedgedoc/commons'; import { Logger } from '@nestjs/common'; -import { EventEmitter2 } from 'eventemitter2'; +import { EventEmitter2, EventMap } from 'eventemitter2'; import { Awareness } from 'y-protocols/awareness'; import { Note } from '../../notes/note.entity'; @@ -16,10 +16,15 @@ import { WebsocketAwareness } from './websocket-awareness'; import { WebsocketConnection } from './websocket-connection'; import { WebsocketDoc } from './websocket-doc'; +export interface MapType extends EventMap { + destroy: () => void; + beforeDestroy: () => void; +} + /** * Represents a note currently being edited by a number of clients. */ -export class RealtimeNote extends EventEmitter2 { +export class RealtimeNote extends EventEmitter2 { protected logger: Logger; private readonly websocketDoc: WebsocketDoc; private readonly websocketAwareness: WebsocketAwareness; diff --git a/backend/src/realtime/realtime-note/test-utils/mock-realtime-note.ts b/backend/src/realtime/realtime-note/test-utils/mock-realtime-note.ts index e7ac0198f..ef95809b0 100644 --- a/backend/src/realtime/realtime-note/test-utils/mock-realtime-note.ts +++ b/backend/src/realtime/realtime-note/test-utils/mock-realtime-note.ts @@ -7,13 +7,13 @@ import { EventEmitter2 } from 'eventemitter2'; import { Mock } from 'ts-mockery'; import { Note } from '../../../notes/note.entity'; -import { RealtimeNote } from '../realtime-note'; +import { MapType, RealtimeNote } from '../realtime-note'; import { WebsocketAwareness } from '../websocket-awareness'; import { WebsocketDoc } from '../websocket-doc'; import { mockAwareness } from './mock-awareness'; import { mockWebsocketDoc } from './mock-websocket-doc'; -class MockRealtimeNote extends EventEmitter2 { +class MockRealtimeNote extends EventEmitter2 { constructor( private note: Note, private doc: WebsocketDoc, diff --git a/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts b/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts index 6d566e352..18960c33f 100644 --- a/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts +++ b/frontend/src/components/common/note-loading-boundary/hooks/use-load-note-from-server.ts @@ -17,7 +17,7 @@ import type { AsyncState } from 'react-use/lib/useAsyncFn' export const useLoadNoteFromServer = (): [AsyncState, () => void] => { const id = useSingleStringUrlParameter('noteId', undefined) - return useAsyncFn(async () => { + return useAsyncFn(async (): Promise => { if (id === undefined) { throw new Error('Invalid id') } diff --git a/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-line.tsx b/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-line.tsx index 44757dab8..ffde615d7 100644 --- a/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-line.tsx +++ b/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-line.tsx @@ -7,7 +7,8 @@ import type { TaskCheckedEventPayload } from '../../../../extensions/extra-integ import { TaskListCheckboxAppExtension } from '../../../../extensions/extra-integrations/task-list/task-list-checkbox-app-extension' import { WaitSpinner } from '../../../common/wait-spinner/wait-spinner' import { eventEmitterContext } from '../../../markdown-renderer/hooks/use-extension-event-emitter' -import EventEmitter2 from 'eventemitter2' +import type { Listener } from 'eventemitter2' +import { EventEmitter2 } from 'eventemitter2' import React, { Suspense, useEffect, useMemo } from 'react' export interface CheatsheetLineProps { @@ -32,10 +33,13 @@ export const CheatsheetLine: React.FC = ({ markdown, onTask const eventEmitter = useMemo(() => new EventEmitter2(), []) useEffect(() => { - const handler = ({ checked }: TaskCheckedEventPayload) => onTaskCheckedChange(checked) - eventEmitter.on(TaskListCheckboxAppExtension.EVENT_NAME, handler) + const handler = eventEmitter.on( + TaskListCheckboxAppExtension.EVENT_NAME, + ({ checked }: TaskCheckedEventPayload) => onTaskCheckedChange(checked), + { objectify: true } + ) as Listener return () => { - eventEmitter.off(TaskListCheckboxAppExtension.EVENT_NAME, handler) + handler.off() } }) diff --git a/frontend/src/components/markdown-renderer/extensions/base/markdown-renderer-extension.ts b/frontend/src/components/markdown-renderer/extensions/base/markdown-renderer-extension.ts index 5c29c4958..d4338300a 100644 --- a/frontend/src/components/markdown-renderer/extensions/base/markdown-renderer-extension.ts +++ b/frontend/src/components/markdown-renderer/extensions/base/markdown-renderer-extension.ts @@ -5,7 +5,7 @@ */ import type { NodeProcessor } from '../../node-preprocessors/node-processor' import type { ComponentReplacer } from '../../replace-components/component-replacer' -import type EventEmitter2 from 'eventemitter2' +import type { EventEmitter2 } from 'eventemitter2' import type MarkdownIt from 'markdown-it' /** diff --git a/frontend/src/components/markdown-renderer/hooks/use-extension-event-emitter.tsx b/frontend/src/components/markdown-renderer/hooks/use-extension-event-emitter.tsx index cac00bf03..a01f775f8 100644 --- a/frontend/src/components/markdown-renderer/hooks/use-extension-event-emitter.tsx +++ b/frontend/src/components/markdown-renderer/hooks/use-extension-event-emitter.tsx @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import EventEmitter2 from 'eventemitter2' +import { EventEmitter2 } from 'eventemitter2' import type { PropsWithChildren } from 'react' import React, { createContext, useContext, useEffect, useMemo } from 'react' diff --git a/frontend/src/components/render-page/iframe-markdown-renderer.tsx b/frontend/src/components/render-page/iframe-markdown-renderer.tsx index f28c6fc3b..c409f87c8 100644 --- a/frontend/src/components/render-page/iframe-markdown-renderer.tsx +++ b/frontend/src/components/render-page/iframe-markdown-renderer.tsx @@ -14,7 +14,7 @@ import { useRendererReceiveHandler } from './window-post-message-communicator/ho import type { BaseConfiguration } from './window-post-message-communicator/rendering-message' import { CommunicationMessageType, RendererType } from './window-post-message-communicator/rendering-message' import { countWords } from './word-counter' -import EventEmitter2 from 'eventemitter2' +import { EventEmitter2 } from 'eventemitter2' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' /** @@ -174,10 +174,10 @@ export const IframeMarkdownRenderer: React.FC = () => { const extensionEventEmitter = useMemo(() => new EventEmitter2({ wildcard: true }), []) useEffect(() => { - extensionEventEmitter.onAny((event, values) => { + extensionEventEmitter.onAny((event: string, values: unknown) => { communicator.sendMessageToOtherSide({ type: CommunicationMessageType.EXTENSION_EVENT, - eventName: typeof event === 'object' ? event.join('.') : event, + eventName: event, payload: values }) }) diff --git a/frontend/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts b/frontend/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts index 79ace90c1..3b830472a 100644 --- a/frontend/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts +++ b/frontend/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts @@ -5,7 +5,7 @@ */ import type { Logger } from '../../../utils/logger' import { Optional } from '@mrdrogdrog/optional' -import EventEmitter2 from 'eventemitter2' +import { EventEmitter2 } from 'eventemitter2' /** * Error that will be thrown if a message couldn't be sent. diff --git a/frontend/src/extensions/base/app-extension.ts b/frontend/src/extensions/base/app-extension.ts index af4706a6d..8d2e13697 100644 --- a/frontend/src/extensions/base/app-extension.ts +++ b/frontend/src/extensions/base/app-extension.ts @@ -5,7 +5,7 @@ */ import type { Linter } from '../../components/editor-page/editor-pane/linter/linter' import type { MarkdownRendererExtension } from '../../components/markdown-renderer/extensions/base/markdown-renderer-extension' -import type EventEmitter2 from 'eventemitter2' +import type { EventEmitter2 } from 'eventemitter2' import type React from 'react' import { Fragment } from 'react' diff --git a/frontend/src/extensions/extra-integrations/task-list/task-list-checkbox-app-extension.ts b/frontend/src/extensions/extra-integrations/task-list/task-list-checkbox-app-extension.ts index 7b31eb03a..659792017 100644 --- a/frontend/src/extensions/extra-integrations/task-list/task-list-checkbox-app-extension.ts +++ b/frontend/src/extensions/extra-integrations/task-list/task-list-checkbox-app-extension.ts @@ -6,7 +6,7 @@ import { AppExtension } from '../../base/app-extension' import { SetCheckboxInEditor } from './set-checkbox-in-editor' import { TaskListMarkdownExtension } from './task-list-markdown-extension' -import type EventEmitter2 from 'eventemitter2' +import type { EventEmitter2 } from 'eventemitter2' import type React from 'react' /** diff --git a/package.json b/package.json index 1f0d0f831..8802537b5 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "@codemirror/theme-one-dark": "6.1.0", "@types/react": "18.0.27", "y-protocols@^1.0.0": "patch:y-protocols@npm%3A1.0.5#./.yarn/patches/y-protocols-npm-1.0.5-af6f64b4df.patch", - "y-protocols@1.0.5": "patch:y-protocols@npm%3A1.0.5#./.yarn/patches/y-protocols-npm-1.0.5-af6f64b4df.patch" + "y-protocols@1.0.5": "patch:y-protocols@npm%3A1.0.5#./.yarn/patches/y-protocols-npm-1.0.5-af6f64b4df.patch", + "eventemitter2@6.4.9": "patch:eventemitter2@npm%3A6.4.9#./.yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch" }, "devDependencies": { "turbo": "1.6.3" diff --git a/yarn.lock b/yarn.lock index 7f37e4ba8..7699c9757 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9298,6 +9298,13 @@ __metadata: languageName: node linkType: hard +"eventemitter2@patch:eventemitter2@npm%3A6.4.9#./.yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch::locator=hedgedoc%40workspace%3A.": + version: 6.4.9 + resolution: "eventemitter2@patch:eventemitter2@npm%3A6.4.9#./.yarn/patches/eventemitter2-npm-6.4.9-ba37798a18.patch::version=6.4.9&hash=7bad23&locator=hedgedoc%40workspace%3A." + checksum: 058a7ea1566747b005835f0c1f2348aabd355c819c1d63d4d879a476503f51c5bde93f72796813dcdae066fe6e4535c6415b91c66acaadc53251b54a274c9263 + languageName: node + linkType: hard + "eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.4": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7"