From 7f236c5b182936cab66d126a28e3dabc0cbb14b4 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 8 Jul 2022 21:26:50 -0500 Subject: [PATCH] Add OpenAPI Specs and Response DTOs (#320) * Added swagger bearer auth method authentication accordingly * Update Auth endpoint * Added additional api information for authentication * Added Swagger CLI pluggin * Added DTO for /user endpoint * Added /device-info reponse DTOs * Implement server version * Added DTOs for /server-info * Added DTOs for /assets * Added album to Swagger group * Added generated specs file * Add Client API generator for web * Remove incorrectly placed node_modules * Created class to handle access token * Remove password and hash when getting all user * PR feedback * Fixed video from CLI doesn't get metadata extracted * Fixed issue with TSConfig to work with generated openAPI * PR feedback * Remove console.log --- .../src/api-v1/album/album.controller.ts | 9 +- .../album/response-dto/album-response.dto.ts | 18 +- .../src/api-v1/asset/asset.controller.ts | 39 +- .../immich/src/api-v1/asset/asset.service.ts | 72 +- .../src/api-v1/asset/dto/delete-asset.dto.ts | 11 + .../src/api-v1/asset/dto/serve-file.dto.ts | 5 +- .../asset/response-dto/asset-response.dto.ts | 30 +- .../curated-locations-response.dto.ts | 7 + .../curated-objects-response.dto.ts | 7 + .../asset/response-dto/exif-response.dto.ts | 42 +- .../response-dto/smart-info-response.dto.ts | 8 +- .../immich/src/api-v1/auth/auth.controller.ts | 26 +- .../immich/src/api-v1/auth/auth.service.ts | 21 +- .../api-v1/auth/dto/login-credential.dto.ts | 3 + .../immich/src/api-v1/auth/dto/sign-up.dto.ts | 5 + .../response-dto/admin-signup-response.dto.ts | 19 + .../auth/response-dto/login-response.dto.ts | 41 + .../validate-asset-token-response.dto,.ts | 7 + .../device-info/device-info.controller.ts | 16 +- .../api-v1/device-info/device-info.service.ts | 27 +- .../create-device-info-response.dto.ts | 23 + .../server-info-response.dto.ts} | 3 +- .../response-dto/server-ping-response.dto.ts | 10 + .../server-version-response.dto.ts | 8 + .../server-info/server-info.controller.ts | 24 +- .../api-v1/server-info/server-info.service.ts | 4 +- .../user/dto/create-profile-image.dto.ts | 6 + .../src/api-v1/user/dto/create-user.dto.ts | 17 +- .../src/api-v1/user/dto/update-user.dto.ts | 26 +- .../create-profile-image-response.dto.ts | 11 + .../response-dto/user-count-response.dto.ts | 10 + .../user/response-dto/user-response.dto.ts | 20 +- .../immich/src/api-v1/user/user.controller.ts | 41 +- .../immich/src/api-v1/user/user.service.ts | 51 +- .../src/constants/server_version.constant.ts | 9 +- server/apps/immich/src/main.ts | 35 + .../background-task.processor.ts | 3 +- .../background-task.service.ts | 3 +- .../processors/asset-uploaded.processor.ts | 2 +- server/immich-openapi-specs.json | 1 + server/nest-cli.json | 11 +- server/openapitools.json | 7 + server/package-lock.json | 594 ++- server/package.json | 8 +- web/.eslintrc.cjs | 8 +- web/src/lib/immich-api/index.ts | 34 + web/src/lib/open-api/.gitignore | 4 + web/src/lib/open-api/.npmignore | 1 + .../lib/open-api/.openapi-generator-ignore | 23 + web/src/lib/open-api/.openapi-generator/FILES | 9 + .../lib/open-api/.openapi-generator/VERSION | 1 + web/src/lib/open-api/api.ts | 3874 +++++++++++++++++ web/src/lib/open-api/base.ts | 74 + web/src/lib/open-api/common.ts | 138 + web/src/lib/open-api/configuration.ts | 101 + web/src/lib/open-api/git_push.sh | 57 + web/src/lib/open-api/index.ts | 18 + web/src/routes/photos/index.svelte | 17 +- web/tsconfig.json | 4 +- 59 files changed, 5477 insertions(+), 226 deletions(-) create mode 100644 server/apps/immich/src/api-v1/asset/response-dto/curated-locations-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/asset/response-dto/curated-objects-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/auth/response-dto/admin-signup-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts create mode 100644 server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts rename server/apps/immich/src/api-v1/server-info/{dto/server-info.dto.ts => response-dto/server-info-response.dto.ts} (62%) create mode 100644 server/apps/immich/src/api-v1/server-info/response-dto/server-ping-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts create mode 100644 server/apps/immich/src/api-v1/user/response-dto/create-profile-image-response.dto.ts create mode 100644 server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts create mode 100644 server/immich-openapi-specs.json create mode 100644 server/openapitools.json create mode 100644 web/src/lib/immich-api/index.ts create mode 100644 web/src/lib/open-api/.gitignore create mode 100644 web/src/lib/open-api/.npmignore create mode 100644 web/src/lib/open-api/.openapi-generator-ignore create mode 100644 web/src/lib/open-api/.openapi-generator/FILES create mode 100644 web/src/lib/open-api/.openapi-generator/VERSION create mode 100644 web/src/lib/open-api/api.ts create mode 100644 web/src/lib/open-api/base.ts create mode 100644 web/src/lib/open-api/common.ts create mode 100644 web/src/lib/open-api/configuration.ts create mode 100644 web/src/lib/open-api/git_push.sh create mode 100644 web/src/lib/open-api/index.ts diff --git a/server/apps/immich/src/api-v1/album/album.controller.ts b/server/apps/immich/src/api-v1/album/album.controller.ts index 9eeb42080f..3762d05132 100644 --- a/server/apps/immich/src/api-v1/album/album.controller.ts +++ b/server/apps/immich/src/api-v1/album/album.controller.ts @@ -22,20 +22,23 @@ import { AddUsersDto } from './dto/add-users.dto'; import { RemoveAssetsDto } from './dto/remove-assets.dto'; import { UpdateAlbumDto } from './dto/update-album.dto'; import { GetAlbumsDto } from './dto/get-albums.dto'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; // TODO might be worth creating a AlbumParamsDto that validates `albumId` instead of using the pipe. @UseGuards(JwtAuthGuard) +@ApiBearerAuth() +@ApiTags('Album') @Controller('album') export class AlbumController { constructor(private readonly albumService: AlbumService) {} @Post() - async create(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) createAlbumDto: CreateAlbumDto) { + async createAlbum(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) createAlbumDto: CreateAlbumDto) { return this.albumService.create(authUser, createAlbumDto); } @Put('/:albumId/users') - async addUsers( + async addUsersToAlbum( @GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) addUsersDto: AddUsersDto, @Param('albumId', new ParseUUIDPipe({ version: '4' })) albumId: string, @@ -44,7 +47,7 @@ export class AlbumController { } @Put('/:albumId/assets') - async addAssets( + async addAssetsToAlbum( @GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) addAssetsDto: AddAssetsDto, @Param('albumId', new ParseUUIDPipe({ version: '4' })) albumId: string, diff --git a/server/apps/immich/src/api-v1/album/response-dto/album-response.dto.ts b/server/apps/immich/src/api-v1/album/response-dto/album-response.dto.ts index 0a2ec33e72..11eb60baa6 100644 --- a/server/apps/immich/src/api-v1/album/response-dto/album-response.dto.ts +++ b/server/apps/immich/src/api-v1/album/response-dto/album-response.dto.ts @@ -2,15 +2,15 @@ import { AlbumEntity } from '../../../../../../libs/database/src/entities/album. import { UserResponseDto, mapUser } from '../../user/response-dto/user-response.dto'; import { AssetResponseDto, mapAsset } from '../../asset/response-dto/asset-response.dto'; -export interface AlbumResponseDto { - id: string; - ownerId: string; - albumName: string; - createdAt: string; - albumThumbnailAssetId: string | null; - shared: boolean; - sharedUsers: UserResponseDto[]; - assets: AssetResponseDto[]; +export class AlbumResponseDto { + id!: string; + ownerId!: string; + albumName!: string; + createdAt!: string; + albumThumbnailAssetId!: string | null; + shared!: boolean; + sharedUsers!: UserResponseDto[]; + assets!: AssetResponseDto[]; } export function mapAlbum(entity: AlbumEntity): AlbumResponseDto { diff --git a/server/apps/immich/src/api-v1/asset/asset.controller.ts b/server/apps/immich/src/api-v1/asset/asset.controller.ts index 8814fc1a37..910d3df29a 100644 --- a/server/apps/immich/src/api-v1/asset/asset.controller.ts +++ b/server/apps/immich/src/api-v1/asset/asset.controller.ts @@ -36,8 +36,14 @@ import { IAssetUploadedJob } from '@app/job/index'; import { assetUploadedQueueName } from '@app/job/constants/queue-name.constant'; import { assetUploadedProcessorName } from '@app/job/constants/job-name.constant'; import { CheckDuplicateAssetDto } from './dto/check-duplicate-asset.dto'; +import { ApiBearerAuth, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { CuratedObjectsResponseDto } from './response-dto/curated-objects-response.dto'; +import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto'; +import { AssetResponseDto } from './response-dto/asset-response.dto'; @UseGuards(JwtAuthGuard) +@ApiBearerAuth() +@ApiTags('Asset') @Controller('asset') export class AssetController { constructor( @@ -89,7 +95,7 @@ export class AssetController { @GetAuthUser() authUser: AuthUserDto, @Response({ passthrough: true }) res: Res, @Query(ValidationPipe) query: ServeFileDto, - ) { + ): Promise { return this.assetService.downloadFile(query, res); } @@ -109,43 +115,58 @@ export class AssetController { } @Get('/allObjects') - async getCuratedObject(@GetAuthUser() authUser: AuthUserDto) { + async getCuratedObjects(@GetAuthUser() authUser: AuthUserDto): Promise { return this.assetService.getCuratedObject(authUser); } @Get('/allLocation') - async getCuratedLocation(@GetAuthUser() authUser: AuthUserDto) { + async getCuratedLocations(@GetAuthUser() authUser: AuthUserDto): Promise { return this.assetService.getCuratedLocation(authUser); } @Get('/searchTerm') - async getAssetSearchTerm(@GetAuthUser() authUser: AuthUserDto) { + async getAssetSearchTerms(@GetAuthUser() authUser: AuthUserDto): Promise { return this.assetService.getAssetSearchTerm(authUser); } @Post('/search') - async searchAsset(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) searchAssetDto: SearchAssetDto) { + async searchAsset( + @GetAuthUser() authUser: AuthUserDto, + @Body(ValidationPipe) searchAssetDto: SearchAssetDto, + ): Promise { return this.assetService.searchAsset(authUser, searchAssetDto); } + /** + * Get all AssetEntity belong to the user + */ @Get('/') - async getAllAssets(@GetAuthUser() authUser: AuthUserDto) { + async getAllAssets(@GetAuthUser() authUser: AuthUserDto): Promise { return await this.assetService.getAllAssets(authUser); } + /** + * Get all asset of a device that are in the database, ID only. + */ @Get('/:deviceId') async getUserAssetsByDeviceId(@GetAuthUser() authUser: AuthUserDto, @Param('deviceId') deviceId: string) { return await this.assetService.getUserAssetsByDeviceId(authUser, deviceId); } + /** + * Get a single asset's information + */ @Get('/assetById/:assetId') - async getAssetById(@GetAuthUser() authUser: AuthUserDto, @Param('assetId') assetId: string) { + async getAssetById( + @GetAuthUser() authUser: AuthUserDto, + @Param('assetId') assetId: string, + ): Promise { return await this.assetService.getAssetById(authUser, assetId); } @Delete('/') - async deleteAssetById(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) assetIds: DeleteAssetDto) { - const deleteAssetList: AssetEntity[] = []; + async deleteAsset(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) assetIds: DeleteAssetDto) { + const deleteAssetList: AssetResponseDto[] = []; for (const id of assetIds.ids) { const assets = await this.assetService.getAssetById(authUser, id); diff --git a/server/apps/immich/src/api-v1/asset/asset.service.ts b/server/apps/immich/src/api-v1/asset/asset.service.ts index 12cf2080ea..c2bb24e69f 100644 --- a/server/apps/immich/src/api-v1/asset/asset.service.ts +++ b/server/apps/immich/src/api-v1/asset/asset.service.ts @@ -19,6 +19,8 @@ import { DeleteAssetDto } from './dto/delete-asset.dto'; import { SearchAssetDto } from './dto/search-asset.dto'; import fs from 'fs/promises'; import { CheckDuplicateAssetDto } from './dto/check-duplicate-asset.dto'; +import { CuratedObjectsResponseDto } from './response-dto/curated-objects-response.dto'; +import { AssetResponseDto, mapAsset } from './response-dto/asset-response.dto'; const fileInfo = promisify(stat); @@ -80,49 +82,55 @@ export class AssetService { return res; } - public async getAllAssets(authUser: AuthUserDto) { - try { - return await this.assetRepository.find({ - where: { - userId: authUser.id, - resizePath: Not(IsNull()), - }, - relations: ['exifInfo'], - order: { - createdAt: 'DESC', - }, - }); - } catch (e) { - Logger.error(e, 'getAllAssets'); - } + public async getAllAssets(authUser: AuthUserDto): Promise { + const assets = await this.assetRepository.find({ + where: { + userId: authUser.id, + resizePath: Not(IsNull()), + }, + relations: ['exifInfo'], + order: { + createdAt: 'DESC', + }, + }); + + return assets.map((asset) => mapAsset(asset)); } - public async findOne(deviceId: string, assetId: string): Promise { + public async findAssetOfDevice(deviceId: string, assetId: string): Promise { const rows = await this.assetRepository.query( 'SELECT * FROM assets a WHERE a."deviceAssetId" = $1 AND a."deviceId" = $2', [assetId, deviceId], ); if (rows.lengh == 0) { - throw new BadRequestException('Not Found'); + throw new NotFoundException('Not Found'); } - return rows[0] as AssetEntity; + const assetOnDevice = rows[0] as AssetEntity; + + return mapAsset(assetOnDevice); } - public async getAssetById(authUser: AuthUserDto, assetId: string) { - return await this.assetRepository.findOne({ + public async getAssetById(authUser: AuthUserDto, assetId: string): Promise { + const asset = await this.assetRepository.findOne({ where: { id: assetId, }, relations: ['exifInfo'], }); + + if (!asset) { + throw new NotFoundException('Asset not found'); + } + + return mapAsset(asset); } public async downloadFile(query: ServeFileDto, res: Res) { try { let fileReadStream = null; - const asset = await this.findOne(query.did, query.aid); + const asset = await this.findAssetOfDevice(query.did, query.aid); if (query.isThumb === 'false' || !query.isThumb) { const { size } = await fileInfo(asset.originalPath); @@ -188,7 +196,7 @@ export class AssetService { public async serveFile(authUser: AuthUserDto, query: ServeFileDto, res: Res, headers: any) { let fileReadStream: ReadStream; - const asset = await this.findOne(query.did, query.aid); + const asset = await this.findAssetOfDevice(query.did, query.aid); if (!asset) { throw new NotFoundException('Asset does not exist'); @@ -258,12 +266,13 @@ export class AssetService { try { // Handle Video let videoPath = asset.originalPath; + let mimeType = asset.mimeType; await fs.access(videoPath, constants.R_OK | constants.W_OK); if (query.isWeb && asset.mimeType == 'video/quicktime') { - videoPath = asset.encodedVideoPath == '' ? asset.originalPath : asset.encodedVideoPath; + videoPath = asset.encodedVideoPath == '' ? String(asset.originalPath) : String(asset.encodedVideoPath); mimeType = asset.encodedVideoPath == '' ? asset.mimeType : 'video/mp4'; } @@ -390,7 +399,7 @@ export class AssetService { return Array.from(possibleSearchTerm).filter((x) => x != null); } - async searchAsset(authUser: AuthUserDto, searchAssetDto: SearchAssetDto) { + async searchAsset(authUser: AuthUserDto, searchAssetDto: SearchAssetDto): Promise { const query = ` SELECT a.* FROM assets a @@ -406,7 +415,12 @@ export class AssetService { ); `; - return await this.assetRepository.query(query, [authUser.id, searchAssetDto.searchTerm]); + const searchResults: AssetEntity[] = await this.assetRepository.query(query, [ + authUser.id, + searchAssetDto.searchTerm, + ]); + + return searchResults.map((asset) => mapAsset(asset)); } async getCuratedLocation(authUser: AuthUserDto) { @@ -423,8 +437,8 @@ export class AssetService { ); } - async getCuratedObject(authUser: AuthUserDto) { - return await this.assetRepository.query( + async getCuratedObject(authUser: AuthUserDto): Promise { + const curatedObjects: CuratedObjectsResponseDto[] = await this.assetRepository.query( ` SELECT DISTINCT ON (unnest(si.objects)) a.id, unnest(si.objects) as "object", a."resizePath", a."deviceAssetId", a."deviceId" FROM assets a @@ -434,9 +448,11 @@ export class AssetService { `, [authUser.id], ); + + return curatedObjects; } - async checkDuplicatedAsset(authUser: AuthUserDto, checkDuplicateAssetDto: CheckDuplicateAssetDto) { + async checkDuplicatedAsset(authUser: AuthUserDto, checkDuplicateAssetDto: CheckDuplicateAssetDto): Promise { const res = await this.assetRepository.findOne({ where: { deviceAssetId: checkDuplicateAssetDto.deviceAssetId, diff --git a/server/apps/immich/src/api-v1/asset/dto/delete-asset.dto.ts b/server/apps/immich/src/api-v1/asset/dto/delete-asset.dto.ts index 7bed48455f..12cb89a9ba 100644 --- a/server/apps/immich/src/api-v1/asset/dto/delete-asset.dto.ts +++ b/server/apps/immich/src/api-v1/asset/dto/delete-asset.dto.ts @@ -1,6 +1,17 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty } from 'class-validator'; export class DeleteAssetDto { @IsNotEmpty() + @ApiProperty({ + isArray: true, + type: String, + title: 'Array of asset IDs to delete', + example: [ + 'bf973405-3f2a-48d2-a687-2ed4167164be', + 'dd41870b-5d00-46d2-924e-1d8489a0aa0f', + 'fad77c3f-deef-4e7e-9608-14c1aa4e559a', + ], + }) ids!: string[]; } diff --git a/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts b/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts index 9a24035602..0e18d2919b 100644 --- a/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts +++ b/server/apps/immich/src/api-v1/asset/dto/serve-file.dto.ts @@ -1,12 +1,13 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsBooleanString, IsNotEmpty, IsOptional } from 'class-validator'; export class ServeFileDto { - //assetId @IsNotEmpty() + @ApiProperty({ type: String, title: 'Device Asset ID' }) aid!: string; - //deviceId @IsNotEmpty() + @ApiProperty({ type: String, title: 'Device ID' }) did!: string; @IsOptional() diff --git a/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts index 6337405b3b..ef74145abf 100644 --- a/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts +++ b/server/apps/immich/src/api-v1/asset/response-dto/asset-response.dto.ts @@ -2,19 +2,21 @@ import { AssetEntity, AssetType } from '@app/database/entities/asset.entity'; import { ExifResponseDto, mapExif } from './exif-response.dto'; import { SmartInfoResponseDto, mapSmartInfo } from './smart-info-response.dto'; -export interface AssetResponseDto { - id: string; - deviceAssetId: string; - ownerId: string; - deviceId: string; - type: AssetType; - originalPath: string; - resizePath: string | null; - createdAt: string; - modifiedAt: string; - isFavorite: boolean; - mimeType: string | null; - duration: string; +export class AssetResponseDto { + id!: string; + deviceAssetId!: string; + ownerId!: string; + deviceId!: string; + type!: AssetType; + originalPath!: string; + resizePath!: string | null; + createdAt!: string; + modifiedAt!: string; + isFavorite!: boolean; + mimeType!: string | null; + duration!: string; + webpPath!: string | null; + encodedVideoPath!: string | null; exifInfo?: ExifResponseDto; smartInfo?: SmartInfoResponseDto; } @@ -32,6 +34,8 @@ export function mapAsset(entity: AssetEntity): AssetResponseDto { modifiedAt: entity.modifiedAt, isFavorite: entity.isFavorite, mimeType: entity.mimeType, + webpPath: entity.webpPath, + encodedVideoPath: entity.encodedVideoPath, duration: entity.duration ?? '0:00:00.00000', exifInfo: entity.exifInfo ? mapExif(entity.exifInfo) : undefined, smartInfo: entity.smartInfo ? mapSmartInfo(entity.smartInfo) : undefined, diff --git a/server/apps/immich/src/api-v1/asset/response-dto/curated-locations-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/curated-locations-response.dto.ts new file mode 100644 index 0000000000..63b1b09693 --- /dev/null +++ b/server/apps/immich/src/api-v1/asset/response-dto/curated-locations-response.dto.ts @@ -0,0 +1,7 @@ +export class CuratedLocationsResponseDto { + id!: string; + city!: string; + resizePath!: string; + deviceAssetId!: string; + deviceId!: string; +} diff --git a/server/apps/immich/src/api-v1/asset/response-dto/curated-objects-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/curated-objects-response.dto.ts new file mode 100644 index 0000000000..0d23b3eb79 --- /dev/null +++ b/server/apps/immich/src/api-v1/asset/response-dto/curated-objects-response.dto.ts @@ -0,0 +1,7 @@ +export class CuratedObjectsResponseDto { + id!: string; + object!: string; + resizePath!: string; + deviceAssetId!: string; + deviceId!: string; +} diff --git a/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts index defd7a5f37..57b0c8e9c0 100644 --- a/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts +++ b/server/apps/immich/src/api-v1/asset/response-dto/exif-response.dto.ts @@ -1,26 +1,26 @@ import { ExifEntity } from '@app/database/entities/exif.entity'; -export interface ExifResponseDto { - id: string; - make: string | null; - model: string | null; - imageName: string | null; - exifImageWidth: number | null; - exifImageHeight: number | null; - fileSizeInByte: number | null; - orientation: string | null; - dateTimeOriginal: Date | null; - modifyDate: Date | null; - lensModel: string | null; - fNumber: number | null; - focalLength: number | null; - iso: number | null; - exposureTime: number | null; - latitude: number | null; - longitude: number | null; - city: string | null; - state: string | null; - country: string | null; +export class ExifResponseDto { + id!: string; + make: string | null = null; + model: string | null = null; + imageName: string | null = null; + exifImageWidth: number | null = null; + exifImageHeight: number | null = null; + fileSizeInByte: number | null = null; + orientation: string | null = null; + dateTimeOriginal: Date | null = null; + modifyDate: Date | null = null; + lensModel: string | null = null; + fNumber: number | null = null; + focalLength: number | null = null; + iso: number | null = null; + exposureTime: number | null = null; + latitude: number | null = null; + longitude: number | null = null; + city: string | null = null; + state: string | null = null; + country: string | null = null; } export function mapExif(entity: ExifEntity): ExifResponseDto { diff --git a/server/apps/immich/src/api-v1/asset/response-dto/smart-info-response.dto.ts b/server/apps/immich/src/api-v1/asset/response-dto/smart-info-response.dto.ts index efb05e0126..cc9f3118e1 100644 --- a/server/apps/immich/src/api-v1/asset/response-dto/smart-info-response.dto.ts +++ b/server/apps/immich/src/api-v1/asset/response-dto/smart-info-response.dto.ts @@ -1,9 +1,9 @@ import { SmartInfoEntity } from '@app/database/entities/smart-info.entity'; -export interface SmartInfoResponseDto { - id: string; - tags: string[] | null; - objects: string[] | null; +export class SmartInfoResponseDto { + id?: string; + tags?: string[] | null; + objects?: string[] | null; } export function mapSmartInfo(entity: SmartInfoEntity): SmartInfoResponseDto { diff --git a/server/apps/immich/src/api-v1/auth/auth.controller.ts b/server/apps/immich/src/api-v1/auth/auth.controller.ts index d7942c4d9a..a7a571e76b 100644 --- a/server/apps/immich/src/api-v1/auth/auth.controller.ts +++ b/server/apps/immich/src/api-v1/auth/auth.controller.ts @@ -1,30 +1,42 @@ import { Body, Controller, Post, UseGuards, ValidationPipe } from '@nestjs/common'; +import { + ApiBadRequestResponse, + ApiBearerAuth, + ApiBody, + ApiCreatedResponse, + ApiResponse, + ApiTags, +} from '@nestjs/swagger'; import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { AuthService } from './auth.service'; import { LoginCredentialDto } from './dto/login-credential.dto'; +import { LoginResponseDto } from './response-dto/login-response.dto'; import { SignUpDto } from './dto/sign-up.dto'; +import { AdminSignupResponseDto } from './response-dto/admin-signup-response.dto'; +import { ValidateAccessTokenResponseDto } from './response-dto/validate-asset-token-response.dto,'; +@ApiTags('Authentication') @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Post('/login') - async login(@Body(ValidationPipe) loginCredential: LoginCredentialDto) { + async login(@Body(ValidationPipe) loginCredential: LoginCredentialDto): Promise { return await this.authService.login(loginCredential); } @Post('/admin-sign-up') - async adminSignUp(@Body(ValidationPipe) signUpCrendential: SignUpDto) { - return await this.authService.adminSignUp(signUpCrendential); + @ApiBadRequestResponse({ description: 'The server already has an admin' }) + async adminSignUp(@Body(ValidationPipe) signUpCredential: SignUpDto): Promise { + return await this.authService.adminSignUp(signUpCredential); } @UseGuards(JwtAuthGuard) + @ApiBearerAuth() @Post('/validateToken') // eslint-disable-next-line @typescript-eslint/no-unused-vars - async validateToken(@GetAuthUser() authUser: AuthUserDto) { - return { - authStatus: true, - }; + async validateAccessToken(@GetAuthUser() authUser: AuthUserDto): Promise { + return new ValidateAccessTokenResponseDto(true); } } diff --git a/server/apps/immich/src/api-v1/auth/auth.service.ts b/server/apps/immich/src/api-v1/auth/auth.service.ts index a34a8a3083..efdbb022f5 100644 --- a/server/apps/immich/src/api-v1/auth/auth.service.ts +++ b/server/apps/immich/src/api-v1/auth/auth.service.ts @@ -7,7 +7,8 @@ import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service'; import { JwtPayloadDto } from './dto/jwt-payload.dto'; import { SignUpDto } from './dto/sign-up.dto'; import * as bcrypt from 'bcrypt'; -import { mapUser, UserResponseDto } from '../user/response-dto/user-response.dto'; +import { LoginResponseDto, mapLoginResponse } from './response-dto/login-response.dto'; +import { AdminSignupResponseDto, mapAdminSignupResponse } from './response-dto/admin-signup-response.dto'; @Injectable() export class AuthService { @@ -49,7 +50,7 @@ export class AuthService { return null; } - public async login(loginCredential: LoginCredentialDto) { + public async login(loginCredential: LoginCredentialDto): Promise { const validatedUser = await this.validateUser(loginCredential); if (!validatedUser) { @@ -57,20 +58,12 @@ export class AuthService { } const payload = new JwtPayloadDto(validatedUser.id, validatedUser.email); + const accessToken = await this.immichJwtService.generateToken(payload); - return { - accessToken: await this.immichJwtService.generateToken(payload), - userId: validatedUser.id, - userEmail: validatedUser.email, - firstName: validatedUser.firstName, - lastName: validatedUser.lastName, - isAdmin: validatedUser.isAdmin, - profileImagePath: validatedUser.profileImagePath, - shouldChangePassword: validatedUser.shouldChangePassword, - }; + return mapLoginResponse(validatedUser, accessToken); } - public async adminSignUp(signUpCredential: SignUpDto): Promise { + public async adminSignUp(signUpCredential: SignUpDto): Promise { const adminUser = await this.userRepository.findOne({ where: { isAdmin: true } }); if (adminUser) { @@ -88,7 +81,7 @@ export class AuthService { try { const savedNewAdminUserUser = await this.userRepository.save(newAdminUser); - return mapUser(savedNewAdminUserUser); + return mapAdminSignupResponse(savedNewAdminUserUser); } catch (e) { Logger.error('e', 'signUp'); throw new InternalServerErrorException('Failed to register new admin user'); diff --git a/server/apps/immich/src/api-v1/auth/dto/login-credential.dto.ts b/server/apps/immich/src/api-v1/auth/dto/login-credential.dto.ts index da0077a6f7..29ba5cf026 100644 --- a/server/apps/immich/src/api-v1/auth/dto/login-credential.dto.ts +++ b/server/apps/immich/src/api-v1/auth/dto/login-credential.dto.ts @@ -1,9 +1,12 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty } from 'class-validator'; export class LoginCredentialDto { @IsNotEmpty() + @ApiProperty({ example: 'testuser@email.com' }) email!: string; @IsNotEmpty() + @ApiProperty({ example: 'password' }) password!: string; } diff --git a/server/apps/immich/src/api-v1/auth/dto/sign-up.dto.ts b/server/apps/immich/src/api-v1/auth/dto/sign-up.dto.ts index b8f666adb8..bbeef17b96 100644 --- a/server/apps/immich/src/api-v1/auth/dto/sign-up.dto.ts +++ b/server/apps/immich/src/api-v1/auth/dto/sign-up.dto.ts @@ -1,15 +1,20 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty } from 'class-validator'; export class SignUpDto { @IsNotEmpty() + @ApiProperty({ example: 'testuser@email.com' }) email!: string; @IsNotEmpty() + @ApiProperty({ example: 'password' }) password!: string; @IsNotEmpty() + @ApiProperty({ example: 'Admin' }) firstName!: string; @IsNotEmpty() + @ApiProperty({ example: 'Doe' }) lastName!: string; } diff --git a/server/apps/immich/src/api-v1/auth/response-dto/admin-signup-response.dto.ts b/server/apps/immich/src/api-v1/auth/response-dto/admin-signup-response.dto.ts new file mode 100644 index 0000000000..994846d9da --- /dev/null +++ b/server/apps/immich/src/api-v1/auth/response-dto/admin-signup-response.dto.ts @@ -0,0 +1,19 @@ +import { UserEntity } from '@app/database/entities/user.entity'; + +export class AdminSignupResponseDto { + id!: string; + email!: string; + firstName!: string; + lastName!: string; + createdAt!: string; +} + +export function mapAdminSignupResponse(entity: UserEntity): AdminSignupResponseDto { + return { + id: entity.id, + email: entity.email, + firstName: entity.firstName, + lastName: entity.lastName, + createdAt: entity.createdAt, + }; +} diff --git a/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts b/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts new file mode 100644 index 0000000000..f6870158aa --- /dev/null +++ b/server/apps/immich/src/api-v1/auth/response-dto/login-response.dto.ts @@ -0,0 +1,41 @@ +import { UserEntity } from '@app/database/entities/user.entity'; +import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger'; + +export class LoginResponseDto { + @ApiResponseProperty() + accessToken!: string; + + @ApiResponseProperty() + userId!: string; + + @ApiResponseProperty() + userEmail!: string; + + @ApiResponseProperty() + firstName!: string; + + @ApiResponseProperty() + lastName!: string; + + @ApiResponseProperty() + profileImagePath!: string; + + @ApiResponseProperty() + isAdmin!: boolean; + + @ApiResponseProperty() + shouldChangePassword!: boolean; +} + +export function mapLoginResponse(entity: UserEntity, accessToken: string): LoginResponseDto { + return { + accessToken: accessToken, + userId: entity.id, + userEmail: entity.email, + firstName: entity.firstName, + lastName: entity.lastName, + isAdmin: entity.isAdmin, + profileImagePath: entity.profileImagePath, + shouldChangePassword: entity.shouldChangePassword, + }; +} diff --git a/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts b/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts new file mode 100644 index 0000000000..151d59e6f1 --- /dev/null +++ b/server/apps/immich/src/api-v1/auth/response-dto/validate-asset-token-response.dto,.ts @@ -0,0 +1,7 @@ +export class ValidateAccessTokenResponseDto { + constructor(authStatus: boolean) { + this.authStatus = authStatus; + } + + authStatus: boolean; +} diff --git a/server/apps/immich/src/api-v1/device-info/device-info.controller.ts b/server/apps/immich/src/api-v1/device-info/device-info.controller.ts index 61d3e9d050..554da4b4bd 100644 --- a/server/apps/immich/src/api-v1/device-info/device-info.controller.ts +++ b/server/apps/immich/src/api-v1/device-info/device-info.controller.ts @@ -1,22 +1,32 @@ import { Controller, Post, Body, Patch, UseGuards, ValidationPipe } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { DeviceInfoService } from './device-info.service'; import { CreateDeviceInfoDto } from './dto/create-device-info.dto'; import { UpdateDeviceInfoDto } from './dto/update-device-info.dto'; +import { DeviceInfoResponseDto } from './response-dto/create-device-info-response.dto'; @UseGuards(JwtAuthGuard) +@ApiBearerAuth() +@ApiTags('Device Info') @Controller('device-info') export class DeviceInfoController { constructor(private readonly deviceInfoService: DeviceInfoService) {} @Post() - async create(@Body(ValidationPipe) createDeviceInfoDto: CreateDeviceInfoDto, @GetAuthUser() authUser: AuthUserDto) { - return await this.deviceInfoService.create(createDeviceInfoDto, authUser); + async createDeviceInfo( + @Body(ValidationPipe) createDeviceInfoDto: CreateDeviceInfoDto, + @GetAuthUser() authUser: AuthUserDto, + ): Promise { + return this.deviceInfoService.create(createDeviceInfoDto, authUser); } @Patch() - async update(@Body(ValidationPipe) updateDeviceInfoDto: UpdateDeviceInfoDto, @GetAuthUser() authUser: AuthUserDto) { + async updateDeviceInfo( + @Body(ValidationPipe) updateDeviceInfoDto: UpdateDeviceInfoDto, + @GetAuthUser() authUser: AuthUserDto, + ): Promise { return this.deviceInfoService.update(authUser.id, updateDeviceInfoDto); } } diff --git a/server/apps/immich/src/api-v1/device-info/device-info.service.ts b/server/apps/immich/src/api-v1/device-info/device-info.service.ts index 710b19a7da..76a546fbc0 100644 --- a/server/apps/immich/src/api-v1/device-info/device-info.service.ts +++ b/server/apps/immich/src/api-v1/device-info/device-info.service.ts @@ -1,10 +1,11 @@ -import { BadRequestException, Injectable, Logger } from '@nestjs/common'; +import { BadRequestException, Injectable, Logger, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { AuthUserDto } from '../../decorators/auth-user.decorator'; import { CreateDeviceInfoDto } from './dto/create-device-info.dto'; import { UpdateDeviceInfoDto } from './dto/update-device-info.dto'; import { DeviceInfoEntity } from '@app/database/entities/device-info.entity'; +import { DeviceInfoResponseDto, mapDeviceInfoResponse } from './response-dto/create-device-info-response.dto'; @Injectable() export class DeviceInfoService { @@ -13,7 +14,7 @@ export class DeviceInfoService { private deviceRepository: Repository, ) {} - async create(createDeviceInfoDto: CreateDeviceInfoDto, authUser: AuthUserDto) { + async create(createDeviceInfoDto: CreateDeviceInfoDto, authUser: AuthUserDto): Promise { const res = await this.deviceRepository.findOne({ where: { deviceId: createDeviceInfoDto.deviceId, @@ -23,7 +24,7 @@ export class DeviceInfoService { if (res) { Logger.log('Device Info Exist', 'createDeviceInfo'); - return res; + return mapDeviceInfoResponse(res); } const deviceInfo = new DeviceInfoEntity(); @@ -31,20 +32,18 @@ export class DeviceInfoService { deviceInfo.deviceType = createDeviceInfoDto.deviceType; deviceInfo.userId = authUser.id; - try { - return await this.deviceRepository.save(deviceInfo); - } catch (e) { - Logger.error('Error creating new device info', 'createDeviceInfo'); - } + const newDeviceInfo = await this.deviceRepository.save(deviceInfo); + + return mapDeviceInfoResponse(newDeviceInfo); } - async update(userId: string, updateDeviceInfoDto: UpdateDeviceInfoDto) { + async update(userId: string, updateDeviceInfoDto: UpdateDeviceInfoDto): Promise { const deviceInfo = await this.deviceRepository.findOne({ where: { deviceId: updateDeviceInfoDto.deviceId, userId: userId }, }); if (!deviceInfo) { - throw new BadRequestException('Device Not Found'); + throw new NotFoundException('Device Not Found'); } const res = await this.deviceRepository.update( @@ -55,9 +54,15 @@ export class DeviceInfoService { ); if (res.affected == 1) { - return await this.deviceRepository.findOne({ + const updatedDeviceInfo = await this.deviceRepository.findOne({ where: { deviceId: updateDeviceInfoDto.deviceId, userId: userId }, }); + + if (!updatedDeviceInfo) { + throw new NotFoundException('Device Not Found'); + } + + return mapDeviceInfoResponse(updatedDeviceInfo); } else { throw new BadRequestException('Bad Request'); } diff --git a/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts b/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts new file mode 100644 index 0000000000..e36389d332 --- /dev/null +++ b/server/apps/immich/src/api-v1/device-info/response-dto/create-device-info-response.dto.ts @@ -0,0 +1,23 @@ +import { DeviceInfoEntity, DeviceType } from '@app/database/entities/device-info.entity'; + +export class DeviceInfoResponseDto { + id!: number; + userId!: string; + deviceId!: string; + deviceType!: DeviceType; + notificationToken!: string | null; + createdAt!: string; + isAutoBackup!: boolean; +} + +export function mapDeviceInfoResponse(entity: DeviceInfoEntity): DeviceInfoResponseDto { + return { + id: entity.id, + userId: entity.userId, + deviceId: entity.deviceId, + deviceType: entity.deviceType, + notificationToken: entity.notificationToken, + createdAt: entity.createdAt, + isAutoBackup: entity.isAutoBackup, + }; +} diff --git a/server/apps/immich/src/api-v1/server-info/dto/server-info.dto.ts b/server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts similarity index 62% rename from server/apps/immich/src/api-v1/server-info/dto/server-info.dto.ts rename to server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts index 00cf7e4e68..e0a5f5c2da 100644 --- a/server/apps/immich/src/api-v1/server-info/dto/server-info.dto.ts +++ b/server/apps/immich/src/api-v1/server-info/response-dto/server-info-response.dto.ts @@ -1,5 +1,4 @@ -// TODO: this is being used as a response DTO. Should be changed to interface -export class ServerInfoDto { +export class ServerInfoResponseDto { diskSize!: string; diskUse!: string; diskAvailable!: string; diff --git a/server/apps/immich/src/api-v1/server-info/response-dto/server-ping-response.dto.ts b/server/apps/immich/src/api-v1/server-info/response-dto/server-ping-response.dto.ts new file mode 100644 index 0000000000..8b41b4af1b --- /dev/null +++ b/server/apps/immich/src/api-v1/server-info/response-dto/server-ping-response.dto.ts @@ -0,0 +1,10 @@ +import { ApiResponseProperty } from '@nestjs/swagger'; + +export class ServerPingResponse { + constructor(res: string) { + this.res = res; + } + + @ApiResponseProperty({ type: String, example: 'pong' }) + res!: string; +} diff --git a/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts b/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts new file mode 100644 index 0000000000..d054d9b3ce --- /dev/null +++ b/server/apps/immich/src/api-v1/server-info/response-dto/server-version-response.dto.ts @@ -0,0 +1,8 @@ +import { IServerVersion } from 'apps/immich/src/constants/server_version.constant'; + +export class ServerVersionReponseDto implements IServerVersion { + major!: number; + minor!: number; + patch!: number; + build!: number; +} diff --git a/server/apps/immich/src/api-v1/server-info/server-info.controller.ts b/server/apps/immich/src/api-v1/server-info/server-info.controller.ts index 54894dd66e..16eb9d5aaf 100644 --- a/server/apps/immich/src/api-v1/server-info/server-info.controller.ts +++ b/server/apps/immich/src/api-v1/server-info/server-info.controller.ts @@ -3,34 +3,28 @@ import { ConfigService } from '@nestjs/config'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { ServerInfoService } from './server-info.service'; import { serverVersion } from '../../constants/server_version.constant'; +import { ApiTags } from '@nestjs/swagger'; +import { ServerPingResponse } from './response-dto/server-ping-response.dto'; +import { ServerVersionReponseDto } from './response-dto/server-version-response.dto'; +import { ServerInfoResponseDto } from './response-dto/server-info-response.dto'; +@ApiTags('Server Info') @Controller('server-info') export class ServerInfoController { constructor(private readonly serverInfoService: ServerInfoService, private readonly configService: ConfigService) {} @Get() - async getServerInfo() { + async getServerInfo(): Promise { return await this.serverInfoService.getServerInfo(); } @Get('/ping') - async getServerPulse() { - return { - res: 'pong', - }; - } - - @UseGuards(JwtAuthGuard) - @Get('/mapbox') - async getMapboxInfo() { - return { - isEnable: this.configService.get('ENABLE_MAPBOX'), - mapboxSecret: this.configService.get('MAPBOX_KEY'), - }; + async pingServer(): Promise { + return new ServerPingResponse('pong'); } @Get('/version') - async getServerVersion() { + async getServerVersion(): Promise { return serverVersion; } } diff --git a/server/apps/immich/src/api-v1/server-info/server-info.service.ts b/server/apps/immich/src/api-v1/server-info/server-info.service.ts index e196f397df..606161aa77 100644 --- a/server/apps/immich/src/api-v1/server-info/server-info.service.ts +++ b/server/apps/immich/src/api-v1/server-info/server-info.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { ServerInfoDto } from './dto/server-info.dto'; +import { ServerInfoResponseDto } from './response-dto/server-info-response.dto'; import diskusage from 'diskusage'; import { APP_UPLOAD_LOCATION } from '../../constants/upload_location.constant'; @@ -10,7 +10,7 @@ export class ServerInfoService { const usagePercentage = (((diskInfo.total - diskInfo.free) / diskInfo.total) * 100).toFixed(2); - const serverInfo = new ServerInfoDto(); + const serverInfo = new ServerInfoResponseDto(); serverInfo.diskAvailable = ServerInfoService.getHumanReadableString(diskInfo.available); serverInfo.diskSize = ServerInfoService.getHumanReadableString(diskInfo.total); serverInfo.diskUse = ServerInfoService.getHumanReadableString(diskInfo.total - diskInfo.free); diff --git a/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts b/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts new file mode 100644 index 0000000000..a01f10f466 --- /dev/null +++ b/server/apps/immich/src/api-v1/user/dto/create-profile-image.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateProfileImageDto { + @ApiProperty({ type: 'string', format: 'binary' }) + file: any; +} diff --git a/server/apps/immich/src/api-v1/user/dto/create-user.dto.ts b/server/apps/immich/src/api-v1/user/dto/create-user.dto.ts index b8df1d249c..66f311dc20 100644 --- a/server/apps/immich/src/api-v1/user/dto/create-user.dto.ts +++ b/server/apps/immich/src/api-v1/user/dto/create-user.dto.ts @@ -1,27 +1,20 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsOptional } from 'class-validator'; export class CreateUserDto { @IsNotEmpty() + @ApiProperty({ example: 'testuser@email.com' }) email!: string; @IsNotEmpty() + @ApiProperty({ example: 'password' }) password!: string; @IsNotEmpty() + @ApiProperty({ example: 'John' }) firstName!: string; @IsNotEmpty() + @ApiProperty({ example: 'Doe' }) lastName!: string; - - @IsOptional() - profileImagePath?: string; - - @IsOptional() - isAdmin?: boolean; - - @IsOptional() - shouldChangePassword?: boolean; - - @IsOptional() - id?: string; } diff --git a/server/apps/immich/src/api-v1/user/dto/update-user.dto.ts b/server/apps/immich/src/api-v1/user/dto/update-user.dto.ts index dfd37fb1ed..424e08e1ac 100644 --- a/server/apps/immich/src/api-v1/user/dto/update-user.dto.ts +++ b/server/apps/immich/src/api-v1/user/dto/update-user.dto.ts @@ -1,4 +1,24 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateUserDto } from './create-user.dto'; +import { IsNotEmpty, IsOptional } from 'class-validator'; -export class UpdateUserDto extends PartialType(CreateUserDto) {} +export class UpdateUserDto { + @IsNotEmpty() + id!: string; + + @IsOptional() + password?: string; + + @IsOptional() + firstName?: string; + + @IsOptional() + lastName?: string; + + @IsOptional() + isAdmin?: boolean; + + @IsOptional() + shouldChangePassword?: boolean; + + @IsOptional() + profileImagePath?: string; +} diff --git a/server/apps/immich/src/api-v1/user/response-dto/create-profile-image-response.dto.ts b/server/apps/immich/src/api-v1/user/response-dto/create-profile-image-response.dto.ts new file mode 100644 index 0000000000..2c7fd17be7 --- /dev/null +++ b/server/apps/immich/src/api-v1/user/response-dto/create-profile-image-response.dto.ts @@ -0,0 +1,11 @@ +export class CreateProfileImageResponseDto { + userId!: string; + profileImagePath!: string; +} + +export function mapCreateProfileImageResponse(userId: string, profileImagePath: string): CreateProfileImageResponseDto { + return { + userId: userId, + profileImagePath: profileImagePath, + }; +} diff --git a/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts b/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts new file mode 100644 index 0000000000..63df372350 --- /dev/null +++ b/server/apps/immich/src/api-v1/user/response-dto/user-count-response.dto.ts @@ -0,0 +1,10 @@ + +export class UserCountResponseDto { + userCount!: number; +} + +export function mapUserCountResponse(count: number): UserCountResponseDto { + return { + userCount: count, + }; +} \ No newline at end of file diff --git a/server/apps/immich/src/api-v1/user/response-dto/user-response.dto.ts b/server/apps/immich/src/api-v1/user/response-dto/user-response.dto.ts index 06bb11843f..d571506f29 100644 --- a/server/apps/immich/src/api-v1/user/response-dto/user-response.dto.ts +++ b/server/apps/immich/src/api-v1/user/response-dto/user-response.dto.ts @@ -1,11 +1,14 @@ -import { UserEntity } from '../../../../../../libs/database/src/entities/user.entity'; +import { UserEntity } from '@app/database/entities/user.entity'; -export interface UserResponseDto { - id: string; - email: string; - firstName: string; - lastName: string; - createdAt: string; +export class UserResponseDto { + id!: string; + email!: string; + firstName!: string; + lastName!: string; + createdAt!: string; + profileImagePath!: string; + shouldChangePassword!: boolean; + isAdmin!: boolean; } export function mapUser(entity: UserEntity): UserResponseDto { @@ -15,5 +18,8 @@ export function mapUser(entity: UserEntity): UserResponseDto { firstName: entity.firstName, lastName: entity.lastName, createdAt: entity.createdAt, + profileImagePath: entity.profileImagePath, + shouldChangePassword: entity.shouldChangePassword, + isAdmin: entity.isAdmin, }; } diff --git a/server/apps/immich/src/api-v1/user/user.controller.ts b/server/apps/immich/src/api-v1/user/user.controller.ts index 3a1f422790..5855fc18f8 100644 --- a/server/apps/immich/src/api-v1/user/user.controller.ts +++ b/server/apps/immich/src/api-v1/user/user.controller.ts @@ -11,6 +11,7 @@ import { UseInterceptors, UploadedFile, Response, + StreamableFile, } from '@nestjs/common'; import { UserService } from './user.service'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; @@ -21,50 +22,72 @@ import { UpdateUserDto } from './dto/update-user.dto'; import { FileInterceptor } from '@nestjs/platform-express'; import { profileImageUploadOption } from '../../config/profile-image-upload.config'; import { Response as Res } from 'express'; +import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger'; +import { UserResponseDto } from './response-dto/user-response.dto'; +import { UserEntity } from '@app/database/entities/user.entity'; +import { UserCountResponseDto } from './response-dto/user-count-response.dto'; +import { CreateProfileImageDto } from './dto/create-profile-image.dto'; +import { CreateProfileImageResponseDto } from './response-dto/create-profile-image-response.dto'; +@ApiTags('User') @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @UseGuards(JwtAuthGuard) + @ApiBearerAuth() @Get() - async getAllUsers(@GetAuthUser() authUser: AuthUserDto, @Query('isAll') isAll: boolean) { + async getAllUsers(@GetAuthUser() authUser: AuthUserDto, @Query('isAll') isAll: boolean): Promise { return await this.userService.getAllUsers(authUser, isAll); } @UseGuards(JwtAuthGuard) + @ApiBearerAuth() @Get('me') - async getUserInfo(@GetAuthUser() authUser: AuthUserDto) { + async getMyUserInfo(@GetAuthUser() authUser: AuthUserDto): Promise { return await this.userService.getUserInfo(authUser); } @UseGuards(JwtAuthGuard) + @ApiBearerAuth() @UseGuards(AdminRolesGuard) @Post() - async createNewUser(@Body(ValidationPipe) createUserDto: CreateUserDto) { + async createUser(@Body(ValidationPipe) createUserDto: CreateUserDto): Promise { return await this.userService.createUser(createUserDto); } @Get('/count') - async getUserCount(@Query('isAdmin') isAdmin: boolean) { + async getUserCount(@Query('isAdmin') isAdmin: boolean): Promise { return await this.userService.getUserCount(isAdmin); } @UseGuards(JwtAuthGuard) + @ApiBearerAuth() @Put() - async updateUser(@Body(ValidationPipe) updateUserDto: UpdateUserDto) { + async updateUser(@Body(ValidationPipe) updateUserDto: UpdateUserDto): Promise { return await this.userService.updateUser(updateUserDto); } - @UseGuards(JwtAuthGuard) @UseInterceptors(FileInterceptor('file', profileImageUploadOption)) + @UseGuards(JwtAuthGuard) + @ApiBearerAuth() + @ApiConsumes('multipart/form-data') + @ApiBody({ + type: CreateProfileImageDto, + }) @Post('/profile-image') - async createProfileImage(@GetAuthUser() authUser: AuthUserDto, @UploadedFile() fileInfo: Express.Multer.File) { + async createProfileImage( + @GetAuthUser() authUser: AuthUserDto, + @UploadedFile() fileInfo: Express.Multer.File, + ): Promise { return await this.userService.createProfileImage(authUser, fileInfo); } @Get('/profile-image/:userId') - async getProfileImage(@Param('userId') userId: string, @Response({ passthrough: true }) res: Res) { - return await this.userService.getUserProfileImage(userId, res); + async getProfileImage( + @Param('userId') userId: string, + @Response({ passthrough: true }) res: Res, + ): Promise { + return this.userService.getUserProfileImage(userId, res); } } diff --git a/server/apps/immich/src/api-v1/user/user.service.ts b/server/apps/immich/src/api-v1/user/user.service.ts index 20fcd5136f..a0761d3fa4 100644 --- a/server/apps/immich/src/api-v1/user/user.service.ts +++ b/server/apps/immich/src/api-v1/user/user.service.ts @@ -16,6 +16,11 @@ import * as bcrypt from 'bcrypt'; import { createReadStream } from 'fs'; import { Response as Res } from 'express'; import { mapUser, UserResponseDto } from './response-dto/user-response.dto'; +import { mapUserCountResponse, UserCountResponseDto } from './response-dto/user-count-response.dto'; +import { + CreateProfileImageResponseDto, + mapCreateProfileImageResponse, +} from './response-dto/create-profile-image-response.dto'; @Injectable() export class UserService { @@ -24,24 +29,32 @@ export class UserService { private userRepository: Repository, ) {} - async getAllUsers(authUser: AuthUserDto, isAll: boolean) { + async getAllUsers(authUser: AuthUserDto, isAll: boolean): Promise { if (isAll) { - return await this.userRepository.find(); + const allUsers = await this.userRepository.find(); + + return allUsers.map(mapUser); } - return await this.userRepository.find({ + const allUserExceptRequestedUser = await this.userRepository.find({ where: { id: Not(authUser.id) }, order: { createdAt: 'DESC', }, }); + + return allUserExceptRequestedUser.map(mapUser); } - async getUserInfo(authUser: AuthUserDto) { - return this.userRepository.findOne({ where: { id: authUser.id } }); + async getUserInfo(authUser: AuthUserDto): Promise { + const user = await this.userRepository.findOne({ where: { id: authUser.id } }); + if (!user) { + throw new BadRequestException('User not found'); + } + return mapUser(user); } - async getUserCount(isAdmin: boolean) { + async getUserCount(isAdmin: boolean): Promise { let users; if (isAdmin) { @@ -50,9 +63,7 @@ export class UserService { users = await this.userRepository.find(); } - return { - userCount: users.length, - }; + return mapUserCountResponse(users.length); } async createUser(createUserDto: CreateUserDto): Promise { @@ -84,7 +95,7 @@ export class UserService { return bcrypt.hash(password, salt); } - async updateUser(updateUserDto: UpdateUserDto) { + async updateUser(updateUserDto: UpdateUserDto): Promise { const user = await this.userRepository.findOne({ where: { id: updateUserDto.id } }); if (!user) { throw new NotFoundException('User not found'); @@ -115,31 +126,23 @@ export class UserService { try { const updatedUser = await this.userRepository.save(user); - // TODO: this should probably retrun UserResponseDto - return { - id: updatedUser.id, - email: updatedUser.email, - firstName: updatedUser.firstName, - lastName: updatedUser.lastName, - isAdmin: updatedUser.isAdmin, - profileImagePath: updatedUser.profileImagePath, - }; + return mapUser(updatedUser); } catch (e) { Logger.error(e, 'Create new user'); throw new InternalServerErrorException('Failed to register new user'); } } - async createProfileImage(authUser: AuthUserDto, fileInfo: Express.Multer.File) { + async createProfileImage( + authUser: AuthUserDto, + fileInfo: Express.Multer.File, + ): Promise { try { await this.userRepository.update(authUser.id, { profileImagePath: fileInfo.path, }); - return { - userId: authUser.id, - profileImagePath: fileInfo.path, - }; + return mapCreateProfileImageResponse(authUser.id, fileInfo.path); } catch (e) { Logger.error(e, 'Create User Profile Image'); throw new InternalServerErrorException('Failed to create new user profile image'); diff --git a/server/apps/immich/src/constants/server_version.constant.ts b/server/apps/immich/src/constants/server_version.constant.ts index ed266d341d..e0feea55e9 100644 --- a/server/apps/immich/src/constants/server_version.constant.ts +++ b/server/apps/immich/src/constants/server_version.constant.ts @@ -1,7 +1,14 @@ // major.minor.patch+build // check mobile/pubspec.yml for current release version -export const serverVersion = { +export interface IServerVersion { + major: number; + minor: number; + patch: number; + build: number; +} + +export const serverVersion: IServerVersion = { major: 1, minor: 17, patch: 0, diff --git a/server/apps/immich/src/main.ts b/server/apps/immich/src/main.ts index fe316b75fb..770e3c2e2d 100644 --- a/server/apps/immich/src/main.ts +++ b/server/apps/immich/src/main.ts @@ -1,6 +1,9 @@ import { Logger } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; +import { DocumentBuilder, SwaggerDocumentOptions, SwaggerModule } from '@nestjs/swagger'; +import { writeFileSync } from 'fs'; +import path from 'path'; import { AppModule } from './app.module'; import { RedisIoAdapter } from './middlewares/redis-io.adapter.middleware'; @@ -15,6 +18,38 @@ async function bootstrap() { app.useWebSocketAdapter(new RedisIoAdapter(app)); + const config = new DocumentBuilder() + .setTitle('Immich') + .setDescription('Immich API') + .setVersion('1.17.0') + .addBearerAuth({ + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + name: 'JWT', + description: 'Enter JWT token', + in: 'header', + }) + .addServer('/api') + .build(); + + const apiDocumentOptions: SwaggerDocumentOptions = { + operationIdFactory: (controllerKey: string, methodKey: string) => methodKey, + }; + + const apiDocument = SwaggerModule.createDocument(app, config, apiDocumentOptions); + + SwaggerModule.setup('doc', app, apiDocument, { + swaggerOptions: { + persistAuthorization: true, + }, + customSiteTitle: 'Immich API Documentation', + }); + + // Generate API Documentation + const outputPath = path.resolve(process.cwd(), 'immich-openapi-specs.json'); + writeFileSync(outputPath, JSON.stringify(apiDocument), { encoding: 'utf8' }); + await app.listen(3001, () => { if (process.env.NODE_ENV == 'development') { Logger.log('Running Immich Server in DEVELOPMENT environment', 'ImmichServer'); diff --git a/server/apps/immich/src/modules/background-task/background-task.processor.ts b/server/apps/immich/src/modules/background-task/background-task.processor.ts index 5fa760c082..dfd11d2f30 100644 --- a/server/apps/immich/src/modules/background-task/background-task.processor.ts +++ b/server/apps/immich/src/modules/background-task/background-task.processor.ts @@ -5,6 +5,7 @@ import { AssetEntity } from '@app/database/entities/asset.entity'; import fs from 'fs'; import { SmartInfoEntity } from '@app/database/entities/smart-info.entity'; import { Job } from 'bull'; +import { AssetResponseDto } from '../../api-v1/asset/response-dto/asset-response.dto'; @Processor('background-task') export class BackgroundTaskProcessor { @@ -18,7 +19,7 @@ export class BackgroundTaskProcessor { // TODO: Should probably use constants / Interfaces for Queue names / data @Process('delete-file-on-disk') - async deleteFileOnDisk(job: Job<{ assets: AssetEntity[] }>) { + async deleteFileOnDisk(job: Job<{ assets: AssetResponseDto[] }>) { const { assets } = job.data; for (const asset of assets) { diff --git a/server/apps/immich/src/modules/background-task/background-task.service.ts b/server/apps/immich/src/modules/background-task/background-task.service.ts index 6b15b7ff6b..f73091ffb9 100644 --- a/server/apps/immich/src/modules/background-task/background-task.service.ts +++ b/server/apps/immich/src/modules/background-task/background-task.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common'; import { Queue } from 'bull'; import { randomUUID } from 'node:crypto'; import { AssetEntity } from '@app/database/entities/asset.entity'; +import { AssetResponseDto } from '../../api-v1/asset/response-dto/asset-response.dto'; @Injectable() export class BackgroundTaskService { @@ -11,7 +12,7 @@ export class BackgroundTaskService { private backgroundTaskQueue: Queue, ) {} - async deleteFileOnDisk(assets: AssetEntity[]) { + async deleteFileOnDisk(assets: AssetResponseDto[]) { await this.backgroundTaskQueue.add( 'delete-file-on-disk', { diff --git a/server/apps/microservices/src/processors/asset-uploaded.processor.ts b/server/apps/microservices/src/processors/asset-uploaded.processor.ts index 2aa5735d23..b7a75af428 100644 --- a/server/apps/microservices/src/processors/asset-uploaded.processor.ts +++ b/server/apps/microservices/src/processors/asset-uploaded.processor.ts @@ -63,7 +63,7 @@ export class AssetUploadedProcessor { } // Extract video duration if uploaded from the web & CLI - if (asset.type == AssetType.VIDEO && asset.duration == '0:00:00.000000') { + if (asset.type == AssetType.VIDEO) { await this.metadataExtractionQueue.add(videoMetadataExtractionProcessorName, { asset }, { jobId: randomUUID() }); } } diff --git a/server/immich-openapi-specs.json b/server/immich-openapi-specs.json new file mode 100644 index 0000000000..84e257f0d0 --- /dev/null +++ b/server/immich-openapi-specs.json @@ -0,0 +1 @@ +{"openapi":"3.0.0","paths":{"/user":{"get":{"operationId":"getAllUsers","parameters":[{"name":"isAll","required":true,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}}}}}},"tags":["User"],"security":[{"bearer":[]}]},"post":{"operationId":"createUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]},"put":{"operationId":"updateUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/me":{"get":{"operationId":"getMyUserInfo","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/count":{"get":{"operationId":"getUserCount","parameters":[{"name":"isAdmin","required":true,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCountResponseDto"}}}}},"tags":["User"]}},"/user/profile-image":{"post":{"operationId":"createProfileImage","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateProfileImageDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProfileImageResponseDto"}}}}},"tags":["User"],"security":[{"bearer":[]}]}},"/user/profile-image/{userId}":{"get":{"operationId":"getProfileImage","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["User"]}},"/asset/upload":{"post":{"operationId":"uploadFile","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssetDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"string"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/download":{"get":{"operationId":"downloadFile","parameters":[{"name":"aid","required":true,"in":"query","schema":{"title":"Device Asset ID","type":"string"}},{"name":"did","required":true,"in":"query","schema":{"title":"Device ID","type":"string"}},{"name":"isThumb","required":false,"in":"query","schema":{"type":"string"}},{"name":"isWeb","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/file":{"get":{"operationId":"serveFile","parameters":[{"name":"aid","required":true,"in":"query","schema":{"title":"Device Asset ID","type":"string"}},{"name":"did","required":true,"in":"query","schema":{"title":"Device ID","type":"string"}},{"name":"isThumb","required":false,"in":"query","schema":{"type":"string"}},{"name":"isWeb","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/thumbnail/{assetId}":{"get":{"operationId":"getAssetThumbnail","parameters":[{"name":"assetId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/allObjects":{"get":{"operationId":"getCuratedObjects","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CuratedObjectsResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/allLocation":{"get":{"operationId":"getCuratedLocations","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CuratedLocationsResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/searchTerm":{"get":{"operationId":"getAssetSearchTerms","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/search":{"post":{"operationId":"searchAsset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAssetDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset":{"get":{"operationId":"getAllAssets","summary":"","description":"Get all AssetEntity belong to the user","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]},"delete":{"operationId":"deleteAsset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAssetDto"}}}},"responses":{"200":{"description":""}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/{deviceId}":{"get":{"operationId":"getUserAssetsByDeviceId","summary":"","description":"Get all asset of a device that are in the database, ID only.","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/assetById/{assetId}":{"get":{"operationId":"getAssetById","summary":"","description":"Get a single asset's information","parameters":[{"name":"assetId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponseDto"}}}}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/asset/check":{"post":{"operationId":"checkDuplicateAsset","summary":"","description":"Check duplicated asset before uploading - for Web upload used","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDuplicateAssetDto"}}}},"responses":{"200":{"description":""}},"tags":["Asset"],"security":[{"bearer":[]}]}},"/auth/login":{"post":{"operationId":"login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginCredentialDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"tags":["Authentication"]}},"/auth/admin-sign-up":{"post":{"operationId":"adminSignUp","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSignupResponseDto"}}}},"400":{"description":"The server already has an admin"}},"tags":["Authentication"]}},"/auth/validateToken":{"post":{"operationId":"validateAccessToken","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateAccessTokenResponseDto"}}}}},"tags":["Authentication"],"security":[{"bearer":[]}]}},"/device-info":{"post":{"operationId":"createDeviceInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceInfoDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceInfoResponseDto"}}}}},"tags":["Device Info"],"security":[{"bearer":[]}]},"patch":{"operationId":"updateDeviceInfo","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceInfoDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceInfoResponseDto"}}}}},"tags":["Device Info"],"security":[{"bearer":[]}]}},"/server-info":{"get":{"operationId":"getServerInfo","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerInfoResponseDto"}}}}},"tags":["Server Info"]}},"/server-info/ping":{"get":{"operationId":"pingServer","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerPingResponse"}}}}},"tags":["Server Info"]}},"/server-info/version":{"get":{"operationId":"getServerVersion","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerVersionReponseDto"}}}}},"tags":["Server Info"]}},"/album":{"post":{"operationId":"createAlbum","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlbumDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"get":{"operationId":"getAllAlbums","parameters":[{"name":"shared","required":false,"in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/users":{"put":{"operationId":"addUsersToAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddUsersDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/assets":{"put":{"operationId":"addAssetsToAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddAssetsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"delete":{"operationId":"removeAssetFromAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveAssetsDto"}}}},"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}":{"get":{"operationId":"getAlbumInfo","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]},"delete":{"operationId":"deleteAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]},"patch":{"operationId":"updateAlbumInfo","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlbumDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumResponseDto"}}}}},"tags":["Album"],"security":[{"bearer":[]}]}},"/album/{albumId}/user/{userId}":{"delete":{"operationId":"removeUserFromAlbum","parameters":[{"name":"albumId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Album"],"security":[{"bearer":[]}]}}},"info":{"title":"Immich","description":"Immich API","version":"1.17.0","contact":{}},"tags":[],"servers":[{"url":"/api"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"JWT","description":"Enter JWT token","in":"header"}},"schemas":{"UserResponseDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"createdAt":{"type":"string"},"profileImagePath":{"type":"string"},"shouldChangePassword":{"type":"boolean"},"isAdmin":{"type":"boolean"}},"required":["id","email","firstName","lastName","createdAt","profileImagePath","shouldChangePassword","isAdmin"]},"CreateUserDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"},"firstName":{"type":"string","example":"John"},"lastName":{"type":"string","example":"Doe"}},"required":["email","password","firstName","lastName"]},"UserCountResponseDto":{"type":"object","properties":{"userCount":{"type":"number"}},"required":["userCount"]},"UpdateUserDto":{"type":"object","properties":{"id":{"type":"string"},"password":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"isAdmin":{"type":"boolean"},"shouldChangePassword":{"type":"boolean"},"profileImagePath":{"type":"string"}},"required":["id"]},"CreateProfileImageDto":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]},"CreateProfileImageResponseDto":{"type":"object","properties":{"userId":{"type":"string"},"profileImagePath":{"type":"string"}},"required":["userId","profileImagePath"]},"CreateAssetDto":{"type":"object","properties":{"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"},"assetType":{"type":"string","enum":["IMAGE","VIDEO","AUDIO","OTHER"]},"createdAt":{"type":"string"},"modifiedAt":{"type":"string"},"isFavorite":{"type":"boolean"},"fileExtension":{"type":"string"},"duration":{"type":"string"}},"required":["deviceAssetId","deviceId","assetType","createdAt","modifiedAt","isFavorite","fileExtension"]},"CuratedObjectsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string"},"resizePath":{"type":"string"},"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["id","object","resizePath","deviceAssetId","deviceId"]},"CuratedLocationsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"city":{"type":"string"},"resizePath":{"type":"string"},"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["id","city","resizePath","deviceAssetId","deviceId"]},"SearchAssetDto":{"type":"object","properties":{"searchTerm":{"type":"string"}},"required":["searchTerm"]},"ExifResponseDto":{"type":"object","properties":{"id":{"type":"string"},"make":{"type":"string","nullable":true,"default":null},"model":{"type":"string","nullable":true,"default":null},"imageName":{"type":"string","nullable":true,"default":null},"exifImageWidth":{"type":"number","nullable":true,"default":null},"exifImageHeight":{"type":"number","nullable":true,"default":null},"fileSizeInByte":{"type":"number","nullable":true,"default":null},"orientation":{"type":"string","nullable":true,"default":null},"dateTimeOriginal":{"format":"date-time","type":"string","nullable":true,"default":null},"modifyDate":{"format":"date-time","type":"string","nullable":true,"default":null},"lensModel":{"type":"string","nullable":true,"default":null},"fNumber":{"type":"number","nullable":true,"default":null},"focalLength":{"type":"number","nullable":true,"default":null},"iso":{"type":"number","nullable":true,"default":null},"exposureTime":{"type":"number","nullable":true,"default":null},"latitude":{"type":"number","nullable":true,"default":null},"longitude":{"type":"number","nullable":true,"default":null},"city":{"type":"string","nullable":true,"default":null},"state":{"type":"string","nullable":true,"default":null},"country":{"type":"string","nullable":true,"default":null}},"required":["id","make","model","imageName","exifImageWidth","exifImageHeight","fileSizeInByte","orientation","dateTimeOriginal","modifyDate","lensModel","fNumber","focalLength","iso","exposureTime","latitude","longitude","city","state","country"]},"SmartInfoResponseDto":{"type":"object","properties":{"id":{"type":"string"},"tags":{"nullable":true,"type":"array","items":{"type":"string"}},"objects":{"nullable":true,"type":"array","items":{"type":"string"}}}},"AssetResponseDto":{"type":"object","properties":{"id":{"type":"string"},"deviceAssetId":{"type":"string"},"ownerId":{"type":"string"},"deviceId":{"type":"string"},"type":{"enum":["IMAGE","VIDEO","AUDIO","OTHER"],"type":"string"},"originalPath":{"type":"string"},"resizePath":{"type":"string","nullable":true},"createdAt":{"type":"string"},"modifiedAt":{"type":"string"},"isFavorite":{"type":"boolean"},"mimeType":{"type":"string","nullable":true},"duration":{"type":"string"},"webpPath":{"type":"string","nullable":true},"encodedVideoPath":{"type":"string","nullable":true},"exifInfo":{"$ref":"#/components/schemas/ExifResponseDto"},"smartInfo":{"$ref":"#/components/schemas/SmartInfoResponseDto"}},"required":["id","deviceAssetId","ownerId","deviceId","type","originalPath","resizePath","createdAt","modifiedAt","isFavorite","mimeType","duration","webpPath","encodedVideoPath"]},"DeleteAssetDto":{"type":"object","properties":{"ids":{"title":"Array of asset IDs to delete","example":["bf973405-3f2a-48d2-a687-2ed4167164be","dd41870b-5d00-46d2-924e-1d8489a0aa0f","fad77c3f-deef-4e7e-9608-14c1aa4e559a"],"type":"array","items":{"type":"string"}}},"required":["ids"]},"CheckDuplicateAssetDto":{"type":"object","properties":{"deviceAssetId":{"type":"string"},"deviceId":{"type":"string"}},"required":["deviceAssetId","deviceId"]},"LoginCredentialDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"}},"required":["email","password"]},"LoginResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","readOnly":true},"userId":{"type":"string","readOnly":true},"userEmail":{"type":"string","readOnly":true},"firstName":{"type":"string","readOnly":true},"lastName":{"type":"string","readOnly":true},"profileImagePath":{"type":"string","readOnly":true},"isAdmin":{"type":"boolean","readOnly":true},"shouldChangePassword":{"type":"boolean","readOnly":true}},"required":["accessToken","userId","userEmail","firstName","lastName","profileImagePath","isAdmin","shouldChangePassword"]},"SignUpDto":{"type":"object","properties":{"email":{"type":"string","example":"testuser@email.com"},"password":{"type":"string","example":"password"},"firstName":{"type":"string","example":"Admin"},"lastName":{"type":"string","example":"Doe"}},"required":["email","password","firstName","lastName"]},"AdminSignupResponseDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","email","firstName","lastName","createdAt"]},"ValidateAccessTokenResponseDto":{"type":"object","properties":{}},"CreateDeviceInfoDto":{"type":"object","properties":{"deviceId":{"type":"string"},"deviceType":{"type":"string","enum":["IOS","ANDROID","WEB"]},"isAutoBackup":{"type":"boolean"}},"required":["deviceId","deviceType"]},"DeviceInfoResponseDto":{"type":"object","properties":{"id":{"type":"number"},"userId":{"type":"string"},"deviceId":{"type":"string"},"deviceType":{"enum":["IOS","ANDROID","WEB"],"type":"string"},"notificationToken":{"type":"string","nullable":true},"createdAt":{"type":"string"},"isAutoBackup":{"type":"boolean"}},"required":["id","userId","deviceId","deviceType","notificationToken","createdAt","isAutoBackup"]},"UpdateDeviceInfoDto":{"type":"object","properties":{}},"ServerInfoResponseDto":{"type":"object","properties":{"diskSize":{"type":"string"},"diskUse":{"type":"string"},"diskAvailable":{"type":"string"},"diskSizeRaw":{"type":"number"},"diskUseRaw":{"type":"number"},"diskAvailableRaw":{"type":"number"},"diskUsagePercentage":{"type":"number"}},"required":["diskSize","diskUse","diskAvailable","diskSizeRaw","diskUseRaw","diskAvailableRaw","diskUsagePercentage"]},"ServerPingResponse":{"type":"object","properties":{"res":{"type":"string","readOnly":true,"example":"pong"}},"required":["res"]},"ServerVersionReponseDto":{"type":"object","properties":{"major":{"type":"number"},"minor":{"type":"number"},"patch":{"type":"number"},"build":{"type":"number"}},"required":["major","minor","patch","build"]},"CreateAlbumDto":{"type":"object","properties":{"albumName":{"type":"string"},"sharedWithUserIds":{"type":"array","items":{"type":"string"}},"assetIds":{"type":"array","items":{"type":"string"}}},"required":["albumName"]},"AlbumResponseDto":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"type":"string"},"albumName":{"type":"string"},"createdAt":{"type":"string"},"albumThumbnailAssetId":{"type":"string","nullable":true},"shared":{"type":"boolean"},"sharedUsers":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}},"assets":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}},"required":["id","ownerId","albumName","createdAt","albumThumbnailAssetId","shared","sharedUsers","assets"]},"AddUsersDto":{"type":"object","properties":{"sharedUserIds":{"type":"array","items":{"type":"string"}}},"required":["sharedUserIds"]},"AddAssetsDto":{"type":"object","properties":{"assetIds":{"type":"array","items":{"type":"string"}}},"required":["assetIds"]},"RemoveAssetsDto":{"type":"object","properties":{"assetIds":{"type":"array","items":{"type":"string"}}},"required":["assetIds"]},"UpdateAlbumDto":{"type":"object","properties":{"albumName":{"type":"string"},"ownerId":{"type":"string"}},"required":["albumName","ownerId"]}}}} \ No newline at end of file diff --git a/server/nest-cli.json b/server/nest-cli.json index 5af76aff68..564b61f011 100644 --- a/server/nest-cli.json +++ b/server/nest-cli.json @@ -5,7 +5,14 @@ "root": "apps/immich", "compilerOptions": { "webpack": false, - "tsConfigPath": "apps/immich/tsconfig.app.json" + "tsConfigPath": "apps/immich/tsconfig.app.json", + "plugins": [ { + "name": "@nestjs/swagger", + "options": { + "classValidatorShim": false, + "introspectComments": true + } + }] }, "projects": { "immich": { @@ -45,4 +52,4 @@ } } } -} \ No newline at end of file +} diff --git a/server/openapitools.json b/server/openapitools.json new file mode 100644 index 0000000000..061a772190 --- /dev/null +++ b/server/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "6.0.1" + } +} diff --git a/server/package-lock.json b/server/package-lock.json index 0360e72828..3eaccf5162 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -21,6 +21,7 @@ "@nestjs/platform-fastify": "^8.4.7", "@nestjs/platform-socket.io": "^8.4.7", "@nestjs/schedule": "^2.0.1", + "@nestjs/swagger": "^5.2.1", "@nestjs/typeorm": "^8.1.4", "@nestjs/websockets": "^8.4.7", "@socket.io/redis-adapter": "^7.1.0", @@ -44,6 +45,7 @@ "rxjs": "^7.2.0", "sharp": "^0.28.0", "socket.io-redis": "^6.1.1", + "swagger-ui-express": "^4.4.0", "systeminformation": "^5.11.0", "typeorm": "^0.3.6" }, @@ -51,6 +53,7 @@ "@nestjs/cli": "^8.2.8", "@nestjs/schematics": "^8.0.11", "@nestjs/testing": "^8.4.7", + "@openapitools/openapi-generator-cli": "^2.5.1", "@types/bcrypt": "^5.0.0", "@types/bull": "^3.15.7", "@types/cron": "^2.0.0", @@ -1839,6 +1842,31 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/@nestjs/swagger": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-5.2.1.tgz", + "integrity": "sha512-7dNa08WCnTsW/oAk3Ujde+z64JMfNm19DhpXasFR8oJp/9pggYAbYU927HpA+GJsSFJX6adjIRZsCKUqaGWznw==", + "dependencies": { + "@nestjs/mapped-types": "1.0.1", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0", + "@nestjs/core": "^8.0.0", + "fastify-swagger": "*", + "reflect-metadata": "^0.1.12", + "swagger-ui-express": "*" + }, + "peerDependenciesMeta": { + "fastify-swagger": { + "optional": true + }, + "swagger-ui-express": { + "optional": true + } + } + }, "node_modules/@nestjs/testing": { "version": "8.4.7", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.7.tgz", @@ -1966,6 +1994,214 @@ "npm": ">=5.0.0" } }, + "node_modules/@openapitools/openapi-generator-cli": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.5.1.tgz", + "integrity": "sha512-WSRQBU0dCSVD+0Qv8iCsv0C4iMaZe/NpJ/CT4SmrEYLH3txoKTE8wEfbdj/kqShS8Or0YEGDPUzhSIKY151L0w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@nestjs/common": "8.4.4", + "@nestjs/core": "8.4.4", + "@nuxtjs/opencollective": "0.3.2", + "chalk": "4.1.2", + "commander": "8.3.0", + "compare-versions": "4.1.3", + "concurrently": "6.5.1", + "console.table": "0.10.0", + "fs-extra": "10.0.1", + "glob": "7.1.6", + "inquirer": "8.2.2", + "lodash": "4.17.21", + "reflect-metadata": "0.1.13", + "rxjs": "7.5.5", + "tslib": "2.0.3" + }, + "bin": { + "openapi-generator-cli": "main.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/openapi_generator" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/@nestjs/common": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-8.4.4.tgz", + "integrity": "sha512-QHi7QcgH/5Jinz+SCfIZJkFHc6Cch1YsAEGFEhi6wSp6MILb0sJMQ1CX06e9tCOAjSlBwaJj4PH0eFCVau5v9Q==", + "dev": true, + "dependencies": { + "axios": "0.26.1", + "iterare": "1.2.1", + "tslib": "2.3.1", + "uuid": "8.3.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "cache-manager": "*", + "class-transformer": "*", + "class-validator": "*", + "reflect-metadata": "^0.1.12", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "cache-manager": { + "optional": true + }, + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/@nestjs/common/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/@nestjs/core": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-8.4.4.tgz", + "integrity": "sha512-Ef3yJPuzAttpNfehnGqIV5kHIL9SHptB5F4ERxoU7pT61H3xiYpZw6hSjx68cJO7cc6rm7/N+b4zeuJvFHtvBg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@nuxtjs/opencollective": "0.3.2", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "object-hash": "3.0.0", + "path-to-regexp": "3.2.0", + "tslib": "2.3.1", + "uuid": "8.3.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0", + "@nestjs/microservices": "^8.0.0", + "@nestjs/platform-express": "^8.0.0", + "@nestjs/websockets": "^8.0.0", + "reflect-metadata": "^0.1.12", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + } + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/@nestjs/core/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/fs-extra": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/inquirer": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.2.tgz", + "integrity": "sha512-pG7I/si6K/0X7p1qU+rfWnpTE1UIkTONN1wxtzh0d+dHXtT/JG6qBgLxoyHVsQa8cFABxAPh0pD6uUUHiAoaow==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/rxjs/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + }, "node_modules/@sideway/address": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", @@ -3247,9 +3483,9 @@ } }, "node_modules/axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "dependencies": { "follow-redirects": "^1.14.8" } @@ -3989,6 +4225,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/compare-versions": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", + "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==", + "dev": true + }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -4040,6 +4282,61 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/concurrently": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", + "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "bin": { + "concurrently": "bin/concurrently.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/concurrently/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/consola": { "version": "2.15.3", "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", @@ -4050,6 +4347,18 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "node_modules/console.table": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", + "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", + "dev": true, + "dependencies": { + "easy-table": "1.1.0" + }, + "engines": { + "node": "> 0.10" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -4521,6 +4830,15 @@ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, + "node_modules/easy-table": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", + "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "dev": true, + "optionalDependencies": { + "wcwidth": ">=1.0.1" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -9737,6 +10055,12 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -9996,6 +10320,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz", + "integrity": "sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w==" + }, + "node_modules/swagger-ui-express": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.4.0.tgz", + "integrity": "sha512-1CzRkHG386VQMVZK406jcpgnW2a9A5A/NiAjKhsFTQqUBWRF+uGbXTU/mA7WSV3mTzyOQDvjBdWP/c2qd5lqKw==", + "dependencies": { + "swagger-ui-dist": ">=4.11.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0" + } + }, "node_modules/symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", @@ -12510,6 +12853,16 @@ } } }, + "@nestjs/swagger": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-5.2.1.tgz", + "integrity": "sha512-7dNa08WCnTsW/oAk3Ujde+z64JMfNm19DhpXasFR8oJp/9pggYAbYU927HpA+GJsSFJX6adjIRZsCKUqaGWznw==", + "requires": { + "@nestjs/mapped-types": "1.0.1", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0" + } + }, "@nestjs/testing": { "version": "8.4.7", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.7.tgz", @@ -12588,6 +12941,150 @@ "node-fetch": "^2.6.1" } }, + "@openapitools/openapi-generator-cli": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.5.1.tgz", + "integrity": "sha512-WSRQBU0dCSVD+0Qv8iCsv0C4iMaZe/NpJ/CT4SmrEYLH3txoKTE8wEfbdj/kqShS8Or0YEGDPUzhSIKY151L0w==", + "dev": true, + "requires": { + "@nestjs/common": "8.4.4", + "@nestjs/core": "8.4.4", + "@nuxtjs/opencollective": "0.3.2", + "chalk": "4.1.2", + "commander": "8.3.0", + "compare-versions": "4.1.3", + "concurrently": "6.5.1", + "console.table": "0.10.0", + "fs-extra": "10.0.1", + "glob": "7.1.6", + "inquirer": "8.2.2", + "lodash": "4.17.21", + "reflect-metadata": "0.1.13", + "rxjs": "7.5.5", + "tslib": "2.0.3" + }, + "dependencies": { + "@nestjs/common": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-8.4.4.tgz", + "integrity": "sha512-QHi7QcgH/5Jinz+SCfIZJkFHc6Cch1YsAEGFEhi6wSp6MILb0sJMQ1CX06e9tCOAjSlBwaJj4PH0eFCVau5v9Q==", + "dev": true, + "requires": { + "axios": "0.26.1", + "iterare": "1.2.1", + "tslib": "2.3.1", + "uuid": "8.3.2" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "@nestjs/core": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-8.4.4.tgz", + "integrity": "sha512-Ef3yJPuzAttpNfehnGqIV5kHIL9SHptB5F4ERxoU7pT61H3xiYpZw6hSjx68cJO7cc6rm7/N+b4zeuJvFHtvBg==", + "dev": true, + "requires": { + "@nuxtjs/opencollective": "0.3.2", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "object-hash": "3.0.0", + "path-to-regexp": "3.2.0", + "tslib": "2.3.1", + "uuid": "8.3.2" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + }, + "fs-extra": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "inquirer": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.2.tgz", + "integrity": "sha512-pG7I/si6K/0X7p1qU+rfWnpTE1UIkTONN1wxtzh0d+dHXtT/JG6qBgLxoyHVsQa8cFABxAPh0pD6uUUHiAoaow==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + } + } + }, + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } + }, "@sideway/address": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", @@ -13697,9 +14194,9 @@ } }, "axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "requires": { "follow-redirects": "^1.14.8" } @@ -14259,6 +14756,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "compare-versions": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", + "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==", + "dev": true + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -14309,6 +14812,48 @@ } } }, + "concurrently": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", + "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "consola": { "version": "2.15.3", "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", @@ -14319,6 +14864,15 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "console.table": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", + "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", + "dev": true, + "requires": { + "easy-table": "1.1.0" + } + }, "content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -14683,6 +15237,15 @@ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, + "easy-table": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", + "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "dev": true, + "requires": { + "wcwidth": ">=1.0.1" + } + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -18655,6 +19218,12 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -18858,6 +19427,19 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "swagger-ui-dist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz", + "integrity": "sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w==" + }, + "swagger-ui-express": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.4.0.tgz", + "integrity": "sha512-1CzRkHG386VQMVZK406jcpgnW2a9A5A/NiAjKhsFTQqUBWRF+uGbXTU/mA7WSV3mTzyOQDvjBdWP/c2qd5lqKw==", + "requires": { + "swagger-ui-dist": ">=4.11.0" + } + }, "symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", diff --git a/server/package.json b/server/package.json index d43a7b49bd..434fe0911e 100644 --- a/server/package.json +++ b/server/package.json @@ -22,7 +22,8 @@ "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./apps/immich/test/jest-e2e.json", - "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js" + "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js", + "api:generate-typescript": "rm -rf ../web/src/lib/open-api && npx openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ../web/src/lib/open-api" }, "dependencies": { "@mapbox/mapbox-sdk": "^0.13.3", @@ -37,6 +38,7 @@ "@nestjs/platform-fastify": "^8.4.7", "@nestjs/platform-socket.io": "^8.4.7", "@nestjs/schedule": "^2.0.1", + "@nestjs/swagger": "^5.2.1", "@nestjs/typeorm": "^8.1.4", "@nestjs/websockets": "^8.4.7", "@socket.io/redis-adapter": "^7.1.0", @@ -60,6 +62,7 @@ "rxjs": "^7.2.0", "sharp": "^0.28.0", "socket.io-redis": "^6.1.1", + "swagger-ui-express": "^4.4.0", "systeminformation": "^5.11.0", "typeorm": "^0.3.6" }, @@ -83,6 +86,7 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", + "@openapitools/openapi-generator-cli": "2.5.1", "eslint": "^8.0.1", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", @@ -124,4 +128,4 @@ "^@app/job(|/.*)$": "/libs/job/src/$1" } } -} \ No newline at end of file +} diff --git a/web/.eslintrc.cjs b/web/.eslintrc.cjs index 3ccf435f02..68be379b91 100644 --- a/web/.eslintrc.cjs +++ b/web/.eslintrc.cjs @@ -6,15 +6,15 @@ module.exports = { ignorePatterns: ['*.cjs'], overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], settings: { - 'svelte3/typescript': () => require('typescript') + 'svelte3/typescript': () => require('typescript'), }, parserOptions: { sourceType: 'module', - ecmaVersion: 2020 + ecmaVersion: 2020, }, env: { browser: true, es2017: true, - node: true - } + node: true, + }, }; diff --git a/web/src/lib/immich-api/index.ts b/web/src/lib/immich-api/index.ts new file mode 100644 index 0000000000..6441bec67f --- /dev/null +++ b/web/src/lib/immich-api/index.ts @@ -0,0 +1,34 @@ +import { + AlbumApi, + AssetApi, + AuthenticationApi, + Configuration, + DeviceInfoApi, + ServerInfoApi, + UserApi, +} from '../open-api'; + +class ImmichApi { + public userApi: UserApi; + public albumApi: AlbumApi; + public assetApi: AssetApi; + public authenticationApi: AuthenticationApi; + public deviceInfoApi: DeviceInfoApi; + public serverInfoApi: ServerInfoApi; + private config = new Configuration(); + + constructor() { + this.userApi = new UserApi(this.config); + this.albumApi = new AlbumApi(this.config); + this.assetApi = new AssetApi(this.config); + this.authenticationApi = new AuthenticationApi(this.config); + this.deviceInfoApi = new DeviceInfoApi(this.config); + this.serverInfoApi = new ServerInfoApi(this.config); + } + + public setAccessToken(accessToken: string) { + this.config.accessToken = accessToken; + } +} + +export const immichApi = new ImmichApi(); diff --git a/web/src/lib/open-api/.gitignore b/web/src/lib/open-api/.gitignore new file mode 100644 index 0000000000..149b576547 --- /dev/null +++ b/web/src/lib/open-api/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/web/src/lib/open-api/.npmignore b/web/src/lib/open-api/.npmignore new file mode 100644 index 0000000000..999d88df69 --- /dev/null +++ b/web/src/lib/open-api/.npmignore @@ -0,0 +1 @@ +# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm \ No newline at end of file diff --git a/web/src/lib/open-api/.openapi-generator-ignore b/web/src/lib/open-api/.openapi-generator-ignore new file mode 100644 index 0000000000..7484ee590a --- /dev/null +++ b/web/src/lib/open-api/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/web/src/lib/open-api/.openapi-generator/FILES b/web/src/lib/open-api/.openapi-generator/FILES new file mode 100644 index 0000000000..16b445eee6 --- /dev/null +++ b/web/src/lib/open-api/.openapi-generator/FILES @@ -0,0 +1,9 @@ +.gitignore +.npmignore +.openapi-generator-ignore +api.ts +base.ts +common.ts +configuration.ts +git_push.sh +index.ts diff --git a/web/src/lib/open-api/.openapi-generator/VERSION b/web/src/lib/open-api/.openapi-generator/VERSION new file mode 100644 index 0000000000..6d54bbd775 --- /dev/null +++ b/web/src/lib/open-api/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.0.1 \ No newline at end of file diff --git a/web/src/lib/open-api/api.ts b/web/src/lib/open-api/api.ts new file mode 100644 index 0000000000..46b0b25834 --- /dev/null +++ b/web/src/lib/open-api/api.ts @@ -0,0 +1,3874 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.17.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import { Configuration } from './configuration'; +import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from './common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base'; + +/** + * + * @export + * @interface AddAssetsDto + */ +export interface AddAssetsDto { + /** + * + * @type {Array} + * @memberof AddAssetsDto + */ + 'assetIds': Array; +} +/** + * + * @export + * @interface AddUsersDto + */ +export interface AddUsersDto { + /** + * + * @type {Array} + * @memberof AddUsersDto + */ + 'sharedUserIds': Array; +} +/** + * + * @export + * @interface AdminSignupResponseDto + */ +export interface AdminSignupResponseDto { + /** + * + * @type {string} + * @memberof AdminSignupResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof AdminSignupResponseDto + */ + 'email': string; + /** + * + * @type {string} + * @memberof AdminSignupResponseDto + */ + 'firstName': string; + /** + * + * @type {string} + * @memberof AdminSignupResponseDto + */ + 'lastName': string; + /** + * + * @type {string} + * @memberof AdminSignupResponseDto + */ + 'createdAt': string; +} +/** + * + * @export + * @interface AlbumResponseDto + */ +export interface AlbumResponseDto { + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + 'ownerId': string; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + 'albumName': string; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + 'createdAt': string; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + 'albumThumbnailAssetId': string | null; + /** + * + * @type {boolean} + * @memberof AlbumResponseDto + */ + 'shared': boolean; + /** + * + * @type {Array} + * @memberof AlbumResponseDto + */ + 'sharedUsers': Array; + /** + * + * @type {Array} + * @memberof AlbumResponseDto + */ + 'assets': Array; +} +/** + * + * @export + * @interface AssetResponseDto + */ +export interface AssetResponseDto { + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'deviceAssetId': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'ownerId': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'deviceId': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'type': AssetResponseDtoTypeEnum; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'originalPath': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'resizePath': string | null; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'createdAt': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'modifiedAt': string; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + 'isFavorite': boolean; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'mimeType': string | null; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'duration': string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'webpPath': string | null; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + 'encodedVideoPath': string | null; + /** + * + * @type {ExifResponseDto} + * @memberof AssetResponseDto + */ + 'exifInfo'?: ExifResponseDto; + /** + * + * @type {SmartInfoResponseDto} + * @memberof AssetResponseDto + */ + 'smartInfo'?: SmartInfoResponseDto; +} + +export const AssetResponseDtoTypeEnum = { + Image: 'IMAGE', + Video: 'VIDEO', + Audio: 'AUDIO', + Other: 'OTHER' +} as const; + +export type AssetResponseDtoTypeEnum = typeof AssetResponseDtoTypeEnum[keyof typeof AssetResponseDtoTypeEnum]; + +/** + * + * @export + * @interface CheckDuplicateAssetDto + */ +export interface CheckDuplicateAssetDto { + /** + * + * @type {string} + * @memberof CheckDuplicateAssetDto + */ + 'deviceAssetId': string; + /** + * + * @type {string} + * @memberof CheckDuplicateAssetDto + */ + 'deviceId': string; +} +/** + * + * @export + * @interface CreateAlbumDto + */ +export interface CreateAlbumDto { + /** + * + * @type {string} + * @memberof CreateAlbumDto + */ + 'albumName': string; + /** + * + * @type {Array} + * @memberof CreateAlbumDto + */ + 'sharedWithUserIds'?: Array; + /** + * + * @type {Array} + * @memberof CreateAlbumDto + */ + 'assetIds'?: Array; +} +/** + * + * @export + * @interface CreateAssetDto + */ +export interface CreateAssetDto { + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'deviceAssetId': string; + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'deviceId': string; + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'assetType': CreateAssetDtoAssetTypeEnum; + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'createdAt': string; + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'modifiedAt': string; + /** + * + * @type {boolean} + * @memberof CreateAssetDto + */ + 'isFavorite': boolean; + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'fileExtension': string; + /** + * + * @type {string} + * @memberof CreateAssetDto + */ + 'duration'?: string; +} + +export const CreateAssetDtoAssetTypeEnum = { + Image: 'IMAGE', + Video: 'VIDEO', + Audio: 'AUDIO', + Other: 'OTHER' +} as const; + +export type CreateAssetDtoAssetTypeEnum = typeof CreateAssetDtoAssetTypeEnum[keyof typeof CreateAssetDtoAssetTypeEnum]; + +/** + * + * @export + * @interface CreateDeviceInfoDto + */ +export interface CreateDeviceInfoDto { + /** + * + * @type {string} + * @memberof CreateDeviceInfoDto + */ + 'deviceId': string; + /** + * + * @type {string} + * @memberof CreateDeviceInfoDto + */ + 'deviceType': CreateDeviceInfoDtoDeviceTypeEnum; + /** + * + * @type {boolean} + * @memberof CreateDeviceInfoDto + */ + 'isAutoBackup'?: boolean; +} + +export const CreateDeviceInfoDtoDeviceTypeEnum = { + Ios: 'IOS', + Android: 'ANDROID', + Web: 'WEB' +} as const; + +export type CreateDeviceInfoDtoDeviceTypeEnum = typeof CreateDeviceInfoDtoDeviceTypeEnum[keyof typeof CreateDeviceInfoDtoDeviceTypeEnum]; + +/** + * + * @export + * @interface CreateProfileImageResponseDto + */ +export interface CreateProfileImageResponseDto { + /** + * + * @type {string} + * @memberof CreateProfileImageResponseDto + */ + 'userId': string; + /** + * + * @type {string} + * @memberof CreateProfileImageResponseDto + */ + 'profileImagePath': string; +} +/** + * + * @export + * @interface CreateUserDto + */ +export interface CreateUserDto { + /** + * + * @type {string} + * @memberof CreateUserDto + */ + 'email': string; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + 'password': string; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + 'firstName': string; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + 'lastName': string; +} +/** + * + * @export + * @interface CuratedLocationsResponseDto + */ +export interface CuratedLocationsResponseDto { + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + 'city': string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + 'resizePath': string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + 'deviceAssetId': string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + 'deviceId': string; +} +/** + * + * @export + * @interface CuratedObjectsResponseDto + */ +export interface CuratedObjectsResponseDto { + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + 'object': string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + 'resizePath': string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + 'deviceAssetId': string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + 'deviceId': string; +} +/** + * + * @export + * @interface DeleteAssetDto + */ +export interface DeleteAssetDto { + /** + * + * @type {Array} + * @memberof DeleteAssetDto + */ + 'ids': Array; +} +/** + * + * @export + * @interface DeviceInfoResponseDto + */ +export interface DeviceInfoResponseDto { + /** + * + * @type {number} + * @memberof DeviceInfoResponseDto + */ + 'id': number; + /** + * + * @type {string} + * @memberof DeviceInfoResponseDto + */ + 'userId': string; + /** + * + * @type {string} + * @memberof DeviceInfoResponseDto + */ + 'deviceId': string; + /** + * + * @type {string} + * @memberof DeviceInfoResponseDto + */ + 'deviceType': DeviceInfoResponseDtoDeviceTypeEnum; + /** + * + * @type {string} + * @memberof DeviceInfoResponseDto + */ + 'notificationToken': string | null; + /** + * + * @type {string} + * @memberof DeviceInfoResponseDto + */ + 'createdAt': string; + /** + * + * @type {boolean} + * @memberof DeviceInfoResponseDto + */ + 'isAutoBackup': boolean; +} + +export const DeviceInfoResponseDtoDeviceTypeEnum = { + Ios: 'IOS', + Android: 'ANDROID', + Web: 'WEB' +} as const; + +export type DeviceInfoResponseDtoDeviceTypeEnum = typeof DeviceInfoResponseDtoDeviceTypeEnum[keyof typeof DeviceInfoResponseDtoDeviceTypeEnum]; + +/** + * + * @export + * @interface ExifResponseDto + */ +export interface ExifResponseDto { + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'make': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'model': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'imageName': string | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'exifImageWidth': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'exifImageHeight': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'fileSizeInByte': number | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'orientation': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'dateTimeOriginal': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'modifyDate': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'lensModel': string | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'fNumber': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'focalLength': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'iso': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'exposureTime': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'latitude': number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + 'longitude': number | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'city': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'state': string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + 'country': string | null; +} +/** + * + * @export + * @interface LoginCredentialDto + */ +export interface LoginCredentialDto { + /** + * + * @type {string} + * @memberof LoginCredentialDto + */ + 'email': string; + /** + * + * @type {string} + * @memberof LoginCredentialDto + */ + 'password': string; +} +/** + * + * @export + * @interface LoginResponseDto + */ +export interface LoginResponseDto { + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + 'accessToken': string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + 'userId': string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + 'userEmail': string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + 'firstName': string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + 'lastName': string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + 'profileImagePath': string; + /** + * + * @type {boolean} + * @memberof LoginResponseDto + */ + 'isAdmin': boolean; + /** + * + * @type {boolean} + * @memberof LoginResponseDto + */ + 'shouldChangePassword': boolean; +} +/** + * + * @export + * @interface RemoveAssetsDto + */ +export interface RemoveAssetsDto { + /** + * + * @type {Array} + * @memberof RemoveAssetsDto + */ + 'assetIds': Array; +} +/** + * + * @export + * @interface SearchAssetDto + */ +export interface SearchAssetDto { + /** + * + * @type {string} + * @memberof SearchAssetDto + */ + 'searchTerm': string; +} +/** + * + * @export + * @interface ServerInfoResponseDto + */ +export interface ServerInfoResponseDto { + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + 'diskSize': string; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + 'diskUse': string; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + 'diskAvailable': string; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + 'diskSizeRaw': number; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + 'diskUseRaw': number; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + 'diskAvailableRaw': number; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + 'diskUsagePercentage': number; +} +/** + * + * @export + * @interface ServerPingResponse + */ +export interface ServerPingResponse { + /** + * + * @type {string} + * @memberof ServerPingResponse + */ + 'res': string; +} +/** + * + * @export + * @interface ServerVersionReponseDto + */ +export interface ServerVersionReponseDto { + /** + * + * @type {number} + * @memberof ServerVersionReponseDto + */ + 'major': number; + /** + * + * @type {number} + * @memberof ServerVersionReponseDto + */ + 'minor': number; + /** + * + * @type {number} + * @memberof ServerVersionReponseDto + */ + 'patch': number; + /** + * + * @type {number} + * @memberof ServerVersionReponseDto + */ + 'build': number; +} +/** + * + * @export + * @interface SignUpDto + */ +export interface SignUpDto { + /** + * + * @type {string} + * @memberof SignUpDto + */ + 'email': string; + /** + * + * @type {string} + * @memberof SignUpDto + */ + 'password': string; + /** + * + * @type {string} + * @memberof SignUpDto + */ + 'firstName': string; + /** + * + * @type {string} + * @memberof SignUpDto + */ + 'lastName': string; +} +/** + * + * @export + * @interface SmartInfoResponseDto + */ +export interface SmartInfoResponseDto { + /** + * + * @type {string} + * @memberof SmartInfoResponseDto + */ + 'id'?: string; + /** + * + * @type {Array} + * @memberof SmartInfoResponseDto + */ + 'tags'?: Array | null; + /** + * + * @type {Array} + * @memberof SmartInfoResponseDto + */ + 'objects'?: Array | null; +} +/** + * + * @export + * @interface UpdateAlbumDto + */ +export interface UpdateAlbumDto { + /** + * + * @type {string} + * @memberof UpdateAlbumDto + */ + 'albumName': string; + /** + * + * @type {string} + * @memberof UpdateAlbumDto + */ + 'ownerId': string; +} +/** + * + * @export + * @interface UpdateUserDto + */ +export interface UpdateUserDto { + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + 'password'?: string; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + 'firstName'?: string; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + 'lastName'?: string; + /** + * + * @type {boolean} + * @memberof UpdateUserDto + */ + 'isAdmin'?: boolean; + /** + * + * @type {boolean} + * @memberof UpdateUserDto + */ + 'shouldChangePassword'?: boolean; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + 'profileImagePath'?: string; +} +/** + * + * @export + * @interface UserCountResponseDto + */ +export interface UserCountResponseDto { + /** + * + * @type {number} + * @memberof UserCountResponseDto + */ + 'userCount': number; +} +/** + * + * @export + * @interface UserResponseDto + */ +export interface UserResponseDto { + /** + * + * @type {string} + * @memberof UserResponseDto + */ + 'id': string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + 'email': string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + 'firstName': string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + 'lastName': string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + 'createdAt': string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + 'profileImagePath': string; + /** + * + * @type {boolean} + * @memberof UserResponseDto + */ + 'shouldChangePassword': boolean; + /** + * + * @type {boolean} + * @memberof UserResponseDto + */ + 'isAdmin': boolean; +} + +/** + * AlbumApi - axios parameter creator + * @export + */ +export const AlbumApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {string} albumId + * @param {AddAssetsDto} addAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addAssetsToAlbum: async (albumId: string, addAssetsDto: AddAssetsDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('addAssetsToAlbum', 'albumId', albumId) + // verify required parameter 'addAssetsDto' is not null or undefined + assertParamExists('addAssetsToAlbum', 'addAssetsDto', addAssetsDto) + const localVarPath = `/album/{albumId}/assets` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))); + // 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 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(addAssetsDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} albumId + * @param {AddUsersDto} addUsersDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addUsersToAlbum: async (albumId: string, addUsersDto: AddUsersDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('addUsersToAlbum', 'albumId', albumId) + // verify required parameter 'addUsersDto' is not null or undefined + assertParamExists('addUsersToAlbum', 'addUsersDto', addUsersDto) + const localVarPath = `/album/{albumId}/users` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))); + // 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 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(addUsersDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {CreateAlbumDto} createAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createAlbum: async (createAlbumDto: CreateAlbumDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'createAlbumDto' is not null or undefined + assertParamExists('createAlbum', 'createAlbumDto', createAlbumDto) + const localVarPath = `/album`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(createAlbumDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteAlbum: async (albumId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('deleteAlbum', 'albumId', albumId) + const localVarPath = `/album/{albumId}` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))); + // 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 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} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAlbumInfo: async (albumId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('getAlbumInfo', 'albumId', albumId) + const localVarPath = `/album/{albumId}` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))); + // 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 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 {boolean} [shared] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllAlbums: async (shared?: boolean, options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/album`; + // 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 bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + if (shared !== undefined) { + localVarQueryParameter['shared'] = shared; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} albumId + * @param {RemoveAssetsDto} removeAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeAssetFromAlbum: async (albumId: string, removeAssetsDto: RemoveAssetsDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('removeAssetFromAlbum', 'albumId', albumId) + // verify required parameter 'removeAssetsDto' is not null or undefined + assertParamExists('removeAssetFromAlbum', 'removeAssetsDto', removeAssetsDto) + const localVarPath = `/album/{albumId}/assets` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))); + // 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 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(removeAssetsDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} albumId + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeUserFromAlbum: async (albumId: string, userId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('removeUserFromAlbum', 'albumId', albumId) + // verify required parameter 'userId' is not null or undefined + assertParamExists('removeUserFromAlbum', 'userId', userId) + const localVarPath = `/album/{albumId}/user/{userId}` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))) + .replace(`{${"userId"}}`, encodeURIComponent(String(userId))); + // 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 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} albumId + * @param {UpdateAlbumDto} updateAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateAlbumInfo: async (albumId: string, updateAlbumDto: UpdateAlbumDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'albumId' is not null or undefined + assertParamExists('updateAlbumInfo', 'albumId', albumId) + // verify required parameter 'updateAlbumDto' is not null or undefined + assertParamExists('updateAlbumInfo', 'updateAlbumDto', updateAlbumDto) + const localVarPath = `/album/{albumId}` + .replace(`{${"albumId"}}`, encodeURIComponent(String(albumId))); + // 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: 'PATCH', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(updateAlbumDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * AlbumApi - functional programming interface + * @export + */ +export const AlbumApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AlbumApiAxiosParamCreator(configuration) + return { + /** + * + * @param {string} albumId + * @param {AddAssetsDto} addAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async addAssetsToAlbum(albumId: string, addAssetsDto: AddAssetsDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.addAssetsToAlbum(albumId, addAssetsDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} albumId + * @param {AddUsersDto} addUsersDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async addUsersToAlbum(albumId: string, addUsersDto: AddUsersDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.addUsersToAlbum(albumId, addUsersDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {CreateAlbumDto} createAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createAlbum(createAlbumDto: CreateAlbumDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createAlbum(createAlbumDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteAlbum(albumId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAlbum(albumId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAlbumInfo(albumId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAlbumInfo(albumId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {boolean} [shared] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAllAlbums(shared?: boolean, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAlbums(shared, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} albumId + * @param {RemoveAssetsDto} removeAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async removeAssetFromAlbum(albumId: string, removeAssetsDto: RemoveAssetsDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.removeAssetFromAlbum(albumId, removeAssetsDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} albumId + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async removeUserFromAlbum(albumId: string, userId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.removeUserFromAlbum(albumId, userId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} albumId + * @param {UpdateAlbumDto} updateAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateAlbumInfo(albumId: string, updateAlbumDto: UpdateAlbumDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateAlbumInfo(albumId, updateAlbumDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * AlbumApi - factory interface + * @export + */ +export const AlbumApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AlbumApiFp(configuration) + return { + /** + * + * @param {string} albumId + * @param {AddAssetsDto} addAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addAssetsToAlbum(albumId: string, addAssetsDto: AddAssetsDto, options?: any): AxiosPromise { + return localVarFp.addAssetsToAlbum(albumId, addAssetsDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} albumId + * @param {AddUsersDto} addUsersDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addUsersToAlbum(albumId: string, addUsersDto: AddUsersDto, options?: any): AxiosPromise { + return localVarFp.addUsersToAlbum(albumId, addUsersDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {CreateAlbumDto} createAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createAlbum(createAlbumDto: CreateAlbumDto, options?: any): AxiosPromise { + return localVarFp.createAlbum(createAlbumDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteAlbum(albumId: string, options?: any): AxiosPromise { + return localVarFp.deleteAlbum(albumId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAlbumInfo(albumId: string, options?: any): AxiosPromise { + return localVarFp.getAlbumInfo(albumId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {boolean} [shared] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllAlbums(shared?: boolean, options?: any): AxiosPromise> { + return localVarFp.getAllAlbums(shared, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} albumId + * @param {RemoveAssetsDto} removeAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeAssetFromAlbum(albumId: string, removeAssetsDto: RemoveAssetsDto, options?: any): AxiosPromise { + return localVarFp.removeAssetFromAlbum(albumId, removeAssetsDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} albumId + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeUserFromAlbum(albumId: string, userId: string, options?: any): AxiosPromise { + return localVarFp.removeUserFromAlbum(albumId, userId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} albumId + * @param {UpdateAlbumDto} updateAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateAlbumInfo(albumId: string, updateAlbumDto: UpdateAlbumDto, options?: any): AxiosPromise { + return localVarFp.updateAlbumInfo(albumId, updateAlbumDto, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AlbumApi - object-oriented interface + * @export + * @class AlbumApi + * @extends {BaseAPI} + */ +export class AlbumApi extends BaseAPI { + /** + * + * @param {string} albumId + * @param {AddAssetsDto} addAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public addAssetsToAlbum(albumId: string, addAssetsDto: AddAssetsDto, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).addAssetsToAlbum(albumId, addAssetsDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} albumId + * @param {AddUsersDto} addUsersDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public addUsersToAlbum(albumId: string, addUsersDto: AddUsersDto, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).addUsersToAlbum(albumId, addUsersDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {CreateAlbumDto} createAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public createAlbum(createAlbumDto: CreateAlbumDto, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).createAlbum(createAlbumDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public deleteAlbum(albumId: string, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).deleteAlbum(albumId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} albumId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public getAlbumInfo(albumId: string, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).getAlbumInfo(albumId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {boolean} [shared] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public getAllAlbums(shared?: boolean, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).getAllAlbums(shared, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} albumId + * @param {RemoveAssetsDto} removeAssetsDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public removeAssetFromAlbum(albumId: string, removeAssetsDto: RemoveAssetsDto, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).removeAssetFromAlbum(albumId, removeAssetsDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} albumId + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public removeUserFromAlbum(albumId: string, userId: string, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).removeUserFromAlbum(albumId, userId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} albumId + * @param {UpdateAlbumDto} updateAlbumDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AlbumApi + */ + public updateAlbumInfo(albumId: string, updateAlbumDto: UpdateAlbumDto, options?: AxiosRequestConfig) { + return AlbumApiFp(this.configuration).updateAlbumInfo(albumId, updateAlbumDto, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * AssetApi - axios parameter creator + * @export + */ +export const AssetApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Check duplicated asset before uploading - for Web upload used + * @summary + * @param {CheckDuplicateAssetDto} checkDuplicateAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + checkDuplicateAsset: async (checkDuplicateAssetDto: CheckDuplicateAssetDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'checkDuplicateAssetDto' is not null or undefined + assertParamExists('checkDuplicateAsset', 'checkDuplicateAssetDto', checkDuplicateAssetDto) + const localVarPath = `/asset/check`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(checkDuplicateAssetDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {DeleteAssetDto} deleteAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteAsset: async (deleteAssetDto: DeleteAssetDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'deleteAssetDto' is not null or undefined + assertParamExists('deleteAsset', 'deleteAssetDto', deleteAssetDto) + const localVarPath = `/asset`; + // 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 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(deleteAssetDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + downloadFile: async (aid: string, did: string, isThumb?: string, isWeb?: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'aid' is not null or undefined + assertParamExists('downloadFile', 'aid', aid) + // verify required parameter 'did' is not null or undefined + assertParamExists('downloadFile', 'did', did) + const localVarPath = `/asset/download`; + // 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 bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + if (aid !== undefined) { + localVarQueryParameter['aid'] = aid; + } + + if (did !== undefined) { + localVarQueryParameter['did'] = did; + } + + if (isThumb !== undefined) { + localVarQueryParameter['isThumb'] = isThumb; + } + + if (isWeb !== undefined) { + localVarQueryParameter['isWeb'] = isWeb; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get all AssetEntity belong to the user + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllAssets: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/asset`; + // 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 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, + }; + }, + /** + * Get a single asset\'s information + * @summary + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAssetById: async (assetId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'assetId' is not null or undefined + assertParamExists('getAssetById', 'assetId', assetId) + const localVarPath = `/asset/assetById/{assetId}` + .replace(`{${"assetId"}}`, encodeURIComponent(String(assetId))); + // 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 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} + */ + getAssetSearchTerms: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/asset/searchTerm`; + // 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 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} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAssetThumbnail: async (assetId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'assetId' is not null or undefined + assertParamExists('getAssetThumbnail', 'assetId', assetId) + const localVarPath = `/asset/thumbnail/{assetId}` + .replace(`{${"assetId"}}`, encodeURIComponent(String(assetId))); + // 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 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} + */ + getCuratedLocations: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/asset/allLocation`; + // 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 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} + */ + getCuratedObjects: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/asset/allObjects`; + // 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 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, + }; + }, + /** + * Get all asset of a device that are in the database, ID only. + * @summary + * @param {string} deviceId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserAssetsByDeviceId: async (deviceId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'deviceId' is not null or undefined + assertParamExists('getUserAssetsByDeviceId', 'deviceId', deviceId) + const localVarPath = `/asset/{deviceId}` + .replace(`{${"deviceId"}}`, encodeURIComponent(String(deviceId))); + // 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 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 {SearchAssetDto} searchAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + searchAsset: async (searchAssetDto: SearchAssetDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'searchAssetDto' is not null or undefined + assertParamExists('searchAsset', 'searchAssetDto', searchAssetDto) + const localVarPath = `/asset/search`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(searchAssetDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + serveFile: async (aid: string, did: string, isThumb?: string, isWeb?: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'aid' is not null or undefined + assertParamExists('serveFile', 'aid', aid) + // verify required parameter 'did' is not null or undefined + assertParamExists('serveFile', 'did', did) + const localVarPath = `/asset/file`; + // 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 bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + if (aid !== undefined) { + localVarQueryParameter['aid'] = aid; + } + + if (did !== undefined) { + localVarQueryParameter['did'] = did; + } + + if (isThumb !== undefined) { + localVarQueryParameter['isThumb'] = isThumb; + } + + if (isWeb !== undefined) { + localVarQueryParameter['isWeb'] = isWeb; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {CreateAssetDto} createAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + uploadFile: async (createAssetDto: CreateAssetDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'createAssetDto' is not null or undefined + assertParamExists('uploadFile', 'createAssetDto', createAssetDto) + const localVarPath = `/asset/upload`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(createAssetDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * AssetApi - functional programming interface + * @export + */ +export const AssetApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AssetApiAxiosParamCreator(configuration) + return { + /** + * Check duplicated asset before uploading - for Web upload used + * @summary + * @param {CheckDuplicateAssetDto} checkDuplicateAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async checkDuplicateAsset(checkDuplicateAssetDto: CheckDuplicateAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.checkDuplicateAsset(checkDuplicateAssetDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {DeleteAssetDto} deleteAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteAsset(deleteAssetDto: DeleteAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAsset(deleteAssetDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async downloadFile(aid: string, did: string, isThumb?: string, isWeb?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.downloadFile(aid, did, isThumb, isWeb, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Get all AssetEntity belong to the user + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAllAssets(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Get a single asset\'s information + * @summary + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAssetById(assetId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetById(assetId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetSearchTerms(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAssetThumbnail(assetId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetThumbnail(assetId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCuratedLocations(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCuratedLocations(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCuratedObjects(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCuratedObjects(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Get all asset of a device that are in the database, ID only. + * @summary + * @param {string} deviceId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserAssetsByDeviceId(deviceId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserAssetsByDeviceId(deviceId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {SearchAssetDto} searchAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async searchAsset(searchAssetDto: SearchAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.searchAsset(searchAssetDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async serveFile(aid: string, did: string, isThumb?: string, isWeb?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.serveFile(aid, did, isThumb, isWeb, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {CreateAssetDto} createAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async uploadFile(createAssetDto: CreateAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFile(createAssetDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * AssetApi - factory interface + * @export + */ +export const AssetApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AssetApiFp(configuration) + return { + /** + * Check duplicated asset before uploading - for Web upload used + * @summary + * @param {CheckDuplicateAssetDto} checkDuplicateAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + checkDuplicateAsset(checkDuplicateAssetDto: CheckDuplicateAssetDto, options?: any): AxiosPromise { + return localVarFp.checkDuplicateAsset(checkDuplicateAssetDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {DeleteAssetDto} deleteAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteAsset(deleteAssetDto: DeleteAssetDto, options?: any): AxiosPromise { + return localVarFp.deleteAsset(deleteAssetDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + downloadFile(aid: string, did: string, isThumb?: string, isWeb?: string, options?: any): AxiosPromise { + return localVarFp.downloadFile(aid, did, isThumb, isWeb, options).then((request) => request(axios, basePath)); + }, + /** + * Get all AssetEntity belong to the user + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllAssets(options?: any): AxiosPromise> { + return localVarFp.getAllAssets(options).then((request) => request(axios, basePath)); + }, + /** + * Get a single asset\'s information + * @summary + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAssetById(assetId: string, options?: any): AxiosPromise { + return localVarFp.getAssetById(assetId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAssetSearchTerms(options?: any): AxiosPromise> { + return localVarFp.getAssetSearchTerms(options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAssetThumbnail(assetId: string, options?: any): AxiosPromise { + return localVarFp.getAssetThumbnail(assetId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCuratedLocations(options?: any): AxiosPromise> { + return localVarFp.getCuratedLocations(options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCuratedObjects(options?: any): AxiosPromise> { + return localVarFp.getCuratedObjects(options).then((request) => request(axios, basePath)); + }, + /** + * Get all asset of a device that are in the database, ID only. + * @summary + * @param {string} deviceId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserAssetsByDeviceId(deviceId: string, options?: any): AxiosPromise> { + return localVarFp.getUserAssetsByDeviceId(deviceId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {SearchAssetDto} searchAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + searchAsset(searchAssetDto: SearchAssetDto, options?: any): AxiosPromise> { + return localVarFp.searchAsset(searchAssetDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + serveFile(aid: string, did: string, isThumb?: string, isWeb?: string, options?: any): AxiosPromise { + return localVarFp.serveFile(aid, did, isThumb, isWeb, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {CreateAssetDto} createAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + uploadFile(createAssetDto: CreateAssetDto, options?: any): AxiosPromise { + return localVarFp.uploadFile(createAssetDto, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AssetApi - object-oriented interface + * @export + * @class AssetApi + * @extends {BaseAPI} + */ +export class AssetApi extends BaseAPI { + /** + * Check duplicated asset before uploading - for Web upload used + * @summary + * @param {CheckDuplicateAssetDto} checkDuplicateAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public checkDuplicateAsset(checkDuplicateAssetDto: CheckDuplicateAssetDto, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).checkDuplicateAsset(checkDuplicateAssetDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {DeleteAssetDto} deleteAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public deleteAsset(deleteAssetDto: DeleteAssetDto, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).deleteAsset(deleteAssetDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public downloadFile(aid: string, did: string, isThumb?: string, isWeb?: string, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).downloadFile(aid, did, isThumb, isWeb, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Get all AssetEntity belong to the user + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getAllAssets(options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getAllAssets(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Get a single asset\'s information + * @summary + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getAssetById(assetId: string, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getAssetById(assetId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getAssetSearchTerms(options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getAssetSearchTerms(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} assetId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getAssetThumbnail(assetId: string, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getAssetThumbnail(assetId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getCuratedLocations(options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getCuratedLocations(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getCuratedObjects(options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getCuratedObjects(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Get all asset of a device that are in the database, ID only. + * @summary + * @param {string} deviceId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public getUserAssetsByDeviceId(deviceId: string, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getUserAssetsByDeviceId(deviceId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {SearchAssetDto} searchAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public searchAsset(searchAssetDto: SearchAssetDto, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).searchAsset(searchAssetDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} aid + * @param {string} did + * @param {string} [isThumb] + * @param {string} [isWeb] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public serveFile(aid: string, did: string, isThumb?: string, isWeb?: string, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).serveFile(aid, did, isThumb, isWeb, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {CreateAssetDto} createAssetDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AssetApi + */ + public uploadFile(createAssetDto: CreateAssetDto, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).uploadFile(createAssetDto, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * AuthenticationApi - axios parameter creator + * @export + */ +export const AuthenticationApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {SignUpDto} signUpDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + adminSignUp: async (signUpDto: SignUpDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'signUpDto' is not null or undefined + assertParamExists('adminSignUp', 'signUpDto', signUpDto) + const localVarPath = `/auth/admin-sign-up`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(signUpDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {LoginCredentialDto} loginCredentialDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + login: async (loginCredentialDto: LoginCredentialDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'loginCredentialDto' is not null or undefined + assertParamExists('login', 'loginCredentialDto', loginCredentialDto) + const localVarPath = `/auth/login`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(loginCredentialDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + validateAccessToken: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/auth/validateToken`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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, + }; + }, + } +}; + +/** + * AuthenticationApi - functional programming interface + * @export + */ +export const AuthenticationApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AuthenticationApiAxiosParamCreator(configuration) + return { + /** + * + * @param {SignUpDto} signUpDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async adminSignUp(signUpDto: SignUpDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.adminSignUp(signUpDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {LoginCredentialDto} loginCredentialDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async login(loginCredentialDto: LoginCredentialDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.login(loginCredentialDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async validateAccessToken(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.validateAccessToken(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * AuthenticationApi - factory interface + * @export + */ +export const AuthenticationApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AuthenticationApiFp(configuration) + return { + /** + * + * @param {SignUpDto} signUpDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + adminSignUp(signUpDto: SignUpDto, options?: any): AxiosPromise { + return localVarFp.adminSignUp(signUpDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {LoginCredentialDto} loginCredentialDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + login(loginCredentialDto: LoginCredentialDto, options?: any): AxiosPromise { + return localVarFp.login(loginCredentialDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + validateAccessToken(options?: any): AxiosPromise { + return localVarFp.validateAccessToken(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AuthenticationApi - object-oriented interface + * @export + * @class AuthenticationApi + * @extends {BaseAPI} + */ +export class AuthenticationApi extends BaseAPI { + /** + * + * @param {SignUpDto} signUpDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthenticationApi + */ + public adminSignUp(signUpDto: SignUpDto, options?: AxiosRequestConfig) { + return AuthenticationApiFp(this.configuration).adminSignUp(signUpDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {LoginCredentialDto} loginCredentialDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthenticationApi + */ + public login(loginCredentialDto: LoginCredentialDto, options?: AxiosRequestConfig) { + return AuthenticationApiFp(this.configuration).login(loginCredentialDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthenticationApi + */ + public validateAccessToken(options?: AxiosRequestConfig) { + return AuthenticationApiFp(this.configuration).validateAccessToken(options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * DeviceInfoApi - axios parameter creator + * @export + */ +export const DeviceInfoApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateDeviceInfoDto} createDeviceInfoDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createDeviceInfo: async (createDeviceInfoDto: CreateDeviceInfoDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'createDeviceInfoDto' is not null or undefined + assertParamExists('createDeviceInfo', 'createDeviceInfoDto', createDeviceInfoDto) + const localVarPath = `/device-info`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(createDeviceInfoDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {object} body + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateDeviceInfo: async (body: object, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'body' is not null or undefined + assertParamExists('updateDeviceInfo', 'body', body) + const localVarPath = `/device-info`; + // 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: 'PATCH', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(body, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * DeviceInfoApi - functional programming interface + * @export + */ +export const DeviceInfoApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = DeviceInfoApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateDeviceInfoDto} createDeviceInfoDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createDeviceInfo(createDeviceInfoDto: CreateDeviceInfoDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createDeviceInfo(createDeviceInfoDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {object} body + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateDeviceInfo(body: object, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateDeviceInfo(body, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * DeviceInfoApi - factory interface + * @export + */ +export const DeviceInfoApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = DeviceInfoApiFp(configuration) + return { + /** + * + * @param {CreateDeviceInfoDto} createDeviceInfoDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createDeviceInfo(createDeviceInfoDto: CreateDeviceInfoDto, options?: any): AxiosPromise { + return localVarFp.createDeviceInfo(createDeviceInfoDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {object} body + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateDeviceInfo(body: object, options?: any): AxiosPromise { + return localVarFp.updateDeviceInfo(body, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * DeviceInfoApi - object-oriented interface + * @export + * @class DeviceInfoApi + * @extends {BaseAPI} + */ +export class DeviceInfoApi extends BaseAPI { + /** + * + * @param {CreateDeviceInfoDto} createDeviceInfoDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DeviceInfoApi + */ + public createDeviceInfo(createDeviceInfoDto: CreateDeviceInfoDto, options?: AxiosRequestConfig) { + return DeviceInfoApiFp(this.configuration).createDeviceInfo(createDeviceInfoDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {object} body + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DeviceInfoApi + */ + public updateDeviceInfo(body: object, options?: AxiosRequestConfig) { + return DeviceInfoApiFp(this.configuration).updateDeviceInfo(body, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * ServerInfoApi - axios parameter creator + * @export + */ +export const ServerInfoApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getServerInfo: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/server-info`; + // 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; + + + + 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} + */ + getServerVersion: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/server-info/version`; + // 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; + + + + 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} + */ + pingServer: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/server-info/ping`; + // 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; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ServerInfoApi - functional programming interface + * @export + */ +export const ServerInfoApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ServerInfoApiAxiosParamCreator(configuration) + return { + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getServerInfo(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getServerInfo(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getServerVersion(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getServerVersion(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async pingServer(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.pingServer(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * ServerInfoApi - factory interface + * @export + */ +export const ServerInfoApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ServerInfoApiFp(configuration) + return { + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getServerInfo(options?: any): AxiosPromise { + return localVarFp.getServerInfo(options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getServerVersion(options?: any): AxiosPromise { + return localVarFp.getServerVersion(options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + pingServer(options?: any): AxiosPromise { + return localVarFp.pingServer(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ServerInfoApi - object-oriented interface + * @export + * @class ServerInfoApi + * @extends {BaseAPI} + */ +export class ServerInfoApi extends BaseAPI { + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ServerInfoApi + */ + public getServerInfo(options?: AxiosRequestConfig) { + return ServerInfoApiFp(this.configuration).getServerInfo(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ServerInfoApi + */ + public getServerVersion(options?: AxiosRequestConfig) { + return ServerInfoApiFp(this.configuration).getServerVersion(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ServerInfoApi + */ + public pingServer(options?: AxiosRequestConfig) { + return ServerInfoApiFp(this.configuration).pingServer(options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * UserApi - axios parameter creator + * @export + */ +export const UserApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {any} file + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createProfileImage: async (file: any, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'file' is not null or undefined + assertParamExists('createProfileImage', 'file', file) + const localVarPath = `/user/profile-image`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + const localVarFormParams = new ((configuration && configuration.formDataCtor) || FormData)(); + + // authentication bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + if (file !== undefined) { + localVarFormParams.append('file', file as any); + } + + + localVarHeaderParameter['Content-Type'] = 'multipart/form-data'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = localVarFormParams; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {CreateUserDto} createUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUser: async (createUserDto: CreateUserDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'createUserDto' is not null or undefined + assertParamExists('createUser', 'createUserDto', createUserDto) + const localVarPath = `/user`; + // 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: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // 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(createUserDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {boolean} isAll + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllUsers: async (isAll: boolean, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'isAll' is not null or undefined + assertParamExists('getAllUsers', 'isAll', isAll) + const localVarPath = `/user`; + // 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 bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + if (isAll !== undefined) { + localVarQueryParameter['isAll'] = isAll; + } + + + + 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} + */ + getMyUserInfo: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/user/me`; + // 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 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} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getProfileImage: async (userId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'userId' is not null or undefined + assertParamExists('getProfileImage', 'userId', userId) + const localVarPath = `/user/profile-image/{userId}` + .replace(`{${"userId"}}`, encodeURIComponent(String(userId))); + // 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; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {boolean} isAdmin + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserCount: async (isAdmin: boolean, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'isAdmin' is not null or undefined + assertParamExists('getUserCount', 'isAdmin', isAdmin) + const localVarPath = `/user/count`; + // 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; + + if (isAdmin !== undefined) { + localVarQueryParameter['isAdmin'] = isAdmin; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {UpdateUserDto} updateUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUser: async (updateUserDto: UpdateUserDto, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'updateUserDto' is not null or undefined + assertParamExists('updateUser', 'updateUserDto', updateUserDto) + const localVarPath = `/user`; + // 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 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(updateUserDto, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UserApi - functional programming interface + * @export + */ +export const UserApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UserApiAxiosParamCreator(configuration) + return { + /** + * + * @param {any} file + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createProfileImage(file: any, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createProfileImage(file, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {CreateUserDto} createUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createUser(createUserDto: CreateUserDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createUser(createUserDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {boolean} isAll + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAllUsers(isAll: boolean, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAllUsers(isAll, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getMyUserInfo(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getMyUserInfo(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getProfileImage(userId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getProfileImage(userId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {boolean} isAdmin + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserCount(isAdmin: boolean, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserCount(isAdmin, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @param {UpdateUserDto} updateUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateUser(updateUserDto: UpdateUserDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateUser(updateUserDto, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * UserApi - factory interface + * @export + */ +export const UserApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UserApiFp(configuration) + return { + /** + * + * @param {any} file + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createProfileImage(file: any, options?: any): AxiosPromise { + return localVarFp.createProfileImage(file, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {CreateUserDto} createUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUser(createUserDto: CreateUserDto, options?: any): AxiosPromise { + return localVarFp.createUser(createUserDto, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {boolean} isAll + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAllUsers(isAll: boolean, options?: any): AxiosPromise> { + return localVarFp.getAllUsers(isAll, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getMyUserInfo(options?: any): AxiosPromise { + return localVarFp.getMyUserInfo(options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getProfileImage(userId: string, options?: any): AxiosPromise { + return localVarFp.getProfileImage(userId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {boolean} isAdmin + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserCount(isAdmin: boolean, options?: any): AxiosPromise { + return localVarFp.getUserCount(isAdmin, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {UpdateUserDto} updateUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUser(updateUserDto: UpdateUserDto, options?: any): AxiosPromise { + return localVarFp.updateUser(updateUserDto, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UserApi - object-oriented interface + * @export + * @class UserApi + * @extends {BaseAPI} + */ +export class UserApi extends BaseAPI { + /** + * + * @param {any} file + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public createProfileImage(file: any, options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).createProfileImage(file, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {CreateUserDto} createUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public createUser(createUserDto: CreateUserDto, options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).createUser(createUserDto, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {boolean} isAll + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public getAllUsers(isAll: boolean, options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).getAllUsers(isAll, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public getMyUserInfo(options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).getMyUserInfo(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {string} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public getProfileImage(userId: string, options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).getProfileImage(userId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {boolean} isAdmin + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public getUserCount(isAdmin: boolean, options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).getUserCount(isAdmin, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {UpdateUserDto} updateUserDto + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserApi + */ + public updateUser(updateUserDto: UpdateUserDto, options?: AxiosRequestConfig) { + return UserApiFp(this.configuration).updateUser(updateUserDto, options).then((request) => request(this.axios, this.basePath)); + } +} + + diff --git a/web/src/lib/open-api/base.ts b/web/src/lib/open-api/base.ts new file mode 100644 index 0000000000..d6c8a7fef9 --- /dev/null +++ b/web/src/lib/open-api/base.ts @@ -0,0 +1,74 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.17.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { Configuration } from './configuration'; +// Some imports not used depending on template conditions +// @ts-ignore +import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; + +export const BASE_PATH = '/api'.replace(/\/+$/, ''); + +/** + * + * @export + */ +export const COLLECTION_FORMATS = { + csv: ',', + ssv: ' ', + tsv: '\t', + pipes: '|', +}; + +/** + * + * @export + * @interface RequestArgs + */ +export interface RequestArgs { + url: string; + options: AxiosRequestConfig; +} + +/** + * + * @export + * @class BaseAPI + */ +export class BaseAPI { + protected configuration: Configuration | undefined; + + constructor( + configuration?: Configuration, + protected basePath: string = BASE_PATH, + protected axios: AxiosInstance = globalAxios, + ) { + if (configuration) { + this.configuration = configuration; + this.basePath = configuration.basePath || this.basePath; + } + } +} + +/** + * + * @export + * @class RequiredError + * @extends {Error} + */ +export class RequiredError extends Error { + name: 'RequiredError' = 'RequiredError'; + constructor(public field: string, msg?: string) { + super(msg); + } +} diff --git a/web/src/lib/open-api/common.ts b/web/src/lib/open-api/common.ts new file mode 100644 index 0000000000..528225211b --- /dev/null +++ b/web/src/lib/open-api/common.ts @@ -0,0 +1,138 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.17.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import { Configuration } from "./configuration"; +import { RequiredError, RequestArgs } from "./base"; +import { AxiosInstance, AxiosResponse } from 'axios'; + +/** + * + * @export + */ +export const DUMMY_BASE_URL = 'https://example.com' + +/** + * + * @throws {RequiredError} + * @export + */ +export const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) { + if (paramValue === null || paramValue === undefined) { + throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`); + } +} + +/** + * + * @export + */ +export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) { + if (configuration && configuration.apiKey) { + const localVarApiKeyValue = typeof configuration.apiKey === 'function' + ? await configuration.apiKey(keyParamName) + : await configuration.apiKey; + object[keyParamName] = localVarApiKeyValue; + } +} + +/** + * + * @export + */ +export const setBasicAuthToObject = function (object: any, configuration?: Configuration) { + if (configuration && (configuration.username || configuration.password)) { + object["auth"] = { username: configuration.username, password: configuration.password }; + } +} + +/** + * + * @export + */ +export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + object["Authorization"] = "Bearer " + accessToken; + } +} + +/** + * + * @export + */ +export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const localVarAccessTokenValue = typeof configuration.accessToken === 'function' + ? await configuration.accessToken(name, scopes) + : await configuration.accessToken; + object["Authorization"] = "Bearer " + localVarAccessTokenValue; + } +} + +/** + * + * @export + */ +export const setSearchParams = function (url: URL, ...objects: any[]) { + const searchParams = new URLSearchParams(url.search); + for (const object of objects) { + for (const key in object) { + if (Array.isArray(object[key])) { + searchParams.delete(key); + for (const item of object[key]) { + searchParams.append(key, item); + } + } else { + searchParams.set(key, object[key]); + } + } + } + url.search = searchParams.toString(); +} + +/** + * + * @export + */ +export const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) { + const nonString = typeof value !== 'string'; + const needsSerialization = nonString && configuration && configuration.isJsonMime + ? configuration.isJsonMime(requestOptions.headers['Content-Type']) + : nonString; + return needsSerialization + ? JSON.stringify(value !== undefined ? value : {}) + : (value || ""); +} + +/** + * + * @export + */ +export const toPathString = function (url: URL) { + return url.pathname + url.search + url.hash +} + +/** + * + * @export + */ +export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { + return >(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs = {...axiosArgs.options, url: (configuration?.basePath || basePath) + axiosArgs.url}; + return axios.request(axiosRequestArgs); + }; +} diff --git a/web/src/lib/open-api/configuration.ts b/web/src/lib/open-api/configuration.ts new file mode 100644 index 0000000000..d16b363492 --- /dev/null +++ b/web/src/lib/open-api/configuration.ts @@ -0,0 +1,101 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.17.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export interface ConfigurationParameters { + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + username?: string; + password?: string; + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + basePath?: string; + baseOptions?: any; + formDataCtor?: new () => any; +} + +export class Configuration { + /** + * parameter for apiKey security + * @param name security name + * @memberof Configuration + */ + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + username?: string; + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + password?: string; + /** + * parameter for oauth2 security + * @param name security name + * @param scopes oauth2 scope + * @memberof Configuration + */ + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + /** + * override base path + * + * @type {string} + * @memberof Configuration + */ + basePath?: string; + /** + * base options for axios calls + * + * @type {any} + * @memberof Configuration + */ + baseOptions?: any; + /** + * The FormData constructor that will be used to create multipart form data + * requests. You can inject this here so that execution environments that + * do not support the FormData class can still run the generated client. + * + * @type {new () => FormData} + */ + formDataCtor?: new () => any; + + constructor(param: ConfigurationParameters = {}) { + this.apiKey = param.apiKey; + this.username = param.username; + this.password = param.password; + this.accessToken = param.accessToken; + this.basePath = param.basePath; + this.baseOptions = param.baseOptions; + this.formDataCtor = param.formDataCtor; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/web/src/lib/open-api/git_push.sh b/web/src/lib/open-api/git_push.sh new file mode 100644 index 0000000000..f53a75d4fa --- /dev/null +++ b/web/src/lib/open-api/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/web/src/lib/open-api/index.ts b/web/src/lib/open-api/index.ts new file mode 100644 index 0000000000..30725ab46a --- /dev/null +++ b/web/src/lib/open-api/index.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.17.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export * from "./api"; +export * from "./configuration"; + diff --git a/web/src/routes/photos/index.svelte b/web/src/routes/photos/index.svelte index a028be551c..97e35f2fe9 100644 --- a/web/src/routes/photos/index.svelte +++ b/web/src/routes/photos/index.svelte @@ -3,7 +3,6 @@ import type { Load } from '@sveltejs/kit'; import { getAssetsInfo } from '$lib/stores/assets'; - import { checkAppVersion } from '$lib/utils/check-app-version'; export const load: Load = async ({ session }) => { if (!session.user) { @@ -25,7 +24,7 @@