refactor(backend): use @hedgedoc/commons DTOs

Co-authored-by: Erik Michelson <github@erik.michelson.eu>
Signed-off-by: Erik Michelson <github@erik.michelson.eu>
Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2025-03-22 00:38:15 +01:00
parent 7285c2bc50
commit b11dbd51c8
94 changed files with 514 additions and 1642 deletions

View file

@ -12,7 +12,7 @@ exports[`NotesService toNoteDto works 1`] = `
"primaryAlias": true,
},
],
"createdAt": undefined,
"createdAt": "2019-02-04T20:34:12.000Z",
"description": "mockDescription",
"editedBy": [
"hardcoded",
@ -39,7 +39,7 @@ exports[`NotesService toNoteDto works 1`] = `
],
"title": "mockTitle",
"updateUsername": "hardcoded",
"updatedAt": 2019-02-04T20:34:12.000Z,
"updatedAt": "2019-02-04T20:34:12.000Z",
"version": undefined,
"viewCount": 1337,
},
@ -55,7 +55,7 @@ exports[`NotesService toNoteMetadataDto works 1`] = `
"primaryAlias": true,
},
],
"createdAt": undefined,
"createdAt": "2019-02-04T20:34:12.000Z",
"description": "mockDescription",
"editedBy": [
"hardcoded",
@ -82,7 +82,7 @@ exports[`NotesService toNoteMetadataDto works 1`] = `
],
"title": "mockTitle",
"updateUsername": "hardcoded",
"updatedAt": 2019-02-04T20:34:12.000Z,
"updatedAt": "2019-02-04T20:34:12.000Z",
"version": undefined,
"viewCount": 1337,
}

View file

@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';
import { BaseDto } from '../utils/base.dto.';
export class AliasCreateDto extends BaseDto {
/**
* The note id or alias, which identifies the note the alias should be added to
*/
@IsString()
@ApiProperty()
noteIdOrAlias: string;
/**
* The new alias
*/
@IsString()
@ApiProperty()
newAlias: string;
}

View file

@ -1,18 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean } from 'class-validator';
import { BaseDto } from '../utils/base.dto.';
export class AliasUpdateDto extends BaseDto {
/**
* Whether the alias should become the primary alias or not
*/
@IsBoolean()
@ApiProperty()
primaryAlias: boolean;
}

View file

@ -1,32 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsString } from 'class-validator';
import { BaseDto } from '../utils/base.dto.';
export class AliasDto extends BaseDto {
/**
* The name of the alias
*/
@IsString()
@ApiProperty()
name: string;
/**
* Is the alias the primary alias or not
*/
@IsBoolean()
@ApiProperty()
primaryAlias: boolean;
/**
* The public id of the note the alias is associated with
*/
@IsString()
@ApiProperty()
noteId: string;
}

View file

