diff --git a/commons/.prettierrc.json b/commons/.prettierrc.json index 3421bdfba..c4b3736a8 100644 --- a/commons/.prettierrc.json +++ b/commons/.prettierrc.json @@ -4,7 +4,7 @@ "jsxSingleQuote": true, "semi": false, "tabWidth": 2, - "trailingComma": "none", + "trailingComma": "all", "bracketSpacing": true, "bracketSameLine": true, "arrowParens": "always" diff --git a/commons/src/frontmatter-extractor/extractor.spec.ts b/commons/src/frontmatter-extractor/extractor.spec.ts index 3a646f6b4..182e28fb3 100644 --- a/commons/src/frontmatter-extractor/extractor.spec.ts +++ b/commons/src/frontmatter-extractor/extractor.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -34,7 +34,7 @@ describe('frontmatter extraction', () => { 'this is not frontmatter', 'because', 'there is no', - 'end marker' + 'end marker', ] const extraction = extractFrontmatter(testNote) expect(extraction).toBeUndefined() diff --git a/commons/src/frontmatter-extractor/extractor.ts b/commons/src/frontmatter-extractor/extractor.ts index dbeaed6d8..c7df7f5e3 100644 --- a/commons/src/frontmatter-extractor/extractor.ts +++ b/commons/src/frontmatter-extractor/extractor.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -20,7 +20,7 @@ const FRONTMATTER_INCOMPLETE_END_REGEX = /^-{1,2}$/ * given multiline string for retrieving the non-frontmatter content. */ export const extractFrontmatter = ( - lines: string[] + lines: string[], ): FrontmatterExtractionResult | undefined => { if (lines.length < 2 || !FRONTMATTER_BEGIN_REGEX.test(lines[0])) { return undefined @@ -30,7 +30,7 @@ export const extractFrontmatter = ( return { rawText: '', lineOffset: i + 1, - incomplete: true + incomplete: true, } } if ( @@ -40,7 +40,7 @@ export const extractFrontmatter = ( return { rawText: lines.slice(1, i).join('\n'), lineOffset: i + 1, - incomplete: false + incomplete: false, } } } diff --git a/commons/src/message-transporters/disconnect_reason.ts b/commons/src/message-transporters/disconnect_reason.ts index 070bd4842..5ff98cf1e 100644 --- a/commons/src/message-transporters/disconnect_reason.ts +++ b/commons/src/message-transporters/disconnect_reason.ts @@ -1,9 +1,9 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ export enum DisconnectReason { - USER_NOT_PERMITTED = 4000 + USER_NOT_PERMITTED = 4000, } diff --git a/commons/src/message-transporters/message-transporter.ts b/commons/src/message-transporters/message-transporter.ts index 24c4b7af7..52286c3a8 100644 --- a/commons/src/message-transporters/message-transporter.ts +++ b/commons/src/message-transporters/message-transporter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import { ConnectionStateEvent, Message, MessagePayloads, - MessageType + MessageType, } from './message.js' import { TransportAdapter } from './transport-adapter.js' import { EventEmitter2, Listener } from 'eventemitter2' @@ -26,7 +26,7 @@ type MessageEventPayloadMap = { export enum ConnectionState { DISCONNECTED = 'DISCONNECTED', CONNECTING = 'CONNECTING', - CONNECTED = 'CONNECTED' + CONNECTED = 'CONNECTED', } /** @@ -53,7 +53,7 @@ export class MessageTransporter extends EventEmitter2 { if (this.transportAdapter === undefined) { console.debug( "Can't send message without transport adapter. Message that couldn't be sent was", - content + content, ) return } @@ -62,7 +62,7 @@ export class MessageTransporter extends EventEmitter2 { this.onDisconnecting() console.debug( "Can't send message over closed connection. Triggering onDisconencted event. Message that couldn't be sent was", - content + content, ) return } @@ -105,7 +105,7 @@ export class MessageTransporter extends EventEmitter2 { this.onConnected() } else { this.destroyOnConnectedEventHandler = websocket.bindOnConnectedEvent( - this.onConnected.bind(this) + this.onConnected.bind(this), ) } } @@ -167,13 +167,13 @@ export class MessageTransporter extends EventEmitter2 { private bindWebsocketEvents(transportAdapter: TransportAdapter) { this.destroyOnErrorEventHandler = transportAdapter.bindOnErrorEvent( - this.onDisconnecting.bind(this) + this.onDisconnecting.bind(this), ) this.destroyOnCloseEventHandler = transportAdapter.bindOnCloseEvent( - this.onDisconnecting.bind(this) + this.onDisconnecting.bind(this), ) this.destroyOnMessageEventHandler = transportAdapter.bindOnMessageEvent( - this.receiveMessage.bind(this) + this.receiveMessage.bind(this), ) } @@ -221,7 +221,7 @@ export class MessageTransporter extends EventEmitter2 { callback() } return this.on('ready', callback, { - objectify: true + objectify: true, }) as Listener } @@ -237,7 +237,7 @@ export class MessageTransporter extends EventEmitter2 { callback() } return this.on('connected', callback, { - objectify: true + objectify: true, }) as Listener } @@ -253,11 +253,11 @@ export class MessageTransporter extends EventEmitter2 { protected startSendingOfReadyRequests(): void { this.readyInterval = setInterval(() => { this.sendMessage({ - type: MessageType.READY_REQUEST + type: MessageType.READY_REQUEST, }) }, 400) this.sendMessage({ - type: MessageType.READY_REQUEST + type: MessageType.READY_REQUEST, }) } } diff --git a/commons/src/message-transporters/message.ts b/commons/src/message-transporters/message.ts index f45e33c06..1fcb53112 100644 --- a/commons/src/message-transporters/message.ts +++ b/commons/src/message-transporters/message.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -19,13 +19,13 @@ export enum MessageType { REALTIME_USER_SET_ACTIVITY = 'REALTIME_USER_SET_ACTIVITY', READY_REQUEST = 'READY_REQUEST', - READY_ANSWER = 'READY_ANSWER' + READY_ANSWER = 'READY_ANSWER', } export enum ConnectionStateEvent { READY = 'ready', CONNECTED = 'connected', - DISCONNECTED = 'disconnected' + DISCONNECTED = 'disconnected', } export interface MessagePayloads { diff --git a/commons/src/message-transporters/mocked-backend-transport-adapter.ts b/commons/src/message-transporters/mocked-backend-transport-adapter.ts index 1d824368b..217c29467 100644 --- a/commons/src/message-transporters/mocked-backend-transport-adapter.ts +++ b/commons/src/message-transporters/mocked-backend-transport-adapter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -46,7 +46,7 @@ export class MockedBackendTransportAdapter implements TransportAdapter { } bindOnMessageEvent( - handler: (value: Message) => void + handler: (value: Message) => void, ): () => void { this.messageHandler = handler return () => { @@ -74,17 +74,17 @@ export class MockedBackendTransportAdapter implements TransportAdapter { () => this.messageHandler?.({ type: MessageType.NOTE_CONTENT_UPDATE, - payload: this.doc.encodeStateAsUpdate(value.payload) + payload: this.doc.encodeStateAsUpdate(value.payload), }), - 0 + 0, ) } else if (value.type === MessageType.READY_REQUEST) { setTimeout( () => this.messageHandler?.({ - type: MessageType.READY_ANSWER + type: MessageType.READY_ANSWER, }), - 0 + 0, ) } } diff --git a/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts b/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts index 87cde1a70..9fda9be7f 100644 --- a/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts +++ b/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import { NoteFrontmatter, NoteTextDirection, NoteType, - OpenGraph + OpenGraph, } from '../note-frontmatter/frontmatter.js' import { SlideOptions } from '../note-frontmatter/slide-show-options.js' import { convertRawFrontmatterToNoteFrontmatter } from './convert-raw-frontmatter-to-note-frontmatter.js' @@ -31,8 +31,8 @@ describe('convertRawFrontmatterToNoteFrontmatter', () => { breaks: breaks, opengraph: opengraph, slideOptions: slideOptions, - tags: 'tags' - }) + tags: 'tags', + }), ).toStrictEqual({ title: 'title', description: 'description', @@ -44,8 +44,8 @@ describe('convertRawFrontmatterToNoteFrontmatter', () => { opengraph: opengraph, slideOptions: slideOptions, license: 'license', - tags: ['tags'] + tags: ['tags'], } as NoteFrontmatter) - } + }, ) }) diff --git a/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.ts b/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.ts index 234504375..4d8c3b5af 100644 --- a/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.ts +++ b/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -12,7 +12,7 @@ import { RawNoteFrontmatter } from './types.js' * @param rawData A {@link RawNoteFrontmatter} object containing the properties of the parsed yaml frontmatter. */ export const convertRawFrontmatterToNoteFrontmatter = ( - rawData: RawNoteFrontmatter + rawData: RawNoteFrontmatter, ): NoteFrontmatter => { return { title: rawData.title, @@ -25,6 +25,6 @@ export const convertRawFrontmatterToNoteFrontmatter = ( opengraph: rawData.opengraph, slideOptions: rawData.slideOptions, license: rawData.license, - tags: parseTags(rawData.tags) + tags: parseTags(rawData.tags), } } diff --git a/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts b/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts index 7417f6eb1..45b215c61 100644 --- a/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts +++ b/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -32,7 +32,7 @@ describe('yaml frontmatter', () => { it('should parse the tag inline-list syntax', () => { const noteFrontmatter = parseRawFrontmatterFromYaml( - "tags: ['test123', 'abc']" + "tags: ['test123', 'abc']", ) expect(noteFrontmatter.value?.tags).toEqual(['test123', 'abc']) }) @@ -57,7 +57,7 @@ describe('yaml frontmatter', () => { `) expect(noteFrontmatter.value?.opengraph.title).toEqual('Testtitle') expect(noteFrontmatter.value?.opengraph.image).toEqual( - 'https://dummyimage.com/48.png' + 'https://dummyimage.com/48.png', ) expect(noteFrontmatter.value?.opengraph['image:type']).toEqual('image/png') }) diff --git a/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.ts b/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.ts index 63b29b6ce..27ffca1ea 100644 --- a/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.ts +++ b/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import { defaultNoteFrontmatter } from '../note-frontmatter/index.js' import { NoteTextDirection, NoteType, - OpenGraph + OpenGraph, } from '../note-frontmatter/index.js' import { SlideOptions } from '../note-frontmatter/index.js' import { ISO6391 } from '../note-frontmatter/iso6391.js' @@ -24,7 +24,7 @@ const schema = Joi.object({ tags: Joi.alternatives( Joi.array().items(Joi.string()), Joi.string(), - Joi.number().cast('string') + Joi.number().cast('string'), ) .optional() .default(defaultNoteFrontmatter.tags), @@ -51,17 +51,17 @@ const schema = Joi.object({ transition: Joi.string().optional(), backgroundTransition: Joi.string().optional(), autoSlideStoppable: Joi.boolean().optional(), - slideNumber: Joi.boolean().optional() + slideNumber: Joi.boolean().optional(), }) .optional() .default(defaultNoteFrontmatter.slideOptions), opengraph: Joi.object({ title: Joi.string().optional(), - image: Joi.string().uri().optional() + image: Joi.string().uri().optional(), }) .unknown(true) .optional() - .default(defaultNoteFrontmatter.opengraph) + .default(defaultNoteFrontmatter.opengraph), }) .default(defaultNoteFrontmatter) .unknown(true) diff --git a/commons/src/note-frontmatter-parser/parse-tags.spec.ts b/commons/src/note-frontmatter-parser/parse-tags.spec.ts index dae438e3c..323819aac 100644 --- a/commons/src/note-frontmatter-parser/parse-tags.spec.ts +++ b/commons/src/note-frontmatter-parser/parse-tags.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -14,7 +14,7 @@ describe('parse tags', () => { 'c', 'd', 'e', - 'f' + 'f', ]) }) @@ -25,7 +25,7 @@ describe('parse tags', () => { 'c', 'd', 'e', - 'f' + 'f', ]) }) }) diff --git a/commons/src/note-frontmatter-parser/types.ts b/commons/src/note-frontmatter-parser/types.ts index f4b07e8d8..c3575dca0 100644 --- a/commons/src/note-frontmatter-parser/types.ts +++ b/commons/src/note-frontmatter-parser/types.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import { Iso6391Language, NoteTextDirection, NoteType, - OpenGraph + OpenGraph, } from '../note-frontmatter/index.js' import { SlideOptions } from '../note-frontmatter/index.js' diff --git a/commons/src/note-frontmatter/default-values.ts b/commons/src/note-frontmatter/default-values.ts index 2b9479461..03123c7a4 100644 --- a/commons/src/note-frontmatter/default-values.ts +++ b/commons/src/note-frontmatter/default-values.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -11,7 +11,7 @@ export const defaultSlideOptions: SlideOptions = { autoSlide: 0, autoSlideStoppable: true, backgroundTransition: 'fade', - slideNumber: false + slideNumber: false, } export const defaultNoteFrontmatter: NoteFrontmatter = { @@ -25,5 +25,5 @@ export const defaultNoteFrontmatter: NoteFrontmatter = { license: '', type: NoteType.DOCUMENT, opengraph: {}, - slideOptions: defaultSlideOptions + slideOptions: defaultSlideOptions, } diff --git a/commons/src/note-frontmatter/frontmatter.ts b/commons/src/note-frontmatter/frontmatter.ts index 394557c84..41de9b66b 100644 --- a/commons/src/note-frontmatter/frontmatter.ts +++ b/commons/src/note-frontmatter/frontmatter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -12,12 +12,12 @@ export type OpenGraph = Record export enum NoteTextDirection { LTR = 'ltr', - RTL = 'rtl' + RTL = 'rtl', } export enum NoteType { DOCUMENT = 'document', - SLIDE = 'slide' + SLIDE = 'slide', } export interface NoteFrontmatter { title: string diff --git a/commons/src/note-frontmatter/iso6391.ts b/commons/src/note-frontmatter/iso6391.ts index 4ec2294d5..e7315b88c 100644 --- a/commons/src/note-frontmatter/iso6391.ts +++ b/commons/src/note-frontmatter/iso6391.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -187,5 +187,5 @@ export const ISO6391 = [ 'yo', 'za', 'zh', - 'zu' + 'zu', ] as const diff --git a/commons/src/parse-url/parse-url.spec.ts b/commons/src/parse-url/parse-url.spec.ts index 28a69f209..5c53de098 100644 --- a/commons/src/parse-url/parse-url.spec.ts +++ b/commons/src/parse-url/parse-url.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -15,12 +15,12 @@ describe('validate url', () => { describe('protocols', () => { it('works with http', () => { expect(parseUrl('http://example.org').get().toString()).toEqual( - 'http://example.org/' + 'http://example.org/', ) }) it('works with https', () => { expect(parseUrl('https://example.org').get().toString()).toEqual( - 'https://example.org/' + 'https://example.org/', ) }) it("doesn't work without protocol", () => { @@ -28,7 +28,7 @@ describe('validate url', () => { }) it("doesn't work any other protocol", () => { expect(() => parseUrl('git://example.org').get()).toThrowError( - WrongProtocolError + WrongProtocolError, ) }) }) @@ -36,22 +36,22 @@ describe('validate url', () => { describe('trailing slash', () => { it('accepts urls with just domain with trailing slash', () => { expect(parseUrl('http://example.org/').get().toString()).toEqual( - 'http://example.org/' + 'http://example.org/', ) }) it('accepts urls with just domain without trailing slash', () => { expect(parseUrl('http://example.org').get().toString()).toEqual( - 'http://example.org/' + 'http://example.org/', ) }) it('declines urls with with subpath and trailing slash', () => { expect(() => - parseUrl('http://example.org/asd/').get().toString() + parseUrl('http://example.org/asd/').get().toString(), ).toThrow(NoSubdirectoryAllowedError) }) it('declines urls with with subpath and without trailing slash', () => { expect(() => parseUrl('http://example.org/asd').get().toString()).toThrow( - NoSubdirectoryAllowedError + NoSubdirectoryAllowedError, ) }) }) diff --git a/commons/src/parse-url/parse-url.ts b/commons/src/parse-url/parse-url.ts index d1a8430c6..29ba600fb 100644 --- a/commons/src/parse-url/parse-url.ts +++ b/commons/src/parse-url/parse-url.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -18,11 +18,11 @@ export function parseUrl(url: string | undefined): Optional { return createOptionalUrl(url) .guard( (value) => value.protocol === 'https:' || value.protocol === 'http:', - () => new WrongProtocolError() + () => new WrongProtocolError(), ) .guard( (value) => value.pathname === '/', - () => new NoSubdirectoryAllowedError() + () => new NoSubdirectoryAllowedError(), ) } diff --git a/commons/src/permissions/permissions.spec.ts b/commons/src/permissions/permissions.spec.ts index 605e16fbe..9358bd448 100644 --- a/commons/src/permissions/permissions.spec.ts +++ b/commons/src/permissions/permissions.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -13,19 +13,19 @@ describe('Permissions', () => { sharedToUsers: [ { username: 'logged_in', - canEdit: true - } + canEdit: true, + }, ], sharedToGroups: [ { groupName: SpecialGroup.EVERYONE, - canEdit: true + canEdit: true, }, { groupName: SpecialGroup.LOGGED_IN, - canEdit: true - } - ] + canEdit: true, + }, + ], } describe('userIsOwner', () => { it('returns true, if user is owner', () => { @@ -45,25 +45,25 @@ describe('Permissions', () => { }) it('returns true, if user is logged in and this is user specifically may edit', () => { expect( - userCanEdit({ ...testPermissions, sharedToGroups: [] }, 'logged_in') + userCanEdit({ ...testPermissions, sharedToGroups: [] }, 'logged_in'), ).toBeTruthy() }) it('returns true, if user is logged in and loggedIn users may edit', () => { expect( - userCanEdit({ ...testPermissions, sharedToUsers: [] }, 'logged_in') + userCanEdit({ ...testPermissions, sharedToUsers: [] }, 'logged_in'), ).toBeTruthy() }) it('returns true, if user is guest and guests are allowed to edit', () => { expect( - userCanEdit({ ...testPermissions, sharedToUsers: [] }, undefined) + userCanEdit({ ...testPermissions, sharedToUsers: [] }, undefined), ).toBeTruthy() }) it('returns false, if user is logged in and loggedIn users may not edit', () => { expect( userCanEdit( { ...testPermissions, sharedToUsers: [], sharedToGroups: [] }, - 'logged_in' - ) + 'logged_in', + ), ).toBeFalsy() }) it('returns false, if user is guest and guests are not allowed to edit', () => { @@ -75,12 +75,12 @@ describe('Permissions', () => { sharedToGroups: [ { groupName: SpecialGroup.LOGGED_IN, - canEdit: true - } - ] + canEdit: true, + }, + ], }, - undefined - ) + undefined, + ), ).toBeFalsy() }) }) diff --git a/commons/src/permissions/permissions.ts b/commons/src/permissions/permissions.ts index 98218d3a7..0e8f2b252 100644 --- a/commons/src/permissions/permissions.ts +++ b/commons/src/permissions/permissions.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -14,7 +14,7 @@ import { NotePermissions, SpecialGroup } from './permissions.types.js' */ export const userIsOwner = ( permissions: NotePermissions, - user?: string + user?: string, ): boolean => { return !!user && permissions.owner === user } @@ -28,21 +28,21 @@ export const userIsOwner = ( */ export const userCanEdit = ( permissions: NotePermissions, - user?: string + user?: string, ): boolean => { const isOwner = userIsOwner(permissions, user) const mayWriteViaUserPermission = permissions.sharedToUsers.some( - (value) => value.canEdit && value.username === user + (value) => value.canEdit && value.username === user, ) const mayWriteViaGroupPermission = !!user && permissions.sharedToGroups.some( (value) => - value.groupName === (SpecialGroup.LOGGED_IN as string) && value.canEdit + value.groupName === (SpecialGroup.LOGGED_IN as string) && value.canEdit, ) const everyoneMayWriteViaGroupPermission = permissions.sharedToGroups.some( (value) => - value.groupName === (SpecialGroup.EVERYONE as string) && value.canEdit + value.groupName === (SpecialGroup.EVERYONE as string) && value.canEdit, ) return ( isOwner || diff --git a/commons/src/permissions/permissions.types.ts b/commons/src/permissions/permissions.types.ts index bb8f95e7e..8a0d6834b 100644 --- a/commons/src/permissions/permissions.types.ts +++ b/commons/src/permissions/permissions.types.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -22,10 +22,10 @@ export interface NoteGroupPermissionEntry { export enum AccessLevel { NONE, READ_ONLY, - WRITEABLE + WRITEABLE, } export enum SpecialGroup { EVERYONE = '_EVERYONE', - LOGGED_IN = '_LOGGED_IN' + LOGGED_IN = '_LOGGED_IN', } diff --git a/commons/src/title-extraction/extract-first-heading.spec.ts b/commons/src/title-extraction/extract-first-heading.spec.ts index 153e76002..531447b5c 100644 --- a/commons/src/title-extraction/extract-first-heading.spec.ts +++ b/commons/src/title-extraction/extract-first-heading.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -19,8 +19,8 @@ describe('extract first heading', () => { it("doesn't extract heading-anchor", () => { const headline = new Element(`h${headlineIndex}`, {}, [ new Element('a', { class: 'class1 heading-anchor class2' }, [ - new Text('invalid link content') - ]) + new Text('invalid link content'), + ]), ]) const document = new Document([headline]) expect(extractFirstHeading(document)).toBe('') @@ -31,8 +31,8 @@ describe('extract first heading', () => { new Element('a', {}, [ new Text('Valid'), new Element('div', {}, [new Text('Text')]), - new Text(`${headlineIndex}`) - ]) + new Text(`${headlineIndex}`), + ]), ]) const document = new Document([headline]) expect(extractFirstHeading(document)).toBe(`ValidText${headlineIndex}`) @@ -40,7 +40,7 @@ describe('extract first heading', () => { it('extracts image alt texts', () => { const headline = new Element(`h${headlineIndex}`, {}, [ - new Element('img', { alt: 'Image Alt' }) + new Element('img', { alt: 'Image Alt' }), ]) const document = new Document([headline]) expect(extractFirstHeading(document)).toBe('Image Alt') @@ -48,10 +48,10 @@ describe('extract first heading', () => { it('extracts only the first found headline', () => { const headline1 = new Element(`h${headlineIndex}`, {}, [ - new Text(`headline${headlineIndex}`) + new Text(`headline${headlineIndex}`), ]) const headline2 = new Element(`h${headlineIndex}`, {}, [ - new Text('headline1') + new Text('headline1'), ]) const document = new Document([headline1, headline2]) expect(extractFirstHeading(document)).toBe(`headline${headlineIndex}`) diff --git a/commons/src/title-extraction/extract-first-heading.ts b/commons/src/title-extraction/extract-first-heading.ts index 1cfece20c..a4d6a82ca 100644 --- a/commons/src/title-extraction/extract-first-heading.ts +++ b/commons/src/title-extraction/extract-first-heading.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -14,7 +14,7 @@ const headlineTagRegex = /^h[1-6]$/gi * @return the plain text representation of the first headline. {@code undefined} if no headline has been found. */ export function extractFirstHeading( - nodes: NodeWithChildren + nodes: NodeWithChildren, ): string | undefined { const foundHeadlineNode = checkNodesForHeadline(nodes.children) if (!foundHeadlineNode) { diff --git a/commons/src/title-extraction/generate-note-title.spec.ts b/commons/src/title-extraction/generate-note-title.spec.ts index 97de95e80..d29b388b5 100644 --- a/commons/src/title-extraction/generate-note-title.spec.ts +++ b/commons/src/title-extraction/generate-note-title.spec.ts @@ -1,12 +1,12 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { NoteFrontmatter, NoteTextDirection, - NoteType + NoteType, } from '../note-frontmatter/frontmatter.js' import { generateNoteTitle } from './generate-note-title.js' import { describe, expect, it } from '@jest/globals' @@ -27,8 +27,8 @@ const testFrontmatter: NoteFrontmatter = { autoSlide: 0, autoSlideStoppable: true, backgroundTransition: 'fade', - slideNumber: false - } + slideNumber: false, + }, } describe('generate note title', () => { @@ -37,9 +37,9 @@ describe('generate note title', () => { { ...testFrontmatter, title: 'frontmatter', - opengraph: { title: 'opengraph' } + opengraph: { title: 'opengraph' }, }, - () => 'first-heading' + () => 'first-heading', ) expect(actual).toEqual('frontmatter') }) @@ -47,7 +47,7 @@ describe('generate note title', () => { it('will choose the opengraph title second', () => { const actual = generateNoteTitle( { ...testFrontmatter, opengraph: { title: 'opengraph' } }, - () => 'first-heading' + () => 'first-heading', ) expect(actual).toEqual('opengraph') }) @@ -55,7 +55,7 @@ describe('generate note title', () => { it('will choose the first heading third', () => { const actual = generateNoteTitle( { ...testFrontmatter }, - () => 'first-heading' + () => 'first-heading', ) expect(actual).toEqual('first-heading') }) diff --git a/commons/src/title-extraction/generate-note-title.ts b/commons/src/title-extraction/generate-note-title.ts index 56badf0ae..6478c7a6c 100644 --- a/commons/src/title-extraction/generate-note-title.ts +++ b/commons/src/title-extraction/generate-note-title.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -14,7 +14,7 @@ import type { NoteFrontmatter } from '../note-frontmatter/frontmatter.js' */ export const generateNoteTitle = ( frontmatter: NoteFrontmatter | undefined, - firstHeadingProvider: () => string | undefined + firstHeadingProvider: () => string | undefined, ): string => { if (frontmatter?.title) { return frontmatter.title.trim() diff --git a/commons/src/y-doc-sync/in-memory-connection-transport-adapter.ts b/commons/src/y-doc-sync/in-memory-connection-transport-adapter.ts index 8dd7478a3..51bbf4a34 100644 --- a/commons/src/y-doc-sync/in-memory-connection-transport-adapter.ts +++ b/commons/src/y-doc-sync/in-memory-connection-transport-adapter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -42,7 +42,7 @@ export class InMemoryConnectionTransportAdapter implements TransportAdapter { } bindOnMessageEvent( - handler: (value: Message) => void + handler: (value: Message) => void, ): () => void { this.onMessageHandler = handler return () => (this.onMessageHandler = undefined) diff --git a/commons/src/y-doc-sync/realtime-doc.spec.ts b/commons/src/y-doc-sync/realtime-doc.spec.ts index 78afe474d..dd00e52ed 100644 --- a/commons/src/y-doc-sync/realtime-doc.spec.ts +++ b/commons/src/y-doc-sync/realtime-doc.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -25,12 +25,12 @@ describe('realtime doc', () => { 1, 1, 221, 208, 165, 230, 3, 0, 4, 1, 15, 109, 97, 114, 107, 100, 111, 119, 110, 67, 111, 110, 116, 101, 110, 116, 32, 116, 101, 120, 116, 67, 111, 110, 116, 101, 110, 116, 70, 114, 111, 109, 83, 116, 97, 116, 101, - 86, 101, 99, 116, 111, 114, 85, 112, 100, 97, 116, 101, 0 - ] + 86, 101, 99, 116, 111, 114, 85, 112, 100, 97, 116, 101, 0, + ], ) expect(realtimeDoc.getCurrentContent()).toBe( - 'textContentFromStateVectorUpdate' + 'textContentFromStateVectorUpdate', ) }) }) diff --git a/commons/src/y-doc-sync/realtime-doc.ts b/commons/src/y-doc-sync/realtime-doc.ts index 5ac782ed4..b1741d54e 100644 --- a/commons/src/y-doc-sync/realtime-doc.ts +++ b/commons/src/y-doc-sync/realtime-doc.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -10,7 +10,7 @@ import { Doc, encodeStateAsUpdate, encodeStateVector, - Text as YText + Text as YText, } from 'yjs' const MARKDOWN_CONTENT_CHANNEL_NAME = 'markdownContent' @@ -26,7 +26,7 @@ export class RealtimeDoc extends EventEmitter2 { private doc: Doc = new Doc() private readonly docUpdateListener: ( update: Uint8Array, - origin: unknown + origin: unknown, ) => void /** diff --git a/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts b/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts index 033d5c4c6..d2c6c9d53 100644 --- a/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts +++ b/commons/src/y-doc-sync/y-doc-sync-adapter.spec.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -30,28 +30,28 @@ describe('y-doc-sync-adapter', () => { textServer.observe(() => // eslint-disable-next-line @typescript-eslint/no-base-to-string - console.log('textServer', new Date(), textServer.toString()) + console.log('textServer', new Date(), textServer.toString()), ) textClient1.observe(() => // eslint-disable-next-line @typescript-eslint/no-base-to-string - console.log('textClient1', new Date(), textClient1.toString()) + console.log('textClient1', new Date(), textClient1.toString()), ) textClient2.observe(() => // eslint-disable-next-line @typescript-eslint/no-base-to-string - console.log('textClient2', new Date(), textClient2.toString()) + console.log('textClient2', new Date(), textClient2.toString()), ) const transporterAdapterServerTo1 = new InMemoryConnectionTransportAdapter( - 's>1' + 's>1', ) const transporterAdapterServerTo2 = new InMemoryConnectionTransportAdapter( - 's>2' + 's>2', ) const transporterAdapterClient1 = new InMemoryConnectionTransportAdapter( - '1>s' + '1>s', ) const transporterAdapterClient2 = new InMemoryConnectionTransportAdapter( - '2>s' + '2>s', ) const messageTransporterServerTo1 = new MessageTransporter() @@ -60,54 +60,54 @@ describe('y-doc-sync-adapter', () => { const messageTransporterClient2 = new MessageTransporter() messageTransporterServerTo1.on(MessageType.NOTE_CONTENT_UPDATE, () => - console.log('Received NOTE_CONTENT_UPDATE from client 1 to server') + console.log('Received NOTE_CONTENT_UPDATE from client 1 to server'), ) messageTransporterServerTo2.on(MessageType.NOTE_CONTENT_UPDATE, () => - console.log('Received NOTE_CONTENT_UPDATE from client 2 to server') + console.log('Received NOTE_CONTENT_UPDATE from client 2 to server'), ) messageTransporterClient1.on(MessageType.NOTE_CONTENT_UPDATE, () => - console.log('Received NOTE_CONTENT_UPDATE from server to client 1') + console.log('Received NOTE_CONTENT_UPDATE from server to client 1'), ) messageTransporterClient2.on(MessageType.NOTE_CONTENT_UPDATE, () => - console.log('Received NOTE_CONTENT_UPDATE from server to client 2') + console.log('Received NOTE_CONTENT_UPDATE from server to client 2'), ) messageTransporterServerTo1.on(MessageType.NOTE_CONTENT_STATE_REQUEST, () => - console.log('Received NOTE_CONTENT_REQUEST from client 1 to server') + console.log('Received NOTE_CONTENT_REQUEST from client 1 to server'), ) messageTransporterServerTo2.on(MessageType.NOTE_CONTENT_STATE_REQUEST, () => - console.log('Received NOTE_CONTENT_REQUEST from client 2 to server') + console.log('Received NOTE_CONTENT_REQUEST from client 2 to server'), ) messageTransporterClient1.on(MessageType.NOTE_CONTENT_STATE_REQUEST, () => - console.log('Received NOTE_CONTENT_REQUEST from server to client 1') + console.log('Received NOTE_CONTENT_REQUEST from server to client 1'), ) messageTransporterClient2.on(MessageType.NOTE_CONTENT_STATE_REQUEST, () => - console.log('Received NOTE_CONTENT_REQUEST from server to client 2') + console.log('Received NOTE_CONTENT_REQUEST from server to client 2'), ) messageTransporterClient1.doAsSoonAsConnected(() => - console.log('1>s is connected') + console.log('1>s is connected'), ) messageTransporterClient2.doAsSoonAsConnected(() => - console.log('2>s is connected') + console.log('2>s is connected'), ) messageTransporterServerTo1.doAsSoonAsConnected(() => - console.log('s>1 is connected') + console.log('s>1 is connected'), ) messageTransporterServerTo2.doAsSoonAsConnected(() => - console.log('s>2 is connected') + console.log('s>2 is connected'), ) messageTransporterClient1.doAsSoonAsReady(() => console.log('1>s is ready')) messageTransporterClient2.doAsSoonAsReady(() => console.log('2>s is ready')) messageTransporterServerTo1.doAsSoonAsReady(() => - console.log('s>1 is connected') + console.log('s>1 is connected'), ) messageTransporterServerTo2.doAsSoonAsReady(() => - console.log('s>2 is connected') + console.log('s>2 is connected'), ) docServer.on('update', (update: number[], origin: unknown) => { const message: Message = { type: MessageType.NOTE_CONTENT_UPDATE, - payload: update + payload: update, } if (origin !== messageTransporterServerTo1) { console.log('YDoc on Server updated. Sending to Client 1') @@ -131,23 +131,23 @@ describe('y-doc-sync-adapter', () => { const yDocSyncAdapter1 = new YDocSyncClientAdapter( messageTransporterClient1, - docClient1 + docClient1, ) const yDocSyncAdapter2 = new YDocSyncClientAdapter( messageTransporterClient2, - docClient2 + docClient2, ) const yDocSyncAdapterServerTo1 = new YDocSyncServerAdapter( messageTransporterServerTo1, docServer, - () => true + () => true, ) const yDocSyncAdapterServerTo2 = new YDocSyncServerAdapter( messageTransporterServerTo2, docServer, - () => true + () => true, ) const waitForClient1Sync = new Promise((resolve) => { @@ -202,7 +202,7 @@ describe('y-doc-sync-adapter', () => { waitForClient1Sync, waitForClient2Sync, waitForServerTo11Sync, - waitForServerTo21Sync + waitForServerTo21Sync, ]) textClient1.insert(0, 'test2') diff --git a/commons/src/y-doc-sync/y-doc-sync-adapter.ts b/commons/src/y-doc-sync/y-doc-sync-adapter.ts index 00de3d8ae..752692dca 100644 --- a/commons/src/y-doc-sync/y-doc-sync-adapter.ts +++ b/commons/src/y-doc-sync/y-doc-sync-adapter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -23,7 +23,7 @@ export abstract class YDocSyncAdapter { constructor( protected readonly messageTransporter: MessageTransporter, - protected readonly doc: RealtimeDoc + protected readonly doc: RealtimeDoc, ) { this.yDocUpdateListener = doc.on( 'update', @@ -31,8 +31,8 @@ export abstract class YDocSyncAdapter { this.distributeDocUpdate(update, origin) }, { - objectify: true - } + objectify: true, + }, ) as Listener this.destroyEventListenerCallback = this.bindDocumentSyncMessageEvents() @@ -50,7 +50,7 @@ export abstract class YDocSyncAdapter { callback() } return this.eventEmitter.on('synced', callback, { - objectify: true + objectify: true, }) as Listener } @@ -69,10 +69,10 @@ export abstract class YDocSyncAdapter { (payload) => { this.messageTransporter.sendMessage({ type: MessageType.NOTE_CONTENT_UPDATE, - payload: this.doc.encodeStateAsUpdate(payload.payload) + payload: this.doc.encodeStateAsUpdate(payload.payload), }) }, - { objectify: true } + { objectify: true }, ) as Listener const disconnectedListener = this.messageTransporter.on( @@ -81,13 +81,13 @@ export abstract class YDocSyncAdapter { this.synced = false this.eventEmitter.emit('desynced') }, - { objectify: true } + { objectify: true }, ) as Listener const noteContentUpdateListener = this.messageTransporter.on( MessageType.NOTE_CONTENT_UPDATE, (payload) => this.applyIncomingUpdatePayload(payload.payload), - { objectify: true } + { objectify: true }, ) as Listener return () => { @@ -107,7 +107,7 @@ export abstract class YDocSyncAdapter { } const message: Message = { type: MessageType.NOTE_CONTENT_UPDATE, - payload: update + payload: update, } this.messageTransporter.sendMessage(message) @@ -124,7 +124,7 @@ export abstract class YDocSyncAdapter { public requestDocumentState(): void { this.messageTransporter.sendMessage({ type: MessageType.NOTE_CONTENT_STATE_REQUEST, - payload: this.doc.encodeStateVector() + payload: this.doc.encodeStateVector(), }) } } diff --git a/commons/src/y-doc-sync/y-doc-sync-client-adapter.ts b/commons/src/y-doc-sync/y-doc-sync-client-adapter.ts index 7bf140d0f..95fadfc13 100644 --- a/commons/src/y-doc-sync/y-doc-sync-client-adapter.ts +++ b/commons/src/y-doc-sync/y-doc-sync-client-adapter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -16,7 +16,7 @@ export class YDocSyncClientAdapter extends YDocSyncAdapter { () => { this.markAsSynced() }, - { objectify: true } + { objectify: true }, ) as Listener return () => { diff --git a/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts b/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts index eac4ff08b..396bc19a2 100644 --- a/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts +++ b/commons/src/y-doc-sync/y-doc-sync-server-adapter.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -11,7 +11,7 @@ export class YDocSyncServerAdapter extends YDocSyncAdapter { constructor( readonly messageTransporter: MessageTransporter, readonly doc: RealtimeDoc, - private readonly acceptEditsProvider: () => boolean + private readonly acceptEditsProvider: () => boolean, ) { super(messageTransporter, doc) this.markAsSynced()