mirror of
https://github.com/immich-app/immich.git
synced 2024-11-28 09:33:27 +02:00
refactor(server): tags (#2589)
* refactor: tags * chore: open api * chore: unused import * feat: add/remove/get tag assets * chore: open api * chore: finish tag tests for add/remove assets
This commit is contained in:
parent
631f13cf2f
commit
656dc08406
6
mobile/openapi/.openapi-generator/FILES
generated
6
mobile/openapi/.openapi-generator/FILES
generated
@ -25,6 +25,8 @@ doc/AssetCountByTimeBucket.md
|
||||
doc/AssetCountByTimeBucketResponseDto.md
|
||||
doc/AssetCountByUserIdResponseDto.md
|
||||
doc/AssetFileUploadResponseDto.md
|
||||
doc/AssetIdsDto.md
|
||||
doc/AssetIdsResponseDto.md
|
||||
doc/AssetResponseDto.md
|
||||
doc/AssetTypeEnum.md
|
||||
doc/AuthDeviceResponseDto.md
|
||||
@ -154,6 +156,8 @@ lib/model/asset_count_by_time_bucket.dart
|
||||
lib/model/asset_count_by_time_bucket_response_dto.dart
|
||||
lib/model/asset_count_by_user_id_response_dto.dart
|
||||
lib/model/asset_file_upload_response_dto.dart
|
||||
lib/model/asset_ids_dto.dart
|
||||
lib/model/asset_ids_response_dto.dart
|
||||
lib/model/asset_response_dto.dart
|
||||
lib/model/asset_type_enum.dart
|
||||
lib/model/auth_device_response_dto.dart
|
||||
@ -252,6 +256,8 @@ test/asset_count_by_time_bucket_response_dto_test.dart
|
||||
test/asset_count_by_time_bucket_test.dart
|
||||
test/asset_count_by_user_id_response_dto_test.dart
|
||||
test/asset_file_upload_response_dto_test.dart
|
||||
test/asset_ids_dto_test.dart
|
||||
test/asset_ids_response_dto_test.dart
|
||||
test/asset_response_dto_test.dart
|
||||
test/asset_type_enum_test.dart
|
||||
test/auth_device_response_dto_test.dart
|
||||
|
BIN
mobile/openapi/README.md
generated
BIN
mobile/openapi/README.md
generated
Binary file not shown.
BIN
mobile/openapi/doc/AssetIdsDto.md
generated
Normal file
BIN
mobile/openapi/doc/AssetIdsDto.md
generated
Normal file
Binary file not shown.
BIN
mobile/openapi/doc/AssetIdsResponseDto.md
generated
Normal file
BIN
mobile/openapi/doc/AssetIdsResponseDto.md
generated
Normal file
Binary file not shown.
BIN
mobile/openapi/doc/TagApi.md
generated
BIN
mobile/openapi/doc/TagApi.md
generated
Binary file not shown.
BIN
mobile/openapi/doc/TagResponseDto.md
generated
BIN
mobile/openapi/doc/TagResponseDto.md
generated
Binary file not shown.
BIN
mobile/openapi/doc/UpdateTagDto.md
generated
BIN
mobile/openapi/doc/UpdateTagDto.md
generated
Binary file not shown.
BIN
mobile/openapi/lib/api.dart
generated
BIN
mobile/openapi/lib/api.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/api/tag_api.dart
generated
BIN
mobile/openapi/lib/api/tag_api.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/api_client.dart
generated
BIN
mobile/openapi/lib/api_client.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/asset_ids_dto.dart
generated
Normal file
BIN
mobile/openapi/lib/model/asset_ids_dto.dart
generated
Normal file
Binary file not shown.
BIN
mobile/openapi/lib/model/asset_ids_response_dto.dart
generated
Normal file
BIN
mobile/openapi/lib/model/asset_ids_response_dto.dart
generated
Normal file
Binary file not shown.
BIN
mobile/openapi/lib/model/tag_response_dto.dart
generated
BIN
mobile/openapi/lib/model/tag_response_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/update_tag_dto.dart
generated
BIN
mobile/openapi/lib/model/update_tag_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/test/asset_ids_dto_test.dart
generated
Normal file
BIN
mobile/openapi/test/asset_ids_dto_test.dart
generated
Normal file
Binary file not shown.
BIN
mobile/openapi/test/asset_ids_response_dto_test.dart
generated
Normal file
BIN
mobile/openapi/test/asset_ids_response_dto_test.dart
generated
Normal file
Binary file not shown.
BIN
mobile/openapi/test/tag_api_test.dart
generated
BIN
mobile/openapi/test/tag_api_test.dart
generated
Binary file not shown.
BIN
mobile/openapi/test/tag_response_dto_test.dart
generated
BIN
mobile/openapi/test/tag_response_dto_test.dart
generated
Binary file not shown.
BIN
mobile/openapi/test/update_tag_dto_test.dart
generated
BIN
mobile/openapi/test/update_tag_dto_test.dart
generated
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
import { SearchPropertiesDto } from './dto/search-properties.dto';
|
||||
import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto';
|
||||
import { AssetEntity, AssetType, ExifEntity } from '@app/infra/entities';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm/repository/Repository';
|
||||
import { CuratedObjectsResponseDto } from './response-dto/curated-objects-response.dto';
|
||||
@ -12,7 +12,6 @@ import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-use
|
||||
import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto';
|
||||
import { In } from 'typeorm/find-options/operator/In';
|
||||
import { UpdateAssetDto } from './dto/update-asset.dto';
|
||||
import { ITagRepository } from '../tag/tag.repository';
|
||||
import { IsNull, Not } from 'typeorm';
|
||||
import { AssetSearchDto } from './dto/asset-search.dto';
|
||||
|
||||
@ -52,10 +51,7 @@ export const IAssetRepository = 'IAssetRepository';
|
||||
@Injectable()
|
||||
export class AssetRepository implements IAssetRepository {
|
||||
constructor(
|
||||
@InjectRepository(AssetEntity)
|
||||
private assetRepository: Repository<AssetEntity>,
|
||||
|
||||
@Inject(ITagRepository) private _tagRepository: ITagRepository,
|
||||
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
|
||||
@InjectRepository(ExifEntity) private exifRepository: Repository<ExifEntity>,
|
||||
) {}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { AssetEntity, ExifEntity } from '@app/infra/entities';
|
||||
import { AssetRepository, IAssetRepository } from './asset-repository';
|
||||
import { DownloadModule } from '../../modules/download/download.module';
|
||||
import { TagModule } from '../tag/tag.module';
|
||||
import { AlbumModule } from '../album/album.module';
|
||||
|
||||
const ASSET_REPOSITORY_PROVIDER = {
|
||||
@ -18,7 +17,6 @@ const ASSET_REPOSITORY_PROVIDER = {
|
||||
//
|
||||
TypeOrmModule.forFeature([AssetEntity, ExifEntity]),
|
||||
DownloadModule,
|
||||
TagModule,
|
||||
AlbumModule,
|
||||
],
|
||||
controllers: [AssetController],
|
||||
|
@ -1,11 +0,0 @@
|
||||
import { IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class UpdateTagDto {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
name?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
renameTagId?: string;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete, ValidationPipe } from '@nestjs/common';
|
||||
import { TagService } from './tag.service';
|
||||
import { CreateTagDto } from './dto/create-tag.dto';
|
||||
import { UpdateTagDto } from './dto/update-tag.dto';
|
||||
import { Authenticated } from '../../decorators/authenticated.decorator';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
|
||||
import { mapTag, TagResponseDto } from '@app/domain';
|
||||
import { UUIDParamDto } from '../../controllers/dto/uuid-param.dto';
|
||||
|
||||
@ApiTags('Tag')
|
||||
@Controller('tag')
|
||||
@Authenticated()
|
||||
export class TagController {
|
||||
constructor(private readonly tagService: TagService) {}
|
||||
|
||||
@Post()
|
||||
create(
|
||||
@GetAuthUser() authUser: AuthUserDto,
|
||||
@Body(ValidationPipe) createTagDto: CreateTagDto,
|
||||
): Promise<TagResponseDto> {
|
||||
return this.tagService.create(authUser, createTagDto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll(@GetAuthUser() authUser: AuthUserDto): Promise<TagResponseDto[]> {
|
||||
return this.tagService.findAll(authUser);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
async findOne(@GetAuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto): Promise<TagResponseDto> {
|
||||
const tag = await this.tagService.findOne(authUser, id);
|
||||
return mapTag(tag);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
update(
|
||||
@GetAuthUser() authUser: AuthUserDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body(ValidationPipe) updateTagDto: UpdateTagDto,
|
||||
): Promise<TagResponseDto> {
|
||||
return this.tagService.update(authUser, id, updateTagDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
delete(@GetAuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.tagService.remove(authUser, id);
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TagService } from './tag.service';
|
||||
import { TagController } from './tag.controller';
|
||||
import { TagEntity } from '@app/infra/entities';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { TagRepository, ITagRepository } from './tag.repository';
|
||||
|
||||
const TAG_REPOSITORY_PROVIDER = {
|
||||
provide: ITagRepository,
|
||||
useClass: TagRepository,
|
||||
};
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([TagEntity])],
|
||||
controllers: [TagController],
|
||||
providers: [TagService, TAG_REPOSITORY_PROVIDER],
|
||||
exports: [TAG_REPOSITORY_PROVIDER],
|
||||
})
|
||||
export class TagModule {}
|
@ -1,61 +0,0 @@
|
||||
import { TagEntity, TagType } from '@app/infra/entities';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { UpdateTagDto } from './dto/update-tag.dto';
|
||||
|
||||
export interface ITagRepository {
|
||||
create(userId: string, tagType: TagType, tagName: string): Promise<TagEntity>;
|
||||
getByIds(userId: string, tagIds: string[]): Promise<TagEntity[]>;
|
||||
getById(tagId: string, userId: string): Promise<TagEntity | null>;
|
||||
getByUserId(userId: string): Promise<TagEntity[]>;
|
||||
update(tag: TagEntity, updateTagDto: UpdateTagDto): Promise<TagEntity | null>;
|
||||
remove(tag: TagEntity): Promise<TagEntity>;
|
||||
}
|
||||
|
||||
export const ITagRepository = 'ITagRepository';
|
||||
|
||||
@Injectable()
|
||||
export class TagRepository implements ITagRepository {
|
||||
constructor(
|
||||
@InjectRepository(TagEntity)
|
||||
private tagRepository: Repository<TagEntity>,
|
||||
) {}
|
||||
|
||||
async create(userId: string, tagType: TagType, tagName: string): Promise<TagEntity> {
|
||||
const tag = new TagEntity();
|
||||
tag.name = tagName;
|
||||
tag.type = tagType;
|
||||
tag.userId = userId;
|
||||
|
||||
return this.tagRepository.save(tag);
|
||||
}
|
||||
|
||||
async getById(tagId: string, userId: string): Promise<TagEntity | null> {
|
||||
return await this.tagRepository.findOne({ where: { id: tagId, userId }, relations: ['user'] });
|
||||
}
|
||||
|
||||
async getByIds(userId: string, tagIds: string[]): Promise<TagEntity[]> {
|
||||
return await this.tagRepository.find({
|
||||
where: { id: In(tagIds), userId },
|
||||
relations: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getByUserId(userId: string): Promise<TagEntity[]> {
|
||||
return await this.tagRepository.find({ where: { userId } });
|
||||
}
|
||||
|
||||
async update(tag: TagEntity, updateTagDto: UpdateTagDto): Promise<TagEntity> {
|
||||
tag.name = updateTagDto.name ?? tag.name;
|
||||
tag.renameTagId = updateTagDto.renameTagId ?? tag.renameTagId;
|
||||
|
||||
return this.tagRepository.save(tag);
|
||||
}
|
||||
|
||||
async remove(tag: TagEntity): Promise<TagEntity> {
|
||||
return await this.tagRepository.remove(tag);
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
import { TagEntity, TagType, UserEntity } from '@app/infra/entities';
|
||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||
import { ITagRepository } from './tag.repository';
|
||||
import { TagService } from './tag.service';
|
||||
|
||||
describe('TagService', () => {
|
||||
let sut: TagService;
|
||||
let tagRepositoryMock: jest.Mocked<ITagRepository>;
|
||||
|
||||
const user1AuthUser: AuthUserDto = Object.freeze({
|
||||
id: '1111',
|
||||
email: 'testuser@email.com',
|
||||
isAdmin: false,
|
||||
});
|
||||
|
||||
const user1: UserEntity = Object.freeze({
|
||||
id: '1111',
|
||||
firstName: 'Alex',
|
||||
lastName: 'Tran',
|
||||
isAdmin: true,
|
||||
email: 'testuser@email.com',
|
||||
profileImagePath: '',
|
||||
shouldChangePassword: true,
|
||||
createdAt: new Date('2022-12-02T19:29:23.603Z'),
|
||||
deletedAt: null,
|
||||
updatedAt: new Date('2022-12-02T19:29:23.603Z'),
|
||||
tags: [],
|
||||
assets: [],
|
||||
oauthId: 'oauth-id-1',
|
||||
storageLabel: null,
|
||||
});
|
||||
|
||||
// const user2: UserEntity = Object.freeze({
|
||||
// id: '2222',
|
||||
// firstName: 'Alex',
|
||||
// lastName: 'Tran',
|
||||
// isAdmin: true,
|
||||
// email: 'testuser2@email.com',
|
||||
// profileImagePath: '',
|
||||
// shouldChangePassword: true,
|
||||
// createdAt: '2022-12-02T19:29:23.603Z',
|
||||
// deletedAt: undefined,
|
||||
// tags: [],
|
||||
// oauthId: 'oauth-id-2',
|
||||
// });
|
||||
|
||||
const user1Tag1: TagEntity = Object.freeze({
|
||||
name: 'user 1 tag 1',
|
||||
type: TagType.CUSTOM,
|
||||
userId: user1.id,
|
||||
user: user1,
|
||||
renameTagId: '',
|
||||
id: 'user1-tag-1-id',
|
||||
assets: [],
|
||||
});
|
||||
|
||||
// const user1Tag2: TagEntity = Object.freeze({
|
||||
// name: 'user 1 tag 2',
|
||||
// type: TagType.CUSTOM,
|
||||
// userId: user1.id,
|
||||
// user: user1,
|
||||
// renameTagId: '',
|
||||
// id: 'user1-tag-2-id',
|
||||
// assets: [],
|
||||
// });
|
||||
|
||||
beforeAll(() => {
|
||||
tagRepositoryMock = {
|
||||
create: jest.fn(),
|
||||
getByIds: jest.fn(),
|
||||
getById: jest.fn(),
|
||||
getByUserId: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
sut = new TagService(tagRepositoryMock);
|
||||
});
|
||||
|
||||
it('creates tag', async () => {
|
||||
const createTagDto = {
|
||||
name: 'user 1 tag 1',
|
||||
type: TagType.CUSTOM,
|
||||
};
|
||||
|
||||
tagRepositoryMock.create.mockResolvedValue(user1Tag1);
|
||||
|
||||
const result = await sut.create(user1AuthUser, createTagDto);
|
||||
|
||||
expect(result.userId).toEqual(user1AuthUser.id);
|
||||
expect(result.name).toEqual(createTagDto.name);
|
||||
expect(result.type).toEqual(createTagDto.type);
|
||||
});
|
||||
});
|
@ -1,52 +0,0 @@
|
||||
import { TagEntity } from '@app/infra/entities';
|
||||
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||
import { CreateTagDto } from './dto/create-tag.dto';
|
||||
import { UpdateTagDto } from './dto/update-tag.dto';
|
||||
import { ITagRepository } from './tag.repository';
|
||||
import { mapTag, TagResponseDto } from '@app/domain';
|
||||
|
||||
@Injectable()
|
||||
export class TagService {
|
||||
readonly logger = new Logger(TagService.name);
|
||||
|
||||
constructor(@Inject(ITagRepository) private _tagRepository: ITagRepository) {}
|
||||
|
||||
async create(authUser: AuthUserDto, createTagDto: CreateTagDto) {
|
||||
try {
|
||||
const newTag = await this._tagRepository.create(authUser.id, createTagDto.type, createTagDto.name);
|
||||
return mapTag(newTag);
|
||||
} catch (e: any) {
|
||||
this.logger.error(e, e.stack);
|
||||
throw new BadRequestException(`Failed to create tag: ${e.detail}`);
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(authUser: AuthUserDto) {
|
||||
const tags = await this._tagRepository.getByUserId(authUser.id);
|
||||
return tags.map(mapTag);
|
||||
}
|
||||
|
||||
async findOne(authUser: AuthUserDto, id: string): Promise<TagEntity> {
|
||||
const tag = await this._tagRepository.getById(id, authUser.id);
|
||||
|
||||
if (!tag) {
|
||||
throw new BadRequestException('Tag not found');
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
async update(authUser: AuthUserDto, id: string, updateTagDto: UpdateTagDto): Promise<TagResponseDto> {
|
||||
const tag = await this.findOne(authUser, id);
|
||||
|
||||
await this._tagRepository.update(tag, updateTagDto);
|
||||
|
||||
return mapTag(tag);
|
||||
}
|
||||
|
||||
async remove(authUser: AuthUserDto, id: string): Promise<void> {
|
||||
const tag = await this.findOne(authUser, id);
|
||||
await this._tagRepository.remove(tag);
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ import { AssetModule } from './api-v1/asset/asset.module';
|
||||
import { AlbumModule } from './api-v1/album/album.module';
|
||||
import { AppController } from './app.controller';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { TagModule } from './api-v1/tag/tag.module';
|
||||
import { DomainModule, SearchService } from '@app/domain';
|
||||
import { InfraModule } from '@app/infra';
|
||||
import {
|
||||
@ -20,6 +19,7 @@ import {
|
||||
SharedLinkController,
|
||||
SystemConfigController,
|
||||
UserController,
|
||||
TagController,
|
||||
} from './controllers';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
import { AuthGuard } from './middlewares/auth.guard';
|
||||
@ -27,11 +27,11 @@ import { AppCronJobs } from './app.cron-jobs';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
//
|
||||
DomainModule.register({ imports: [InfraModule] }),
|
||||
AssetModule,
|
||||
AlbumModule,
|
||||
ScheduleModule.forRoot(),
|
||||
TagModule,
|
||||
],
|
||||
controllers: [
|
||||
AppController,
|
||||
@ -46,6 +46,7 @@ import { AppCronJobs } from './app.cron-jobs';
|
||||
ServerInfoController,
|
||||
SharedLinkController,
|
||||
SystemConfigController,
|
||||
TagController,
|
||||
UserController,
|
||||
PersonController,
|
||||
],
|
||||
|
@ -10,4 +10,5 @@ export * from './search.controller';
|
||||
export * from './server-info.controller';
|
||||
export * from './shared-link.controller';
|
||||
export * from './system-config.controller';
|
||||
export * from './tag.controller';
|
||||
export * from './user.controller';
|
||||
|
75
server/apps/immich/src/controllers/tag.controller.ts
Normal file
75
server/apps/immich/src/controllers/tag.controller.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import {
|
||||
AssetIdsDto,
|
||||
AssetIdsResponseDto,
|
||||
AssetResponseDto,
|
||||
CreateTagDto,
|
||||
TagResponseDto,
|
||||
TagService,
|
||||
UpdateTagDto,
|
||||
} from '@app/domain';
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Put } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthUserDto, GetAuthUser } from '../decorators/auth-user.decorator';
|
||||
import { Authenticated } from '../decorators/authenticated.decorator';
|
||||
import { UseValidation } from '../decorators/use-validation.decorator';
|
||||
import { UUIDParamDto } from './dto/uuid-param.dto';
|
||||
|
||||
@ApiTags('Tag')
|
||||
@Controller('tag')
|
||||
@Authenticated()
|
||||
@UseValidation()
|
||||
export class TagController {
|
||||
constructor(private service: TagService) {}
|
||||
|
||||
@Post()
|
||||
createTag(@GetAuthUser() authUser: AuthUserDto, @Body() dto: CreateTagDto): Promise<TagResponseDto> {
|
||||
return this.service.create(authUser, dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
getAllTags(@GetAuthUser() authUser: AuthUserDto): Promise<TagResponseDto[]> {
|
||||
return this.service.getAll(authUser);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getTagById(@GetAuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto): Promise<TagResponseDto> {
|
||||
return this.service.getById(authUser, id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
updateTag(
|
||||
@GetAuthUser() authUser: AuthUserDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: UpdateTagDto,
|
||||
): Promise<TagResponseDto> {
|
||||
return this.service.update(authUser, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
deleteTag(@GetAuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.remove(authUser, id);
|
||||
}
|
||||
|
||||
@Get(':id/assets')
|
||||
getTagAssets(@GetAuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto): Promise<AssetResponseDto[]> {
|
||||
return this.service.getAssets(authUser, id);
|
||||
}
|
||||
|
||||
@Put(':id/assets')
|
||||
tagAssets(
|
||||
@GetAuthUser() authUser: AuthUserDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: AssetIdsDto,
|
||||
): Promise<AssetIdsResponseDto[]> {
|
||||
return this.service.addAssets(authUser, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id/assets')
|
||||
untagAssets(
|
||||
@GetAuthUser() authUser: AuthUserDto,
|
||||
@Body() dto: AssetIdsDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
): Promise<AssetIdsResponseDto[]> {
|
||||
return this.service.removeAssets(authUser, id, dto);
|
||||
}
|
||||
}
|
@ -1785,6 +1785,357 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/tag": {
|
||||
"post": {
|
||||
"operationId": "createTag",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateTagDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"get": {
|
||||
"operationId": "getAllTags",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/tag/{id}": {
|
||||
"get": {
|
||||
"operationId": "getTagById",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"patch": {
|
||||
"operationId": "updateTag",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UpdateTagDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "deleteTag",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/tag/{id}/assets": {
|
||||
"get": {
|
||||
"operationId": "getTagAssets",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AssetResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"operationId": "tagAssets",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetIdsDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AssetIdsResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "untagAssets",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetIdsDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AssetIdsResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/user": {
|
||||
"get": {
|
||||
"operationId": "getAllUsers",
|
||||
@ -3598,206 +3949,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/tag": {
|
||||
"post": {
|
||||
"operationId": "create",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateTagDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"get": {
|
||||
"operationId": "findAll",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/tag/{id}": {
|
||||
"get": {
|
||||
"operationId": "findOne",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"patch": {
|
||||
"operationId": "update",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UpdateTagDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TagResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "delete",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Tag"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/album/count-by-user-id": {
|
||||
"get": {
|
||||
"operationId": "getAlbumCountByUserId",
|
||||
@ -4384,26 +4535,22 @@
|
||||
"TagResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/components/schemas/TagTypeEnum"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
"type": "string"
|
||||
},
|
||||
"renameTagId": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type",
|
||||
"id",
|
||||
"name",
|
||||
"userId"
|
||||
]
|
||||
@ -5665,6 +5812,67 @@
|
||||
"presetOptions"
|
||||
]
|
||||
},
|
||||
"CreateTagDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"$ref": "#/components/schemas/TagTypeEnum"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"UpdateTagDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"AssetIdsDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"assetIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"assetIds"
|
||||
]
|
||||
},
|
||||
"AssetIdsResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"type": "string"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"error": {
|
||||
"enum": [
|
||||
"duplicate",
|
||||
"no_permission",
|
||||
"not_found"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"assetId",
|
||||
"success"
|
||||
]
|
||||
},
|
||||
"CreateUserDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -6318,32 +6526,6 @@
|
||||
"assetIds"
|
||||
]
|
||||
},
|
||||
"CreateTagDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"$ref": "#/components/schemas/TagTypeEnum"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"UpdateTagDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"renameTagId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"AlbumCountResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
6
server/libs/domain/src/asset/dto/asset-ids.dto.ts
Normal file
6
server/libs/domain/src/asset/dto/asset-ids.dto.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { ValidateUUID } from '../../../../../apps/immich/src/decorators/validate-uuid.decorator';
|
||||
|
||||
export class AssetIdsDto {
|
||||
@ValidateUUID({ each: true })
|
||||
assetIds!: string[];
|
||||
}
|
2
server/libs/domain/src/asset/dto/index.ts
Normal file
2
server/libs/domain/src/asset/dto/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './asset-ids.dto';
|
||||
export * from './map-marker.dto';
|
@ -1,7 +1,7 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { toBoolean } from 'apps/immich/src/utils/transform.util';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsBoolean, IsDate, IsOptional } from 'class-validator';
|
||||
import { toBoolean } from '../../../../../apps/immich/src/utils/transform.util';
|
||||
|
||||
export class MapMarkerDto {
|
||||
@ApiProperty()
|
||||
|
@ -1,3 +1,4 @@
|
||||
export * from './asset.repository';
|
||||
export * from './asset.service';
|
||||
export * from './dto';
|
||||
export * from './response-dto';
|
||||
|
@ -0,0 +1,11 @@
|
||||
export enum AssetIdErrorReason {
|
||||
DUPLICATE = 'duplicate',
|
||||
NO_PERMISSION = 'no_permission',
|
||||
NOT_FOUND = 'not_found',
|
||||
}
|
||||
|
||||
export class AssetIdsResponseDto {
|
||||
assetId!: string;
|
||||
success!: boolean;
|
||||
error?: AssetIdErrorReason;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
export * from './asset-ids-response.dto';
|
||||
export * from './asset-response.dto';
|
||||
export * from './exif-response.dto';
|
||||
export * from './smart-info-response.dto';
|
||||
export * from './map-marker-response.dto';
|
||||
export * from './smart-info-response.dto';
|
||||
|
@ -17,6 +17,7 @@ import { SmartInfoService } from './smart-info';
|
||||
import { StorageService } from './storage';
|
||||
import { StorageTemplateService } from './storage-template';
|
||||
import { INITIAL_SYSTEM_CONFIG, SystemConfigService } from './system-config';
|
||||
import { TagService } from './tag';
|
||||
import { UserService } from './user';
|
||||
|
||||
const providers: Provider[] = [
|
||||
@ -38,6 +39,7 @@ const providers: Provider[] = [
|
||||
StorageService,
|
||||
StorageTemplateService,
|
||||
SystemConfigService,
|
||||
TagService,
|
||||
UserService,
|
||||
{
|
||||
provide: INITIAL_SYSTEM_CONFIG,
|
||||
|
@ -1 +1,4 @@
|
||||
export * from './response-dto';
|
||||
export * from './tag-response.dto';
|
||||
export * from './tag.dto';
|
||||
export * from './tag.repository';
|
||||
export * from './tag.service';
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './tag-response.dto';
|
@ -2,17 +2,11 @@ import { TagEntity, TagType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class TagResponseDto {
|
||||
@ApiProperty()
|
||||
id!: string;
|
||||
|
||||
@ApiProperty({ enumName: 'TagTypeEnum', enum: TagType })
|
||||
type!: string;
|
||||
|
||||
name!: string;
|
||||
|
||||
userId!: string;
|
||||
|
||||
renameTagId?: string | null;
|
||||
}
|
||||
|
||||
export function mapTag(entity: TagEntity): TagResponseDto {
|
||||
@ -21,6 +15,5 @@ export function mapTag(entity: TagEntity): TagResponseDto {
|
||||
type: entity.type,
|
||||
name: entity.name,
|
||||
userId: entity.userId,
|
||||
renameTagId: entity.renameTagId,
|
||||
};
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { TagType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
import { IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class CreateTagDto {
|
||||
@IsString()
|
||||
@ -12,3 +12,9 @@ export class CreateTagDto {
|
||||
@ApiProperty({ enumName: 'TagTypeEnum', enum: TagType })
|
||||
type!: TagType;
|
||||
}
|
||||
|
||||
export class UpdateTagDto {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
name?: string;
|
||||
}
|
16
server/libs/domain/src/tag/tag.repository.ts
Normal file
16
server/libs/domain/src/tag/tag.repository.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { AssetEntity, TagEntity } from '@app/infra/entities';
|
||||
|
||||
export const ITagRepository = 'ITagRepository';
|
||||
|
||||
export interface ITagRepository {
|
||||
getById(userId: string, tagId: string): Promise<TagEntity | null>;
|
||||
getAll(userId: string): Promise<TagEntity[]>;
|
||||
create(tag: Partial<TagEntity>): Promise<TagEntity>;
|
||||
update(tag: Partial<TagEntity>): Promise<TagEntity>;
|
||||
remove(tag: TagEntity): Promise<void>;
|
||||
hasName(userId: string, name: string): Promise<boolean>;
|
||||
hasAsset(userId: string, tagId: string, assetId: string): Promise<boolean>;
|
||||
getAssets(userId: string, tagId: string): Promise<AssetEntity[]>;
|
||||
addAssets(userId: string, tagId: string, assetIds: string[]): Promise<void>;
|
||||
removeAssets(userId: string, tagId: string, assetIds: string[]): Promise<void>;
|
||||
}
|
178
server/libs/domain/src/tag/tag.service.spec.ts
Normal file
178
server/libs/domain/src/tag/tag.service.spec.ts
Normal file
@ -0,0 +1,178 @@
|
||||
import { TagType } from '@app/infra/entities';
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { when } from 'jest-when';
|
||||
import { assetEntityStub, authStub, newTagRepositoryMock, tagResponseStub, tagStub } from '../../test';
|
||||
import { AssetIdErrorReason } from '../asset';
|
||||
import { ITagRepository } from './tag.repository';
|
||||
import { TagService } from './tag.service';
|
||||
|
||||
describe(TagService.name, () => {
|
||||
let sut: TagService;
|
||||
let tagMock: jest.Mocked<ITagRepository>;
|
||||
|
||||
beforeEach(() => {
|
||||
tagMock = newTagRepositoryMock();
|
||||
sut = new TagService(tagMock);
|
||||
});
|
||||
|
||||
it('should work', () => {
|
||||
expect(sut).toBeDefined();
|
||||
});
|
||||
|
||||
describe('getAll', () => {
|
||||
it('should return all tags for a user', async () => {
|
||||
tagMock.getAll.mockResolvedValue([tagStub.tag1]);
|
||||
await expect(sut.getAll(authStub.admin)).resolves.toEqual([tagResponseStub.tag1]);
|
||||
expect(tagMock.getAll).toHaveBeenCalledWith(authStub.admin.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getById', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
tagMock.getById.mockResolvedValue(null);
|
||||
await expect(sut.getById(authStub.admin, 'tag-1')).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
});
|
||||
|
||||
it('should return a tag for a user', async () => {
|
||||
tagMock.getById.mockResolvedValue(tagStub.tag1);
|
||||
await expect(sut.getById(authStub.admin, 'tag-1')).resolves.toEqual(tagResponseStub.tag1);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should throw an error for a duplicate tag', async () => {
|
||||
tagMock.hasName.mockResolvedValue(true);
|
||||
await expect(sut.create(authStub.admin, { name: 'tag-1', type: TagType.CUSTOM })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
expect(tagMock.hasName).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should create a new tag', async () => {
|
||||
tagMock.create.mockResolvedValue(tagStub.tag1);
|
||||
await expect(sut.create(authStub.admin, { name: 'tag-1', type: TagType.CUSTOM })).resolves.toEqual(
|
||||
tagResponseStub.tag1,
|
||||
);
|
||||
expect(tagMock.create).toHaveBeenCalledWith({
|
||||
userId: authStub.admin.id,
|
||||
name: 'tag-1',
|
||||
type: TagType.CUSTOM,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
tagMock.getById.mockResolvedValue(null);
|
||||
await expect(sut.update(authStub.admin, 'tag-1', { name: 'tag-2' })).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.remove).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update a tag', async () => {
|
||||
tagMock.getById.mockResolvedValue(tagStub.tag1);
|
||||
tagMock.update.mockResolvedValue(tagStub.tag1);
|
||||
await expect(sut.update(authStub.admin, 'tag-1', { name: 'tag-2' })).resolves.toEqual(tagResponseStub.tag1);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.update).toHaveBeenCalledWith({ id: 'tag-1', name: 'tag-2' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
tagMock.getById.mockResolvedValue(null);
|
||||
await expect(sut.remove(authStub.admin, 'tag-1')).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.remove).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should remove a tag', async () => {
|
||||
tagMock.getById.mockResolvedValue(tagStub.tag1);
|
||||
await sut.remove(authStub.admin, 'tag-1');
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.remove).toHaveBeenCalledWith(tagStub.tag1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAssets', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
tagMock.getById.mockResolvedValue(null);
|
||||
await expect(sut.remove(authStub.admin, 'tag-1')).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.remove).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should get the assets for a tag', async () => {
|
||||
tagMock.getById.mockResolvedValue(tagStub.tag1);
|
||||
tagMock.getAssets.mockResolvedValue([assetEntityStub.image]);
|
||||
await sut.getAssets(authStub.admin, 'tag-1');
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.getAssets).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('addAssets', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
tagMock.getById.mockResolvedValue(null);
|
||||
await expect(sut.addAssets(authStub.admin, 'tag-1', { assetIds: ['asset-1'] })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.addAssets).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reject duplicate asset ids and accept new ones', async () => {
|
||||
tagMock.getById.mockResolvedValue(tagStub.tag1);
|
||||
|
||||
when(tagMock.hasAsset).calledWith(authStub.admin.id, 'tag-1', 'asset-1').mockResolvedValue(true);
|
||||
when(tagMock.hasAsset).calledWith(authStub.admin.id, 'tag-1', 'asset-2').mockResolvedValue(false);
|
||||
|
||||
await expect(
|
||||
sut.addAssets(authStub.admin, 'tag-1', {
|
||||
assetIds: ['asset-1', 'asset-2'],
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{ assetId: 'asset-1', success: false, error: AssetIdErrorReason.DUPLICATE },
|
||||
{ assetId: 'asset-2', success: true },
|
||||
]);
|
||||
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.hasAsset).toHaveBeenCalledTimes(2);
|
||||
expect(tagMock.addAssets).toHaveBeenCalledWith(authStub.admin.id, 'tag-1', ['asset-2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeAssets', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
tagMock.getById.mockResolvedValue(null);
|
||||
await expect(sut.removeAssets(authStub.admin, 'tag-1', { assetIds: ['asset-1'] })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.removeAssets).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should accept accept ids that are tagged and reject the rest', async () => {
|
||||
tagMock.getById.mockResolvedValue(tagStub.tag1);
|
||||
|
||||
when(tagMock.hasAsset).calledWith(authStub.admin.id, 'tag-1', 'asset-1').mockResolvedValue(true);
|
||||
when(tagMock.hasAsset).calledWith(authStub.admin.id, 'tag-1', 'asset-2').mockResolvedValue(false);
|
||||
|
||||
await expect(
|
||||
sut.removeAssets(authStub.admin, 'tag-1', {
|
||||
assetIds: ['asset-1', 'asset-2'],
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{ assetId: 'asset-1', success: true },
|
||||
{ assetId: 'asset-2', success: false, error: AssetIdErrorReason.NOT_FOUND },
|
||||
]);
|
||||
|
||||
expect(tagMock.getById).toHaveBeenCalledWith(authStub.admin.id, 'tag-1');
|
||||
expect(tagMock.hasAsset).toHaveBeenCalledTimes(2);
|
||||
expect(tagMock.removeAssets).toHaveBeenCalledWith(authStub.admin.id, 'tag-1', ['asset-1']);
|
||||
});
|
||||
});
|
||||
});
|
104
server/libs/domain/src/tag/tag.service.ts
Normal file
104
server/libs/domain/src/tag/tag.service.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||
import { AssetIdErrorReason, AssetIdsDto, AssetIdsResponseDto, AssetResponseDto, mapAsset } from '../asset';
|
||||
import { AuthUserDto } from '../auth';
|
||||
import { mapTag, TagResponseDto } from './tag-response.dto';
|
||||
import { CreateTagDto, UpdateTagDto } from './tag.dto';
|
||||
import { ITagRepository } from './tag.repository';
|
||||
|
||||
@Injectable()
|
||||
export class TagService {
|
||||
constructor(@Inject(ITagRepository) private repository: ITagRepository) {}
|
||||
|
||||
getAll(authUser: AuthUserDto) {
|
||||
return this.repository.getAll(authUser.id).then((tags) => tags.map(mapTag));
|
||||
}
|
||||
|
||||
async getById(authUser: AuthUserDto, id: string): Promise<TagResponseDto> {
|
||||
const tag = await this.findOrFail(authUser, id);
|
||||
return mapTag(tag);
|
||||
}
|
||||
|
||||
async create(authUser: AuthUserDto, dto: CreateTagDto) {
|
||||
const duplicate = await this.repository.hasName(authUser.id, dto.name);
|
||||
if (duplicate) {
|
||||
throw new BadRequestException(`A tag with that name already exists`);
|
||||
}
|
||||
|
||||
const tag = await this.repository.create({
|
||||
userId: authUser.id,
|
||||
name: dto.name,
|
||||
type: dto.type,
|
||||
});
|
||||
|
||||
return mapTag(tag);
|
||||
}
|
||||
|
||||
async update(authUser: AuthUserDto, id: string, dto: UpdateTagDto): Promise<TagResponseDto> {
|
||||
await this.findOrFail(authUser, id);
|
||||
const tag = await this.repository.update({ id, name: dto.name });
|
||||
return mapTag(tag);
|
||||
}
|
||||
|
||||
async remove(authUser: AuthUserDto, id: string): Promise<void> {
|
||||
const tag = await this.findOrFail(authUser, id);
|
||||
await this.repository.remove(tag);
|
||||
}
|
||||
|
||||
async getAssets(authUser: AuthUserDto, id: string): Promise<AssetResponseDto[]> {
|
||||
await this.findOrFail(authUser, id);
|
||||
const assets = await this.repository.getAssets(authUser.id, id);
|
||||
return assets.map(mapAsset);
|
||||
}
|
||||
|
||||
async addAssets(authUser: AuthUserDto, id: string, dto: AssetIdsDto): Promise<AssetIdsResponseDto[]> {
|
||||
await this.findOrFail(authUser, id);
|
||||
|
||||
const results: AssetIdsResponseDto[] = [];
|
||||
for (const assetId of dto.assetIds) {
|
||||
const hasAsset = await this.repository.hasAsset(authUser.id, id, assetId);
|
||||
if (hasAsset) {
|
||||
results.push({ assetId, success: false, error: AssetIdErrorReason.DUPLICATE });
|
||||
} else {
|
||||
results.push({ assetId, success: true });
|
||||
}
|
||||
}
|
||||
|
||||
await this.repository.addAssets(
|
||||
authUser.id,
|
||||
id,
|
||||
results.filter((result) => result.success).map((result) => result.assetId),
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async removeAssets(authUser: AuthUserDto, id: string, dto: AssetIdsDto): Promise<AssetIdsResponseDto[]> {
|
||||
await this.findOrFail(authUser, id);
|
||||
|
||||
const results: AssetIdsResponseDto[] = [];
|
||||
for (const assetId of dto.assetIds) {
|
||||
const hasAsset = await this.repository.hasAsset(authUser.id, id, assetId);
|
||||
if (!hasAsset) {
|
||||
results.push({ assetId, success: false, error: AssetIdErrorReason.NOT_FOUND });
|
||||
} else {
|
||||
results.push({ assetId, success: true });
|
||||
}
|
||||
}
|
||||
|
||||
await this.repository.removeAssets(
|
||||
authUser.id,
|
||||
id,
|
||||
results.filter((result) => result.success).map((result) => result.assetId),
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private async findOrFail(authUser: AuthUserDto, id: string) {
|
||||
const tag = await this.repository.getById(authUser.id, id);
|
||||
if (!tag) {
|
||||
throw new BadRequestException('Tag not found');
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
}
|
@ -2,17 +2,19 @@ import {
|
||||
AlbumEntity,
|
||||
APIKeyEntity,
|
||||
AssetEntity,
|
||||
AssetFaceEntity,
|
||||
AssetType,
|
||||
PersonEntity,
|
||||
ExifEntity,
|
||||
PartnerEntity,
|
||||
PersonEntity,
|
||||
SharedLinkEntity,
|
||||
SharedLinkType,
|
||||
SystemConfig,
|
||||
TagEntity,
|
||||
TagType,
|
||||
TranscodePreset,
|
||||
UserEntity,
|
||||
UserTokenEntity,
|
||||
AssetFaceEntity,
|
||||
ExifEntity,
|
||||
} from '@app/infra/entities';
|
||||
import {
|
||||
AlbumResponseDto,
|
||||
@ -23,6 +25,7 @@ import {
|
||||
mapUser,
|
||||
SearchResult,
|
||||
SharedLinkResponseDto,
|
||||
TagResponseDto,
|
||||
VideoFormat,
|
||||
VideoInfo,
|
||||
VideoStreamInfo,
|
||||
@ -988,3 +991,24 @@ export const faceStub = {
|
||||
embedding: [1, 2, 3, 4],
|
||||
}),
|
||||
};
|
||||
|
||||
export const tagStub = {
|
||||
tag1: Object.freeze<TagEntity>({
|
||||
id: 'tag-1',
|
||||
name: 'Tag1',
|
||||
type: TagType.CUSTOM,
|
||||
userId: userEntityStub.admin.id,
|
||||
user: userEntityStub.admin,
|
||||
renameTagId: null,
|
||||
assets: [],
|
||||
}),
|
||||
};
|
||||
|
||||
export const tagResponseStub = {
|
||||
tag1: Object.freeze<TagResponseDto>({
|
||||
id: 'tag-1',
|
||||
name: 'Tag1',
|
||||
type: 'CUSTOM',
|
||||
userId: 'admin_id',
|
||||
}),
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ export * from './shared-link.repository.mock';
|
||||
export * from './smart-info.repository.mock';
|
||||
export * from './storage.repository.mock';
|
||||
export * from './system-config.repository.mock';
|
||||
export * from './tag.repository.mock';
|
||||
export * from './user-token.repository.mock';
|
||||
export * from './user.repository.mock';
|
||||
|
||||
|
16
server/libs/domain/test/tag.repository.mock.ts
Normal file
16
server/libs/domain/test/tag.repository.mock.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ITagRepository } from '../src';
|
||||
|
||||
export const newTagRepositoryMock = (): jest.Mocked<ITagRepository> => {
|
||||
return {
|
||||
getAll: jest.fn(),
|
||||
getById: jest.fn(),
|
||||
create: jest.fn(),
|
||||
update: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
hasAsset: jest.fn(),
|
||||
hasName: jest.fn(),
|
||||
getAssets: jest.fn(),
|
||||
addAssets: jest.fn(),
|
||||
removeAssets: jest.fn(),
|
||||
};
|
||||
};
|
@ -7,6 +7,7 @@ import { PersonEntity } from './person.entity';
|
||||
import { SharedLinkEntity } from './shared-link.entity';
|
||||
import { SmartInfoEntity } from './smart-info.entity';
|
||||
import { SystemConfigEntity } from './system-config.entity';
|
||||
import { TagEntity } from './tag.entity';
|
||||
import { UserTokenEntity } from './user-token.entity';
|
||||
import { UserEntity } from './user.entity';
|
||||
|
||||
@ -34,6 +35,7 @@ export const databaseEntities = [
|
||||
SharedLinkEntity,
|
||||
SmartInfoEntity,
|
||||
SystemConfigEntity,
|
||||
TagEntity,
|
||||
UserEntity,
|
||||
UserTokenEntity,
|
||||
];
|
||||
|
@ -21,7 +21,7 @@ export class TagEntity {
|
||||
userId!: string;
|
||||
|
||||
@Column({ type: 'uuid', comment: 'The new renamed tagId', nullable: true })
|
||||
renameTagId!: string;
|
||||
renameTagId!: string | null;
|
||||
|
||||
@ManyToMany(() => AssetEntity, (asset) => asset.tags)
|
||||
assets!: AssetEntity[];
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
ISmartInfoRepository,
|
||||
IStorageRepository,
|
||||
ISystemConfigRepository,
|
||||
ITagRepository,
|
||||
IUserRepository,
|
||||
IUserTokenRepository,
|
||||
} from '@app/domain';
|
||||
@ -45,6 +46,7 @@ import {
|
||||
SharedLinkRepository,
|
||||
SmartInfoRepository,
|
||||
SystemConfigRepository,
|
||||
TagRepository,
|
||||
TypesenseRepository,
|
||||
UserRepository,
|
||||
UserTokenRepository,
|
||||
@ -68,6 +70,7 @@ const providers: Provider[] = [
|
||||
{ provide: ISmartInfoRepository, useClass: SmartInfoRepository },
|
||||
{ provide: IStorageRepository, useClass: FilesystemProvider },
|
||||
{ provide: ISystemConfigRepository, useClass: SystemConfigRepository },
|
||||
{ provide: ITagRepository, useClass: TagRepository },
|
||||
{ provide: IUserRepository, useClass: UserRepository },
|
||||
{ provide: IUserTokenRepository, useClass: UserTokenRepository },
|
||||
];
|
||||
|
@ -14,6 +14,7 @@ export * from './person.repository';
|
||||
export * from './shared-link.repository';
|
||||
export * from './smart-info.repository';
|
||||
export * from './system-config.repository';
|
||||
export * from './tag.repository';
|
||||
export * from './typesense.repository';
|
||||
export * from './user-token.repository';
|
||||
export * from './user.repository';
|
||||
|
123
server/libs/infra/src/repositories/tag.repository.ts
Normal file
123
server/libs/infra/src/repositories/tag.repository.ts
Normal file
@ -0,0 +1,123 @@
|
||||
import { ITagRepository } from '@app/domain';
|
||||
import { AssetEntity, TagEntity } from '@app/infra/entities';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class TagRepository implements ITagRepository {
|
||||
constructor(
|
||||
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
|
||||
@InjectRepository(TagEntity) private repository: Repository<TagEntity>,
|
||||
) {}
|
||||
|
||||
getById(userId: string, id: string): Promise<TagEntity | null> {
|
||||
return this.repository.findOne({
|
||||
where: {
|
||||
id,
|
||||
userId,
|
||||
},
|
||||
relations: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getAll(userId: string): Promise<TagEntity[]> {
|
||||
return this.repository.find({ where: { userId } });
|
||||
}
|
||||
|
||||
create(tag: Partial<TagEntity>): Promise<TagEntity> {
|
||||
return this.save(tag);
|
||||
}
|
||||
|
||||
update(tag: Partial<TagEntity>): Promise<TagEntity> {
|
||||
return this.save(tag);
|
||||
}
|
||||
|
||||
async remove(tag: TagEntity): Promise<void> {
|
||||
await this.repository.remove(tag);
|
||||
}
|
||||
|
||||
async getAssets(userId: string, tagId: string): Promise<AssetEntity[]> {
|
||||
return this.assetRepository.find({
|
||||
where: {
|
||||
tags: {
|
||||
userId,
|
||||
id: tagId,
|
||||
},
|
||||
},
|
||||
relations: {
|
||||
exifInfo: true,
|
||||
tags: true,
|
||||
faces: {
|
||||
person: true,
|
||||
},
|
||||
},
|
||||
order: {
|
||||
createdAt: 'ASC',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async addAssets(userId: string, id: string, assetIds: string[]): Promise<void> {
|
||||
for (const assetId of assetIds) {
|
||||
const asset = await this.assetRepository.findOneOrFail({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
id: assetId,
|
||||
},
|
||||
relations: {
|
||||
tags: true,
|
||||
},
|
||||
});
|
||||
asset.tags.push({ id } as TagEntity);
|
||||
await this.assetRepository.save(asset);
|
||||
}
|
||||
}
|
||||
|
||||
async removeAssets(userId: string, id: string, assetIds: string[]): Promise<void> {
|
||||
for (const assetId of assetIds) {
|
||||
const asset = await this.assetRepository.findOneOrFail({
|
||||
where: {
|
||||
ownerId: userId,
|
||||
id: assetId,
|
||||
},
|
||||
relations: {
|
||||
tags: true,
|
||||
},
|
||||
});
|
||||
asset.tags = asset.tags.filter((tag) => tag.id !== id);
|
||||
await this.assetRepository.save(asset);
|
||||
}
|
||||
}
|
||||
|
||||
hasAsset(userId: string, tagId: string, assetId: string): Promise<boolean> {
|
||||
return this.repository.exist({
|
||||
where: {
|
||||
id: tagId,
|
||||
userId,
|
||||
assets: {
|
||||
id: assetId,
|
||||
},
|
||||
},
|
||||
relations: {
|
||||
assets: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
hasName(userId: string, name: string): Promise<boolean> {
|
||||
return this.repository.exist({
|
||||
where: {
|
||||
name,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async save(tag: Partial<TagEntity>): Promise<TagEntity> {
|
||||
const { id } = await this.repository.save(tag);
|
||||
return this.repository.findOneOrFail({ where: { id }, relations: { user: true } });
|
||||
}
|
||||
}
|
637
web/src/api/open-api/api.ts
generated
637
web/src/api/open-api/api.ts
generated
@ -536,6 +536,53 @@ export interface AssetFileUploadResponseDto {
|
||||
*/
|
||||
'duplicate': boolean;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetIdsDto
|
||||
*/
|
||||
export interface AssetIdsDto {
|
||||
/**
|
||||
*
|
||||
* @type {Array<string>}
|
||||
* @memberof AssetIdsDto
|
||||
*/
|
||||
'assetIds': Array<string>;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetIdsResponseDto
|
||||
*/
|
||||
export interface AssetIdsResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetIdsResponseDto
|
||||
*/
|
||||
'assetId': string;
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof AssetIdsResponseDto
|
||||
*/
|
||||
'success': boolean;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetIdsResponseDto
|
||||
*/
|
||||
'error'?: AssetIdsResponseDtoErrorEnum;
|
||||
}
|
||||
|
||||
export const AssetIdsResponseDtoErrorEnum = {
|
||||
Duplicate: 'duplicate',
|
||||
NoPermission: 'no_permission',
|
||||
NotFound: 'not_found'
|
||||
} as const;
|
||||
|
||||
export type AssetIdsResponseDtoErrorEnum = typeof AssetIdsResponseDtoErrorEnum[keyof typeof AssetIdsResponseDtoErrorEnum];
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
@ -2420,18 +2467,18 @@ export interface SystemConfigTemplateStorageOptionDto {
|
||||
* @interface TagResponseDto
|
||||
*/
|
||||
export interface TagResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagResponseDto
|
||||
*/
|
||||
'id': string;
|
||||
/**
|
||||
*
|
||||
* @type {TagTypeEnum}
|
||||
* @memberof TagResponseDto
|
||||
*/
|
||||
'type': TagTypeEnum;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagResponseDto
|
||||
*/
|
||||
'id': string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
@ -2444,12 +2491,6 @@ export interface TagResponseDto {
|
||||
* @memberof TagResponseDto
|
||||
*/
|
||||
'userId': string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagResponseDto
|
||||
*/
|
||||
'renameTagId'?: string | null;
|
||||
}
|
||||
|
||||
|
||||
@ -2558,12 +2599,6 @@ export interface UpdateTagDto {
|
||||
* @memberof UpdateTagDto
|
||||
*/
|
||||
'name'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UpdateTagDto
|
||||
*/
|
||||
'renameTagId'?: string;
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -10647,57 +10682,15 @@ export class SystemConfigApi extends BaseAPI {
|
||||
*/
|
||||
export const TagApiAxiosParamCreator = function (configuration?: Configuration) {
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
_delete: async (id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('_delete', 'id', id)
|
||||
const localVarPath = `/tag/{id}`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {CreateTagDto} createTagDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
create: async (createTagDto: CreateTagDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
createTag: async (createTagDto: CreateTagDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'createTagDto' is not null or undefined
|
||||
assertParamExists('create', 'createTagDto', createTagDto)
|
||||
assertParamExists('createTag', 'createTagDto', createTagDto)
|
||||
const localVarPath = `/tag`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
@ -10735,10 +10728,52 @@ export const TagApiAxiosParamCreator = function (configuration?: Configuration)
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
findAll: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
deleteTag: async (id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('deleteTag', 'id', id)
|
||||
const localVarPath = `/tag/{id}`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAllTags: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/tag`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
@ -10777,9 +10812,51 @@ export const TagApiAxiosParamCreator = function (configuration?: Configuration)
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
findOne: async (id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
getTagAssets: async (id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('findOne', 'id', id)
|
||||
assertParamExists('getTagAssets', 'id', id)
|
||||
const localVarPath = `/tag/{id}/assets`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getTagById: async (id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('getTagById', 'id', id)
|
||||
const localVarPath = `/tag/{id}`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
@ -10813,6 +10890,102 @@ export const TagApiAxiosParamCreator = function (configuration?: Configuration)
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {AssetIdsDto} assetIdsDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
tagAssets: async (id: string, assetIdsDto: AssetIdsDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('tagAssets', 'id', id)
|
||||
// verify required parameter 'assetIdsDto' is not null or undefined
|
||||
assertParamExists('tagAssets', 'assetIdsDto', assetIdsDto)
|
||||
const localVarPath = `/tag/{id}/assets`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(assetIdsDto, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {AssetIdsDto} assetIdsDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
untagAssets: async (id: string, assetIdsDto: AssetIdsDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('untagAssets', 'id', id)
|
||||
// verify required parameter 'assetIdsDto' is not null or undefined
|
||||
assertParamExists('untagAssets', 'assetIdsDto', assetIdsDto)
|
||||
const localVarPath = `/tag/{id}/assets`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(assetIdsDto, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
@ -10820,11 +10993,11 @@ export const TagApiAxiosParamCreator = function (configuration?: Configuration)
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
update: async (id: string, updateTagDto: UpdateTagDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
updateTag: async (id: string, updateTagDto: UpdateTagDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('update', 'id', id)
|
||||
assertParamExists('updateTag', 'id', id)
|
||||
// verify required parameter 'updateTagDto' is not null or undefined
|
||||
assertParamExists('update', 'updateTagDto', updateTagDto)
|
||||
assertParamExists('updateTag', 'updateTagDto', updateTagDto)
|
||||
const localVarPath = `/tag/{id}`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
@ -10871,33 +11044,14 @@ export const TagApiAxiosParamCreator = function (configuration?: Configuration)
|
||||
export const TagApiFp = function(configuration?: Configuration) {
|
||||
const localVarAxiosParamCreator = TagApiAxiosParamCreator(configuration)
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async _delete(id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator._delete(id, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {CreateTagDto} createTagDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async create(createTagDto: CreateTagDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<TagResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.create(createTagDto, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async findAll(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<TagResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.findAll(options);
|
||||
async createTag(createTagDto: CreateTagDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<TagResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.createTag(createTagDto, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
@ -10906,8 +11060,59 @@ export const TagApiFp = function(configuration?: Configuration) {
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async findOne(id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<TagResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.findOne(id, options);
|
||||
async deleteTag(id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.deleteTag(id, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getAllTags(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<TagResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAllTags(options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getTagAssets(id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getTagAssets(id, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getTagById(id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<TagResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getTagById(id, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {AssetIdsDto} assetIdsDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async tagAssets(id: string, assetIdsDto: AssetIdsDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetIdsResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.tagAssets(id, assetIdsDto, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {AssetIdsDto} assetIdsDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async untagAssets(id: string, assetIdsDto: AssetIdsDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetIdsResponseDto>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.untagAssets(id, assetIdsDto, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
@ -10917,8 +11122,8 @@ export const TagApiFp = function(configuration?: Configuration) {
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async update(id: string, updateTagDto: UpdateTagDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<TagResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.update(id, updateTagDto, options);
|
||||
async updateTag(id: string, updateTagDto: UpdateTagDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<TagResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.updateTag(id, updateTagDto, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
}
|
||||
@ -10931,31 +11136,14 @@ export const TagApiFp = function(configuration?: Configuration) {
|
||||
export const TagApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
|
||||
const localVarFp = TagApiFp(configuration)
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
_delete(id: string, options?: any): AxiosPromise<void> {
|
||||
return localVarFp._delete(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {CreateTagDto} createTagDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
create(createTagDto: CreateTagDto, options?: any): AxiosPromise<TagResponseDto> {
|
||||
return localVarFp.create(createTagDto, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
findAll(options?: any): AxiosPromise<Array<TagResponseDto>> {
|
||||
return localVarFp.findAll(options).then((request) => request(axios, basePath));
|
||||
createTag(createTagDto: CreateTagDto, options?: any): AxiosPromise<TagResponseDto> {
|
||||
return localVarFp.createTag(createTagDto, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
@ -10963,8 +11151,54 @@ export const TagApiFactory = function (configuration?: Configuration, basePath?:
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
findOne(id: string, options?: any): AxiosPromise<TagResponseDto> {
|
||||
return localVarFp.findOne(id, options).then((request) => request(axios, basePath));
|
||||
deleteTag(id: string, options?: any): AxiosPromise<void> {
|
||||
return localVarFp.deleteTag(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAllTags(options?: any): AxiosPromise<Array<TagResponseDto>> {
|
||||
return localVarFp.getAllTags(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getTagAssets(id: string, options?: any): AxiosPromise<Array<AssetResponseDto>> {
|
||||
return localVarFp.getTagAssets(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getTagById(id: string, options?: any): AxiosPromise<TagResponseDto> {
|
||||
return localVarFp.getTagById(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {AssetIdsDto} assetIdsDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
tagAssets(id: string, assetIdsDto: AssetIdsDto, options?: any): AxiosPromise<Array<AssetIdsResponseDto>> {
|
||||
return localVarFp.tagAssets(id, assetIdsDto, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {AssetIdsDto} assetIdsDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
untagAssets(id: string, assetIdsDto: AssetIdsDto, options?: any): AxiosPromise<Array<AssetIdsResponseDto>> {
|
||||
return localVarFp.untagAssets(id, assetIdsDto, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
@ -10973,71 +11207,127 @@ export const TagApiFactory = function (configuration?: Configuration, basePath?:
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
update(id: string, updateTagDto: UpdateTagDto, options?: any): AxiosPromise<TagResponseDto> {
|
||||
return localVarFp.update(id, updateTagDto, options).then((request) => request(axios, basePath));
|
||||
updateTag(id: string, updateTagDto: UpdateTagDto, options?: any): AxiosPromise<TagResponseDto> {
|
||||
return localVarFp.updateTag(id, updateTagDto, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Request parameters for _delete operation in TagApi.
|
||||
* Request parameters for createTag operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiDeleteRequest
|
||||
* @interface TagApiCreateTagRequest
|
||||
*/
|
||||
export interface TagApiDeleteRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiDelete
|
||||
*/
|
||||
readonly id: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for create operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiCreateRequest
|
||||
*/
|
||||
export interface TagApiCreateRequest {
|
||||
export interface TagApiCreateTagRequest {
|
||||
/**
|
||||
*
|
||||
* @type {CreateTagDto}
|
||||
* @memberof TagApiCreate
|
||||
* @memberof TagApiCreateTag
|
||||
*/
|
||||
readonly createTagDto: CreateTagDto
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for findOne operation in TagApi.
|
||||
* Request parameters for deleteTag operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiFindOneRequest
|
||||
* @interface TagApiDeleteTagRequest
|
||||
*/
|
||||
export interface TagApiFindOneRequest {
|
||||
export interface TagApiDeleteTagRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiFindOne
|
||||
* @memberof TagApiDeleteTag
|
||||
*/
|
||||
readonly id: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for update operation in TagApi.
|
||||
* Request parameters for getTagAssets operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiUpdateRequest
|
||||
* @interface TagApiGetTagAssetsRequest
|
||||
*/
|
||||
export interface TagApiUpdateRequest {
|
||||
export interface TagApiGetTagAssetsRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiUpdate
|
||||
* @memberof TagApiGetTagAssets
|
||||
*/
|
||||
readonly id: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for getTagById operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiGetTagByIdRequest
|
||||
*/
|
||||
export interface TagApiGetTagByIdRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiGetTagById
|
||||
*/
|
||||
readonly id: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for tagAssets operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiTagAssetsRequest
|
||||
*/
|
||||
export interface TagApiTagAssetsRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiTagAssets
|
||||
*/
|
||||
readonly id: string
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {AssetIdsDto}
|
||||
* @memberof TagApiTagAssets
|
||||
*/
|
||||
readonly assetIdsDto: AssetIdsDto
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for untagAssets operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiUntagAssetsRequest
|
||||
*/
|
||||
export interface TagApiUntagAssetsRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiUntagAssets
|
||||
*/
|
||||
readonly id: string
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {AssetIdsDto}
|
||||
* @memberof TagApiUntagAssets
|
||||
*/
|
||||
readonly assetIdsDto: AssetIdsDto
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for updateTag operation in TagApi.
|
||||
* @export
|
||||
* @interface TagApiUpdateTagRequest
|
||||
*/
|
||||
export interface TagApiUpdateTagRequest {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof TagApiUpdateTag
|
||||
*/
|
||||
readonly id: string
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {UpdateTagDto}
|
||||
* @memberof TagApiUpdate
|
||||
* @memberof TagApiUpdateTag
|
||||
*/
|
||||
readonly updateTagDto: UpdateTagDto
|
||||
}
|
||||
@ -11051,24 +11341,24 @@ export interface TagApiUpdateRequest {
|
||||
export class TagApi extends BaseAPI {
|
||||
/**
|
||||
*
|
||||
* @param {TagApiDeleteRequest} requestParameters Request parameters.
|
||||
* @param {TagApiCreateTagRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public _delete(requestParameters: TagApiDeleteRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration)._delete(requestParameters.id, options).then((request) => request(this.axios, this.basePath));
|
||||
public createTag(requestParameters: TagApiCreateTagRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).createTag(requestParameters.createTagDto, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TagApiCreateRequest} requestParameters Request parameters.
|
||||
* @param {TagApiDeleteTagRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public create(requestParameters: TagApiCreateRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).create(requestParameters.createTagDto, options).then((request) => request(this.axios, this.basePath));
|
||||
public deleteTag(requestParameters: TagApiDeleteTagRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).deleteTag(requestParameters.id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -11077,30 +11367,63 @@ export class TagApi extends BaseAPI {
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public findAll(options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).findAll(options).then((request) => request(this.axios, this.basePath));
|
||||
public getAllTags(options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).getAllTags(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TagApiFindOneRequest} requestParameters Request parameters.
|
||||
* @param {TagApiGetTagAssetsRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public findOne(requestParameters: TagApiFindOneRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).findOne(requestParameters.id, options).then((request) => request(this.axios, this.basePath));
|
||||
public getTagAssets(requestParameters: TagApiGetTagAssetsRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).getTagAssets(requestParameters.id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TagApiUpdateRequest} requestParameters Request parameters.
|
||||
* @param {TagApiGetTagByIdRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public update(requestParameters: TagApiUpdateRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).update(requestParameters.id, requestParameters.updateTagDto, options).then((request) => request(this.axios, this.basePath));
|
||||
public getTagById(requestParameters: TagApiGetTagByIdRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).getTagById(requestParameters.id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TagApiTagAssetsRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public tagAssets(requestParameters: TagApiTagAssetsRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).tagAssets(requestParameters.id, requestParameters.assetIdsDto, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TagApiUntagAssetsRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public untagAssets(requestParameters: TagApiUntagAssetsRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).untagAssets(requestParameters.id, requestParameters.assetIdsDto, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TagApiUpdateTagRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof TagApi
|
||||
*/
|
||||
public updateTag(requestParameters: TagApiUpdateTagRequest, options?: AxiosRequestConfig) {
|
||||
return TagApiFp(this.configuration).updateTag(requestParameters.id, requestParameters.updateTagDto, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user