@ -1,8 +1,9 @@
/*
* SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file)
* SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { AliasDto } from '@hedgedoc/commons';
import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
@ -12,7 +13,6 @@ import {
PrimaryAliasDeletionForbiddenError,
} from '../errors/errors';
import { ConsoleLoggerService } from '../logger/console-logger.service';
import { AliasDto } from './alias.dto';
import { Alias } from './alias.entity';
import { Note } from './note.entity';
import { NotesService } from './notes.service';

View file

@ -1,158 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
IsArray,
IsDate,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { BaseDto } from '../utils/base.dto.';
import { AliasDto } from './alias.dto';
import { NotePermissionsDto } from './note-permissions.dto';
export class NoteMetadataDto extends BaseDto {
/**
* ID of the note
*/
@IsString()
@ApiProperty()
id: string;
/**
* All aliases of the note (including the primaryAlias)
*/
@Type(() => AliasDto)
@IsArray()
@ValidateNested({ each: true })
@ApiProperty({ isArray: true, type: AliasDto })
aliases: AliasDto[];
/**
* The primary adress of the note
* If at least one alias is set, this is the primary alias
* If no alias is set, this is the note's ID
*/
@IsString()
@ApiProperty()
primaryAddress: string;
/**
* Title of the note
* Does not contain any markup but might be empty
* @example "Shopping List"
*/
@IsString()
@ApiProperty()
title: string;
/**
* Description of the note
* Does not contain any markup but might be empty
* @example Everything I want to buy
*/
@IsString()
@ApiProperty()
description: string;
/**
* List of tags assigned to this note
* @example "['shopping', 'personal']
*/
@IsArray()
@IsString({ each: true })
@ApiProperty({ isArray: true, type: String })
tags: string[];
@IsNumber()
@ApiProperty()
version: number;
/**
* Datestring of the last time this note was updated
* @example "2020-12-01 12:23:34"
*/
@IsDate()
@Type(() => Date)
@ApiProperty()
updatedAt: Date;
/**
* User that last edited the note
*/
// eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality
@ApiPropertyOptional()
@IsString()
@IsOptional()
updateUsername: string | null;
/**
* Counts how many times the published note has been viewed
* @example 42
*/
@IsNumber()
@ApiProperty()
viewCount: number;
/**
* Datestring of the time this note was created
* @example "2020-12-01 12:23:34"
*/
@IsDate()
@Type(() => Date)
@ApiProperty()
createdAt: Date;
/**
* List of usernames that edited the note
* @example "['john.smith', 'jane.smith']"
*/
@IsArray()
@IsString({ each: true })
@ApiProperty({ isArray: true, type: String })
editedBy: string[];
/**
* Permissions currently in effect for the note
*/
@ValidateNested()
@Type(() => NotePermissionsDto)
@ApiProperty({ type: NotePermissionsDto })
permissions: NotePermissionsDto;
}
export class NoteMetadataUpdateDto {
/**
* New title of the note
* Can not contain any markup and might be empty
* @example "Shopping List"
*/
@IsString()
@ApiProperty()
title: string;
/**
* New description of the note
* Can not contain any markup but might be empty
* @example Everything I want to buy
*/
@IsString()
@ApiProperty()
description: string;
/**
* New list of tags assigned to this note
* @example "['shopping', 'personal']
*/
@IsArray()
@IsString({ each: true })
@ApiProperty({ isArray: true, type: String })
tags: string[];
}

View file

@ -1,143 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsLowercase,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { BaseDto } from '../utils/base.dto.';
import { Username } from '../utils/username';
export class NoteUserPermissionEntryDto extends BaseDto {
/**
* Username of the User this permission applies to
*/
@Type(() => String)
@IsString()
@IsLowercase()
@ApiProperty()
username: Username;
/**
* True if the user is allowed to edit the note
* @example false
*/
@IsBoolean()
@ApiProperty()
canEdit: boolean;
}
export class NoteUserPermissionUpdateDto {
/**
* Username of the user this permission should apply to
* @example "john.smith"
*/
@Type(() => String)
@IsString()
@IsLowercase()
@ApiProperty()
username: Username;
/**
* True if the user should be allowed to edit the note
* @example false
*/
@IsBoolean()
@ApiProperty()
canEdit: boolean;
}
export class NoteGroupPermissionEntryDto {
/**
* Name of the Group this permission applies to
*/
@IsString()
@ApiProperty()
groupName: string;
/**
* True if the group members are allowed to edit the note
* @example false
*/
@IsBoolean()
@ApiProperty()
canEdit: boolean;
}
export class NoteGroupPermissionUpdateDto {
/**
* Name of the group this permission should apply to
* @example "superheroes"
*/
@IsString()
@ApiProperty()
groupName: string;
/**
* True if the group members should be allowed to edit the note
* @example false
*/
@IsBoolean()
@ApiProperty()
canEdit: boolean;
}
export class NotePermissionsDto {
/**
* Username of the User this permission applies to
*/
// nestjs-typed does not detect '| null' types as optional
// eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality
@Type(() => String)
@IsString()
@ApiPropertyOptional()
@IsOptional()
owner: string | null;
/**
* List of users the note is shared with
*/
@ValidateNested({ each: true })
@IsArray()
@Type(() => NoteUserPermissionEntryDto)
@ApiProperty({ isArray: true, type: NoteUserPermissionEntryDto })
sharedToUsers: NoteUserPermissionEntryDto[];
/**
* List of groups the note is shared with
*/
@ValidateNested({ each: true })
@IsArray()
@Type(() => NoteGroupPermissionEntryDto)
@ApiProperty({ isArray: true, type: NoteGroupPermissionEntryDto })
sharedToGroups: NoteGroupPermissionEntryDto[];
}
export class NotePermissionsUpdateDto {
/**
* List of users the note should be shared with
*/
@IsArray()
@ValidateNested({ each: true })
@Type(() => NoteUserPermissionUpdateDto)
@ApiProperty({ isArray: true, type: NoteUserPermissionUpdateDto })
sharedToUsers: NoteUserPermissionUpdateDto[];
/**
* List of groups the note should be shared with
*/
@IsArray()
@ValidateNested({ each: true })
@Type(() => NoteGroupPermissionUpdateDto)
@ApiProperty({ isArray: true, type: NoteGroupPermissionUpdateDto })
sharedToGroups: NoteGroupPermissionUpdateDto[];
}

View file

@ -1,39 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsArray, IsString, ValidateNested } from 'class-validator';
import { EditDto } from '../revisions/edit.dto';
import { BaseDto } from '../utils/base.dto.';
import { NoteMetadataDto } from './note-metadata.dto';
export class NoteDto extends BaseDto {
/**
* Markdown content of the note
* @example "# I am a heading"
*/
@IsString()
@ApiProperty()
content: string;
/**
* Metadata of the note
*/
@Type(() => NoteMetadataDto)
@ValidateNested()
@ApiProperty({ type: NoteMetadataDto })
metadata: NoteMetadataDto;
/**
* Edit information of this note
*/
@IsArray()
@ValidateNested({ each: true })
@Type(() => EditDto)
@ApiProperty({ isArray: true, type: EditDto })
editedByAtPosition: EditDto[];
}

View file

@ -1,20 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean } from 'class-validator';
import { BaseDto } from '../utils/base.dto.';
export class NoteMediaDeletionDto extends BaseDto {
/**
* Should the associated mediaUploads be keept
* @default false
* @example false
*/
@IsBoolean()
@ApiProperty()
keepMedia: boolean;
}

View file

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file)
* SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -271,6 +271,7 @@ describe('NotesService', () => {
const note = Mock.of<Note>({
revisions: Promise.resolve([revision]),
aliases: Promise.resolve([]),
createdAt: new Date(1549312452000),
});
mockRevisionService(note, revision);

View file

@ -1,8 +1,13 @@
/*
* SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file)
* SPDX-FileCopyrightText: 2025 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import {
NoteDto,
NoteMetadataDto,
NotePermissionsDto,
} from '@hedgedoc/commons';
import { Optional } from '@mrdrogdrog/optional';
import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
@ -30,9 +35,6 @@ import { User } from '../users/user.entity';
import { UsersService } from '../users/users.service';
import { Alias } from './alias.entity';
import { AliasService } from './alias.service';
import { NoteMetadataDto } from './note-metadata.dto';
import { NotePermissionsDto } from './note-permissions.dto';
import { NoteDto } from './note.dto';
import { Note } from './note.entity';
import { Tag } from './tag.entity';
import { getPrimaryAlias } from './utils';
@ -427,11 +429,11 @@ export class NotesService {
title: latestRevision.title,
description: latestRevision.description,
tags: (await latestRevision.tags).map((tag) => tag.name),
createdAt: note.createdAt,
createdAt: note.createdAt.toISOString(),
editedBy: (await this.getAuthorUsers(note)).map((user) => user.username),
permissions: await this.toNotePermissionsDto(note),
version: note.version,
updatedAt: latestRevision.createdAt,
updatedAt: latestRevision.createdAt.toISOString(),
updateUsername: updateUser ? updateUser.username : null,
viewCount: note.viewCount,
};