diff --git a/e2e/src/web/specs/search/search-gallery.ui-spec.ts b/e2e/src/web/specs/search/search-gallery.ui-spec.ts new file mode 100644 index 0000000000000..e358bed1548de --- /dev/null +++ b/e2e/src/web/specs/search/search-gallery.ui-spec.ts @@ -0,0 +1,116 @@ +import { faker } from '@faker-js/faker'; +import { expect, test } from '@playwright/test'; +import { + Changes, + createDefaultTimelineConfig, + generateTimelineData, + TimelineAssetConfig, + TimelineData, +} from 'src/generators/timeline'; +import { setupBaseMockApiRoutes } from 'src/mock-network/base-network'; +import { setupTimelineMockApiRoutes, TimelineTestContext } from 'src/mock-network/timeline-network'; +import { assetViewerUtils } from 'src/web/specs/timeline/utils'; + +const buildSearchUrl = (assetId: string) => { + const searchQuery = encodeURIComponent(JSON.stringify({ originalFileName: 'test' })); + return `/search/photos/${assetId}?query=${searchQuery}`; +}; + +test.describe.configure({ mode: 'parallel' }); +test.describe('search gallery-viewer', () => { + let adminUserId: string; + let timelineRestData: TimelineData; + const assets: TimelineAssetConfig[] = []; + const testContext = new TimelineTestContext(); + const changes: Changes = { + albumAdditions: [], + assetDeletions: [], + assetArchivals: [], + assetFavorites: [], + }; + + test.beforeAll(async () => { + adminUserId = faker.string.uuid(); + testContext.adminId = adminUserId; + timelineRestData = generateTimelineData({ ...createDefaultTimelineConfig(), ownerId: adminUserId }); + for (const timeBucket of timelineRestData.buckets.values()) { + assets.push(...timeBucket); + } + }); + + test.beforeEach(async ({ context }) => { + await setupBaseMockApiRoutes(context, adminUserId); + await setupTimelineMockApiRoutes(context, timelineRestData, changes, testContext); + + await context.route('**/api/search/metadata', async (route, request) => { + if (request.method() === 'POST') { + const searchAssets = assets.slice(0, 5).filter((asset) => !changes.assetDeletions.includes(asset.id)); + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: { + albums: { total: 0, count: 0, items: [], facets: [] }, + assets: { + total: searchAssets.length, + count: searchAssets.length, + items: searchAssets, + facets: [], + nextPage: null, + }, + }, + }); + } + await route.fallback(); + }); + }); + + test.afterEach(() => { + testContext.slowBucket = false; + changes.albumAdditions = []; + changes.assetDeletions = []; + changes.assetArchivals = []; + changes.assetFavorites = []; + }); + + test.describe('/search/photos/:id', () => { + test('Deleting a photo advances to the next photo', async ({ page }) => { + const asset = assets[0]; + await page.goto(buildSearchUrl(asset.id)); + await assetViewerUtils.waitForViewerLoad(page, asset); + await page.getByLabel('Delete').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[1]); + }); + + test('Deleting two photos in a row advances to the next photo each time', async ({ page }) => { + const asset = assets[0]; + await page.goto(buildSearchUrl(asset.id)); + await assetViewerUtils.waitForViewerLoad(page, asset); + await page.getByLabel('Delete').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[1]); + await page.getByLabel('Delete').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[2]); + }); + + test('Navigating backward then deleting advances to the next photo', async ({ page }) => { + const asset = assets[1]; + await page.goto(buildSearchUrl(asset.id)); + await assetViewerUtils.waitForViewerLoad(page, asset); + await page.getByLabel('View previous asset').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[0]); + await page.getByLabel('View next asset').click(); + await assetViewerUtils.waitForViewerLoad(page, asset); + await page.getByLabel('Delete').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[2]); + }); + + test('Deleting the last photo advances to the previous photo', async ({ page }) => { + const lastAsset = assets[4]; + await page.goto(buildSearchUrl(lastAsset.id)); + await assetViewerUtils.waitForViewerLoad(page, lastAsset); + await expect(page.getByLabel('View next asset')).toHaveCount(0); + await page.getByLabel('Delete').click(); + await assetViewerUtils.waitForViewerLoad(page, assets[3]); + await expect(page.getByLabel('View previous asset')).toBeVisible(); + }); + }); +}); diff --git a/mobile/openapi/lib/api/activities_api.dart b/mobile/openapi/lib/api/activities_api.dart index b92f95be72a19..697598ac97f61 100644 --- a/mobile/openapi/lib/api/activities_api.dart +++ b/mobile/openapi/lib/api/activities_api.dart @@ -130,14 +130,19 @@ class ActivitiesApi { /// Parameters: /// /// * [String] albumId (required): + /// Album ID /// /// * [String] assetId: + /// Asset ID (if activity is for an asset) /// /// * [ReactionLevel] level: + /// Filter by activity level /// /// * [ReactionType] type: + /// Filter by activity type /// /// * [String] userId: + /// Filter by user ID Future getActivitiesWithHttpInfo(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async { // ignore: prefer_const_declarations final apiPath = r'/activities'; @@ -184,14 +189,19 @@ class ActivitiesApi { /// Parameters: /// /// * [String] albumId (required): + /// Album ID /// /// * [String] assetId: + /// Asset ID (if activity is for an asset) /// /// * [ReactionLevel] level: + /// Filter by activity level /// /// * [ReactionType] type: + /// Filter by activity type /// /// * [String] userId: + /// Filter by user ID Future?> getActivities(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async { final response = await getActivitiesWithHttpInfo(albumId, assetId: assetId, level: level, type: type, userId: userId, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -219,8 +229,10 @@ class ActivitiesApi { /// Parameters: /// /// * [String] albumId (required): + /// Album ID /// /// * [String] assetId: + /// Asset ID (if activity is for an asset) Future getActivityStatisticsWithHttpInfo(String albumId, { String? assetId, }) async { // ignore: prefer_const_declarations final apiPath = r'/activities/statistics'; @@ -258,8 +270,10 @@ class ActivitiesApi { /// Parameters: /// /// * [String] albumId (required): + /// Album ID /// /// * [String] assetId: + /// Asset ID (if activity is for an asset) Future getActivityStatistics(String albumId, { String? assetId, }) async { final response = await getActivityStatisticsWithHttpInfo(albumId, assetId: assetId, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/albums_api.dart b/mobile/openapi/lib/api/albums_api.dart index 1042a2850f606..713bcafee38c0 100644 --- a/mobile/openapi/lib/api/albums_api.dart +++ b/mobile/openapi/lib/api/albums_api.dart @@ -347,6 +347,7 @@ class AlbumsApi { /// * [String] slug: /// /// * [bool] withoutAssets: + /// Exclude assets from response Future getAlbumInfoWithHttpInfo(String id, { String? key, String? slug, bool? withoutAssets, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}' @@ -396,6 +397,7 @@ class AlbumsApi { /// * [String] slug: /// /// * [bool] withoutAssets: + /// Exclude assets from response Future getAlbumInfo(String id, { String? key, String? slug, bool? withoutAssets, }) async { final response = await getAlbumInfoWithHttpInfo(id, key: key, slug: slug, withoutAssets: withoutAssets, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -468,9 +470,10 @@ class AlbumsApi { /// Parameters: /// /// * [String] assetId: - /// Only returns albums that contain the asset Ignores the shared parameter undefined: get all albums + /// Filter albums containing this asset ID (ignores shared parameter) /// /// * [bool] shared: + /// Filter by shared status: true = only shared, false = only own, undefined = all Future getAllAlbumsWithHttpInfo({ String? assetId, bool? shared, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums'; @@ -510,9 +513,10 @@ class AlbumsApi { /// Parameters: /// /// * [String] assetId: - /// Only returns albums that contain the asset Ignores the shared parameter undefined: get all albums + /// Filter albums containing this asset ID (ignores shared parameter) /// /// * [bool] shared: + /// Filter by shared status: true = only shared, false = only own, undefined = all Future?> getAllAlbums({ String? assetId, bool? shared, }) async { final response = await getAllAlbumsWithHttpInfo( assetId: assetId, shared: shared, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/assets_api.dart b/mobile/openapi/lib/api/assets_api.dart index e737397fc8176..5fda01a59435c 100644 --- a/mobile/openapi/lib/api/assets_api.dart +++ b/mobile/openapi/lib/api/assets_api.dart @@ -185,8 +185,10 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): + /// Asset ID /// /// * [String] key (required): + /// Metadata key Future deleteAssetMetadataWithHttpInfo(String id, String key,) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/metadata/{key}' @@ -221,8 +223,10 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): + /// Asset ID /// /// * [String] key (required): + /// Metadata key Future deleteAssetMetadata(String id, String key,) async { final response = await deleteAssetMetadataWithHttpInfo(id, key,); if (response.statusCode >= HttpStatus.badRequest) { @@ -337,6 +341,7 @@ class AssetsApi { /// * [String] id (required): /// /// * [bool] edited: + /// Return edited asset if available /// /// * [String] key: /// @@ -386,6 +391,7 @@ class AssetsApi { /// * [String] id (required): /// /// * [bool] edited: + /// Return edited asset if available /// /// * [String] key: /// @@ -475,6 +481,7 @@ class AssetsApi { /// Parameters: /// /// * [String] deviceId (required): + /// Device ID Future getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { // ignore: prefer_const_declarations final apiPath = r'/assets/device/{deviceId}' @@ -508,6 +515,7 @@ class AssetsApi { /// Parameters: /// /// * [String] deviceId (required): + /// Device ID Future?> getAllUserAssetsByDeviceId(String deviceId,) async { final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,); if (response.statusCode >= HttpStatus.badRequest) { @@ -724,8 +732,10 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): + /// Asset ID /// /// * [String] key (required): + /// Metadata key Future getAssetMetadataByKeyWithHttpInfo(String id, String key,) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/metadata/{key}' @@ -760,8 +770,10 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): + /// Asset ID /// /// * [String] key (required): + /// Metadata key Future getAssetMetadataByKey(String id, String key,) async { final response = await getAssetMetadataByKeyWithHttpInfo(id, key,); if (response.statusCode >= HttpStatus.badRequest) { @@ -846,10 +858,13 @@ class AssetsApi { /// Parameters: /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] isTrashed: + /// Filter by trash status /// /// * [AssetVisibility] visibility: + /// Filter by visibility Future getAssetStatisticsWithHttpInfo({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/statistics'; @@ -892,10 +907,13 @@ class AssetsApi { /// Parameters: /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] isTrashed: + /// Filter by trash status /// /// * [AssetVisibility] visibility: + /// Filter by visibility Future getAssetStatistics({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { final response = await getAssetStatisticsWithHttpInfo( isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -920,6 +938,7 @@ class AssetsApi { /// Parameters: /// /// * [num] count: + /// Number of random assets to return Future getRandomWithHttpInfo({ num? count, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/random'; @@ -956,6 +975,7 @@ class AssetsApi { /// Parameters: /// /// * [num] count: + /// Number of random assets to return Future?> getRandom({ num? count, }) async { final response = await getRandomWithHttpInfo( count: count, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -1106,22 +1126,29 @@ class AssetsApi { /// * [String] id (required): /// /// * [MultipartFile] assetData (required): + /// Asset file data /// /// * [String] deviceAssetId (required): + /// Device asset ID /// /// * [String] deviceId (required): + /// Device ID /// /// * [DateTime] fileCreatedAt (required): + /// File creation date /// /// * [DateTime] fileModifiedAt (required): + /// File modification date /// /// * [String] key: /// /// * [String] slug: /// /// * [String] duration: + /// Duration (for videos) /// /// * [String] filename: + /// Filename Future replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/original' @@ -1198,22 +1225,29 @@ class AssetsApi { /// * [String] id (required): /// /// * [MultipartFile] assetData (required): + /// Asset file data /// /// * [String] deviceAssetId (required): + /// Device asset ID /// /// * [String] deviceId (required): + /// Device ID /// /// * [DateTime] fileCreatedAt (required): + /// File creation date /// /// * [DateTime] fileModifiedAt (required): + /// File modification date /// /// * [String] key: /// /// * [String] slug: /// /// * [String] duration: + /// Duration (for videos) /// /// * [String] filename: + /// Filename Future replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, duration: duration, filename: filename, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -1518,14 +1552,19 @@ class AssetsApi { /// Parameters: /// /// * [MultipartFile] assetData (required): + /// Asset file data /// /// * [String] deviceAssetId (required): + /// Device asset ID /// /// * [String] deviceId (required): + /// Device ID /// /// * [DateTime] fileCreatedAt (required): + /// File creation date /// /// * [DateTime] fileModifiedAt (required): + /// File modification date /// /// * [String] key: /// @@ -1535,18 +1574,25 @@ class AssetsApi { /// sha1 checksum that can be used for duplicate detection before the file is uploaded /// /// * [String] duration: + /// Duration (for videos) /// /// * [String] filename: + /// Filename /// /// * [bool] isFavorite: + /// Mark as favorite /// /// * [String] livePhotoVideoId: + /// Live photo video ID /// /// * [List] metadata: + /// Asset metadata items /// /// * [MultipartFile] sidecarData: + /// Sidecar file data /// /// * [AssetVisibility] visibility: + /// Asset visibility Future uploadAssetWithHttpInfo(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets'; @@ -1645,14 +1691,19 @@ class AssetsApi { /// Parameters: /// /// * [MultipartFile] assetData (required): + /// Asset file data /// /// * [String] deviceAssetId (required): + /// Device asset ID /// /// * [String] deviceId (required): + /// Device ID /// /// * [DateTime] fileCreatedAt (required): + /// File creation date /// /// * [DateTime] fileModifiedAt (required): + /// File modification date /// /// * [String] key: /// @@ -1662,18 +1713,25 @@ class AssetsApi { /// sha1 checksum that can be used for duplicate detection before the file is uploaded /// /// * [String] duration: + /// Duration (for videos) /// /// * [String] filename: + /// Filename /// /// * [bool] isFavorite: + /// Mark as favorite /// /// * [String] livePhotoVideoId: + /// Live photo video ID /// /// * [List] metadata: + /// Asset metadata items /// /// * [MultipartFile] sidecarData: + /// Sidecar file data /// /// * [AssetVisibility] visibility: + /// Asset visibility Future uploadAsset(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { final response = await uploadAssetWithHttpInfo(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -1700,10 +1758,12 @@ class AssetsApi { /// * [String] id (required): /// /// * [bool] edited: + /// Return edited asset if available /// /// * [String] key: /// /// * [AssetMediaSize] size: + /// Asset media size /// /// * [String] slug: Future viewAssetWithHttpInfo(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async { @@ -1754,10 +1814,12 @@ class AssetsApi { /// * [String] id (required): /// /// * [bool] edited: + /// Return edited asset if available /// /// * [String] key: /// /// * [AssetMediaSize] size: + /// Asset media size /// /// * [String] slug: Future viewAsset(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async { diff --git a/mobile/openapi/lib/api/deprecated_api.dart b/mobile/openapi/lib/api/deprecated_api.dart index d0d92d804db98..33bcaf062cb07 100644 --- a/mobile/openapi/lib/api/deprecated_api.dart +++ b/mobile/openapi/lib/api/deprecated_api.dart @@ -82,6 +82,7 @@ class DeprecatedApi { /// Parameters: /// /// * [String] deviceId (required): + /// Device ID Future getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { // ignore: prefer_const_declarations final apiPath = r'/assets/device/{deviceId}' @@ -115,6 +116,7 @@ class DeprecatedApi { /// Parameters: /// /// * [String] deviceId (required): + /// Device ID Future?> getAllUserAssetsByDeviceId(String deviceId,) async { final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,); if (response.statusCode >= HttpStatus.badRequest) { @@ -305,6 +307,7 @@ class DeprecatedApi { /// Parameters: /// /// * [num] count: + /// Number of random assets to return Future getRandomWithHttpInfo({ num? count, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/random'; @@ -341,6 +344,7 @@ class DeprecatedApi { /// Parameters: /// /// * [num] count: + /// Number of random assets to return Future?> getRandom({ num? count, }) async { final response = await getRandomWithHttpInfo( count: count, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -370,22 +374,29 @@ class DeprecatedApi { /// * [String] id (required): /// /// * [MultipartFile] assetData (required): + /// Asset file data /// /// * [String] deviceAssetId (required): + /// Device asset ID /// /// * [String] deviceId (required): + /// Device ID /// /// * [DateTime] fileCreatedAt (required): + /// File creation date /// /// * [DateTime] fileModifiedAt (required): + /// File modification date /// /// * [String] key: /// /// * [String] slug: /// /// * [String] duration: + /// Duration (for videos) /// /// * [String] filename: + /// Filename Future replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/original' @@ -462,22 +473,29 @@ class DeprecatedApi { /// * [String] id (required): /// /// * [MultipartFile] assetData (required): + /// Asset file data /// /// * [String] deviceAssetId (required): + /// Device asset ID /// /// * [String] deviceId (required): + /// Device ID /// /// * [DateTime] fileCreatedAt (required): + /// File creation date /// /// * [DateTime] fileModifiedAt (required): + /// File modification date /// /// * [String] key: /// /// * [String] slug: /// /// * [String] duration: + /// Duration (for videos) /// /// * [String] filename: + /// Filename Future replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, duration: duration, filename: filename, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -502,6 +520,7 @@ class DeprecatedApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueCommandDto] queueCommandDto (required): Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { @@ -537,6 +556,7 @@ class DeprecatedApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueCommandDto] queueCommandDto (required): Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { diff --git a/mobile/openapi/lib/api/faces_api.dart b/mobile/openapi/lib/api/faces_api.dart index 1d2e7401e8035..43d63b47b9542 100644 --- a/mobile/openapi/lib/api/faces_api.dart +++ b/mobile/openapi/lib/api/faces_api.dart @@ -126,6 +126,7 @@ class FacesApi { /// Parameters: /// /// * [String] id (required): + /// Face ID Future getFacesWithHttpInfo(String id,) async { // ignore: prefer_const_declarations final apiPath = r'/faces'; @@ -160,6 +161,7 @@ class FacesApi { /// Parameters: /// /// * [String] id (required): + /// Face ID Future?> getFaces(String id,) async { final response = await getFacesWithHttpInfo(id,); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/jobs_api.dart b/mobile/openapi/lib/api/jobs_api.dart index 9dda59a883b41..41517f8144a36 100644 --- a/mobile/openapi/lib/api/jobs_api.dart +++ b/mobile/openapi/lib/api/jobs_api.dart @@ -121,6 +121,7 @@ class JobsApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueCommandDto] queueCommandDto (required): Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { @@ -156,6 +157,7 @@ class JobsApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueCommandDto] queueCommandDto (required): Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { diff --git a/mobile/openapi/lib/api/map_api.dart b/mobile/openapi/lib/api/map_api.dart index 6302ac304ed11..4ce62bd96c041 100644 --- a/mobile/openapi/lib/api/map_api.dart +++ b/mobile/openapi/lib/api/map_api.dart @@ -25,16 +25,22 @@ class MapApi { /// Parameters: /// /// * [DateTime] fileCreatedAfter: + /// Filter assets created after this date /// /// * [DateTime] fileCreatedBefore: + /// Filter assets created before this date /// /// * [bool] isArchived: + /// Filter by archived status /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] withPartners: + /// Include partner assets /// /// * [bool] withSharedAlbums: + /// Include shared album assets Future getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async { // ignore: prefer_const_declarations final apiPath = r'/map/markers'; @@ -86,16 +92,22 @@ class MapApi { /// Parameters: /// /// * [DateTime] fileCreatedAfter: + /// Filter assets created after this date /// /// * [DateTime] fileCreatedBefore: + /// Filter assets created before this date /// /// * [bool] isArchived: + /// Filter by archived status /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] withPartners: + /// Include partner assets /// /// * [bool] withSharedAlbums: + /// Include shared album assets Future?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async { final response = await getMapMarkersWithHttpInfo( fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, withPartners: withPartners, withSharedAlbums: withSharedAlbums, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -123,8 +135,10 @@ class MapApi { /// Parameters: /// /// * [double] lat (required): + /// Latitude (-90 to 90) /// /// * [double] lon (required): + /// Longitude (-180 to 180) Future reverseGeocodeWithHttpInfo(double lat, double lon,) async { // ignore: prefer_const_declarations final apiPath = r'/map/reverse-geocode'; @@ -160,8 +174,10 @@ class MapApi { /// Parameters: /// /// * [double] lat (required): + /// Latitude (-90 to 90) /// /// * [double] lon (required): + /// Longitude (-180 to 180) Future?> reverseGeocode(double lat, double lon,) async { final response = await reverseGeocodeWithHttpInfo(lat, lon,); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/memories_api.dart b/mobile/openapi/lib/api/memories_api.dart index 314595e84e3a8..913205428e0be 100644 --- a/mobile/openapi/lib/api/memories_api.dart +++ b/mobile/openapi/lib/api/memories_api.dart @@ -251,17 +251,22 @@ class MemoriesApi { /// Parameters: /// /// * [DateTime] for_: + /// Filter by date /// /// * [bool] isSaved: + /// Filter by saved status /// /// * [bool] isTrashed: + /// Include trashed memories /// /// * [MemorySearchOrder] order: + /// Sort order /// /// * [int] size: /// Number of memories to return /// /// * [MemoryType] type: + /// Memory type Future memoriesStatisticsWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/statistics'; @@ -313,17 +318,22 @@ class MemoriesApi { /// Parameters: /// /// * [DateTime] for_: + /// Filter by date /// /// * [bool] isSaved: + /// Filter by saved status /// /// * [bool] isTrashed: + /// Include trashed memories /// /// * [MemorySearchOrder] order: + /// Sort order /// /// * [int] size: /// Number of memories to return /// /// * [MemoryType] type: + /// Memory type Future memoriesStatistics({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { final response = await memoriesStatisticsWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -412,17 +422,22 @@ class MemoriesApi { /// Parameters: /// /// * [DateTime] for_: + /// Filter by date /// /// * [bool] isSaved: + /// Filter by saved status /// /// * [bool] isTrashed: + /// Include trashed memories /// /// * [MemorySearchOrder] order: + /// Sort order /// /// * [int] size: /// Number of memories to return /// /// * [MemoryType] type: + /// Memory type Future searchMemoriesWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories'; @@ -474,17 +489,22 @@ class MemoriesApi { /// Parameters: /// /// * [DateTime] for_: + /// Filter by date /// /// * [bool] isSaved: + /// Filter by saved status /// /// * [bool] isTrashed: + /// Include trashed memories /// /// * [MemorySearchOrder] order: + /// Sort order /// /// * [int] size: /// Number of memories to return /// /// * [MemoryType] type: + /// Memory type Future?> searchMemories({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { final response = await searchMemoriesWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/notifications_api.dart b/mobile/openapi/lib/api/notifications_api.dart index 2de59a0a7612d..d4e2b1d80fefa 100644 --- a/mobile/openapi/lib/api/notifications_api.dart +++ b/mobile/openapi/lib/api/notifications_api.dart @@ -179,12 +179,16 @@ class NotificationsApi { /// Parameters: /// /// * [String] id: + /// Filter by notification ID /// /// * [NotificationLevel] level: + /// Filter by notification level /// /// * [NotificationType] type: + /// Filter by notification type /// /// * [bool] unread: + /// Filter by unread status Future getNotificationsWithHttpInfo({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications'; @@ -230,12 +234,16 @@ class NotificationsApi { /// Parameters: /// /// * [String] id: + /// Filter by notification ID /// /// * [NotificationLevel] level: + /// Filter by notification level /// /// * [NotificationType] type: + /// Filter by notification type /// /// * [bool] unread: + /// Filter by unread status Future?> getNotifications({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async { final response = await getNotificationsWithHttpInfo( id: id, level: level, type: type, unread: unread, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/partners_api.dart b/mobile/openapi/lib/api/partners_api.dart index 7d18f6d867937..3b15b909090ba 100644 --- a/mobile/openapi/lib/api/partners_api.dart +++ b/mobile/openapi/lib/api/partners_api.dart @@ -138,6 +138,7 @@ class PartnersApi { /// Parameters: /// /// * [PartnerDirection] direction (required): + /// Partner direction Future getPartnersWithHttpInfo(PartnerDirection direction,) async { // ignore: prefer_const_declarations final apiPath = r'/partners'; @@ -172,6 +173,7 @@ class PartnersApi { /// Parameters: /// /// * [PartnerDirection] direction (required): + /// Partner direction Future?> getPartners(PartnerDirection direction,) async { final response = await getPartnersWithHttpInfo(direction,); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/people_api.dart b/mobile/openapi/lib/api/people_api.dart index c38e61584e5c7..c8c18214233df 100644 --- a/mobile/openapi/lib/api/people_api.dart +++ b/mobile/openapi/lib/api/people_api.dart @@ -178,8 +178,10 @@ class PeopleApi { /// Parameters: /// /// * [String] closestAssetId: + /// Closest asset ID for similarity search /// /// * [String] closestPersonId: + /// Closest person ID for similarity search /// /// * [num] page: /// Page number for pagination @@ -188,6 +190,7 @@ class PeopleApi { /// Number of items per page /// /// * [bool] withHidden: + /// Include hidden people Future getAllPeopleWithHttpInfo({ String? closestAssetId, String? closestPersonId, num? page, num? size, bool? withHidden, }) async { // ignore: prefer_const_declarations final apiPath = r'/people'; @@ -236,8 +239,10 @@ class PeopleApi { /// Parameters: /// /// * [String] closestAssetId: + /// Closest asset ID for similarity search /// /// * [String] closestPersonId: + /// Closest person ID for similarity search /// /// * [num] page: /// Page number for pagination @@ -246,6 +251,7 @@ class PeopleApi { /// Number of items per page /// /// * [bool] withHidden: + /// Include hidden people Future getAllPeople({ String? closestAssetId, String? closestPersonId, num? page, num? size, bool? withHidden, }) async { final response = await getAllPeopleWithHttpInfo( closestAssetId: closestAssetId, closestPersonId: closestPersonId, page: page, size: size, withHidden: withHidden, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/queues_api.dart b/mobile/openapi/lib/api/queues_api.dart index 50575ed706322..ecb556e434e10 100644 --- a/mobile/openapi/lib/api/queues_api.dart +++ b/mobile/openapi/lib/api/queues_api.dart @@ -25,6 +25,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueDeleteDto] queueDeleteDto (required): Future emptyQueueWithHttpInfo(QueueName name, QueueDeleteDto queueDeleteDto,) async { @@ -60,6 +61,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueDeleteDto] queueDeleteDto (required): Future emptyQueue(QueueName name, QueueDeleteDto queueDeleteDto,) async { @@ -78,6 +80,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name Future getQueueWithHttpInfo(QueueName name,) async { // ignore: prefer_const_declarations final apiPath = r'/queues/{name}' @@ -111,6 +114,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name Future getQueue(QueueName name,) async { final response = await getQueueWithHttpInfo(name,); if (response.statusCode >= HttpStatus.badRequest) { @@ -135,8 +139,10 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [List] status: + /// Filter jobs by status Future getQueueJobsWithHttpInfo(QueueName name, { List? status, }) async { // ignore: prefer_const_declarations final apiPath = r'/queues/{name}/jobs' @@ -174,8 +180,10 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [List] status: + /// Filter jobs by status Future?> getQueueJobs(QueueName name, { List? status, }) async { final response = await getQueueJobsWithHttpInfo(name, status: status, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -254,6 +262,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueUpdateDto] queueUpdateDto (required): Future updateQueueWithHttpInfo(QueueName name, QueueUpdateDto queueUpdateDto,) async { @@ -289,6 +298,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): + /// Queue name /// /// * [QueueUpdateDto] queueUpdateDto (required): Future updateQueue(QueueName name, QueueUpdateDto queueUpdateDto,) async { diff --git a/mobile/openapi/lib/api/search_api.dart b/mobile/openapi/lib/api/search_api.dart index ee5f64753c376..1b8ed3d9e4c75 100644 --- a/mobile/openapi/lib/api/search_api.dart +++ b/mobile/openapi/lib/api/search_api.dart @@ -127,18 +127,25 @@ class SearchApi { /// Parameters: /// /// * [SearchSuggestionType] type (required): + /// Suggestion type /// /// * [String] country: + /// Filter by country /// /// * [bool] includeNull: + /// Include null values in suggestions /// /// * [String] lensModel: + /// Filter by lens model /// /// * [String] make: + /// Filter by camera make /// /// * [String] model: + /// Filter by camera model /// /// * [String] state: + /// Filter by state/province Future getSearchSuggestionsWithHttpInfo(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/suggestions'; @@ -191,18 +198,25 @@ class SearchApi { /// Parameters: /// /// * [SearchSuggestionType] type (required): + /// Suggestion type /// /// * [String] country: + /// Filter by country /// /// * [bool] includeNull: + /// Include null values in suggestions /// /// * [String] lensModel: + /// Filter by lens model /// /// * [String] make: + /// Filter by camera make /// /// * [String] model: + /// Filter by camera model /// /// * [String] state: + /// Filter by state/province Future?> getSearchSuggestions(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async { final response = await getSearchSuggestionsWithHttpInfo(type, country: country, includeNull: includeNull, lensModel: lensModel, make: make, model: model, state: state, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -342,68 +356,100 @@ class SearchApi { /// Parameters: /// /// * [List] albumIds: + /// Filter by album IDs /// /// * [String] city: + /// Filter by city name /// /// * [String] country: + /// Filter by country name /// /// * [DateTime] createdAfter: + /// Filter by creation date (after) /// /// * [DateTime] createdBefore: + /// Filter by creation date (before) /// /// * [String] deviceId: + /// Device ID to filter by /// /// * [bool] isEncoded: + /// Filter by encoded status /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] isMotion: + /// Filter by motion photo status /// /// * [bool] isNotInAlbum: + /// Filter assets not in any album /// /// * [bool] isOffline: + /// Filter by offline status /// /// * [String] lensModel: + /// Filter by lens model /// /// * [String] libraryId: + /// Library ID to filter by /// /// * [String] make: + /// Filter by camera make /// /// * [int] minFileSize: + /// Minimum file size in bytes /// /// * [String] model: + /// Filter by camera model /// /// * [String] ocr: + /// Filter by OCR text content /// /// * [List] personIds: + /// Filter by person IDs /// /// * [num] rating: + /// Filter by rating /// /// * [num] size: + /// Number of results to return /// /// * [String] state: + /// Filter by state/province name /// /// * [List] tagIds: + /// Filter by tag IDs /// /// * [DateTime] takenAfter: + /// Filter by taken date (after) /// /// * [DateTime] takenBefore: + /// Filter by taken date (before) /// /// * [DateTime] trashedAfter: + /// Filter by trash date (after) /// /// * [DateTime] trashedBefore: + /// Filter by trash date (before) /// /// * [AssetTypeEnum] type: + /// Asset type filter /// /// * [DateTime] updatedAfter: + /// Filter by update date (after) /// /// * [DateTime] updatedBefore: + /// Filter by update date (before) /// /// * [AssetVisibility] visibility: + /// Filter by visibility /// /// * [bool] withDeleted: + /// Include deleted assets /// /// * [bool] withExif: + /// Include EXIF data in response Future searchLargeAssetsWithHttpInfo({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, num? rating, num? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/large-assets'; @@ -533,68 +579,100 @@ class SearchApi { /// Parameters: /// /// * [List] albumIds: + /// Filter by album IDs /// /// * [String] city: + /// Filter by city name /// /// * [String] country: + /// Filter by country name /// /// * [DateTime] createdAfter: + /// Filter by creation date (after) /// /// * [DateTime] createdBefore: + /// Filter by creation date (before) /// /// * [String] deviceId: + /// Device ID to filter by /// /// * [bool] isEncoded: + /// Filter by encoded status /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] isMotion: + /// Filter by motion photo status /// /// * [bool] isNotInAlbum: + /// Filter assets not in any album /// /// * [bool] isOffline: + /// Filter by offline status /// /// * [String] lensModel: + /// Filter by lens model /// /// * [String] libraryId: + /// Library ID to filter by /// /// * [String] make: + /// Filter by camera make /// /// * [int] minFileSize: + /// Minimum file size in bytes /// /// * [String] model: + /// Filter by camera model /// /// * [String] ocr: + /// Filter by OCR text content /// /// * [List] personIds: + /// Filter by person IDs /// /// * [num] rating: + /// Filter by rating /// /// * [num] size: + /// Number of results to return /// /// * [String] state: + /// Filter by state/province name /// /// * [List] tagIds: + /// Filter by tag IDs /// /// * [DateTime] takenAfter: + /// Filter by taken date (after) /// /// * [DateTime] takenBefore: + /// Filter by taken date (before) /// /// * [DateTime] trashedAfter: + /// Filter by trash date (after) /// /// * [DateTime] trashedBefore: + /// Filter by trash date (before) /// /// * [AssetTypeEnum] type: + /// Asset type filter /// /// * [DateTime] updatedAfter: + /// Filter by update date (after) /// /// * [DateTime] updatedBefore: + /// Filter by update date (before) /// /// * [AssetVisibility] visibility: + /// Filter by visibility /// /// * [bool] withDeleted: + /// Include deleted assets /// /// * [bool] withExif: + /// Include EXIF data in response Future?> searchLargeAssets({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, num? rating, num? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { final response = await searchLargeAssetsWithHttpInfo( albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceId: deviceId, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -622,8 +700,10 @@ class SearchApi { /// Parameters: /// /// * [String] name (required): + /// Person name to search for /// /// * [bool] withHidden: + /// Include hidden people Future searchPersonWithHttpInfo(String name, { bool? withHidden, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/person'; @@ -661,8 +741,10 @@ class SearchApi { /// Parameters: /// /// * [String] name (required): + /// Person name to search for /// /// * [bool] withHidden: + /// Include hidden people Future?> searchPerson(String name, { bool? withHidden, }) async { final response = await searchPersonWithHttpInfo(name, withHidden: withHidden, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -690,6 +772,7 @@ class SearchApi { /// Parameters: /// /// * [String] name (required): + /// Place name to search for Future searchPlacesWithHttpInfo(String name,) async { // ignore: prefer_const_declarations final apiPath = r'/search/places'; @@ -724,6 +807,7 @@ class SearchApi { /// Parameters: /// /// * [String] name (required): + /// Place name to search for Future?> searchPlaces(String name,) async { final response = await searchPlacesWithHttpInfo(name,); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/shared_links_api.dart b/mobile/openapi/lib/api/shared_links_api.dart index 587a9640b440d..7f11db76d34f4 100644 --- a/mobile/openapi/lib/api/shared_links_api.dart +++ b/mobile/openapi/lib/api/shared_links_api.dart @@ -160,8 +160,10 @@ class SharedLinksApi { /// Parameters: /// /// * [String] albumId: + /// Filter by album ID /// /// * [String] id: + /// Filter by shared link ID Future getAllSharedLinksWithHttpInfo({ String? albumId, String? id, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links'; @@ -201,8 +203,10 @@ class SharedLinksApi { /// Parameters: /// /// * [String] albumId: + /// Filter by album ID /// /// * [String] id: + /// Filter by shared link ID Future?> getAllSharedLinks({ String? albumId, String? id, }) async { final response = await getAllSharedLinksWithHttpInfo( albumId: albumId, id: id, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -232,10 +236,12 @@ class SharedLinksApi { /// * [String] key: /// /// * [String] password: + /// Link password /// /// * [String] slug: /// /// * [String] token: + /// Access token Future getMySharedLinkWithHttpInfo({ String? key, String? password, String? slug, String? token, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/me'; @@ -283,10 +289,12 @@ class SharedLinksApi { /// * [String] key: /// /// * [String] password: + /// Link password /// /// * [String] slug: /// /// * [String] token: + /// Access token Future getMySharedLink({ String? key, String? password, String? slug, String? token, }) async { final response = await getMySharedLinkWithHttpInfo( key: key, password: password, slug: slug, token: token, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/stacks_api.dart b/mobile/openapi/lib/api/stacks_api.dart index 66fa1881ac395..a691af2a7d0f5 100644 --- a/mobile/openapi/lib/api/stacks_api.dart +++ b/mobile/openapi/lib/api/stacks_api.dart @@ -289,6 +289,7 @@ class StacksApi { /// Parameters: /// /// * [String] primaryAssetId: + /// Filter by primary asset ID Future searchStacksWithHttpInfo({ String? primaryAssetId, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks'; @@ -325,6 +326,7 @@ class StacksApi { /// Parameters: /// /// * [String] primaryAssetId: + /// Filter by primary asset ID Future?> searchStacks({ String? primaryAssetId, }) async { final response = await searchStacksWithHttpInfo( primaryAssetId: primaryAssetId, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/users_admin_api.dart b/mobile/openapi/lib/api/users_admin_api.dart index 842a3ebc5b674..59a4b60096172 100644 --- a/mobile/openapi/lib/api/users_admin_api.dart +++ b/mobile/openapi/lib/api/users_admin_api.dart @@ -318,10 +318,13 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] isTrashed: + /// Filter by trash status /// /// * [AssetVisibility] visibility: + /// Filter by visibility Future getUserStatisticsAdminWithHttpInfo(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}/statistics' @@ -367,10 +370,13 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [bool] isFavorite: + /// Filter by favorite status /// /// * [bool] isTrashed: + /// Filter by trash status /// /// * [AssetVisibility] visibility: + /// Filter by visibility Future getUserStatisticsAdmin(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { final response = await getUserStatisticsAdminWithHttpInfo(id, isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, ); if (response.statusCode >= HttpStatus.badRequest) { @@ -452,8 +458,10 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id: + /// User ID filter /// /// * [bool] withDeleted: + /// Include deleted users Future searchUsersAdminWithHttpInfo({ String? id, bool? withDeleted, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users'; @@ -493,8 +501,10 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id: + /// User ID filter /// /// * [bool] withDeleted: + /// Include deleted users Future?> searchUsersAdmin({ String? id, bool? withDeleted, }) async { final response = await searchUsersAdminWithHttpInfo( id: id, withDeleted: withDeleted, ); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/api/users_api.dart b/mobile/openapi/lib/api/users_api.dart index f398d9c8133f9..7ccae02c76da3 100644 --- a/mobile/openapi/lib/api/users_api.dart +++ b/mobile/openapi/lib/api/users_api.dart @@ -25,6 +25,7 @@ class UsersApi { /// Parameters: /// /// * [MultipartFile] file (required): + /// Profile image file Future createProfileImageWithHttpInfo(MultipartFile file,) async { // ignore: prefer_const_declarations final apiPath = r'/users/profile-image'; @@ -67,6 +68,7 @@ class UsersApi { /// Parameters: /// /// * [MultipartFile] file (required): + /// Profile image file Future createProfileImage(MultipartFile file,) async { final response = await createProfileImageWithHttpInfo(file,); if (response.statusCode >= HttpStatus.badRequest) { diff --git a/mobile/openapi/lib/model/activity_create_dto.dart b/mobile/openapi/lib/model/activity_create_dto.dart index ce4b4a01766a4..fb4b6d084e33d 100644 --- a/mobile/openapi/lib/model/activity_create_dto.dart +++ b/mobile/openapi/lib/model/activity_create_dto.dart @@ -19,8 +19,10 @@ class ActivityCreateDto { required this.type, }); + /// Album ID String albumId; + /// Asset ID (if activity is for an asset) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -29,6 +31,7 @@ class ActivityCreateDto { /// String? assetId; + /// Comment text (required if type is comment) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -37,6 +40,7 @@ class ActivityCreateDto { /// String? comment; + /// Activity type (like or comment) ReactionType type; @override diff --git a/mobile/openapi/lib/model/activity_response_dto.dart b/mobile/openapi/lib/model/activity_response_dto.dart index 25fb0f53f8707..dadb45d8ac655 100644 --- a/mobile/openapi/lib/model/activity_response_dto.dart +++ b/mobile/openapi/lib/model/activity_response_dto.dart @@ -21,14 +21,19 @@ class ActivityResponseDto { required this.user, }); + /// Asset ID (if activity is for an asset) String? assetId; + /// Comment text (for comment activities) String? comment; + /// Creation date DateTime createdAt; + /// Activity ID String id; + /// Activity type ReactionType type; UserResponseDto user; diff --git a/mobile/openapi/lib/model/activity_statistics_response_dto.dart b/mobile/openapi/lib/model/activity_statistics_response_dto.dart index 27c478230db34..15ad2a170e331 100644 --- a/mobile/openapi/lib/model/activity_statistics_response_dto.dart +++ b/mobile/openapi/lib/model/activity_statistics_response_dto.dart @@ -17,8 +17,10 @@ class ActivityStatisticsResponseDto { required this.likes, }); + /// Number of comments int comments; + /// Number of likes int likes; @override diff --git a/mobile/openapi/lib/model/add_users_dto.dart b/mobile/openapi/lib/model/add_users_dto.dart index 531c1ec785b45..1dad2348119e6 100644 --- a/mobile/openapi/lib/model/add_users_dto.dart +++ b/mobile/openapi/lib/model/add_users_dto.dart @@ -16,6 +16,7 @@ class AddUsersDto { this.albumUsers = const [], }); + /// Album users to add List albumUsers; @override diff --git a/mobile/openapi/lib/model/admin_onboarding_update_dto.dart b/mobile/openapi/lib/model/admin_onboarding_update_dto.dart index 298bf318a292b..6daba2a7960a7 100644 --- a/mobile/openapi/lib/model/admin_onboarding_update_dto.dart +++ b/mobile/openapi/lib/model/admin_onboarding_update_dto.dart @@ -16,6 +16,7 @@ class AdminOnboardingUpdateDto { required this.isOnboarded, }); + /// Is admin onboarded bool isOnboarded; @override diff --git a/mobile/openapi/lib/model/album_response_dto.dart b/mobile/openapi/lib/model/album_response_dto.dart index 2f53706e7ad02..43e686fbdc72c 100644 --- a/mobile/openapi/lib/model/album_response_dto.dart +++ b/mobile/openapi/lib/model/album_response_dto.dart @@ -34,22 +34,28 @@ class AlbumResponseDto { required this.updatedAt, }); + /// Album name String albumName; + /// Thumbnail asset ID String? albumThumbnailAssetId; List albumUsers; + /// Number of assets int assetCount; List assets; List contributorCounts; + /// Creation date DateTime createdAt; + /// Album description String description; + /// End date (latest asset) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -58,12 +64,16 @@ class AlbumResponseDto { /// DateTime? endDate; + /// Has shared link bool hasSharedLink; + /// Album ID String id; + /// Activity feed enabled bool isActivityEnabled; + /// Last modified asset timestamp /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -72,6 +82,7 @@ class AlbumResponseDto { /// DateTime? lastModifiedAssetTimestamp; + /// Asset sort order /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -82,10 +93,13 @@ class AlbumResponseDto { UserResponseDto owner; + /// Owner user ID String ownerId; + /// Is shared album bool shared; + /// Start date (earliest asset) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -94,6 +108,7 @@ class AlbumResponseDto { /// DateTime? startDate; + /// Last update date DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/album_statistics_response_dto.dart b/mobile/openapi/lib/model/album_statistics_response_dto.dart index 9e19002cf18c2..127334e687eff 100644 --- a/mobile/openapi/lib/model/album_statistics_response_dto.dart +++ b/mobile/openapi/lib/model/album_statistics_response_dto.dart @@ -18,10 +18,13 @@ class AlbumStatisticsResponseDto { required this.shared, }); + /// Number of non-shared albums int notShared; + /// Number of owned albums int owned; + /// Number of shared albums int shared; @override diff --git a/mobile/openapi/lib/model/album_user_add_dto.dart b/mobile/openapi/lib/model/album_user_add_dto.dart index e1f24377d728c..c448a0b4b7bd3 100644 --- a/mobile/openapi/lib/model/album_user_add_dto.dart +++ b/mobile/openapi/lib/model/album_user_add_dto.dart @@ -17,8 +17,10 @@ class AlbumUserAddDto { required this.userId, }); + /// Album user role AlbumUserRole role; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/album_user_create_dto.dart b/mobile/openapi/lib/model/album_user_create_dto.dart index 93a0661b30251..8006748341e60 100644 --- a/mobile/openapi/lib/model/album_user_create_dto.dart +++ b/mobile/openapi/lib/model/album_user_create_dto.dart @@ -17,8 +17,10 @@ class AlbumUserCreateDto { required this.userId, }); + /// Album user role AlbumUserRole role; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/album_user_response_dto.dart b/mobile/openapi/lib/model/album_user_response_dto.dart index bbae03fba74c3..8d0c01cfb8a43 100644 --- a/mobile/openapi/lib/model/album_user_response_dto.dart +++ b/mobile/openapi/lib/model/album_user_response_dto.dart @@ -17,6 +17,7 @@ class AlbumUserResponseDto { required this.user, }); + /// Album user role AlbumUserRole role; UserResponseDto user; diff --git a/mobile/openapi/lib/model/album_user_role.dart b/mobile/openapi/lib/model/album_user_role.dart index c0d61cd7f5dd0..d797fdc2e89f4 100644 --- a/mobile/openapi/lib/model/album_user_role.dart +++ b/mobile/openapi/lib/model/album_user_role.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Album user role class AlbumUserRole { /// Instantiate a new enum with the provided [value]. const AlbumUserRole._(this.value); diff --git a/mobile/openapi/lib/model/albums_add_assets_dto.dart b/mobile/openapi/lib/model/albums_add_assets_dto.dart index bdbf68980ca27..d6aa3db1c1542 100644 --- a/mobile/openapi/lib/model/albums_add_assets_dto.dart +++ b/mobile/openapi/lib/model/albums_add_assets_dto.dart @@ -17,8 +17,10 @@ class AlbumsAddAssetsDto { this.assetIds = const [], }); + /// Album IDs List albumIds; + /// Asset IDs List assetIds; @override diff --git a/mobile/openapi/lib/model/albums_add_assets_response_dto.dart b/mobile/openapi/lib/model/albums_add_assets_response_dto.dart index 4ad2c5e1509ae..743a9f064511b 100644 --- a/mobile/openapi/lib/model/albums_add_assets_response_dto.dart +++ b/mobile/openapi/lib/model/albums_add_assets_response_dto.dart @@ -17,6 +17,7 @@ class AlbumsAddAssetsResponseDto { required this.success, }); + /// Error reason /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class AlbumsAddAssetsResponseDto { /// BulkIdErrorReason? error; + /// Operation success bool success; @override diff --git a/mobile/openapi/lib/model/albums_response.dart b/mobile/openapi/lib/model/albums_response.dart index 4f9a8eb8f2d28..520ee171c10db 100644 --- a/mobile/openapi/lib/model/albums_response.dart +++ b/mobile/openapi/lib/model/albums_response.dart @@ -16,6 +16,7 @@ class AlbumsResponse { this.defaultAssetOrder = AssetOrder.desc, }); + /// Default asset order for albums AssetOrder defaultAssetOrder; @override diff --git a/mobile/openapi/lib/model/albums_update.dart b/mobile/openapi/lib/model/albums_update.dart index d61b5c1398af7..107c65dd1e226 100644 --- a/mobile/openapi/lib/model/albums_update.dart +++ b/mobile/openapi/lib/model/albums_update.dart @@ -16,6 +16,7 @@ class AlbumsUpdate { this.defaultAssetOrder, }); + /// Default asset order for albums /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/api_key_create_dto.dart b/mobile/openapi/lib/model/api_key_create_dto.dart index 848774e9c9cf7..e64b127820730 100644 --- a/mobile/openapi/lib/model/api_key_create_dto.dart +++ b/mobile/openapi/lib/model/api_key_create_dto.dart @@ -17,6 +17,7 @@ class APIKeyCreateDto { this.permissions = const [], }); + /// API key name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class APIKeyCreateDto { /// String? name; + /// List of permissions List permissions; @override diff --git a/mobile/openapi/lib/model/api_key_create_response_dto.dart b/mobile/openapi/lib/model/api_key_create_response_dto.dart index cdaa70e37de71..7540c4bb26c13 100644 --- a/mobile/openapi/lib/model/api_key_create_response_dto.dart +++ b/mobile/openapi/lib/model/api_key_create_response_dto.dart @@ -19,6 +19,7 @@ class APIKeyCreateResponseDto { APIKeyResponseDto apiKey; + /// API key secret (only shown once) String secret; @override diff --git a/mobile/openapi/lib/model/api_key_response_dto.dart b/mobile/openapi/lib/model/api_key_response_dto.dart index fd0d91f6737e3..32ba5433425d0 100644 --- a/mobile/openapi/lib/model/api_key_response_dto.dart +++ b/mobile/openapi/lib/model/api_key_response_dto.dart @@ -20,14 +20,19 @@ class APIKeyResponseDto { required this.updatedAt, }); + /// Creation date DateTime createdAt; + /// API key ID String id; + /// API key name String name; + /// List of permissions List permissions; + /// Last update date DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/api_key_update_dto.dart b/mobile/openapi/lib/model/api_key_update_dto.dart index 7f32c9511878b..ba107bcda2b94 100644 --- a/mobile/openapi/lib/model/api_key_update_dto.dart +++ b/mobile/openapi/lib/model/api_key_update_dto.dart @@ -17,6 +17,7 @@ class APIKeyUpdateDto { this.permissions = const [], }); + /// API key name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class APIKeyUpdateDto { /// String? name; + /// List of permissions List permissions; @override diff --git a/mobile/openapi/lib/model/asset_bulk_delete_dto.dart b/mobile/openapi/lib/model/asset_bulk_delete_dto.dart index c4453054b1b92..055ef1601522d 100644 --- a/mobile/openapi/lib/model/asset_bulk_delete_dto.dart +++ b/mobile/openapi/lib/model/asset_bulk_delete_dto.dart @@ -17,6 +17,7 @@ class AssetBulkDeleteDto { this.ids = const [], }); + /// Force delete even if in use /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class AssetBulkDeleteDto { /// bool? force; + /// IDs to process List ids; @override diff --git a/mobile/openapi/lib/model/asset_bulk_update_dto.dart b/mobile/openapi/lib/model/asset_bulk_update_dto.dart index d7e75ae365860..c77026586036f 100644 --- a/mobile/openapi/lib/model/asset_bulk_update_dto.dart +++ b/mobile/openapi/lib/model/asset_bulk_update_dto.dart @@ -26,6 +26,7 @@ class AssetBulkUpdateDto { this.visibility, }); + /// Original date and time /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,6 +35,7 @@ class AssetBulkUpdateDto { /// String? dateTimeOriginal; + /// Relative time offset in seconds /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -42,6 +44,7 @@ class AssetBulkUpdateDto { /// num? dateTimeRelative; + /// Asset description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -50,10 +53,13 @@ class AssetBulkUpdateDto { /// String? description; + /// Duplicate asset ID String? duplicateId; + /// Asset IDs to update List ids; + /// Mark as favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -62,6 +68,7 @@ class AssetBulkUpdateDto { /// bool? isFavorite; + /// Latitude coordinate /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -70,6 +77,7 @@ class AssetBulkUpdateDto { /// num? latitude; + /// Longitude coordinate /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -78,6 +86,8 @@ class AssetBulkUpdateDto { /// num? longitude; + /// Rating + /// /// Minimum value: -1 /// Maximum value: 5 /// @@ -88,6 +98,7 @@ class AssetBulkUpdateDto { /// num? rating; + /// Time zone (IANA timezone) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -96,6 +107,7 @@ class AssetBulkUpdateDto { /// String? timeZone; + /// Asset visibility /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/asset_bulk_upload_check_dto.dart b/mobile/openapi/lib/model/asset_bulk_upload_check_dto.dart index 36c13bfdf6889..66f46795e82b3 100644 --- a/mobile/openapi/lib/model/asset_bulk_upload_check_dto.dart +++ b/mobile/openapi/lib/model/asset_bulk_upload_check_dto.dart @@ -16,6 +16,7 @@ class AssetBulkUploadCheckDto { this.assets = const [], }); + /// Assets to check List assets; @override diff --git a/mobile/openapi/lib/model/asset_bulk_upload_check_item.dart b/mobile/openapi/lib/model/asset_bulk_upload_check_item.dart index 13dfa340fad0c..65f81926e383c 100644 --- a/mobile/openapi/lib/model/asset_bulk_upload_check_item.dart +++ b/mobile/openapi/lib/model/asset_bulk_upload_check_item.dart @@ -17,9 +17,10 @@ class AssetBulkUploadCheckItem { required this.id, }); - /// base64 or hex encoded sha1 hash + /// Base64 or hex encoded SHA1 hash String checksum; + /// Asset ID String id; @override diff --git a/mobile/openapi/lib/model/asset_bulk_upload_check_response_dto.dart b/mobile/openapi/lib/model/asset_bulk_upload_check_response_dto.dart index 8c3651e9fa189..b37bb0de8aad3 100644 --- a/mobile/openapi/lib/model/asset_bulk_upload_check_response_dto.dart +++ b/mobile/openapi/lib/model/asset_bulk_upload_check_response_dto.dart @@ -16,6 +16,7 @@ class AssetBulkUploadCheckResponseDto { this.results = const [], }); + /// Upload check results List results; @override diff --git a/mobile/openapi/lib/model/asset_bulk_upload_check_result.dart b/mobile/openapi/lib/model/asset_bulk_upload_check_result.dart index 88e46dae7daa7..b56370f689a9b 100644 --- a/mobile/openapi/lib/model/asset_bulk_upload_check_result.dart +++ b/mobile/openapi/lib/model/asset_bulk_upload_check_result.dart @@ -20,8 +20,10 @@ class AssetBulkUploadCheckResult { this.reason, }); + /// Upload action AssetBulkUploadCheckResultActionEnum action; + /// Existing asset ID if duplicate /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -30,8 +32,10 @@ class AssetBulkUploadCheckResult { /// String? assetId; + /// Asset ID String id; + /// Whether existing asset is trashed /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -40,6 +44,7 @@ class AssetBulkUploadCheckResult { /// bool? isTrashed; + /// Rejection reason if rejected AssetBulkUploadCheckResultReasonEnum? reason; @override @@ -150,7 +155,7 @@ class AssetBulkUploadCheckResult { }; } - +/// Upload action class AssetBulkUploadCheckResultActionEnum { /// Instantiate a new enum with the provided [value]. const AssetBulkUploadCheckResultActionEnum._(this.value); @@ -224,7 +229,7 @@ class AssetBulkUploadCheckResultActionEnumTypeTransformer { } - +/// Rejection reason if rejected class AssetBulkUploadCheckResultReasonEnum { /// Instantiate a new enum with the provided [value]. const AssetBulkUploadCheckResultReasonEnum._(this.value); diff --git a/mobile/openapi/lib/model/asset_copy_dto.dart b/mobile/openapi/lib/model/asset_copy_dto.dart index ba19cb1dbce42..2e68c5c113cef 100644 --- a/mobile/openapi/lib/model/asset_copy_dto.dart +++ b/mobile/openapi/lib/model/asset_copy_dto.dart @@ -22,18 +22,25 @@ class AssetCopyDto { required this.targetId, }); + /// Copy album associations bool albums; + /// Copy favorite status bool favorite; + /// Copy shared links bool sharedLinks; + /// Copy sidecar file bool sidecar; + /// Source asset ID String sourceId; + /// Copy stack association bool stack; + /// Target asset ID String targetId; @override diff --git a/mobile/openapi/lib/model/asset_delta_sync_dto.dart b/mobile/openapi/lib/model/asset_delta_sync_dto.dart index 845aadcdcd3b4..22c09752d2958 100644 --- a/mobile/openapi/lib/model/asset_delta_sync_dto.dart +++ b/mobile/openapi/lib/model/asset_delta_sync_dto.dart @@ -17,8 +17,10 @@ class AssetDeltaSyncDto { this.userIds = const [], }); + /// Sync assets updated after this date DateTime updatedAfter; + /// User IDs to sync List userIds; @override diff --git a/mobile/openapi/lib/model/asset_delta_sync_response_dto.dart b/mobile/openapi/lib/model/asset_delta_sync_response_dto.dart index a64e1a2fbee42..7351840b11c60 100644 --- a/mobile/openapi/lib/model/asset_delta_sync_response_dto.dart +++ b/mobile/openapi/lib/model/asset_delta_sync_response_dto.dart @@ -18,10 +18,13 @@ class AssetDeltaSyncResponseDto { this.upserted = const [], }); + /// Deleted asset IDs List deleted; + /// Whether full sync is needed bool needsFullSync; + /// Upserted assets List upserted; @override diff --git a/mobile/openapi/lib/model/asset_edit_action.dart b/mobile/openapi/lib/model/asset_edit_action.dart index 12aacfb68a9dc..3754cb4501148 100644 --- a/mobile/openapi/lib/model/asset_edit_action.dart +++ b/mobile/openapi/lib/model/asset_edit_action.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Type of edit action to perform class AssetEditAction { /// Instantiate a new enum with the provided [value]. const AssetEditAction._(this.value); diff --git a/mobile/openapi/lib/model/asset_edit_action_crop.dart b/mobile/openapi/lib/model/asset_edit_action_crop.dart index 3b55a105d92fe..7672ed825b5b2 100644 --- a/mobile/openapi/lib/model/asset_edit_action_crop.dart +++ b/mobile/openapi/lib/model/asset_edit_action_crop.dart @@ -17,6 +17,7 @@ class AssetEditActionCrop { required this.parameters, }); + /// Type of edit action to perform AssetEditAction action; CropParameters parameters; diff --git a/mobile/openapi/lib/model/asset_edit_action_list_dto.dart b/mobile/openapi/lib/model/asset_edit_action_list_dto.dart index 48c1e15922932..e843c66e8feab 100644 --- a/mobile/openapi/lib/model/asset_edit_action_list_dto.dart +++ b/mobile/openapi/lib/model/asset_edit_action_list_dto.dart @@ -16,7 +16,7 @@ class AssetEditActionListDto { this.edits = const [], }); - /// list of edits + /// List of edit actions to apply (crop, rotate, or mirror) List edits; @override diff --git a/mobile/openapi/lib/model/asset_edit_action_list_dto_edits_inner.dart b/mobile/openapi/lib/model/asset_edit_action_list_dto_edits_inner.dart index c4c0496631666..00c9be238138d 100644 --- a/mobile/openapi/lib/model/asset_edit_action_list_dto_edits_inner.dart +++ b/mobile/openapi/lib/model/asset_edit_action_list_dto_edits_inner.dart @@ -17,6 +17,7 @@ class AssetEditActionListDtoEditsInner { required this.parameters, }); + /// Type of edit action to perform AssetEditAction action; MirrorParameters parameters; diff --git a/mobile/openapi/lib/model/asset_edit_action_mirror.dart b/mobile/openapi/lib/model/asset_edit_action_mirror.dart index 782d317b7b9ac..aef98fc1a81c4 100644 --- a/mobile/openapi/lib/model/asset_edit_action_mirror.dart +++ b/mobile/openapi/lib/model/asset_edit_action_mirror.dart @@ -17,6 +17,7 @@ class AssetEditActionMirror { required this.parameters, }); + /// Type of edit action to perform AssetEditAction action; MirrorParameters parameters; diff --git a/mobile/openapi/lib/model/asset_edit_action_rotate.dart b/mobile/openapi/lib/model/asset_edit_action_rotate.dart index 1104c06307e14..302e6a0ce6306 100644 --- a/mobile/openapi/lib/model/asset_edit_action_rotate.dart +++ b/mobile/openapi/lib/model/asset_edit_action_rotate.dart @@ -17,6 +17,7 @@ class AssetEditActionRotate { required this.parameters, }); + /// Type of edit action to perform AssetEditAction action; RotateParameters parameters; diff --git a/mobile/openapi/lib/model/asset_edits_dto.dart b/mobile/openapi/lib/model/asset_edits_dto.dart index 26757dce3bb3f..3bfbce8594329 100644 --- a/mobile/openapi/lib/model/asset_edits_dto.dart +++ b/mobile/openapi/lib/model/asset_edits_dto.dart @@ -17,9 +17,10 @@ class AssetEditsDto { this.edits = const [], }); + /// Asset ID to apply edits to String assetId; - /// list of edits + /// List of edit actions to apply (crop, rotate, or mirror) List edits; @override diff --git a/mobile/openapi/lib/model/asset_face_create_dto.dart b/mobile/openapi/lib/model/asset_face_create_dto.dart index 29e8244a9623d..3ecc20c699e96 100644 --- a/mobile/openapi/lib/model/asset_face_create_dto.dart +++ b/mobile/openapi/lib/model/asset_face_create_dto.dart @@ -23,20 +23,28 @@ class AssetFaceCreateDto { required this.y, }); + /// Asset ID String assetId; + /// Face bounding box height int height; + /// Image height in pixels int imageHeight; + /// Image width in pixels int imageWidth; + /// Person ID String personId; + /// Face bounding box width int width; + /// Face bounding box X coordinate int x; + /// Face bounding box Y coordinate int y; @override diff --git a/mobile/openapi/lib/model/asset_face_delete_dto.dart b/mobile/openapi/lib/model/asset_face_delete_dto.dart index 2e53b0699c047..a1f3731beab9f 100644 --- a/mobile/openapi/lib/model/asset_face_delete_dto.dart +++ b/mobile/openapi/lib/model/asset_face_delete_dto.dart @@ -16,6 +16,7 @@ class AssetFaceDeleteDto { required this.force, }); + /// Force delete even if person has other faces bool force; @override diff --git a/mobile/openapi/lib/model/asset_face_response_dto.dart b/mobile/openapi/lib/model/asset_face_response_dto.dart index c05b511649236..61d972a0c493f 100644 --- a/mobile/openapi/lib/model/asset_face_response_dto.dart +++ b/mobile/openapi/lib/model/asset_face_response_dto.dart @@ -24,22 +24,31 @@ class AssetFaceResponseDto { this.sourceType, }); + /// Bounding box X1 coordinate int boundingBoxX1; + /// Bounding box X2 coordinate int boundingBoxX2; + /// Bounding box Y1 coordinate int boundingBoxY1; + /// Bounding box Y2 coordinate int boundingBoxY2; + /// Face ID String id; + /// Image height in pixels int imageHeight; + /// Image width in pixels int imageWidth; + /// Person associated with face PersonResponseDto? person; + /// Face detection source type /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/asset_face_update_dto.dart b/mobile/openapi/lib/model/asset_face_update_dto.dart index 71bdde8e9a6a3..10276275520f4 100644 --- a/mobile/openapi/lib/model/asset_face_update_dto.dart +++ b/mobile/openapi/lib/model/asset_face_update_dto.dart @@ -16,6 +16,7 @@ class AssetFaceUpdateDto { this.data = const [], }); + /// Face update items List data; @override diff --git a/mobile/openapi/lib/model/asset_face_update_item.dart b/mobile/openapi/lib/model/asset_face_update_item.dart index c2c48032595dc..a81b21e13982b 100644 --- a/mobile/openapi/lib/model/asset_face_update_item.dart +++ b/mobile/openapi/lib/model/asset_face_update_item.dart @@ -17,8 +17,10 @@ class AssetFaceUpdateItem { required this.personId, }); + /// Asset ID String assetId; + /// Person ID String personId; @override diff --git a/mobile/openapi/lib/model/asset_face_without_person_response_dto.dart b/mobile/openapi/lib/model/asset_face_without_person_response_dto.dart index 8bf07e15347ca..1ae5cef07e9d4 100644 --- a/mobile/openapi/lib/model/asset_face_without_person_response_dto.dart +++ b/mobile/openapi/lib/model/asset_face_without_person_response_dto.dart @@ -23,20 +23,28 @@ class AssetFaceWithoutPersonResponseDto { this.sourceType, }); + /// Bounding box X1 coordinate int boundingBoxX1; + /// Bounding box X2 coordinate int boundingBoxX2; + /// Bounding box Y1 coordinate int boundingBoxY1; + /// Bounding box Y2 coordinate int boundingBoxY2; + /// Face ID String id; + /// Image height in pixels int imageHeight; + /// Image width in pixels int imageWidth; + /// Face detection source type /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/asset_full_sync_dto.dart b/mobile/openapi/lib/model/asset_full_sync_dto.dart index 7151094b9588c..3fabb1cac65d4 100644 --- a/mobile/openapi/lib/model/asset_full_sync_dto.dart +++ b/mobile/openapi/lib/model/asset_full_sync_dto.dart @@ -19,6 +19,7 @@ class AssetFullSyncDto { this.userId, }); + /// Last asset ID (pagination) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -27,11 +28,15 @@ class AssetFullSyncDto { /// String? lastId; + /// Maximum number of assets to return + /// /// Minimum value: 1 int limit; + /// Sync assets updated until this date DateTime updatedUntil; + /// Filter by user ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/asset_ids_dto.dart b/mobile/openapi/lib/model/asset_ids_dto.dart index b44888f3962b3..85e5cc3aee66b 100644 --- a/mobile/openapi/lib/model/asset_ids_dto.dart +++ b/mobile/openapi/lib/model/asset_ids_dto.dart @@ -16,6 +16,7 @@ class AssetIdsDto { this.assetIds = const [], }); + /// Asset IDs List assetIds; @override diff --git a/mobile/openapi/lib/model/asset_ids_response_dto.dart b/mobile/openapi/lib/model/asset_ids_response_dto.dart index ff63091caa577..974528302119a 100644 --- a/mobile/openapi/lib/model/asset_ids_response_dto.dart +++ b/mobile/openapi/lib/model/asset_ids_response_dto.dart @@ -18,10 +18,13 @@ class AssetIdsResponseDto { required this.success, }); + /// Asset ID String assetId; + /// Error reason if failed AssetIdsResponseDtoErrorEnum? error; + /// Whether operation succeeded bool success; @override @@ -116,7 +119,7 @@ class AssetIdsResponseDto { }; } - +/// Error reason if failed class AssetIdsResponseDtoErrorEnum { /// Instantiate a new enum with the provided [value]. const AssetIdsResponseDtoErrorEnum._(this.value); diff --git a/mobile/openapi/lib/model/asset_job_name.dart b/mobile/openapi/lib/model/asset_job_name.dart index 11e0555b868d4..7625677bb5851 100644 --- a/mobile/openapi/lib/model/asset_job_name.dart +++ b/mobile/openapi/lib/model/asset_job_name.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Job name class AssetJobName { /// Instantiate a new enum with the provided [value]. const AssetJobName._(this.value); diff --git a/mobile/openapi/lib/model/asset_jobs_dto.dart b/mobile/openapi/lib/model/asset_jobs_dto.dart index 0f8bfab009fa1..0aa5544a3aebb 100644 --- a/mobile/openapi/lib/model/asset_jobs_dto.dart +++ b/mobile/openapi/lib/model/asset_jobs_dto.dart @@ -17,8 +17,10 @@ class AssetJobsDto { required this.name, }); + /// Asset IDs List assetIds; + /// Job name AssetJobName name; @override diff --git a/mobile/openapi/lib/model/asset_media_response_dto.dart b/mobile/openapi/lib/model/asset_media_response_dto.dart index 75428ec5f61d8..905e738b6ee93 100644 --- a/mobile/openapi/lib/model/asset_media_response_dto.dart +++ b/mobile/openapi/lib/model/asset_media_response_dto.dart @@ -17,8 +17,10 @@ class AssetMediaResponseDto { required this.status, }); + /// Asset media ID String id; + /// Upload status AssetMediaStatus status; @override diff --git a/mobile/openapi/lib/model/asset_media_status.dart b/mobile/openapi/lib/model/asset_media_status.dart index 42fec08cc7eb4..b45918e5c3b8f 100644 --- a/mobile/openapi/lib/model/asset_media_status.dart +++ b/mobile/openapi/lib/model/asset_media_status.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Upload status class AssetMediaStatus { /// Instantiate a new enum with the provided [value]. const AssetMediaStatus._(this.value); diff --git a/mobile/openapi/lib/model/asset_metadata_bulk_delete_dto.dart b/mobile/openapi/lib/model/asset_metadata_bulk_delete_dto.dart index 23c34d7152c5f..6376ebc531a16 100644 --- a/mobile/openapi/lib/model/asset_metadata_bulk_delete_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_bulk_delete_dto.dart @@ -16,6 +16,7 @@ class AssetMetadataBulkDeleteDto { this.items = const [], }); + /// Metadata items to delete List items; @override diff --git a/mobile/openapi/lib/model/asset_metadata_bulk_delete_item_dto.dart b/mobile/openapi/lib/model/asset_metadata_bulk_delete_item_dto.dart index a3a111f9f72c8..90417b79e053d 100644 --- a/mobile/openapi/lib/model/asset_metadata_bulk_delete_item_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_bulk_delete_item_dto.dart @@ -17,8 +17,10 @@ class AssetMetadataBulkDeleteItemDto { required this.key, }); + /// Asset ID String assetId; + /// Metadata key String key; @override diff --git a/mobile/openapi/lib/model/asset_metadata_bulk_response_dto.dart b/mobile/openapi/lib/model/asset_metadata_bulk_response_dto.dart index 15c130930bef1..b79a69372686f 100644 --- a/mobile/openapi/lib/model/asset_metadata_bulk_response_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_bulk_response_dto.dart @@ -19,12 +19,16 @@ class AssetMetadataBulkResponseDto { required this.value, }); + /// Asset ID String assetId; + /// Metadata key String key; + /// Last update date DateTime updatedAt; + /// Metadata value (object) Object value; @override diff --git a/mobile/openapi/lib/model/asset_metadata_bulk_upsert_dto.dart b/mobile/openapi/lib/model/asset_metadata_bulk_upsert_dto.dart index fe9d9ed251122..a5e770b02adcc 100644 --- a/mobile/openapi/lib/model/asset_metadata_bulk_upsert_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_bulk_upsert_dto.dart @@ -16,6 +16,7 @@ class AssetMetadataBulkUpsertDto { this.items = const [], }); + /// Metadata items to upsert List items; @override diff --git a/mobile/openapi/lib/model/asset_metadata_bulk_upsert_item_dto.dart b/mobile/openapi/lib/model/asset_metadata_bulk_upsert_item_dto.dart index 25a219537eda8..caaf379b30488 100644 --- a/mobile/openapi/lib/model/asset_metadata_bulk_upsert_item_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_bulk_upsert_item_dto.dart @@ -18,10 +18,13 @@ class AssetMetadataBulkUpsertItemDto { required this.value, }); + /// Asset ID String assetId; + /// Metadata key String key; + /// Metadata value (object) Object value; @override diff --git a/mobile/openapi/lib/model/asset_metadata_response_dto.dart b/mobile/openapi/lib/model/asset_metadata_response_dto.dart index cccf42ae87ed0..2c3faab178019 100644 --- a/mobile/openapi/lib/model/asset_metadata_response_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_response_dto.dart @@ -18,10 +18,13 @@ class AssetMetadataResponseDto { required this.value, }); + /// Metadata key String key; + /// Last update date DateTime updatedAt; + /// Metadata value (object) Object value; @override diff --git a/mobile/openapi/lib/model/asset_metadata_upsert_dto.dart b/mobile/openapi/lib/model/asset_metadata_upsert_dto.dart index 45d044feb0f55..b1473d4826619 100644 --- a/mobile/openapi/lib/model/asset_metadata_upsert_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_upsert_dto.dart @@ -16,6 +16,7 @@ class AssetMetadataUpsertDto { this.items = const [], }); + /// Metadata items to upsert List items; @override diff --git a/mobile/openapi/lib/model/asset_metadata_upsert_item_dto.dart b/mobile/openapi/lib/model/asset_metadata_upsert_item_dto.dart index 3d247f8572762..8a6bcb9b01c0a 100644 --- a/mobile/openapi/lib/model/asset_metadata_upsert_item_dto.dart +++ b/mobile/openapi/lib/model/asset_metadata_upsert_item_dto.dart @@ -17,8 +17,10 @@ class AssetMetadataUpsertItemDto { required this.value, }); + /// Metadata key String key; + /// Metadata value (object) Object value; @override diff --git a/mobile/openapi/lib/model/asset_order.dart b/mobile/openapi/lib/model/asset_order.dart index ca04e2b78f4e2..21edd95ff6efb 100644 --- a/mobile/openapi/lib/model/asset_order.dart +++ b/mobile/openapi/lib/model/asset_order.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Asset sort order class AssetOrder { /// Instantiate a new enum with the provided [value]. const AssetOrder._(this.value); diff --git a/mobile/openapi/lib/model/asset_response_dto.dart b/mobile/openapi/lib/model/asset_response_dto.dart index 27aa3b98f35b6..5422ccf55f9de 100644 --- a/mobile/openapi/lib/model/asset_response_dto.dart +++ b/mobile/openapi/lib/model/asset_response_dto.dart @@ -50,18 +50,22 @@ class AssetResponseDto { required this.width, }); - /// base64 encoded sha1 hash + /// Base64 encoded SHA1 hash String checksum; /// The UTC timestamp when the asset was originally uploaded to Immich. DateTime createdAt; + /// Device asset ID String deviceAssetId; + /// Device ID String deviceId; + /// Duplicate group ID String? duplicateId; + /// Video duration (for videos) String duration; /// @@ -78,31 +82,43 @@ class AssetResponseDto { /// The UTC timestamp when the file was last modified on the filesystem. This reflects the last time the physical file was changed, which may be different from when the photo was originally taken. DateTime fileModifiedAt; + /// Whether asset has metadata bool hasMetadata; + /// Asset height num? height; + /// Asset ID String id; + /// Is archived bool isArchived; + /// Is edited bool isEdited; + /// Is favorite bool isFavorite; + /// Is offline bool isOffline; + /// Is trashed bool isTrashed; + /// Library ID String? libraryId; + /// Live photo video ID String? livePhotoVideoId; /// The local date and time when the photo/video was taken, derived from EXIF metadata. This represents the photographer's local time regardless of timezone, stored as a timezone-agnostic timestamp. Used for timeline grouping by \"local\" days and months. DateTime localDateTime; + /// Original file name String originalFileName; + /// Original MIME type /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -111,6 +127,7 @@ class AssetResponseDto { /// String? originalMimeType; + /// Original file path String originalPath; /// @@ -121,10 +138,12 @@ class AssetResponseDto { /// UserResponseDto? owner; + /// Owner user ID String ownerId; List people; + /// Is resized /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -137,8 +156,10 @@ class AssetResponseDto { List tags; + /// Thumbhash for thumbnail generation String? thumbhash; + /// Asset type AssetTypeEnum type; List unassignedFaces; @@ -146,8 +167,10 @@ class AssetResponseDto { /// The UTC timestamp when the asset record was last updated in the database. This is automatically maintained by the database and reflects when any field in the asset was last modified. DateTime updatedAt; + /// Asset visibility AssetVisibility visibility; + /// Asset width num? width; @override diff --git a/mobile/openapi/lib/model/asset_stack_response_dto.dart b/mobile/openapi/lib/model/asset_stack_response_dto.dart index bb4becb129c17..229e7aa710023 100644 --- a/mobile/openapi/lib/model/asset_stack_response_dto.dart +++ b/mobile/openapi/lib/model/asset_stack_response_dto.dart @@ -18,10 +18,13 @@ class AssetStackResponseDto { required this.primaryAssetId, }); + /// Number of assets in stack int assetCount; + /// Stack ID String id; + /// Primary asset ID String primaryAssetId; @override diff --git a/mobile/openapi/lib/model/asset_stats_response_dto.dart b/mobile/openapi/lib/model/asset_stats_response_dto.dart index d11ce55a5cc5c..201550c87fe22 100644 --- a/mobile/openapi/lib/model/asset_stats_response_dto.dart +++ b/mobile/openapi/lib/model/asset_stats_response_dto.dart @@ -18,10 +18,13 @@ class AssetStatsResponseDto { required this.videos, }); + /// Number of images int images; + /// Total number of assets int total; + /// Number of videos int videos; @override diff --git a/mobile/openapi/lib/model/asset_type_enum.dart b/mobile/openapi/lib/model/asset_type_enum.dart index 1022beb24e621..b6e0351198d32 100644 --- a/mobile/openapi/lib/model/asset_type_enum.dart +++ b/mobile/openapi/lib/model/asset_type_enum.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Asset type class AssetTypeEnum { /// Instantiate a new enum with the provided [value]. const AssetTypeEnum._(this.value); diff --git a/mobile/openapi/lib/model/asset_visibility.dart b/mobile/openapi/lib/model/asset_visibility.dart index 498bf17c38242..6290dffb2eea0 100644 --- a/mobile/openapi/lib/model/asset_visibility.dart +++ b/mobile/openapi/lib/model/asset_visibility.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Asset visibility class AssetVisibility { /// Instantiate a new enum with the provided [value]. const AssetVisibility._(this.value); diff --git a/mobile/openapi/lib/model/audio_codec.dart b/mobile/openapi/lib/model/audio_codec.dart index ea1e96f36e00a..095c616995fac 100644 --- a/mobile/openapi/lib/model/audio_codec.dart +++ b/mobile/openapi/lib/model/audio_codec.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Target audio codec class AudioCodec { /// Instantiate a new enum with the provided [value]. const AudioCodec._(this.value); diff --git a/mobile/openapi/lib/model/auth_status_response_dto.dart b/mobile/openapi/lib/model/auth_status_response_dto.dart index 4e823506ee079..23b9d405252ed 100644 --- a/mobile/openapi/lib/model/auth_status_response_dto.dart +++ b/mobile/openapi/lib/model/auth_status_response_dto.dart @@ -20,6 +20,7 @@ class AuthStatusResponseDto { this.pinExpiresAt, }); + /// Session expiration date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -28,12 +29,16 @@ class AuthStatusResponseDto { /// String? expiresAt; + /// Is elevated session bool isElevated; + /// Has password set bool password; + /// Has PIN code set bool pinCode; + /// PIN expiration date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/avatar_update.dart b/mobile/openapi/lib/model/avatar_update.dart index 875eb138a8dbf..a817832dab0e3 100644 --- a/mobile/openapi/lib/model/avatar_update.dart +++ b/mobile/openapi/lib/model/avatar_update.dart @@ -16,6 +16,7 @@ class AvatarUpdate { this.color, }); + /// Avatar color /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/bulk_id_error_reason.dart b/mobile/openapi/lib/model/bulk_id_error_reason.dart index cdaf70217e92a..ea56e9dbbaf4e 100644 --- a/mobile/openapi/lib/model/bulk_id_error_reason.dart +++ b/mobile/openapi/lib/model/bulk_id_error_reason.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Error reason class BulkIdErrorReason { /// Instantiate a new enum with the provided [value]. const BulkIdErrorReason._(this.value); diff --git a/mobile/openapi/lib/model/bulk_id_response_dto.dart b/mobile/openapi/lib/model/bulk_id_response_dto.dart index 67a587e8d001e..cd122785dd2cb 100644 --- a/mobile/openapi/lib/model/bulk_id_response_dto.dart +++ b/mobile/openapi/lib/model/bulk_id_response_dto.dart @@ -18,10 +18,13 @@ class BulkIdResponseDto { required this.success, }); + /// Error reason if failed BulkIdResponseDtoErrorEnum? error; + /// ID String id; + /// Whether operation succeeded bool success; @override @@ -116,7 +119,7 @@ class BulkIdResponseDto { }; } - +/// Error reason if failed class BulkIdResponseDtoErrorEnum { /// Instantiate a new enum with the provided [value]. const BulkIdResponseDtoErrorEnum._(this.value); diff --git a/mobile/openapi/lib/model/bulk_ids_dto.dart b/mobile/openapi/lib/model/bulk_ids_dto.dart index 6a7f8ceeec6f6..7e7864a2850c9 100644 --- a/mobile/openapi/lib/model/bulk_ids_dto.dart +++ b/mobile/openapi/lib/model/bulk_ids_dto.dart @@ -16,6 +16,7 @@ class BulkIdsDto { this.ids = const [], }); + /// IDs to process List ids; @override diff --git a/mobile/openapi/lib/model/cast_response.dart b/mobile/openapi/lib/model/cast_response.dart index d49f1ad3d766e..0b7f0738fe7b5 100644 --- a/mobile/openapi/lib/model/cast_response.dart +++ b/mobile/openapi/lib/model/cast_response.dart @@ -16,6 +16,7 @@ class CastResponse { this.gCastEnabled = false, }); + /// Whether Google Cast is enabled bool gCastEnabled; @override diff --git a/mobile/openapi/lib/model/cast_update.dart b/mobile/openapi/lib/model/cast_update.dart index 87076391325c5..8dbf80f171a82 100644 --- a/mobile/openapi/lib/model/cast_update.dart +++ b/mobile/openapi/lib/model/cast_update.dart @@ -16,6 +16,7 @@ class CastUpdate { this.gCastEnabled, }); + /// Whether Google Cast is enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/change_password_dto.dart b/mobile/openapi/lib/model/change_password_dto.dart index 4a897f4079aca..3dd6e437da841 100644 --- a/mobile/openapi/lib/model/change_password_dto.dart +++ b/mobile/openapi/lib/model/change_password_dto.dart @@ -18,10 +18,13 @@ class ChangePasswordDto { required this.password, }); + /// Invalidate all other sessions bool invalidateSessions; + /// New password (min 8 characters) String newPassword; + /// Current password String password; @override diff --git a/mobile/openapi/lib/model/check_existing_assets_dto.dart b/mobile/openapi/lib/model/check_existing_assets_dto.dart index 42ce6d5c3ea0c..6e4a4710924a5 100644 --- a/mobile/openapi/lib/model/check_existing_assets_dto.dart +++ b/mobile/openapi/lib/model/check_existing_assets_dto.dart @@ -17,8 +17,10 @@ class CheckExistingAssetsDto { required this.deviceId, }); + /// Device asset IDs to check List deviceAssetIds; + /// Device ID String deviceId; @override diff --git a/mobile/openapi/lib/model/check_existing_assets_response_dto.dart b/mobile/openapi/lib/model/check_existing_assets_response_dto.dart index ad93578ebc34c..9fb13f100fb4f 100644 --- a/mobile/openapi/lib/model/check_existing_assets_response_dto.dart +++ b/mobile/openapi/lib/model/check_existing_assets_response_dto.dart @@ -16,6 +16,7 @@ class CheckExistingAssetsResponseDto { this.existingIds = const [], }); + /// Existing asset IDs List existingIds; @override diff --git a/mobile/openapi/lib/model/clip_config.dart b/mobile/openapi/lib/model/clip_config.dart index b500d20f2e6eb..915e4975ed74d 100644 --- a/mobile/openapi/lib/model/clip_config.dart +++ b/mobile/openapi/lib/model/clip_config.dart @@ -17,8 +17,10 @@ class CLIPConfig { required this.modelName, }); + /// Whether the task is enabled bool enabled; + /// Name of the model to use String modelName; @override diff --git a/mobile/openapi/lib/model/colorspace.dart b/mobile/openapi/lib/model/colorspace.dart index e0c1658be5a3d..e871e140fb241 100644 --- a/mobile/openapi/lib/model/colorspace.dart +++ b/mobile/openapi/lib/model/colorspace.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Colorspace class Colorspace { /// Instantiate a new enum with the provided [value]. const Colorspace._(this.value); diff --git a/mobile/openapi/lib/model/contributor_count_response_dto.dart b/mobile/openapi/lib/model/contributor_count_response_dto.dart index e0e16ee427543..1bef8f29d829b 100644 --- a/mobile/openapi/lib/model/contributor_count_response_dto.dart +++ b/mobile/openapi/lib/model/contributor_count_response_dto.dart @@ -17,8 +17,10 @@ class ContributorCountResponseDto { required this.userId, }); + /// Number of assets contributed int assetCount; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/cq_mode.dart b/mobile/openapi/lib/model/cq_mode.dart index f660fabf1f540..efd788b5fbd66 100644 --- a/mobile/openapi/lib/model/cq_mode.dart +++ b/mobile/openapi/lib/model/cq_mode.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// CQ mode class CQMode { /// Instantiate a new enum with the provided [value]. const CQMode._(this.value); diff --git a/mobile/openapi/lib/model/create_album_dto.dart b/mobile/openapi/lib/model/create_album_dto.dart index ff8c1df647fdc..183a41c772f67 100644 --- a/mobile/openapi/lib/model/create_album_dto.dart +++ b/mobile/openapi/lib/model/create_album_dto.dart @@ -19,12 +19,16 @@ class CreateAlbumDto { this.description, }); + /// Album name String albumName; + /// Album users List albumUsers; + /// Initial asset IDs List assetIds; + /// Album description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/create_library_dto.dart b/mobile/openapi/lib/model/create_library_dto.dart index 2b8085be6f3a6..69942fee5c7ed 100644 --- a/mobile/openapi/lib/model/create_library_dto.dart +++ b/mobile/openapi/lib/model/create_library_dto.dart @@ -19,10 +19,13 @@ class CreateLibraryDto { required this.ownerId, }); + /// Exclusion patterns (max 128) Set exclusionPatterns; + /// Import paths (max 128) Set importPaths; + /// Library name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -31,6 +34,7 @@ class CreateLibraryDto { /// String? name; + /// Owner user ID String ownerId; @override diff --git a/mobile/openapi/lib/model/create_profile_image_response_dto.dart b/mobile/openapi/lib/model/create_profile_image_response_dto.dart index ee98142e86097..20d7cbd5e703c 100644 --- a/mobile/openapi/lib/model/create_profile_image_response_dto.dart +++ b/mobile/openapi/lib/model/create_profile_image_response_dto.dart @@ -18,10 +18,13 @@ class CreateProfileImageResponseDto { required this.userId, }); + /// Profile image change date DateTime profileChangedAt; + /// Profile image file path String profileImagePath; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/database_backup_config.dart b/mobile/openapi/lib/model/database_backup_config.dart index d82128bd4443a..419968c3f3c98 100644 --- a/mobile/openapi/lib/model/database_backup_config.dart +++ b/mobile/openapi/lib/model/database_backup_config.dart @@ -18,10 +18,14 @@ class DatabaseBackupConfig { required this.keepLastAmount, }); + /// Cron expression String cronExpression; + /// Enabled bool enabled; + /// Keep last amount + /// /// Minimum value: 1 num keepLastAmount; diff --git a/mobile/openapi/lib/model/download_archive_info.dart b/mobile/openapi/lib/model/download_archive_info.dart index 5f3fd1a8c1f3d..97a3346a67ba2 100644 --- a/mobile/openapi/lib/model/download_archive_info.dart +++ b/mobile/openapi/lib/model/download_archive_info.dart @@ -17,8 +17,10 @@ class DownloadArchiveInfo { required this.size, }); + /// Asset IDs in this archive List assetIds; + /// Archive size in bytes int size; @override diff --git a/mobile/openapi/lib/model/download_info_dto.dart b/mobile/openapi/lib/model/download_info_dto.dart index 6f4777975c6b2..a1ba44920ede8 100644 --- a/mobile/openapi/lib/model/download_info_dto.dart +++ b/mobile/openapi/lib/model/download_info_dto.dart @@ -19,6 +19,7 @@ class DownloadInfoDto { this.userId, }); + /// Album ID to download /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -27,6 +28,8 @@ class DownloadInfoDto { /// String? albumId; + /// Archive size limit in bytes + /// /// Minimum value: 1 /// /// Please note: This property should have been non-nullable! Since the specification file @@ -36,8 +39,10 @@ class DownloadInfoDto { /// int? archiveSize; + /// Asset IDs to download List assetIds; + /// User ID to download assets from /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/download_response.dart b/mobile/openapi/lib/model/download_response.dart index 041da44b718bc..32e9487475ecc 100644 --- a/mobile/openapi/lib/model/download_response.dart +++ b/mobile/openapi/lib/model/download_response.dart @@ -17,8 +17,10 @@ class DownloadResponse { this.includeEmbeddedVideos = false, }); + /// Maximum archive size in bytes int archiveSize; + /// Whether to include embedded videos in downloads bool includeEmbeddedVideos; @override diff --git a/mobile/openapi/lib/model/download_response_dto.dart b/mobile/openapi/lib/model/download_response_dto.dart index 5c6bd112661e8..81912e1d3044a 100644 --- a/mobile/openapi/lib/model/download_response_dto.dart +++ b/mobile/openapi/lib/model/download_response_dto.dart @@ -17,8 +17,10 @@ class DownloadResponseDto { required this.totalSize, }); + /// Archive information List archives; + /// Total size in bytes int totalSize; @override diff --git a/mobile/openapi/lib/model/download_update.dart b/mobile/openapi/lib/model/download_update.dart index 8df825a922315..4acc1c8bd3511 100644 --- a/mobile/openapi/lib/model/download_update.dart +++ b/mobile/openapi/lib/model/download_update.dart @@ -17,6 +17,8 @@ class DownloadUpdate { this.includeEmbeddedVideos, }); + /// Maximum archive size in bytes + /// /// Minimum value: 1 /// /// Please note: This property should have been non-nullable! Since the specification file @@ -26,6 +28,7 @@ class DownloadUpdate { /// int? archiveSize; + /// Whether to include embedded videos in downloads /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/duplicate_detection_config.dart b/mobile/openapi/lib/model/duplicate_detection_config.dart index e4fc352028ec0..43233826ef122 100644 --- a/mobile/openapi/lib/model/duplicate_detection_config.dart +++ b/mobile/openapi/lib/model/duplicate_detection_config.dart @@ -17,8 +17,11 @@ class DuplicateDetectionConfig { required this.maxDistance, }); + /// Whether the task is enabled bool enabled; + /// Maximum distance threshold for duplicate detection + /// /// Minimum value: 0.001 /// Maximum value: 0.1 double maxDistance; diff --git a/mobile/openapi/lib/model/duplicate_response_dto.dart b/mobile/openapi/lib/model/duplicate_response_dto.dart index 6ac7c468711e0..6c85dc8013713 100644 --- a/mobile/openapi/lib/model/duplicate_response_dto.dart +++ b/mobile/openapi/lib/model/duplicate_response_dto.dart @@ -17,8 +17,10 @@ class DuplicateResponseDto { required this.duplicateId, }); + /// Duplicate assets List assets; + /// Duplicate group ID String duplicateId; @override diff --git a/mobile/openapi/lib/model/email_notifications_response.dart b/mobile/openapi/lib/model/email_notifications_response.dart index d6dcfb9273be6..08a3d580c6db4 100644 --- a/mobile/openapi/lib/model/email_notifications_response.dart +++ b/mobile/openapi/lib/model/email_notifications_response.dart @@ -18,10 +18,13 @@ class EmailNotificationsResponse { required this.enabled, }); + /// Whether to receive email notifications for album invites bool albumInvite; + /// Whether to receive email notifications for album updates bool albumUpdate; + /// Whether email notifications are enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/email_notifications_update.dart b/mobile/openapi/lib/model/email_notifications_update.dart index dad0a52fdef28..e158e45598021 100644 --- a/mobile/openapi/lib/model/email_notifications_update.dart +++ b/mobile/openapi/lib/model/email_notifications_update.dart @@ -18,6 +18,7 @@ class EmailNotificationsUpdate { this.enabled, }); + /// Whether to receive email notifications for album invites /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -26,6 +27,7 @@ class EmailNotificationsUpdate { /// bool? albumInvite; + /// Whether to receive email notifications for album updates /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,6 +36,7 @@ class EmailNotificationsUpdate { /// bool? albumUpdate; + /// Whether email notifications are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/exif_response_dto.dart b/mobile/openapi/lib/model/exif_response_dto.dart index 17397b20815e0..6bb58a8ab98e2 100644 --- a/mobile/openapi/lib/model/exif_response_dto.dart +++ b/mobile/openapi/lib/model/exif_response_dto.dart @@ -37,48 +37,70 @@ class ExifResponseDto { this.timeZone, }); + /// City name String? city; + /// Country name String? country; + /// Original date/time DateTime? dateTimeOriginal; + /// Image description String? description; + /// Image height in pixels num? exifImageHeight; + /// Image width in pixels num? exifImageWidth; + /// Exposure time String? exposureTime; + /// F-number (aperture) num? fNumber; + /// File size in bytes int? fileSizeInByte; + /// Focal length in mm num? focalLength; + /// ISO sensitivity num? iso; + /// GPS latitude num? latitude; + /// Lens model String? lensModel; + /// GPS longitude num? longitude; + /// Camera make String? make; + /// Camera model String? model; + /// Modification date/time DateTime? modifyDate; + /// Image orientation String? orientation; + /// Projection type String? projectionType; + /// Rating num? rating; + /// State/province name String? state; + /// Time zone String? timeZone; @override diff --git a/mobile/openapi/lib/model/face_dto.dart b/mobile/openapi/lib/model/face_dto.dart index c84a518b8c784..ec5f5c8a6c4de 100644 --- a/mobile/openapi/lib/model/face_dto.dart +++ b/mobile/openapi/lib/model/face_dto.dart @@ -16,6 +16,7 @@ class FaceDto { required this.id, }); + /// Face ID String id; @override diff --git a/mobile/openapi/lib/model/facial_recognition_config.dart b/mobile/openapi/lib/model/facial_recognition_config.dart index 439efbbfaeeb1..4b9d7a6e9e504 100644 --- a/mobile/openapi/lib/model/facial_recognition_config.dart +++ b/mobile/openapi/lib/model/facial_recognition_config.dart @@ -20,19 +20,27 @@ class FacialRecognitionConfig { required this.modelName, }); + /// Whether the task is enabled bool enabled; + /// Maximum distance threshold for face recognition + /// /// Minimum value: 0.1 /// Maximum value: 2 double maxDistance; + /// Minimum number of faces required for recognition + /// /// Minimum value: 1 int minFaces; + /// Minimum confidence score for face detection + /// /// Minimum value: 0.1 /// Maximum value: 1 double minScore; + /// Name of the model to use String modelName; @override diff --git a/mobile/openapi/lib/model/folders_response.dart b/mobile/openapi/lib/model/folders_response.dart index 248b64b054c83..906a95a83c20d 100644 --- a/mobile/openapi/lib/model/folders_response.dart +++ b/mobile/openapi/lib/model/folders_response.dart @@ -17,8 +17,10 @@ class FoldersResponse { this.sidebarWeb = false, }); + /// Whether folders are enabled bool enabled; + /// Whether folders appear in web sidebar bool sidebarWeb; @override diff --git a/mobile/openapi/lib/model/folders_update.dart b/mobile/openapi/lib/model/folders_update.dart index 02347177545d0..edd58014d40ec 100644 --- a/mobile/openapi/lib/model/folders_update.dart +++ b/mobile/openapi/lib/model/folders_update.dart @@ -17,6 +17,7 @@ class FoldersUpdate { this.sidebarWeb, }); + /// Whether folders are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class FoldersUpdate { /// bool? enabled; + /// Whether folders appear in web sidebar /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/image_format.dart b/mobile/openapi/lib/model/image_format.dart index 479b519e248dd..1a0dde5defb27 100644 --- a/mobile/openapi/lib/model/image_format.dart +++ b/mobile/openapi/lib/model/image_format.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Image format class ImageFormat { /// Instantiate a new enum with the provided [value]. const ImageFormat._(this.value); diff --git a/mobile/openapi/lib/model/job_create_dto.dart b/mobile/openapi/lib/model/job_create_dto.dart index fe6743cba09d9..3a3412384e8ad 100644 --- a/mobile/openapi/lib/model/job_create_dto.dart +++ b/mobile/openapi/lib/model/job_create_dto.dart @@ -16,6 +16,7 @@ class JobCreateDto { required this.name, }); + /// Job name ManualJobName name; @override diff --git a/mobile/openapi/lib/model/job_name.dart b/mobile/openapi/lib/model/job_name.dart index b027c921143a7..96b9339b7dcf1 100644 --- a/mobile/openapi/lib/model/job_name.dart +++ b/mobile/openapi/lib/model/job_name.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Job name class JobName { /// Instantiate a new enum with the provided [value]. const JobName._(this.value); diff --git a/mobile/openapi/lib/model/job_settings_dto.dart b/mobile/openapi/lib/model/job_settings_dto.dart index af354bef9e953..73a0187ddd3ba 100644 --- a/mobile/openapi/lib/model/job_settings_dto.dart +++ b/mobile/openapi/lib/model/job_settings_dto.dart @@ -16,6 +16,8 @@ class JobSettingsDto { required this.concurrency, }); + /// Concurrency + /// /// Minimum value: 1 int concurrency; diff --git a/mobile/openapi/lib/model/library_response_dto.dart b/mobile/openapi/lib/model/library_response_dto.dart index 3cf12485080ac..aa9158e591846 100644 --- a/mobile/openapi/lib/model/library_response_dto.dart +++ b/mobile/openapi/lib/model/library_response_dto.dart @@ -24,22 +24,31 @@ class LibraryResponseDto { required this.updatedAt, }); + /// Number of assets int assetCount; + /// Creation date DateTime createdAt; + /// Exclusion patterns List exclusionPatterns; + /// Library ID String id; + /// Import paths List importPaths; + /// Library name String name; + /// Owner user ID String ownerId; + /// Last refresh date DateTime? refreshedAt; + /// Last update date DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/library_stats_response_dto.dart b/mobile/openapi/lib/model/library_stats_response_dto.dart index afe67da31a251..6eec3ae8d77aa 100644 --- a/mobile/openapi/lib/model/library_stats_response_dto.dart +++ b/mobile/openapi/lib/model/library_stats_response_dto.dart @@ -19,12 +19,16 @@ class LibraryStatsResponseDto { this.videos = 0, }); + /// Number of photos int photos; + /// Total number of assets int total; + /// Storage usage in bytes int usage; + /// Number of videos int videos; @override diff --git a/mobile/openapi/lib/model/license_key_dto.dart b/mobile/openapi/lib/model/license_key_dto.dart index d27d579bb4831..ea1fee9d7abf4 100644 --- a/mobile/openapi/lib/model/license_key_dto.dart +++ b/mobile/openapi/lib/model/license_key_dto.dart @@ -17,8 +17,10 @@ class LicenseKeyDto { required this.licenseKey, }); + /// Activation key String activationKey; + /// License key (format: IM(SV|CL)(-XXXX){8}) String licenseKey; @override diff --git a/mobile/openapi/lib/model/license_response_dto.dart b/mobile/openapi/lib/model/license_response_dto.dart index 6d3009433fd80..84ff72c1eb3f2 100644 --- a/mobile/openapi/lib/model/license_response_dto.dart +++ b/mobile/openapi/lib/model/license_response_dto.dart @@ -18,10 +18,13 @@ class LicenseResponseDto { required this.licenseKey, }); + /// Activation date DateTime activatedAt; + /// Activation key String activationKey; + /// License key (format: IM(SV|CL)(-XXXX){8}) String licenseKey; @override diff --git a/mobile/openapi/lib/model/login_credential_dto.dart b/mobile/openapi/lib/model/login_credential_dto.dart index 7e892ab5fbcb6..1fdfdc3d40721 100644 --- a/mobile/openapi/lib/model/login_credential_dto.dart +++ b/mobile/openapi/lib/model/login_credential_dto.dart @@ -17,8 +17,10 @@ class LoginCredentialDto { required this.password, }); + /// User email String email; + /// User password String password; @override diff --git a/mobile/openapi/lib/model/login_response_dto.dart b/mobile/openapi/lib/model/login_response_dto.dart index 82a4f9b3ed72f..c6938c2393bf1 100644 --- a/mobile/openapi/lib/model/login_response_dto.dart +++ b/mobile/openapi/lib/model/login_response_dto.dart @@ -23,20 +23,28 @@ class LoginResponseDto { required this.userId, }); + /// Access token String accessToken; + /// Is admin user bool isAdmin; + /// Is onboarded bool isOnboarded; + /// User name String name; + /// Profile image path String profileImagePath; + /// Should change password bool shouldChangePassword; + /// User email String userEmail; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/logout_response_dto.dart b/mobile/openapi/lib/model/logout_response_dto.dart index aa94904e2a7df..b50db2c28b730 100644 --- a/mobile/openapi/lib/model/logout_response_dto.dart +++ b/mobile/openapi/lib/model/logout_response_dto.dart @@ -17,8 +17,10 @@ class LogoutResponseDto { required this.successful, }); + /// Redirect URI String redirectUri; + /// Logout successful bool successful; @override diff --git a/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart b/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart index 84b3181426ace..dc0cf5fac05bb 100644 --- a/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart +++ b/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart @@ -18,6 +18,7 @@ class MachineLearningAvailabilityChecksDto { required this.timeout, }); + /// Enabled bool enabled; num interval; diff --git a/mobile/openapi/lib/model/maintenance_action.dart b/mobile/openapi/lib/model/maintenance_action.dart index 59cfd0b21f4f6..ebf5ec0f717ea 100644 --- a/mobile/openapi/lib/model/maintenance_action.dart +++ b/mobile/openapi/lib/model/maintenance_action.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Maintenance action class MaintenanceAction { /// Instantiate a new enum with the provided [value]. const MaintenanceAction._(this.value); diff --git a/mobile/openapi/lib/model/maintenance_auth_dto.dart b/mobile/openapi/lib/model/maintenance_auth_dto.dart index 919da5502b0b9..f9511bdd2ba0f 100644 --- a/mobile/openapi/lib/model/maintenance_auth_dto.dart +++ b/mobile/openapi/lib/model/maintenance_auth_dto.dart @@ -16,6 +16,7 @@ class MaintenanceAuthDto { required this.username, }); + /// Maintenance username String username; @override diff --git a/mobile/openapi/lib/model/maintenance_detect_install_storage_folder_dto.dart b/mobile/openapi/lib/model/maintenance_detect_install_storage_folder_dto.dart index e2a1e35dea567..ad524914b49e7 100644 --- a/mobile/openapi/lib/model/maintenance_detect_install_storage_folder_dto.dart +++ b/mobile/openapi/lib/model/maintenance_detect_install_storage_folder_dto.dart @@ -19,12 +19,16 @@ class MaintenanceDetectInstallStorageFolderDto { required this.writable, }); + /// Number of files in the folder num files; + /// Storage folder StorageFolder folder; + /// Whether the folder is readable bool readable; + /// Whether the folder is writable bool writable; @override diff --git a/mobile/openapi/lib/model/maintenance_login_dto.dart b/mobile/openapi/lib/model/maintenance_login_dto.dart index 45f56bd3baf30..64cf6b234bc54 100644 --- a/mobile/openapi/lib/model/maintenance_login_dto.dart +++ b/mobile/openapi/lib/model/maintenance_login_dto.dart @@ -16,6 +16,7 @@ class MaintenanceLoginDto { this.token, }); + /// Maintenance token /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/maintenance_status_response_dto.dart b/mobile/openapi/lib/model/maintenance_status_response_dto.dart index 124fa674fdd65..52dbb5b95bb38 100644 --- a/mobile/openapi/lib/model/maintenance_status_response_dto.dart +++ b/mobile/openapi/lib/model/maintenance_status_response_dto.dart @@ -20,6 +20,7 @@ class MaintenanceStatusResponseDto { this.task, }); + /// Maintenance action MaintenanceAction action; bool active; diff --git a/mobile/openapi/lib/model/manual_job_name.dart b/mobile/openapi/lib/model/manual_job_name.dart index 311215ad9e3df..d09790a81a08e 100644 --- a/mobile/openapi/lib/model/manual_job_name.dart +++ b/mobile/openapi/lib/model/manual_job_name.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Job name class ManualJobName { /// Instantiate a new enum with the provided [value]. const ManualJobName._(this.value); diff --git a/mobile/openapi/lib/model/map_marker_response_dto.dart b/mobile/openapi/lib/model/map_marker_response_dto.dart index 74ac51a271478..c0a47a5458fd0 100644 --- a/mobile/openapi/lib/model/map_marker_response_dto.dart +++ b/mobile/openapi/lib/model/map_marker_response_dto.dart @@ -21,16 +21,22 @@ class MapMarkerResponseDto { required this.state, }); + /// City name String? city; + /// Country name String? country; + /// Asset ID String id; + /// Latitude double lat; + /// Longitude double lon; + /// State/Province name String? state; @override diff --git a/mobile/openapi/lib/model/map_reverse_geocode_response_dto.dart b/mobile/openapi/lib/model/map_reverse_geocode_response_dto.dart index 6d8757d39ff61..85435485e6215 100644 --- a/mobile/openapi/lib/model/map_reverse_geocode_response_dto.dart +++ b/mobile/openapi/lib/model/map_reverse_geocode_response_dto.dart @@ -18,10 +18,13 @@ class MapReverseGeocodeResponseDto { required this.state, }); + /// City name String? city; + /// Country name String? country; + /// State/Province name String? state; @override diff --git a/mobile/openapi/lib/model/memories_response.dart b/mobile/openapi/lib/model/memories_response.dart index cb42f596a6db6..63d4094cd0d31 100644 --- a/mobile/openapi/lib/model/memories_response.dart +++ b/mobile/openapi/lib/model/memories_response.dart @@ -17,8 +17,10 @@ class MemoriesResponse { this.enabled = true, }); + /// Memory duration in seconds int duration; + /// Whether memories are enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/memories_update.dart b/mobile/openapi/lib/model/memories_update.dart index 39c46ffd2f06b..d27cef022d426 100644 --- a/mobile/openapi/lib/model/memories_update.dart +++ b/mobile/openapi/lib/model/memories_update.dart @@ -17,6 +17,8 @@ class MemoriesUpdate { this.enabled, }); + /// Memory duration in seconds + /// /// Minimum value: 1 /// /// Please note: This property should have been non-nullable! Since the specification file @@ -26,6 +28,7 @@ class MemoriesUpdate { /// int? duration; + /// Whether memories are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/memory_create_dto.dart b/mobile/openapi/lib/model/memory_create_dto.dart index 15985f2f1c175..7fd938b31a0e5 100644 --- a/mobile/openapi/lib/model/memory_create_dto.dart +++ b/mobile/openapi/lib/model/memory_create_dto.dart @@ -21,10 +21,12 @@ class MemoryCreateDto { required this.type, }); + /// Asset IDs to associate with memory List assetIds; OnThisDayDto data; + /// Is memory saved /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -33,8 +35,10 @@ class MemoryCreateDto { /// bool? isSaved; + /// Memory date DateTime memoryAt; + /// Date when memory was seen /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -43,6 +47,7 @@ class MemoryCreateDto { /// DateTime? seenAt; + /// Memory type MemoryType type; @override diff --git a/mobile/openapi/lib/model/memory_response_dto.dart b/mobile/openapi/lib/model/memory_response_dto.dart index 7d50259e24e77..1835095cf7270 100644 --- a/mobile/openapi/lib/model/memory_response_dto.dart +++ b/mobile/openapi/lib/model/memory_response_dto.dart @@ -30,10 +30,12 @@ class MemoryResponseDto { List assets; + /// Creation date DateTime createdAt; OnThisDayDto data; + /// Deletion date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -42,6 +44,7 @@ class MemoryResponseDto { /// DateTime? deletedAt; + /// Date when memory should be hidden /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -50,14 +53,19 @@ class MemoryResponseDto { /// DateTime? hideAt; + /// Memory ID String id; + /// Is memory saved bool isSaved; + /// Memory date DateTime memoryAt; + /// Owner user ID String ownerId; + /// Date when memory was seen /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -66,6 +74,7 @@ class MemoryResponseDto { /// DateTime? seenAt; + /// Date when memory should be shown /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -74,8 +83,10 @@ class MemoryResponseDto { /// DateTime? showAt; + /// Memory type MemoryType type; + /// Last update date DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/memory_statistics_response_dto.dart b/mobile/openapi/lib/model/memory_statistics_response_dto.dart index a9a10ad327d8a..bde78de481012 100644 --- a/mobile/openapi/lib/model/memory_statistics_response_dto.dart +++ b/mobile/openapi/lib/model/memory_statistics_response_dto.dart @@ -16,6 +16,7 @@ class MemoryStatisticsResponseDto { required this.total, }); + /// Total number of memories int total; @override diff --git a/mobile/openapi/lib/model/memory_update_dto.dart b/mobile/openapi/lib/model/memory_update_dto.dart index e750f9faad330..4905b161bfb48 100644 --- a/mobile/openapi/lib/model/memory_update_dto.dart +++ b/mobile/openapi/lib/model/memory_update_dto.dart @@ -18,6 +18,7 @@ class MemoryUpdateDto { this.seenAt, }); + /// Is memory saved /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -26,6 +27,7 @@ class MemoryUpdateDto { /// bool? isSaved; + /// Memory date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,6 +36,7 @@ class MemoryUpdateDto { /// DateTime? memoryAt; + /// Date when memory was seen /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/merge_person_dto.dart b/mobile/openapi/lib/model/merge_person_dto.dart index fd225276b6f0a..8a647890c3f98 100644 --- a/mobile/openapi/lib/model/merge_person_dto.dart +++ b/mobile/openapi/lib/model/merge_person_dto.dart @@ -16,6 +16,7 @@ class MergePersonDto { this.ids = const [], }); + /// Person IDs to merge List ids; @override diff --git a/mobile/openapi/lib/model/metadata_search_dto.dart b/mobile/openapi/lib/model/metadata_search_dto.dart index 7d8d2b1314614..4a7ca403ab1ea 100644 --- a/mobile/openapi/lib/model/metadata_search_dto.dart +++ b/mobile/openapi/lib/model/metadata_search_dto.dart @@ -59,8 +59,10 @@ class MetadataSearchDto { this.withStacked, }); + /// Filter by album IDs List albumIds; + /// Filter by file checksum /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -69,10 +71,13 @@ class MetadataSearchDto { /// String? checksum; + /// Filter by city name String? city; + /// Filter by country name String? country; + /// Filter by creation date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -81,6 +86,7 @@ class MetadataSearchDto { /// DateTime? createdAfter; + /// Filter by creation date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -89,6 +95,7 @@ class MetadataSearchDto { /// DateTime? createdBefore; + /// Filter by description text /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -97,6 +104,7 @@ class MetadataSearchDto { /// String? description; + /// Filter by device asset ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -105,6 +113,7 @@ class MetadataSearchDto { /// String? deviceAssetId; + /// Device ID to filter by /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -113,6 +122,7 @@ class MetadataSearchDto { /// String? deviceId; + /// Filter by encoded video file path /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -121,6 +131,7 @@ class MetadataSearchDto { /// String? encodedVideoPath; + /// Filter by asset ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -129,6 +140,7 @@ class MetadataSearchDto { /// String? id; + /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -137,6 +149,7 @@ class MetadataSearchDto { /// bool? isEncoded; + /// Filter by favorite status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -145,6 +158,7 @@ class MetadataSearchDto { /// bool? isFavorite; + /// Filter by motion photo status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -153,6 +167,7 @@ class MetadataSearchDto { /// bool? isMotion; + /// Filter assets not in any album /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -161,6 +176,7 @@ class MetadataSearchDto { /// bool? isNotInAlbum; + /// Filter by offline status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -169,10 +185,13 @@ class MetadataSearchDto { /// bool? isOffline; + /// Filter by lens model String? lensModel; + /// Library ID to filter by String? libraryId; + /// Filter by camera make /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -181,8 +200,10 @@ class MetadataSearchDto { /// String? make; + /// Filter by camera model String? model; + /// Filter by OCR text content /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -191,8 +212,10 @@ class MetadataSearchDto { /// String? ocr; + /// Sort order AssetOrder order; + /// Filter by original file name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -201,6 +224,7 @@ class MetadataSearchDto { /// String? originalFileName; + /// Filter by original file path /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -209,6 +233,8 @@ class MetadataSearchDto { /// String? originalPath; + /// Page number + /// /// Minimum value: 1 /// /// Please note: This property should have been non-nullable! Since the specification file @@ -218,8 +244,10 @@ class MetadataSearchDto { /// num? page; + /// Filter by person IDs List personIds; + /// Filter by preview file path /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -228,6 +256,8 @@ class MetadataSearchDto { /// String? previewPath; + /// Filter by rating + /// /// Minimum value: -1 /// Maximum value: 5 /// @@ -238,6 +268,8 @@ class MetadataSearchDto { /// num? rating; + /// Number of results to return + /// /// Minimum value: 1 /// Maximum value: 1000 /// @@ -248,10 +280,13 @@ class MetadataSearchDto { /// num? size; + /// Filter by state/province name String? state; + /// Filter by tag IDs List? tagIds; + /// Filter by taken date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -260,6 +295,7 @@ class MetadataSearchDto { /// DateTime? takenAfter; + /// Filter by taken date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -268,6 +304,7 @@ class MetadataSearchDto { /// DateTime? takenBefore; + /// Filter by thumbnail file path /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -276,6 +313,7 @@ class MetadataSearchDto { /// String? thumbnailPath; + /// Filter by trash date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -284,6 +322,7 @@ class MetadataSearchDto { /// DateTime? trashedAfter; + /// Filter by trash date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -292,6 +331,7 @@ class MetadataSearchDto { /// DateTime? trashedBefore; + /// Asset type filter /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -300,6 +340,7 @@ class MetadataSearchDto { /// AssetTypeEnum? type; + /// Filter by update date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -308,6 +349,7 @@ class MetadataSearchDto { /// DateTime? updatedAfter; + /// Filter by update date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -316,6 +358,7 @@ class MetadataSearchDto { /// DateTime? updatedBefore; + /// Filter by visibility /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -324,6 +367,7 @@ class MetadataSearchDto { /// AssetVisibility? visibility; + /// Include deleted assets /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -332,6 +376,7 @@ class MetadataSearchDto { /// bool? withDeleted; + /// Include EXIF data in response /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -340,6 +385,7 @@ class MetadataSearchDto { /// bool? withExif; + /// Include assets with people /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -348,6 +394,7 @@ class MetadataSearchDto { /// bool? withPeople; + /// Include stacked assets /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/notification_create_dto.dart b/mobile/openapi/lib/model/notification_create_dto.dart index 07985353b2f27..1288da8670b81 100644 --- a/mobile/openapi/lib/model/notification_create_dto.dart +++ b/mobile/openapi/lib/model/notification_create_dto.dart @@ -22,6 +22,7 @@ class NotificationCreateDto { required this.userId, }); + /// Additional notification data /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -30,8 +31,10 @@ class NotificationCreateDto { /// Object? data; + /// Notification description String? description; + /// Notification level /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -40,10 +43,13 @@ class NotificationCreateDto { /// NotificationLevel? level; + /// Date when notification was read DateTime? readAt; + /// Notification title String title; + /// Notification type /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -52,6 +58,7 @@ class NotificationCreateDto { /// NotificationType? type; + /// User ID to send notification to String userId; @override diff --git a/mobile/openapi/lib/model/notification_delete_all_dto.dart b/mobile/openapi/lib/model/notification_delete_all_dto.dart index 4be1b89e920c5..1b398a4f339d2 100644 --- a/mobile/openapi/lib/model/notification_delete_all_dto.dart +++ b/mobile/openapi/lib/model/notification_delete_all_dto.dart @@ -16,6 +16,7 @@ class NotificationDeleteAllDto { this.ids = const [], }); + /// Notification IDs to delete List ids; @override diff --git a/mobile/openapi/lib/model/notification_dto.dart b/mobile/openapi/lib/model/notification_dto.dart index 4f730b4e50dee..30d43de1155c2 100644 --- a/mobile/openapi/lib/model/notification_dto.dart +++ b/mobile/openapi/lib/model/notification_dto.dart @@ -23,8 +23,10 @@ class NotificationDto { required this.type, }); + /// Creation date DateTime createdAt; + /// Additional notification data /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -33,6 +35,7 @@ class NotificationDto { /// Object? data; + /// Notification description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -41,10 +44,13 @@ class NotificationDto { /// String? description; + /// Notification ID String id; + /// Notification level NotificationLevel level; + /// Date when notification was read /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -53,8 +59,10 @@ class NotificationDto { /// DateTime? readAt; + /// Notification title String title; + /// Notification type NotificationType type; @override diff --git a/mobile/openapi/lib/model/notification_update_all_dto.dart b/mobile/openapi/lib/model/notification_update_all_dto.dart index a6393b275a576..a1570583245a6 100644 --- a/mobile/openapi/lib/model/notification_update_all_dto.dart +++ b/mobile/openapi/lib/model/notification_update_all_dto.dart @@ -17,8 +17,10 @@ class NotificationUpdateAllDto { this.readAt, }); + /// Notification IDs to update List ids; + /// Date when notifications were read DateTime? readAt; @override diff --git a/mobile/openapi/lib/model/notification_update_dto.dart b/mobile/openapi/lib/model/notification_update_dto.dart index e76496eb9757f..eddf9c7e12ba0 100644 --- a/mobile/openapi/lib/model/notification_update_dto.dart +++ b/mobile/openapi/lib/model/notification_update_dto.dart @@ -16,6 +16,7 @@ class NotificationUpdateDto { this.readAt, }); + /// Date when notification was read DateTime? readAt; @override diff --git a/mobile/openapi/lib/model/o_auth_authorize_response_dto.dart b/mobile/openapi/lib/model/o_auth_authorize_response_dto.dart index 869c3be753f70..7eedc45673a7b 100644 --- a/mobile/openapi/lib/model/o_auth_authorize_response_dto.dart +++ b/mobile/openapi/lib/model/o_auth_authorize_response_dto.dart @@ -16,6 +16,7 @@ class OAuthAuthorizeResponseDto { required this.url, }); + /// OAuth authorization URL String url; @override diff --git a/mobile/openapi/lib/model/o_auth_callback_dto.dart b/mobile/openapi/lib/model/o_auth_callback_dto.dart index ea8cac31a03b1..d94374935a61b 100644 --- a/mobile/openapi/lib/model/o_auth_callback_dto.dart +++ b/mobile/openapi/lib/model/o_auth_callback_dto.dart @@ -18,6 +18,7 @@ class OAuthCallbackDto { required this.url, }); + /// OAuth code verifier (PKCE) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -26,6 +27,7 @@ class OAuthCallbackDto { /// String? codeVerifier; + /// OAuth state parameter /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,6 +36,7 @@ class OAuthCallbackDto { /// String? state; + /// OAuth callback URL String url; @override diff --git a/mobile/openapi/lib/model/o_auth_config_dto.dart b/mobile/openapi/lib/model/o_auth_config_dto.dart index bb3e8d448de14..1c9ce8d5b8386 100644 --- a/mobile/openapi/lib/model/o_auth_config_dto.dart +++ b/mobile/openapi/lib/model/o_auth_config_dto.dart @@ -18,6 +18,7 @@ class OAuthConfigDto { this.state, }); + /// OAuth code challenge (PKCE) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -26,8 +27,10 @@ class OAuthConfigDto { /// String? codeChallenge; + /// OAuth redirect URI String redirectUri; + /// OAuth state parameter /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/o_auth_token_endpoint_auth_method.dart b/mobile/openapi/lib/model/o_auth_token_endpoint_auth_method.dart index fc528888b39dc..77466d61d92cb 100644 --- a/mobile/openapi/lib/model/o_auth_token_endpoint_auth_method.dart +++ b/mobile/openapi/lib/model/o_auth_token_endpoint_auth_method.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Token endpoint auth method class OAuthTokenEndpointAuthMethod { /// Instantiate a new enum with the provided [value]. const OAuthTokenEndpointAuthMethod._(this.value); diff --git a/mobile/openapi/lib/model/ocr_config.dart b/mobile/openapi/lib/model/ocr_config.dart index 51746c49246a9..d97cd5ffca6c0 100644 --- a/mobile/openapi/lib/model/ocr_config.dart +++ b/mobile/openapi/lib/model/ocr_config.dart @@ -20,19 +20,27 @@ class OcrConfig { required this.modelName, }); + /// Whether the task is enabled bool enabled; + /// Maximum resolution for OCR processing + /// /// Minimum value: 1 int maxResolution; + /// Minimum confidence score for text detection + /// /// Minimum value: 0.1 /// Maximum value: 1 double minDetectionScore; + /// Minimum confidence score for text recognition + /// /// Minimum value: 0.1 /// Maximum value: 1 double minRecognitionScore; + /// Name of the model to use String modelName; @override diff --git a/mobile/openapi/lib/model/on_this_day_dto.dart b/mobile/openapi/lib/model/on_this_day_dto.dart index bfcc4fd630589..93ec956f5801c 100644 --- a/mobile/openapi/lib/model/on_this_day_dto.dart +++ b/mobile/openapi/lib/model/on_this_day_dto.dart @@ -16,6 +16,8 @@ class OnThisDayDto { required this.year, }); + /// Year for on this day memory + /// /// Minimum value: 1 num year; diff --git a/mobile/openapi/lib/model/onboarding_dto.dart b/mobile/openapi/lib/model/onboarding_dto.dart index 670b6a5c681ca..8499bc9b9abd7 100644 --- a/mobile/openapi/lib/model/onboarding_dto.dart +++ b/mobile/openapi/lib/model/onboarding_dto.dart @@ -16,6 +16,7 @@ class OnboardingDto { required this.isOnboarded, }); + /// Is user onboarded bool isOnboarded; @override diff --git a/mobile/openapi/lib/model/onboarding_response_dto.dart b/mobile/openapi/lib/model/onboarding_response_dto.dart index 033466e96b4ed..2b0dbe2b9622a 100644 --- a/mobile/openapi/lib/model/onboarding_response_dto.dart +++ b/mobile/openapi/lib/model/onboarding_response_dto.dart @@ -16,6 +16,7 @@ class OnboardingResponseDto { required this.isOnboarded, }); + /// Is user onboarded bool isOnboarded; @override diff --git a/mobile/openapi/lib/model/partner_create_dto.dart b/mobile/openapi/lib/model/partner_create_dto.dart index 09d60c5c772cf..30aa96ff301a8 100644 --- a/mobile/openapi/lib/model/partner_create_dto.dart +++ b/mobile/openapi/lib/model/partner_create_dto.dart @@ -16,6 +16,7 @@ class PartnerCreateDto { required this.sharedWithId, }); + /// User ID to share with String sharedWithId; @override diff --git a/mobile/openapi/lib/model/partner_response_dto.dart b/mobile/openapi/lib/model/partner_response_dto.dart index f61df86b42bf4..5789938d187b2 100644 --- a/mobile/openapi/lib/model/partner_response_dto.dart +++ b/mobile/openapi/lib/model/partner_response_dto.dart @@ -22,12 +22,16 @@ class PartnerResponseDto { required this.profileImagePath, }); + /// Avatar color UserAvatarColor avatarColor; + /// User email String email; + /// User ID String id; + /// Show in timeline /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -36,10 +40,13 @@ class PartnerResponseDto { /// bool? inTimeline; + /// User name String name; + /// Profile change date DateTime profileChangedAt; + /// Profile image path String profileImagePath; @override diff --git a/mobile/openapi/lib/model/partner_update_dto.dart b/mobile/openapi/lib/model/partner_update_dto.dart index 25cf2177642a2..db3516e3a17fd 100644 --- a/mobile/openapi/lib/model/partner_update_dto.dart +++ b/mobile/openapi/lib/model/partner_update_dto.dart @@ -16,6 +16,7 @@ class PartnerUpdateDto { required this.inTimeline, }); + /// Show partner assets in timeline bool inTimeline; @override diff --git a/mobile/openapi/lib/model/people_response.dart b/mobile/openapi/lib/model/people_response.dart index 1312c738744ef..c09560e08c67b 100644 --- a/mobile/openapi/lib/model/people_response.dart +++ b/mobile/openapi/lib/model/people_response.dart @@ -17,8 +17,10 @@ class PeopleResponse { this.sidebarWeb = false, }); + /// Whether people are enabled bool enabled; + /// Whether people appear in web sidebar bool sidebarWeb; @override diff --git a/mobile/openapi/lib/model/people_response_dto.dart b/mobile/openapi/lib/model/people_response_dto.dart index 901c38ade9c79..f345657e739ea 100644 --- a/mobile/openapi/lib/model/people_response_dto.dart +++ b/mobile/openapi/lib/model/people_response_dto.dart @@ -19,6 +19,7 @@ class PeopleResponseDto { required this.total, }); + /// Whether there are more pages /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -27,10 +28,13 @@ class PeopleResponseDto { /// bool? hasNextPage; + /// Number of hidden people int hidden; + /// List of people List people; + /// Total number of people int total; @override diff --git a/mobile/openapi/lib/model/people_update.dart b/mobile/openapi/lib/model/people_update.dart index fb4eeeb434fda..fe16479bac0e4 100644 --- a/mobile/openapi/lib/model/people_update.dart +++ b/mobile/openapi/lib/model/people_update.dart @@ -17,6 +17,7 @@ class PeopleUpdate { this.sidebarWeb, }); + /// Whether people are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class PeopleUpdate { /// bool? enabled; + /// Whether people appear in web sidebar /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/people_update_dto.dart b/mobile/openapi/lib/model/people_update_dto.dart index f771084f75c63..c9ce74d659afa 100644 --- a/mobile/openapi/lib/model/people_update_dto.dart +++ b/mobile/openapi/lib/model/people_update_dto.dart @@ -16,6 +16,7 @@ class PeopleUpdateDto { this.people = const [], }); + /// People to update List people; @override diff --git a/mobile/openapi/lib/model/people_update_item.dart b/mobile/openapi/lib/model/people_update_item.dart index ce324b859eb79..5e20aeb46416a 100644 --- a/mobile/openapi/lib/model/people_update_item.dart +++ b/mobile/openapi/lib/model/people_update_item.dart @@ -22,12 +22,13 @@ class PeopleUpdateItem { this.name, }); - /// Person date of birth. Note: the mobile app cannot currently set the birth date to null. + /// Person date of birth DateTime? birthDate; + /// Person color (hex) String? color; - /// Asset is used to get the feature face thumbnail. + /// Asset ID used for feature face thumbnail /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -36,9 +37,10 @@ class PeopleUpdateItem { /// String? featureFaceAssetId; - /// Person id. + /// Person ID String id; + /// Mark as favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -47,7 +49,7 @@ class PeopleUpdateItem { /// bool? isFavorite; - /// Person visibility + /// Person visibility (hidden) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -56,7 +58,7 @@ class PeopleUpdateItem { /// bool? isHidden; - /// Person name. + /// Person name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/permission.dart b/mobile/openapi/lib/model/permission.dart index 01bb689538d26..9092ede786c02 100644 --- a/mobile/openapi/lib/model/permission.dart +++ b/mobile/openapi/lib/model/permission.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// List of permissions class Permission { /// Instantiate a new enum with the provided [value]. const Permission._(this.value); diff --git a/mobile/openapi/lib/model/person_create_dto.dart b/mobile/openapi/lib/model/person_create_dto.dart index 87b426eaed1ed..f2ba702c2fd05 100644 --- a/mobile/openapi/lib/model/person_create_dto.dart +++ b/mobile/openapi/lib/model/person_create_dto.dart @@ -20,11 +20,13 @@ class PersonCreateDto { this.name, }); - /// Person date of birth. Note: the mobile app cannot currently set the birth date to null. + /// Person date of birth DateTime? birthDate; + /// Person color (hex) String? color; + /// Mark as favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -33,7 +35,7 @@ class PersonCreateDto { /// bool? isFavorite; - /// Person visibility + /// Person visibility (hidden) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -42,7 +44,7 @@ class PersonCreateDto { /// bool? isHidden; - /// Person name. + /// Person name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/person_response_dto.dart b/mobile/openapi/lib/model/person_response_dto.dart index a6ad5e0c24886..455dfb98d6fde 100644 --- a/mobile/openapi/lib/model/person_response_dto.dart +++ b/mobile/openapi/lib/model/person_response_dto.dart @@ -23,8 +23,10 @@ class PersonResponseDto { this.updatedAt, }); + /// Person date of birth DateTime? birthDate; + /// Person color (hex) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -33,8 +35,10 @@ class PersonResponseDto { /// String? color; + /// Person ID String id; + /// Is favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -43,12 +47,16 @@ class PersonResponseDto { /// bool? isFavorite; + /// Is hidden bool isHidden; + /// Person name String name; + /// Thumbnail path String thumbnailPath; + /// Last update date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/person_statistics_response_dto.dart b/mobile/openapi/lib/model/person_statistics_response_dto.dart index d9f84e9f4c226..d2b45c8ccbd93 100644 --- a/mobile/openapi/lib/model/person_statistics_response_dto.dart +++ b/mobile/openapi/lib/model/person_statistics_response_dto.dart @@ -16,6 +16,7 @@ class PersonStatisticsResponseDto { required this.assets, }); + /// Number of assets int assets; @override diff --git a/mobile/openapi/lib/model/person_update_dto.dart b/mobile/openapi/lib/model/person_update_dto.dart index 6736b4e177284..b56940e51db0c 100644 --- a/mobile/openapi/lib/model/person_update_dto.dart +++ b/mobile/openapi/lib/model/person_update_dto.dart @@ -21,12 +21,13 @@ class PersonUpdateDto { this.name, }); - /// Person date of birth. Note: the mobile app cannot currently set the birth date to null. + /// Person date of birth DateTime? birthDate; + /// Person color (hex) String? color; - /// Asset is used to get the feature face thumbnail. + /// Asset ID used for feature face thumbnail /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -35,6 +36,7 @@ class PersonUpdateDto { /// String? featureFaceAssetId; + /// Mark as favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -43,7 +45,7 @@ class PersonUpdateDto { /// bool? isFavorite; - /// Person visibility + /// Person visibility (hidden) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -52,7 +54,7 @@ class PersonUpdateDto { /// bool? isHidden; - /// Person name. + /// Person name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/person_with_faces_response_dto.dart b/mobile/openapi/lib/model/person_with_faces_response_dto.dart index 9b2e40cf56fbc..f31c04b69ff90 100644 --- a/mobile/openapi/lib/model/person_with_faces_response_dto.dart +++ b/mobile/openapi/lib/model/person_with_faces_response_dto.dart @@ -24,8 +24,10 @@ class PersonWithFacesResponseDto { this.updatedAt, }); + /// Person date of birth DateTime? birthDate; + /// Person color (hex) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,10 +36,13 @@ class PersonWithFacesResponseDto { /// String? color; + /// Face detections List faces; + /// Person ID String id; + /// Is favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -46,12 +51,16 @@ class PersonWithFacesResponseDto { /// bool? isFavorite; + /// Is hidden bool isHidden; + /// Person name String name; + /// Thumbnail path String thumbnailPath; + /// Last update date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/pin_code_change_dto.dart b/mobile/openapi/lib/model/pin_code_change_dto.dart index 2e9967aa6bb66..068cc9e91bae1 100644 --- a/mobile/openapi/lib/model/pin_code_change_dto.dart +++ b/mobile/openapi/lib/model/pin_code_change_dto.dart @@ -18,8 +18,10 @@ class PinCodeChangeDto { this.pinCode, }); + /// New PIN code (4-6 digits) String newPinCode; + /// User password (required if PIN code is not provided) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -28,6 +30,7 @@ class PinCodeChangeDto { /// String? password; + /// New PIN code (4-6 digits) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/pin_code_reset_dto.dart b/mobile/openapi/lib/model/pin_code_reset_dto.dart index 3585348675f78..c37be76f18246 100644 --- a/mobile/openapi/lib/model/pin_code_reset_dto.dart +++ b/mobile/openapi/lib/model/pin_code_reset_dto.dart @@ -17,6 +17,7 @@ class PinCodeResetDto { this.pinCode, }); + /// User password (required if PIN code is not provided) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class PinCodeResetDto { /// String? password; + /// New PIN code (4-6 digits) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/pin_code_setup_dto.dart b/mobile/openapi/lib/model/pin_code_setup_dto.dart index 09933790de355..e2f08f102b5de 100644 --- a/mobile/openapi/lib/model/pin_code_setup_dto.dart +++ b/mobile/openapi/lib/model/pin_code_setup_dto.dart @@ -16,6 +16,7 @@ class PinCodeSetupDto { required this.pinCode, }); + /// PIN code (4-6 digits) String pinCode; @override diff --git a/mobile/openapi/lib/model/places_response_dto.dart b/mobile/openapi/lib/model/places_response_dto.dart index 4f77788263450..94aa58eba41e1 100644 --- a/mobile/openapi/lib/model/places_response_dto.dart +++ b/mobile/openapi/lib/model/places_response_dto.dart @@ -20,6 +20,7 @@ class PlacesResponseDto { required this.name, }); + /// Administrative level 1 name (state/province) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -28,6 +29,7 @@ class PlacesResponseDto { /// String? admin1name; + /// Administrative level 2 name (county/district) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -36,10 +38,13 @@ class PlacesResponseDto { /// String? admin2name; + /// Latitude coordinate num latitude; + /// Longitude coordinate num longitude; + /// Place name String name; @override diff --git a/mobile/openapi/lib/model/plugin_action_response_dto.dart b/mobile/openapi/lib/model/plugin_action_response_dto.dart index 5ba54f6eb5278..34fa314ba94c9 100644 --- a/mobile/openapi/lib/model/plugin_action_response_dto.dart +++ b/mobile/openapi/lib/model/plugin_action_response_dto.dart @@ -22,18 +22,25 @@ class PluginActionResponseDto { required this.title, }); + /// Action description String description; + /// Action ID String id; + /// Method name String methodName; + /// Plugin ID String pluginId; + /// Action schema Object? schema; + /// Supported contexts List supportedContexts; + /// Action title String title; @override diff --git a/mobile/openapi/lib/model/plugin_context_type.dart b/mobile/openapi/lib/model/plugin_context_type.dart index 797d2c3d3b792..6f4ac91fdbb0d 100644 --- a/mobile/openapi/lib/model/plugin_context_type.dart +++ b/mobile/openapi/lib/model/plugin_context_type.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Context type class PluginContextType { /// Instantiate a new enum with the provided [value]. const PluginContextType._(this.value); diff --git a/mobile/openapi/lib/model/plugin_filter_response_dto.dart b/mobile/openapi/lib/model/plugin_filter_response_dto.dart index 5873d72f077d8..ea6411a9c1b01 100644 --- a/mobile/openapi/lib/model/plugin_filter_response_dto.dart +++ b/mobile/openapi/lib/model/plugin_filter_response_dto.dart @@ -22,18 +22,25 @@ class PluginFilterResponseDto { required this.title, }); + /// Filter description String description; + /// Filter ID String id; + /// Method name String methodName; + /// Plugin ID String pluginId; + /// Filter schema Object? schema; + /// Supported contexts List supportedContexts; + /// Filter title String title; @override diff --git a/mobile/openapi/lib/model/plugin_response_dto.dart b/mobile/openapi/lib/model/plugin_response_dto.dart index afa6f3e1aba81..7a99896475998 100644 --- a/mobile/openapi/lib/model/plugin_response_dto.dart +++ b/mobile/openapi/lib/model/plugin_response_dto.dart @@ -25,24 +25,34 @@ class PluginResponseDto { required this.version, }); + /// Plugin actions List actions; + /// Plugin author String author; + /// Creation date String createdAt; + /// Plugin description String description; + /// Plugin filters List filters; + /// Plugin ID String id; + /// Plugin name String name; + /// Plugin title String title; + /// Last update date String updatedAt; + /// Plugin version String version; @override diff --git a/mobile/openapi/lib/model/plugin_trigger_response_dto.dart b/mobile/openapi/lib/model/plugin_trigger_response_dto.dart index a6ee1c6b69046..16a9604bcd3e5 100644 --- a/mobile/openapi/lib/model/plugin_trigger_response_dto.dart +++ b/mobile/openapi/lib/model/plugin_trigger_response_dto.dart @@ -17,8 +17,10 @@ class PluginTriggerResponseDto { required this.type, }); + /// Context type PluginContextType contextType; + /// Trigger type PluginTriggerType type; @override diff --git a/mobile/openapi/lib/model/plugin_trigger_type.dart b/mobile/openapi/lib/model/plugin_trigger_type.dart index b200f1b9e6cf2..9ae64acf6c4a1 100644 --- a/mobile/openapi/lib/model/plugin_trigger_type.dart +++ b/mobile/openapi/lib/model/plugin_trigger_type.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Trigger type class PluginTriggerType { /// Instantiate a new enum with the provided [value]. const PluginTriggerType._(this.value); diff --git a/mobile/openapi/lib/model/purchase_response.dart b/mobile/openapi/lib/model/purchase_response.dart index a1172069771ea..e55c2866295b7 100644 --- a/mobile/openapi/lib/model/purchase_response.dart +++ b/mobile/openapi/lib/model/purchase_response.dart @@ -17,8 +17,10 @@ class PurchaseResponse { required this.showSupportBadge, }); + /// Date until which to hide buy button String hideBuyButtonUntil; + /// Whether to show support badge bool showSupportBadge; @override diff --git a/mobile/openapi/lib/model/purchase_update.dart b/mobile/openapi/lib/model/purchase_update.dart index 69057e6c55a46..913faf9bc4fdc 100644 --- a/mobile/openapi/lib/model/purchase_update.dart +++ b/mobile/openapi/lib/model/purchase_update.dart @@ -17,6 +17,7 @@ class PurchaseUpdate { this.showSupportBadge, }); + /// Date until which to hide buy button /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class PurchaseUpdate { /// String? hideBuyButtonUntil; + /// Whether to show support badge /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/queue_command.dart b/mobile/openapi/lib/model/queue_command.dart index f03ec6eccd0be..3cf689a02dd58 100644 --- a/mobile/openapi/lib/model/queue_command.dart +++ b/mobile/openapi/lib/model/queue_command.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Queue command to execute class QueueCommand { /// Instantiate a new enum with the provided [value]. const QueueCommand._(this.value); diff --git a/mobile/openapi/lib/model/queue_command_dto.dart b/mobile/openapi/lib/model/queue_command_dto.dart index ded848c12f158..9e1eea15dbde1 100644 --- a/mobile/openapi/lib/model/queue_command_dto.dart +++ b/mobile/openapi/lib/model/queue_command_dto.dart @@ -17,8 +17,10 @@ class QueueCommandDto { this.force, }); + /// Queue command to execute QueueCommand command; + /// Force the command execution (if applicable) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/queue_job_response_dto.dart b/mobile/openapi/lib/model/queue_job_response_dto.dart index 1bfaa56195c5c..2ce63784ebe8f 100644 --- a/mobile/openapi/lib/model/queue_job_response_dto.dart +++ b/mobile/openapi/lib/model/queue_job_response_dto.dart @@ -19,8 +19,10 @@ class QueueJobResponseDto { required this.timestamp, }); + /// Job data payload Object data; + /// Job ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -29,8 +31,10 @@ class QueueJobResponseDto { /// String? id; + /// Job name JobName name; + /// Job creation timestamp int timestamp; @override diff --git a/mobile/openapi/lib/model/queue_response_dto.dart b/mobile/openapi/lib/model/queue_response_dto.dart index c5d4ed8e3d48f..ac9244514c3f3 100644 --- a/mobile/openapi/lib/model/queue_response_dto.dart +++ b/mobile/openapi/lib/model/queue_response_dto.dart @@ -18,8 +18,10 @@ class QueueResponseDto { required this.statistics, }); + /// Whether the queue is paused bool isPaused; + /// Queue name QueueName name; QueueStatisticsDto statistics; diff --git a/mobile/openapi/lib/model/queue_statistics_dto.dart b/mobile/openapi/lib/model/queue_statistics_dto.dart index c27c4a5892d67..c9a37ee30aab6 100644 --- a/mobile/openapi/lib/model/queue_statistics_dto.dart +++ b/mobile/openapi/lib/model/queue_statistics_dto.dart @@ -21,16 +21,22 @@ class QueueStatisticsDto { required this.waiting, }); + /// Number of active jobs int active; + /// Number of completed jobs int completed; + /// Number of delayed jobs int delayed; + /// Number of failed jobs int failed; + /// Number of paused jobs int paused; + /// Number of waiting jobs int waiting; @override diff --git a/mobile/openapi/lib/model/queue_status_legacy_dto.dart b/mobile/openapi/lib/model/queue_status_legacy_dto.dart index 88c4eac340ef4..de6ce63319c28 100644 --- a/mobile/openapi/lib/model/queue_status_legacy_dto.dart +++ b/mobile/openapi/lib/model/queue_status_legacy_dto.dart @@ -17,8 +17,10 @@ class QueueStatusLegacyDto { required this.isPaused, }); + /// Whether the queue is currently active (has running jobs) bool isActive; + /// Whether the queue is paused bool isPaused; @override diff --git a/mobile/openapi/lib/model/queue_update_dto.dart b/mobile/openapi/lib/model/queue_update_dto.dart index ce89e51878ba9..28aafe95f704b 100644 --- a/mobile/openapi/lib/model/queue_update_dto.dart +++ b/mobile/openapi/lib/model/queue_update_dto.dart @@ -16,6 +16,7 @@ class QueueUpdateDto { this.isPaused, }); + /// Whether to pause the queue /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/random_search_dto.dart b/mobile/openapi/lib/model/random_search_dto.dart index 96d670fd96170..7e0fb0c5c24c7 100644 --- a/mobile/openapi/lib/model/random_search_dto.dart +++ b/mobile/openapi/lib/model/random_search_dto.dart @@ -48,12 +48,16 @@ class RandomSearchDto { this.withStacked, }); + /// Filter by album IDs List albumIds; + /// Filter by city name String? city; + /// Filter by country name String? country; + /// Filter by creation date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -62,6 +66,7 @@ class RandomSearchDto { /// DateTime? createdAfter; + /// Filter by creation date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -70,6 +75,7 @@ class RandomSearchDto { /// DateTime? createdBefore; + /// Device ID to filter by /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -78,6 +84,7 @@ class RandomSearchDto { /// String? deviceId; + /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -86,6 +93,7 @@ class RandomSearchDto { /// bool? isEncoded; + /// Filter by favorite status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -94,6 +102,7 @@ class RandomSearchDto { /// bool? isFavorite; + /// Filter by motion photo status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -102,6 +111,7 @@ class RandomSearchDto { /// bool? isMotion; + /// Filter assets not in any album /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -110,6 +120,7 @@ class RandomSearchDto { /// bool? isNotInAlbum; + /// Filter by offline status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -118,10 +129,13 @@ class RandomSearchDto { /// bool? isOffline; + /// Filter by lens model String? lensModel; + /// Library ID to filter by String? libraryId; + /// Filter by camera make /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -130,8 +144,10 @@ class RandomSearchDto { /// String? make; + /// Filter by camera model String? model; + /// Filter by OCR text content /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -140,8 +156,11 @@ class RandomSearchDto { /// String? ocr; + /// Filter by person IDs List personIds; + /// Filter by rating + /// /// Minimum value: -1 /// Maximum value: 5 /// @@ -152,6 +171,8 @@ class RandomSearchDto { /// num? rating; + /// Number of results to return + /// /// Minimum value: 1 /// Maximum value: 1000 /// @@ -162,10 +183,13 @@ class RandomSearchDto { /// num? size; + /// Filter by state/province name String? state; + /// Filter by tag IDs List? tagIds; + /// Filter by taken date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -174,6 +198,7 @@ class RandomSearchDto { /// DateTime? takenAfter; + /// Filter by taken date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -182,6 +207,7 @@ class RandomSearchDto { /// DateTime? takenBefore; + /// Filter by trash date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -190,6 +216,7 @@ class RandomSearchDto { /// DateTime? trashedAfter; + /// Filter by trash date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -198,6 +225,7 @@ class RandomSearchDto { /// DateTime? trashedBefore; + /// Asset type filter /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -206,6 +234,7 @@ class RandomSearchDto { /// AssetTypeEnum? type; + /// Filter by update date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -214,6 +243,7 @@ class RandomSearchDto { /// DateTime? updatedAfter; + /// Filter by update date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -222,6 +252,7 @@ class RandomSearchDto { /// DateTime? updatedBefore; + /// Filter by visibility /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -230,6 +261,7 @@ class RandomSearchDto { /// AssetVisibility? visibility; + /// Include deleted assets /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -238,6 +270,7 @@ class RandomSearchDto { /// bool? withDeleted; + /// Include EXIF data in response /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -246,6 +279,7 @@ class RandomSearchDto { /// bool? withExif; + /// Include assets with people /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -254,6 +288,7 @@ class RandomSearchDto { /// bool? withPeople; + /// Include stacked assets /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/ratings_response.dart b/mobile/openapi/lib/model/ratings_response.dart index 8e1951277ae80..4346fa5c583c0 100644 --- a/mobile/openapi/lib/model/ratings_response.dart +++ b/mobile/openapi/lib/model/ratings_response.dart @@ -16,6 +16,7 @@ class RatingsResponse { this.enabled = false, }); + /// Whether ratings are enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/ratings_update.dart b/mobile/openapi/lib/model/ratings_update.dart index 5d9f9a655f0ad..8079172e219a4 100644 --- a/mobile/openapi/lib/model/ratings_update.dart +++ b/mobile/openapi/lib/model/ratings_update.dart @@ -16,6 +16,7 @@ class RatingsUpdate { this.enabled, }); + /// Whether ratings are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/reverse_geocoding_state_response_dto.dart b/mobile/openapi/lib/model/reverse_geocoding_state_response_dto.dart index 5b3648b46bb2a..6ad8c1a7b9db1 100644 --- a/mobile/openapi/lib/model/reverse_geocoding_state_response_dto.dart +++ b/mobile/openapi/lib/model/reverse_geocoding_state_response_dto.dart @@ -17,8 +17,10 @@ class ReverseGeocodingStateResponseDto { required this.lastUpdate, }); + /// Last import file name String? lastImportFileName; + /// Last update timestamp String? lastUpdate; @override diff --git a/mobile/openapi/lib/model/search_album_response_dto.dart b/mobile/openapi/lib/model/search_album_response_dto.dart index e9b47e85ec9a3..8841251e4adcb 100644 --- a/mobile/openapi/lib/model/search_album_response_dto.dart +++ b/mobile/openapi/lib/model/search_album_response_dto.dart @@ -19,12 +19,14 @@ class SearchAlbumResponseDto { required this.total, }); + /// Number of albums in this page int count; List facets; List items; + /// Total number of matching albums int total; @override diff --git a/mobile/openapi/lib/model/search_asset_response_dto.dart b/mobile/openapi/lib/model/search_asset_response_dto.dart index 3d214e61d9fef..acb81f28e28d8 100644 --- a/mobile/openapi/lib/model/search_asset_response_dto.dart +++ b/mobile/openapi/lib/model/search_asset_response_dto.dart @@ -20,14 +20,17 @@ class SearchAssetResponseDto { required this.total, }); + /// Number of assets in this page int count; List facets; List items; + /// Next page token String? nextPage; + /// Total number of matching assets int total; @override diff --git a/mobile/openapi/lib/model/search_explore_item.dart b/mobile/openapi/lib/model/search_explore_item.dart index d44b2cd704a9a..4089011879e8a 100644 --- a/mobile/openapi/lib/model/search_explore_item.dart +++ b/mobile/openapi/lib/model/search_explore_item.dart @@ -19,6 +19,7 @@ class SearchExploreItem { AssetResponseDto data; + /// Explore value String value; @override diff --git a/mobile/openapi/lib/model/search_explore_response_dto.dart b/mobile/openapi/lib/model/search_explore_response_dto.dart index 3b5d4f984933a..07ce26c9b85a8 100644 --- a/mobile/openapi/lib/model/search_explore_response_dto.dart +++ b/mobile/openapi/lib/model/search_explore_response_dto.dart @@ -17,6 +17,7 @@ class SearchExploreResponseDto { this.items = const [], }); + /// Explore field name String fieldName; List items; diff --git a/mobile/openapi/lib/model/search_facet_count_response_dto.dart b/mobile/openapi/lib/model/search_facet_count_response_dto.dart index f8eee844859e3..8318fbfb3bcc0 100644 --- a/mobile/openapi/lib/model/search_facet_count_response_dto.dart +++ b/mobile/openapi/lib/model/search_facet_count_response_dto.dart @@ -17,8 +17,10 @@ class SearchFacetCountResponseDto { required this.value, }); + /// Number of assets with this facet value int count; + /// Facet value String value; @override diff --git a/mobile/openapi/lib/model/search_facet_response_dto.dart b/mobile/openapi/lib/model/search_facet_response_dto.dart index aeec873c8ddfb..43b5ac5c81219 100644 --- a/mobile/openapi/lib/model/search_facet_response_dto.dart +++ b/mobile/openapi/lib/model/search_facet_response_dto.dart @@ -17,8 +17,10 @@ class SearchFacetResponseDto { required this.fieldName, }); + /// Facet counts List counts; + /// Facet field name String fieldName; @override diff --git a/mobile/openapi/lib/model/search_statistics_response_dto.dart b/mobile/openapi/lib/model/search_statistics_response_dto.dart index 84f31373d8883..5aebe4d6a9dcb 100644 --- a/mobile/openapi/lib/model/search_statistics_response_dto.dart +++ b/mobile/openapi/lib/model/search_statistics_response_dto.dart @@ -16,6 +16,7 @@ class SearchStatisticsResponseDto { required this.total, }); + /// Total number of matching assets int total; @override diff --git a/mobile/openapi/lib/model/server_about_response_dto.dart b/mobile/openapi/lib/model/server_about_response_dto.dart index 5d53d5fdee665..1ae53763fec7f 100644 --- a/mobile/openapi/lib/model/server_about_response_dto.dart +++ b/mobile/openapi/lib/model/server_about_response_dto.dart @@ -36,6 +36,7 @@ class ServerAboutResponseDto { required this.versionUrl, }); + /// Build identifier /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -44,6 +45,7 @@ class ServerAboutResponseDto { /// String? build; + /// Build image name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -52,6 +54,7 @@ class ServerAboutResponseDto { /// String? buildImage; + /// Build image URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -60,6 +63,7 @@ class ServerAboutResponseDto { /// String? buildImageUrl; + /// Build URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -68,6 +72,7 @@ class ServerAboutResponseDto { /// String? buildUrl; + /// ExifTool version /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -76,6 +81,7 @@ class ServerAboutResponseDto { /// String? exiftool; + /// FFmpeg version /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -84,6 +90,7 @@ class ServerAboutResponseDto { /// String? ffmpeg; + /// ImageMagick version /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -92,6 +99,7 @@ class ServerAboutResponseDto { /// String? imagemagick; + /// libvips version /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -100,8 +108,10 @@ class ServerAboutResponseDto { /// String? libvips; + /// Whether the server is licensed bool licensed; + /// Node.js version /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -110,6 +120,7 @@ class ServerAboutResponseDto { /// String? nodejs; + /// Repository name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -118,6 +129,7 @@ class ServerAboutResponseDto { /// String? repository; + /// Repository URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -126,6 +138,7 @@ class ServerAboutResponseDto { /// String? repositoryUrl; + /// Source commit hash /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -134,6 +147,7 @@ class ServerAboutResponseDto { /// String? sourceCommit; + /// Source reference (branch/tag) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -142,6 +156,7 @@ class ServerAboutResponseDto { /// String? sourceRef; + /// Source URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -150,6 +165,7 @@ class ServerAboutResponseDto { /// String? sourceUrl; + /// Third-party bug/feature URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -158,6 +174,7 @@ class ServerAboutResponseDto { /// String? thirdPartyBugFeatureUrl; + /// Third-party documentation URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -166,6 +183,7 @@ class ServerAboutResponseDto { /// String? thirdPartyDocumentationUrl; + /// Third-party source URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -174,6 +192,7 @@ class ServerAboutResponseDto { /// String? thirdPartySourceUrl; + /// Third-party support URL /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -182,8 +201,10 @@ class ServerAboutResponseDto { /// String? thirdPartySupportUrl; + /// Server version String version; + /// URL to version information String versionUrl; @override diff --git a/mobile/openapi/lib/model/server_apk_links_dto.dart b/mobile/openapi/lib/model/server_apk_links_dto.dart index 086a2f172b39f..2227018468748 100644 --- a/mobile/openapi/lib/model/server_apk_links_dto.dart +++ b/mobile/openapi/lib/model/server_apk_links_dto.dart @@ -19,12 +19,16 @@ class ServerApkLinksDto { required this.x8664, }); + /// APK download link for ARM64 v8a architecture String arm64v8a; + /// APK download link for ARM EABI v7a architecture String armeabiv7a; + /// APK download link for universal architecture String universal; + /// APK download link for x86_64 architecture String x8664; @override diff --git a/mobile/openapi/lib/model/server_config_dto.dart b/mobile/openapi/lib/model/server_config_dto.dart index 8e701472b164e..fec096d51aad5 100644 --- a/mobile/openapi/lib/model/server_config_dto.dart +++ b/mobile/openapi/lib/model/server_config_dto.dart @@ -26,26 +26,37 @@ class ServerConfigDto { required this.userDeleteDelay, }); + /// External domain URL String externalDomain; + /// Whether the server has been initialized bool isInitialized; + /// Whether the admin has completed onboarding bool isOnboarded; + /// Login page message String loginPageMessage; + /// Whether maintenance mode is active bool maintenanceMode; + /// Map dark style URL String mapDarkStyleUrl; + /// Map light style URL String mapLightStyleUrl; + /// OAuth button text String oauthButtonText; + /// Whether public user registration is enabled bool publicUsers; + /// Number of days before trashed assets are permanently deleted int trashDays; + /// Delay in days before deleted users are permanently removed int userDeleteDelay; @override diff --git a/mobile/openapi/lib/model/server_features_dto.dart b/mobile/openapi/lib/model/server_features_dto.dart index 7b5980ca13c89..79494b74eb593 100644 --- a/mobile/openapi/lib/model/server_features_dto.dart +++ b/mobile/openapi/lib/model/server_features_dto.dart @@ -30,34 +30,49 @@ class ServerFeaturesDto { required this.trash, }); + /// Whether config file is available bool configFile; + /// Whether duplicate detection is enabled bool duplicateDetection; + /// Whether email notifications are enabled bool email; + /// Whether facial recognition is enabled bool facialRecognition; + /// Whether face import is enabled bool importFaces; + /// Whether map feature is enabled bool map; + /// Whether OAuth is enabled bool oauth; + /// Whether OAuth auto-launch is enabled bool oauthAutoLaunch; + /// Whether OCR is enabled bool ocr; + /// Whether password login is enabled bool passwordLogin; + /// Whether reverse geocoding is enabled bool reverseGeocoding; + /// Whether search is enabled bool search; + /// Whether sidecar files are supported bool sidecar; + /// Whether smart search is enabled bool smartSearch; + /// Whether trash feature is enabled bool trash; @override diff --git a/mobile/openapi/lib/model/server_media_types_response_dto.dart b/mobile/openapi/lib/model/server_media_types_response_dto.dart index 506cbb44b4d76..6a2aaeb9e16b0 100644 --- a/mobile/openapi/lib/model/server_media_types_response_dto.dart +++ b/mobile/openapi/lib/model/server_media_types_response_dto.dart @@ -18,10 +18,13 @@ class ServerMediaTypesResponseDto { this.video = const [], }); + /// Supported image MIME types List image; + /// Supported sidecar MIME types List sidecar; + /// Supported video MIME types List video; @override diff --git a/mobile/openapi/lib/model/server_stats_response_dto.dart b/mobile/openapi/lib/model/server_stats_response_dto.dart index 531fa8f03e16a..ef2fa458e2545 100644 --- a/mobile/openapi/lib/model/server_stats_response_dto.dart +++ b/mobile/openapi/lib/model/server_stats_response_dto.dart @@ -21,16 +21,21 @@ class ServerStatsResponseDto { this.videos = 0, }); + /// Total number of photos int photos; + /// Total storage usage in bytes int usage; List usageByUser; + /// Storage usage for photos in bytes int usagePhotos; + /// Storage usage for videos in bytes int usageVideos; + /// Total number of videos int videos; @override diff --git a/mobile/openapi/lib/model/server_storage_response_dto.dart b/mobile/openapi/lib/model/server_storage_response_dto.dart index 8d12e77834bec..476b048b4dfe3 100644 --- a/mobile/openapi/lib/model/server_storage_response_dto.dart +++ b/mobile/openapi/lib/model/server_storage_response_dto.dart @@ -22,18 +22,25 @@ class ServerStorageResponseDto { required this.diskUseRaw, }); + /// Available disk space (human-readable format) String diskAvailable; + /// Available disk space in bytes int diskAvailableRaw; + /// Total disk size (human-readable format) String diskSize; + /// Total disk size in bytes int diskSizeRaw; + /// Disk usage percentage (0-100) double diskUsagePercentage; + /// Used disk space (human-readable format) String diskUse; + /// Used disk space in bytes int diskUseRaw; @override diff --git a/mobile/openapi/lib/model/server_theme_dto.dart b/mobile/openapi/lib/model/server_theme_dto.dart index 69e1b2d2c87a7..957cf84d554eb 100644 --- a/mobile/openapi/lib/model/server_theme_dto.dart +++ b/mobile/openapi/lib/model/server_theme_dto.dart @@ -16,6 +16,7 @@ class ServerThemeDto { required this.customCss, }); + /// Custom CSS for theming String customCss; @override diff --git a/mobile/openapi/lib/model/server_version_history_response_dto.dart b/mobile/openapi/lib/model/server_version_history_response_dto.dart index c81cb0e8b9f8b..c3b7049016fbc 100644 --- a/mobile/openapi/lib/model/server_version_history_response_dto.dart +++ b/mobile/openapi/lib/model/server_version_history_response_dto.dart @@ -18,10 +18,13 @@ class ServerVersionHistoryResponseDto { required this.version, }); + /// When this version was first seen DateTime createdAt; + /// Version history entry ID String id; + /// Version string String version; @override diff --git a/mobile/openapi/lib/model/server_version_response_dto.dart b/mobile/openapi/lib/model/server_version_response_dto.dart index 751347fabd2c1..a13cd81ad7682 100644 --- a/mobile/openapi/lib/model/server_version_response_dto.dart +++ b/mobile/openapi/lib/model/server_version_response_dto.dart @@ -18,10 +18,13 @@ class ServerVersionResponseDto { required this.patch_, }); + /// Major version number int major; + /// Minor version number int minor; + /// Patch version number int patch_; @override diff --git a/mobile/openapi/lib/model/session_create_dto.dart b/mobile/openapi/lib/model/session_create_dto.dart index aacf1150a51e3..3874bc33037c9 100644 --- a/mobile/openapi/lib/model/session_create_dto.dart +++ b/mobile/openapi/lib/model/session_create_dto.dart @@ -18,6 +18,7 @@ class SessionCreateDto { this.duration, }); + /// Device OS /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -26,6 +27,7 @@ class SessionCreateDto { /// String? deviceOS; + /// Device type /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,7 +36,7 @@ class SessionCreateDto { /// String? deviceType; - /// session duration, in seconds + /// Session duration in seconds /// /// Minimum value: 1 /// diff --git a/mobile/openapi/lib/model/session_create_response_dto.dart b/mobile/openapi/lib/model/session_create_response_dto.dart index e16597f3b5d3b..f35232b0e8b60 100644 --- a/mobile/openapi/lib/model/session_create_response_dto.dart +++ b/mobile/openapi/lib/model/session_create_response_dto.dart @@ -25,16 +25,22 @@ class SessionCreateResponseDto { required this.updatedAt, }); + /// App version String? appVersion; + /// Creation date String createdAt; + /// Is current session bool current; + /// Device OS String deviceOS; + /// Device type String deviceType; + /// Expiration date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -43,12 +49,16 @@ class SessionCreateResponseDto { /// String? expiresAt; + /// Session ID String id; + /// Is pending sync reset bool isPendingSyncReset; + /// Session token String token; + /// Last update date String updatedAt; @override diff --git a/mobile/openapi/lib/model/session_response_dto.dart b/mobile/openapi/lib/model/session_response_dto.dart index 85acb8a358215..ed84160827a47 100644 --- a/mobile/openapi/lib/model/session_response_dto.dart +++ b/mobile/openapi/lib/model/session_response_dto.dart @@ -24,16 +24,22 @@ class SessionResponseDto { required this.updatedAt, }); + /// App version String? appVersion; + /// Creation date String createdAt; + /// Is current session bool current; + /// Device OS String deviceOS; + /// Device type String deviceType; + /// Expiration date /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -42,10 +48,13 @@ class SessionResponseDto { /// String? expiresAt; + /// Session ID String id; + /// Is pending sync reset bool isPendingSyncReset; + /// Last update date String updatedAt; @override diff --git a/mobile/openapi/lib/model/session_unlock_dto.dart b/mobile/openapi/lib/model/session_unlock_dto.dart index 4cfeb143854a0..48ee75fb05b8a 100644 --- a/mobile/openapi/lib/model/session_unlock_dto.dart +++ b/mobile/openapi/lib/model/session_unlock_dto.dart @@ -17,6 +17,7 @@ class SessionUnlockDto { this.pinCode, }); + /// User password (required if PIN code is not provided) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class SessionUnlockDto { /// String? password; + /// New PIN code (4-6 digits) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/session_update_dto.dart b/mobile/openapi/lib/model/session_update_dto.dart index cd170b1baa916..3ab430deaa214 100644 --- a/mobile/openapi/lib/model/session_update_dto.dart +++ b/mobile/openapi/lib/model/session_update_dto.dart @@ -16,6 +16,7 @@ class SessionUpdateDto { this.isPendingSyncReset, }); + /// Reset pending sync state /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/set_maintenance_mode_dto.dart b/mobile/openapi/lib/model/set_maintenance_mode_dto.dart index d2fe900d4f53e..14bf584bb90a4 100644 --- a/mobile/openapi/lib/model/set_maintenance_mode_dto.dart +++ b/mobile/openapi/lib/model/set_maintenance_mode_dto.dart @@ -17,8 +17,10 @@ class SetMaintenanceModeDto { this.restoreBackupFilename, }); + /// Maintenance action MaintenanceAction action; + /// Restore backup filename /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/shared_link_create_dto.dart b/mobile/openapi/lib/model/shared_link_create_dto.dart index 644227bd6e471..2675ad4beb3f7 100644 --- a/mobile/openapi/lib/model/shared_link_create_dto.dart +++ b/mobile/openapi/lib/model/shared_link_create_dto.dart @@ -25,6 +25,7 @@ class SharedLinkCreateDto { required this.type, }); + /// Album ID (for album sharing) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -33,8 +34,10 @@ class SharedLinkCreateDto { /// String? albumId; + /// Allow downloads bool allowDownload; + /// Allow uploads /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -43,18 +46,25 @@ class SharedLinkCreateDto { /// bool? allowUpload; + /// Asset IDs (for individual assets) List assetIds; + /// Link description String? description; + /// Expiration date DateTime? expiresAt; + /// Link password String? password; + /// Show metadata bool showMetadata; + /// Custom URL slug String? slug; + /// Shared link type SharedLinkType type; @override diff --git a/mobile/openapi/lib/model/shared_link_edit_dto.dart b/mobile/openapi/lib/model/shared_link_edit_dto.dart index f13bc6977bc86..b22232add6d79 100644 --- a/mobile/openapi/lib/model/shared_link_edit_dto.dart +++ b/mobile/openapi/lib/model/shared_link_edit_dto.dart @@ -23,6 +23,7 @@ class SharedLinkEditDto { this.slug, }); + /// Allow downloads /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -31,6 +32,7 @@ class SharedLinkEditDto { /// bool? allowDownload; + /// Allow uploads /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -39,7 +41,7 @@ class SharedLinkEditDto { /// bool? allowUpload; - /// Few clients cannot send null to set the expiryTime to never. Setting this flag and not sending expiryAt is considered as null instead. Clients that can send null values can ignore this. + /// Whether to change the expiry time. Few clients cannot send null to set the expiryTime to never. Setting this flag and not sending expiryAt is considered as null instead. Clients that can send null values can ignore this. /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -48,12 +50,16 @@ class SharedLinkEditDto { /// bool? changeExpiryTime; + /// Link description String? description; + /// Expiration date DateTime? expiresAt; + /// Link password String? password; + /// Show metadata /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -62,6 +68,7 @@ class SharedLinkEditDto { /// bool? showMetadata; + /// Custom URL slug String? slug; @override diff --git a/mobile/openapi/lib/model/shared_link_response_dto.dart b/mobile/openapi/lib/model/shared_link_response_dto.dart index d81e1dfa319d5..d9aec48c39391 100644 --- a/mobile/openapi/lib/model/shared_link_response_dto.dart +++ b/mobile/openapi/lib/model/shared_link_response_dto.dart @@ -38,32 +38,45 @@ class SharedLinkResponseDto { /// AlbumResponseDto? album; + /// Allow downloads bool allowDownload; + /// Allow uploads bool allowUpload; List assets; + /// Creation date DateTime createdAt; + /// Link description String? description; + /// Expiration date DateTime? expiresAt; + /// Shared link ID String id; + /// Encryption key (base64url) String key; + /// Has password String? password; + /// Show metadata bool showMetadata; + /// Custom URL slug String? slug; + /// Access token String? token; + /// Shared link type SharedLinkType type; + /// Owner user ID String userId; @override diff --git a/mobile/openapi/lib/model/shared_link_type.dart b/mobile/openapi/lib/model/shared_link_type.dart index efab97c2095ec..6a17a9c76342f 100644 --- a/mobile/openapi/lib/model/shared_link_type.dart +++ b/mobile/openapi/lib/model/shared_link_type.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Shared link type class SharedLinkType { /// Instantiate a new enum with the provided [value]. const SharedLinkType._(this.value); diff --git a/mobile/openapi/lib/model/shared_links_response.dart b/mobile/openapi/lib/model/shared_links_response.dart index 80875e6174da3..510e94e43f898 100644 --- a/mobile/openapi/lib/model/shared_links_response.dart +++ b/mobile/openapi/lib/model/shared_links_response.dart @@ -17,8 +17,10 @@ class SharedLinksResponse { this.sidebarWeb = false, }); + /// Whether shared links are enabled bool enabled; + /// Whether shared links appear in web sidebar bool sidebarWeb; @override diff --git a/mobile/openapi/lib/model/shared_links_update.dart b/mobile/openapi/lib/model/shared_links_update.dart index 5d9eda3001cca..8e792b4f49b0f 100644 --- a/mobile/openapi/lib/model/shared_links_update.dart +++ b/mobile/openapi/lib/model/shared_links_update.dart @@ -17,6 +17,7 @@ class SharedLinksUpdate { this.sidebarWeb, }); + /// Whether shared links are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class SharedLinksUpdate { /// bool? enabled; + /// Whether shared links appear in web sidebar /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/sign_up_dto.dart b/mobile/openapi/lib/model/sign_up_dto.dart index 7e0ff4045c7b5..54c8fa07d23b8 100644 --- a/mobile/openapi/lib/model/sign_up_dto.dart +++ b/mobile/openapi/lib/model/sign_up_dto.dart @@ -18,10 +18,13 @@ class SignUpDto { required this.password, }); + /// User email String email; + /// User name String name; + /// User password String password; @override diff --git a/mobile/openapi/lib/model/smart_search_dto.dart b/mobile/openapi/lib/model/smart_search_dto.dart index 24f040a92b904..7d43cea8729e2 100644 --- a/mobile/openapi/lib/model/smart_search_dto.dart +++ b/mobile/openapi/lib/model/smart_search_dto.dart @@ -50,12 +50,16 @@ class SmartSearchDto { this.withExif, }); + /// Filter by album IDs List albumIds; + /// Filter by city name String? city; + /// Filter by country name String? country; + /// Filter by creation date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -64,6 +68,7 @@ class SmartSearchDto { /// DateTime? createdAfter; + /// Filter by creation date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -72,6 +77,7 @@ class SmartSearchDto { /// DateTime? createdBefore; + /// Device ID to filter by /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -80,6 +86,7 @@ class SmartSearchDto { /// String? deviceId; + /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -88,6 +95,7 @@ class SmartSearchDto { /// bool? isEncoded; + /// Filter by favorite status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -96,6 +104,7 @@ class SmartSearchDto { /// bool? isFavorite; + /// Filter by motion photo status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -104,6 +113,7 @@ class SmartSearchDto { /// bool? isMotion; + /// Filter assets not in any album /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -112,6 +122,7 @@ class SmartSearchDto { /// bool? isNotInAlbum; + /// Filter by offline status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -120,6 +131,7 @@ class SmartSearchDto { /// bool? isOffline; + /// Search language code /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -128,10 +140,13 @@ class SmartSearchDto { /// String? language; + /// Filter by lens model String? lensModel; + /// Library ID to filter by String? libraryId; + /// Filter by camera make /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -140,8 +155,10 @@ class SmartSearchDto { /// String? make; + /// Filter by camera model String? model; + /// Filter by OCR text content /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -150,6 +167,8 @@ class SmartSearchDto { /// String? ocr; + /// Page number + /// /// Minimum value: 1 /// /// Please note: This property should have been non-nullable! Since the specification file @@ -159,8 +178,10 @@ class SmartSearchDto { /// num? page; + /// Filter by person IDs List personIds; + /// Natural language search query /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -169,6 +190,7 @@ class SmartSearchDto { /// String? query; + /// Asset ID to use as search reference /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -177,6 +199,8 @@ class SmartSearchDto { /// String? queryAssetId; + /// Filter by rating + /// /// Minimum value: -1 /// Maximum value: 5 /// @@ -187,6 +211,8 @@ class SmartSearchDto { /// num? rating; + /// Number of results to return + /// /// Minimum value: 1 /// Maximum value: 1000 /// @@ -197,10 +223,13 @@ class SmartSearchDto { /// num? size; + /// Filter by state/province name String? state; + /// Filter by tag IDs List? tagIds; + /// Filter by taken date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -209,6 +238,7 @@ class SmartSearchDto { /// DateTime? takenAfter; + /// Filter by taken date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -217,6 +247,7 @@ class SmartSearchDto { /// DateTime? takenBefore; + /// Filter by trash date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -225,6 +256,7 @@ class SmartSearchDto { /// DateTime? trashedAfter; + /// Filter by trash date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -233,6 +265,7 @@ class SmartSearchDto { /// DateTime? trashedBefore; + /// Asset type filter /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -241,6 +274,7 @@ class SmartSearchDto { /// AssetTypeEnum? type; + /// Filter by update date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -249,6 +283,7 @@ class SmartSearchDto { /// DateTime? updatedAfter; + /// Filter by update date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -257,6 +292,7 @@ class SmartSearchDto { /// DateTime? updatedBefore; + /// Filter by visibility /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -265,6 +301,7 @@ class SmartSearchDto { /// AssetVisibility? visibility; + /// Include deleted assets /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -273,6 +310,7 @@ class SmartSearchDto { /// bool? withDeleted; + /// Include EXIF data in response /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/source_type.dart b/mobile/openapi/lib/model/source_type.dart index 4da5aba495d0e..ed164172a370b 100644 --- a/mobile/openapi/lib/model/source_type.dart +++ b/mobile/openapi/lib/model/source_type.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Face detection source type class SourceType { /// Instantiate a new enum with the provided [value]. const SourceType._(this.value); diff --git a/mobile/openapi/lib/model/stack_create_dto.dart b/mobile/openapi/lib/model/stack_create_dto.dart index cb51081eb1ee4..6b08c83401752 100644 --- a/mobile/openapi/lib/model/stack_create_dto.dart +++ b/mobile/openapi/lib/model/stack_create_dto.dart @@ -16,7 +16,7 @@ class StackCreateDto { this.assetIds = const [], }); - /// first asset becomes the primary + /// Asset IDs (first becomes primary, min 2) List assetIds; @override diff --git a/mobile/openapi/lib/model/stack_response_dto.dart b/mobile/openapi/lib/model/stack_response_dto.dart index b6cb747cafc5f..638dfb52557cc 100644 --- a/mobile/openapi/lib/model/stack_response_dto.dart +++ b/mobile/openapi/lib/model/stack_response_dto.dart @@ -18,10 +18,13 @@ class StackResponseDto { required this.primaryAssetId, }); + /// Stack assets List assets; + /// Stack ID String id; + /// Primary asset ID String primaryAssetId; @override diff --git a/mobile/openapi/lib/model/stack_update_dto.dart b/mobile/openapi/lib/model/stack_update_dto.dart index 0101499edfc51..e81c204f972c3 100644 --- a/mobile/openapi/lib/model/stack_update_dto.dart +++ b/mobile/openapi/lib/model/stack_update_dto.dart @@ -16,6 +16,7 @@ class StackUpdateDto { this.primaryAssetId, }); + /// Primary asset ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/statistics_search_dto.dart b/mobile/openapi/lib/model/statistics_search_dto.dart index e0965352e08a2..fce2feb421b92 100644 --- a/mobile/openapi/lib/model/statistics_search_dto.dart +++ b/mobile/openapi/lib/model/statistics_search_dto.dart @@ -44,12 +44,16 @@ class StatisticsSearchDto { this.visibility, }); + /// Filter by album IDs List albumIds; + /// Filter by city name String? city; + /// Filter by country name String? country; + /// Filter by creation date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -58,6 +62,7 @@ class StatisticsSearchDto { /// DateTime? createdAfter; + /// Filter by creation date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -66,6 +71,7 @@ class StatisticsSearchDto { /// DateTime? createdBefore; + /// Filter by description text /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -74,6 +80,7 @@ class StatisticsSearchDto { /// String? description; + /// Device ID to filter by /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -82,6 +89,7 @@ class StatisticsSearchDto { /// String? deviceId; + /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -90,6 +98,7 @@ class StatisticsSearchDto { /// bool? isEncoded; + /// Filter by favorite status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -98,6 +107,7 @@ class StatisticsSearchDto { /// bool? isFavorite; + /// Filter by motion photo status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -106,6 +116,7 @@ class StatisticsSearchDto { /// bool? isMotion; + /// Filter assets not in any album /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -114,6 +125,7 @@ class StatisticsSearchDto { /// bool? isNotInAlbum; + /// Filter by offline status /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -122,10 +134,13 @@ class StatisticsSearchDto { /// bool? isOffline; + /// Filter by lens model String? lensModel; + /// Library ID to filter by String? libraryId; + /// Filter by camera make /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -134,8 +149,10 @@ class StatisticsSearchDto { /// String? make; + /// Filter by camera model String? model; + /// Filter by OCR text content /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -144,8 +161,11 @@ class StatisticsSearchDto { /// String? ocr; + /// Filter by person IDs List personIds; + /// Filter by rating + /// /// Minimum value: -1 /// Maximum value: 5 /// @@ -156,10 +176,13 @@ class StatisticsSearchDto { /// num? rating; + /// Filter by state/province name String? state; + /// Filter by tag IDs List? tagIds; + /// Filter by taken date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -168,6 +191,7 @@ class StatisticsSearchDto { /// DateTime? takenAfter; + /// Filter by taken date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -176,6 +200,7 @@ class StatisticsSearchDto { /// DateTime? takenBefore; + /// Filter by trash date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -184,6 +209,7 @@ class StatisticsSearchDto { /// DateTime? trashedAfter; + /// Filter by trash date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -192,6 +218,7 @@ class StatisticsSearchDto { /// DateTime? trashedBefore; + /// Asset type filter /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -200,6 +227,7 @@ class StatisticsSearchDto { /// AssetTypeEnum? type; + /// Filter by update date (after) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -208,6 +236,7 @@ class StatisticsSearchDto { /// DateTime? updatedAfter; + /// Filter by update date (before) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -216,6 +245,7 @@ class StatisticsSearchDto { /// DateTime? updatedBefore; + /// Filter by visibility /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/storage_folder.dart b/mobile/openapi/lib/model/storage_folder.dart index df66bc187a33f..8579d48f288ec 100644 --- a/mobile/openapi/lib/model/storage_folder.dart +++ b/mobile/openapi/lib/model/storage_folder.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Storage folder class StorageFolder { /// Instantiate a new enum with the provided [value]. const StorageFolder._(this.value); diff --git a/mobile/openapi/lib/model/sync_ack_delete_dto.dart b/mobile/openapi/lib/model/sync_ack_delete_dto.dart index 998f812f2e40d..b72ae8c5a6c14 100644 --- a/mobile/openapi/lib/model/sync_ack_delete_dto.dart +++ b/mobile/openapi/lib/model/sync_ack_delete_dto.dart @@ -16,6 +16,7 @@ class SyncAckDeleteDto { this.types = const [], }); + /// Sync entity types to delete acks for List types; @override diff --git a/mobile/openapi/lib/model/sync_ack_dto.dart b/mobile/openapi/lib/model/sync_ack_dto.dart index c7fafa17d20d4..747f671557756 100644 --- a/mobile/openapi/lib/model/sync_ack_dto.dart +++ b/mobile/openapi/lib/model/sync_ack_dto.dart @@ -17,8 +17,10 @@ class SyncAckDto { required this.type, }); + /// Acknowledgment ID String ack; + /// Sync entity type SyncEntityType type; @override diff --git a/mobile/openapi/lib/model/sync_ack_set_dto.dart b/mobile/openapi/lib/model/sync_ack_set_dto.dart index 0d9eedc389296..531a9dc76304d 100644 --- a/mobile/openapi/lib/model/sync_ack_set_dto.dart +++ b/mobile/openapi/lib/model/sync_ack_set_dto.dart @@ -16,6 +16,7 @@ class SyncAckSetDto { this.acks = const [], }); + /// Acknowledgment IDs (max 1000) List acks; @override diff --git a/mobile/openapi/lib/model/sync_album_delete_v1.dart b/mobile/openapi/lib/model/sync_album_delete_v1.dart index ae5ba3da5d1bf..a6fdf5c68c767 100644 --- a/mobile/openapi/lib/model/sync_album_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_album_delete_v1.dart @@ -16,6 +16,7 @@ class SyncAlbumDeleteV1 { required this.albumId, }); + /// Album ID String albumId; @override diff --git a/mobile/openapi/lib/model/sync_album_to_asset_delete_v1.dart b/mobile/openapi/lib/model/sync_album_to_asset_delete_v1.dart index d18c850b2acd8..08952b90ede3d 100644 --- a/mobile/openapi/lib/model/sync_album_to_asset_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_album_to_asset_delete_v1.dart @@ -17,8 +17,10 @@ class SyncAlbumToAssetDeleteV1 { required this.assetId, }); + /// Album ID String albumId; + /// Asset ID String assetId; @override diff --git a/mobile/openapi/lib/model/sync_album_to_asset_v1.dart b/mobile/openapi/lib/model/sync_album_to_asset_v1.dart index 6908f320f8060..5f38b35088891 100644 --- a/mobile/openapi/lib/model/sync_album_to_asset_v1.dart +++ b/mobile/openapi/lib/model/sync_album_to_asset_v1.dart @@ -17,8 +17,10 @@ class SyncAlbumToAssetV1 { required this.assetId, }); + /// Album ID String albumId; + /// Asset ID String assetId; @override diff --git a/mobile/openapi/lib/model/sync_album_user_delete_v1.dart b/mobile/openapi/lib/model/sync_album_user_delete_v1.dart index f2b0fbee2638d..526bcc6b6e00a 100644 --- a/mobile/openapi/lib/model/sync_album_user_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_album_user_delete_v1.dart @@ -17,8 +17,10 @@ class SyncAlbumUserDeleteV1 { required this.userId, }); + /// Album ID String albumId; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/sync_album_user_v1.dart b/mobile/openapi/lib/model/sync_album_user_v1.dart index 0b4968b34dd6d..3fc8972069239 100644 --- a/mobile/openapi/lib/model/sync_album_user_v1.dart +++ b/mobile/openapi/lib/model/sync_album_user_v1.dart @@ -18,10 +18,13 @@ class SyncAlbumUserV1 { required this.userId, }); + /// Album ID String albumId; + /// Album user role AlbumUserRole role; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/sync_album_v1.dart b/mobile/openapi/lib/model/sync_album_v1.dart index 8ac8246d46ab5..6c89d93724f4f 100644 --- a/mobile/openapi/lib/model/sync_album_v1.dart +++ b/mobile/openapi/lib/model/sync_album_v1.dart @@ -24,22 +24,30 @@ class SyncAlbumV1 { required this.updatedAt, }); + /// Created at DateTime createdAt; + /// Album description String description; + /// Album ID String id; + /// Is activity enabled bool isActivityEnabled; + /// Album name String name; AssetOrder order; + /// Owner ID String ownerId; + /// Thumbnail asset ID String? thumbnailAssetId; + /// Updated at DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/sync_asset_delete_v1.dart b/mobile/openapi/lib/model/sync_asset_delete_v1.dart index c1787caf04feb..1d5a947774015 100644 --- a/mobile/openapi/lib/model/sync_asset_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_delete_v1.dart @@ -16,6 +16,7 @@ class SyncAssetDeleteV1 { required this.assetId, }); + /// Asset ID String assetId; @override diff --git a/mobile/openapi/lib/model/sync_asset_exif_v1.dart b/mobile/openapi/lib/model/sync_asset_exif_v1.dart index d4fdc9249d6ed..ff9efdfea3f53 100644 --- a/mobile/openapi/lib/model/sync_asset_exif_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_exif_v1.dart @@ -40,54 +40,79 @@ class SyncAssetExifV1 { required this.timeZone, }); + /// Asset ID String assetId; + /// City String? city; + /// Country String? country; + /// Date time original DateTime? dateTimeOriginal; + /// Description String? description; + /// Exif image height int? exifImageHeight; + /// Exif image width int? exifImageWidth; + /// Exposure time String? exposureTime; + /// F number double? fNumber; + /// File size in byte int? fileSizeInByte; + /// Focal length double? focalLength; + /// FPS double? fps; + /// ISO int? iso; + /// Latitude double? latitude; + /// Lens model String? lensModel; + /// Longitude double? longitude; + /// Make String? make; + /// Model String? model; + /// Modify date DateTime? modifyDate; + /// Orientation String? orientation; + /// Profile description String? profileDescription; + /// Projection type String? projectionType; + /// Rating int? rating; + /// State String? state; + /// Time zone String? timeZone; @override diff --git a/mobile/openapi/lib/model/sync_asset_face_delete_v1.dart b/mobile/openapi/lib/model/sync_asset_face_delete_v1.dart index 0992bfdcba6b6..9cfb8814a728a 100644 --- a/mobile/openapi/lib/model/sync_asset_face_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_face_delete_v1.dart @@ -16,6 +16,7 @@ class SyncAssetFaceDeleteV1 { required this.assetFaceId, }); + /// Asset face ID String assetFaceId; @override diff --git a/mobile/openapi/lib/model/sync_asset_face_v1.dart b/mobile/openapi/lib/model/sync_asset_face_v1.dart index 60d1766e347b8..647a07d5eb0bd 100644 --- a/mobile/openapi/lib/model/sync_asset_face_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_face_v1.dart @@ -25,6 +25,7 @@ class SyncAssetFaceV1 { required this.sourceType, }); + /// Asset ID String assetId; int boundingBoxX1; @@ -35,14 +36,17 @@ class SyncAssetFaceV1 { int boundingBoxY2; + /// Asset face ID String id; int imageHeight; int imageWidth; + /// Person ID String? personId; + /// Source type String sourceType; @override diff --git a/mobile/openapi/lib/model/sync_asset_metadata_delete_v1.dart b/mobile/openapi/lib/model/sync_asset_metadata_delete_v1.dart index cf67b68dd240f..326555ef13338 100644 --- a/mobile/openapi/lib/model/sync_asset_metadata_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_metadata_delete_v1.dart @@ -17,8 +17,10 @@ class SyncAssetMetadataDeleteV1 { required this.key, }); + /// Asset ID String assetId; + /// Key String key; @override diff --git a/mobile/openapi/lib/model/sync_asset_metadata_v1.dart b/mobile/openapi/lib/model/sync_asset_metadata_v1.dart index 4fa6ed84ed012..4a66623939d20 100644 --- a/mobile/openapi/lib/model/sync_asset_metadata_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_metadata_v1.dart @@ -18,10 +18,13 @@ class SyncAssetMetadataV1 { required this.value, }); + /// Asset ID String assetId; + /// Key String key; + /// Value Object value; @override diff --git a/mobile/openapi/lib/model/sync_asset_v1.dart b/mobile/openapi/lib/model/sync_asset_v1.dart index 1d0e735396fd0..debde4488ebd2 100644 --- a/mobile/openapi/lib/model/sync_asset_v1.dart +++ b/mobile/openapi/lib/model/sync_asset_v1.dart @@ -34,42 +34,61 @@ class SyncAssetV1 { required this.width, }); + /// Checksum String checksum; + /// Deleted at DateTime? deletedAt; + /// Duration String? duration; + /// File created at DateTime? fileCreatedAt; + /// File modified at DateTime? fileModifiedAt; + /// Asset height int? height; + /// Asset ID String id; + /// Is edited bool isEdited; + /// Is favorite bool isFavorite; + /// Library ID String? libraryId; + /// Live photo video ID String? livePhotoVideoId; + /// Local date time DateTime? localDateTime; + /// Original file name String originalFileName; + /// Owner ID String ownerId; + /// Stack ID String? stackId; + /// Thumbhash String? thumbhash; + /// Asset type AssetTypeEnum type; + /// Asset visibility AssetVisibility visibility; + /// Asset width int? width; @override diff --git a/mobile/openapi/lib/model/sync_auth_user_v1.dart b/mobile/openapi/lib/model/sync_auth_user_v1.dart index 1dab7f47e3922..0edd804c6ab2d 100644 --- a/mobile/openapi/lib/model/sync_auth_user_v1.dart +++ b/mobile/openapi/lib/model/sync_auth_user_v1.dart @@ -28,30 +28,41 @@ class SyncAuthUserV1 { required this.storageLabel, }); + /// User avatar color UserAvatarColor? avatarColor; + /// User deleted at DateTime? deletedAt; + /// User email String email; + /// User has profile image bool hasProfileImage; + /// User ID String id; + /// User is admin bool isAdmin; + /// User name String name; + /// User OAuth ID String oauthId; + /// User pin code String? pinCode; + /// User profile changed at DateTime profileChangedAt; int? quotaSizeInBytes; int quotaUsageInBytes; + /// User storage label String? storageLabel; @override diff --git a/mobile/openapi/lib/model/sync_entity_type.dart b/mobile/openapi/lib/model/sync_entity_type.dart index 1b4ca91f3bff6..d1e321f39bf72 100644 --- a/mobile/openapi/lib/model/sync_entity_type.dart +++ b/mobile/openapi/lib/model/sync_entity_type.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Sync entity type class SyncEntityType { /// Instantiate a new enum with the provided [value]. const SyncEntityType._(this.value); diff --git a/mobile/openapi/lib/model/sync_memory_asset_delete_v1.dart b/mobile/openapi/lib/model/sync_memory_asset_delete_v1.dart index a9af77e929461..c37682d02decb 100644 --- a/mobile/openapi/lib/model/sync_memory_asset_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_memory_asset_delete_v1.dart @@ -17,8 +17,10 @@ class SyncMemoryAssetDeleteV1 { required this.memoryId, }); + /// Asset ID String assetId; + /// Memory ID String memoryId; @override diff --git a/mobile/openapi/lib/model/sync_memory_asset_v1.dart b/mobile/openapi/lib/model/sync_memory_asset_v1.dart index d26e3c9a29237..2cfab98afd74c 100644 --- a/mobile/openapi/lib/model/sync_memory_asset_v1.dart +++ b/mobile/openapi/lib/model/sync_memory_asset_v1.dart @@ -17,8 +17,10 @@ class SyncMemoryAssetV1 { required this.memoryId, }); + /// Asset ID String assetId; + /// Memory ID String memoryId; @override diff --git a/mobile/openapi/lib/model/sync_memory_delete_v1.dart b/mobile/openapi/lib/model/sync_memory_delete_v1.dart index 9702da5aafccd..d5f63ec8fa255 100644 --- a/mobile/openapi/lib/model/sync_memory_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_memory_delete_v1.dart @@ -16,6 +16,7 @@ class SyncMemoryDeleteV1 { required this.memoryId, }); + /// Memory ID String memoryId; @override diff --git a/mobile/openapi/lib/model/sync_memory_v1.dart b/mobile/openapi/lib/model/sync_memory_v1.dart index 2ae2b01fd7403..c506738d97ceb 100644 --- a/mobile/openapi/lib/model/sync_memory_v1.dart +++ b/mobile/openapi/lib/model/sync_memory_v1.dart @@ -27,28 +27,40 @@ class SyncMemoryV1 { required this.updatedAt, }); + /// Created at DateTime createdAt; + /// Data Object data; + /// Deleted at DateTime? deletedAt; + /// Hide at DateTime? hideAt; + /// Memory ID String id; + /// Is saved bool isSaved; + /// Memory at DateTime memoryAt; + /// Owner ID String ownerId; + /// Seen at DateTime? seenAt; + /// Show at DateTime? showAt; + /// Memory type MemoryType type; + /// Updated at DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/sync_partner_delete_v1.dart b/mobile/openapi/lib/model/sync_partner_delete_v1.dart index f5e10d6576f69..64dfb4eb98761 100644 --- a/mobile/openapi/lib/model/sync_partner_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_partner_delete_v1.dart @@ -17,8 +17,10 @@ class SyncPartnerDeleteV1 { required this.sharedWithId, }); + /// Shared by ID String sharedById; + /// Shared with ID String sharedWithId; @override diff --git a/mobile/openapi/lib/model/sync_partner_v1.dart b/mobile/openapi/lib/model/sync_partner_v1.dart index e551c4c83d798..9f9c3d14c1c27 100644 --- a/mobile/openapi/lib/model/sync_partner_v1.dart +++ b/mobile/openapi/lib/model/sync_partner_v1.dart @@ -18,10 +18,13 @@ class SyncPartnerV1 { required this.sharedWithId, }); + /// In timeline bool inTimeline; + /// Shared by ID String sharedById; + /// Shared with ID String sharedWithId; @override diff --git a/mobile/openapi/lib/model/sync_person_delete_v1.dart b/mobile/openapi/lib/model/sync_person_delete_v1.dart index 002f5c5b83b2c..526bc26187b8e 100644 --- a/mobile/openapi/lib/model/sync_person_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_person_delete_v1.dart @@ -16,6 +16,7 @@ class SyncPersonDeleteV1 { required this.personId, }); + /// Person ID String personId; @override diff --git a/mobile/openapi/lib/model/sync_person_v1.dart b/mobile/openapi/lib/model/sync_person_v1.dart index 6749beb3e1070..fc2c36aa8c469 100644 --- a/mobile/openapi/lib/model/sync_person_v1.dart +++ b/mobile/openapi/lib/model/sync_person_v1.dart @@ -25,24 +25,34 @@ class SyncPersonV1 { required this.updatedAt, }); + /// Birth date DateTime? birthDate; + /// Color String? color; + /// Created at DateTime createdAt; + /// Face asset ID String? faceAssetId; + /// Person ID String id; + /// Is favorite bool isFavorite; + /// Is hidden bool isHidden; + /// Person name String name; + /// Owner ID String ownerId; + /// Updated at DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/sync_request_type.dart b/mobile/openapi/lib/model/sync_request_type.dart index c3dc1c4d6102b..135af3c7bbc1a 100644 --- a/mobile/openapi/lib/model/sync_request_type.dart +++ b/mobile/openapi/lib/model/sync_request_type.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Sync request types class SyncRequestType { /// Instantiate a new enum with the provided [value]. const SyncRequestType._(this.value); diff --git a/mobile/openapi/lib/model/sync_stack_delete_v1.dart b/mobile/openapi/lib/model/sync_stack_delete_v1.dart index 22c6d99a523af..2a7398291a69c 100644 --- a/mobile/openapi/lib/model/sync_stack_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_stack_delete_v1.dart @@ -16,6 +16,7 @@ class SyncStackDeleteV1 { required this.stackId, }); + /// Stack ID String stackId; @override diff --git a/mobile/openapi/lib/model/sync_stack_v1.dart b/mobile/openapi/lib/model/sync_stack_v1.dart index c65affe8c0b8b..e4487ccfaf04d 100644 --- a/mobile/openapi/lib/model/sync_stack_v1.dart +++ b/mobile/openapi/lib/model/sync_stack_v1.dart @@ -20,14 +20,19 @@ class SyncStackV1 { required this.updatedAt, }); + /// Created at DateTime createdAt; + /// Stack ID String id; + /// Owner ID String ownerId; + /// Primary asset ID String primaryAssetId; + /// Updated at DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/sync_stream_dto.dart b/mobile/openapi/lib/model/sync_stream_dto.dart index 9884eef342a72..932477cb1537f 100644 --- a/mobile/openapi/lib/model/sync_stream_dto.dart +++ b/mobile/openapi/lib/model/sync_stream_dto.dart @@ -17,6 +17,7 @@ class SyncStreamDto { this.types = const [], }); + /// Reset sync state /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class SyncStreamDto { /// bool? reset; + /// Sync request types List types; @override diff --git a/mobile/openapi/lib/model/sync_user_delete_v1.dart b/mobile/openapi/lib/model/sync_user_delete_v1.dart index 09411cb79d7d1..bbbdc147dd0ff 100644 --- a/mobile/openapi/lib/model/sync_user_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_user_delete_v1.dart @@ -16,6 +16,7 @@ class SyncUserDeleteV1 { required this.userId, }); + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/sync_user_metadata_delete_v1.dart b/mobile/openapi/lib/model/sync_user_metadata_delete_v1.dart index f39acc617b3b2..61340a8f82ed0 100644 --- a/mobile/openapi/lib/model/sync_user_metadata_delete_v1.dart +++ b/mobile/openapi/lib/model/sync_user_metadata_delete_v1.dart @@ -17,8 +17,10 @@ class SyncUserMetadataDeleteV1 { required this.userId, }); + /// User metadata key UserMetadataKey key; + /// User ID String userId; @override diff --git a/mobile/openapi/lib/model/sync_user_metadata_v1.dart b/mobile/openapi/lib/model/sync_user_metadata_v1.dart index cf39b6d960c97..23803d0be4b9a 100644 --- a/mobile/openapi/lib/model/sync_user_metadata_v1.dart +++ b/mobile/openapi/lib/model/sync_user_metadata_v1.dart @@ -18,10 +18,13 @@ class SyncUserMetadataV1 { required this.value, }); + /// User metadata key UserMetadataKey key; + /// User ID String userId; + /// User metadata value Object value; @override diff --git a/mobile/openapi/lib/model/sync_user_v1.dart b/mobile/openapi/lib/model/sync_user_v1.dart index b9fad5ae8c5fe..6d425130a3127 100644 --- a/mobile/openapi/lib/model/sync_user_v1.dart +++ b/mobile/openapi/lib/model/sync_user_v1.dart @@ -22,18 +22,25 @@ class SyncUserV1 { required this.profileChangedAt, }); + /// User avatar color UserAvatarColor? avatarColor; + /// User deleted at DateTime? deletedAt; + /// User email String email; + /// User has profile image bool hasProfileImage; + /// User ID String id; + /// User name String name; + /// User profile changed at DateTime profileChangedAt; @override diff --git a/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart b/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart index 0acfc9e8fbf9d..6c7acbd2189eb 100644 --- a/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart +++ b/mobile/openapi/lib/model/system_config_f_fmpeg_dto.dart @@ -36,54 +36,80 @@ class SystemConfigFFmpegDto { required this.twoPass, }); + /// Transcode hardware acceleration TranscodeHWAccel accel; + /// Accelerated decode bool accelDecode; + /// Accepted audio codecs List acceptedAudioCodecs; + /// Accepted containers List acceptedContainers; + /// Accepted video codecs List acceptedVideoCodecs; + /// B-frames + /// /// Minimum value: -1 /// Maximum value: 16 int bframes; + /// CQ mode CQMode cqMode; + /// CRF + /// /// Minimum value: 0 /// Maximum value: 51 int crf; + /// GOP size + /// /// Minimum value: 0 int gopSize; + /// Max bitrate String maxBitrate; + /// Preferred hardware device String preferredHwDevice; + /// Preset String preset; + /// References + /// /// Minimum value: 0 /// Maximum value: 6 int refs; + /// Target audio codec AudioCodec targetAudioCodec; + /// Target resolution String targetResolution; + /// Target video codec VideoCodec targetVideoCodec; + /// Temporal AQ bool temporalAQ; + /// Threads + /// /// Minimum value: 0 int threads; + /// Tone mapping ToneMapping tonemap; + /// Transcode policy TranscodePolicy transcode; + /// Two pass bool twoPass; @override diff --git a/mobile/openapi/lib/model/system_config_faces_dto.dart b/mobile/openapi/lib/model/system_config_faces_dto.dart index 4e18eb8de20e4..f57303c310238 100644 --- a/mobile/openapi/lib/model/system_config_faces_dto.dart +++ b/mobile/openapi/lib/model/system_config_faces_dto.dart @@ -16,6 +16,7 @@ class SystemConfigFacesDto { required this.import_, }); + /// Import bool import_; @override diff --git a/mobile/openapi/lib/model/system_config_generated_fullsize_image_dto.dart b/mobile/openapi/lib/model/system_config_generated_fullsize_image_dto.dart index e7111771bdec9..b5640f82c8d83 100644 --- a/mobile/openapi/lib/model/system_config_generated_fullsize_image_dto.dart +++ b/mobile/openapi/lib/model/system_config_generated_fullsize_image_dto.dart @@ -19,12 +19,17 @@ class SystemConfigGeneratedFullsizeImageDto { required this.quality, }); + /// Enabled bool enabled; + /// Image format ImageFormat format; + /// Progressive bool progressive; + /// Quality + /// /// Minimum value: 1 /// Maximum value: 100 int quality; diff --git a/mobile/openapi/lib/model/system_config_generated_image_dto.dart b/mobile/openapi/lib/model/system_config_generated_image_dto.dart index a46fc13d275e7..3e8fed2c6859c 100644 --- a/mobile/openapi/lib/model/system_config_generated_image_dto.dart +++ b/mobile/openapi/lib/model/system_config_generated_image_dto.dart @@ -19,14 +19,19 @@ class SystemConfigGeneratedImageDto { required this.size, }); + /// Image format ImageFormat format; bool progressive; + /// Quality + /// /// Minimum value: 1 /// Maximum value: 100 int quality; + /// Size + /// /// Minimum value: 1 int size; diff --git a/mobile/openapi/lib/model/system_config_image_dto.dart b/mobile/openapi/lib/model/system_config_image_dto.dart index 783eaa7d46060..217a666a675eb 100644 --- a/mobile/openapi/lib/model/system_config_image_dto.dart +++ b/mobile/openapi/lib/model/system_config_image_dto.dart @@ -20,8 +20,10 @@ class SystemConfigImageDto { required this.thumbnail, }); + /// Colorspace Colorspace colorspace; + /// Extract embedded bool extractEmbedded; SystemConfigGeneratedFullsizeImageDto fullsize; diff --git a/mobile/openapi/lib/model/system_config_library_scan_dto.dart b/mobile/openapi/lib/model/system_config_library_scan_dto.dart index 6a6558b4b32ee..28ea603c2a0cf 100644 --- a/mobile/openapi/lib/model/system_config_library_scan_dto.dart +++ b/mobile/openapi/lib/model/system_config_library_scan_dto.dart @@ -19,6 +19,7 @@ class SystemConfigLibraryScanDto { String cronExpression; + /// Enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/system_config_library_watch_dto.dart b/mobile/openapi/lib/model/system_config_library_watch_dto.dart index 1a1f5d7126b34..b4f171bd25b78 100644 --- a/mobile/openapi/lib/model/system_config_library_watch_dto.dart +++ b/mobile/openapi/lib/model/system_config_library_watch_dto.dart @@ -16,6 +16,7 @@ class SystemConfigLibraryWatchDto { required this.enabled, }); + /// Enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/system_config_logging_dto.dart b/mobile/openapi/lib/model/system_config_logging_dto.dart index f025221eff996..54278893db0c1 100644 --- a/mobile/openapi/lib/model/system_config_logging_dto.dart +++ b/mobile/openapi/lib/model/system_config_logging_dto.dart @@ -17,6 +17,7 @@ class SystemConfigLoggingDto { required this.level, }); + /// Enabled bool enabled; LogLevel level; diff --git a/mobile/openapi/lib/model/system_config_machine_learning_dto.dart b/mobile/openapi/lib/model/system_config_machine_learning_dto.dart index da689936f861a..2a0f1ffbc61db 100644 --- a/mobile/openapi/lib/model/system_config_machine_learning_dto.dart +++ b/mobile/openapi/lib/model/system_config_machine_learning_dto.dart @@ -28,6 +28,7 @@ class SystemConfigMachineLearningDto { DuplicateDetectionConfig duplicateDetection; + /// Enabled bool enabled; FacialRecognitionConfig facialRecognition; diff --git a/mobile/openapi/lib/model/system_config_map_dto.dart b/mobile/openapi/lib/model/system_config_map_dto.dart index d53d5711db2af..109babd37463e 100644 --- a/mobile/openapi/lib/model/system_config_map_dto.dart +++ b/mobile/openapi/lib/model/system_config_map_dto.dart @@ -20,6 +20,7 @@ class SystemConfigMapDto { String darkStyle; + /// Enabled bool enabled; String lightStyle; diff --git a/mobile/openapi/lib/model/system_config_new_version_check_dto.dart b/mobile/openapi/lib/model/system_config_new_version_check_dto.dart index c63d2abc1ba30..ec2b400dfdee5 100644 --- a/mobile/openapi/lib/model/system_config_new_version_check_dto.dart +++ b/mobile/openapi/lib/model/system_config_new_version_check_dto.dart @@ -16,6 +16,7 @@ class SystemConfigNewVersionCheckDto { required this.enabled, }); + /// Enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/system_config_nightly_tasks_dto.dart b/mobile/openapi/lib/model/system_config_nightly_tasks_dto.dart index ab7b4b37c2e9b..cfb18b181e83a 100644 --- a/mobile/openapi/lib/model/system_config_nightly_tasks_dto.dart +++ b/mobile/openapi/lib/model/system_config_nightly_tasks_dto.dart @@ -21,16 +21,21 @@ class SystemConfigNightlyTasksDto { required this.syncQuotaUsage, }); + /// Cluster new faces bool clusterNewFaces; + /// Database cleanup bool databaseCleanup; + /// Generate memories bool generateMemories; + /// Missing thumbnails bool missingThumbnails; String startTime; + /// Sync quota usage bool syncQuotaUsage; @override diff --git a/mobile/openapi/lib/model/system_config_o_auth_dto.dart b/mobile/openapi/lib/model/system_config_o_auth_dto.dart index c8f91be1f1690..82195e498beab 100644 --- a/mobile/openapi/lib/model/system_config_o_auth_dto.dart +++ b/mobile/openapi/lib/model/system_config_o_auth_dto.dart @@ -33,42 +33,61 @@ class SystemConfigOAuthDto { required this.tokenEndpointAuthMethod, }); + /// Auto launch bool autoLaunch; + /// Auto register bool autoRegister; + /// Button text String buttonText; + /// Client ID String clientId; + /// Client secret String clientSecret; + /// Default storage quota + /// /// Minimum value: 0 int? defaultStorageQuota; + /// Enabled bool enabled; + /// Issuer URL String issuerUrl; + /// Mobile override enabled bool mobileOverrideEnabled; + /// Mobile redirect URI String mobileRedirectUri; + /// Profile signing algorithm String profileSigningAlgorithm; + /// Role claim String roleClaim; + /// Scope String scope; String signingAlgorithm; + /// Storage label claim String storageLabelClaim; + /// Storage quota claim String storageQuotaClaim; + /// Timeout + /// /// Minimum value: 1 int timeout; + /// Token endpoint auth method OAuthTokenEndpointAuthMethod tokenEndpointAuthMethod; @override diff --git a/mobile/openapi/lib/model/system_config_password_login_dto.dart b/mobile/openapi/lib/model/system_config_password_login_dto.dart index 69c8942bb6471..1328a6acaa2ba 100644 --- a/mobile/openapi/lib/model/system_config_password_login_dto.dart +++ b/mobile/openapi/lib/model/system_config_password_login_dto.dart @@ -16,6 +16,7 @@ class SystemConfigPasswordLoginDto { required this.enabled, }); + /// Enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/system_config_reverse_geocoding_dto.dart b/mobile/openapi/lib/model/system_config_reverse_geocoding_dto.dart index 6c1673d46c07d..0374e19be1b62 100644 --- a/mobile/openapi/lib/model/system_config_reverse_geocoding_dto.dart +++ b/mobile/openapi/lib/model/system_config_reverse_geocoding_dto.dart @@ -16,6 +16,7 @@ class SystemConfigReverseGeocodingDto { required this.enabled, }); + /// Enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/system_config_server_dto.dart b/mobile/openapi/lib/model/system_config_server_dto.dart index 8099292dd052b..200f75f7c679c 100644 --- a/mobile/openapi/lib/model/system_config_server_dto.dart +++ b/mobile/openapi/lib/model/system_config_server_dto.dart @@ -18,10 +18,13 @@ class SystemConfigServerDto { required this.publicUsers, }); + /// External domain String externalDomain; + /// Login page message String loginPageMessage; + /// Public users bool publicUsers; @override diff --git a/mobile/openapi/lib/model/system_config_smtp_dto.dart b/mobile/openapi/lib/model/system_config_smtp_dto.dart index fcde49cf3564e..a3d14cda63bf0 100644 --- a/mobile/openapi/lib/model/system_config_smtp_dto.dart +++ b/mobile/openapi/lib/model/system_config_smtp_dto.dart @@ -19,10 +19,13 @@ class SystemConfigSmtpDto { required this.transport, }); + /// Whether SMTP email notifications are enabled bool enabled; + /// Email address to send from String from; + /// Email address for replies String replyTo; SystemConfigSmtpTransportDto transport; diff --git a/mobile/openapi/lib/model/system_config_smtp_transport_dto.dart b/mobile/openapi/lib/model/system_config_smtp_transport_dto.dart index 46307046b44e2..9e16e5badf8bb 100644 --- a/mobile/openapi/lib/model/system_config_smtp_transport_dto.dart +++ b/mobile/openapi/lib/model/system_config_smtp_transport_dto.dart @@ -21,18 +21,25 @@ class SystemConfigSmtpTransportDto { required this.username, }); + /// SMTP server hostname String host; + /// Whether to ignore SSL certificate errors bool ignoreCert; + /// SMTP password String password; + /// SMTP server port + /// /// Minimum value: 0 /// Maximum value: 65535 num port; + /// Whether to use secure connection (TLS/SSL) bool secure; + /// SMTP username String username; @override diff --git a/mobile/openapi/lib/model/system_config_storage_template_dto.dart b/mobile/openapi/lib/model/system_config_storage_template_dto.dart index 596aafc1950a1..f9f37e48add30 100644 --- a/mobile/openapi/lib/model/system_config_storage_template_dto.dart +++ b/mobile/openapi/lib/model/system_config_storage_template_dto.dart @@ -18,10 +18,13 @@ class SystemConfigStorageTemplateDto { required this.template, }); + /// Enabled bool enabled; + /// Hash verification enabled bool hashVerificationEnabled; + /// Template String template; @override diff --git a/mobile/openapi/lib/model/system_config_template_storage_option_dto.dart b/mobile/openapi/lib/model/system_config_template_storage_option_dto.dart index f8586d344c5aa..6f81513039ac4 100644 --- a/mobile/openapi/lib/model/system_config_template_storage_option_dto.dart +++ b/mobile/openapi/lib/model/system_config_template_storage_option_dto.dart @@ -23,20 +23,28 @@ class SystemConfigTemplateStorageOptionDto { this.yearOptions = const [], }); + /// Available day format options for storage template List dayOptions; + /// Available hour format options for storage template List hourOptions; + /// Available minute format options for storage template List minuteOptions; + /// Available month format options for storage template List monthOptions; + /// Available preset template options List presetOptions; + /// Available second format options for storage template List secondOptions; + /// Available week format options for storage template List weekOptions; + /// Available year format options for storage template List yearOptions; @override diff --git a/mobile/openapi/lib/model/system_config_theme_dto.dart b/mobile/openapi/lib/model/system_config_theme_dto.dart index a97c2cf84c1f3..fca38f71fb62a 100644 --- a/mobile/openapi/lib/model/system_config_theme_dto.dart +++ b/mobile/openapi/lib/model/system_config_theme_dto.dart @@ -16,6 +16,7 @@ class SystemConfigThemeDto { required this.customCss, }); + /// Custom CSS for theming String customCss; @override diff --git a/mobile/openapi/lib/model/system_config_trash_dto.dart b/mobile/openapi/lib/model/system_config_trash_dto.dart index 51b39e9a55c1f..9bdaef92d3511 100644 --- a/mobile/openapi/lib/model/system_config_trash_dto.dart +++ b/mobile/openapi/lib/model/system_config_trash_dto.dart @@ -17,9 +17,12 @@ class SystemConfigTrashDto { required this.enabled, }); + /// Days + /// /// Minimum value: 0 int days; + /// Enabled bool enabled; @override diff --git a/mobile/openapi/lib/model/system_config_user_dto.dart b/mobile/openapi/lib/model/system_config_user_dto.dart index 8e6bd3c9c306e..a7313560e61eb 100644 --- a/mobile/openapi/lib/model/system_config_user_dto.dart +++ b/mobile/openapi/lib/model/system_config_user_dto.dart @@ -16,6 +16,8 @@ class SystemConfigUserDto { required this.deleteDelay, }); + /// Delete delay + /// /// Minimum value: 1 int deleteDelay; diff --git a/mobile/openapi/lib/model/tag_bulk_assets_dto.dart b/mobile/openapi/lib/model/tag_bulk_assets_dto.dart index 26a575e193dc6..16abc3bcdc7ed 100644 --- a/mobile/openapi/lib/model/tag_bulk_assets_dto.dart +++ b/mobile/openapi/lib/model/tag_bulk_assets_dto.dart @@ -17,8 +17,10 @@ class TagBulkAssetsDto { this.tagIds = const [], }); + /// Asset IDs List assetIds; + /// Tag IDs List tagIds; @override diff --git a/mobile/openapi/lib/model/tag_bulk_assets_response_dto.dart b/mobile/openapi/lib/model/tag_bulk_assets_response_dto.dart index 009f26bfe4f49..5566846e3cf99 100644 --- a/mobile/openapi/lib/model/tag_bulk_assets_response_dto.dart +++ b/mobile/openapi/lib/model/tag_bulk_assets_response_dto.dart @@ -16,6 +16,7 @@ class TagBulkAssetsResponseDto { required this.count, }); + /// Number of assets tagged int count; @override diff --git a/mobile/openapi/lib/model/tag_create_dto.dart b/mobile/openapi/lib/model/tag_create_dto.dart index 9a5171074d622..fd6a10163cdaf 100644 --- a/mobile/openapi/lib/model/tag_create_dto.dart +++ b/mobile/openapi/lib/model/tag_create_dto.dart @@ -18,6 +18,7 @@ class TagCreateDto { this.parentId, }); + /// Tag color (hex) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -26,8 +27,10 @@ class TagCreateDto { /// String? color; + /// Tag name String name; + /// Parent tag ID String? parentId; @override diff --git a/mobile/openapi/lib/model/tag_response_dto.dart b/mobile/openapi/lib/model/tag_response_dto.dart index cd684b163a27d..9a71912153c9b 100644 --- a/mobile/openapi/lib/model/tag_response_dto.dart +++ b/mobile/openapi/lib/model/tag_response_dto.dart @@ -22,6 +22,7 @@ class TagResponseDto { required this.value, }); + /// Tag color (hex) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -30,12 +31,16 @@ class TagResponseDto { /// String? color; + /// Creation date DateTime createdAt; + /// Tag ID String id; + /// Tag name String name; + /// Parent tag ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -44,8 +49,10 @@ class TagResponseDto { /// String? parentId; + /// Last update date DateTime updatedAt; + /// Tag value (full path) String value; @override diff --git a/mobile/openapi/lib/model/tag_update_dto.dart b/mobile/openapi/lib/model/tag_update_dto.dart index ab1adb127bacb..98cb6af523d7d 100644 --- a/mobile/openapi/lib/model/tag_update_dto.dart +++ b/mobile/openapi/lib/model/tag_update_dto.dart @@ -16,6 +16,7 @@ class TagUpdateDto { this.color, }); + /// Tag color (hex) String? color; @override diff --git a/mobile/openapi/lib/model/tag_upsert_dto.dart b/mobile/openapi/lib/model/tag_upsert_dto.dart index d60a00f466e1f..3581ef1e8f9bf 100644 --- a/mobile/openapi/lib/model/tag_upsert_dto.dart +++ b/mobile/openapi/lib/model/tag_upsert_dto.dart @@ -16,6 +16,7 @@ class TagUpsertDto { this.tags = const [], }); + /// Tag names to upsert List tags; @override diff --git a/mobile/openapi/lib/model/tags_response.dart b/mobile/openapi/lib/model/tags_response.dart index 2470edf979239..1e4a4bd109b6f 100644 --- a/mobile/openapi/lib/model/tags_response.dart +++ b/mobile/openapi/lib/model/tags_response.dart @@ -17,8 +17,10 @@ class TagsResponse { this.sidebarWeb = true, }); + /// Whether tags are enabled bool enabled; + /// Whether tags appear in web sidebar bool sidebarWeb; @override diff --git a/mobile/openapi/lib/model/tags_update.dart b/mobile/openapi/lib/model/tags_update.dart index d99236914055c..e42357e3d44df 100644 --- a/mobile/openapi/lib/model/tags_update.dart +++ b/mobile/openapi/lib/model/tags_update.dart @@ -17,6 +17,7 @@ class TagsUpdate { this.sidebarWeb, }); + /// Whether tags are enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class TagsUpdate { /// bool? enabled; + /// Whether tags appear in web sidebar /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/template_dto.dart b/mobile/openapi/lib/model/template_dto.dart index f818e0508acab..b1eab848edfe4 100644 --- a/mobile/openapi/lib/model/template_dto.dart +++ b/mobile/openapi/lib/model/template_dto.dart @@ -16,6 +16,7 @@ class TemplateDto { required this.template, }); + /// Template name String template; @override diff --git a/mobile/openapi/lib/model/template_response_dto.dart b/mobile/openapi/lib/model/template_response_dto.dart index 3c3224a54beb0..f19c1eae7d516 100644 --- a/mobile/openapi/lib/model/template_response_dto.dart +++ b/mobile/openapi/lib/model/template_response_dto.dart @@ -17,8 +17,10 @@ class TemplateResponseDto { required this.name, }); + /// Template HTML content String html; + /// Template name String name; @override diff --git a/mobile/openapi/lib/model/test_email_response_dto.dart b/mobile/openapi/lib/model/test_email_response_dto.dart index 33e6c042d8d09..e14783f3c4edc 100644 --- a/mobile/openapi/lib/model/test_email_response_dto.dart +++ b/mobile/openapi/lib/model/test_email_response_dto.dart @@ -16,6 +16,7 @@ class TestEmailResponseDto { required this.messageId, }); + /// Email message ID String messageId; @override diff --git a/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart b/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart index 58032b7c51445..720323cd147d0 100644 --- a/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart +++ b/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart @@ -42,7 +42,7 @@ class TimeBucketAssetResponseDto { /// Array of video durations in HH:MM:SS format (null for images) List duration; - /// Array of file creation timestamps in UTC (ISO 8601 format, without timezone) + /// Array of file creation timestamps in UTC List fileCreatedAt; /// Array of asset IDs in the time bucket diff --git a/mobile/openapi/lib/model/tone_mapping.dart b/mobile/openapi/lib/model/tone_mapping.dart index e05aea2b77c40..a1db2f5c9ca75 100644 --- a/mobile/openapi/lib/model/tone_mapping.dart +++ b/mobile/openapi/lib/model/tone_mapping.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Tone mapping class ToneMapping { /// Instantiate a new enum with the provided [value]. const ToneMapping._(this.value); diff --git a/mobile/openapi/lib/model/transcode_hw_accel.dart b/mobile/openapi/lib/model/transcode_hw_accel.dart index de5006341ebc6..22d20de320f09 100644 --- a/mobile/openapi/lib/model/transcode_hw_accel.dart +++ b/mobile/openapi/lib/model/transcode_hw_accel.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Transcode hardware acceleration class TranscodeHWAccel { /// Instantiate a new enum with the provided [value]. const TranscodeHWAccel._(this.value); diff --git a/mobile/openapi/lib/model/transcode_policy.dart b/mobile/openapi/lib/model/transcode_policy.dart index 6e9617428a3cb..ab3a876a9387a 100644 --- a/mobile/openapi/lib/model/transcode_policy.dart +++ b/mobile/openapi/lib/model/transcode_policy.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Transcode policy class TranscodePolicy { /// Instantiate a new enum with the provided [value]. const TranscodePolicy._(this.value); diff --git a/mobile/openapi/lib/model/trash_response_dto.dart b/mobile/openapi/lib/model/trash_response_dto.dart index 2df154d06c1a0..7edd5d032af17 100644 --- a/mobile/openapi/lib/model/trash_response_dto.dart +++ b/mobile/openapi/lib/model/trash_response_dto.dart @@ -16,6 +16,7 @@ class TrashResponseDto { required this.count, }); + /// Number of items in trash int count; @override diff --git a/mobile/openapi/lib/model/update_album_dto.dart b/mobile/openapi/lib/model/update_album_dto.dart index 8353dba14e627..46ce8b0ecc714 100644 --- a/mobile/openapi/lib/model/update_album_dto.dart +++ b/mobile/openapi/lib/model/update_album_dto.dart @@ -20,6 +20,7 @@ class UpdateAlbumDto { this.order, }); + /// Album name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -28,6 +29,7 @@ class UpdateAlbumDto { /// String? albumName; + /// Album thumbnail asset ID /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -36,6 +38,7 @@ class UpdateAlbumDto { /// String? albumThumbnailAssetId; + /// Album description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -44,6 +47,7 @@ class UpdateAlbumDto { /// String? description; + /// Enable activity feed /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -52,6 +56,7 @@ class UpdateAlbumDto { /// bool? isActivityEnabled; + /// Asset sort order /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/update_album_user_dto.dart b/mobile/openapi/lib/model/update_album_user_dto.dart index 43218cae6e140..9d934eb465de2 100644 --- a/mobile/openapi/lib/model/update_album_user_dto.dart +++ b/mobile/openapi/lib/model/update_album_user_dto.dart @@ -16,6 +16,7 @@ class UpdateAlbumUserDto { required this.role, }); + /// Album user role AlbumUserRole role; @override diff --git a/mobile/openapi/lib/model/update_asset_dto.dart b/mobile/openapi/lib/model/update_asset_dto.dart index 7b364f13874af..42e8ec387f844 100644 --- a/mobile/openapi/lib/model/update_asset_dto.dart +++ b/mobile/openapi/lib/model/update_asset_dto.dart @@ -23,6 +23,7 @@ class UpdateAssetDto { this.visibility, }); + /// Original date and time /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -31,6 +32,7 @@ class UpdateAssetDto { /// String? dateTimeOriginal; + /// Asset description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -39,6 +41,7 @@ class UpdateAssetDto { /// String? description; + /// Mark as favorite /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -47,6 +50,7 @@ class UpdateAssetDto { /// bool? isFavorite; + /// Latitude coordinate /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -55,8 +59,10 @@ class UpdateAssetDto { /// num? latitude; + /// Live photo video ID String? livePhotoVideoId; + /// Longitude coordinate /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -65,6 +71,8 @@ class UpdateAssetDto { /// num? longitude; + /// Rating + /// /// Minimum value: -1 /// Maximum value: 5 /// @@ -75,6 +83,7 @@ class UpdateAssetDto { /// num? rating; + /// Asset visibility /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/update_library_dto.dart b/mobile/openapi/lib/model/update_library_dto.dart index 6a4f36906f74a..628bdc0055ebb 100644 --- a/mobile/openapi/lib/model/update_library_dto.dart +++ b/mobile/openapi/lib/model/update_library_dto.dart @@ -18,10 +18,13 @@ class UpdateLibraryDto { this.name, }); + /// Exclusion patterns (max 128) Set exclusionPatterns; + /// Import paths (max 128) Set importPaths; + /// Library name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/usage_by_user_dto.dart b/mobile/openapi/lib/model/usage_by_user_dto.dart index 80235915fea8e..da1fe600a5c8d 100644 --- a/mobile/openapi/lib/model/usage_by_user_dto.dart +++ b/mobile/openapi/lib/model/usage_by_user_dto.dart @@ -23,20 +23,28 @@ class UsageByUserDto { required this.videos, }); + /// Number of photos int photos; + /// User quota size in bytes (null if unlimited) int? quotaSizeInBytes; + /// Total storage usage in bytes int usage; + /// Storage usage for photos in bytes int usagePhotos; + /// Storage usage for videos in bytes int usageVideos; + /// User ID String userId; + /// User name String userName; + /// Number of videos int videos; @override diff --git a/mobile/openapi/lib/model/user_admin_create_dto.dart b/mobile/openapi/lib/model/user_admin_create_dto.dart index 8c8b70fbce0ff..320d3180625bc 100644 --- a/mobile/openapi/lib/model/user_admin_create_dto.dart +++ b/mobile/openapi/lib/model/user_admin_create_dto.dart @@ -24,10 +24,13 @@ class UserAdminCreateDto { this.storageLabel, }); + /// Avatar color UserAvatarColor? avatarColor; + /// User email String email; + /// Grant admin privileges /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -36,8 +39,10 @@ class UserAdminCreateDto { /// bool? isAdmin; + /// User name String name; + /// Send notification email /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -46,11 +51,15 @@ class UserAdminCreateDto { /// bool? notify; + /// User password String password; + /// Storage quota in bytes + /// /// Minimum value: 0 int? quotaSizeInBytes; + /// Require password change on next login /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -59,6 +68,7 @@ class UserAdminCreateDto { /// bool? shouldChangePassword; + /// Storage label String? storageLabel; @override diff --git a/mobile/openapi/lib/model/user_admin_delete_dto.dart b/mobile/openapi/lib/model/user_admin_delete_dto.dart index 2cf68ad7b25ee..6be70f37b7c98 100644 --- a/mobile/openapi/lib/model/user_admin_delete_dto.dart +++ b/mobile/openapi/lib/model/user_admin_delete_dto.dart @@ -16,6 +16,7 @@ class UserAdminDeleteDto { this.force, }); + /// Force delete even if user has assets /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/user_admin_response_dto.dart b/mobile/openapi/lib/model/user_admin_response_dto.dart index e5ae8e1d4ef27..706f65cf35a32 100644 --- a/mobile/openapi/lib/model/user_admin_response_dto.dart +++ b/mobile/openapi/lib/model/user_admin_response_dto.dart @@ -32,38 +32,55 @@ class UserAdminResponseDto { required this.updatedAt, }); + /// Avatar color UserAvatarColor avatarColor; + /// Creation date DateTime createdAt; + /// Deletion date DateTime? deletedAt; + /// User email String email; + /// User ID String id; + /// Is admin user bool isAdmin; + /// User license UserLicense? license; + /// User name String name; + /// OAuth ID String oauthId; + /// Profile change date DateTime profileChangedAt; + /// Profile image path String profileImagePath; + /// Storage quota in bytes int? quotaSizeInBytes; + /// Storage usage in bytes int? quotaUsageInBytes; + /// Require password change on next login bool shouldChangePassword; + /// User status UserStatus status; + /// Storage label String? storageLabel; + /// Last update date DateTime updatedAt; @override diff --git a/mobile/openapi/lib/model/user_admin_update_dto.dart b/mobile/openapi/lib/model/user_admin_update_dto.dart index 9605552d201e8..3cce65745f6af 100644 --- a/mobile/openapi/lib/model/user_admin_update_dto.dart +++ b/mobile/openapi/lib/model/user_admin_update_dto.dart @@ -24,8 +24,10 @@ class UserAdminUpdateDto { this.storageLabel, }); + /// Avatar color UserAvatarColor? avatarColor; + /// User email /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -34,6 +36,7 @@ class UserAdminUpdateDto { /// String? email; + /// Grant admin privileges /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -42,6 +45,7 @@ class UserAdminUpdateDto { /// bool? isAdmin; + /// User name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -50,6 +54,7 @@ class UserAdminUpdateDto { /// String? name; + /// User password /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -58,11 +63,15 @@ class UserAdminUpdateDto { /// String? password; + /// PIN code String? pinCode; + /// Storage quota in bytes + /// /// Minimum value: 0 int? quotaSizeInBytes; + /// Require password change on next login /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -71,6 +80,7 @@ class UserAdminUpdateDto { /// bool? shouldChangePassword; + /// Storage label String? storageLabel; @override diff --git a/mobile/openapi/lib/model/user_avatar_color.dart b/mobile/openapi/lib/model/user_avatar_color.dart index 4cd7dd320477a..4fcf518550a13 100644 --- a/mobile/openapi/lib/model/user_avatar_color.dart +++ b/mobile/openapi/lib/model/user_avatar_color.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Avatar color class UserAvatarColor { /// Instantiate a new enum with the provided [value]. const UserAvatarColor._(this.value); diff --git a/mobile/openapi/lib/model/user_license.dart b/mobile/openapi/lib/model/user_license.dart index 9bed8d5c43633..f02dc73befcfd 100644 --- a/mobile/openapi/lib/model/user_license.dart +++ b/mobile/openapi/lib/model/user_license.dart @@ -18,10 +18,13 @@ class UserLicense { required this.licenseKey, }); + /// Activation date DateTime activatedAt; + /// Activation key String activationKey; + /// License key String licenseKey; @override diff --git a/mobile/openapi/lib/model/user_metadata_key.dart b/mobile/openapi/lib/model/user_metadata_key.dart index 845b5ae9bb7dc..2b4c11a73d678 100644 --- a/mobile/openapi/lib/model/user_metadata_key.dart +++ b/mobile/openapi/lib/model/user_metadata_key.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// User metadata key class UserMetadataKey { /// Instantiate a new enum with the provided [value]. const UserMetadataKey._(this.value); diff --git a/mobile/openapi/lib/model/user_response_dto.dart b/mobile/openapi/lib/model/user_response_dto.dart index a02da299481b8..bf0e2cbf09cbc 100644 --- a/mobile/openapi/lib/model/user_response_dto.dart +++ b/mobile/openapi/lib/model/user_response_dto.dart @@ -21,16 +21,22 @@ class UserResponseDto { required this.profileImagePath, }); + /// Avatar color UserAvatarColor avatarColor; + /// User email String email; + /// User ID String id; + /// User name String name; + /// Profile change date DateTime profileChangedAt; + /// Profile image path String profileImagePath; @override diff --git a/mobile/openapi/lib/model/user_status.dart b/mobile/openapi/lib/model/user_status.dart index 596abf324e7f7..130bd650f219e 100644 --- a/mobile/openapi/lib/model/user_status.dart +++ b/mobile/openapi/lib/model/user_status.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// User status class UserStatus { /// Instantiate a new enum with the provided [value]. const UserStatus._(this.value); diff --git a/mobile/openapi/lib/model/user_update_me_dto.dart b/mobile/openapi/lib/model/user_update_me_dto.dart index 779e07ffa6f44..066c435eb304c 100644 --- a/mobile/openapi/lib/model/user_update_me_dto.dart +++ b/mobile/openapi/lib/model/user_update_me_dto.dart @@ -19,8 +19,10 @@ class UserUpdateMeDto { this.password, }); + /// Avatar color UserAvatarColor? avatarColor; + /// User email /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -29,6 +31,7 @@ class UserUpdateMeDto { /// String? email; + /// User name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -37,6 +40,7 @@ class UserUpdateMeDto { /// String? name; + /// User password (deprecated, use change password endpoint) /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/validate_access_token_response_dto.dart b/mobile/openapi/lib/model/validate_access_token_response_dto.dart index 5e36efcfedf5b..16b9d0f925b8f 100644 --- a/mobile/openapi/lib/model/validate_access_token_response_dto.dart +++ b/mobile/openapi/lib/model/validate_access_token_response_dto.dart @@ -16,6 +16,7 @@ class ValidateAccessTokenResponseDto { required this.authStatus, }); + /// Authentication status bool authStatus; @override diff --git a/mobile/openapi/lib/model/validate_library_dto.dart b/mobile/openapi/lib/model/validate_library_dto.dart index 79ddb9a540359..59c368078252a 100644 --- a/mobile/openapi/lib/model/validate_library_dto.dart +++ b/mobile/openapi/lib/model/validate_library_dto.dart @@ -17,8 +17,10 @@ class ValidateLibraryDto { this.importPaths = const {}, }); + /// Exclusion patterns (max 128) Set exclusionPatterns; + /// Import paths to validate (max 128) Set importPaths; @override diff --git a/mobile/openapi/lib/model/validate_library_import_path_response_dto.dart b/mobile/openapi/lib/model/validate_library_import_path_response_dto.dart index 11fbbd74c2aaa..78cc03dc94502 100644 --- a/mobile/openapi/lib/model/validate_library_import_path_response_dto.dart +++ b/mobile/openapi/lib/model/validate_library_import_path_response_dto.dart @@ -18,10 +18,13 @@ class ValidateLibraryImportPathResponseDto { this.message, }); + /// Import path String importPath; + /// Is valid bool isValid; + /// Validation message /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/mobile/openapi/lib/model/validate_library_response_dto.dart b/mobile/openapi/lib/model/validate_library_response_dto.dart index e0dc2a2d14233..37f6ad07d196b 100644 --- a/mobile/openapi/lib/model/validate_library_response_dto.dart +++ b/mobile/openapi/lib/model/validate_library_response_dto.dart @@ -16,6 +16,7 @@ class ValidateLibraryResponseDto { this.importPaths = const [], }); + /// Validation results for import paths List importPaths; @override diff --git a/mobile/openapi/lib/model/version_check_state_response_dto.dart b/mobile/openapi/lib/model/version_check_state_response_dto.dart index d3f9a6cd95936..71075a681c9b3 100644 --- a/mobile/openapi/lib/model/version_check_state_response_dto.dart +++ b/mobile/openapi/lib/model/version_check_state_response_dto.dart @@ -17,8 +17,10 @@ class VersionCheckStateResponseDto { required this.releaseVersion, }); + /// Last check timestamp String? checkedAt; + /// Release version String? releaseVersion; @override diff --git a/mobile/openapi/lib/model/video_codec.dart b/mobile/openapi/lib/model/video_codec.dart index 307b2087575b9..ba6441c8f7d79 100644 --- a/mobile/openapi/lib/model/video_codec.dart +++ b/mobile/openapi/lib/model/video_codec.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Target video codec class VideoCodec { /// Instantiate a new enum with the provided [value]. const VideoCodec._(this.value); diff --git a/mobile/openapi/lib/model/video_container.dart b/mobile/openapi/lib/model/video_container.dart index b8efc94adc1fb..b1a47c8721902 100644 --- a/mobile/openapi/lib/model/video_container.dart +++ b/mobile/openapi/lib/model/video_container.dart @@ -10,7 +10,7 @@ part of openapi.api; - +/// Accepted containers class VideoContainer { /// Instantiate a new enum with the provided [value]. const VideoContainer._(this.value); diff --git a/mobile/openapi/lib/model/workflow_action_item_dto.dart b/mobile/openapi/lib/model/workflow_action_item_dto.dart index cb0c39eae965d..9222dd6ba7c87 100644 --- a/mobile/openapi/lib/model/workflow_action_item_dto.dart +++ b/mobile/openapi/lib/model/workflow_action_item_dto.dart @@ -17,6 +17,7 @@ class WorkflowActionItemDto { required this.pluginActionId, }); + /// Action configuration /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class WorkflowActionItemDto { /// Object? actionConfig; + /// Plugin action ID String pluginActionId; @override diff --git a/mobile/openapi/lib/model/workflow_action_response_dto.dart b/mobile/openapi/lib/model/workflow_action_response_dto.dart index 5132623e896de..8f77e9cf2b05a 100644 --- a/mobile/openapi/lib/model/workflow_action_response_dto.dart +++ b/mobile/openapi/lib/model/workflow_action_response_dto.dart @@ -20,14 +20,19 @@ class WorkflowActionResponseDto { required this.workflowId, }); + /// Action configuration Object? actionConfig; + /// Action ID String id; + /// Action order num order; + /// Plugin action ID String pluginActionId; + /// Workflow ID String workflowId; @override diff --git a/mobile/openapi/lib/model/workflow_create_dto.dart b/mobile/openapi/lib/model/workflow_create_dto.dart index c6e44743acbe6..38665a19128d0 100644 --- a/mobile/openapi/lib/model/workflow_create_dto.dart +++ b/mobile/openapi/lib/model/workflow_create_dto.dart @@ -21,8 +21,10 @@ class WorkflowCreateDto { required this.triggerType, }); + /// Workflow actions List actions; + /// Workflow description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -31,6 +33,7 @@ class WorkflowCreateDto { /// String? description; + /// Workflow enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -39,10 +42,13 @@ class WorkflowCreateDto { /// bool? enabled; + /// Workflow filters List filters; + /// Workflow name String name; + /// Workflow trigger type PluginTriggerType triggerType; @override diff --git a/mobile/openapi/lib/model/workflow_filter_item_dto.dart b/mobile/openapi/lib/model/workflow_filter_item_dto.dart index bd8090b05efad..52e29c3e93ab1 100644 --- a/mobile/openapi/lib/model/workflow_filter_item_dto.dart +++ b/mobile/openapi/lib/model/workflow_filter_item_dto.dart @@ -17,6 +17,7 @@ class WorkflowFilterItemDto { required this.pluginFilterId, }); + /// Filter configuration /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -25,6 +26,7 @@ class WorkflowFilterItemDto { /// Object? filterConfig; + /// Plugin filter ID String pluginFilterId; @override diff --git a/mobile/openapi/lib/model/workflow_filter_response_dto.dart b/mobile/openapi/lib/model/workflow_filter_response_dto.dart index 94dce27a3f0b7..355378adacb97 100644 --- a/mobile/openapi/lib/model/workflow_filter_response_dto.dart +++ b/mobile/openapi/lib/model/workflow_filter_response_dto.dart @@ -20,14 +20,19 @@ class WorkflowFilterResponseDto { required this.workflowId, }); + /// Filter configuration Object? filterConfig; + /// Filter ID String id; + /// Filter order num order; + /// Plugin filter ID String pluginFilterId; + /// Workflow ID String workflowId; @override diff --git a/mobile/openapi/lib/model/workflow_response_dto.dart b/mobile/openapi/lib/model/workflow_response_dto.dart index 1ad36f300b587..ae3e6510aae3d 100644 --- a/mobile/openapi/lib/model/workflow_response_dto.dart +++ b/mobile/openapi/lib/model/workflow_response_dto.dart @@ -24,22 +24,31 @@ class WorkflowResponseDto { required this.triggerType, }); + /// Workflow actions List actions; + /// Creation date String createdAt; + /// Workflow description String description; + /// Workflow enabled bool enabled; + /// Workflow filters List filters; + /// Workflow ID String id; + /// Workflow name String? name; + /// Owner user ID String ownerId; + /// Workflow trigger type PluginTriggerType triggerType; @override diff --git a/mobile/openapi/lib/model/workflow_update_dto.dart b/mobile/openapi/lib/model/workflow_update_dto.dart index 135c032b772b2..9891fff079374 100644 --- a/mobile/openapi/lib/model/workflow_update_dto.dart +++ b/mobile/openapi/lib/model/workflow_update_dto.dart @@ -21,8 +21,10 @@ class WorkflowUpdateDto { this.triggerType, }); + /// Workflow actions List actions; + /// Workflow description /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -31,6 +33,7 @@ class WorkflowUpdateDto { /// String? description; + /// Workflow enabled /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -39,8 +42,10 @@ class WorkflowUpdateDto { /// bool? enabled; + /// Workflow filters List filters; + /// Workflow name /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -49,6 +54,7 @@ class WorkflowUpdateDto { /// String? name; + /// Workflow trigger type /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 193c966c7be59..b75c7ce867441 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -10,6 +10,7 @@ "name": "albumId", "required": true, "in": "query", + "description": "Album ID", "schema": { "format": "uuid", "type": "string" @@ -19,6 +20,7 @@ "name": "assetId", "required": false, "in": "query", + "description": "Asset ID (if activity is for an asset)", "schema": { "format": "uuid", "type": "string" @@ -28,6 +30,7 @@ "name": "level", "required": false, "in": "query", + "description": "Filter by activity level", "schema": { "$ref": "#/components/schemas/ReactionLevel" } @@ -36,6 +39,7 @@ "name": "type", "required": false, "in": "query", + "description": "Filter by activity type", "schema": { "$ref": "#/components/schemas/ReactionType" } @@ -44,6 +48,7 @@ "name": "userId", "required": false, "in": "query", + "description": "Filter by user ID", "schema": { "format": "uuid", "type": "string" @@ -165,6 +170,7 @@ "name": "albumId", "required": true, "in": "query", + "description": "Album ID", "schema": { "format": "uuid", "type": "string" @@ -174,6 +180,7 @@ "name": "assetId", "required": false, "in": "query", + "description": "Asset ID (if activity is for an asset)", "schema": { "format": "uuid", "type": "string" @@ -926,6 +933,7 @@ "name": "id", "required": false, "in": "query", + "description": "User ID filter", "schema": { "format": "uuid", "type": "string" @@ -935,6 +943,7 @@ "name": "withDeleted", "required": false, "in": "query", + "description": "Include deleted users", "schema": { "type": "boolean" } @@ -1520,6 +1529,7 @@ "name": "isFavorite", "required": false, "in": "query", + "description": "Filter by favorite status", "schema": { "type": "boolean" } @@ -1528,6 +1538,7 @@ "name": "isTrashed", "required": false, "in": "query", + "description": "Filter by trash status", "schema": { "type": "boolean" } @@ -1536,6 +1547,7 @@ "name": "visibility", "required": false, "in": "query", + "description": "Filter by visibility", "schema": { "$ref": "#/components/schemas/AssetVisibility" } @@ -1596,7 +1608,7 @@ "name": "assetId", "required": false, "in": "query", - "description": "Only returns albums that contain the asset\nIgnores the shared parameter\nundefined: get all albums", + "description": "Filter albums containing this asset ID (ignores shared parameter)", "schema": { "format": "uuid", "type": "string" @@ -1606,6 +1618,7 @@ "name": "shared", "required": false, "in": "query", + "description": "Filter by shared status: true = only shared, false = only own, undefined = all", "schema": { "type": "boolean" } @@ -1929,6 +1942,7 @@ "name": "withoutAssets", "required": false, "in": "query", + "description": "Exclude assets from response", "schema": { "type": "boolean" } @@ -3068,6 +3082,7 @@ "name": "deviceId", "required": true, "in": "path", + "description": "Device ID", "schema": { "type": "string" } @@ -3346,6 +3361,7 @@ "name": "count", "required": false, "in": "query", + "description": "Number of random assets to return", "schema": { "minimum": 1, "type": "number" @@ -3407,6 +3423,7 @@ "name": "isFavorite", "required": false, "in": "query", + "description": "Filter by favorite status", "schema": { "type": "boolean" } @@ -3415,6 +3432,7 @@ "name": "isTrashed", "required": false, "in": "query", + "description": "Filter by trash status", "schema": { "type": "boolean" } @@ -3423,6 +3441,7 @@ "name": "visibility", "required": false, "in": "query", + "description": "Filter by visibility", "schema": { "$ref": "#/components/schemas/AssetVisibility" } @@ -3927,6 +3946,7 @@ "name": "id", "required": true, "in": "path", + "description": "Asset ID", "schema": { "format": "uuid", "type": "string" @@ -3936,6 +3956,7 @@ "name": "key", "required": true, "in": "path", + "description": "Metadata key", "schema": { "type": "string" } @@ -3986,6 +4007,7 @@ "name": "id", "required": true, "in": "path", + "description": "Asset ID", "schema": { "format": "uuid", "type": "string" @@ -3995,6 +4017,7 @@ "name": "key", "required": true, "in": "path", + "description": "Metadata key", "schema": { "type": "string" } @@ -4117,6 +4140,7 @@ "name": "edited", "required": false, "in": "query", + "description": "Return edited asset if available", "schema": { "default": false, "type": "boolean" @@ -4286,6 +4310,7 @@ "name": "edited", "required": false, "in": "query", + "description": "Return edited asset if available", "schema": { "default": false, "type": "boolean" @@ -4312,6 +4337,7 @@ "name": "size", "required": false, "in": "query", + "description": "Asset media size", "schema": { "$ref": "#/components/schemas/AssetMediaSize" } @@ -5306,6 +5332,7 @@ "name": "id", "required": true, "in": "query", + "description": "Face ID", "schema": { "format": "uuid", "type": "string" @@ -5661,6 +5688,7 @@ "name": "name", "required": true, "in": "path", + "description": "Queue name", "schema": { "$ref": "#/components/schemas/QueueName" } @@ -6216,6 +6244,7 @@ "name": "fileCreatedAfter", "required": false, "in": "query", + "description": "Filter assets created after this date", "schema": { "format": "date-time", "type": "string" @@ -6225,6 +6254,7 @@ "name": "fileCreatedBefore", "required": false, "in": "query", + "description": "Filter assets created before this date", "schema": { "format": "date-time", "type": "string" @@ -6234,6 +6264,7 @@ "name": "isArchived", "required": false, "in": "query", + "description": "Filter by archived status", "schema": { "type": "boolean" } @@ -6242,6 +6273,7 @@ "name": "isFavorite", "required": false, "in": "query", + "description": "Filter by favorite status", "schema": { "type": "boolean" } @@ -6250,6 +6282,7 @@ "name": "withPartners", "required": false, "in": "query", + "description": "Include partner assets", "schema": { "type": "boolean" } @@ -6258,6 +6291,7 @@ "name": "withSharedAlbums", "required": false, "in": "query", + "description": "Include shared album assets", "schema": { "type": "boolean" } @@ -6320,6 +6354,7 @@ "name": "lat", "required": true, "in": "query", + "description": "Latitude (-90 to 90)", "schema": { "format": "double", "type": "number" @@ -6329,6 +6364,7 @@ "name": "lon", "required": true, "in": "query", + "description": "Longitude (-180 to 180)", "schema": { "format": "double", "type": "number" @@ -6392,6 +6428,7 @@ "name": "for", "required": false, "in": "query", + "description": "Filter by date", "schema": { "format": "date-time", "type": "string" @@ -6401,6 +6438,7 @@ "name": "isSaved", "required": false, "in": "query", + "description": "Filter by saved status", "schema": { "type": "boolean" } @@ -6409,6 +6447,7 @@ "name": "isTrashed", "required": false, "in": "query", + "description": "Include trashed memories", "schema": { "type": "boolean" } @@ -6417,6 +6456,7 @@ "name": "order", "required": false, "in": "query", + "description": "Sort order", "schema": { "$ref": "#/components/schemas/MemorySearchOrder" } @@ -6435,6 +6475,7 @@ "name": "type", "required": false, "in": "query", + "description": "Memory type", "schema": { "$ref": "#/components/schemas/MemoryType" } @@ -6555,6 +6596,7 @@ "name": "for", "required": false, "in": "query", + "description": "Filter by date", "schema": { "format": "date-time", "type": "string" @@ -6564,6 +6606,7 @@ "name": "isSaved", "required": false, "in": "query", + "description": "Filter by saved status", "schema": { "type": "boolean" } @@ -6572,6 +6615,7 @@ "name": "isTrashed", "required": false, "in": "query", + "description": "Include trashed memories", "schema": { "type": "boolean" } @@ -6580,6 +6624,7 @@ "name": "order", "required": false, "in": "query", + "description": "Sort order", "schema": { "$ref": "#/components/schemas/MemorySearchOrder" } @@ -6598,6 +6643,7 @@ "name": "type", "required": false, "in": "query", + "description": "Memory type", "schema": { "$ref": "#/components/schemas/MemoryType" } @@ -7031,6 +7077,7 @@ "name": "id", "required": false, "in": "query", + "description": "Filter by notification ID", "schema": { "format": "uuid", "type": "string" @@ -7040,6 +7087,7 @@ "name": "level", "required": false, "in": "query", + "description": "Filter by notification level", "schema": { "$ref": "#/components/schemas/NotificationLevel" } @@ -7048,6 +7096,7 @@ "name": "type", "required": false, "in": "query", + "description": "Filter by notification type", "schema": { "$ref": "#/components/schemas/NotificationType" } @@ -7056,6 +7105,7 @@ "name": "unread", "required": false, "in": "query", + "description": "Filter by unread status", "schema": { "type": "boolean" } @@ -7583,6 +7633,7 @@ "name": "direction", "required": true, "in": "query", + "description": "Partner direction", "schema": { "$ref": "#/components/schemas/PartnerDirection" } @@ -7932,6 +7983,7 @@ "name": "closestAssetId", "required": false, "in": "query", + "description": "Closest asset ID for similarity search", "schema": { "format": "uuid", "type": "string" @@ -7941,6 +7993,7 @@ "name": "closestPersonId", "required": false, "in": "query", + "description": "Closest person ID for similarity search", "schema": { "format": "uuid", "type": "string" @@ -7973,6 +8026,7 @@ "name": "withHidden", "required": false, "in": "query", + "description": "Include hidden people", "schema": { "type": "boolean" } @@ -8801,6 +8855,7 @@ "name": "name", "required": true, "in": "path", + "description": "Queue name", "schema": { "$ref": "#/components/schemas/QueueName" } @@ -8855,6 +8910,7 @@ "name": "name", "required": true, "in": "path", + "description": "Queue name", "schema": { "$ref": "#/components/schemas/QueueName" } @@ -8921,6 +8977,7 @@ "name": "name", "required": true, "in": "path", + "description": "Queue name", "schema": { "$ref": "#/components/schemas/QueueName" } @@ -8978,6 +9035,7 @@ "name": "name", "required": true, "in": "path", + "description": "Queue name", "schema": { "$ref": "#/components/schemas/QueueName" } @@ -8986,6 +9044,7 @@ "name": "status", "required": false, "in": "query", + "description": "Filter jobs by status", "schema": { "type": "array", "items": { @@ -9154,6 +9213,7 @@ "name": "albumIds", "required": false, "in": "query", + "description": "Filter by album IDs", "schema": { "type": "array", "items": { @@ -9166,6 +9226,7 @@ "name": "city", "required": false, "in": "query", + "description": "Filter by city name", "schema": { "nullable": true, "type": "string" @@ -9175,6 +9236,7 @@ "name": "country", "required": false, "in": "query", + "description": "Filter by country name", "schema": { "nullable": true, "type": "string" @@ -9184,6 +9246,7 @@ "name": "createdAfter", "required": false, "in": "query", + "description": "Filter by creation date (after)", "schema": { "format": "date-time", "type": "string" @@ -9193,6 +9256,7 @@ "name": "createdBefore", "required": false, "in": "query", + "description": "Filter by creation date (before)", "schema": { "format": "date-time", "type": "string" @@ -9202,6 +9266,7 @@ "name": "deviceId", "required": false, "in": "query", + "description": "Device ID to filter by", "schema": { "type": "string" } @@ -9210,6 +9275,7 @@ "name": "isEncoded", "required": false, "in": "query", + "description": "Filter by encoded status", "schema": { "type": "boolean" } @@ -9218,6 +9284,7 @@ "name": "isFavorite", "required": false, "in": "query", + "description": "Filter by favorite status", "schema": { "type": "boolean" } @@ -9226,6 +9293,7 @@ "name": "isMotion", "required": false, "in": "query", + "description": "Filter by motion photo status", "schema": { "type": "boolean" } @@ -9234,6 +9302,7 @@ "name": "isNotInAlbum", "required": false, "in": "query", + "description": "Filter assets not in any album", "schema": { "type": "boolean" } @@ -9242,6 +9311,7 @@ "name": "isOffline", "required": false, "in": "query", + "description": "Filter by offline status", "schema": { "type": "boolean" } @@ -9250,6 +9320,7 @@ "name": "lensModel", "required": false, "in": "query", + "description": "Filter by lens model", "schema": { "nullable": true, "type": "string" @@ -9259,6 +9330,7 @@ "name": "libraryId", "required": false, "in": "query", + "description": "Library ID to filter by", "schema": { "format": "uuid", "nullable": true, @@ -9269,6 +9341,7 @@ "name": "make", "required": false, "in": "query", + "description": "Filter by camera make", "schema": { "type": "string" } @@ -9277,6 +9350,7 @@ "name": "minFileSize", "required": false, "in": "query", + "description": "Minimum file size in bytes", "schema": { "minimum": 0, "type": "integer" @@ -9286,6 +9360,7 @@ "name": "model", "required": false, "in": "query", + "description": "Filter by camera model", "schema": { "nullable": true, "type": "string" @@ -9295,6 +9370,7 @@ "name": "ocr", "required": false, "in": "query", + "description": "Filter by OCR text content", "schema": { "type": "string" } @@ -9303,6 +9379,7 @@ "name": "personIds", "required": false, "in": "query", + "description": "Filter by person IDs", "schema": { "type": "array", "items": { @@ -9315,6 +9392,7 @@ "name": "rating", "required": false, "in": "query", + "description": "Filter by rating", "schema": { "minimum": -1, "maximum": 5, @@ -9325,6 +9403,7 @@ "name": "size", "required": false, "in": "query", + "description": "Number of results to return", "schema": { "minimum": 1, "maximum": 1000, @@ -9335,6 +9414,7 @@ "name": "state", "required": false, "in": "query", + "description": "Filter by state/province name", "schema": { "nullable": true, "type": "string" @@ -9344,6 +9424,7 @@ "name": "tagIds", "required": false, "in": "query", + "description": "Filter by tag IDs", "schema": { "nullable": true, "type": "array", @@ -9357,6 +9438,7 @@ "name": "takenAfter", "required": false, "in": "query", + "description": "Filter by taken date (after)", "schema": { "format": "date-time", "type": "string" @@ -9366,6 +9448,7 @@ "name": "takenBefore", "required": false, "in": "query", + "description": "Filter by taken date (before)", "schema": { "format": "date-time", "type": "string" @@ -9375,6 +9458,7 @@ "name": "trashedAfter", "required": false, "in": "query", + "description": "Filter by trash date (after)", "schema": { "format": "date-time", "type": "string" @@ -9384,6 +9468,7 @@ "name": "trashedBefore", "required": false, "in": "query", + "description": "Filter by trash date (before)", "schema": { "format": "date-time", "type": "string" @@ -9393,6 +9478,7 @@ "name": "type", "required": false, "in": "query", + "description": "Asset type filter", "schema": { "$ref": "#/components/schemas/AssetTypeEnum" } @@ -9401,6 +9487,7 @@ "name": "updatedAfter", "required": false, "in": "query", + "description": "Filter by update date (after)", "schema": { "format": "date-time", "type": "string" @@ -9410,6 +9497,7 @@ "name": "updatedBefore", "required": false, "in": "query", + "description": "Filter by update date (before)", "schema": { "format": "date-time", "type": "string" @@ -9419,6 +9507,7 @@ "name": "visibility", "required": false, "in": "query", + "description": "Filter by visibility", "schema": { "$ref": "#/components/schemas/AssetVisibility" } @@ -9427,6 +9516,7 @@ "name": "withDeleted", "required": false, "in": "query", + "description": "Include deleted assets", "schema": { "type": "boolean" } @@ -9435,6 +9525,7 @@ "name": "withExif", "required": false, "in": "query", + "description": "Include EXIF data in response", "schema": { "type": "boolean" } @@ -9557,6 +9648,7 @@ "name": "name", "required": true, "in": "query", + "description": "Person name to search for", "schema": { "type": "string" } @@ -9565,6 +9657,7 @@ "name": "withHidden", "required": false, "in": "query", + "description": "Include hidden people", "schema": { "type": "boolean" } @@ -9627,6 +9720,7 @@ "name": "name", "required": true, "in": "query", + "description": "Place name to search for", "schema": { "type": "string" } @@ -9872,6 +9966,7 @@ "name": "country", "required": false, "in": "query", + "description": "Filter by country", "schema": { "type": "string" } @@ -9880,6 +9975,7 @@ "name": "includeNull", "required": false, "in": "query", + "description": "Include null values in suggestions", "x-immich-history": [ { "version": "v1.111.0", @@ -9899,6 +9995,7 @@ "name": "lensModel", "required": false, "in": "query", + "description": "Filter by lens model", "schema": { "type": "string" } @@ -9907,6 +10004,7 @@ "name": "make", "required": false, "in": "query", + "description": "Filter by camera make", "schema": { "type": "string" } @@ -9915,6 +10013,7 @@ "name": "model", "required": false, "in": "query", + "description": "Filter by camera model", "schema": { "type": "string" } @@ -9923,6 +10022,7 @@ "name": "state", "required": false, "in": "query", + "description": "Filter by state/province", "schema": { "type": "string" } @@ -9931,6 +10031,7 @@ "name": "type", "required": true, "in": "query", + "description": "Suggestion type", "schema": { "$ref": "#/components/schemas/SearchSuggestionType" } @@ -10994,6 +11095,7 @@ "name": "albumId", "required": false, "in": "query", + "description": "Filter by album ID", "schema": { "format": "uuid", "type": "string" @@ -11003,6 +11105,7 @@ "name": "id", "required": false, "in": "query", + "description": "Filter by shared link ID", "x-immich-history": [ { "version": "v2.5.0", @@ -11138,6 +11241,7 @@ "name": "password", "required": false, "in": "query", + "description": "Link password", "schema": { "example": "password", "type": "string" @@ -11155,6 +11259,7 @@ "name": "token", "required": false, "in": "query", + "description": "Access token", "schema": { "type": "string" } @@ -11617,6 +11722,7 @@ "name": "primaryAssetId", "required": false, "in": "query", + "description": "Filter by primary asset ID", "schema": { "format": "uuid", "type": "string" @@ -15132,9 +15238,11 @@ "APIKeyCreateDto": { "properties": { "name": { + "description": "API key name", "type": "string" }, "permissions": { + "description": "List of permissions", "items": { "$ref": "#/components/schemas/Permission" }, @@ -15153,6 +15261,7 @@ "$ref": "#/components/schemas/APIKeyResponseDto" }, "secret": { + "description": "API key secret (only shown once)", "type": "string" } }, @@ -15165,22 +15274,27 @@ "APIKeyResponseDto": { "properties": { "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "id": { + "description": "API key ID", "type": "string" }, "name": { + "description": "API key name", "type": "string" }, "permissions": { + "description": "List of permissions", "items": { "$ref": "#/components/schemas/Permission" }, "type": "array" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" } @@ -15197,9 +15311,11 @@ "APIKeyUpdateDto": { "properties": { "name": { + "description": "API key name", "type": "string" }, "permissions": { + "description": "List of permissions", "items": { "$ref": "#/components/schemas/Permission" }, @@ -15212,14 +15328,17 @@ "ActivityCreateDto": { "properties": { "albumId": { + "description": "Album ID", "format": "uuid", "type": "string" }, "assetId": { + "description": "Asset ID (if activity is for an asset)", "format": "uuid", "type": "string" }, "comment": { + "description": "Comment text (required if type is comment)", "type": "string" }, "type": { @@ -15227,7 +15346,8 @@ { "$ref": "#/components/schemas/ReactionType" } - ] + ], + "description": "Activity type (like or comment)" } }, "required": [ @@ -15239,18 +15359,22 @@ "ActivityResponseDto": { "properties": { "assetId": { + "description": "Asset ID (if activity is for an asset)", "nullable": true, "type": "string" }, "comment": { + "description": "Comment text (for comment activities)", "nullable": true, "type": "string" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "id": { + "description": "Activity ID", "type": "string" }, "type": { @@ -15258,7 +15382,8 @@ { "$ref": "#/components/schemas/ReactionType" } - ] + ], + "description": "Activity type" }, "user": { "$ref": "#/components/schemas/UserResponseDto" @@ -15276,9 +15401,11 @@ "ActivityStatisticsResponseDto": { "properties": { "comments": { + "description": "Number of comments", "type": "integer" }, "likes": { + "description": "Number of likes", "type": "integer" } }, @@ -15291,6 +15418,7 @@ "AddUsersDto": { "properties": { "albumUsers": { + "description": "Album users to add", "items": { "$ref": "#/components/schemas/AlbumUserAddDto" }, @@ -15306,6 +15434,7 @@ "AdminOnboardingUpdateDto": { "properties": { "isOnboarded": { + "description": "Is admin onboarded", "type": "boolean" } }, @@ -15317,9 +15446,11 @@ "AlbumResponseDto": { "properties": { "albumName": { + "description": "Album name", "type": "string" }, "albumThumbnailAssetId": { + "description": "Thumbnail asset ID", "nullable": true, "type": "string" }, @@ -15330,6 +15461,7 @@ "type": "array" }, "assetCount": { + "description": "Number of assets", "type": "integer" }, "assets": { @@ -15345,26 +15477,33 @@ "type": "array" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "description": { + "description": "Album description", "type": "string" }, "endDate": { + "description": "End date (latest asset)", "format": "date-time", "type": "string" }, "hasSharedLink": { + "description": "Has shared link", "type": "boolean" }, "id": { + "description": "Album ID", "type": "string" }, "isActivityEnabled": { + "description": "Activity feed enabled", "type": "boolean" }, "lastModifiedAssetTimestamp": { + "description": "Last modified asset timestamp", "format": "date-time", "type": "string" }, @@ -15373,22 +15512,27 @@ { "$ref": "#/components/schemas/AssetOrder" } - ] + ], + "description": "Asset sort order" }, "owner": { "$ref": "#/components/schemas/UserResponseDto" }, "ownerId": { + "description": "Owner user ID", "type": "string" }, "shared": { + "description": "Is shared album", "type": "boolean" }, "startDate": { + "description": "Start date (earliest asset)", "format": "date-time", "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" } @@ -15414,12 +15558,15 @@ "AlbumStatisticsResponseDto": { "properties": { "notShared": { + "description": "Number of non-shared albums", "type": "integer" }, "owned": { + "description": "Number of owned albums", "type": "integer" }, "shared": { + "description": "Number of shared albums", "type": "integer" } }, @@ -15438,9 +15585,11 @@ "$ref": "#/components/schemas/AlbumUserRole" } ], - "default": "editor" + "default": "editor", + "description": "Album user role" }, "userId": { + "description": "User ID", "format": "uuid", "type": "string" } @@ -15457,9 +15606,11 @@ { "$ref": "#/components/schemas/AlbumUserRole" } - ] + ], + "description": "Album user role" }, "userId": { + "description": "User ID", "format": "uuid", "type": "string" } @@ -15477,7 +15628,8 @@ { "$ref": "#/components/schemas/AlbumUserRole" } - ] + ], + "description": "Album user role" }, "user": { "$ref": "#/components/schemas/UserResponseDto" @@ -15490,6 +15642,7 @@ "type": "object" }, "AlbumUserRole": { + "description": "Album user role", "enum": [ "editor", "viewer" @@ -15499,6 +15652,7 @@ "AlbumsAddAssetsDto": { "properties": { "albumIds": { + "description": "Album IDs", "items": { "format": "uuid", "type": "string" @@ -15506,6 +15660,7 @@ "type": "array" }, "assetIds": { + "description": "Asset IDs", "items": { "format": "uuid", "type": "string" @@ -15526,9 +15681,11 @@ { "$ref": "#/components/schemas/BulkIdErrorReason" } - ] + ], + "description": "Error reason" }, "success": { + "description": "Operation success", "type": "boolean" } }, @@ -15545,7 +15702,8 @@ "$ref": "#/components/schemas/AssetOrder" } ], - "default": "desc" + "default": "desc", + "description": "Default asset order for albums" } }, "required": [ @@ -15554,13 +15712,15 @@ "type": "object" }, "AlbumsUpdate": { + "description": "Album preferences", "properties": { "defaultAssetOrder": { "allOf": [ { "$ref": "#/components/schemas/AssetOrder" } - ] + ], + "description": "Default asset order for albums" } }, "type": "object" @@ -15568,9 +15728,11 @@ "AssetBulkDeleteDto": { "properties": { "force": { + "description": "Force delete even if in use", "type": "boolean" }, "ids": { + "description": "IDs to process", "items": { "format": "uuid", "type": "string" @@ -15586,19 +15748,24 @@ "AssetBulkUpdateDto": { "properties": { "dateTimeOriginal": { + "description": "Original date and time", "type": "string" }, "dateTimeRelative": { + "description": "Relative time offset in seconds", "type": "number" }, "description": { + "description": "Asset description", "type": "string" }, "duplicateId": { + "description": "Duplicate asset ID", "nullable": true, "type": "string" }, "ids": { + "description": "Asset IDs to update", "items": { "format": "uuid", "type": "string" @@ -15606,20 +15773,25 @@ "type": "array" }, "isFavorite": { + "description": "Mark as favorite", "type": "boolean" }, "latitude": { + "description": "Latitude coordinate", "type": "number" }, "longitude": { + "description": "Longitude coordinate", "type": "number" }, "rating": { + "description": "Rating", "maximum": 5, "minimum": -1, "type": "number" }, "timeZone": { + "description": "Time zone (IANA timezone)", "type": "string" }, "visibility": { @@ -15627,7 +15799,8 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Asset visibility" } }, "required": [ @@ -15638,6 +15811,7 @@ "AssetBulkUploadCheckDto": { "properties": { "assets": { + "description": "Assets to check", "items": { "$ref": "#/components/schemas/AssetBulkUploadCheckItem" }, @@ -15652,10 +15826,11 @@ "AssetBulkUploadCheckItem": { "properties": { "checksum": { - "description": "base64 or hex encoded sha1 hash", + "description": "Base64 or hex encoded SHA1 hash", "type": "string" }, "id": { + "description": "Asset ID", "type": "string" } }, @@ -15668,6 +15843,7 @@ "AssetBulkUploadCheckResponseDto": { "properties": { "results": { + "description": "Upload check results", "items": { "$ref": "#/components/schemas/AssetBulkUploadCheckResult" }, @@ -15682,6 +15858,7 @@ "AssetBulkUploadCheckResult": { "properties": { "action": { + "description": "Upload action", "enum": [ "accept", "reject" @@ -15689,15 +15866,19 @@ "type": "string" }, "assetId": { + "description": "Existing asset ID if duplicate", "type": "string" }, "id": { + "description": "Asset ID", "type": "string" }, "isTrashed": { + "description": "Whether existing asset is trashed", "type": "boolean" }, "reason": { + "description": "Rejection reason if rejected", "enum": [ "duplicate", "unsupported-format" @@ -15715,29 +15896,36 @@ "properties": { "albums": { "default": true, + "description": "Copy album associations", "type": "boolean" }, "favorite": { "default": true, + "description": "Copy favorite status", "type": "boolean" }, "sharedLinks": { "default": true, + "description": "Copy shared links", "type": "boolean" }, "sidecar": { "default": true, + "description": "Copy sidecar file", "type": "boolean" }, "sourceId": { + "description": "Source asset ID", "format": "uuid", "type": "string" }, "stack": { "default": true, + "description": "Copy stack association", "type": "boolean" }, "targetId": { + "description": "Target asset ID", "format": "uuid", "type": "string" } @@ -15751,10 +15939,12 @@ "AssetDeltaSyncDto": { "properties": { "updatedAfter": { + "description": "Sync assets updated after this date", "format": "date-time", "type": "string" }, "userIds": { + "description": "User IDs to sync", "items": { "format": "uuid", "type": "string" @@ -15771,15 +15961,18 @@ "AssetDeltaSyncResponseDto": { "properties": { "deleted": { + "description": "Deleted asset IDs", "items": { "type": "string" }, "type": "array" }, "needsFullSync": { + "description": "Whether full sync is needed", "type": "boolean" }, "upserted": { + "description": "Upserted assets", "items": { "$ref": "#/components/schemas/AssetResponseDto" }, @@ -15794,6 +15987,7 @@ "type": "object" }, "AssetEditAction": { + "description": "Type of edit action to perform", "enum": [ "crop", "rotate", @@ -15808,7 +16002,8 @@ { "$ref": "#/components/schemas/AssetEditAction" } - ] + ], + "description": "Type of edit action to perform" }, "parameters": { "$ref": "#/components/schemas/CropParameters" @@ -15823,7 +16018,7 @@ "AssetEditActionListDto": { "properties": { "edits": { - "description": "list of edits", + "description": "List of edit actions to apply (crop, rotate, or mirror)", "items": { "anyOf": [ { @@ -15853,7 +16048,8 @@ { "$ref": "#/components/schemas/AssetEditAction" } - ] + ], + "description": "Type of edit action to perform" }, "parameters": { "$ref": "#/components/schemas/MirrorParameters" @@ -15872,7 +16068,8 @@ { "$ref": "#/components/schemas/AssetEditAction" } - ] + ], + "description": "Type of edit action to perform" }, "parameters": { "$ref": "#/components/schemas/RotateParameters" @@ -15887,11 +16084,12 @@ "AssetEditsDto": { "properties": { "assetId": { + "description": "Asset ID to apply edits to", "format": "uuid", "type": "string" }, "edits": { - "description": "list of edits", + "description": "List of edit actions to apply (crop, rotate, or mirror)", "items": { "anyOf": [ { @@ -15918,29 +16116,37 @@ "AssetFaceCreateDto": { "properties": { "assetId": { + "description": "Asset ID", "format": "uuid", "type": "string" }, "height": { + "description": "Face bounding box height", "type": "integer" }, "imageHeight": { + "description": "Image height in pixels", "type": "integer" }, "imageWidth": { + "description": "Image width in pixels", "type": "integer" }, "personId": { + "description": "Person ID", "format": "uuid", "type": "string" }, "width": { + "description": "Face bounding box width", "type": "integer" }, "x": { + "description": "Face bounding box X coordinate", "type": "integer" }, "y": { + "description": "Face bounding box Y coordinate", "type": "integer" } }, @@ -15959,6 +16165,7 @@ "AssetFaceDeleteDto": { "properties": { "force": { + "description": "Force delete even if person has other faces", "type": "boolean" } }, @@ -15970,25 +16177,32 @@ "AssetFaceResponseDto": { "properties": { "boundingBoxX1": { + "description": "Bounding box X1 coordinate", "type": "integer" }, "boundingBoxX2": { + "description": "Bounding box X2 coordinate", "type": "integer" }, "boundingBoxY1": { + "description": "Bounding box Y1 coordinate", "type": "integer" }, "boundingBoxY2": { + "description": "Bounding box Y2 coordinate", "type": "integer" }, "id": { + "description": "Face ID", "format": "uuid", "type": "string" }, "imageHeight": { + "description": "Image height in pixels", "type": "integer" }, "imageWidth": { + "description": "Image width in pixels", "type": "integer" }, "person": { @@ -15997,6 +16211,7 @@ "$ref": "#/components/schemas/PersonResponseDto" } ], + "description": "Person associated with face", "nullable": true }, "sourceType": { @@ -16004,7 +16219,8 @@ { "$ref": "#/components/schemas/SourceType" } - ] + ], + "description": "Face detection source type" } }, "required": [ @@ -16022,6 +16238,7 @@ "AssetFaceUpdateDto": { "properties": { "data": { + "description": "Face update items", "items": { "$ref": "#/components/schemas/AssetFaceUpdateItem" }, @@ -16036,10 +16253,12 @@ "AssetFaceUpdateItem": { "properties": { "assetId": { + "description": "Asset ID", "format": "uuid", "type": "string" }, "personId": { + "description": "Person ID", "format": "uuid", "type": "string" } @@ -16053,25 +16272,32 @@ "AssetFaceWithoutPersonResponseDto": { "properties": { "boundingBoxX1": { + "description": "Bounding box X1 coordinate", "type": "integer" }, "boundingBoxX2": { + "description": "Bounding box X2 coordinate", "type": "integer" }, "boundingBoxY1": { + "description": "Bounding box Y1 coordinate", "type": "integer" }, "boundingBoxY2": { + "description": "Bounding box Y2 coordinate", "type": "integer" }, "id": { + "description": "Face ID", "format": "uuid", "type": "string" }, "imageHeight": { + "description": "Image height in pixels", "type": "integer" }, "imageWidth": { + "description": "Image width in pixels", "type": "integer" }, "sourceType": { @@ -16079,7 +16305,8 @@ { "$ref": "#/components/schemas/SourceType" } - ] + ], + "description": "Face detection source type" } }, "required": [ @@ -16096,18 +16323,22 @@ "AssetFullSyncDto": { "properties": { "lastId": { + "description": "Last asset ID (pagination)", "format": "uuid", "type": "string" }, "limit": { + "description": "Maximum number of assets to return", "minimum": 1, "type": "integer" }, "updatedUntil": { + "description": "Sync assets updated until this date", "format": "date-time", "type": "string" }, "userId": { + "description": "Filter by user ID", "format": "uuid", "type": "string" } @@ -16121,6 +16352,7 @@ "AssetIdsDto": { "properties": { "assetIds": { + "description": "Asset IDs", "items": { "format": "uuid", "type": "string" @@ -16136,9 +16368,11 @@ "AssetIdsResponseDto": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "error": { + "description": "Error reason if failed", "enum": [ "duplicate", "no_permission", @@ -16147,6 +16381,7 @@ "type": "string" }, "success": { + "description": "Whether operation succeeded", "type": "boolean" } }, @@ -16157,6 +16392,7 @@ "type": "object" }, "AssetJobName": { + "description": "Job name", "enum": [ "refresh-faces", "refresh-metadata", @@ -16168,6 +16404,7 @@ "AssetJobsDto": { "properties": { "assetIds": { + "description": "Asset IDs", "items": { "format": "uuid", "type": "string" @@ -16179,7 +16416,8 @@ { "$ref": "#/components/schemas/AssetJobName" } - ] + ], + "description": "Job name" } }, "required": [ @@ -16191,43 +16429,54 @@ "AssetMediaCreateDto": { "properties": { "assetData": { + "description": "Asset file data", "format": "binary", "type": "string" }, "deviceAssetId": { + "description": "Device asset ID", "type": "string" }, "deviceId": { + "description": "Device ID", "type": "string" }, "duration": { + "description": "Duration (for videos)", "type": "string" }, "fileCreatedAt": { + "description": "File creation date", "format": "date-time", "type": "string" }, "fileModifiedAt": { + "description": "File modification date", "format": "date-time", "type": "string" }, "filename": { + "description": "Filename", "type": "string" }, "isFavorite": { + "description": "Mark as favorite", "type": "boolean" }, "livePhotoVideoId": { + "description": "Live photo video ID", "format": "uuid", "type": "string" }, "metadata": { + "description": "Asset metadata items", "items": { "$ref": "#/components/schemas/AssetMetadataUpsertItemDto" }, "type": "array" }, "sidecarData": { + "description": "Sidecar file data", "format": "binary", "type": "string" }, @@ -16236,7 +16485,8 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Asset visibility" } }, "required": [ @@ -16251,27 +16501,34 @@ "AssetMediaReplaceDto": { "properties": { "assetData": { + "description": "Asset file data", "format": "binary", "type": "string" }, "deviceAssetId": { + "description": "Device asset ID", "type": "string" }, "deviceId": { + "description": "Device ID", "type": "string" }, "duration": { + "description": "Duration (for videos)", "type": "string" }, "fileCreatedAt": { + "description": "File creation date", "format": "date-time", "type": "string" }, "fileModifiedAt": { + "description": "File modification date", "format": "date-time", "type": "string" }, "filename": { + "description": "Filename", "type": "string" } }, @@ -16287,6 +16544,7 @@ "AssetMediaResponseDto": { "properties": { "id": { + "description": "Asset media ID", "type": "string" }, "status": { @@ -16294,7 +16552,8 @@ { "$ref": "#/components/schemas/AssetMediaStatus" } - ] + ], + "description": "Upload status" } }, "required": [ @@ -16313,6 +16572,7 @@ "type": "string" }, "AssetMediaStatus": { + "description": "Upload status", "enum": [ "created", "replaced", @@ -16323,6 +16583,7 @@ "AssetMetadataBulkDeleteDto": { "properties": { "items": { + "description": "Metadata items to delete", "items": { "$ref": "#/components/schemas/AssetMetadataBulkDeleteItemDto" }, @@ -16337,10 +16598,12 @@ "AssetMetadataBulkDeleteItemDto": { "properties": { "assetId": { + "description": "Asset ID", "format": "uuid", "type": "string" }, "key": { + "description": "Metadata key", "type": "string" } }, @@ -16353,16 +16616,20 @@ "AssetMetadataBulkResponseDto": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "key": { + "description": "Metadata key", "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" }, "value": { + "description": "Metadata value (object)", "type": "object" } }, @@ -16377,6 +16644,7 @@ "AssetMetadataBulkUpsertDto": { "properties": { "items": { + "description": "Metadata items to upsert", "items": { "$ref": "#/components/schemas/AssetMetadataBulkUpsertItemDto" }, @@ -16391,13 +16659,16 @@ "AssetMetadataBulkUpsertItemDto": { "properties": { "assetId": { + "description": "Asset ID", "format": "uuid", "type": "string" }, "key": { + "description": "Metadata key", "type": "string" }, "value": { + "description": "Metadata value (object)", "type": "object" } }, @@ -16411,13 +16682,16 @@ "AssetMetadataResponseDto": { "properties": { "key": { + "description": "Metadata key", "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" }, "value": { + "description": "Metadata value (object)", "type": "object" } }, @@ -16431,6 +16705,7 @@ "AssetMetadataUpsertDto": { "properties": { "items": { + "description": "Metadata items to upsert", "items": { "$ref": "#/components/schemas/AssetMetadataUpsertItemDto" }, @@ -16445,9 +16720,11 @@ "AssetMetadataUpsertItemDto": { "properties": { "key": { + "description": "Metadata key", "type": "string" }, "value": { + "description": "Metadata value (object)", "type": "object" } }, @@ -16540,6 +16817,7 @@ "type": "object" }, "AssetOrder": { + "description": "Asset sort order", "enum": [ "asc", "desc" @@ -16549,7 +16827,7 @@ "AssetResponseDto": { "properties": { "checksum": { - "description": "base64 encoded sha1 hash", + "description": "Base64 encoded SHA1 hash", "type": "string" }, "createdAt": { @@ -16559,16 +16837,20 @@ "type": "string" }, "deviceAssetId": { + "description": "Device asset ID", "type": "string" }, "deviceId": { + "description": "Device ID", "type": "string" }, "duplicateId": { + "description": "Duplicate group ID", "nullable": true, "type": "string" }, "duration": { + "description": "Video duration (for videos)", "type": "string" }, "exifInfo": { @@ -16587,19 +16869,24 @@ "type": "string" }, "hasMetadata": { + "description": "Whether asset has metadata", "type": "boolean" }, "height": { + "description": "Asset height", "nullable": true, "type": "number" }, "id": { + "description": "Asset ID", "type": "string" }, "isArchived": { + "description": "Is archived", "type": "boolean" }, "isEdited": { + "description": "Is edited", "type": "boolean", "x-immich-history": [ { @@ -16614,16 +16901,21 @@ "x-immich-state": "Beta" }, "isFavorite": { + "description": "Is favorite", "type": "boolean" }, "isOffline": { + "description": "Is offline", "type": "boolean" }, "isTrashed": { + "description": "Is trashed", "type": "boolean" }, "libraryId": { "deprecated": true, + "description": "Library ID", + "format": "uuid", "nullable": true, "type": "string", "x-immich-history": [ @@ -16639,6 +16931,7 @@ "x-immich-state": "Deprecated" }, "livePhotoVideoId": { + "description": "Live photo video ID", "nullable": true, "type": "string" }, @@ -16649,18 +16942,22 @@ "type": "string" }, "originalFileName": { + "description": "Original file name", "type": "string" }, "originalMimeType": { + "description": "Original MIME type", "type": "string" }, "originalPath": { + "description": "Original file path", "type": "string" }, "owner": { "$ref": "#/components/schemas/UserResponseDto" }, "ownerId": { + "description": "Owner user ID", "type": "string" }, "people": { @@ -16671,6 +16968,7 @@ }, "resized": { "deprecated": true, + "description": "Is resized", "type": "boolean", "x-immich-history": [ { @@ -16699,6 +16997,7 @@ "type": "array" }, "thumbhash": { + "description": "Thumbhash for thumbnail generation", "nullable": true, "type": "string" }, @@ -16707,7 +17006,8 @@ { "$ref": "#/components/schemas/AssetTypeEnum" } - ] + ], + "description": "Asset type" }, "unassignedFaces": { "items": { @@ -16726,9 +17026,11 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Asset visibility" }, "width": { + "description": "Asset width", "nullable": true, "type": "number" } @@ -16764,12 +17066,15 @@ "AssetStackResponseDto": { "properties": { "assetCount": { + "description": "Number of assets in stack", "type": "integer" }, "id": { + "description": "Stack ID", "type": "string" }, "primaryAssetId": { + "description": "Primary asset ID", "type": "string" } }, @@ -16783,12 +17088,15 @@ "AssetStatsResponseDto": { "properties": { "images": { + "description": "Number of images", "type": "integer" }, "total": { + "description": "Total number of assets", "type": "integer" }, "videos": { + "description": "Number of videos", "type": "integer" } }, @@ -16800,6 +17108,7 @@ "type": "object" }, "AssetTypeEnum": { + "description": "Asset type", "enum": [ "IMAGE", "VIDEO", @@ -16809,6 +17118,7 @@ "type": "string" }, "AssetVisibility": { + "description": "Asset visibility", "enum": [ "archive", "timeline", @@ -16818,6 +17128,7 @@ "type": "string" }, "AudioCodec": { + "description": "Target audio codec", "enum": [ "mp3", "aac", @@ -16829,18 +17140,23 @@ "AuthStatusResponseDto": { "properties": { "expiresAt": { + "description": "Session expiration date", "type": "string" }, "isElevated": { + "description": "Is elevated session", "type": "boolean" }, "password": { + "description": "Has password set", "type": "boolean" }, "pinCode": { + "description": "Has PIN code set", "type": "boolean" }, "pinExpiresAt": { + "description": "PIN expiration date", "type": "string" } }, @@ -16858,12 +17174,14 @@ { "$ref": "#/components/schemas/UserAvatarColor" } - ] + ], + "description": "Avatar color" } }, "type": "object" }, "BulkIdErrorReason": { + "description": "Error reason", "enum": [ "duplicate", "no_permission", @@ -16875,6 +17193,7 @@ "BulkIdResponseDto": { "properties": { "error": { + "description": "Error reason if failed", "enum": [ "duplicate", "no_permission", @@ -16884,9 +17203,11 @@ "type": "string" }, "id": { + "description": "ID", "type": "string" }, "success": { + "description": "Whether operation succeeded", "type": "boolean" } }, @@ -16899,6 +17220,7 @@ "BulkIdsDto": { "properties": { "ids": { + "description": "IDs to process", "items": { "format": "uuid", "type": "string" @@ -16914,9 +17236,11 @@ "CLIPConfig": { "properties": { "enabled": { + "description": "Whether the task is enabled", "type": "boolean" }, "modelName": { + "description": "Name of the model to use", "type": "string" } }, @@ -16927,6 +17251,7 @@ "type": "object" }, "CQMode": { + "description": "CQ mode", "enum": [ "auto", "cqp", @@ -16938,6 +17263,7 @@ "properties": { "gCastEnabled": { "default": false, + "description": "Whether Google Cast is enabled", "type": "boolean" } }, @@ -16949,6 +17275,7 @@ "CastUpdate": { "properties": { "gCastEnabled": { + "description": "Whether Google Cast is enabled", "type": "boolean" } }, @@ -16958,14 +17285,17 @@ "properties": { "invalidateSessions": { "default": false, + "description": "Invalidate all other sessions", "type": "boolean" }, "newPassword": { + "description": "New password (min 8 characters)", "example": "password", "minLength": 8, "type": "string" }, "password": { + "description": "Current password", "example": "password", "type": "string" } @@ -16979,6 +17309,7 @@ "CheckExistingAssetsDto": { "properties": { "deviceAssetIds": { + "description": "Device asset IDs to check", "items": { "type": "string" }, @@ -16986,6 +17317,7 @@ "type": "array" }, "deviceId": { + "description": "Device ID", "type": "string" } }, @@ -16998,6 +17330,7 @@ "CheckExistingAssetsResponseDto": { "properties": { "existingIds": { + "description": "Existing asset IDs", "items": { "type": "string" }, @@ -17010,6 +17343,7 @@ "type": "object" }, "Colorspace": { + "description": "Colorspace", "enum": [ "srgb", "p3" @@ -17019,9 +17353,11 @@ "ContributorCountResponseDto": { "properties": { "assetCount": { + "description": "Number of assets contributed", "type": "integer" }, "userId": { + "description": "User ID", "type": "string" } }, @@ -17034,15 +17370,18 @@ "CreateAlbumDto": { "properties": { "albumName": { + "description": "Album name", "type": "string" }, "albumUsers": { + "description": "Album users", "items": { "$ref": "#/components/schemas/AlbumUserCreateDto" }, "type": "array" }, "assetIds": { + "description": "Initial asset IDs", "items": { "format": "uuid", "type": "string" @@ -17050,6 +17389,7 @@ "type": "array" }, "description": { + "description": "Album description", "type": "string" } }, @@ -17061,6 +17401,7 @@ "CreateLibraryDto": { "properties": { "exclusionPatterns": { + "description": "Exclusion patterns (max 128)", "items": { "type": "string" }, @@ -17069,6 +17410,7 @@ "uniqueItems": true }, "importPaths": { + "description": "Import paths (max 128)", "items": { "type": "string" }, @@ -17077,9 +17419,11 @@ "uniqueItems": true }, "name": { + "description": "Library name", "type": "string" }, "ownerId": { + "description": "Owner user ID", "format": "uuid", "type": "string" } @@ -17092,6 +17436,7 @@ "CreateProfileImageDto": { "properties": { "file": { + "description": "Profile image file", "format": "binary", "type": "string" } @@ -17104,13 +17449,16 @@ "CreateProfileImageResponseDto": { "properties": { "profileChangedAt": { + "description": "Profile image change date", "format": "date-time", "type": "string" }, "profileImagePath": { + "description": "Profile image file path", "type": "string" }, "userId": { + "description": "User ID", "type": "string" } }, @@ -17155,12 +17503,15 @@ "DatabaseBackupConfig": { "properties": { "cronExpression": { + "description": "Cron expression", "type": "string" }, "enabled": { + "description": "Enabled", "type": "boolean" }, "keepLastAmount": { + "description": "Keep last amount", "minimum": 1, "type": "number" } @@ -17227,12 +17578,14 @@ "DownloadArchiveInfo": { "properties": { "assetIds": { + "description": "Asset IDs in this archive", "items": { "type": "string" }, "type": "array" }, "size": { + "description": "Archive size in bytes", "type": "integer" } }, @@ -17245,14 +17598,17 @@ "DownloadInfoDto": { "properties": { "albumId": { + "description": "Album ID to download", "format": "uuid", "type": "string" }, "archiveSize": { + "description": "Archive size limit in bytes", "minimum": 1, "type": "integer" }, "assetIds": { + "description": "Asset IDs to download", "items": { "format": "uuid", "type": "string" @@ -17260,6 +17616,7 @@ "type": "array" }, "userId": { + "description": "User ID to download assets from", "format": "uuid", "type": "string" } @@ -17269,10 +17626,12 @@ "DownloadResponse": { "properties": { "archiveSize": { + "description": "Maximum archive size in bytes", "type": "integer" }, "includeEmbeddedVideos": { "default": false, + "description": "Whether to include embedded videos in downloads", "type": "boolean" } }, @@ -17285,12 +17644,14 @@ "DownloadResponseDto": { "properties": { "archives": { + "description": "Archive information", "items": { "$ref": "#/components/schemas/DownloadArchiveInfo" }, "type": "array" }, "totalSize": { + "description": "Total size in bytes", "type": "integer" } }, @@ -17303,10 +17664,12 @@ "DownloadUpdate": { "properties": { "archiveSize": { + "description": "Maximum archive size in bytes", "minimum": 1, "type": "integer" }, "includeEmbeddedVideos": { + "description": "Whether to include embedded videos in downloads", "type": "boolean" } }, @@ -17315,9 +17678,11 @@ "DuplicateDetectionConfig": { "properties": { "enabled": { + "description": "Whether the task is enabled", "type": "boolean" }, "maxDistance": { + "description": "Maximum distance threshold for duplicate detection", "format": "double", "maximum": 0.1, "minimum": 0.001, @@ -17333,12 +17698,14 @@ "DuplicateResponseDto": { "properties": { "assets": { + "description": "Duplicate assets", "items": { "$ref": "#/components/schemas/AssetResponseDto" }, "type": "array" }, "duplicateId": { + "description": "Duplicate group ID", "type": "string" } }, @@ -17351,12 +17718,15 @@ "EmailNotificationsResponse": { "properties": { "albumInvite": { + "description": "Whether to receive email notifications for album invites", "type": "boolean" }, "albumUpdate": { + "description": "Whether to receive email notifications for album updates", "type": "boolean" }, "enabled": { + "description": "Whether email notifications are enabled", "type": "boolean" } }, @@ -17370,12 +17740,15 @@ "EmailNotificationsUpdate": { "properties": { "albumInvite": { + "description": "Whether to receive email notifications for album invites", "type": "boolean" }, "albumUpdate": { + "description": "Whether to receive email notifications for album updates", "type": "boolean" }, "enabled": { + "description": "Whether email notifications are enabled", "type": "boolean" } }, @@ -17385,114 +17758,136 @@ "properties": { "city": { "default": null, + "description": "City name", "nullable": true, "type": "string" }, "country": { "default": null, + "description": "Country name", "nullable": true, "type": "string" }, "dateTimeOriginal": { "default": null, + "description": "Original date/time", "format": "date-time", "nullable": true, "type": "string" }, "description": { "default": null, + "description": "Image description", "nullable": true, "type": "string" }, "exifImageHeight": { "default": null, + "description": "Image height in pixels", "nullable": true, "type": "number" }, "exifImageWidth": { "default": null, + "description": "Image width in pixels", "nullable": true, "type": "number" }, "exposureTime": { "default": null, + "description": "Exposure time", "nullable": true, "type": "string" }, "fNumber": { "default": null, + "description": "F-number (aperture)", "nullable": true, "type": "number" }, "fileSizeInByte": { "default": null, + "description": "File size in bytes", "format": "int64", "nullable": true, "type": "integer" }, "focalLength": { "default": null, + "description": "Focal length in mm", "nullable": true, "type": "number" }, "iso": { "default": null, + "description": "ISO sensitivity", "nullable": true, "type": "number" }, "latitude": { "default": null, + "description": "GPS latitude", "nullable": true, "type": "number" }, "lensModel": { "default": null, + "description": "Lens model", "nullable": true, "type": "string" }, "longitude": { "default": null, + "description": "GPS longitude", "nullable": true, "type": "number" }, "make": { "default": null, + "description": "Camera make", "nullable": true, "type": "string" }, "model": { "default": null, + "description": "Camera model", "nullable": true, "type": "string" }, "modifyDate": { "default": null, + "description": "Modification date/time", "format": "date-time", "nullable": true, "type": "string" }, "orientation": { "default": null, + "description": "Image orientation", "nullable": true, "type": "string" }, "projectionType": { "default": null, + "description": "Projection type", "nullable": true, "type": "string" }, "rating": { "default": null, + "description": "Rating", "nullable": true, "type": "number" }, "state": { "default": null, + "description": "State/province name", "nullable": true, "type": "string" }, "timeZone": { "default": null, + "description": "Time zone", "nullable": true, "type": "string" } @@ -17502,6 +17897,7 @@ "FaceDto": { "properties": { "id": { + "description": "Face ID", "format": "uuid", "type": "string" } @@ -17514,25 +17910,30 @@ "FacialRecognitionConfig": { "properties": { "enabled": { + "description": "Whether the task is enabled", "type": "boolean" }, "maxDistance": { + "description": "Maximum distance threshold for face recognition", "format": "double", "maximum": 2, "minimum": 0.1, "type": "number" }, "minFaces": { + "description": "Minimum number of faces required for recognition", "minimum": 1, "type": "integer" }, "minScore": { + "description": "Minimum confidence score for face detection", "format": "double", "maximum": 1, "minimum": 0.1, "type": "number" }, "modelName": { + "description": "Name of the model to use", "type": "string" } }, @@ -17549,10 +17950,12 @@ "properties": { "enabled": { "default": false, + "description": "Whether folders are enabled", "type": "boolean" }, "sidebarWeb": { "default": false, + "description": "Whether folders appear in web sidebar", "type": "boolean" } }, @@ -17565,15 +17968,18 @@ "FoldersUpdate": { "properties": { "enabled": { + "description": "Whether folders are enabled", "type": "boolean" }, "sidebarWeb": { + "description": "Whether folders appear in web sidebar", "type": "boolean" } }, "type": "object" }, "ImageFormat": { + "description": "Image format", "enum": [ "jpeg", "webp" @@ -17587,7 +17993,8 @@ { "$ref": "#/components/schemas/ManualJobName" } - ] + ], + "description": "Job name" } }, "required": [ @@ -17596,6 +18003,7 @@ "type": "object" }, "JobName": { + "description": "Job name", "enum": [ "AssetDelete", "AssetDeleteCheck", @@ -17659,6 +18067,7 @@ "JobSettingsDto": { "properties": { "concurrency": { + "description": "Concurrency", "minimum": 1, "type": "integer" } @@ -17671,39 +18080,48 @@ "LibraryResponseDto": { "properties": { "assetCount": { + "description": "Number of assets", "type": "integer" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "exclusionPatterns": { + "description": "Exclusion patterns", "items": { "type": "string" }, "type": "array" }, "id": { + "description": "Library ID", "type": "string" }, "importPaths": { + "description": "Import paths", "items": { "type": "string" }, "type": "array" }, "name": { + "description": "Library name", "type": "string" }, "ownerId": { + "description": "Owner user ID", "type": "string" }, "refreshedAt": { + "description": "Last refresh date", "format": "date-time", "nullable": true, "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" } @@ -17725,19 +18143,23 @@ "properties": { "photos": { "default": 0, + "description": "Number of photos", "type": "integer" }, "total": { "default": 0, + "description": "Total number of assets", "type": "integer" }, "usage": { "default": 0, + "description": "Storage usage in bytes", "format": "int64", "type": "integer" }, "videos": { "default": 0, + "description": "Number of videos", "type": "integer" } }, @@ -17752,9 +18174,11 @@ "LicenseKeyDto": { "properties": { "activationKey": { + "description": "Activation key", "type": "string" }, "licenseKey": { + "description": "License key (format: IM(SV|CL)(-XXXX){8})", "pattern": "/IM(SV|CL)(-[\\dA-Za-z]{4}){8}/", "type": "string" } @@ -17768,13 +18192,16 @@ "LicenseResponseDto": { "properties": { "activatedAt": { + "description": "Activation date", "format": "date-time", "type": "string" }, "activationKey": { + "description": "Activation key", "type": "string" }, "licenseKey": { + "description": "License key (format: IM(SV|CL)(-XXXX){8})", "pattern": "/IM(SV|CL)(-[\\dA-Za-z]{4}){8}/", "type": "string" } @@ -17800,11 +18227,13 @@ "LoginCredentialDto": { "properties": { "email": { + "description": "User email", "example": "testuser@email.com", "format": "email", "type": "string" }, "password": { + "description": "User password", "example": "password", "type": "string" } @@ -17818,27 +18247,35 @@ "LoginResponseDto": { "properties": { "accessToken": { + "description": "Access token", "type": "string" }, "isAdmin": { + "description": "Is admin user", "type": "boolean" }, "isOnboarded": { + "description": "Is onboarded", "type": "boolean" }, "name": { + "description": "User name", "type": "string" }, "profileImagePath": { + "description": "Profile image path", "type": "string" }, "shouldChangePassword": { + "description": "Should change password", "type": "boolean" }, "userEmail": { + "description": "User email", "type": "string" }, "userId": { + "description": "User ID", "type": "string" } }, @@ -17857,9 +18294,11 @@ "LogoutResponseDto": { "properties": { "redirectUri": { + "description": "Redirect URI", "type": "string" }, "successful": { + "description": "Logout successful", "type": "boolean" } }, @@ -17872,6 +18311,7 @@ "MachineLearningAvailabilityChecksDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" }, "interval": { @@ -17889,6 +18329,7 @@ "type": "object" }, "MaintenanceAction": { + "description": "Maintenance action", "enum": [ "start", "end", @@ -17900,6 +18341,7 @@ "MaintenanceAuthDto": { "properties": { "username": { + "description": "Maintenance username", "type": "string" } }, @@ -17925,6 +18367,7 @@ "MaintenanceDetectInstallStorageFolderDto": { "properties": { "files": { + "description": "Number of files in the folder", "type": "number" }, "folder": { @@ -17932,12 +18375,15 @@ { "$ref": "#/components/schemas/StorageFolder" } - ] + ], + "description": "Storage folder" }, "readable": { + "description": "Whether the folder is readable", "type": "boolean" }, "writable": { + "description": "Whether the folder is writable", "type": "boolean" } }, @@ -17952,6 +18398,7 @@ "MaintenanceLoginDto": { "properties": { "token": { + "description": "Maintenance token", "type": "string" } }, @@ -17964,7 +18411,8 @@ { "$ref": "#/components/schemas/MaintenanceAction" } - ] + ], + "description": "Maintenance action" }, "active": { "type": "boolean" @@ -17986,6 +18434,7 @@ "type": "object" }, "ManualJobName": { + "description": "Job name", "enum": [ "person-cleanup", "tag-cleanup", @@ -17999,25 +18448,31 @@ "MapMarkerResponseDto": { "properties": { "city": { + "description": "City name", "nullable": true, "type": "string" }, "country": { + "description": "Country name", "nullable": true, "type": "string" }, "id": { + "description": "Asset ID", "type": "string" }, "lat": { + "description": "Latitude", "format": "double", "type": "number" }, "lon": { + "description": "Longitude", "format": "double", "type": "number" }, "state": { + "description": "State/Province name", "nullable": true, "type": "string" } @@ -18035,14 +18490,17 @@ "MapReverseGeocodeResponseDto": { "properties": { "city": { + "description": "City name", "nullable": true, "type": "string" }, "country": { + "description": "Country name", "nullable": true, "type": "string" }, "state": { + "description": "State/Province name", "nullable": true, "type": "string" } @@ -18058,10 +18516,12 @@ "properties": { "duration": { "default": 5, + "description": "Memory duration in seconds", "type": "integer" }, "enabled": { "default": true, + "description": "Whether memories are enabled", "type": "boolean" } }, @@ -18074,10 +18534,12 @@ "MemoriesUpdate": { "properties": { "duration": { + "description": "Memory duration in seconds", "minimum": 1, "type": "integer" }, "enabled": { + "description": "Whether memories are enabled", "type": "boolean" } }, @@ -18086,6 +18548,7 @@ "MemoryCreateDto": { "properties": { "assetIds": { + "description": "Asset IDs to associate with memory", "items": { "format": "uuid", "type": "string" @@ -18096,13 +18559,16 @@ "$ref": "#/components/schemas/OnThisDayDto" }, "isSaved": { + "description": "Is memory saved", "type": "boolean" }, "memoryAt": { + "description": "Memory date", "format": "date-time", "type": "string" }, "seenAt": { + "description": "Date when memory was seen", "format": "date-time", "type": "string" }, @@ -18111,7 +18577,8 @@ { "$ref": "#/components/schemas/MemoryType" } - ] + ], + "description": "Memory type" } }, "required": [ @@ -18130,6 +18597,7 @@ "type": "array" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, @@ -18137,31 +18605,39 @@ "$ref": "#/components/schemas/OnThisDayDto" }, "deletedAt": { + "description": "Deletion date", "format": "date-time", "type": "string" }, "hideAt": { + "description": "Date when memory should be hidden", "format": "date-time", "type": "string" }, "id": { + "description": "Memory ID", "type": "string" }, "isSaved": { + "description": "Is memory saved", "type": "boolean" }, "memoryAt": { + "description": "Memory date", "format": "date-time", "type": "string" }, "ownerId": { + "description": "Owner user ID", "type": "string" }, "seenAt": { + "description": "Date when memory was seen", "format": "date-time", "type": "string" }, "showAt": { + "description": "Date when memory should be shown", "format": "date-time", "type": "string" }, @@ -18170,9 +18646,11 @@ { "$ref": "#/components/schemas/MemoryType" } - ] + ], + "description": "Memory type" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" } @@ -18201,6 +18679,7 @@ "MemoryStatisticsResponseDto": { "properties": { "total": { + "description": "Total number of memories", "type": "integer" } }, @@ -18218,13 +18697,16 @@ "MemoryUpdateDto": { "properties": { "isSaved": { + "description": "Is memory saved", "type": "boolean" }, "memoryAt": { + "description": "Memory date", "format": "date-time", "type": "string" }, "seenAt": { + "description": "Date when memory was seen", "format": "date-time", "type": "string" } @@ -18234,6 +18716,7 @@ "MergePersonDto": { "properties": { "ids": { + "description": "Person IDs to merge", "items": { "format": "uuid", "type": "string" @@ -18249,6 +18732,7 @@ "MetadataSearchDto": { "properties": { "albumIds": { + "description": "Filter by album IDs", "items": { "format": "uuid", "type": "string" @@ -18256,72 +18740,92 @@ "type": "array" }, "checksum": { + "description": "Filter by file checksum", "type": "string" }, "city": { + "description": "Filter by city name", "nullable": true, "type": "string" }, "country": { + "description": "Filter by country name", "nullable": true, "type": "string" }, "createdAfter": { + "description": "Filter by creation date (after)", "format": "date-time", "type": "string" }, "createdBefore": { + "description": "Filter by creation date (before)", "format": "date-time", "type": "string" }, "description": { + "description": "Filter by description text", "type": "string" }, "deviceAssetId": { + "description": "Filter by device asset ID", "type": "string" }, "deviceId": { + "description": "Device ID to filter by", "type": "string" }, "encodedVideoPath": { + "description": "Filter by encoded video file path", "type": "string" }, "id": { + "description": "Filter by asset ID", "format": "uuid", "type": "string" }, "isEncoded": { + "description": "Filter by encoded status", "type": "boolean" }, "isFavorite": { + "description": "Filter by favorite status", "type": "boolean" }, "isMotion": { + "description": "Filter by motion photo status", "type": "boolean" }, "isNotInAlbum": { + "description": "Filter assets not in any album", "type": "boolean" }, "isOffline": { + "description": "Filter by offline status", "type": "boolean" }, "lensModel": { + "description": "Filter by lens model", "nullable": true, "type": "string" }, "libraryId": { + "description": "Library ID to filter by", "format": "uuid", "nullable": true, "type": "string" }, "make": { + "description": "Filter by camera make", "type": "string" }, "model": { + "description": "Filter by camera model", "nullable": true, "type": "string" }, "ocr": { + "description": "Filter by OCR text content", "type": "string" }, "order": { @@ -18330,19 +18834,24 @@ "$ref": "#/components/schemas/AssetOrder" } ], - "default": "desc" + "default": "desc", + "description": "Sort order" }, "originalFileName": { + "description": "Filter by original file name", "type": "string" }, "originalPath": { + "description": "Filter by original file path", "type": "string" }, "page": { + "description": "Page number", "minimum": 1, "type": "number" }, "personIds": { + "description": "Filter by person IDs", "items": { "format": "uuid", "type": "string" @@ -18350,23 +18859,28 @@ "type": "array" }, "previewPath": { + "description": "Filter by preview file path", "type": "string" }, "rating": { + "description": "Filter by rating", "maximum": 5, "minimum": -1, "type": "number" }, "size": { + "description": "Number of results to return", "maximum": 1000, "minimum": 1, "type": "number" }, "state": { + "description": "Filter by state/province name", "nullable": true, "type": "string" }, "tagIds": { + "description": "Filter by tag IDs", "items": { "format": "uuid", "type": "string" @@ -18375,21 +18889,26 @@ "type": "array" }, "takenAfter": { + "description": "Filter by taken date (after)", "format": "date-time", "type": "string" }, "takenBefore": { + "description": "Filter by taken date (before)", "format": "date-time", "type": "string" }, "thumbnailPath": { + "description": "Filter by thumbnail file path", "type": "string" }, "trashedAfter": { + "description": "Filter by trash date (after)", "format": "date-time", "type": "string" }, "trashedBefore": { + "description": "Filter by trash date (before)", "format": "date-time", "type": "string" }, @@ -18398,13 +18917,16 @@ { "$ref": "#/components/schemas/AssetTypeEnum" } - ] + ], + "description": "Asset type filter" }, "updatedAfter": { + "description": "Filter by update date (after)", "format": "date-time", "type": "string" }, "updatedBefore": { + "description": "Filter by update date (before)", "format": "date-time", "type": "string" }, @@ -18413,18 +18935,23 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Filter by visibility" }, "withDeleted": { + "description": "Include deleted assets", "type": "boolean" }, "withExif": { + "description": "Include EXIF data in response", "type": "boolean" }, "withPeople": { + "description": "Include assets with people", "type": "boolean" }, "withStacked": { + "description": "Include stacked assets", "type": "boolean" } }, @@ -18457,9 +18984,11 @@ "NotificationCreateDto": { "properties": { "data": { + "description": "Additional notification data", "type": "object" }, "description": { + "description": "Notification description", "nullable": true, "type": "string" }, @@ -18468,14 +18997,17 @@ { "$ref": "#/components/schemas/NotificationLevel" } - ] + ], + "description": "Notification level" }, "readAt": { + "description": "Date when notification was read", "format": "date-time", "nullable": true, "type": "string" }, "title": { + "description": "Notification title", "type": "string" }, "type": { @@ -18483,9 +19015,11 @@ { "$ref": "#/components/schemas/NotificationType" } - ] + ], + "description": "Notification type" }, "userId": { + "description": "User ID to send notification to", "format": "uuid", "type": "string" } @@ -18499,6 +19033,7 @@ "NotificationDeleteAllDto": { "properties": { "ids": { + "description": "Notification IDs to delete", "items": { "format": "uuid", "type": "string" @@ -18514,16 +19049,20 @@ "NotificationDto": { "properties": { "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "data": { + "description": "Additional notification data", "type": "object" }, "description": { + "description": "Notification description", "type": "string" }, "id": { + "description": "Notification ID", "type": "string" }, "level": { @@ -18531,13 +19070,16 @@ { "$ref": "#/components/schemas/NotificationLevel" } - ] + ], + "description": "Notification level" }, "readAt": { + "description": "Date when notification was read", "format": "date-time", "type": "string" }, "title": { + "description": "Notification title", "type": "string" }, "type": { @@ -18545,7 +19087,8 @@ { "$ref": "#/components/schemas/NotificationType" } - ] + ], + "description": "Notification type" } }, "required": [ @@ -18580,6 +19123,7 @@ "NotificationUpdateAllDto": { "properties": { "ids": { + "description": "Notification IDs to update", "items": { "format": "uuid", "type": "string" @@ -18587,6 +19131,7 @@ "type": "array" }, "readAt": { + "description": "Date when notifications were read", "format": "date-time", "nullable": true, "type": "string" @@ -18600,6 +19145,7 @@ "NotificationUpdateDto": { "properties": { "readAt": { + "description": "Date when notification was read", "format": "date-time", "nullable": true, "type": "string" @@ -18610,6 +19156,7 @@ "OAuthAuthorizeResponseDto": { "properties": { "url": { + "description": "OAuth authorization URL", "type": "string" } }, @@ -18621,12 +19168,15 @@ "OAuthCallbackDto": { "properties": { "codeVerifier": { + "description": "OAuth code verifier (PKCE)", "type": "string" }, "state": { + "description": "OAuth state parameter", "type": "string" }, "url": { + "description": "OAuth callback URL", "type": "string" } }, @@ -18638,12 +19188,15 @@ "OAuthConfigDto": { "properties": { "codeChallenge": { + "description": "OAuth code challenge (PKCE)", "type": "string" }, "redirectUri": { + "description": "OAuth redirect URI", "type": "string" }, "state": { + "description": "OAuth state parameter", "type": "string" } }, @@ -18653,6 +19206,7 @@ "type": "object" }, "OAuthTokenEndpointAuthMethod": { + "description": "Token endpoint auth method", "enum": [ "client_secret_post", "client_secret_basic" @@ -18662,25 +19216,30 @@ "OcrConfig": { "properties": { "enabled": { + "description": "Whether the task is enabled", "type": "boolean" }, "maxResolution": { + "description": "Maximum resolution for OCR processing", "minimum": 1, "type": "integer" }, "minDetectionScore": { + "description": "Minimum confidence score for text detection", "format": "double", "maximum": 1, "minimum": 0.1, "type": "number" }, "minRecognitionScore": { + "description": "Minimum confidence score for text recognition", "format": "double", "maximum": 1, "minimum": 0.1, "type": "number" }, "modelName": { + "description": "Name of the model to use", "type": "string" } }, @@ -18696,6 +19255,7 @@ "OnThisDayDto": { "properties": { "year": { + "description": "Year for on this day memory", "minimum": 1, "type": "number" } @@ -18708,6 +19268,7 @@ "OnboardingDto": { "properties": { "isOnboarded": { + "description": "Is user onboarded", "type": "boolean" } }, @@ -18719,6 +19280,7 @@ "OnboardingResponseDto": { "properties": { "isOnboarded": { + "description": "Is user onboarded", "type": "boolean" } }, @@ -18730,6 +19292,7 @@ "PartnerCreateDto": { "properties": { "sharedWithId": { + "description": "User ID to share with", "format": "uuid", "type": "string" } @@ -18753,25 +19316,32 @@ { "$ref": "#/components/schemas/UserAvatarColor" } - ] + ], + "description": "Avatar color" }, "email": { + "description": "User email", "type": "string" }, "id": { + "description": "User ID", "type": "string" }, "inTimeline": { + "description": "Show in timeline", "type": "boolean" }, "name": { + "description": "User name", "type": "string" }, "profileChangedAt": { + "description": "Profile change date", "format": "date-time", "type": "string" }, "profileImagePath": { + "description": "Profile image path", "type": "string" } }, @@ -18788,6 +19358,7 @@ "PartnerUpdateDto": { "properties": { "inTimeline": { + "description": "Show partner assets in timeline", "type": "boolean" } }, @@ -18800,10 +19371,12 @@ "properties": { "enabled": { "default": true, + "description": "Whether people are enabled", "type": "boolean" }, "sidebarWeb": { "default": false, + "description": "Whether people appear in web sidebar", "type": "boolean" } }, @@ -18816,6 +19389,7 @@ "PeopleResponseDto": { "properties": { "hasNextPage": { + "description": "Whether there are more pages", "type": "boolean", "x-immich-history": [ { @@ -18830,15 +19404,18 @@ "x-immich-state": "Stable" }, "hidden": { + "description": "Number of hidden people", "type": "integer" }, "people": { + "description": "List of people", "items": { "$ref": "#/components/schemas/PersonResponseDto" }, "type": "array" }, "total": { + "description": "Total number of people", "type": "integer" } }, @@ -18852,9 +19429,11 @@ "PeopleUpdate": { "properties": { "enabled": { + "description": "Whether people are enabled", "type": "boolean" }, "sidebarWeb": { + "description": "Whether people appear in web sidebar", "type": "boolean" } }, @@ -18863,6 +19442,7 @@ "PeopleUpdateDto": { "properties": { "people": { + "description": "People to update", "items": { "$ref": "#/components/schemas/PeopleUpdateItem" }, @@ -18877,33 +19457,35 @@ "PeopleUpdateItem": { "properties": { "birthDate": { - "description": "Person date of birth.\nNote: the mobile app cannot currently set the birth date to null.", + "description": "Person date of birth", "format": "date", "nullable": true, "type": "string" }, "color": { + "description": "Person color (hex)", "nullable": true, "type": "string" }, "featureFaceAssetId": { - "description": "Asset is used to get the feature face thumbnail.", + "description": "Asset ID used for feature face thumbnail", "format": "uuid", "type": "string" }, "id": { - "description": "Person id.", + "description": "Person ID", "type": "string" }, "isFavorite": { + "description": "Mark as favorite", "type": "boolean" }, "isHidden": { - "description": "Person visibility", + "description": "Person visibility (hidden)", "type": "boolean" }, "name": { - "description": "Person name.", + "description": "Person name", "type": "string" } }, @@ -18913,6 +19495,7 @@ "type": "object" }, "Permission": { + "description": "List of permissions", "enum": [ "all", "activity.create", @@ -19076,24 +19659,26 @@ "PersonCreateDto": { "properties": { "birthDate": { - "description": "Person date of birth.\nNote: the mobile app cannot currently set the birth date to null.", + "description": "Person date of birth", "format": "date", "nullable": true, "type": "string" }, "color": { + "description": "Person color (hex)", "nullable": true, "type": "string" }, "isFavorite": { + "description": "Mark as favorite", "type": "boolean" }, "isHidden": { - "description": "Person visibility", + "description": "Person visibility (hidden)", "type": "boolean" }, "name": { - "description": "Person name.", + "description": "Person name", "type": "string" } }, @@ -19102,11 +19687,13 @@ "PersonResponseDto": { "properties": { "birthDate": { + "description": "Person date of birth", "format": "date", "nullable": true, "type": "string" }, "color": { + "description": "Person color (hex)", "type": "string", "x-immich-history": [ { @@ -19121,9 +19708,11 @@ "x-immich-state": "Stable" }, "id": { + "description": "Person ID", "type": "string" }, "isFavorite": { + "description": "Is favorite", "type": "boolean", "x-immich-history": [ { @@ -19138,15 +19727,19 @@ "x-immich-state": "Stable" }, "isHidden": { + "description": "Is hidden", "type": "boolean" }, "name": { + "description": "Person name", "type": "string" }, "thumbnailPath": { + "description": "Thumbnail path", "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string", "x-immich-history": [ @@ -19174,6 +19767,7 @@ "PersonStatisticsResponseDto": { "properties": { "assets": { + "description": "Number of assets", "type": "integer" } }, @@ -19185,29 +19779,31 @@ "PersonUpdateDto": { "properties": { "birthDate": { - "description": "Person date of birth.\nNote: the mobile app cannot currently set the birth date to null.", + "description": "Person date of birth", "format": "date", "nullable": true, "type": "string" }, "color": { + "description": "Person color (hex)", "nullable": true, "type": "string" }, "featureFaceAssetId": { - "description": "Asset is used to get the feature face thumbnail.", + "description": "Asset ID used for feature face thumbnail", "format": "uuid", "type": "string" }, "isFavorite": { + "description": "Mark as favorite", "type": "boolean" }, "isHidden": { - "description": "Person visibility", + "description": "Person visibility (hidden)", "type": "boolean" }, "name": { - "description": "Person name.", + "description": "Person name", "type": "string" } }, @@ -19216,11 +19812,13 @@ "PersonWithFacesResponseDto": { "properties": { "birthDate": { + "description": "Person date of birth", "format": "date", "nullable": true, "type": "string" }, "color": { + "description": "Person color (hex)", "type": "string", "x-immich-history": [ { @@ -19235,15 +19833,18 @@ "x-immich-state": "Stable" }, "faces": { + "description": "Face detections", "items": { "$ref": "#/components/schemas/AssetFaceWithoutPersonResponseDto" }, "type": "array" }, "id": { + "description": "Person ID", "type": "string" }, "isFavorite": { + "description": "Is favorite", "type": "boolean", "x-immich-history": [ { @@ -19258,15 +19859,19 @@ "x-immich-state": "Stable" }, "isHidden": { + "description": "Is hidden", "type": "boolean" }, "name": { + "description": "Person name", "type": "string" }, "thumbnailPath": { + "description": "Thumbnail path", "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string", "x-immich-history": [ @@ -19295,13 +19900,16 @@ "PinCodeChangeDto": { "properties": { "newPinCode": { + "description": "New PIN code (4-6 digits)", "example": "123456", "type": "string" }, "password": { + "description": "User password (required if PIN code is not provided)", "type": "string" }, "pinCode": { + "description": "New PIN code (4-6 digits)", "example": "123456", "type": "string" } @@ -19314,9 +19922,11 @@ "PinCodeResetDto": { "properties": { "password": { + "description": "User password (required if PIN code is not provided)", "type": "string" }, "pinCode": { + "description": "New PIN code (4-6 digits)", "example": "123456", "type": "string" } @@ -19326,6 +19936,7 @@ "PinCodeSetupDto": { "properties": { "pinCode": { + "description": "PIN code (4-6 digits)", "example": "123456", "type": "string" } @@ -19338,18 +19949,23 @@ "PlacesResponseDto": { "properties": { "admin1name": { + "description": "Administrative level 1 name (state/province)", "type": "string" }, "admin2name": { + "description": "Administrative level 2 name (county/district)", "type": "string" }, "latitude": { + "description": "Latitude coordinate", "type": "number" }, "longitude": { + "description": "Longitude coordinate", "type": "number" }, "name": { + "description": "Place name", "type": "string" } }, @@ -19363,28 +19979,35 @@ "PluginActionResponseDto": { "properties": { "description": { + "description": "Action description", "type": "string" }, "id": { + "description": "Action ID", "type": "string" }, "methodName": { + "description": "Method name", "type": "string" }, "pluginId": { + "description": "Plugin ID", "type": "string" }, "schema": { + "description": "Action schema", "nullable": true, "type": "object" }, "supportedContexts": { + "description": "Supported contexts", "items": { "$ref": "#/components/schemas/PluginContextType" }, "type": "array" }, "title": { + "description": "Action title", "type": "string" } }, @@ -19400,6 +20023,7 @@ "type": "object" }, "PluginContextType": { + "description": "Context type", "enum": [ "asset", "album", @@ -19410,28 +20034,35 @@ "PluginFilterResponseDto": { "properties": { "description": { + "description": "Filter description", "type": "string" }, "id": { + "description": "Filter ID", "type": "string" }, "methodName": { + "description": "Method name", "type": "string" }, "pluginId": { + "description": "Plugin ID", "type": "string" }, "schema": { + "description": "Filter schema", "nullable": true, "type": "object" }, "supportedContexts": { + "description": "Supported contexts", "items": { "$ref": "#/components/schemas/PluginContextType" }, "type": "array" }, "title": { + "description": "Filter title", "type": "string" } }, @@ -19449,39 +20080,49 @@ "PluginResponseDto": { "properties": { "actions": { + "description": "Plugin actions", "items": { "$ref": "#/components/schemas/PluginActionResponseDto" }, "type": "array" }, "author": { + "description": "Plugin author", "type": "string" }, "createdAt": { + "description": "Creation date", "type": "string" }, "description": { + "description": "Plugin description", "type": "string" }, "filters": { + "description": "Plugin filters", "items": { "$ref": "#/components/schemas/PluginFilterResponseDto" }, "type": "array" }, "id": { + "description": "Plugin ID", "type": "string" }, "name": { + "description": "Plugin name", "type": "string" }, "title": { + "description": "Plugin title", "type": "string" }, "updatedAt": { + "description": "Last update date", "type": "string" }, "version": { + "description": "Plugin version", "type": "string" } }, @@ -19506,14 +20147,16 @@ { "$ref": "#/components/schemas/PluginContextType" } - ] + ], + "description": "Context type" }, "type": { "allOf": [ { "$ref": "#/components/schemas/PluginTriggerType" } - ] + ], + "description": "Trigger type" } }, "required": [ @@ -19523,6 +20166,7 @@ "type": "object" }, "PluginTriggerType": { + "description": "Trigger type", "enum": [ "AssetCreate", "PersonRecognized" @@ -19532,9 +20176,11 @@ "PurchaseResponse": { "properties": { "hideBuyButtonUntil": { + "description": "Date until which to hide buy button", "type": "string" }, "showSupportBadge": { + "description": "Whether to show support badge", "type": "boolean" } }, @@ -19547,15 +20193,18 @@ "PurchaseUpdate": { "properties": { "hideBuyButtonUntil": { + "description": "Date until which to hide buy button", "type": "string" }, "showSupportBadge": { + "description": "Whether to show support badge", "type": "boolean" } }, "type": "object" }, "QueueCommand": { + "description": "Queue command to execute", "enum": [ "start", "pause", @@ -19572,9 +20221,11 @@ { "$ref": "#/components/schemas/QueueCommand" } - ] + ], + "description": "Queue command to execute" }, "force": { + "description": "Force the command execution (if applicable)", "type": "boolean" } }, @@ -19606,9 +20257,11 @@ "QueueJobResponseDto": { "properties": { "data": { + "description": "Job data payload", "type": "object" }, "id": { + "description": "Job ID", "type": "string" }, "name": { @@ -19616,9 +20269,11 @@ { "$ref": "#/components/schemas/JobName" } - ] + ], + "description": "Job name" }, "timestamp": { + "description": "Job creation timestamp", "type": "integer" } }, @@ -19666,6 +20321,7 @@ "QueueResponseDto": { "properties": { "isPaused": { + "description": "Whether the queue is paused", "type": "boolean" }, "name": { @@ -19673,7 +20329,8 @@ { "$ref": "#/components/schemas/QueueName" } - ] + ], + "description": "Queue name" }, "statistics": { "$ref": "#/components/schemas/QueueStatisticsDto" @@ -19704,21 +20361,27 @@ "QueueStatisticsDto": { "properties": { "active": { + "description": "Number of active jobs", "type": "integer" }, "completed": { + "description": "Number of completed jobs", "type": "integer" }, "delayed": { + "description": "Number of delayed jobs", "type": "integer" }, "failed": { + "description": "Number of failed jobs", "type": "integer" }, "paused": { + "description": "Number of paused jobs", "type": "integer" }, "waiting": { + "description": "Number of waiting jobs", "type": "integer" } }, @@ -19735,9 +20398,11 @@ "QueueStatusLegacyDto": { "properties": { "isActive": { + "description": "Whether the queue is currently active (has running jobs)", "type": "boolean" }, "isPaused": { + "description": "Whether the queue is paused", "type": "boolean" } }, @@ -19750,6 +20415,7 @@ "QueueUpdateDto": { "properties": { "isPaused": { + "description": "Whether to pause the queue", "type": "boolean" } }, @@ -19837,6 +20503,7 @@ "RandomSearchDto": { "properties": { "albumIds": { + "description": "Filter by album IDs", "items": { "format": "uuid", "type": "string" @@ -19844,59 +20511,75 @@ "type": "array" }, "city": { + "description": "Filter by city name", "nullable": true, "type": "string" }, "country": { + "description": "Filter by country name", "nullable": true, "type": "string" }, "createdAfter": { + "description": "Filter by creation date (after)", "format": "date-time", "type": "string" }, "createdBefore": { + "description": "Filter by creation date (before)", "format": "date-time", "type": "string" }, "deviceId": { + "description": "Device ID to filter by", "type": "string" }, "isEncoded": { + "description": "Filter by encoded status", "type": "boolean" }, "isFavorite": { + "description": "Filter by favorite status", "type": "boolean" }, "isMotion": { + "description": "Filter by motion photo status", "type": "boolean" }, "isNotInAlbum": { + "description": "Filter assets not in any album", "type": "boolean" }, "isOffline": { + "description": "Filter by offline status", "type": "boolean" }, "lensModel": { + "description": "Filter by lens model", "nullable": true, "type": "string" }, "libraryId": { + "description": "Library ID to filter by", "format": "uuid", "nullable": true, "type": "string" }, "make": { + "description": "Filter by camera make", "type": "string" }, "model": { + "description": "Filter by camera model", "nullable": true, "type": "string" }, "ocr": { + "description": "Filter by OCR text content", "type": "string" }, "personIds": { + "description": "Filter by person IDs", "items": { "format": "uuid", "type": "string" @@ -19904,20 +20587,24 @@ "type": "array" }, "rating": { + "description": "Filter by rating", "maximum": 5, "minimum": -1, "type": "number" }, "size": { + "description": "Number of results to return", "maximum": 1000, "minimum": 1, "type": "number" }, "state": { + "description": "Filter by state/province name", "nullable": true, "type": "string" }, "tagIds": { + "description": "Filter by tag IDs", "items": { "format": "uuid", "type": "string" @@ -19926,18 +20613,22 @@ "type": "array" }, "takenAfter": { + "description": "Filter by taken date (after)", "format": "date-time", "type": "string" }, "takenBefore": { + "description": "Filter by taken date (before)", "format": "date-time", "type": "string" }, "trashedAfter": { + "description": "Filter by trash date (after)", "format": "date-time", "type": "string" }, "trashedBefore": { + "description": "Filter by trash date (before)", "format": "date-time", "type": "string" }, @@ -19946,13 +20637,16 @@ { "$ref": "#/components/schemas/AssetTypeEnum" } - ] + ], + "description": "Asset type filter" }, "updatedAfter": { + "description": "Filter by update date (after)", "format": "date-time", "type": "string" }, "updatedBefore": { + "description": "Filter by update date (before)", "format": "date-time", "type": "string" }, @@ -19961,18 +20655,23 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Filter by visibility" }, "withDeleted": { + "description": "Include deleted assets", "type": "boolean" }, "withExif": { + "description": "Include EXIF data in response", "type": "boolean" }, "withPeople": { + "description": "Include assets with people", "type": "boolean" }, "withStacked": { + "description": "Include stacked assets", "type": "boolean" } }, @@ -19982,6 +20681,7 @@ "properties": { "enabled": { "default": false, + "description": "Whether ratings are enabled", "type": "boolean" } }, @@ -19993,6 +20693,7 @@ "RatingsUpdate": { "properties": { "enabled": { + "description": "Whether ratings are enabled", "type": "boolean" } }, @@ -20015,10 +20716,12 @@ "ReverseGeocodingStateResponseDto": { "properties": { "lastImportFileName": { + "description": "Last import file name", "nullable": true, "type": "string" }, "lastUpdate": { + "description": "Last update timestamp", "nullable": true, "type": "string" } @@ -20044,6 +20747,7 @@ "SearchAlbumResponseDto": { "properties": { "count": { + "description": "Number of albums in this page", "type": "integer" }, "facets": { @@ -20059,6 +20763,7 @@ "type": "array" }, "total": { + "description": "Total number of matching albums", "type": "integer" } }, @@ -20073,6 +20778,7 @@ "SearchAssetResponseDto": { "properties": { "count": { + "description": "Number of assets in this page", "type": "integer" }, "facets": { @@ -20088,10 +20794,12 @@ "type": "array" }, "nextPage": { + "description": "Next page token", "nullable": true, "type": "string" }, "total": { + "description": "Total number of matching assets", "type": "integer" } }, @@ -20110,6 +20818,7 @@ "$ref": "#/components/schemas/AssetResponseDto" }, "value": { + "description": "Explore value", "type": "string" } }, @@ -20122,6 +20831,7 @@ "SearchExploreResponseDto": { "properties": { "fieldName": { + "description": "Explore field name", "type": "string" }, "items": { @@ -20140,9 +20850,11 @@ "SearchFacetCountResponseDto": { "properties": { "count": { + "description": "Number of assets with this facet value", "type": "integer" }, "value": { + "description": "Facet value", "type": "string" } }, @@ -20155,12 +20867,14 @@ "SearchFacetResponseDto": { "properties": { "counts": { + "description": "Facet counts", "items": { "$ref": "#/components/schemas/SearchFacetCountResponseDto" }, "type": "array" }, "fieldName": { + "description": "Facet field name", "type": "string" } }, @@ -20188,6 +20902,7 @@ "SearchStatisticsResponseDto": { "properties": { "total": { + "description": "Total number of matching assets", "type": "integer" } }, @@ -20210,66 +20925,87 @@ "ServerAboutResponseDto": { "properties": { "build": { + "description": "Build identifier", "type": "string" }, "buildImage": { + "description": "Build image name", "type": "string" }, "buildImageUrl": { + "description": "Build image URL", "type": "string" }, "buildUrl": { + "description": "Build URL", "type": "string" }, "exiftool": { + "description": "ExifTool version", "type": "string" }, "ffmpeg": { + "description": "FFmpeg version", "type": "string" }, "imagemagick": { + "description": "ImageMagick version", "type": "string" }, "libvips": { + "description": "libvips version", "type": "string" }, "licensed": { + "description": "Whether the server is licensed", "type": "boolean" }, "nodejs": { + "description": "Node.js version", "type": "string" }, "repository": { + "description": "Repository name", "type": "string" }, "repositoryUrl": { + "description": "Repository URL", "type": "string" }, "sourceCommit": { + "description": "Source commit hash", "type": "string" }, "sourceRef": { + "description": "Source reference (branch/tag)", "type": "string" }, "sourceUrl": { + "description": "Source URL", "type": "string" }, "thirdPartyBugFeatureUrl": { + "description": "Third-party bug/feature URL", "type": "string" }, "thirdPartyDocumentationUrl": { + "description": "Third-party documentation URL", "type": "string" }, "thirdPartySourceUrl": { + "description": "Third-party source URL", "type": "string" }, "thirdPartySupportUrl": { + "description": "Third-party support URL", "type": "string" }, "version": { + "description": "Server version", "type": "string" }, "versionUrl": { + "description": "URL to version information", "type": "string" } }, @@ -20283,15 +21019,19 @@ "ServerApkLinksDto": { "properties": { "arm64v8a": { + "description": "APK download link for ARM64 v8a architecture", "type": "string" }, "armeabiv7a": { + "description": "APK download link for ARM EABI v7a architecture", "type": "string" }, "universal": { + "description": "APK download link for universal architecture", "type": "string" }, "x86_64": { + "description": "APK download link for x86_64 architecture", "type": "string" } }, @@ -20306,36 +21046,47 @@ "ServerConfigDto": { "properties": { "externalDomain": { + "description": "External domain URL", "type": "string" }, "isInitialized": { + "description": "Whether the server has been initialized", "type": "boolean" }, "isOnboarded": { + "description": "Whether the admin has completed onboarding", "type": "boolean" }, "loginPageMessage": { + "description": "Login page message", "type": "string" }, "maintenanceMode": { + "description": "Whether maintenance mode is active", "type": "boolean" }, "mapDarkStyleUrl": { + "description": "Map dark style URL", "type": "string" }, "mapLightStyleUrl": { + "description": "Map light style URL", "type": "string" }, "oauthButtonText": { + "description": "OAuth button text", "type": "string" }, "publicUsers": { + "description": "Whether public user registration is enabled", "type": "boolean" }, "trashDays": { + "description": "Number of days before trashed assets are permanently deleted", "type": "integer" }, "userDeleteDelay": { + "description": "Delay in days before deleted users are permanently removed", "type": "integer" } }, @@ -20357,48 +21108,63 @@ "ServerFeaturesDto": { "properties": { "configFile": { + "description": "Whether config file is available", "type": "boolean" }, "duplicateDetection": { + "description": "Whether duplicate detection is enabled", "type": "boolean" }, "email": { + "description": "Whether email notifications are enabled", "type": "boolean" }, "facialRecognition": { + "description": "Whether facial recognition is enabled", "type": "boolean" }, "importFaces": { + "description": "Whether face import is enabled", "type": "boolean" }, "map": { + "description": "Whether map feature is enabled", "type": "boolean" }, "oauth": { + "description": "Whether OAuth is enabled", "type": "boolean" }, "oauthAutoLaunch": { + "description": "Whether OAuth auto-launch is enabled", "type": "boolean" }, "ocr": { + "description": "Whether OCR is enabled", "type": "boolean" }, "passwordLogin": { + "description": "Whether password login is enabled", "type": "boolean" }, "reverseGeocoding": { + "description": "Whether reverse geocoding is enabled", "type": "boolean" }, "search": { + "description": "Whether search is enabled", "type": "boolean" }, "sidecar": { + "description": "Whether sidecar files are supported", "type": "boolean" }, "smartSearch": { + "description": "Whether smart search is enabled", "type": "boolean" }, "trash": { + "description": "Whether trash feature is enabled", "type": "boolean" } }, @@ -20424,18 +21190,21 @@ "ServerMediaTypesResponseDto": { "properties": { "image": { + "description": "Supported image MIME types", "items": { "type": "string" }, "type": "array" }, "sidecar": { + "description": "Supported sidecar MIME types", "items": { "type": "string" }, "type": "array" }, "video": { + "description": "Supported video MIME types", "items": { "type": "string" }, @@ -20466,10 +21235,12 @@ "properties": { "photos": { "default": 0, + "description": "Total number of photos", "type": "integer" }, "usage": { "default": 0, + "description": "Total storage usage in bytes", "format": "int64", "type": "integer" }, @@ -20492,16 +21263,19 @@ }, "usagePhotos": { "default": 0, + "description": "Storage usage for photos in bytes", "format": "int64", "type": "integer" }, "usageVideos": { "default": 0, + "description": "Storage usage for videos in bytes", "format": "int64", "type": "integer" }, "videos": { "default": 0, + "description": "Total number of videos", "type": "integer" } }, @@ -20518,27 +21292,34 @@ "ServerStorageResponseDto": { "properties": { "diskAvailable": { + "description": "Available disk space (human-readable format)", "type": "string" }, "diskAvailableRaw": { + "description": "Available disk space in bytes", "format": "int64", "type": "integer" }, "diskSize": { + "description": "Total disk size (human-readable format)", "type": "string" }, "diskSizeRaw": { + "description": "Total disk size in bytes", "format": "int64", "type": "integer" }, "diskUsagePercentage": { + "description": "Disk usage percentage (0-100)", "format": "double", "type": "number" }, "diskUse": { + "description": "Used disk space (human-readable format)", "type": "string" }, "diskUseRaw": { + "description": "Used disk space in bytes", "format": "int64", "type": "integer" } @@ -20557,6 +21338,7 @@ "ServerThemeDto": { "properties": { "customCss": { + "description": "Custom CSS for theming", "type": "string" } }, @@ -20568,13 +21350,16 @@ "ServerVersionHistoryResponseDto": { "properties": { "createdAt": { + "description": "When this version was first seen", "format": "date-time", "type": "string" }, "id": { + "description": "Version history entry ID", "type": "string" }, "version": { + "description": "Version string", "type": "string" } }, @@ -20588,12 +21373,15 @@ "ServerVersionResponseDto": { "properties": { "major": { + "description": "Major version number", "type": "integer" }, "minor": { + "description": "Minor version number", "type": "integer" }, "patch": { + "description": "Patch version number", "type": "integer" } }, @@ -20607,13 +21395,15 @@ "SessionCreateDto": { "properties": { "deviceOS": { + "description": "Device OS", "type": "string" }, "deviceType": { + "description": "Device type", "type": "string" }, "duration": { - "description": "session duration, in seconds", + "description": "Session duration in seconds", "minimum": 1, "type": "number" } @@ -20623,34 +21413,44 @@ "SessionCreateResponseDto": { "properties": { "appVersion": { + "description": "App version", "nullable": true, "type": "string" }, "createdAt": { + "description": "Creation date", "type": "string" }, "current": { + "description": "Is current session", "type": "boolean" }, "deviceOS": { + "description": "Device OS", "type": "string" }, "deviceType": { + "description": "Device type", "type": "string" }, "expiresAt": { + "description": "Expiration date", "type": "string" }, "id": { + "description": "Session ID", "type": "string" }, "isPendingSyncReset": { + "description": "Is pending sync reset", "type": "boolean" }, "token": { + "description": "Session token", "type": "string" }, "updatedAt": { + "description": "Last update date", "type": "string" } }, @@ -20670,31 +21470,40 @@ "SessionResponseDto": { "properties": { "appVersion": { + "description": "App version", "nullable": true, "type": "string" }, "createdAt": { + "description": "Creation date", "type": "string" }, "current": { + "description": "Is current session", "type": "boolean" }, "deviceOS": { + "description": "Device OS", "type": "string" }, "deviceType": { + "description": "Device type", "type": "string" }, "expiresAt": { + "description": "Expiration date", "type": "string" }, "id": { + "description": "Session ID", "type": "string" }, "isPendingSyncReset": { + "description": "Is pending sync reset", "type": "boolean" }, "updatedAt": { + "description": "Last update date", "type": "string" } }, @@ -20713,9 +21522,11 @@ "SessionUnlockDto": { "properties": { "password": { + "description": "User password (required if PIN code is not provided)", "type": "string" }, "pinCode": { + "description": "New PIN code (4-6 digits)", "example": "123456", "type": "string" } @@ -20725,6 +21536,7 @@ "SessionUpdateDto": { "properties": { "isPendingSyncReset": { + "description": "Reset pending sync state", "type": "boolean" } }, @@ -20737,9 +21549,11 @@ { "$ref": "#/components/schemas/MaintenanceAction" } - ] + ], + "description": "Maintenance action" }, "restoreBackupFilename": { + "description": "Restore backup filename", "type": "string" } }, @@ -20751,17 +21565,21 @@ "SharedLinkCreateDto": { "properties": { "albumId": { + "description": "Album ID (for album sharing)", "format": "uuid", "type": "string" }, "allowDownload": { "default": true, + "description": "Allow downloads", "type": "boolean" }, "allowUpload": { + "description": "Allow uploads", "type": "boolean" }, "assetIds": { + "description": "Asset IDs (for individual assets)", "items": { "format": "uuid", "type": "string" @@ -20769,24 +21587,29 @@ "type": "array" }, "description": { + "description": "Link description", "nullable": true, "type": "string" }, "expiresAt": { "default": null, + "description": "Expiration date", "format": "date-time", "nullable": true, "type": "string" }, "password": { + "description": "Link password", "nullable": true, "type": "string" }, "showMetadata": { "default": true, + "description": "Show metadata", "type": "boolean" }, "slug": { + "description": "Custom URL slug", "nullable": true, "type": "string" }, @@ -20795,7 +21618,8 @@ { "$ref": "#/components/schemas/SharedLinkType" } - ] + ], + "description": "Shared link type" } }, "required": [ @@ -20806,32 +21630,39 @@ "SharedLinkEditDto": { "properties": { "allowDownload": { + "description": "Allow downloads", "type": "boolean" }, "allowUpload": { + "description": "Allow uploads", "type": "boolean" }, "changeExpiryTime": { - "description": "Few clients cannot send null to set the expiryTime to never.\nSetting this flag and not sending expiryAt is considered as null instead.\nClients that can send null values can ignore this.", + "description": "Whether to change the expiry time. Few clients cannot send null to set the expiryTime to never. Setting this flag and not sending expiryAt is considered as null instead. Clients that can send null values can ignore this.", "type": "boolean" }, "description": { + "description": "Link description", "nullable": true, "type": "string" }, "expiresAt": { + "description": "Expiration date", "format": "date-time", "nullable": true, "type": "string" }, "password": { + "description": "Link password", "nullable": true, "type": "string" }, "showMetadata": { + "description": "Show metadata", "type": "boolean" }, "slug": { + "description": "Custom URL slug", "nullable": true, "type": "string" } @@ -20844,9 +21675,11 @@ "$ref": "#/components/schemas/AlbumResponseDto" }, "allowDownload": { + "description": "Allow downloads", "type": "boolean" }, "allowUpload": { + "description": "Allow uploads", "type": "boolean" }, "assets": { @@ -20856,36 +21689,45 @@ "type": "array" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "description": { + "description": "Link description", "nullable": true, "type": "string" }, "expiresAt": { + "description": "Expiration date", "format": "date-time", "nullable": true, "type": "string" }, "id": { + "description": "Shared link ID", "type": "string" }, "key": { + "description": "Encryption key (base64url)", "type": "string" }, "password": { + "description": "Has password", "nullable": true, "type": "string" }, "showMetadata": { + "description": "Show metadata", "type": "boolean" }, "slug": { + "description": "Custom URL slug", "nullable": true, "type": "string" }, "token": { + "description": "Access token", "nullable": true, "type": "string" }, @@ -20894,9 +21736,11 @@ { "$ref": "#/components/schemas/SharedLinkType" } - ] + ], + "description": "Shared link type" }, "userId": { + "description": "Owner user ID", "type": "string" } }, @@ -20918,6 +21762,7 @@ "type": "object" }, "SharedLinkType": { + "description": "Shared link type", "enum": [ "ALBUM", "INDIVIDUAL" @@ -20928,10 +21773,12 @@ "properties": { "enabled": { "default": true, + "description": "Whether shared links are enabled", "type": "boolean" }, "sidebarWeb": { "default": false, + "description": "Whether shared links appear in web sidebar", "type": "boolean" } }, @@ -20944,9 +21791,11 @@ "SharedLinksUpdate": { "properties": { "enabled": { + "description": "Whether shared links are enabled", "type": "boolean" }, "sidebarWeb": { + "description": "Whether shared links appear in web sidebar", "type": "boolean" } }, @@ -20955,15 +21804,18 @@ "SignUpDto": { "properties": { "email": { + "description": "User email", "example": "testuser@email.com", "format": "email", "type": "string" }, "name": { + "description": "User name", "example": "Admin", "type": "string" }, "password": { + "description": "User password", "example": "password", "type": "string" } @@ -20978,6 +21830,7 @@ "SmartSearchDto": { "properties": { "albumIds": { + "description": "Filter by album IDs", "items": { "format": "uuid", "type": "string" @@ -20985,66 +21838,84 @@ "type": "array" }, "city": { + "description": "Filter by city name", "nullable": true, "type": "string" }, "country": { + "description": "Filter by country name", "nullable": true, "type": "string" }, "createdAfter": { + "description": "Filter by creation date (after)", "format": "date-time", "type": "string" }, "createdBefore": { + "description": "Filter by creation date (before)", "format": "date-time", "type": "string" }, "deviceId": { + "description": "Device ID to filter by", "type": "string" }, "isEncoded": { + "description": "Filter by encoded status", "type": "boolean" }, "isFavorite": { + "description": "Filter by favorite status", "type": "boolean" }, "isMotion": { + "description": "Filter by motion photo status", "type": "boolean" }, "isNotInAlbum": { + "description": "Filter assets not in any album", "type": "boolean" }, "isOffline": { + "description": "Filter by offline status", "type": "boolean" }, "language": { + "description": "Search language code", "type": "string" }, "lensModel": { + "description": "Filter by lens model", "nullable": true, "type": "string" }, "libraryId": { + "description": "Library ID to filter by", "format": "uuid", "nullable": true, "type": "string" }, "make": { + "description": "Filter by camera make", "type": "string" }, "model": { + "description": "Filter by camera model", "nullable": true, "type": "string" }, "ocr": { + "description": "Filter by OCR text content", "type": "string" }, "page": { + "description": "Page number", "minimum": 1, "type": "number" }, "personIds": { + "description": "Filter by person IDs", "items": { "format": "uuid", "type": "string" @@ -21052,27 +21923,33 @@ "type": "array" }, "query": { + "description": "Natural language search query", "type": "string" }, "queryAssetId": { + "description": "Asset ID to use as search reference", "format": "uuid", "type": "string" }, "rating": { + "description": "Filter by rating", "maximum": 5, "minimum": -1, "type": "number" }, "size": { + "description": "Number of results to return", "maximum": 1000, "minimum": 1, "type": "number" }, "state": { + "description": "Filter by state/province name", "nullable": true, "type": "string" }, "tagIds": { + "description": "Filter by tag IDs", "items": { "format": "uuid", "type": "string" @@ -21081,18 +21958,22 @@ "type": "array" }, "takenAfter": { + "description": "Filter by taken date (after)", "format": "date-time", "type": "string" }, "takenBefore": { + "description": "Filter by taken date (before)", "format": "date-time", "type": "string" }, "trashedAfter": { + "description": "Filter by trash date (after)", "format": "date-time", "type": "string" }, "trashedBefore": { + "description": "Filter by trash date (before)", "format": "date-time", "type": "string" }, @@ -21101,13 +21982,16 @@ { "$ref": "#/components/schemas/AssetTypeEnum" } - ] + ], + "description": "Asset type filter" }, "updatedAfter": { + "description": "Filter by update date (after)", "format": "date-time", "type": "string" }, "updatedBefore": { + "description": "Filter by update date (before)", "format": "date-time", "type": "string" }, @@ -21116,18 +22000,22 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Filter by visibility" }, "withDeleted": { + "description": "Include deleted assets", "type": "boolean" }, "withExif": { + "description": "Include EXIF data in response", "type": "boolean" } }, "type": "object" }, "SourceType": { + "description": "Face detection source type", "enum": [ "machine-learning", "exif", @@ -21138,7 +22026,7 @@ "StackCreateDto": { "properties": { "assetIds": { - "description": "first asset becomes the primary", + "description": "Asset IDs (first becomes primary, min 2)", "items": { "format": "uuid", "type": "string" @@ -21155,15 +22043,18 @@ "StackResponseDto": { "properties": { "assets": { + "description": "Stack assets", "items": { "$ref": "#/components/schemas/AssetResponseDto" }, "type": "array" }, "id": { + "description": "Stack ID", "type": "string" }, "primaryAssetId": { + "description": "Primary asset ID", "type": "string" } }, @@ -21177,6 +22068,7 @@ "StackUpdateDto": { "properties": { "primaryAssetId": { + "description": "Primary asset ID", "format": "uuid", "type": "string" } @@ -21186,6 +22078,7 @@ "StatisticsSearchDto": { "properties": { "albumIds": { + "description": "Filter by album IDs", "items": { "format": "uuid", "type": "string" @@ -21193,62 +22086,79 @@ "type": "array" }, "city": { + "description": "Filter by city name", "nullable": true, "type": "string" }, "country": { + "description": "Filter by country name", "nullable": true, "type": "string" }, "createdAfter": { + "description": "Filter by creation date (after)", "format": "date-time", "type": "string" }, "createdBefore": { + "description": "Filter by creation date (before)", "format": "date-time", "type": "string" }, "description": { + "description": "Filter by description text", "type": "string" }, "deviceId": { + "description": "Device ID to filter by", "type": "string" }, "isEncoded": { + "description": "Filter by encoded status", "type": "boolean" }, "isFavorite": { + "description": "Filter by favorite status", "type": "boolean" }, "isMotion": { + "description": "Filter by motion photo status", "type": "boolean" }, "isNotInAlbum": { + "description": "Filter assets not in any album", "type": "boolean" }, "isOffline": { + "description": "Filter by offline status", "type": "boolean" }, "lensModel": { + "description": "Filter by lens model", "nullable": true, "type": "string" }, "libraryId": { + "description": "Library ID to filter by", "format": "uuid", "nullable": true, "type": "string" }, "make": { + "description": "Filter by camera make", "type": "string" }, "model": { + "description": "Filter by camera model", "nullable": true, "type": "string" }, "ocr": { + "description": "Filter by OCR text content", "type": "string" }, "personIds": { + "description": "Filter by person IDs", "items": { "format": "uuid", "type": "string" @@ -21256,15 +22166,18 @@ "type": "array" }, "rating": { + "description": "Filter by rating", "maximum": 5, "minimum": -1, "type": "number" }, "state": { + "description": "Filter by state/province name", "nullable": true, "type": "string" }, "tagIds": { + "description": "Filter by tag IDs", "items": { "format": "uuid", "type": "string" @@ -21273,18 +22186,22 @@ "type": "array" }, "takenAfter": { + "description": "Filter by taken date (after)", "format": "date-time", "type": "string" }, "takenBefore": { + "description": "Filter by taken date (before)", "format": "date-time", "type": "string" }, "trashedAfter": { + "description": "Filter by trash date (after)", "format": "date-time", "type": "string" }, "trashedBefore": { + "description": "Filter by trash date (before)", "format": "date-time", "type": "string" }, @@ -21293,13 +22210,16 @@ { "$ref": "#/components/schemas/AssetTypeEnum" } - ] + ], + "description": "Asset type filter" }, "updatedAfter": { + "description": "Filter by update date (after)", "format": "date-time", "type": "string" }, "updatedBefore": { + "description": "Filter by update date (before)", "format": "date-time", "type": "string" }, @@ -21308,12 +22228,14 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Filter by visibility" } }, "type": "object" }, "StorageFolder": { + "description": "Storage folder", "enum": [ "encoded-video", "library", @@ -21327,6 +22249,7 @@ "SyncAckDeleteDto": { "properties": { "types": { + "description": "Sync entity types to delete acks for", "items": { "$ref": "#/components/schemas/SyncEntityType" }, @@ -21338,6 +22261,7 @@ "SyncAckDto": { "properties": { "ack": { + "description": "Acknowledgment ID", "type": "string" }, "type": { @@ -21345,7 +22269,8 @@ { "$ref": "#/components/schemas/SyncEntityType" } - ] + ], + "description": "Sync entity type" } }, "required": [ @@ -21357,6 +22282,7 @@ "SyncAckSetDto": { "properties": { "acks": { + "description": "Acknowledgment IDs (max 1000)", "items": { "type": "string" }, @@ -21376,6 +22302,7 @@ "SyncAlbumDeleteV1": { "properties": { "albumId": { + "description": "Album ID", "type": "string" } }, @@ -21387,9 +22314,11 @@ "SyncAlbumToAssetDeleteV1": { "properties": { "albumId": { + "description": "Album ID", "type": "string" }, "assetId": { + "description": "Asset ID", "type": "string" } }, @@ -21402,9 +22331,11 @@ "SyncAlbumToAssetV1": { "properties": { "albumId": { + "description": "Album ID", "type": "string" }, "assetId": { + "description": "Asset ID", "type": "string" } }, @@ -21417,9 +22348,11 @@ "SyncAlbumUserDeleteV1": { "properties": { "albumId": { + "description": "Album ID", "type": "string" }, "userId": { + "description": "User ID", "type": "string" } }, @@ -21432,6 +22365,7 @@ "SyncAlbumUserV1": { "properties": { "albumId": { + "description": "Album ID", "type": "string" }, "role": { @@ -21439,9 +22373,11 @@ { "$ref": "#/components/schemas/AlbumUserRole" } - ] + ], + "description": "Album user role" }, "userId": { + "description": "User ID", "type": "string" } }, @@ -21455,19 +22391,24 @@ "SyncAlbumV1": { "properties": { "createdAt": { + "description": "Created at", "format": "date-time", "type": "string" }, "description": { + "description": "Album description", "type": "string" }, "id": { + "description": "Album ID", "type": "string" }, "isActivityEnabled": { + "description": "Is activity enabled", "type": "boolean" }, "name": { + "description": "Album name", "type": "string" }, "order": { @@ -21478,13 +22419,16 @@ ] }, "ownerId": { + "description": "Owner ID", "type": "string" }, "thumbnailAssetId": { + "description": "Thumbnail asset ID", "nullable": true, "type": "string" }, "updatedAt": { + "description": "Updated at", "format": "date-time", "type": "string" } @@ -21505,6 +22449,7 @@ "SyncAssetDeleteV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" } }, @@ -21516,108 +22461,133 @@ "SyncAssetExifV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "city": { + "description": "City", "nullable": true, "type": "string" }, "country": { + "description": "Country", "nullable": true, "type": "string" }, "dateTimeOriginal": { + "description": "Date time original", "format": "date-time", "nullable": true, "type": "string" }, "description": { + "description": "Description", "nullable": true, "type": "string" }, "exifImageHeight": { + "description": "Exif image height", "nullable": true, "type": "integer" }, "exifImageWidth": { + "description": "Exif image width", "nullable": true, "type": "integer" }, "exposureTime": { + "description": "Exposure time", "nullable": true, "type": "string" }, "fNumber": { + "description": "F number", "format": "double", "nullable": true, "type": "number" }, "fileSizeInByte": { + "description": "File size in byte", "nullable": true, "type": "integer" }, "focalLength": { + "description": "Focal length", "format": "double", "nullable": true, "type": "number" }, "fps": { + "description": "FPS", "format": "double", "nullable": true, "type": "number" }, "iso": { + "description": "ISO", "nullable": true, "type": "integer" }, "latitude": { + "description": "Latitude", "format": "double", "nullable": true, "type": "number" }, "lensModel": { + "description": "Lens model", "nullable": true, "type": "string" }, "longitude": { + "description": "Longitude", "format": "double", "nullable": true, "type": "number" }, "make": { + "description": "Make", "nullable": true, "type": "string" }, "model": { + "description": "Model", "nullable": true, "type": "string" }, "modifyDate": { + "description": "Modify date", "format": "date-time", "nullable": true, "type": "string" }, "orientation": { + "description": "Orientation", "nullable": true, "type": "string" }, "profileDescription": { + "description": "Profile description", "nullable": true, "type": "string" }, "projectionType": { + "description": "Projection type", "nullable": true, "type": "string" }, "rating": { + "description": "Rating", "nullable": true, "type": "integer" }, "state": { + "description": "State", "nullable": true, "type": "string" }, "timeZone": { + "description": "Time zone", "nullable": true, "type": "string" } @@ -21654,6 +22624,7 @@ "SyncAssetFaceDeleteV1": { "properties": { "assetFaceId": { + "description": "Asset face ID", "type": "string" } }, @@ -21665,6 +22636,7 @@ "SyncAssetFaceV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "boundingBoxX1": { @@ -21680,6 +22652,7 @@ "type": "integer" }, "id": { + "description": "Asset face ID", "type": "string" }, "imageHeight": { @@ -21689,10 +22662,12 @@ "type": "integer" }, "personId": { + "description": "Person ID", "nullable": true, "type": "string" }, "sourceType": { + "description": "Source type", "type": "string" } }, @@ -21713,9 +22688,11 @@ "SyncAssetMetadataDeleteV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "key": { + "description": "Key", "type": "string" } }, @@ -21728,12 +22705,15 @@ "SyncAssetMetadataV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "key": { + "description": "Key", "type": "string" }, "value": { + "description": "Value", "type": "object" } }, @@ -21747,64 +22727,80 @@ "SyncAssetV1": { "properties": { "checksum": { + "description": "Checksum", "type": "string" }, "deletedAt": { + "description": "Deleted at", "format": "date-time", "nullable": true, "type": "string" }, "duration": { + "description": "Duration", "nullable": true, "type": "string" }, "fileCreatedAt": { + "description": "File created at", "format": "date-time", "nullable": true, "type": "string" }, "fileModifiedAt": { + "description": "File modified at", "format": "date-time", "nullable": true, "type": "string" }, "height": { + "description": "Asset height", "nullable": true, "type": "integer" }, "id": { + "description": "Asset ID", "type": "string" }, "isEdited": { + "description": "Is edited", "type": "boolean" }, "isFavorite": { + "description": "Is favorite", "type": "boolean" }, "libraryId": { + "description": "Library ID", "nullable": true, "type": "string" }, "livePhotoVideoId": { + "description": "Live photo video ID", "nullable": true, "type": "string" }, "localDateTime": { + "description": "Local date time", "format": "date-time", "nullable": true, "type": "string" }, "originalFileName": { + "description": "Original file name", "type": "string" }, "ownerId": { + "description": "Owner ID", "type": "string" }, "stackId": { + "description": "Stack ID", "nullable": true, "type": "string" }, "thumbhash": { + "description": "Thumbhash", "nullable": true, "type": "string" }, @@ -21813,16 +22809,19 @@ { "$ref": "#/components/schemas/AssetTypeEnum" } - ] + ], + "description": "Asset type" }, "visibility": { "allOf": [ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Asset visibility" }, "width": { + "description": "Asset width", "nullable": true, "type": "integer" } @@ -21858,36 +22857,46 @@ "$ref": "#/components/schemas/UserAvatarColor" } ], + "description": "User avatar color", "nullable": true }, "deletedAt": { + "description": "User deleted at", "format": "date-time", "nullable": true, "type": "string" }, "email": { + "description": "User email", "type": "string" }, "hasProfileImage": { + "description": "User has profile image", "type": "boolean" }, "id": { + "description": "User ID", "type": "string" }, "isAdmin": { + "description": "User is admin", "type": "boolean" }, "name": { + "description": "User name", "type": "string" }, "oauthId": { + "description": "User OAuth ID", "type": "string" }, "pinCode": { + "description": "User pin code", "nullable": true, "type": "string" }, "profileChangedAt": { + "description": "User profile changed at", "format": "date-time", "type": "string" }, @@ -21899,6 +22908,7 @@ "type": "integer" }, "storageLabel": { + "description": "User storage label", "nullable": true, "type": "string" } @@ -21925,6 +22935,7 @@ "type": "object" }, "SyncEntityType": { + "description": "Sync entity type", "enum": [ "AuthUserV1", "UserV1", @@ -21979,9 +22990,11 @@ "SyncMemoryAssetDeleteV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "memoryId": { + "description": "Memory ID", "type": "string" } }, @@ -21994,9 +23007,11 @@ "SyncMemoryAssetV1": { "properties": { "assetId": { + "description": "Asset ID", "type": "string" }, "memoryId": { + "description": "Memory ID", "type": "string" } }, @@ -22009,6 +23024,7 @@ "SyncMemoryDeleteV1": { "properties": { "memoryId": { + "description": "Memory ID", "type": "string" } }, @@ -22020,41 +23036,51 @@ "SyncMemoryV1": { "properties": { "createdAt": { + "description": "Created at", "format": "date-time", "type": "string" }, "data": { + "description": "Data", "type": "object" }, "deletedAt": { + "description": "Deleted at", "format": "date-time", "nullable": true, "type": "string" }, "hideAt": { + "description": "Hide at", "format": "date-time", "nullable": true, "type": "string" }, "id": { + "description": "Memory ID", "type": "string" }, "isSaved": { + "description": "Is saved", "type": "boolean" }, "memoryAt": { + "description": "Memory at", "format": "date-time", "type": "string" }, "ownerId": { + "description": "Owner ID", "type": "string" }, "seenAt": { + "description": "Seen at", "format": "date-time", "nullable": true, "type": "string" }, "showAt": { + "description": "Show at", "format": "date-time", "nullable": true, "type": "string" @@ -22064,9 +23090,11 @@ { "$ref": "#/components/schemas/MemoryType" } - ] + ], + "description": "Memory type" }, "updatedAt": { + "description": "Updated at", "format": "date-time", "type": "string" } @@ -22090,9 +23118,11 @@ "SyncPartnerDeleteV1": { "properties": { "sharedById": { + "description": "Shared by ID", "type": "string" }, "sharedWithId": { + "description": "Shared with ID", "type": "string" } }, @@ -22105,12 +23135,15 @@ "SyncPartnerV1": { "properties": { "inTimeline": { + "description": "In timeline", "type": "boolean" }, "sharedById": { + "description": "Shared by ID", "type": "string" }, "sharedWithId": { + "description": "Shared with ID", "type": "string" } }, @@ -22124,6 +23157,7 @@ "SyncPersonDeleteV1": { "properties": { "personId": { + "description": "Person ID", "type": "string" } }, @@ -22135,38 +23169,48 @@ "SyncPersonV1": { "properties": { "birthDate": { + "description": "Birth date", "format": "date-time", "nullable": true, "type": "string" }, "color": { + "description": "Color", "nullable": true, "type": "string" }, "createdAt": { + "description": "Created at", "format": "date-time", "type": "string" }, "faceAssetId": { + "description": "Face asset ID", "nullable": true, "type": "string" }, "id": { + "description": "Person ID", "type": "string" }, "isFavorite": { + "description": "Is favorite", "type": "boolean" }, "isHidden": { + "description": "Is hidden", "type": "boolean" }, "name": { + "description": "Person name", "type": "string" }, "ownerId": { + "description": "Owner ID", "type": "string" }, "updatedAt": { + "description": "Updated at", "format": "date-time", "type": "string" } @@ -22186,6 +23230,7 @@ "type": "object" }, "SyncRequestType": { + "description": "Sync request types", "enum": [ "AlbumsV1", "AlbumUsersV1", @@ -22217,6 +23262,7 @@ "SyncStackDeleteV1": { "properties": { "stackId": { + "description": "Stack ID", "type": "string" } }, @@ -22228,19 +23274,24 @@ "SyncStackV1": { "properties": { "createdAt": { + "description": "Created at", "format": "date-time", "type": "string" }, "id": { + "description": "Stack ID", "type": "string" }, "ownerId": { + "description": "Owner ID", "type": "string" }, "primaryAssetId": { + "description": "Primary asset ID", "type": "string" }, "updatedAt": { + "description": "Updated at", "format": "date-time", "type": "string" } @@ -22257,9 +23308,11 @@ "SyncStreamDto": { "properties": { "reset": { + "description": "Reset sync state", "type": "boolean" }, "types": { + "description": "Sync request types", "items": { "$ref": "#/components/schemas/SyncRequestType" }, @@ -22274,6 +23327,7 @@ "SyncUserDeleteV1": { "properties": { "userId": { + "description": "User ID", "type": "string" } }, @@ -22289,9 +23343,11 @@ { "$ref": "#/components/schemas/UserMetadataKey" } - ] + ], + "description": "User metadata key" }, "userId": { + "description": "User ID", "type": "string" } }, @@ -22308,12 +23364,15 @@ { "$ref": "#/components/schemas/UserMetadataKey" } - ] + ], + "description": "User metadata key" }, "userId": { + "description": "User ID", "type": "string" }, "value": { + "description": "User metadata value", "type": "object" } }, @@ -22332,26 +23391,33 @@ "$ref": "#/components/schemas/UserAvatarColor" } ], + "description": "User avatar color", "nullable": true }, "deletedAt": { + "description": "User deleted at", "format": "date-time", "nullable": true, "type": "string" }, "email": { + "description": "User email", "type": "string" }, "hasProfileImage": { + "description": "User has profile image", "type": "boolean" }, "id": { + "description": "User ID", "type": "string" }, "name": { + "description": "User name", "type": "string" }, "profileChangedAt": { + "description": "User profile changed at", "format": "date-time", "type": "string" } @@ -22476,30 +23542,36 @@ { "$ref": "#/components/schemas/TranscodeHWAccel" } - ] + ], + "description": "Transcode hardware acceleration" }, "accelDecode": { + "description": "Accelerated decode", "type": "boolean" }, "acceptedAudioCodecs": { + "description": "Accepted audio codecs", "items": { "$ref": "#/components/schemas/AudioCodec" }, "type": "array" }, "acceptedContainers": { + "description": "Accepted containers", "items": { "$ref": "#/components/schemas/VideoContainer" }, "type": "array" }, "acceptedVideoCodecs": { + "description": "Accepted video codecs", "items": { "$ref": "#/components/schemas/VideoCodec" }, "type": "array" }, "bframes": { + "description": "B-frames", "maximum": 16, "minimum": -1, "type": "integer" @@ -22509,27 +23581,34 @@ { "$ref": "#/components/schemas/CQMode" } - ] + ], + "description": "CQ mode" }, "crf": { + "description": "CRF", "maximum": 51, "minimum": 0, "type": "integer" }, "gopSize": { + "description": "GOP size", "minimum": 0, "type": "integer" }, "maxBitrate": { + "description": "Max bitrate", "type": "string" }, "preferredHwDevice": { + "description": "Preferred hardware device", "type": "string" }, "preset": { + "description": "Preset", "type": "string" }, "refs": { + "description": "References", "maximum": 6, "minimum": 0, "type": "integer" @@ -22539,9 +23618,11 @@ { "$ref": "#/components/schemas/AudioCodec" } - ] + ], + "description": "Target audio codec" }, "targetResolution": { + "description": "Target resolution", "type": "string" }, "targetVideoCodec": { @@ -22549,12 +23630,15 @@ { "$ref": "#/components/schemas/VideoCodec" } - ] + ], + "description": "Target video codec" }, "temporalAQ": { + "description": "Temporal AQ", "type": "boolean" }, "threads": { + "description": "Threads", "minimum": 0, "type": "integer" }, @@ -22563,16 +23647,19 @@ { "$ref": "#/components/schemas/ToneMapping" } - ] + ], + "description": "Tone mapping" }, "transcode": { "allOf": [ { "$ref": "#/components/schemas/TranscodePolicy" } - ] + ], + "description": "Transcode policy" }, "twoPass": { + "description": "Two pass", "type": "boolean" } }, @@ -22604,6 +23691,7 @@ "SystemConfigFacesDto": { "properties": { "import": { + "description": "Import", "type": "boolean" } }, @@ -22615,6 +23703,7 @@ "SystemConfigGeneratedFullsizeImageDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" }, "format": { @@ -22622,13 +23711,16 @@ { "$ref": "#/components/schemas/ImageFormat" } - ] + ], + "description": "Image format" }, "progressive": { "default": false, + "description": "Progressive", "type": "boolean" }, "quality": { + "description": "Quality", "maximum": 100, "minimum": 1, "type": "integer" @@ -22648,18 +23740,21 @@ { "$ref": "#/components/schemas/ImageFormat" } - ] + ], + "description": "Image format" }, "progressive": { "default": false, "type": "boolean" }, "quality": { + "description": "Quality", "maximum": 100, "minimum": 1, "type": "integer" }, "size": { + "description": "Size", "minimum": 1, "type": "integer" } @@ -22678,9 +23773,11 @@ { "$ref": "#/components/schemas/Colorspace" } - ] + ], + "description": "Colorspace" }, "extractEmbedded": { + "description": "Extract embedded", "type": "boolean" }, "fullsize": { @@ -22786,6 +23883,7 @@ "type": "string" }, "enabled": { + "description": "Enabled", "type": "boolean" } }, @@ -22798,6 +23896,7 @@ "SystemConfigLibraryWatchDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" } }, @@ -22809,6 +23908,7 @@ "SystemConfigLoggingDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" }, "level": { @@ -22837,6 +23937,7 @@ "$ref": "#/components/schemas/DuplicateDetectionConfig" }, "enabled": { + "description": "Enabled", "type": "boolean" }, "facialRecognition": { @@ -22873,6 +23974,7 @@ "type": "string" }, "enabled": { + "description": "Enabled", "type": "boolean" }, "lightStyle": { @@ -22901,6 +24003,7 @@ "SystemConfigNewVersionCheckDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" } }, @@ -22912,21 +24015,26 @@ "SystemConfigNightlyTasksDto": { "properties": { "clusterNewFaces": { + "description": "Cluster new faces", "type": "boolean" }, "databaseCleanup": { + "description": "Database cleanup", "type": "boolean" }, "generateMemories": { + "description": "Generate memories", "type": "boolean" }, "missingThumbnails": { + "description": "Missing thumbnails", "type": "boolean" }, "startTime": { "type": "string" }, "syncQuotaUsage": { + "description": "Sync quota usage", "type": "boolean" } }, @@ -22954,58 +24062,74 @@ "SystemConfigOAuthDto": { "properties": { "autoLaunch": { + "description": "Auto launch", "type": "boolean" }, "autoRegister": { + "description": "Auto register", "type": "boolean" }, "buttonText": { + "description": "Button text", "type": "string" }, "clientId": { + "description": "Client ID", "type": "string" }, "clientSecret": { + "description": "Client secret", "type": "string" }, "defaultStorageQuota": { + "description": "Default storage quota", "format": "int64", "minimum": 0, "nullable": true, "type": "integer" }, "enabled": { + "description": "Enabled", "type": "boolean" }, "issuerUrl": { + "description": "Issuer URL", "type": "string" }, "mobileOverrideEnabled": { + "description": "Mobile override enabled", "type": "boolean" }, "mobileRedirectUri": { + "description": "Mobile redirect URI", "format": "uri", "type": "string" }, "profileSigningAlgorithm": { + "description": "Profile signing algorithm", "type": "string" }, "roleClaim": { + "description": "Role claim", "type": "string" }, "scope": { + "description": "Scope", "type": "string" }, "signingAlgorithm": { "type": "string" }, "storageLabelClaim": { + "description": "Storage label claim", "type": "string" }, "storageQuotaClaim": { + "description": "Storage quota claim", "type": "string" }, "timeout": { + "description": "Timeout", "minimum": 1, "type": "integer" }, @@ -23014,7 +24138,8 @@ { "$ref": "#/components/schemas/OAuthTokenEndpointAuthMethod" } - ] + ], + "description": "Token endpoint auth method" } }, "required": [ @@ -23042,6 +24167,7 @@ "SystemConfigPasswordLoginDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" } }, @@ -23053,6 +24179,7 @@ "SystemConfigReverseGeocodingDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" } }, @@ -23064,13 +24191,16 @@ "SystemConfigServerDto": { "properties": { "externalDomain": { + "description": "External domain", "format": "uri", "type": "string" }, "loginPageMessage": { + "description": "Login page message", "type": "string" }, "publicUsers": { + "description": "Public users", "type": "boolean" } }, @@ -23084,12 +24214,15 @@ "SystemConfigSmtpDto": { "properties": { "enabled": { + "description": "Whether SMTP email notifications are enabled", "type": "boolean" }, "from": { + "description": "Email address to send from", "type": "string" }, "replyTo": { + "description": "Email address for replies", "type": "string" }, "transport": { @@ -23107,23 +24240,29 @@ "SystemConfigSmtpTransportDto": { "properties": { "host": { + "description": "SMTP server hostname", "type": "string" }, "ignoreCert": { + "description": "Whether to ignore SSL certificate errors", "type": "boolean" }, "password": { + "description": "SMTP password", "type": "string" }, "port": { + "description": "SMTP server port", "maximum": 65535, "minimum": 0, "type": "number" }, "secure": { + "description": "Whether to use secure connection (TLS/SSL)", "type": "boolean" }, "username": { + "description": "SMTP username", "type": "string" } }, @@ -23140,12 +24279,15 @@ "SystemConfigStorageTemplateDto": { "properties": { "enabled": { + "description": "Enabled", "type": "boolean" }, "hashVerificationEnabled": { + "description": "Hash verification enabled", "type": "boolean" }, "template": { + "description": "Template", "type": "string" } }, @@ -23178,48 +24320,56 @@ "SystemConfigTemplateStorageOptionDto": { "properties": { "dayOptions": { + "description": "Available day format options for storage template", "items": { "type": "string" }, "type": "array" }, "hourOptions": { + "description": "Available hour format options for storage template", "items": { "type": "string" }, "type": "array" }, "minuteOptions": { + "description": "Available minute format options for storage template", "items": { "type": "string" }, "type": "array" }, "monthOptions": { + "description": "Available month format options for storage template", "items": { "type": "string" }, "type": "array" }, "presetOptions": { + "description": "Available preset template options", "items": { "type": "string" }, "type": "array" }, "secondOptions": { + "description": "Available second format options for storage template", "items": { "type": "string" }, "type": "array" }, "weekOptions": { + "description": "Available week format options for storage template", "items": { "type": "string" }, "type": "array" }, "yearOptions": { + "description": "Available year format options for storage template", "items": { "type": "string" }, @@ -23252,6 +24402,7 @@ "SystemConfigThemeDto": { "properties": { "customCss": { + "description": "Custom CSS for theming", "type": "string" } }, @@ -23263,10 +24414,12 @@ "SystemConfigTrashDto": { "properties": { "days": { + "description": "Days", "minimum": 0, "type": "integer" }, "enabled": { + "description": "Enabled", "type": "boolean" } }, @@ -23279,6 +24432,7 @@ "SystemConfigUserDto": { "properties": { "deleteDelay": { + "description": "Delete delay", "minimum": 1, "type": "integer" } @@ -23291,6 +24445,7 @@ "TagBulkAssetsDto": { "properties": { "assetIds": { + "description": "Asset IDs", "items": { "format": "uuid", "type": "string" @@ -23298,6 +24453,7 @@ "type": "array" }, "tagIds": { + "description": "Tag IDs", "items": { "format": "uuid", "type": "string" @@ -23314,6 +24470,7 @@ "TagBulkAssetsResponseDto": { "properties": { "count": { + "description": "Number of assets tagged", "type": "integer" } }, @@ -23325,13 +24482,16 @@ "TagCreateDto": { "properties": { "color": { + "description": "Tag color (hex)", "pattern": "^#?([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$", "type": "string" }, "name": { + "description": "Tag name", "type": "string" }, "parentId": { + "description": "Parent tag ID", "format": "uuid", "nullable": true, "type": "string" @@ -23345,26 +24505,33 @@ "TagResponseDto": { "properties": { "color": { + "description": "Tag color (hex)", "type": "string" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "id": { + "description": "Tag ID", "type": "string" }, "name": { + "description": "Tag name", "type": "string" }, "parentId": { + "description": "Parent tag ID", "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" }, "value": { + "description": "Tag value (full path)", "type": "string" } }, @@ -23380,6 +24547,7 @@ "TagUpdateDto": { "properties": { "color": { + "description": "Tag color (hex)", "nullable": true, "type": "string" } @@ -23389,6 +24557,7 @@ "TagUpsertDto": { "properties": { "tags": { + "description": "Tag names to upsert", "items": { "type": "string" }, @@ -23404,10 +24573,12 @@ "properties": { "enabled": { "default": true, + "description": "Whether tags are enabled", "type": "boolean" }, "sidebarWeb": { "default": true, + "description": "Whether tags appear in web sidebar", "type": "boolean" } }, @@ -23420,9 +24591,11 @@ "TagsUpdate": { "properties": { "enabled": { + "description": "Whether tags are enabled", "type": "boolean" }, "sidebarWeb": { + "description": "Whether tags appear in web sidebar", "type": "boolean" } }, @@ -23431,6 +24604,7 @@ "TemplateDto": { "properties": { "template": { + "description": "Template name", "type": "string" } }, @@ -23442,9 +24616,11 @@ "TemplateResponseDto": { "properties": { "html": { + "description": "Template HTML content", "type": "string" }, "name": { + "description": "Template name", "type": "string" } }, @@ -23457,6 +24633,7 @@ "TestEmailResponseDto": { "properties": { "messageId": { + "description": "Email message ID", "type": "string" } }, @@ -23492,7 +24669,7 @@ "type": "array" }, "fileCreatedAt": { - "description": "Array of file creation timestamps in UTC (ISO 8601 format, without timezone)", + "description": "Array of file creation timestamps in UTC", "items": { "type": "string" }, @@ -23647,6 +24824,7 @@ "type": "object" }, "ToneMapping": { + "description": "Tone mapping", "enum": [ "hable", "mobius", @@ -23656,6 +24834,7 @@ "type": "string" }, "TranscodeHWAccel": { + "description": "Transcode hardware acceleration", "enum": [ "nvenc", "qsv", @@ -23666,6 +24845,7 @@ "type": "string" }, "TranscodePolicy": { + "description": "Transcode policy", "enum": [ "all", "optimal", @@ -23678,6 +24858,7 @@ "TrashResponseDto": { "properties": { "count": { + "description": "Number of items in trash", "type": "integer" } }, @@ -23689,16 +24870,20 @@ "UpdateAlbumDto": { "properties": { "albumName": { + "description": "Album name", "type": "string" }, "albumThumbnailAssetId": { + "description": "Album thumbnail asset ID", "format": "uuid", "type": "string" }, "description": { + "description": "Album description", "type": "string" }, "isActivityEnabled": { + "description": "Enable activity feed", "type": "boolean" }, "order": { @@ -23706,7 +24891,8 @@ { "$ref": "#/components/schemas/AssetOrder" } - ] + ], + "description": "Asset sort order" } }, "type": "object" @@ -23718,7 +24904,8 @@ { "$ref": "#/components/schemas/AlbumUserRole" } - ] + ], + "description": "Album user role" } }, "required": [ @@ -23729,26 +24916,33 @@ "UpdateAssetDto": { "properties": { "dateTimeOriginal": { + "description": "Original date and time", "type": "string" }, "description": { + "description": "Asset description", "type": "string" }, "isFavorite": { + "description": "Mark as favorite", "type": "boolean" }, "latitude": { + "description": "Latitude coordinate", "type": "number" }, "livePhotoVideoId": { + "description": "Live photo video ID", "format": "uuid", "nullable": true, "type": "string" }, "longitude": { + "description": "Longitude coordinate", "type": "number" }, "rating": { + "description": "Rating", "maximum": 5, "minimum": -1, "type": "number" @@ -23758,7 +24952,8 @@ { "$ref": "#/components/schemas/AssetVisibility" } - ] + ], + "description": "Asset visibility" } }, "type": "object" @@ -23766,6 +24961,7 @@ "UpdateLibraryDto": { "properties": { "exclusionPatterns": { + "description": "Exclusion patterns (max 128)", "items": { "type": "string" }, @@ -23774,6 +24970,7 @@ "uniqueItems": true }, "importPaths": { + "description": "Import paths (max 128)", "items": { "type": "string" }, @@ -23782,6 +24979,7 @@ "uniqueItems": true }, "name": { + "description": "Library name", "type": "string" } }, @@ -23790,32 +24988,40 @@ "UsageByUserDto": { "properties": { "photos": { + "description": "Number of photos", "type": "integer" }, "quotaSizeInBytes": { + "description": "User quota size in bytes (null if unlimited)", "format": "int64", "nullable": true, "type": "integer" }, "usage": { + "description": "Total storage usage in bytes", "format": "int64", "type": "integer" }, "usagePhotos": { + "description": "Storage usage for photos in bytes", "format": "int64", "type": "integer" }, "usageVideos": { + "description": "Storage usage for videos in bytes", "format": "int64", "type": "integer" }, "userId": { + "description": "User ID", "type": "string" }, "userName": { + "description": "User name", "type": "string" }, "videos": { + "description": "Number of videos", "type": "integer" } }, @@ -23839,34 +25045,43 @@ "$ref": "#/components/schemas/UserAvatarColor" } ], + "description": "Avatar color", "nullable": true }, "email": { + "description": "User email", "format": "email", "type": "string" }, "isAdmin": { + "description": "Grant admin privileges", "type": "boolean" }, "name": { + "description": "User name", "type": "string" }, "notify": { + "description": "Send notification email", "type": "boolean" }, "password": { + "description": "User password", "type": "string" }, "quotaSizeInBytes": { + "description": "Storage quota in bytes", "format": "int64", "minimum": 0, "nullable": true, "type": "integer" }, "shouldChangePassword": { + "description": "Require password change on next login", "type": "boolean" }, "storageLabel": { + "description": "Storage label", "nullable": true, "type": "string" } @@ -23881,6 +25096,7 @@ "UserAdminDeleteDto": { "properties": { "force": { + "description": "Force delete even if user has assets", "type": "boolean" } }, @@ -23893,24 +25109,30 @@ { "$ref": "#/components/schemas/UserAvatarColor" } - ] + ], + "description": "Avatar color" }, "createdAt": { + "description": "Creation date", "format": "date-time", "type": "string" }, "deletedAt": { + "description": "Deletion date", "format": "date-time", "nullable": true, "type": "string" }, "email": { + "description": "User email", "type": "string" }, "id": { + "description": "User ID", "type": "string" }, "isAdmin": { + "description": "Is admin user", "type": "boolean" }, "license": { @@ -23919,32 +25141,40 @@ "$ref": "#/components/schemas/UserLicense" } ], + "description": "User license", "nullable": true }, "name": { + "description": "User name", "type": "string" }, "oauthId": { + "description": "OAuth ID", "type": "string" }, "profileChangedAt": { + "description": "Profile change date", "format": "date-time", "type": "string" }, "profileImagePath": { + "description": "Profile image path", "type": "string" }, "quotaSizeInBytes": { + "description": "Storage quota in bytes", "format": "int64", "nullable": true, "type": "integer" }, "quotaUsageInBytes": { + "description": "Storage usage in bytes", "format": "int64", "nullable": true, "type": "integer" }, "shouldChangePassword": { + "description": "Require password change on next login", "type": "boolean" }, "status": { @@ -23952,13 +25182,16 @@ { "$ref": "#/components/schemas/UserStatus" } - ] + ], + "description": "User status" }, "storageLabel": { + "description": "Storage label", "nullable": true, "type": "string" }, "updatedAt": { + "description": "Last update date", "format": "date-time", "type": "string" } @@ -23992,36 +25225,45 @@ "$ref": "#/components/schemas/UserAvatarColor" } ], + "description": "Avatar color", "nullable": true }, "email": { + "description": "User email", "format": "email", "type": "string" }, "isAdmin": { + "description": "Grant admin privileges", "type": "boolean" }, "name": { + "description": "User name", "type": "string" }, "password": { + "description": "User password", "type": "string" }, "pinCode": { + "description": "PIN code", "example": "123456", "nullable": true, "type": "string" }, "quotaSizeInBytes": { + "description": "Storage quota in bytes", "format": "int64", "minimum": 0, "nullable": true, "type": "integer" }, "shouldChangePassword": { + "description": "Require password change on next login", "type": "boolean" }, "storageLabel": { + "description": "Storage label", "nullable": true, "type": "string" } @@ -24029,6 +25271,7 @@ "type": "object" }, "UserAvatarColor": { + "description": "Avatar color", "enum": [ "primary", "pink", @@ -24046,13 +25289,16 @@ "UserLicense": { "properties": { "activatedAt": { + "description": "Activation date", "format": "date-time", "type": "string" }, "activationKey": { + "description": "Activation key", "type": "string" }, "licenseKey": { + "description": "License key", "type": "string" } }, @@ -24064,6 +25310,7 @@ "type": "object" }, "UserMetadataKey": { + "description": "User metadata key", "enum": [ "preferences", "license", @@ -24170,22 +25417,28 @@ { "$ref": "#/components/schemas/UserAvatarColor" } - ] + ], + "description": "Avatar color" }, "email": { + "description": "User email", "type": "string" }, "id": { + "description": "User ID", "type": "string" }, "name": { + "description": "User name", "type": "string" }, "profileChangedAt": { + "description": "Profile change date", "format": "date-time", "type": "string" }, "profileImagePath": { + "description": "Profile image path", "type": "string" } }, @@ -24200,6 +25453,7 @@ "type": "object" }, "UserStatus": { + "description": "User status", "enum": [ "active", "removing", @@ -24215,16 +25469,20 @@ "$ref": "#/components/schemas/UserAvatarColor" } ], + "description": "Avatar color", "nullable": true }, "email": { + "description": "User email", "format": "email", "type": "string" }, "name": { + "description": "User name", "type": "string" }, "password": { + "description": "User password (deprecated, use change password endpoint)", "type": "string" } }, @@ -24233,6 +25491,7 @@ "ValidateAccessTokenResponseDto": { "properties": { "authStatus": { + "description": "Authentication status", "type": "boolean" } }, @@ -24244,6 +25503,7 @@ "ValidateLibraryDto": { "properties": { "exclusionPatterns": { + "description": "Exclusion patterns (max 128)", "items": { "type": "string" }, @@ -24252,6 +25512,7 @@ "uniqueItems": true }, "importPaths": { + "description": "Import paths to validate (max 128)", "items": { "type": "string" }, @@ -24265,13 +25526,16 @@ "ValidateLibraryImportPathResponseDto": { "properties": { "importPath": { + "description": "Import path", "type": "string" }, "isValid": { "default": false, + "description": "Is valid", "type": "boolean" }, "message": { + "description": "Validation message", "type": "string" } }, @@ -24284,6 +25548,7 @@ "ValidateLibraryResponseDto": { "properties": { "importPaths": { + "description": "Validation results for import paths", "items": { "$ref": "#/components/schemas/ValidateLibraryImportPathResponseDto" }, @@ -24295,10 +25560,12 @@ "VersionCheckStateResponseDto": { "properties": { "checkedAt": { + "description": "Last check timestamp", "nullable": true, "type": "string" }, "releaseVersion": { + "description": "Release version", "nullable": true, "type": "string" } @@ -24310,6 +25577,7 @@ "type": "object" }, "VideoCodec": { + "description": "Target video codec", "enum": [ "h264", "hevc", @@ -24319,6 +25587,7 @@ "type": "string" }, "VideoContainer": { + "description": "Accepted containers", "enum": [ "mov", "mp4", @@ -24330,9 +25599,11 @@ "WorkflowActionItemDto": { "properties": { "actionConfig": { + "description": "Action configuration", "type": "object" }, "pluginActionId": { + "description": "Plugin action ID", "format": "uuid", "type": "string" } @@ -24345,19 +25616,24 @@ "WorkflowActionResponseDto": { "properties": { "actionConfig": { + "description": "Action configuration", "nullable": true, "type": "object" }, "id": { + "description": "Action ID", "type": "string" }, "order": { + "description": "Action order", "type": "number" }, "pluginActionId": { + "description": "Plugin action ID", "type": "string" }, "workflowId": { + "description": "Workflow ID", "type": "string" } }, @@ -24373,24 +25649,29 @@ "WorkflowCreateDto": { "properties": { "actions": { + "description": "Workflow actions", "items": { "$ref": "#/components/schemas/WorkflowActionItemDto" }, "type": "array" }, "description": { + "description": "Workflow description", "type": "string" }, "enabled": { + "description": "Workflow enabled", "type": "boolean" }, "filters": { + "description": "Workflow filters", "items": { "$ref": "#/components/schemas/WorkflowFilterItemDto" }, "type": "array" }, "name": { + "description": "Workflow name", "type": "string" }, "triggerType": { @@ -24398,7 +25679,8 @@ { "$ref": "#/components/schemas/PluginTriggerType" } - ] + ], + "description": "Workflow trigger type" } }, "required": [ @@ -24412,9 +25694,11 @@ "WorkflowFilterItemDto": { "properties": { "filterConfig": { + "description": "Filter configuration", "type": "object" }, "pluginFilterId": { + "description": "Plugin filter ID", "format": "uuid", "type": "string" } @@ -24427,19 +25711,24 @@ "WorkflowFilterResponseDto": { "properties": { "filterConfig": { + "description": "Filter configuration", "nullable": true, "type": "object" }, "id": { + "description": "Filter ID", "type": "string" }, "order": { + "description": "Filter order", "type": "number" }, "pluginFilterId": { + "description": "Plugin filter ID", "type": "string" }, "workflowId": { + "description": "Workflow ID", "type": "string" } }, @@ -24455,34 +25744,42 @@ "WorkflowResponseDto": { "properties": { "actions": { + "description": "Workflow actions", "items": { "$ref": "#/components/schemas/WorkflowActionResponseDto" }, "type": "array" }, "createdAt": { + "description": "Creation date", "type": "string" }, "description": { + "description": "Workflow description", "type": "string" }, "enabled": { + "description": "Workflow enabled", "type": "boolean" }, "filters": { + "description": "Workflow filters", "items": { "$ref": "#/components/schemas/WorkflowFilterResponseDto" }, "type": "array" }, "id": { + "description": "Workflow ID", "type": "string" }, "name": { + "description": "Workflow name", "nullable": true, "type": "string" }, "ownerId": { + "description": "Owner user ID", "type": "string" }, "triggerType": { @@ -24490,7 +25787,8 @@ { "$ref": "#/components/schemas/PluginTriggerType" } - ] + ], + "description": "Workflow trigger type" } }, "required": [ @@ -24509,24 +25807,29 @@ "WorkflowUpdateDto": { "properties": { "actions": { + "description": "Workflow actions", "items": { "$ref": "#/components/schemas/WorkflowActionItemDto" }, "type": "array" }, "description": { + "description": "Workflow description", "type": "string" }, "enabled": { + "description": "Workflow enabled", "type": "boolean" }, "filters": { + "description": "Workflow filters", "items": { "$ref": "#/components/schemas/WorkflowFilterItemDto" }, "type": "array" }, "name": { + "description": "Workflow name", "type": "string" }, "triggerType": { @@ -24534,7 +25837,8 @@ { "$ref": "#/components/schemas/PluginTriggerType" } - ] + ], + "description": "Workflow trigger type" } }, "type": "object" diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index 346d96bdf3632..dda10568bbb78 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -15,29 +15,46 @@ export const servers = { server1: "/api" }; export type UserResponseDto = { + /** Avatar color */ avatarColor: UserAvatarColor; + /** User email */ email: string; + /** User ID */ id: string; + /** User name */ name: string; + /** Profile change date */ profileChangedAt: string; + /** Profile image path */ profileImagePath: string; }; export type ActivityResponseDto = { + /** Asset ID (if activity is for an asset) */ assetId: string | null; + /** Comment text (for comment activities) */ comment?: string | null; + /** Creation date */ createdAt: string; + /** Activity ID */ id: string; + /** Activity type */ "type": ReactionType; user: UserResponseDto; }; export type ActivityCreateDto = { + /** Album ID */ albumId: string; + /** Asset ID (if activity is for an asset) */ assetId?: string; + /** Comment text (required if type is comment) */ comment?: string; + /** Activity type (like or comment) */ "type": ReactionType; }; export type ActivityStatisticsResponseDto = { + /** Number of comments */ comments: number; + /** Number of likes */ likes: number; }; export type DatabaseBackupDeleteDto = { @@ -54,25 +71,34 @@ export type DatabaseBackupUploadDto = { file?: Blob; }; export type SetMaintenanceModeDto = { + /** Maintenance action */ action: MaintenanceAction; + /** Restore backup filename */ restoreBackupFilename?: string; }; export type MaintenanceDetectInstallStorageFolderDto = { + /** Number of files in the folder */ files: number; + /** Storage folder */ folder: StorageFolder; + /** Whether the folder is readable */ readable: boolean; + /** Whether the folder is writable */ writable: boolean; }; export type MaintenanceDetectInstallResponseDto = { storage: MaintenanceDetectInstallStorageFolderDto[]; }; export type MaintenanceLoginDto = { + /** Maintenance token */ token?: string; }; export type MaintenanceAuthDto = { + /** Maintenance username */ username: string; }; export type MaintenanceStatusResponseDto = { + /** Maintenance action */ action: MaintenanceAction; active: boolean; error?: string; @@ -80,137 +106,224 @@ export type MaintenanceStatusResponseDto = { task?: string; }; export type NotificationCreateDto = { + /** Additional notification data */ data?: object; + /** Notification description */ description?: string | null; + /** Notification level */ level?: NotificationLevel; + /** Date when notification was read */ readAt?: string | null; + /** Notification title */ title: string; + /** Notification type */ "type"?: NotificationType; + /** User ID to send notification to */ userId: string; }; export type NotificationDto = { + /** Creation date */ createdAt: string; + /** Additional notification data */ data?: object; + /** Notification description */ description?: string; + /** Notification ID */ id: string; + /** Notification level */ level: NotificationLevel; + /** Date when notification was read */ readAt?: string; + /** Notification title */ title: string; + /** Notification type */ "type": NotificationType; }; export type TemplateDto = { + /** Template name */ template: string; }; export type TemplateResponseDto = { + /** Template HTML content */ html: string; + /** Template name */ name: string; }; export type SystemConfigSmtpTransportDto = { + /** SMTP server hostname */ host: string; + /** Whether to ignore SSL certificate errors */ ignoreCert: boolean; + /** SMTP password */ password: string; + /** SMTP server port */ port: number; + /** Whether to use secure connection (TLS/SSL) */ secure: boolean; + /** SMTP username */ username: string; }; export type SystemConfigSmtpDto = { + /** Whether SMTP email notifications are enabled */ enabled: boolean; + /** Email address to send from */ "from": string; + /** Email address for replies */ replyTo: string; transport: SystemConfigSmtpTransportDto; }; export type TestEmailResponseDto = { + /** Email message ID */ messageId: string; }; export type UserLicense = { + /** Activation date */ activatedAt: string; + /** Activation key */ activationKey: string; + /** License key */ licenseKey: string; }; export type UserAdminResponseDto = { + /** Avatar color */ avatarColor: UserAvatarColor; + /** Creation date */ createdAt: string; + /** Deletion date */ deletedAt: string | null; + /** User email */ email: string; + /** User ID */ id: string; + /** Is admin user */ isAdmin: boolean; + /** User license */ license: (UserLicense) | null; + /** User name */ name: string; + /** OAuth ID */ oauthId: string; + /** Profile change date */ profileChangedAt: string; + /** Profile image path */ profileImagePath: string; + /** Storage quota in bytes */ quotaSizeInBytes: number | null; + /** Storage usage in bytes */ quotaUsageInBytes: number | null; + /** Require password change on next login */ shouldChangePassword: boolean; + /** User status */ status: UserStatus; + /** Storage label */ storageLabel: string | null; + /** Last update date */ updatedAt: string; }; export type UserAdminCreateDto = { + /** Avatar color */ avatarColor?: (UserAvatarColor) | null; + /** User email */ email: string; + /** Grant admin privileges */ isAdmin?: boolean; + /** User name */ name: string; + /** Send notification email */ notify?: boolean; + /** User password */ password: string; + /** Storage quota in bytes */ quotaSizeInBytes?: number | null; + /** Require password change on next login */ shouldChangePassword?: boolean; + /** Storage label */ storageLabel?: string | null; }; export type UserAdminDeleteDto = { + /** Force delete even if user has assets */ force?: boolean; }; export type UserAdminUpdateDto = { + /** Avatar color */ avatarColor?: (UserAvatarColor) | null; + /** User email */ email?: string; + /** Grant admin privileges */ isAdmin?: boolean; + /** User name */ name?: string; + /** User password */ password?: string; + /** PIN code */ pinCode?: string | null; + /** Storage quota in bytes */ quotaSizeInBytes?: number | null; + /** Require password change on next login */ shouldChangePassword?: boolean; + /** Storage label */ storageLabel?: string | null; }; export type AlbumsResponse = { + /** Default asset order for albums */ defaultAssetOrder: AssetOrder; }; export type CastResponse = { + /** Whether Google Cast is enabled */ gCastEnabled: boolean; }; export type DownloadResponse = { + /** Maximum archive size in bytes */ archiveSize: number; + /** Whether to include embedded videos in downloads */ includeEmbeddedVideos: boolean; }; export type EmailNotificationsResponse = { + /** Whether to receive email notifications for album invites */ albumInvite: boolean; + /** Whether to receive email notifications for album updates */ albumUpdate: boolean; + /** Whether email notifications are enabled */ enabled: boolean; }; export type FoldersResponse = { + /** Whether folders are enabled */ enabled: boolean; + /** Whether folders appear in web sidebar */ sidebarWeb: boolean; }; export type MemoriesResponse = { + /** Memory duration in seconds */ duration: number; + /** Whether memories are enabled */ enabled: boolean; }; export type PeopleResponse = { + /** Whether people are enabled */ enabled: boolean; + /** Whether people appear in web sidebar */ sidebarWeb: boolean; }; export type PurchaseResponse = { + /** Date until which to hide buy button */ hideBuyButtonUntil: string; + /** Whether to show support badge */ showSupportBadge: boolean; }; export type RatingsResponse = { + /** Whether ratings are enabled */ enabled: boolean; }; export type SharedLinksResponse = { + /** Whether shared links are enabled */ enabled: boolean; + /** Whether shared links appear in web sidebar */ sidebarWeb: boolean; }; export type TagsResponse = { + /** Whether tags are enabled */ enabled: boolean; + /** Whether tags appear in web sidebar */ sidebarWeb: boolean; }; export type UserPreferencesResponseDto = { @@ -227,48 +340,69 @@ export type UserPreferencesResponseDto = { tags: TagsResponse; }; export type AlbumsUpdate = { + /** Default asset order for albums */ defaultAssetOrder?: AssetOrder; }; export type AvatarUpdate = { + /** Avatar color */ color?: UserAvatarColor; }; export type CastUpdate = { + /** Whether Google Cast is enabled */ gCastEnabled?: boolean; }; export type DownloadUpdate = { + /** Maximum archive size in bytes */ archiveSize?: number; + /** Whether to include embedded videos in downloads */ includeEmbeddedVideos?: boolean; }; export type EmailNotificationsUpdate = { + /** Whether to receive email notifications for album invites */ albumInvite?: boolean; + /** Whether to receive email notifications for album updates */ albumUpdate?: boolean; + /** Whether email notifications are enabled */ enabled?: boolean; }; export type FoldersUpdate = { + /** Whether folders are enabled */ enabled?: boolean; + /** Whether folders appear in web sidebar */ sidebarWeb?: boolean; }; export type MemoriesUpdate = { + /** Memory duration in seconds */ duration?: number; + /** Whether memories are enabled */ enabled?: boolean; }; export type PeopleUpdate = { + /** Whether people are enabled */ enabled?: boolean; + /** Whether people appear in web sidebar */ sidebarWeb?: boolean; }; export type PurchaseUpdate = { + /** Date until which to hide buy button */ hideBuyButtonUntil?: string; + /** Whether to show support badge */ showSupportBadge?: boolean; }; export type RatingsUpdate = { + /** Whether ratings are enabled */ enabled?: boolean; }; export type SharedLinksUpdate = { + /** Whether shared links are enabled */ enabled?: boolean; + /** Whether shared links appear in web sidebar */ sidebarWeb?: boolean; }; export type TagsUpdate = { + /** Whether tags are enabled */ enabled?: boolean; + /** Whether tags appear in web sidebar */ sidebarWeb?: boolean; }; export type UserPreferencesUpdateDto = { @@ -286,325 +420,531 @@ export type UserPreferencesUpdateDto = { tags?: TagsUpdate; }; export type SessionResponseDto = { + /** App version */ appVersion: string | null; + /** Creation date */ createdAt: string; + /** Is current session */ current: boolean; + /** Device OS */ deviceOS: string; + /** Device type */ deviceType: string; + /** Expiration date */ expiresAt?: string; + /** Session ID */ id: string; + /** Is pending sync reset */ isPendingSyncReset: boolean; + /** Last update date */ updatedAt: string; }; export type AssetStatsResponseDto = { + /** Number of images */ images: number; + /** Total number of assets */ total: number; + /** Number of videos */ videos: number; }; export type AlbumUserResponseDto = { + /** Album user role */ role: AlbumUserRole; user: UserResponseDto; }; export type ExifResponseDto = { + /** City name */ city?: string | null; + /** Country name */ country?: string | null; + /** Original date/time */ dateTimeOriginal?: string | null; + /** Image description */ description?: string | null; + /** Image height in pixels */ exifImageHeight?: number | null; + /** Image width in pixels */ exifImageWidth?: number | null; + /** Exposure time */ exposureTime?: string | null; + /** F-number (aperture) */ fNumber?: number | null; + /** File size in bytes */ fileSizeInByte?: number | null; + /** Focal length in mm */ focalLength?: number | null; + /** ISO sensitivity */ iso?: number | null; + /** GPS latitude */ latitude?: number | null; + /** Lens model */ lensModel?: string | null; + /** GPS longitude */ longitude?: number | null; + /** Camera make */ make?: string | null; + /** Camera model */ model?: string | null; + /** Modification date/time */ modifyDate?: string | null; + /** Image orientation */ orientation?: string | null; + /** Projection type */ projectionType?: string | null; + /** Rating */ rating?: number | null; + /** State/province name */ state?: string | null; + /** Time zone */ timeZone?: string | null; }; export type AssetFaceWithoutPersonResponseDto = { + /** Bounding box X1 coordinate */ boundingBoxX1: number; + /** Bounding box X2 coordinate */ boundingBoxX2: number; + /** Bounding box Y1 coordinate */ boundingBoxY1: number; + /** Bounding box Y2 coordinate */ boundingBoxY2: number; + /** Face ID */ id: string; + /** Image height in pixels */ imageHeight: number; + /** Image width in pixels */ imageWidth: number; + /** Face detection source type */ sourceType?: SourceType; }; export type PersonWithFacesResponseDto = { + /** Person date of birth */ birthDate: string | null; + /** Person color (hex) */ color?: string; + /** Face detections */ faces: AssetFaceWithoutPersonResponseDto[]; + /** Person ID */ id: string; + /** Is favorite */ isFavorite?: boolean; + /** Is hidden */ isHidden: boolean; + /** Person name */ name: string; + /** Thumbnail path */ thumbnailPath: string; + /** Last update date */ updatedAt?: string; }; export type AssetStackResponseDto = { + /** Number of assets in stack */ assetCount: number; + /** Stack ID */ id: string; + /** Primary asset ID */ primaryAssetId: string; }; export type TagResponseDto = { + /** Tag color (hex) */ color?: string; + /** Creation date */ createdAt: string; + /** Tag ID */ id: string; + /** Tag name */ name: string; + /** Parent tag ID */ parentId?: string; + /** Last update date */ updatedAt: string; + /** Tag value (full path) */ value: string; }; export type AssetResponseDto = { - /** base64 encoded sha1 hash */ + /** Base64 encoded SHA1 hash */ checksum: string; /** The UTC timestamp when the asset was originally uploaded to Immich. */ createdAt: string; + /** Device asset ID */ deviceAssetId: string; + /** Device ID */ deviceId: string; + /** Duplicate group ID */ duplicateId?: string | null; + /** Video duration (for videos) */ duration: string; exifInfo?: ExifResponseDto; /** The actual UTC timestamp when the file was created/captured, preserving timezone information. This is the authoritative timestamp for chronological sorting within timeline groups. Combined with timezone data, this can be used to determine the exact moment the photo was taken. */ fileCreatedAt: string; /** The UTC timestamp when the file was last modified on the filesystem. This reflects the last time the physical file was changed, which may be different from when the photo was originally taken. */ fileModifiedAt: string; + /** Whether asset has metadata */ hasMetadata: boolean; + /** Asset height */ height: number | null; + /** Asset ID */ id: string; + /** Is archived */ isArchived: boolean; + /** Is edited */ isEdited: boolean; + /** Is favorite */ isFavorite: boolean; + /** Is offline */ isOffline: boolean; + /** Is trashed */ isTrashed: boolean; + /** Library ID */ libraryId?: string | null; + /** Live photo video ID */ livePhotoVideoId?: string | null; /** The local date and time when the photo/video was taken, derived from EXIF metadata. This represents the photographer's local time regardless of timezone, stored as a timezone-agnostic timestamp. Used for timeline grouping by "local" days and months. */ localDateTime: string; + /** Original file name */ originalFileName: string; + /** Original MIME type */ originalMimeType?: string; + /** Original file path */ originalPath: string; owner?: UserResponseDto; + /** Owner user ID */ ownerId: string; people?: PersonWithFacesResponseDto[]; + /** Is resized */ resized?: boolean; stack?: (AssetStackResponseDto) | null; tags?: TagResponseDto[]; + /** Thumbhash for thumbnail generation */ thumbhash: string | null; + /** Asset type */ "type": AssetTypeEnum; unassignedFaces?: AssetFaceWithoutPersonResponseDto[]; /** The UTC timestamp when the asset record was last updated in the database. This is automatically maintained by the database and reflects when any field in the asset was last modified. */ updatedAt: string; + /** Asset visibility */ visibility: AssetVisibility; + /** Asset width */ width: number | null; }; export type ContributorCountResponseDto = { + /** Number of assets contributed */ assetCount: number; + /** User ID */ userId: string; }; export type AlbumResponseDto = { + /** Album name */ albumName: string; + /** Thumbnail asset ID */ albumThumbnailAssetId: string | null; albumUsers: AlbumUserResponseDto[]; + /** Number of assets */ assetCount: number; assets: AssetResponseDto[]; contributorCounts?: ContributorCountResponseDto[]; + /** Creation date */ createdAt: string; + /** Album description */ description: string; + /** End date (latest asset) */ endDate?: string; + /** Has shared link */ hasSharedLink: boolean; + /** Album ID */ id: string; + /** Activity feed enabled */ isActivityEnabled: boolean; + /** Last modified asset timestamp */ lastModifiedAssetTimestamp?: string; + /** Asset sort order */ order?: AssetOrder; owner: UserResponseDto; + /** Owner user ID */ ownerId: string; + /** Is shared album */ shared: boolean; + /** Start date (earliest asset) */ startDate?: string; + /** Last update date */ updatedAt: string; }; export type AlbumUserCreateDto = { + /** Album user role */ role: AlbumUserRole; + /** User ID */ userId: string; }; export type CreateAlbumDto = { + /** Album name */ albumName: string; + /** Album users */ albumUsers?: AlbumUserCreateDto[]; + /** Initial asset IDs */ assetIds?: string[]; + /** Album description */ description?: string; }; export type AlbumsAddAssetsDto = { + /** Album IDs */ albumIds: string[]; + /** Asset IDs */ assetIds: string[]; }; export type AlbumsAddAssetsResponseDto = { + /** Error reason */ error?: BulkIdErrorReason; + /** Operation success */ success: boolean; }; export type AlbumStatisticsResponseDto = { + /** Number of non-shared albums */ notShared: number; + /** Number of owned albums */ owned: number; + /** Number of shared albums */ shared: number; }; export type UpdateAlbumDto = { + /** Album name */ albumName?: string; + /** Album thumbnail asset ID */ albumThumbnailAssetId?: string; + /** Album description */ description?: string; + /** Enable activity feed */ isActivityEnabled?: boolean; + /** Asset sort order */ order?: AssetOrder; }; export type BulkIdsDto = { + /** IDs to process */ ids: string[]; }; export type BulkIdResponseDto = { + /** Error reason if failed */ error?: Error; + /** ID */ id: string; + /** Whether operation succeeded */ success: boolean; }; export type UpdateAlbumUserDto = { + /** Album user role */ role: AlbumUserRole; }; export type AlbumUserAddDto = { + /** Album user role */ role?: AlbumUserRole; + /** User ID */ userId: string; }; export type AddUsersDto = { + /** Album users to add */ albumUsers: AlbumUserAddDto[]; }; export type ApiKeyResponseDto = { + /** Creation date */ createdAt: string; + /** API key ID */ id: string; + /** API key name */ name: string; + /** List of permissions */ permissions: Permission[]; + /** Last update date */ updatedAt: string; }; export type ApiKeyCreateDto = { + /** API key name */ name?: string; + /** List of permissions */ permissions: Permission[]; }; export type ApiKeyCreateResponseDto = { apiKey: ApiKeyResponseDto; + /** API key secret (only shown once) */ secret: string; }; export type ApiKeyUpdateDto = { + /** API key name */ name?: string; + /** List of permissions */ permissions?: Permission[]; }; export type AssetBulkDeleteDto = { + /** Force delete even if in use */ force?: boolean; + /** IDs to process */ ids: string[]; }; export type AssetMetadataUpsertItemDto = { + /** Metadata key */ key: string; + /** Metadata value (object) */ value: object; }; export type AssetMediaCreateDto = { + /** Asset file data */ assetData: Blob; + /** Device asset ID */ deviceAssetId: string; + /** Device ID */ deviceId: string; + /** Duration (for videos) */ duration?: string; + /** File creation date */ fileCreatedAt: string; + /** File modification date */ fileModifiedAt: string; + /** Filename */ filename?: string; + /** Mark as favorite */ isFavorite?: boolean; + /** Live photo video ID */ livePhotoVideoId?: string; + /** Asset metadata items */ metadata?: AssetMetadataUpsertItemDto[]; + /** Sidecar file data */ sidecarData?: Blob; + /** Asset visibility */ visibility?: AssetVisibility; }; export type AssetMediaResponseDto = { + /** Asset media ID */ id: string; + /** Upload status */ status: AssetMediaStatus; }; export type AssetBulkUpdateDto = { + /** Original date and time */ dateTimeOriginal?: string; + /** Relative time offset in seconds */ dateTimeRelative?: number; + /** Asset description */ description?: string; + /** Duplicate asset ID */ duplicateId?: string | null; + /** Asset IDs to update */ ids: string[]; + /** Mark as favorite */ isFavorite?: boolean; + /** Latitude coordinate */ latitude?: number; + /** Longitude coordinate */ longitude?: number; + /** Rating */ rating?: number; + /** Time zone (IANA timezone) */ timeZone?: string; + /** Asset visibility */ visibility?: AssetVisibility; }; export type AssetBulkUploadCheckItem = { - /** base64 or hex encoded sha1 hash */ + /** Base64 or hex encoded SHA1 hash */ checksum: string; + /** Asset ID */ id: string; }; export type AssetBulkUploadCheckDto = { + /** Assets to check */ assets: AssetBulkUploadCheckItem[]; }; export type AssetBulkUploadCheckResult = { + /** Upload action */ action: Action; + /** Existing asset ID if duplicate */ assetId?: string; + /** Asset ID */ id: string; + /** Whether existing asset is trashed */ isTrashed?: boolean; + /** Rejection reason if rejected */ reason?: Reason; }; export type AssetBulkUploadCheckResponseDto = { + /** Upload check results */ results: AssetBulkUploadCheckResult[]; }; export type AssetCopyDto = { + /** Copy album associations */ albums?: boolean; + /** Copy favorite status */ favorite?: boolean; + /** Copy shared links */ sharedLinks?: boolean; + /** Copy sidecar file */ sidecar?: boolean; + /** Source asset ID */ sourceId: string; + /** Copy stack association */ stack?: boolean; + /** Target asset ID */ targetId: string; }; export type CheckExistingAssetsDto = { + /** Device asset IDs to check */ deviceAssetIds: string[]; + /** Device ID */ deviceId: string; }; export type CheckExistingAssetsResponseDto = { + /** Existing asset IDs */ existingIds: string[]; }; export type AssetJobsDto = { + /** Asset IDs */ assetIds: string[]; + /** Job name */ name: AssetJobName; }; export type AssetMetadataBulkDeleteItemDto = { + /** Asset ID */ assetId: string; + /** Metadata key */ key: string; }; export type AssetMetadataBulkDeleteDto = { + /** Metadata items to delete */ items: AssetMetadataBulkDeleteItemDto[]; }; export type AssetMetadataBulkUpsertItemDto = { + /** Asset ID */ assetId: string; + /** Metadata key */ key: string; + /** Metadata value (object) */ value: object; }; export type AssetMetadataBulkUpsertDto = { + /** Metadata items to upsert */ items: AssetMetadataBulkUpsertItemDto[]; }; export type AssetMetadataBulkResponseDto = { + /** Asset ID */ assetId: string; + /** Metadata key */ key: string; + /** Last update date */ updatedAt: string; + /** Metadata value (object) */ value: object; }; export type UpdateAssetDto = { + /** Original date and time */ dateTimeOriginal?: string; + /** Asset description */ description?: string; + /** Mark as favorite */ isFavorite?: boolean; + /** Latitude coordinate */ latitude?: number; + /** Live photo video ID */ livePhotoVideoId?: string | null; + /** Longitude coordinate */ longitude?: number; + /** Rating */ rating?: number; + /** Asset visibility */ visibility?: AssetVisibility; }; export type CropParameters = { @@ -618,6 +958,7 @@ export type CropParameters = { y: number; }; export type AssetEditActionCrop = { + /** Type of edit action to perform */ action: AssetEditAction; parameters: CropParameters; }; @@ -626,6 +967,7 @@ export type RotateParameters = { angle: number; }; export type AssetEditActionRotate = { + /** Type of edit action to perform */ action: AssetEditAction; parameters: RotateParameters; }; @@ -634,24 +976,30 @@ export type MirrorParameters = { axis: MirrorAxis; }; export type AssetEditActionMirror = { + /** Type of edit action to perform */ action: AssetEditAction; parameters: MirrorParameters; }; export type AssetEditsDto = { + /** Asset ID to apply edits to */ assetId: string; - /** list of edits */ + /** List of edit actions to apply (crop, rotate, or mirror) */ edits: (AssetEditActionCrop | AssetEditActionRotate | AssetEditActionMirror)[]; }; export type AssetEditActionListDto = { - /** list of edits */ + /** List of edit actions to apply (crop, rotate, or mirror) */ edits: (AssetEditActionCrop | AssetEditActionRotate | AssetEditActionMirror)[]; }; export type AssetMetadataResponseDto = { + /** Metadata key */ key: string; + /** Last update date */ updatedAt: string; + /** Metadata value (object) */ value: object; }; export type AssetMetadataUpsertDto = { + /** Metadata items to upsert */ items: AssetMetadataUpsertItemDto[]; }; export type AssetOcrResponseDto = { @@ -681,136 +1029,221 @@ export type AssetOcrResponseDto = { y4: number; }; export type AssetMediaReplaceDto = { + /** Asset file data */ assetData: Blob; + /** Device asset ID */ deviceAssetId: string; + /** Device ID */ deviceId: string; + /** Duration (for videos) */ duration?: string; + /** File creation date */ fileCreatedAt: string; + /** File modification date */ fileModifiedAt: string; + /** Filename */ filename?: string; }; export type SignUpDto = { + /** User email */ email: string; + /** User name */ name: string; + /** User password */ password: string; }; export type ChangePasswordDto = { + /** Invalidate all other sessions */ invalidateSessions?: boolean; + /** New password (min 8 characters) */ newPassword: string; + /** Current password */ password: string; }; export type LoginCredentialDto = { + /** User email */ email: string; + /** User password */ password: string; }; export type LoginResponseDto = { + /** Access token */ accessToken: string; + /** Is admin user */ isAdmin: boolean; + /** Is onboarded */ isOnboarded: boolean; + /** User name */ name: string; + /** Profile image path */ profileImagePath: string; + /** Should change password */ shouldChangePassword: boolean; + /** User email */ userEmail: string; + /** User ID */ userId: string; }; export type LogoutResponseDto = { + /** Redirect URI */ redirectUri: string; + /** Logout successful */ successful: boolean; }; export type PinCodeResetDto = { + /** User password (required if PIN code is not provided) */ password?: string; + /** New PIN code (4-6 digits) */ pinCode?: string; }; export type PinCodeSetupDto = { + /** PIN code (4-6 digits) */ pinCode: string; }; export type PinCodeChangeDto = { + /** New PIN code (4-6 digits) */ newPinCode: string; + /** User password (required if PIN code is not provided) */ password?: string; + /** New PIN code (4-6 digits) */ pinCode?: string; }; export type SessionUnlockDto = { + /** User password (required if PIN code is not provided) */ password?: string; + /** New PIN code (4-6 digits) */ pinCode?: string; }; export type AuthStatusResponseDto = { + /** Session expiration date */ expiresAt?: string; + /** Is elevated session */ isElevated: boolean; + /** Has password set */ password: boolean; + /** Has PIN code set */ pinCode: boolean; + /** PIN expiration date */ pinExpiresAt?: string; }; export type ValidateAccessTokenResponseDto = { + /** Authentication status */ authStatus: boolean; }; export type AssetIdsDto = { + /** Asset IDs */ assetIds: string[]; }; export type DownloadInfoDto = { + /** Album ID to download */ albumId?: string; + /** Archive size limit in bytes */ archiveSize?: number; + /** Asset IDs to download */ assetIds?: string[]; + /** User ID to download assets from */ userId?: string; }; export type DownloadArchiveInfo = { + /** Asset IDs in this archive */ assetIds: string[]; + /** Archive size in bytes */ size: number; }; export type DownloadResponseDto = { + /** Archive information */ archives: DownloadArchiveInfo[]; + /** Total size in bytes */ totalSize: number; }; export type DuplicateResponseDto = { + /** Duplicate assets */ assets: AssetResponseDto[]; + /** Duplicate group ID */ duplicateId: string; }; export type PersonResponseDto = { + /** Person date of birth */ birthDate: string | null; + /** Person color (hex) */ color?: string; + /** Person ID */ id: string; + /** Is favorite */ isFavorite?: boolean; + /** Is hidden */ isHidden: boolean; + /** Person name */ name: string; + /** Thumbnail path */ thumbnailPath: string; + /** Last update date */ updatedAt?: string; }; export type AssetFaceResponseDto = { + /** Bounding box X1 coordinate */ boundingBoxX1: number; + /** Bounding box X2 coordinate */ boundingBoxX2: number; + /** Bounding box Y1 coordinate */ boundingBoxY1: number; + /** Bounding box Y2 coordinate */ boundingBoxY2: number; + /** Face ID */ id: string; + /** Image height in pixels */ imageHeight: number; + /** Image width in pixels */ imageWidth: number; + /** Person associated with face */ person: (PersonResponseDto) | null; + /** Face detection source type */ sourceType?: SourceType; }; export type AssetFaceCreateDto = { + /** Asset ID */ assetId: string; + /** Face bounding box height */ height: number; + /** Image height in pixels */ imageHeight: number; + /** Image width in pixels */ imageWidth: number; + /** Person ID */ personId: string; + /** Face bounding box width */ width: number; + /** Face bounding box X coordinate */ x: number; + /** Face bounding box Y coordinate */ y: number; }; export type AssetFaceDeleteDto = { + /** Force delete even if person has other faces */ force: boolean; }; export type FaceDto = { + /** Face ID */ id: string; }; export type QueueStatisticsDto = { + /** Number of active jobs */ active: number; + /** Number of completed jobs */ completed: number; + /** Number of delayed jobs */ delayed: number; + /** Number of failed jobs */ failed: number; + /** Number of paused jobs */ paused: number; + /** Number of waiting jobs */ waiting: number; }; export type QueueStatusLegacyDto = { + /** Whether the queue is currently active (has running jobs) */ isActive: boolean; + /** Whether the queue is paused */ isPaused: boolean; }; export type QueueResponseLegacyDto = { @@ -838,238 +1271,359 @@ export type QueuesResponseLegacyDto = { workflow: QueueResponseLegacyDto; }; export type JobCreateDto = { + /** Job name */ name: ManualJobName; }; export type QueueCommandDto = { + /** Queue command to execute */ command: QueueCommand; + /** Force the command execution (if applicable) */ force?: boolean; }; export type LibraryResponseDto = { + /** Number of assets */ assetCount: number; + /** Creation date */ createdAt: string; + /** Exclusion patterns */ exclusionPatterns: string[]; + /** Library ID */ id: string; + /** Import paths */ importPaths: string[]; + /** Library name */ name: string; + /** Owner user ID */ ownerId: string; + /** Last refresh date */ refreshedAt: string | null; + /** Last update date */ updatedAt: string; }; export type CreateLibraryDto = { + /** Exclusion patterns (max 128) */ exclusionPatterns?: string[]; + /** Import paths (max 128) */ importPaths?: string[]; + /** Library name */ name?: string; + /** Owner user ID */ ownerId: string; }; export type UpdateLibraryDto = { + /** Exclusion patterns (max 128) */ exclusionPatterns?: string[]; + /** Import paths (max 128) */ importPaths?: string[]; + /** Library name */ name?: string; }; export type LibraryStatsResponseDto = { + /** Number of photos */ photos: number; + /** Total number of assets */ total: number; + /** Storage usage in bytes */ usage: number; + /** Number of videos */ videos: number; }; export type ValidateLibraryDto = { + /** Exclusion patterns (max 128) */ exclusionPatterns?: string[]; + /** Import paths to validate (max 128) */ importPaths?: string[]; }; export type ValidateLibraryImportPathResponseDto = { + /** Import path */ importPath: string; + /** Is valid */ isValid: boolean; + /** Validation message */ message?: string; }; export type ValidateLibraryResponseDto = { + /** Validation results for import paths */ importPaths?: ValidateLibraryImportPathResponseDto[]; }; export type MapMarkerResponseDto = { + /** City name */ city: string | null; + /** Country name */ country: string | null; + /** Asset ID */ id: string; + /** Latitude */ lat: number; + /** Longitude */ lon: number; + /** State/Province name */ state: string | null; }; export type MapReverseGeocodeResponseDto = { + /** City name */ city: string | null; + /** Country name */ country: string | null; + /** State/Province name */ state: string | null; }; export type OnThisDayDto = { + /** Year for on this day memory */ year: number; }; export type MemoryResponseDto = { assets: AssetResponseDto[]; + /** Creation date */ createdAt: string; data: OnThisDayDto; + /** Deletion date */ deletedAt?: string; + /** Date when memory should be hidden */ hideAt?: string; + /** Memory ID */ id: string; + /** Is memory saved */ isSaved: boolean; + /** Memory date */ memoryAt: string; + /** Owner user ID */ ownerId: string; + /** Date when memory was seen */ seenAt?: string; + /** Date when memory should be shown */ showAt?: string; + /** Memory type */ "type": MemoryType; + /** Last update date */ updatedAt: string; }; export type MemoryCreateDto = { + /** Asset IDs to associate with memory */ assetIds?: string[]; data: OnThisDayDto; + /** Is memory saved */ isSaved?: boolean; + /** Memory date */ memoryAt: string; + /** Date when memory was seen */ seenAt?: string; + /** Memory type */ "type": MemoryType; }; export type MemoryStatisticsResponseDto = { + /** Total number of memories */ total: number; }; export type MemoryUpdateDto = { + /** Is memory saved */ isSaved?: boolean; + /** Memory date */ memoryAt?: string; + /** Date when memory was seen */ seenAt?: string; }; export type NotificationDeleteAllDto = { + /** Notification IDs to delete */ ids: string[]; }; export type NotificationUpdateAllDto = { + /** Notification IDs to update */ ids: string[]; + /** Date when notifications were read */ readAt?: string | null; }; export type NotificationUpdateDto = { + /** Date when notification was read */ readAt?: string | null; }; export type OAuthConfigDto = { + /** OAuth code challenge (PKCE) */ codeChallenge?: string; + /** OAuth redirect URI */ redirectUri: string; + /** OAuth state parameter */ state?: string; }; export type OAuthAuthorizeResponseDto = { + /** OAuth authorization URL */ url: string; }; export type OAuthCallbackDto = { + /** OAuth code verifier (PKCE) */ codeVerifier?: string; + /** OAuth state parameter */ state?: string; + /** OAuth callback URL */ url: string; }; export type PartnerResponseDto = { + /** Avatar color */ avatarColor: UserAvatarColor; + /** User email */ email: string; + /** User ID */ id: string; + /** Show in timeline */ inTimeline?: boolean; + /** User name */ name: string; + /** Profile change date */ profileChangedAt: string; + /** Profile image path */ profileImagePath: string; }; export type PartnerCreateDto = { + /** User ID to share with */ sharedWithId: string; }; export type PartnerUpdateDto = { + /** Show partner assets in timeline */ inTimeline: boolean; }; export type PeopleResponseDto = { + /** Whether there are more pages */ hasNextPage?: boolean; + /** Number of hidden people */ hidden: number; + /** List of people */ people: PersonResponseDto[]; + /** Total number of people */ total: number; }; export type PersonCreateDto = { - /** Person date of birth. - Note: the mobile app cannot currently set the birth date to null. */ + /** Person date of birth */ birthDate?: string | null; + /** Person color (hex) */ color?: string | null; + /** Mark as favorite */ isFavorite?: boolean; - /** Person visibility */ + /** Person visibility (hidden) */ isHidden?: boolean; - /** Person name. */ + /** Person name */ name?: string; }; export type PeopleUpdateItem = { - /** Person date of birth. - Note: the mobile app cannot currently set the birth date to null. */ + /** Person date of birth */ birthDate?: string | null; + /** Person color (hex) */ color?: string | null; - /** Asset is used to get the feature face thumbnail. */ + /** Asset ID used for feature face thumbnail */ featureFaceAssetId?: string; - /** Person id. */ + /** Person ID */ id: string; + /** Mark as favorite */ isFavorite?: boolean; - /** Person visibility */ + /** Person visibility (hidden) */ isHidden?: boolean; - /** Person name. */ + /** Person name */ name?: string; }; export type PeopleUpdateDto = { + /** People to update */ people: PeopleUpdateItem[]; }; export type PersonUpdateDto = { - /** Person date of birth. - Note: the mobile app cannot currently set the birth date to null. */ + /** Person date of birth */ birthDate?: string | null; + /** Person color (hex) */ color?: string | null; - /** Asset is used to get the feature face thumbnail. */ + /** Asset ID used for feature face thumbnail */ featureFaceAssetId?: string; + /** Mark as favorite */ isFavorite?: boolean; - /** Person visibility */ + /** Person visibility (hidden) */ isHidden?: boolean; - /** Person name. */ + /** Person name */ name?: string; }; export type MergePersonDto = { + /** Person IDs to merge */ ids: string[]; }; export type AssetFaceUpdateItem = { + /** Asset ID */ assetId: string; + /** Person ID */ personId: string; }; export type AssetFaceUpdateDto = { + /** Face update items */ data: AssetFaceUpdateItem[]; }; export type PersonStatisticsResponseDto = { + /** Number of assets */ assets: number; }; export type PluginActionResponseDto = { + /** Action description */ description: string; + /** Action ID */ id: string; + /** Method name */ methodName: string; + /** Plugin ID */ pluginId: string; + /** Action schema */ schema: object | null; + /** Supported contexts */ supportedContexts: PluginContextType[]; + /** Action title */ title: string; }; export type PluginFilterResponseDto = { + /** Filter description */ description: string; + /** Filter ID */ id: string; + /** Method name */ methodName: string; + /** Plugin ID */ pluginId: string; + /** Filter schema */ schema: object | null; + /** Supported contexts */ supportedContexts: PluginContextType[]; + /** Filter title */ title: string; }; export type PluginResponseDto = { + /** Plugin actions */ actions: PluginActionResponseDto[]; + /** Plugin author */ author: string; + /** Creation date */ createdAt: string; + /** Plugin description */ description: string; + /** Plugin filters */ filters: PluginFilterResponseDto[]; + /** Plugin ID */ id: string; + /** Plugin name */ name: string; + /** Plugin title */ title: string; + /** Last update date */ updatedAt: string; + /** Plugin version */ version: string; }; export type PluginTriggerResponseDto = { + /** Context type */ contextType: PluginContextType; + /** Trigger type */ "type": PluginTriggerType; }; export type QueueResponseDto = { + /** Whether the queue is paused */ isPaused: boolean; + /** Queue name */ name: QueueName; statistics: QueueStatisticsDto; }; export type QueueUpdateDto = { + /** Whether to pause the queue */ isPaused?: boolean; }; export type QueueDeleteDto = { @@ -1077,84 +1631,143 @@ export type QueueDeleteDto = { failed?: boolean; }; export type QueueJobResponseDto = { + /** Job data payload */ data: object; + /** Job ID */ id?: string; + /** Job name */ name: JobName; + /** Job creation timestamp */ timestamp: number; }; export type SearchExploreItem = { data: AssetResponseDto; + /** Explore value */ value: string; }; export type SearchExploreResponseDto = { + /** Explore field name */ fieldName: string; items: SearchExploreItem[]; }; export type MetadataSearchDto = { + /** Filter by album IDs */ albumIds?: string[]; + /** Filter by file checksum */ checksum?: string; + /** Filter by city name */ city?: string | null; + /** Filter by country name */ country?: string | null; + /** Filter by creation date (after) */ createdAfter?: string; + /** Filter by creation date (before) */ createdBefore?: string; + /** Filter by description text */ description?: string; + /** Filter by device asset ID */ deviceAssetId?: string; + /** Device ID to filter by */ deviceId?: string; + /** Filter by encoded video file path */ encodedVideoPath?: string; + /** Filter by asset ID */ id?: string; + /** Filter by encoded status */ isEncoded?: boolean; + /** Filter by favorite status */ isFavorite?: boolean; + /** Filter by motion photo status */ isMotion?: boolean; + /** Filter assets not in any album */ isNotInAlbum?: boolean; + /** Filter by offline status */ isOffline?: boolean; + /** Filter by lens model */ lensModel?: string | null; + /** Library ID to filter by */ libraryId?: string | null; + /** Filter by camera make */ make?: string; + /** Filter by camera model */ model?: string | null; + /** Filter by OCR text content */ ocr?: string; + /** Sort order */ order?: AssetOrder; + /** Filter by original file name */ originalFileName?: string; + /** Filter by original file path */ originalPath?: string; + /** Page number */ page?: number; + /** Filter by person IDs */ personIds?: string[]; + /** Filter by preview file path */ previewPath?: string; + /** Filter by rating */ rating?: number; + /** Number of results to return */ size?: number; + /** Filter by state/province name */ state?: string | null; + /** Filter by tag IDs */ tagIds?: string[] | null; + /** Filter by taken date (after) */ takenAfter?: string; + /** Filter by taken date (before) */ takenBefore?: string; + /** Filter by thumbnail file path */ thumbnailPath?: string; + /** Filter by trash date (after) */ trashedAfter?: string; + /** Filter by trash date (before) */ trashedBefore?: string; + /** Asset type filter */ "type"?: AssetTypeEnum; + /** Filter by update date (after) */ updatedAfter?: string; + /** Filter by update date (before) */ updatedBefore?: string; + /** Filter by visibility */ visibility?: AssetVisibility; + /** Include deleted assets */ withDeleted?: boolean; + /** Include EXIF data in response */ withExif?: boolean; + /** Include assets with people */ withPeople?: boolean; + /** Include stacked assets */ withStacked?: boolean; }; export type SearchFacetCountResponseDto = { + /** Number of assets with this facet value */ count: number; + /** Facet value */ value: string; }; export type SearchFacetResponseDto = { + /** Facet counts */ counts: SearchFacetCountResponseDto[]; + /** Facet field name */ fieldName: string; }; export type SearchAlbumResponseDto = { + /** Number of albums in this page */ count: number; facets: SearchFacetResponseDto[]; items: AlbumResponseDto[]; + /** Total number of matching albums */ total: number; }; export type SearchAssetResponseDto = { + /** Number of assets in this page */ count: number; facets: SearchFacetResponseDto[]; items: AssetResponseDto[]; + /** Next page token */ nextPage: string | null; + /** Total number of matching assets */ total: number; }; export type SearchResponseDto = { @@ -1162,189 +1775,351 @@ export type SearchResponseDto = { assets: SearchAssetResponseDto; }; export type PlacesResponseDto = { + /** Administrative level 1 name (state/province) */ admin1name?: string; + /** Administrative level 2 name (county/district) */ admin2name?: string; + /** Latitude coordinate */ latitude: number; + /** Longitude coordinate */ longitude: number; + /** Place name */ name: string; }; export type RandomSearchDto = { + /** Filter by album IDs */ albumIds?: string[]; + /** Filter by city name */ city?: string | null; + /** Filter by country name */ country?: string | null; + /** Filter by creation date (after) */ createdAfter?: string; + /** Filter by creation date (before) */ createdBefore?: string; + /** Device ID to filter by */ deviceId?: string; + /** Filter by encoded status */ isEncoded?: boolean; + /** Filter by favorite status */ isFavorite?: boolean; + /** Filter by motion photo status */ isMotion?: boolean; + /** Filter assets not in any album */ isNotInAlbum?: boolean; + /** Filter by offline status */ isOffline?: boolean; + /** Filter by lens model */ lensModel?: string | null; + /** Library ID to filter by */ libraryId?: string | null; + /** Filter by camera make */ make?: string; + /** Filter by camera model */ model?: string | null; + /** Filter by OCR text content */ ocr?: string; + /** Filter by person IDs */ personIds?: string[]; + /** Filter by rating */ rating?: number; + /** Number of results to return */ size?: number; + /** Filter by state/province name */ state?: string | null; + /** Filter by tag IDs */ tagIds?: string[] | null; + /** Filter by taken date (after) */ takenAfter?: string; + /** Filter by taken date (before) */ takenBefore?: string; + /** Filter by trash date (after) */ trashedAfter?: string; + /** Filter by trash date (before) */ trashedBefore?: string; + /** Asset type filter */ "type"?: AssetTypeEnum; + /** Filter by update date (after) */ updatedAfter?: string; + /** Filter by update date (before) */ updatedBefore?: string; + /** Filter by visibility */ visibility?: AssetVisibility; + /** Include deleted assets */ withDeleted?: boolean; + /** Include EXIF data in response */ withExif?: boolean; + /** Include assets with people */ withPeople?: boolean; + /** Include stacked assets */ withStacked?: boolean; }; export type SmartSearchDto = { + /** Filter by album IDs */ albumIds?: string[]; + /** Filter by city name */ city?: string | null; + /** Filter by country name */ country?: string | null; + /** Filter by creation date (after) */ createdAfter?: string; + /** Filter by creation date (before) */ createdBefore?: string; + /** Device ID to filter by */ deviceId?: string; + /** Filter by encoded status */ isEncoded?: boolean; + /** Filter by favorite status */ isFavorite?: boolean; + /** Filter by motion photo status */ isMotion?: boolean; + /** Filter assets not in any album */ isNotInAlbum?: boolean; + /** Filter by offline status */ isOffline?: boolean; + /** Search language code */ language?: string; + /** Filter by lens model */ lensModel?: string | null; + /** Library ID to filter by */ libraryId?: string | null; + /** Filter by camera make */ make?: string; + /** Filter by camera model */ model?: string | null; + /** Filter by OCR text content */ ocr?: string; + /** Page number */ page?: number; + /** Filter by person IDs */ personIds?: string[]; + /** Natural language search query */ query?: string; + /** Asset ID to use as search reference */ queryAssetId?: string; + /** Filter by rating */ rating?: number; + /** Number of results to return */ size?: number; + /** Filter by state/province name */ state?: string | null; + /** Filter by tag IDs */ tagIds?: string[] | null; + /** Filter by taken date (after) */ takenAfter?: string; + /** Filter by taken date (before) */ takenBefore?: string; + /** Filter by trash date (after) */ trashedAfter?: string; + /** Filter by trash date (before) */ trashedBefore?: string; + /** Asset type filter */ "type"?: AssetTypeEnum; + /** Filter by update date (after) */ updatedAfter?: string; + /** Filter by update date (before) */ updatedBefore?: string; + /** Filter by visibility */ visibility?: AssetVisibility; + /** Include deleted assets */ withDeleted?: boolean; + /** Include EXIF data in response */ withExif?: boolean; }; export type StatisticsSearchDto = { + /** Filter by album IDs */ albumIds?: string[]; + /** Filter by city name */ city?: string | null; + /** Filter by country name */ country?: string | null; + /** Filter by creation date (after) */ createdAfter?: string; + /** Filter by creation date (before) */ createdBefore?: string; + /** Filter by description text */ description?: string; + /** Device ID to filter by */ deviceId?: string; + /** Filter by encoded status */ isEncoded?: boolean; + /** Filter by favorite status */ isFavorite?: boolean; + /** Filter by motion photo status */ isMotion?: boolean; + /** Filter assets not in any album */ isNotInAlbum?: boolean; + /** Filter by offline status */ isOffline?: boolean; + /** Filter by lens model */ lensModel?: string | null; + /** Library ID to filter by */ libraryId?: string | null; + /** Filter by camera make */ make?: string; + /** Filter by camera model */ model?: string | null; + /** Filter by OCR text content */ ocr?: string; + /** Filter by person IDs */ personIds?: string[]; + /** Filter by rating */ rating?: number; + /** Filter by state/province name */ state?: string | null; + /** Filter by tag IDs */ tagIds?: string[] | null; + /** Filter by taken date (after) */ takenAfter?: string; + /** Filter by taken date (before) */ takenBefore?: string; + /** Filter by trash date (after) */ trashedAfter?: string; + /** Filter by trash date (before) */ trashedBefore?: string; + /** Asset type filter */ "type"?: AssetTypeEnum; + /** Filter by update date (after) */ updatedAfter?: string; + /** Filter by update date (before) */ updatedBefore?: string; + /** Filter by visibility */ visibility?: AssetVisibility; }; export type SearchStatisticsResponseDto = { + /** Total number of matching assets */ total: number; }; export type ServerAboutResponseDto = { + /** Build identifier */ build?: string; + /** Build image name */ buildImage?: string; + /** Build image URL */ buildImageUrl?: string; + /** Build URL */ buildUrl?: string; + /** ExifTool version */ exiftool?: string; + /** FFmpeg version */ ffmpeg?: string; + /** ImageMagick version */ imagemagick?: string; + /** libvips version */ libvips?: string; + /** Whether the server is licensed */ licensed: boolean; + /** Node.js version */ nodejs?: string; + /** Repository name */ repository?: string; + /** Repository URL */ repositoryUrl?: string; + /** Source commit hash */ sourceCommit?: string; + /** Source reference (branch/tag) */ sourceRef?: string; + /** Source URL */ sourceUrl?: string; + /** Third-party bug/feature URL */ thirdPartyBugFeatureUrl?: string; + /** Third-party documentation URL */ thirdPartyDocumentationUrl?: string; + /** Third-party source URL */ thirdPartySourceUrl?: string; + /** Third-party support URL */ thirdPartySupportUrl?: string; + /** Server version */ version: string; + /** URL to version information */ versionUrl: string; }; export type ServerApkLinksDto = { + /** APK download link for ARM64 v8a architecture */ arm64v8a: string; + /** APK download link for ARM EABI v7a architecture */ armeabiv7a: string; + /** APK download link for universal architecture */ universal: string; + /** APK download link for x86_64 architecture */ x86_64: string; }; export type ServerConfigDto = { + /** External domain URL */ externalDomain: string; + /** Whether the server has been initialized */ isInitialized: boolean; + /** Whether the admin has completed onboarding */ isOnboarded: boolean; + /** Login page message */ loginPageMessage: string; + /** Whether maintenance mode is active */ maintenanceMode: boolean; + /** Map dark style URL */ mapDarkStyleUrl: string; + /** Map light style URL */ mapLightStyleUrl: string; + /** OAuth button text */ oauthButtonText: string; + /** Whether public user registration is enabled */ publicUsers: boolean; + /** Number of days before trashed assets are permanently deleted */ trashDays: number; + /** Delay in days before deleted users are permanently removed */ userDeleteDelay: number; }; export type ServerFeaturesDto = { + /** Whether config file is available */ configFile: boolean; + /** Whether duplicate detection is enabled */ duplicateDetection: boolean; + /** Whether email notifications are enabled */ email: boolean; + /** Whether facial recognition is enabled */ facialRecognition: boolean; + /** Whether face import is enabled */ importFaces: boolean; + /** Whether map feature is enabled */ map: boolean; + /** Whether OAuth is enabled */ oauth: boolean; + /** Whether OAuth auto-launch is enabled */ oauthAutoLaunch: boolean; + /** Whether OCR is enabled */ ocr: boolean; + /** Whether password login is enabled */ passwordLogin: boolean; + /** Whether reverse geocoding is enabled */ reverseGeocoding: boolean; + /** Whether search is enabled */ search: boolean; + /** Whether sidecar files are supported */ sidecar: boolean; + /** Whether smart search is enabled */ smartSearch: boolean; + /** Whether trash feature is enabled */ trash: boolean; }; export type LicenseResponseDto = { + /** Activation date */ activatedAt: string; + /** Activation key */ activationKey: string; + /** License key (format: IM(SV|CL)(-XXXX){8}) */ licenseKey: string; }; export type LicenseKeyDto = { + /** Activation key */ activationKey: string; + /** License key (format: IM(SV|CL)(-XXXX){8}) */ licenseKey: string; }; export type ServerMediaTypesResponseDto = { + /** Supported image MIME types */ image: string[]; + /** Supported sidecar MIME types */ sidecar: string[]; + /** Supported video MIME types */ video: string[]; }; export type ServerPingResponse = {}; @@ -1352,209 +2127,335 @@ export type ServerPingResponseRead = { res: string; }; export type UsageByUserDto = { + /** Number of photos */ photos: number; + /** User quota size in bytes (null if unlimited) */ quotaSizeInBytes: number | null; + /** Total storage usage in bytes */ usage: number; + /** Storage usage for photos in bytes */ usagePhotos: number; + /** Storage usage for videos in bytes */ usageVideos: number; + /** User ID */ userId: string; + /** User name */ userName: string; + /** Number of videos */ videos: number; }; export type ServerStatsResponseDto = { + /** Total number of photos */ photos: number; + /** Total storage usage in bytes */ usage: number; usageByUser: UsageByUserDto[]; + /** Storage usage for photos in bytes */ usagePhotos: number; + /** Storage usage for videos in bytes */ usageVideos: number; + /** Total number of videos */ videos: number; }; export type ServerStorageResponseDto = { + /** Available disk space (human-readable format) */ diskAvailable: string; + /** Available disk space in bytes */ diskAvailableRaw: number; + /** Total disk size (human-readable format) */ diskSize: string; + /** Total disk size in bytes */ diskSizeRaw: number; + /** Disk usage percentage (0-100) */ diskUsagePercentage: number; + /** Used disk space (human-readable format) */ diskUse: string; + /** Used disk space in bytes */ diskUseRaw: number; }; export type ServerThemeDto = { + /** Custom CSS for theming */ customCss: string; }; export type ServerVersionResponseDto = { + /** Major version number */ major: number; + /** Minor version number */ minor: number; + /** Patch version number */ patch: number; }; export type VersionCheckStateResponseDto = { + /** Last check timestamp */ checkedAt: string | null; + /** Release version */ releaseVersion: string | null; }; export type ServerVersionHistoryResponseDto = { + /** When this version was first seen */ createdAt: string; + /** Version history entry ID */ id: string; + /** Version string */ version: string; }; export type SessionCreateDto = { + /** Device OS */ deviceOS?: string; + /** Device type */ deviceType?: string; - /** session duration, in seconds */ + /** Session duration in seconds */ duration?: number; }; export type SessionCreateResponseDto = { + /** App version */ appVersion: string | null; + /** Creation date */ createdAt: string; + /** Is current session */ current: boolean; + /** Device OS */ deviceOS: string; + /** Device type */ deviceType: string; + /** Expiration date */ expiresAt?: string; + /** Session ID */ id: string; + /** Is pending sync reset */ isPendingSyncReset: boolean; + /** Session token */ token: string; + /** Last update date */ updatedAt: string; }; export type SessionUpdateDto = { + /** Reset pending sync state */ isPendingSyncReset?: boolean; }; export type SharedLinkResponseDto = { album?: AlbumResponseDto; + /** Allow downloads */ allowDownload: boolean; + /** Allow uploads */ allowUpload: boolean; assets: AssetResponseDto[]; + /** Creation date */ createdAt: string; + /** Link description */ description: string | null; + /** Expiration date */ expiresAt: string | null; + /** Shared link ID */ id: string; + /** Encryption key (base64url) */ key: string; + /** Has password */ password: string | null; + /** Show metadata */ showMetadata: boolean; + /** Custom URL slug */ slug: string | null; + /** Access token */ token?: string | null; + /** Shared link type */ "type": SharedLinkType; + /** Owner user ID */ userId: string; }; export type SharedLinkCreateDto = { + /** Album ID (for album sharing) */ albumId?: string; + /** Allow downloads */ allowDownload?: boolean; + /** Allow uploads */ allowUpload?: boolean; + /** Asset IDs (for individual assets) */ assetIds?: string[]; + /** Link description */ description?: string | null; + /** Expiration date */ expiresAt?: string | null; + /** Link password */ password?: string | null; + /** Show metadata */ showMetadata?: boolean; + /** Custom URL slug */ slug?: string | null; + /** Shared link type */ "type": SharedLinkType; }; export type SharedLinkEditDto = { + /** Allow downloads */ allowDownload?: boolean; + /** Allow uploads */ allowUpload?: boolean; - /** Few clients cannot send null to set the expiryTime to never. - Setting this flag and not sending expiryAt is considered as null instead. - Clients that can send null values can ignore this. */ + /** Whether to change the expiry time. Few clients cannot send null to set the expiryTime to never. Setting this flag and not sending expiryAt is considered as null instead. Clients that can send null values can ignore this. */ changeExpiryTime?: boolean; + /** Link description */ description?: string | null; + /** Expiration date */ expiresAt?: string | null; + /** Link password */ password?: string | null; + /** Show metadata */ showMetadata?: boolean; + /** Custom URL slug */ slug?: string | null; }; export type AssetIdsResponseDto = { + /** Asset ID */ assetId: string; + /** Error reason if failed */ error?: Error2; + /** Whether operation succeeded */ success: boolean; }; export type StackResponseDto = { + /** Stack assets */ assets: AssetResponseDto[]; + /** Stack ID */ id: string; + /** Primary asset ID */ primaryAssetId: string; }; export type StackCreateDto = { - /** first asset becomes the primary */ + /** Asset IDs (first becomes primary, min 2) */ assetIds: string[]; }; export type StackUpdateDto = { + /** Primary asset ID */ primaryAssetId?: string; }; export type SyncAckDeleteDto = { + /** Sync entity types to delete acks for */ types?: SyncEntityType[]; }; export type SyncAckDto = { + /** Acknowledgment ID */ ack: string; + /** Sync entity type */ "type": SyncEntityType; }; export type SyncAckSetDto = { + /** Acknowledgment IDs (max 1000) */ acks: string[]; }; export type AssetDeltaSyncDto = { + /** Sync assets updated after this date */ updatedAfter: string; + /** User IDs to sync */ userIds: string[]; }; export type AssetDeltaSyncResponseDto = { + /** Deleted asset IDs */ deleted: string[]; + /** Whether full sync is needed */ needsFullSync: boolean; + /** Upserted assets */ upserted: AssetResponseDto[]; }; export type AssetFullSyncDto = { + /** Last asset ID (pagination) */ lastId?: string; + /** Maximum number of assets to return */ limit: number; + /** Sync assets updated until this date */ updatedUntil: string; + /** Filter by user ID */ userId?: string; }; export type SyncStreamDto = { + /** Reset sync state */ reset?: boolean; + /** Sync request types */ types: SyncRequestType[]; }; export type DatabaseBackupConfig = { + /** Cron expression */ cronExpression: string; + /** Enabled */ enabled: boolean; + /** Keep last amount */ keepLastAmount: number; }; export type SystemConfigBackupsDto = { database: DatabaseBackupConfig; }; export type SystemConfigFFmpegDto = { + /** Transcode hardware acceleration */ accel: TranscodeHWAccel; + /** Accelerated decode */ accelDecode: boolean; + /** Accepted audio codecs */ acceptedAudioCodecs: AudioCodec[]; + /** Accepted containers */ acceptedContainers: VideoContainer[]; + /** Accepted video codecs */ acceptedVideoCodecs: VideoCodec[]; + /** B-frames */ bframes: number; + /** CQ mode */ cqMode: CQMode; + /** CRF */ crf: number; + /** GOP size */ gopSize: number; + /** Max bitrate */ maxBitrate: string; + /** Preferred hardware device */ preferredHwDevice: string; + /** Preset */ preset: string; + /** References */ refs: number; + /** Target audio codec */ targetAudioCodec: AudioCodec; + /** Target resolution */ targetResolution: string; + /** Target video codec */ targetVideoCodec: VideoCodec; + /** Temporal AQ */ temporalAQ: boolean; + /** Threads */ threads: number; + /** Tone mapping */ tonemap: ToneMapping; + /** Transcode policy */ transcode: TranscodePolicy; + /** Two pass */ twoPass: boolean; }; export type SystemConfigGeneratedFullsizeImageDto = { + /** Enabled */ enabled: boolean; + /** Image format */ format: ImageFormat; + /** Progressive */ progressive?: boolean; + /** Quality */ quality: number; }; export type SystemConfigGeneratedImageDto = { + /** Image format */ format: ImageFormat; progressive?: boolean; + /** Quality */ quality: number; + /** Size */ size: number; }; export type SystemConfigImageDto = { + /** Colorspace */ colorspace: Colorspace; + /** Extract embedded */ extractEmbedded: boolean; fullsize: SystemConfigGeneratedFullsizeImageDto; preview: SystemConfigGeneratedImageDto; thumbnail: SystemConfigGeneratedImageDto; }; export type JobSettingsDto = { + /** Concurrency */ concurrency: number; }; export type SystemConfigJobDto = { @@ -1575,9 +2476,11 @@ export type SystemConfigJobDto = { }; export type SystemConfigLibraryScanDto = { cronExpression: string; + /** Enabled */ enabled: boolean; }; export type SystemConfigLibraryWatchDto = { + /** Enabled */ enabled: boolean; }; export type SystemConfigLibraryDto = { @@ -1585,40 +2488,57 @@ export type SystemConfigLibraryDto = { watch: SystemConfigLibraryWatchDto; }; export type SystemConfigLoggingDto = { + /** Enabled */ enabled: boolean; level: LogLevel; }; export type MachineLearningAvailabilityChecksDto = { + /** Enabled */ enabled: boolean; interval: number; timeout: number; }; export type ClipConfig = { + /** Whether the task is enabled */ enabled: boolean; + /** Name of the model to use */ modelName: string; }; export type DuplicateDetectionConfig = { + /** Whether the task is enabled */ enabled: boolean; + /** Maximum distance threshold for duplicate detection */ maxDistance: number; }; export type FacialRecognitionConfig = { + /** Whether the task is enabled */ enabled: boolean; + /** Maximum distance threshold for face recognition */ maxDistance: number; + /** Minimum number of faces required for recognition */ minFaces: number; + /** Minimum confidence score for face detection */ minScore: number; + /** Name of the model to use */ modelName: string; }; export type OcrConfig = { + /** Whether the task is enabled */ enabled: boolean; + /** Maximum resolution for OCR processing */ maxResolution: number; + /** Minimum confidence score for text detection */ minDetectionScore: number; + /** Minimum confidence score for text recognition */ minRecognitionScore: number; + /** Name of the model to use */ modelName: string; }; export type SystemConfigMachineLearningDto = { availabilityChecks: MachineLearningAvailabilityChecksDto; clip: ClipConfig; duplicateDetection: DuplicateDetectionConfig; + /** Enabled */ enabled: boolean; facialRecognition: FacialRecognitionConfig; ocr: OcrConfig; @@ -1626,63 +2546,96 @@ export type SystemConfigMachineLearningDto = { }; export type SystemConfigMapDto = { darkStyle: string; + /** Enabled */ enabled: boolean; lightStyle: string; }; export type SystemConfigFacesDto = { + /** Import */ "import": boolean; }; export type SystemConfigMetadataDto = { faces: SystemConfigFacesDto; }; export type SystemConfigNewVersionCheckDto = { + /** Enabled */ enabled: boolean; }; export type SystemConfigNightlyTasksDto = { + /** Cluster new faces */ clusterNewFaces: boolean; + /** Database cleanup */ databaseCleanup: boolean; + /** Generate memories */ generateMemories: boolean; + /** Missing thumbnails */ missingThumbnails: boolean; startTime: string; + /** Sync quota usage */ syncQuotaUsage: boolean; }; export type SystemConfigNotificationsDto = { smtp: SystemConfigSmtpDto; }; export type SystemConfigOAuthDto = { + /** Auto launch */ autoLaunch: boolean; + /** Auto register */ autoRegister: boolean; + /** Button text */ buttonText: string; + /** Client ID */ clientId: string; + /** Client secret */ clientSecret: string; + /** Default storage quota */ defaultStorageQuota: number | null; + /** Enabled */ enabled: boolean; + /** Issuer URL */ issuerUrl: string; + /** Mobile override enabled */ mobileOverrideEnabled: boolean; + /** Mobile redirect URI */ mobileRedirectUri: string; + /** Profile signing algorithm */ profileSigningAlgorithm: string; + /** Role claim */ roleClaim: string; + /** Scope */ scope: string; signingAlgorithm: string; + /** Storage label claim */ storageLabelClaim: string; + /** Storage quota claim */ storageQuotaClaim: string; + /** Timeout */ timeout: number; + /** Token endpoint auth method */ tokenEndpointAuthMethod: OAuthTokenEndpointAuthMethod; }; export type SystemConfigPasswordLoginDto = { + /** Enabled */ enabled: boolean; }; export type SystemConfigReverseGeocodingDto = { + /** Enabled */ enabled: boolean; }; export type SystemConfigServerDto = { + /** External domain */ externalDomain: string; + /** Login page message */ loginPageMessage: string; + /** Public users */ publicUsers: boolean; }; export type SystemConfigStorageTemplateDto = { + /** Enabled */ enabled: boolean; + /** Hash verification enabled */ hashVerificationEnabled: boolean; + /** Template */ template: string; }; export type SystemConfigTemplateEmailsDto = { @@ -1694,13 +2647,17 @@ export type SystemConfigTemplatesDto = { email: SystemConfigTemplateEmailsDto; }; export type SystemConfigThemeDto = { + /** Custom CSS for theming */ customCss: string; }; export type SystemConfigTrashDto = { + /** Days */ days: number; + /** Enabled */ enabled: boolean; }; export type SystemConfigUserDto = { + /** Delete delay */ deleteDelay: number; }; export type SystemConfigDto = { @@ -1727,38 +2684,57 @@ export type SystemConfigDto = { user: SystemConfigUserDto; }; export type SystemConfigTemplateStorageOptionDto = { + /** Available day format options for storage template */ dayOptions: string[]; + /** Available hour format options for storage template */ hourOptions: string[]; + /** Available minute format options for storage template */ minuteOptions: string[]; + /** Available month format options for storage template */ monthOptions: string[]; + /** Available preset template options */ presetOptions: string[]; + /** Available second format options for storage template */ secondOptions: string[]; + /** Available week format options for storage template */ weekOptions: string[]; + /** Available year format options for storage template */ yearOptions: string[]; }; export type AdminOnboardingUpdateDto = { + /** Is admin onboarded */ isOnboarded: boolean; }; export type ReverseGeocodingStateResponseDto = { + /** Last import file name */ lastImportFileName: string | null; + /** Last update timestamp */ lastUpdate: string | null; }; export type TagCreateDto = { + /** Tag color (hex) */ color?: string; + /** Tag name */ name: string; + /** Parent tag ID */ parentId?: string | null; }; export type TagUpsertDto = { + /** Tag names to upsert */ tags: string[]; }; export type TagBulkAssetsDto = { + /** Asset IDs */ assetIds: string[]; + /** Tag IDs */ tagIds: string[]; }; export type TagBulkAssetsResponseDto = { + /** Number of assets tagged */ count: number; }; export type TagUpdateDto = { + /** Tag color (hex) */ color?: string | null; }; export type TimeBucketAssetResponseDto = { @@ -1768,7 +2744,7 @@ export type TimeBucketAssetResponseDto = { country: (string | null)[]; /** Array of video durations in HH:MM:SS format (null for images) */ duration: (string | null)[]; - /** Array of file creation timestamps in UTC (ISO 8601 format, without timezone) */ + /** Array of file creation timestamps in UTC */ fileCreatedAt: string[]; /** Array of asset IDs in the time bucket */ id: string[]; @@ -1806,279 +2782,461 @@ export type TimeBucketsResponseDto = { timeBucket: string; }; export type TrashResponseDto = { + /** Number of items in trash */ count: number; }; export type UserUpdateMeDto = { + /** Avatar color */ avatarColor?: (UserAvatarColor) | null; + /** User email */ email?: string; + /** User name */ name?: string; + /** User password (deprecated, use change password endpoint) */ password?: string; }; export type OnboardingResponseDto = { + /** Is user onboarded */ isOnboarded: boolean; }; export type OnboardingDto = { + /** Is user onboarded */ isOnboarded: boolean; }; export type CreateProfileImageDto = { + /** Profile image file */ file: Blob; }; export type CreateProfileImageResponseDto = { + /** Profile image change date */ profileChangedAt: string; + /** Profile image file path */ profileImagePath: string; + /** User ID */ userId: string; }; export type WorkflowActionResponseDto = { + /** Action configuration */ actionConfig: object | null; + /** Action ID */ id: string; + /** Action order */ order: number; + /** Plugin action ID */ pluginActionId: string; + /** Workflow ID */ workflowId: string; }; export type WorkflowFilterResponseDto = { + /** Filter configuration */ filterConfig: object | null; + /** Filter ID */ id: string; + /** Filter order */ order: number; + /** Plugin filter ID */ pluginFilterId: string; + /** Workflow ID */ workflowId: string; }; export type WorkflowResponseDto = { + /** Workflow actions */ actions: WorkflowActionResponseDto[]; + /** Creation date */ createdAt: string; + /** Workflow description */ description: string; + /** Workflow enabled */ enabled: boolean; + /** Workflow filters */ filters: WorkflowFilterResponseDto[]; + /** Workflow ID */ id: string; + /** Workflow name */ name: string | null; + /** Owner user ID */ ownerId: string; + /** Workflow trigger type */ triggerType: PluginTriggerType; }; export type WorkflowActionItemDto = { + /** Action configuration */ actionConfig?: object; + /** Plugin action ID */ pluginActionId: string; }; export type WorkflowFilterItemDto = { + /** Filter configuration */ filterConfig?: object; + /** Plugin filter ID */ pluginFilterId: string; }; export type WorkflowCreateDto = { + /** Workflow actions */ actions: WorkflowActionItemDto[]; + /** Workflow description */ description?: string; + /** Workflow enabled */ enabled?: boolean; + /** Workflow filters */ filters: WorkflowFilterItemDto[]; + /** Workflow name */ name: string; + /** Workflow trigger type */ triggerType: PluginTriggerType; }; export type WorkflowUpdateDto = { + /** Workflow actions */ actions?: WorkflowActionItemDto[]; + /** Workflow description */ description?: string; + /** Workflow enabled */ enabled?: boolean; + /** Workflow filters */ filters?: WorkflowFilterItemDto[]; + /** Workflow name */ name?: string; + /** Workflow trigger type */ triggerType?: PluginTriggerType; }; export type SyncAckV1 = {}; export type SyncAlbumDeleteV1 = { + /** Album ID */ albumId: string; }; export type SyncAlbumToAssetDeleteV1 = { + /** Album ID */ albumId: string; + /** Asset ID */ assetId: string; }; export type SyncAlbumToAssetV1 = { + /** Album ID */ albumId: string; + /** Asset ID */ assetId: string; }; export type SyncAlbumUserDeleteV1 = { + /** Album ID */ albumId: string; + /** User ID */ userId: string; }; export type SyncAlbumUserV1 = { + /** Album ID */ albumId: string; + /** Album user role */ role: AlbumUserRole; + /** User ID */ userId: string; }; export type SyncAlbumV1 = { + /** Created at */ createdAt: string; + /** Album description */ description: string; + /** Album ID */ id: string; + /** Is activity enabled */ isActivityEnabled: boolean; + /** Album name */ name: string; order: AssetOrder; + /** Owner ID */ ownerId: string; + /** Thumbnail asset ID */ thumbnailAssetId: string | null; + /** Updated at */ updatedAt: string; }; export type SyncAssetDeleteV1 = { + /** Asset ID */ assetId: string; }; export type SyncAssetExifV1 = { + /** Asset ID */ assetId: string; + /** City */ city: string | null; + /** Country */ country: string | null; + /** Date time original */ dateTimeOriginal: string | null; + /** Description */ description: string | null; + /** Exif image height */ exifImageHeight: number | null; + /** Exif image width */ exifImageWidth: number | null; + /** Exposure time */ exposureTime: string | null; + /** F number */ fNumber: number | null; + /** File size in byte */ fileSizeInByte: number | null; + /** Focal length */ focalLength: number | null; + /** FPS */ fps: number | null; + /** ISO */ iso: number | null; + /** Latitude */ latitude: number | null; + /** Lens model */ lensModel: string | null; + /** Longitude */ longitude: number | null; + /** Make */ make: string | null; + /** Model */ model: string | null; + /** Modify date */ modifyDate: string | null; + /** Orientation */ orientation: string | null; + /** Profile description */ profileDescription: string | null; + /** Projection type */ projectionType: string | null; + /** Rating */ rating: number | null; + /** State */ state: string | null; + /** Time zone */ timeZone: string | null; }; export type SyncAssetFaceDeleteV1 = { + /** Asset face ID */ assetFaceId: string; }; export type SyncAssetFaceV1 = { + /** Asset ID */ assetId: string; boundingBoxX1: number; boundingBoxX2: number; boundingBoxY1: number; boundingBoxY2: number; + /** Asset face ID */ id: string; imageHeight: number; imageWidth: number; + /** Person ID */ personId: string | null; + /** Source type */ sourceType: string; }; export type SyncAssetMetadataDeleteV1 = { + /** Asset ID */ assetId: string; + /** Key */ key: string; }; export type SyncAssetMetadataV1 = { + /** Asset ID */ assetId: string; + /** Key */ key: string; + /** Value */ value: object; }; export type SyncAssetV1 = { + /** Checksum */ checksum: string; + /** Deleted at */ deletedAt: string | null; + /** Duration */ duration: string | null; + /** File created at */ fileCreatedAt: string | null; + /** File modified at */ fileModifiedAt: string | null; + /** Asset height */ height: number | null; + /** Asset ID */ id: string; + /** Is edited */ isEdited: boolean; + /** Is favorite */ isFavorite: boolean; + /** Library ID */ libraryId: string | null; + /** Live photo video ID */ livePhotoVideoId: string | null; + /** Local date time */ localDateTime: string | null; + /** Original file name */ originalFileName: string; + /** Owner ID */ ownerId: string; + /** Stack ID */ stackId: string | null; + /** Thumbhash */ thumbhash: string | null; + /** Asset type */ "type": AssetTypeEnum; + /** Asset visibility */ visibility: AssetVisibility; + /** Asset width */ width: number | null; }; export type SyncAuthUserV1 = { + /** User avatar color */ avatarColor: (UserAvatarColor) | null; + /** User deleted at */ deletedAt: string | null; + /** User email */ email: string; + /** User has profile image */ hasProfileImage: boolean; + /** User ID */ id: string; + /** User is admin */ isAdmin: boolean; + /** User name */ name: string; + /** User OAuth ID */ oauthId: string; + /** User pin code */ pinCode: string | null; + /** User profile changed at */ profileChangedAt: string; quotaSizeInBytes: number | null; quotaUsageInBytes: number; + /** User storage label */ storageLabel: string | null; }; export type SyncCompleteV1 = {}; export type SyncMemoryAssetDeleteV1 = { + /** Asset ID */ assetId: string; + /** Memory ID */ memoryId: string; }; export type SyncMemoryAssetV1 = { + /** Asset ID */ assetId: string; + /** Memory ID */ memoryId: string; }; export type SyncMemoryDeleteV1 = { + /** Memory ID */ memoryId: string; }; export type SyncMemoryV1 = { + /** Created at */ createdAt: string; + /** Data */ data: object; + /** Deleted at */ deletedAt: string | null; + /** Hide at */ hideAt: string | null; + /** Memory ID */ id: string; + /** Is saved */ isSaved: boolean; + /** Memory at */ memoryAt: string; + /** Owner ID */ ownerId: string; + /** Seen at */ seenAt: string | null; + /** Show at */ showAt: string | null; + /** Memory type */ "type": MemoryType; + /** Updated at */ updatedAt: string; }; export type SyncPartnerDeleteV1 = { + /** Shared by ID */ sharedById: string; + /** Shared with ID */ sharedWithId: string; }; export type SyncPartnerV1 = { + /** In timeline */ inTimeline: boolean; + /** Shared by ID */ sharedById: string; + /** Shared with ID */ sharedWithId: string; }; export type SyncPersonDeleteV1 = { + /** Person ID */ personId: string; }; export type SyncPersonV1 = { + /** Birth date */ birthDate: string | null; + /** Color */ color: string | null; + /** Created at */ createdAt: string; + /** Face asset ID */ faceAssetId: string | null; + /** Person ID */ id: string; + /** Is favorite */ isFavorite: boolean; + /** Is hidden */ isHidden: boolean; + /** Person name */ name: string; + /** Owner ID */ ownerId: string; + /** Updated at */ updatedAt: string; }; export type SyncResetV1 = {}; export type SyncStackDeleteV1 = { + /** Stack ID */ stackId: string; }; export type SyncStackV1 = { + /** Created at */ createdAt: string; + /** Stack ID */ id: string; + /** Owner ID */ ownerId: string; + /** Primary asset ID */ primaryAssetId: string; + /** Updated at */ updatedAt: string; }; export type SyncUserDeleteV1 = { + /** User ID */ userId: string; }; export type SyncUserMetadataDeleteV1 = { + /** User metadata key */ key: UserMetadataKey; + /** User ID */ userId: string; }; export type SyncUserMetadataV1 = { + /** User metadata key */ key: UserMetadataKey; + /** User ID */ userId: string; + /** User metadata value */ value: object; }; export type SyncUserV1 = { + /** User avatar color */ avatarColor: (UserAvatarColor) | null; + /** User deleted at */ deletedAt: string | null; + /** User email */ email: string; + /** User has profile image */ hasProfileImage: boolean; + /** User ID */ id: string; + /** User name */ name: string; + /** User profile changed at */ profileChangedAt: string; }; /** diff --git a/server/src/controllers/maintenance.controller.spec.ts b/server/src/controllers/maintenance.controller.spec.ts new file mode 100644 index 0000000000000..094028687e31a --- /dev/null +++ b/server/src/controllers/maintenance.controller.spec.ts @@ -0,0 +1,39 @@ +import { MaintenanceController } from 'src/controllers/maintenance.controller'; +import { MaintenanceAction } from 'src/enum'; +import { MaintenanceService } from 'src/services/maintenance.service'; +import request from 'supertest'; +import { errorDto } from 'test/medium/responses'; +import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils'; + +describe(MaintenanceController.name, () => { + let ctx: ControllerContext; + const service = mockBaseService(MaintenanceService); + + beforeAll(async () => { + ctx = await controllerSetup(MaintenanceController, [{ provide: MaintenanceService, useValue: service }]); + return () => ctx.close(); + }); + + beforeEach(() => { + service.resetAllMocks(); + ctx.reset(); + }); + + describe('POST /admin/maintenance', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).post('/admin/maintenance').send(); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + + it('should require a backup file when action is restore', async () => { + const { status, body } = await request(ctx.getHttpServer()).post('/admin/maintenance').send({ + action: MaintenanceAction.RestoreDatabase, + }); + expect(status).toBe(400); + expect(body).toEqual( + errorDto.badRequest(['restoreBackupFilename must be a string', 'restoreBackupFilename should not be empty']), + ); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + }); +}); diff --git a/server/src/decorators.ts b/server/src/decorators.ts index 054bbf8fecd30..87a3900a7ff0a 100644 --- a/server/src/decorators.ts +++ b/server/src/decorators.ts @@ -171,7 +171,7 @@ export const Endpoint = ({ history, ...options }: EndpointOptions) => { return applyDecorators(...decorators); }; -type PropertyOptions = ApiPropertyOptions & { history?: HistoryBuilder }; +export type PropertyOptions = ApiPropertyOptions & { history?: HistoryBuilder }; export const Property = ({ history, ...options }: PropertyOptions) => { const extensions = history?.getExtensions() ?? {}; diff --git a/server/src/dtos/activity.dto.ts b/server/src/dtos/activity.dto.ts index 4b11a16e14cce..6464d88508cb6 100644 --- a/server/src/dtos/activity.dto.ts +++ b/server/src/dtos/activity.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsNotEmpty, IsString, ValidateIf } from 'class-validator'; import { Activity } from 'src/database'; import { mapUser, UserResponseDto } from 'src/dtos/user.dto'; @@ -17,48 +17,55 @@ export enum ReactionLevel { export type MaybeDuplicate = { duplicate: boolean; value: T }; export class ActivityResponseDto { + @ApiProperty({ description: 'Activity ID' }) id!: string; + @ApiProperty({ description: 'Creation date', format: 'date-time' }) createdAt!: Date; - @ValidateEnum({ enum: ReactionType, name: 'ReactionType' }) + @ValidateEnum({ enum: ReactionType, name: 'ReactionType', description: 'Activity type' }) type!: ReactionType; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) user!: UserResponseDto; + @ApiProperty({ description: 'Asset ID (if activity is for an asset)' }) assetId!: string | null; + @ApiPropertyOptional({ description: 'Comment text (for comment activities)' }) comment?: string | null; } export class ActivityStatisticsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of comments' }) comments!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of likes' }) likes!: number; } export class ActivityDto { - @ValidateUUID() + @ValidateUUID({ description: 'Album ID' }) albumId!: string; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Asset ID (if activity is for an asset)' }) assetId?: string; } export class ActivitySearchDto extends ActivityDto { - @ValidateEnum({ enum: ReactionType, name: 'ReactionType', optional: true }) + @ValidateEnum({ enum: ReactionType, name: 'ReactionType', description: 'Filter by activity type', optional: true }) type?: ReactionType; - @ValidateEnum({ enum: ReactionLevel, name: 'ReactionLevel', optional: true }) + @ValidateEnum({ enum: ReactionLevel, name: 'ReactionLevel', description: 'Filter by activity level', optional: true }) level?: ReactionLevel; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by user ID' }) userId?: string; } const isComment = (dto: ActivityCreateDto) => dto.type === ReactionType.COMMENT; export class ActivityCreateDto extends ActivityDto { - @ValidateEnum({ enum: ReactionType, name: 'ReactionType' }) + @ValidateEnum({ enum: ReactionType, name: 'ReactionType', description: 'Activity type (like or comment)' }) type!: ReactionType; + @ApiPropertyOptional({ description: 'Comment text (required if type is comment)' }) @ValidateIf(isComment) @IsNotEmpty() @IsString() diff --git a/server/src/dtos/album.dto.ts b/server/src/dtos/album.dto.ts index 2f3f22099aeec..0f46ebaa421bb 100644 --- a/server/src/dtos/album.dto.ts +++ b/server/src/dtos/album.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { ArrayNotEmpty, IsArray, IsString, ValidateNested } from 'class-validator'; import _ from 'lodash'; @@ -11,156 +11,181 @@ import { AlbumUserRole, AssetOrder } from 'src/enum'; import { Optional, ValidateBoolean, ValidateEnum, ValidateUUID } from 'src/validation'; export class AlbumInfoDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Exclude assets from response' }) withoutAssets?: boolean; } export class AlbumUserAddDto { - @ValidateUUID() + @ValidateUUID({ description: 'User ID' }) userId!: string; - @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole', default: AlbumUserRole.Editor }) + @ValidateEnum({ + enum: AlbumUserRole, + name: 'AlbumUserRole', + description: 'Album user role', + default: AlbumUserRole.Editor, + }) role?: AlbumUserRole; } export class AddUsersDto { + @ApiProperty({ description: 'Album users to add' }) @ArrayNotEmpty() albumUsers!: AlbumUserAddDto[]; } export class AlbumUserCreateDto { - @ValidateUUID() + @ValidateUUID({ description: 'User ID' }) userId!: string; - @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole' }) + @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole', description: 'Album user role' }) role!: AlbumUserRole; } export class CreateAlbumDto { + @ApiProperty({ description: 'Album name' }) @IsString() - @ApiProperty() albumName!: string; + @ApiPropertyOptional({ description: 'Album description' }) @IsString() @Optional() description?: string; + @ApiPropertyOptional({ description: 'Album users' }) @Optional() @IsArray() @ValidateNested({ each: true }) @Type(() => AlbumUserCreateDto) albumUsers?: AlbumUserCreateDto[]; - @ValidateUUID({ optional: true, each: true }) + @ValidateUUID({ optional: true, each: true, description: 'Initial asset IDs' }) assetIds?: string[]; } export class AlbumsAddAssetsDto { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Album IDs' }) albumIds!: string[]; - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Asset IDs' }) assetIds!: string[]; } export class AlbumsAddAssetsResponseDto { + @ApiProperty({ description: 'Operation success' }) success!: boolean; - @ValidateEnum({ enum: BulkIdErrorReason, name: 'BulkIdErrorReason', optional: true }) + @ValidateEnum({ enum: BulkIdErrorReason, name: 'BulkIdErrorReason', description: 'Error reason', optional: true }) error?: BulkIdErrorReason; } export class UpdateAlbumDto { + @ApiPropertyOptional({ description: 'Album name' }) @Optional() @IsString() albumName?: string; + @ApiPropertyOptional({ description: 'Album description' }) @Optional() @IsString() description?: string; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Album thumbnail asset ID' }) albumThumbnailAssetId?: string; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Enable activity feed' }) isActivityEnabled?: boolean; - @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', optional: true }) + @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', description: 'Asset sort order', optional: true }) order?: AssetOrder; } export class GetAlbumsDto { - @ValidateBoolean({ optional: true }) - /** - * true: only shared albums - * false: only non-shared own albums - * undefined: shared and owned albums - */ + @ValidateBoolean({ + optional: true, + description: 'Filter by shared status: true = only shared, false = only own, undefined = all', + }) shared?: boolean; - /** - * Only returns albums that contain the asset - * Ignores the shared parameter - * undefined: get all albums - */ - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter albums containing this asset ID (ignores shared parameter)' }) assetId?: string; } export class AlbumStatisticsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of owned albums' }) owned!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of shared albums' }) shared!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of non-shared albums' }) notShared!: number; } export class UpdateAlbumUserDto { - @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole' }) + @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole', description: 'Album user role' }) role!: AlbumUserRole; } export class AlbumUserResponseDto { + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) user!: UserResponseDto; - @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole' }) + @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole', description: 'Album user role' }) role!: AlbumUserRole; } export class ContributorCountResponseDto { - @ApiProperty() + @ApiProperty({ description: 'User ID' }) userId!: string; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets contributed' }) assetCount!: number; } export class AlbumResponseDto { + @ApiProperty({ description: 'Album ID' }) id!: string; + @ApiProperty({ description: 'Owner user ID' }) ownerId!: string; + @ApiProperty({ description: 'Album name' }) albumName!: string; + @ApiProperty({ description: 'Album description' }) description!: string; + @ApiProperty({ description: 'Creation date' }) createdAt!: Date; + @ApiProperty({ description: 'Last update date' }) updatedAt!: Date; + @ApiProperty({ description: 'Thumbnail asset ID' }) albumThumbnailAssetId!: string | null; + @ApiProperty({ description: 'Is shared album' }) shared!: boolean; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) albumUsers!: AlbumUserResponseDto[]; + @ApiProperty({ description: 'Has shared link' }) hasSharedLink!: boolean; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) assets!: AssetResponseDto[]; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) owner!: UserResponseDto; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets' }) assetCount!: number; + @ApiPropertyOptional({ description: 'Last modified asset timestamp' }) lastModifiedAssetTimestamp?: Date; + @ApiPropertyOptional({ description: 'Start date (earliest asset)' }) startDate?: Date; + @ApiPropertyOptional({ description: 'End date (latest asset)' }) endDate?: Date; + @ApiProperty({ description: 'Activity feed enabled' }) isActivityEnabled!: boolean; - @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', optional: true }) + @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', description: 'Asset sort order', optional: true }) order?: AssetOrder; - // Optional per-user contribution counts for shared albums + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Type(() => ContributorCountResponseDto) - @ApiProperty({ type: [ContributorCountResponseDto], required: false }) contributorCounts?: ContributorCountResponseDto[]; } diff --git a/server/src/dtos/api-key.dto.ts b/server/src/dtos/api-key.dto.ts index c9475fa2b13b1..273082c41b597 100644 --- a/server/src/dtos/api-key.dto.ts +++ b/server/src/dtos/api-key.dto.ts @@ -1,38 +1,55 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ArrayMinSize, IsNotEmpty, IsString } from 'class-validator'; import { Permission } from 'src/enum'; import { Optional, ValidateEnum } from 'src/validation'; + export class APIKeyCreateDto { + @ApiPropertyOptional({ description: 'API key name' }) @IsString() @IsNotEmpty() @Optional() name?: string; - @ValidateEnum({ enum: Permission, name: 'Permission', each: true }) + @ValidateEnum({ enum: Permission, name: 'Permission', each: true, description: 'List of permissions' }) @ArrayMinSize(1) permissions!: Permission[]; } export class APIKeyUpdateDto { + @ApiPropertyOptional({ description: 'API key name' }) @Optional() @IsString() @IsNotEmpty() name?: string; - @ValidateEnum({ enum: Permission, name: 'Permission', each: true, optional: true }) + @ValidateEnum({ + enum: Permission, + name: 'Permission', + description: 'List of permissions', + each: true, + optional: true, + }) @ArrayMinSize(1) permissions?: Permission[]; } -export class APIKeyCreateResponseDto { - secret!: string; - apiKey!: APIKeyResponseDto; -} - export class APIKeyResponseDto { + @ApiProperty({ description: 'API key ID' }) id!: string; + @ApiProperty({ description: 'API key name' }) name!: string; + @ApiProperty({ description: 'Creation date' }) createdAt!: Date; + @ApiProperty({ description: 'Last update date' }) updatedAt!: Date; - @ValidateEnum({ enum: Permission, name: 'Permission', each: true }) + @ValidateEnum({ enum: Permission, name: 'Permission', each: true, description: 'List of permissions' }) permissions!: Permission[]; } + +export class APIKeyCreateResponseDto { + @ApiProperty({ description: 'API key secret (only shown once)' }) + secret!: string; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) + apiKey!: APIKeyResponseDto; +} diff --git a/server/src/dtos/asset-ids.response.dto.ts b/server/src/dtos/asset-ids.response.dto.ts index fdc9942e37875..427117518d43a 100644 --- a/server/src/dtos/asset-ids.response.dto.ts +++ b/server/src/dtos/asset-ids.response.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ValidateUUID } from 'src/validation'; /** @deprecated Use `BulkIdResponseDto` instead */ @@ -9,8 +10,11 @@ export enum AssetIdErrorReason { /** @deprecated Use `BulkIdResponseDto` instead */ export class AssetIdsResponseDto { + @ApiProperty({ description: 'Asset ID' }) assetId!: string; + @ApiProperty({ description: 'Whether operation succeeded' }) success!: boolean; + @ApiPropertyOptional({ description: 'Error reason if failed', enum: AssetIdErrorReason }) error?: AssetIdErrorReason; } @@ -22,12 +26,15 @@ export enum BulkIdErrorReason { } export class BulkIdsDto { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'IDs to process' }) ids!: string[]; } export class BulkIdResponseDto { + @ApiProperty({ description: 'ID' }) id!: string; + @ApiProperty({ description: 'Whether operation succeeded' }) success!: boolean; + @ApiPropertyOptional({ description: 'Error reason if failed', enum: BulkIdErrorReason }) error?: BulkIdErrorReason; } diff --git a/server/src/dtos/asset-media-response.dto.ts b/server/src/dtos/asset-media-response.dto.ts index 887762dbdd527..345c1bf4180b2 100644 --- a/server/src/dtos/asset-media-response.dto.ts +++ b/server/src/dtos/asset-media-response.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ValidateEnum } from 'src/validation'; export enum AssetMediaStatus { @@ -6,8 +7,9 @@ export enum AssetMediaStatus { DUPLICATE = 'duplicate', } export class AssetMediaResponseDto { - @ValidateEnum({ enum: AssetMediaStatus, name: 'AssetMediaStatus' }) + @ValidateEnum({ enum: AssetMediaStatus, name: 'AssetMediaStatus', description: 'Upload status' }) status!: AssetMediaStatus; + @ApiProperty({ description: 'Asset media ID' }) id!: string; } @@ -22,17 +24,24 @@ export enum AssetRejectReason { } export class AssetBulkUploadCheckResult { + @ApiProperty({ description: 'Asset ID' }) id!: string; + @ApiProperty({ description: 'Upload action', enum: AssetUploadAction }) action!: AssetUploadAction; + @ApiPropertyOptional({ description: 'Rejection reason if rejected', enum: AssetRejectReason }) reason?: AssetRejectReason; + @ApiPropertyOptional({ description: 'Existing asset ID if duplicate' }) assetId?: string; + @ApiPropertyOptional({ description: 'Whether existing asset is trashed' }) isTrashed?: boolean; } export class AssetBulkUploadCheckResponseDto { + @ApiProperty({ description: 'Upload check results' }) results!: AssetBulkUploadCheckResult[]; } export class CheckExistingAssetsResponseDto { + @ApiProperty({ description: 'Existing asset IDs' }) existingIds!: string[]; } diff --git a/server/src/dtos/asset-media.dto.ts b/server/src/dtos/asset-media.dto.ts index 3935774f3e0f2..46558503793c3 100644 --- a/server/src/dtos/asset-media.dto.ts +++ b/server/src/dtos/asset-media.dto.ts @@ -1,5 +1,5 @@ import { BadRequestException } from '@nestjs/common'; -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { plainToInstance, Transform, Type } from 'class-transformer'; import { ArrayNotEmpty, IsArray, IsNotEmpty, IsString, ValidateNested } from 'class-validator'; import { AssetMetadataUpsertItemDto } from 'src/dtos/asset.dto'; @@ -18,10 +18,10 @@ export enum AssetMediaSize { } export class AssetMediaOptionsDto { - @ValidateEnum({ enum: AssetMediaSize, name: 'AssetMediaSize', optional: true }) + @ValidateEnum({ enum: AssetMediaSize, name: 'AssetMediaSize', description: 'Asset media size', optional: true }) size?: AssetMediaSize; - @ValidateBoolean({ optional: true, default: false }) + @ValidateBoolean({ optional: true, description: 'Return edited asset if available', default: false }) edited?: boolean; } @@ -32,44 +32,49 @@ export enum UploadFieldName { } class AssetMediaBase { + @ApiProperty({ description: 'Device asset ID' }) @IsNotEmpty() @IsString() deviceAssetId!: string; + @ApiProperty({ description: 'Device ID' }) @IsNotEmpty() @IsString() deviceId!: string; - @ValidateDate() + @ValidateDate({ description: 'File creation date' }) fileCreatedAt!: Date; - @ValidateDate() + @ValidateDate({ description: 'File modification date' }) fileModifiedAt!: Date; + @ApiPropertyOptional({ description: 'Duration (for videos)' }) @Optional() @IsString() duration?: string; + @ApiPropertyOptional({ description: 'Filename' }) @Optional() @IsString() filename?: string; // The properties below are added to correctly generate the API docs // and client SDKs. Validation should be handled in the controller. - @ApiProperty({ type: 'string', format: 'binary' }) + @ApiProperty({ type: 'string', format: 'binary', description: 'Asset file data' }) [UploadFieldName.ASSET_DATA]!: any; } export class AssetMediaCreateDto extends AssetMediaBase { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Mark as favorite' }) isFavorite?: boolean; - @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', optional: true }) + @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', description: 'Asset visibility', optional: true }) visibility?: AssetVisibility; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Live photo video ID' }) livePhotoVideoId?: string; + @ApiPropertyOptional({ description: 'Asset metadata items' }) @Transform(({ value }) => { try { const json = JSON.parse(value); @@ -84,24 +89,26 @@ export class AssetMediaCreateDto extends AssetMediaBase { @IsArray() metadata?: AssetMetadataUpsertItemDto[]; - @ApiProperty({ type: 'string', format: 'binary', required: false }) + @ApiProperty({ type: 'string', format: 'binary', required: false, description: 'Sidecar file data' }) [UploadFieldName.SIDECAR_DATA]?: any; } export class AssetMediaReplaceDto extends AssetMediaBase {} export class AssetBulkUploadCheckItem { + @ApiProperty({ description: 'Asset ID' }) @IsString() @IsNotEmpty() id!: string; - /** base64 or hex encoded sha1 hash */ + @ApiProperty({ description: 'Base64 or hex encoded SHA1 hash' }) @IsString() @IsNotEmpty() checksum!: string; } export class AssetBulkUploadCheckDto { + @ApiProperty({ description: 'Assets to check' }) @IsArray() @ValidateNested({ each: true }) @Type(() => AssetBulkUploadCheckItem) @@ -109,11 +116,13 @@ export class AssetBulkUploadCheckDto { } export class CheckExistingAssetsDto { + @ApiProperty({ description: 'Device asset IDs to check' }) @ArrayNotEmpty() @IsString({ each: true }) @IsNotEmpty({ each: true }) deviceAssetIds!: string[]; + @ApiProperty({ description: 'Device ID' }) @IsNotEmpty() deviceId!: string; } diff --git a/server/src/dtos/asset-response.dto.ts b/server/src/dtos/asset-response.dto.ts index 92ee3c587575c..e163b386beffa 100644 --- a/server/src/dtos/asset-response.dto.ts +++ b/server/src/dtos/asset-response.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Selectable } from 'kysely'; import { AssetFace, AssetFile, Exif, Stack, Tag, User } from 'src/database'; import { HistoryBuilder, Property } from 'src/decorators'; @@ -18,13 +18,16 @@ import { ImageDimensions } from 'src/types'; import { getDimensions } from 'src/utils/asset.util'; import { hexOrBufferToBase64 } from 'src/utils/bytes'; import { mimeTypes } from 'src/utils/mime-types'; -import { ValidateEnum } from 'src/validation'; +import { ValidateEnum, ValidateUUID } from 'src/validation'; export class SanitizedAssetResponseDto { + @ApiProperty({ description: 'Asset ID' }) id!: string; - @ValidateEnum({ enum: AssetType, name: 'AssetTypeEnum' }) + @ValidateEnum({ enum: AssetType, name: 'AssetTypeEnum', description: 'Asset type' }) type!: AssetType; + @ApiProperty({ description: 'Thumbhash for thumbnail generation' }) thumbhash!: string | null; + @ApiPropertyOptional({ description: 'Original MIME type' }) originalMimeType?: string; @ApiProperty({ type: 'string', @@ -34,10 +37,15 @@ export class SanitizedAssetResponseDto { example: '2024-01-15T14:30:00.000Z', }) localDateTime!: Date; + @ApiProperty({ description: 'Video duration (for videos)' }) duration!: string; + @ApiPropertyOptional({ description: 'Live photo video ID' }) livePhotoVideoId?: string | null; + @ApiProperty({ description: 'Whether asset has metadata' }) hasMetadata!: boolean; + @ApiProperty({ description: 'Asset width' }) width!: number | null; + @ApiProperty({ description: 'Asset height' }) height!: number | null; } @@ -49,13 +57,24 @@ export class AssetResponseDto extends SanitizedAssetResponseDto { example: '2024-01-15T20:30:00.000Z', }) createdAt!: Date; + @ApiProperty({ description: 'Device asset ID' }) deviceAssetId!: string; + @ApiProperty({ description: 'Device ID' }) deviceId!: string; + @ApiProperty({ description: 'Owner user ID' }) ownerId!: string; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) owner?: UserResponseDto; - @Property({ history: new HistoryBuilder().added('v1').deprecated('v1') }) + @ValidateUUID({ + nullable: true, + description: 'Library ID', + history: new HistoryBuilder().added('v1').deprecated('v1'), + }) libraryId?: string | null; + @ApiProperty({ description: 'Original file path' }) originalPath!: string; + @ApiProperty({ description: 'Original file name' }) originalFileName!: string; @ApiProperty({ type: 'string', @@ -81,24 +100,39 @@ export class AssetResponseDto extends SanitizedAssetResponseDto { example: '2024-01-16T12:45:30.000Z', }) updatedAt!: Date; + @ApiProperty({ description: 'Is favorite' }) isFavorite!: boolean; + @ApiProperty({ description: 'Is archived' }) isArchived!: boolean; + @ApiProperty({ description: 'Is trashed' }) isTrashed!: boolean; + @ApiProperty({ description: 'Is offline' }) isOffline!: boolean; - @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility' }) + @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', description: 'Asset visibility' }) visibility!: AssetVisibility; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) exifInfo?: ExifResponseDto; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) tags?: TagResponseDto[]; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) people?: PersonWithFacesResponseDto[]; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) unassignedFaces?: AssetFaceWithoutPersonResponseDto[]; - /**base64 encoded sha1 hash */ + @ApiProperty({ description: 'Base64 encoded SHA1 hash' }) checksum!: string; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) stack?: AssetStackResponseDto | null; + @ApiPropertyOptional({ description: 'Duplicate group ID' }) duplicateId?: string | null; - @Property({ history: new HistoryBuilder().added('v1').deprecated('v1.113.0') }) + @Property({ description: 'Is resized', history: new HistoryBuilder().added('v1').deprecated('v1.113.0') }) resized?: boolean; - @Property({ history: new HistoryBuilder().added('v2.5.0').beta('v2.5.0') }) + @Property({ description: 'Is edited', history: new HistoryBuilder().added('v2.5.0').beta('v2.5.0') }) isEdited!: boolean; } @@ -143,11 +177,13 @@ export type MapAsset = { }; export class AssetStackResponseDto { + @ApiProperty({ description: 'Stack ID' }) id!: string; + @ApiProperty({ description: 'Primary asset ID' }) primaryAssetId!: string; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets in stack' }) assetCount!: number; } diff --git a/server/src/dtos/asset.dto.ts b/server/src/dtos/asset.dto.ts index 5ac79a9895c53..47226e1503046 100644 --- a/server/src/dtos/asset.dto.ts +++ b/server/src/dtos/asset.dto.ts @@ -22,6 +22,7 @@ import { AssetStats } from 'src/repositories/asset.repository'; import { IsNotSiblingOf, Optional, ValidateBoolean, ValidateEnum, ValidateString, ValidateUUID } from 'src/validation'; export class DeviceIdDto { + @ApiProperty({ description: 'Device ID' }) @IsNotEmpty() @IsString() deviceId!: string; @@ -32,49 +33,57 @@ const hasGPS = (o: { latitude: undefined; longitude: undefined }) => const ValidateGPS = () => ValidateIf(hasGPS); export class UpdateAssetBase { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Mark as favorite' }) isFavorite?: boolean; - @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', optional: true }) + @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', optional: true, description: 'Asset visibility' }) visibility?: AssetVisibility; + @ApiProperty({ description: 'Original date and time' }) @Optional() @IsDateString() dateTimeOriginal?: string; + @ApiProperty({ description: 'Latitude coordinate' }) @ValidateGPS() @IsLatitude() @IsNotEmpty() latitude?: number; + @ApiProperty({ description: 'Longitude coordinate' }) @ValidateGPS() @IsLongitude() @IsNotEmpty() longitude?: number; + @ApiProperty({ description: 'Rating' }) @Optional() @IsInt() @Max(5) @Min(-1) rating?: number; + @ApiProperty({ description: 'Asset description' }) @Optional() @IsString() description?: string; } export class AssetBulkUpdateDto extends UpdateAssetBase { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Asset IDs to update' }) ids!: string[]; + @ApiProperty({ description: 'Duplicate asset ID' }) @Optional() duplicateId?: string | null; + @ApiProperty({ description: 'Relative time offset in seconds' }) @IsNotSiblingOf(['dateTimeOriginal']) @Optional() @IsInt() dateTimeRelative?: number; + @ApiProperty({ description: 'Time zone (IANA timezone)' }) @IsNotSiblingOf(['dateTimeOriginal']) @IsTimeZone() @Optional() @@ -82,11 +91,12 @@ export class AssetBulkUpdateDto extends UpdateAssetBase { } export class UpdateAssetDto extends UpdateAssetBase { - @ValidateUUID({ optional: true, nullable: true }) + @ValidateUUID({ optional: true, nullable: true, description: 'Live photo video ID' }) livePhotoVideoId?: string | null; } export class RandomAssetsDto { + @ApiProperty({ description: 'Number of random assets to return' }) @Optional() @IsInt() @IsPositive() @@ -95,12 +105,12 @@ export class RandomAssetsDto { } export class AssetBulkDeleteDto extends BulkIdsDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Force delete even if in use' }) force?: boolean; } export class AssetIdsDto { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Asset IDs' }) assetIds!: string[]; } @@ -112,41 +122,42 @@ export enum AssetJobName { } export class AssetJobsDto extends AssetIdsDto { - @ValidateEnum({ enum: AssetJobName, name: 'AssetJobName' }) + @ValidateEnum({ enum: AssetJobName, name: 'AssetJobName', description: 'Job name' }) name!: AssetJobName; } export class AssetStatsDto { - @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', optional: true }) + @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', description: 'Filter by visibility', optional: true }) visibility?: AssetVisibility; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by favorite status' }) isFavorite?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by trash status' }) isTrashed?: boolean; } export class AssetStatsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ description: 'Number of images', type: 'integer' }) images!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ description: 'Number of videos', type: 'integer' }) videos!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ description: 'Total number of assets', type: 'integer' }) total!: number; } export class AssetMetadataRouteParams { - @ValidateUUID() + @ValidateUUID({ description: 'Asset ID' }) id!: string; - @ValidateString() + @ValidateString({ description: 'Metadata key' }) key!: string; } export class AssetMetadataUpsertDto { + @ApiProperty({ description: 'Metadata items to upsert' }) @IsArray() @ValidateNested({ each: true }) @Type(() => AssetMetadataUpsertItemDto) @@ -154,14 +165,16 @@ export class AssetMetadataUpsertDto { } export class AssetMetadataUpsertItemDto { - @ValidateString() + @ValidateString({ description: 'Metadata key' }) key!: string; + @ApiProperty({ description: 'Metadata value (object)' }) @IsObject() value!: object; } export class AssetMetadataBulkUpsertDto { + @ApiProperty({ description: 'Metadata items to upsert' }) @IsArray() @ValidateNested({ each: true }) @Type(() => AssetMetadataBulkUpsertItemDto) @@ -169,17 +182,19 @@ export class AssetMetadataBulkUpsertDto { } export class AssetMetadataBulkUpsertItemDto { - @ValidateUUID() + @ValidateUUID({ description: 'Asset ID' }) assetId!: string; - @ValidateString() + @ValidateString({ description: 'Metadata key' }) key!: string; + @ApiProperty({ description: 'Metadata value (object)' }) @IsObject() value!: object; } export class AssetMetadataBulkDeleteDto { + @ApiProperty({ description: 'Metadata items to delete' }) @IsArray() @ValidateNested({ each: true }) @Type(() => AssetMetadataBulkDeleteItemDto) @@ -187,49 +202,54 @@ export class AssetMetadataBulkDeleteDto { } export class AssetMetadataBulkDeleteItemDto { - @ValidateUUID() + @ValidateUUID({ description: 'Asset ID' }) assetId!: string; - @ValidateString() + @ValidateString({ description: 'Metadata key' }) key!: string; } export class AssetMetadataResponseDto { - @ValidateString() + @ValidateString({ description: 'Metadata key' }) key!: string; + + @ApiProperty({ description: 'Metadata value (object)' }) value!: object; + + @ApiProperty({ description: 'Last update date' }) updatedAt!: Date; } export class AssetMetadataBulkResponseDto extends AssetMetadataResponseDto { + @ApiProperty({ description: 'Asset ID' }) assetId!: string; } export class AssetCopyDto { - @ValidateUUID() + @ValidateUUID({ description: 'Source asset ID' }) sourceId!: string; - @ValidateUUID() + @ValidateUUID({ description: 'Target asset ID' }) targetId!: string; - @ValidateBoolean({ optional: true, default: true }) + @ValidateBoolean({ optional: true, description: 'Copy shared links', default: true }) sharedLinks?: boolean; - @ValidateBoolean({ optional: true, default: true }) + @ValidateBoolean({ optional: true, description: 'Copy album associations', default: true }) albums?: boolean; - @ValidateBoolean({ optional: true, default: true }) + @ValidateBoolean({ optional: true, description: 'Copy sidecar file', default: true }) sidecar?: boolean; - @ValidateBoolean({ optional: true, default: true }) + @ValidateBoolean({ optional: true, description: 'Copy stack association', default: true }) stack?: boolean; - @ValidateBoolean({ optional: true, default: true }) + @ValidateBoolean({ optional: true, description: 'Copy favorite status', default: true }) favorite?: boolean; } export class AssetDownloadOriginalDto { - @ValidateBoolean({ optional: true, default: false }) + @ValidateBoolean({ optional: true, description: 'Return edited asset if available', default: false }) edited?: boolean; } diff --git a/server/src/dtos/auth.dto.ts b/server/src/dtos/auth.dto.ts index d700fc2ab8ba2..3df82f4ef405e 100644 --- a/server/src/dtos/auth.dto.ts +++ b/server/src/dtos/auth.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator'; import { AuthApiKey, AuthSession, AuthSharedLink, AuthUser, UserAdmin } from 'src/database'; @@ -12,34 +12,46 @@ export type CookieResponse = { }; export class AuthDto { + @ApiProperty({ description: 'Authenticated user' }) user!: AuthUser; + @ApiPropertyOptional({ description: 'API key (if authenticated via API key)' }) apiKey?: AuthApiKey; + @ApiPropertyOptional({ description: 'Shared link (if authenticated via shared link)' }) sharedLink?: AuthSharedLink; + @ApiPropertyOptional({ description: 'Session (if authenticated via session)' }) session?: AuthSession; } export class LoginCredentialDto { + @ApiProperty({ example: 'testuser@email.com', description: 'User email' }) @IsEmail({ require_tld: false }) @Transform(toEmail) @IsNotEmpty() - @ApiProperty({ example: 'testuser@email.com' }) email!: string; + @ApiProperty({ example: 'password', description: 'User password' }) @IsString() @IsNotEmpty() - @ApiProperty({ example: 'password' }) password!: string; } export class LoginResponseDto { + @ApiProperty({ description: 'Access token' }) accessToken!: string; + @ApiProperty({ description: 'User ID' }) userId!: string; + @ApiProperty({ description: 'User email' }) userEmail!: string; + @ApiProperty({ description: 'User name' }) name!: string; + @ApiProperty({ description: 'Profile image path' }) profileImagePath!: string; + @ApiProperty({ description: 'Is admin user' }) isAdmin!: boolean; + @ApiProperty({ description: 'Should change password' }) shouldChangePassword!: boolean; + @ApiProperty({ description: 'Is onboarded' }) isOnboarded!: boolean; } @@ -61,42 +73,47 @@ export function mapLoginResponse(entity: UserAdmin, accessToken: string): LoginR } export class LogoutResponseDto { + @ApiProperty({ description: 'Logout successful' }) successful!: boolean; + @ApiProperty({ description: 'Redirect URI' }) redirectUri!: string; } export class SignUpDto extends LoginCredentialDto { + @ApiProperty({ example: 'Admin', description: 'User name' }) @IsString() @IsNotEmpty() - @ApiProperty({ example: 'Admin' }) name!: string; } export class ChangePasswordDto { + @ApiProperty({ example: 'password', description: 'Current password' }) @IsString() @IsNotEmpty() - @ApiProperty({ example: 'password' }) password!: string; + @ApiProperty({ example: 'password', description: 'New password (min 8 characters)' }) @IsString() @IsNotEmpty() @MinLength(8) - @ApiProperty({ example: 'password' }) newPassword!: string; - @ValidateBoolean({ optional: true, default: false }) + @ValidateBoolean({ optional: true, default: false, description: 'Invalidate all other sessions' }) invalidateSessions?: boolean; } export class PinCodeSetupDto { + @ApiProperty({ description: 'PIN code (4-6 digits)' }) @PinCode() pinCode!: string; } export class PinCodeResetDto { + @ApiPropertyOptional({ description: 'New PIN code (4-6 digits)' }) @PinCode({ optional: true }) pinCode?: string; + @ApiPropertyOptional({ description: 'User password (required if PIN code is not provided)' }) @Optional() @IsString() @IsNotEmpty() @@ -106,51 +123,64 @@ export class PinCodeResetDto { export class SessionUnlockDto extends PinCodeResetDto {} export class PinCodeChangeDto extends PinCodeResetDto { + @ApiProperty({ description: 'New PIN code (4-6 digits)' }) @PinCode() newPinCode!: string; } export class ValidateAccessTokenResponseDto { + @ApiProperty({ description: 'Authentication status' }) authStatus!: boolean; } export class OAuthCallbackDto { + @ApiProperty({ description: 'OAuth callback URL' }) @IsNotEmpty() @IsString() - @ApiProperty() url!: string; + @ApiPropertyOptional({ description: 'OAuth state parameter' }) @Optional() @IsString() state?: string; + @ApiPropertyOptional({ description: 'OAuth code verifier (PKCE)' }) @Optional() @IsString() codeVerifier?: string; } export class OAuthConfigDto { + @ApiProperty({ description: 'OAuth redirect URI' }) @IsNotEmpty() @IsString() redirectUri!: string; + @ApiPropertyOptional({ description: 'OAuth state parameter' }) @Optional() @IsString() state?: string; + @ApiPropertyOptional({ description: 'OAuth code challenge (PKCE)' }) @Optional() @IsString() codeChallenge?: string; } export class OAuthAuthorizeResponseDto { + @ApiProperty({ description: 'OAuth authorization URL' }) url!: string; } export class AuthStatusResponseDto { + @ApiProperty({ description: 'Has PIN code set' }) pinCode!: boolean; + @ApiProperty({ description: 'Has password set' }) password!: boolean; + @ApiProperty({ description: 'Is elevated session' }) isElevated!: boolean; + @ApiPropertyOptional({ description: 'Session expiration date' }) expiresAt?: string; + @ApiPropertyOptional({ description: 'PIN expiration date' }) pinExpiresAt?: string; } diff --git a/server/src/dtos/download.dto.ts b/server/src/dtos/download.dto.ts index e6588a99445c4..2f877e3c0bb96 100644 --- a/server/src/dtos/download.dto.ts +++ b/server/src/dtos/download.dto.ts @@ -1,32 +1,34 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsInt, IsPositive } from 'class-validator'; import { Optional, ValidateUUID } from 'src/validation'; export class DownloadInfoDto { - @ValidateUUID({ each: true, optional: true }) + @ValidateUUID({ each: true, optional: true, description: 'Asset IDs to download' }) assetIds?: string[]; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Album ID to download' }) albumId?: string; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'User ID to download assets from' }) userId?: string; + @ApiPropertyOptional({ type: 'integer', description: 'Archive size limit in bytes' }) @IsInt() @IsPositive() @Optional() - @ApiProperty({ type: 'integer' }) archiveSize?: number; } export class DownloadResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total size in bytes' }) totalSize!: number; + @ApiProperty({ description: 'Archive information' }) archives!: DownloadArchiveInfo[]; } export class DownloadArchiveInfo { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Archive size in bytes' }) size!: number; + @ApiProperty({ description: 'Asset IDs in this archive' }) assetIds!: string[]; } diff --git a/server/src/dtos/duplicate.dto.ts b/server/src/dtos/duplicate.dto.ts index 166f18ce8f6fc..9cd9147ec5ca7 100644 --- a/server/src/dtos/duplicate.dto.ts +++ b/server/src/dtos/duplicate.dto.ts @@ -1,6 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; import { AssetResponseDto } from 'src/dtos/asset-response.dto'; export class DuplicateResponseDto { + @ApiProperty({ description: 'Duplicate group ID' }) duplicateId!: string; + @ApiProperty({ description: 'Duplicate assets' }) assets!: AssetResponseDto[]; } diff --git a/server/src/dtos/editing.dto.ts b/server/src/dtos/editing.dto.ts index 56bd09f3ea62b..8bb1eef47b82b 100644 --- a/server/src/dtos/editing.dto.ts +++ b/server/src/dtos/editing.dto.ts @@ -50,28 +50,31 @@ export class MirrorParameters { class AssetEditActionBase { @IsEnum(AssetEditAction) - @ApiProperty({ enum: AssetEditAction, enumName: 'AssetEditAction' }) + @ApiProperty({ enum: AssetEditAction, enumName: 'AssetEditAction', description: 'Type of edit action to perform' }) action!: AssetEditAction; } export class AssetEditActionCrop extends AssetEditActionBase { @ValidateNested() @Type(() => CropParameters) - @ApiProperty({ type: CropParameters }) + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) parameters!: CropParameters; } export class AssetEditActionRotate extends AssetEditActionBase { @ValidateNested() @Type(() => RotateParameters) - @ApiProperty({ type: RotateParameters }) + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) parameters!: RotateParameters; } export class AssetEditActionMirror extends AssetEditActionBase { @ValidateNested() @Type(() => MirrorParameters) - @ApiProperty({ type: MirrorParameters }) + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) parameters!: MirrorParameters; } @@ -114,12 +117,14 @@ export class AssetEditActionListDto { @Transform(({ value: edits }) => Array.isArray(edits) ? edits.map((item) => plainToInstance(getActionClass(item), item)) : edits, ) - @ApiProperty({ anyOf: Object.values(actionToClass).map((target) => ({ $ref: getSchemaPath(target) })) }) + @ApiProperty({ + anyOf: Object.values(actionToClass).map((target) => ({ $ref: getSchemaPath(target) })), + description: 'List of edit actions to apply (crop, rotate, or mirror)', + }) edits!: AssetEditActionItem[]; } export class AssetEditsDto extends AssetEditActionListDto { - @ValidateUUID() - @ApiProperty() + @ValidateUUID({ description: 'Asset ID to apply edits to' }) assetId!: string; } diff --git a/server/src/dtos/exif.dto.ts b/server/src/dtos/exif.dto.ts index 9fa61d93c8f64..0052b95b6ec9b 100644 --- a/server/src/dtos/exif.dto.ts +++ b/server/src/dtos/exif.dto.ts @@ -1,30 +1,51 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Exif } from 'src/database'; export class ExifResponseDto { + @ApiPropertyOptional({ description: 'Camera make' }) make?: string | null = null; + @ApiPropertyOptional({ description: 'Camera model' }) model?: string | null = null; + @ApiPropertyOptional({ type: 'number', description: 'Image width in pixels' }) exifImageWidth?: number | null = null; + @ApiPropertyOptional({ type: 'number', description: 'Image height in pixels' }) exifImageHeight?: number | null = null; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'File size in bytes' }) fileSizeInByte?: number | null = null; + @ApiPropertyOptional({ description: 'Image orientation' }) orientation?: string | null = null; + @ApiPropertyOptional({ description: 'Original date/time', format: 'date-time' }) dateTimeOriginal?: Date | null = null; + @ApiPropertyOptional({ description: 'Modification date/time', format: 'date-time' }) modifyDate?: Date | null = null; + @ApiPropertyOptional({ description: 'Time zone' }) timeZone?: string | null = null; + @ApiPropertyOptional({ description: 'Lens model' }) lensModel?: string | null = null; + @ApiPropertyOptional({ type: 'number', description: 'F-number (aperture)' }) fNumber?: number | null = null; + @ApiPropertyOptional({ type: 'number', description: 'Focal length in mm' }) focalLength?: number | null = null; + @ApiPropertyOptional({ type: 'number', description: 'ISO sensitivity' }) iso?: number | null = null; + @ApiPropertyOptional({ description: 'Exposure time' }) exposureTime?: string | null = null; + @ApiPropertyOptional({ type: 'number', description: 'GPS latitude' }) latitude?: number | null = null; + @ApiPropertyOptional({ type: 'number', description: 'GPS longitude' }) longitude?: number | null = null; + @ApiPropertyOptional({ description: 'City name' }) city?: string | null = null; + @ApiPropertyOptional({ description: 'State/province name' }) state?: string | null = null; + @ApiPropertyOptional({ description: 'Country name' }) country?: string | null = null; + @ApiPropertyOptional({ description: 'Image description' }) description?: string | null = null; + @ApiPropertyOptional({ description: 'Projection type' }) projectionType?: string | null = null; + @ApiPropertyOptional({ type: 'number', description: 'Rating' }) rating?: number | null = null; } diff --git a/server/src/dtos/job.dto.ts b/server/src/dtos/job.dto.ts index 794af6e5e072b..ef34a417203ca 100644 --- a/server/src/dtos/job.dto.ts +++ b/server/src/dtos/job.dto.ts @@ -2,6 +2,6 @@ import { ManualJobName } from 'src/enum'; import { ValidateEnum } from 'src/validation'; export class JobCreateDto { - @ValidateEnum({ enum: ManualJobName, name: 'ManualJobName' }) + @ValidateEnum({ enum: ManualJobName, name: 'ManualJobName', description: 'Job name' }) name!: ManualJobName; } diff --git a/server/src/dtos/library.dto.ts b/server/src/dtos/library.dto.ts index a0aaace13d61b..3f71b8a0ed692 100644 --- a/server/src/dtos/library.dto.ts +++ b/server/src/dtos/library.dto.ts @@ -1,17 +1,19 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { ArrayMaxSize, ArrayUnique, IsNotEmpty, IsString } from 'class-validator'; import { Library } from 'src/database'; import { Optional, ValidateUUID } from 'src/validation'; export class CreateLibraryDto { - @ValidateUUID() + @ValidateUUID({ description: 'Owner user ID' }) ownerId!: string; + @ApiPropertyOptional({ description: 'Library name' }) @IsString() @Optional() @IsNotEmpty() name?: string; + @ApiPropertyOptional({ description: 'Import paths (max 128)' }) @Optional() @IsString({ each: true }) @IsNotEmpty({ each: true }) @@ -19,6 +21,7 @@ export class CreateLibraryDto { @ArrayMaxSize(128) importPaths?: string[]; + @ApiPropertyOptional({ description: 'Exclusion patterns (max 128)' }) @Optional() @IsString({ each: true }) @IsNotEmpty({ each: true }) @@ -28,11 +31,13 @@ export class CreateLibraryDto { } export class UpdateLibraryDto { + @ApiPropertyOptional({ description: 'Library name' }) @Optional() @IsString() @IsNotEmpty() name?: string; + @ApiPropertyOptional({ description: 'Import paths (max 128)' }) @Optional() @IsString({ each: true }) @IsNotEmpty({ each: true }) @@ -40,6 +45,7 @@ export class UpdateLibraryDto { @ArrayMaxSize(128) importPaths?: string[]; + @ApiPropertyOptional({ description: 'Exclusion patterns (max 128)' }) @Optional() @IsNotEmpty({ each: true }) @IsString({ each: true }) @@ -59,6 +65,7 @@ export interface WalkOptionsDto extends CrawlOptionsDto { } export class ValidateLibraryDto { + @ApiPropertyOptional({ description: 'Import paths to validate (max 128)' }) @Optional() @IsString({ each: true }) @IsNotEmpty({ each: true }) @@ -66,6 +73,7 @@ export class ValidateLibraryDto { @ArrayMaxSize(128) importPaths?: string[]; + @ApiPropertyOptional({ description: 'Exclusion patterns (max 128)' }) @Optional() @IsNotEmpty({ each: true }) @IsString({ each: true }) @@ -75,48 +83,60 @@ export class ValidateLibraryDto { } export class ValidateLibraryResponseDto { + @ApiPropertyOptional({ description: 'Validation results for import paths' }) importPaths?: ValidateLibraryImportPathResponseDto[]; } export class ValidateLibraryImportPathResponseDto { + @ApiProperty({ description: 'Import path' }) importPath!: string; + @ApiProperty({ description: 'Is valid' }) isValid: boolean = false; + @ApiPropertyOptional({ description: 'Validation message' }) message?: string; } export class LibrarySearchDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by user ID' }) userId?: string; } export class LibraryResponseDto { + @ApiProperty({ description: 'Library ID' }) id!: string; + @ApiProperty({ description: 'Owner user ID' }) ownerId!: string; + @ApiProperty({ description: 'Library name' }) name!: string; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets' }) assetCount!: number; + @ApiProperty({ description: 'Import paths' }) importPaths!: string[]; + @ApiProperty({ description: 'Exclusion patterns' }) exclusionPatterns!: string[]; + @ApiProperty({ description: 'Creation date' }) createdAt!: Date; + @ApiProperty({ description: 'Last update date' }) updatedAt!: Date; + @ApiProperty({ description: 'Last refresh date' }) refreshedAt!: Date | null; } export class LibraryStatsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of photos' }) photos = 0; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of videos' }) videos = 0; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of assets' }) total = 0; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage usage in bytes' }) usage = 0; } diff --git a/server/src/dtos/license.dto.ts b/server/src/dtos/license.dto.ts index 6020d06b6f9f5..14232940b698c 100644 --- a/server/src/dtos/license.dto.ts +++ b/server/src/dtos/license.dto.ts @@ -1,16 +1,20 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, Matches } from 'class-validator'; export class LicenseKeyDto { + @ApiProperty({ description: 'License key (format: IM(SV|CL)(-XXXX){8})' }) @IsString() @IsNotEmpty() @Matches(/IM(SV|CL)(-[\dA-Za-z]{4}){8}/) licenseKey!: string; + @ApiProperty({ description: 'Activation key' }) @IsString() @IsNotEmpty() activationKey!: string; } export class LicenseResponseDto extends LicenseKeyDto { + @ApiProperty({ description: 'Activation date' }) activatedAt!: Date; } diff --git a/server/src/dtos/maintenance.dto.ts b/server/src/dtos/maintenance.dto.ts index 4b8c39c55e7af..f31d9ffa231b5 100644 --- a/server/src/dtos/maintenance.dto.ts +++ b/server/src/dtos/maintenance.dto.ts @@ -1,29 +1,31 @@ +import { ApiProperty } from '@nestjs/swagger'; import { ValidateIf } from 'class-validator'; import { MaintenanceAction, StorageFolder } from 'src/enum'; -import { ValidateEnum, ValidateString } from 'src/validation'; +import { ValidateBoolean, ValidateEnum, ValidateString } from 'src/validation'; export class SetMaintenanceModeDto { - @ValidateEnum({ enum: MaintenanceAction, name: 'MaintenanceAction' }) + @ValidateEnum({ enum: MaintenanceAction, name: 'MaintenanceAction', description: 'Maintenance action' }) action!: MaintenanceAction; @ValidateIf((o) => o.action === MaintenanceAction.RestoreDatabase) - @ValidateString() + @ValidateString({ description: 'Restore backup filename' }) restoreBackupFilename?: string; } export class MaintenanceLoginDto { - @ValidateString({ optional: true }) + @ValidateString({ optional: true, description: 'Maintenance token' }) token?: string; } export class MaintenanceAuthDto { + @ApiProperty({ description: 'Maintenance username' }) username!: string; } export class MaintenanceStatusResponseDto { active!: boolean; - @ValidateEnum({ enum: MaintenanceAction, name: 'MaintenanceAction' }) + @ValidateEnum({ enum: MaintenanceAction, name: 'MaintenanceAction', description: 'Maintenance action' }) action!: MaintenanceAction; progress?: number; @@ -32,10 +34,13 @@ export class MaintenanceStatusResponseDto { } export class MaintenanceDetectInstallStorageFolderDto { - @ValidateEnum({ enum: StorageFolder, name: 'StorageFolder' }) + @ValidateEnum({ enum: StorageFolder, name: 'StorageFolder', description: 'Storage folder' }) folder!: StorageFolder; + @ValidateBoolean({ description: 'Whether the folder is readable' }) readable!: boolean; + @ValidateBoolean({ description: 'Whether the folder is writable' }) writable!: boolean; + @ApiProperty({ description: 'Number of files in the folder' }) files!: number; } diff --git a/server/src/dtos/map.dto.ts b/server/src/dtos/map.dto.ts index 1d0b84a4d05b4..d8db175c289ca 100644 --- a/server/src/dtos/map.dto.ts +++ b/server/src/dtos/map.dto.ts @@ -4,64 +4,64 @@ import { IsLatitude, IsLongitude } from 'class-validator'; import { ValidateBoolean, ValidateDate } from 'src/validation'; export class MapReverseGeocodeDto { - @ApiProperty({ format: 'double' }) + @ApiProperty({ format: 'double', description: 'Latitude (-90 to 90)' }) @Type(() => Number) @IsLatitude({ message: ({ property }) => `${property} must be a number between -90 and 90` }) lat!: number; - @ApiProperty({ format: 'double' }) + @ApiProperty({ format: 'double', description: 'Longitude (-180 to 180)' }) @Type(() => Number) @IsLongitude({ message: ({ property }) => `${property} must be a number between -180 and 180` }) lon!: number; } export class MapReverseGeocodeResponseDto { - @ApiProperty() + @ApiProperty({ description: 'City name' }) city!: string | null; - @ApiProperty() + @ApiProperty({ description: 'State/Province name' }) state!: string | null; - @ApiProperty() + @ApiProperty({ description: 'Country name' }) country!: string | null; } export class MapMarkerDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by archived status' }) isArchived?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by favorite status' }) isFavorite?: boolean; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter assets created after this date' }) fileCreatedAfter?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter assets created before this date' }) fileCreatedBefore?: Date; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include partner assets' }) withPartners?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include shared album assets' }) withSharedAlbums?: boolean; } export class MapMarkerResponseDto { - @ApiProperty() + @ApiProperty({ description: 'Asset ID' }) id!: string; - @ApiProperty({ format: 'double' }) + @ApiProperty({ format: 'double', description: 'Latitude' }) lat!: number; - @ApiProperty({ format: 'double' }) + @ApiProperty({ format: 'double', description: 'Longitude' }) lon!: number; - @ApiProperty() + @ApiProperty({ description: 'City name' }) city!: string | null; - @ApiProperty() + @ApiProperty({ description: 'State/Province name' }) state!: string | null; - @ApiProperty() + @ApiProperty({ description: 'Country name' }) country!: string | null; } diff --git a/server/src/dtos/memory.dto.ts b/server/src/dtos/memory.dto.ts index 8e7320f83101b..0d73c19b2012b 100644 --- a/server/src/dtos/memory.dto.ts +++ b/server/src/dtos/memory.dto.ts @@ -8,24 +8,24 @@ import { AssetOrderWithRandom, MemoryType } from 'src/enum'; import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateUUID } from 'src/validation'; class MemoryBaseDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Is memory saved' }) isSaved?: boolean; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Date when memory was seen' }) seenAt?: Date; } export class MemorySearchDto { - @ValidateEnum({ enum: MemoryType, name: 'MemoryType', optional: true }) + @ValidateEnum({ enum: MemoryType, name: 'MemoryType', description: 'Memory type', optional: true }) type?: MemoryType; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by date' }) for?: Date; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include trashed memories' }) isTrashed?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by saved status' }) isSaved?: boolean; @IsInt() @@ -35,11 +35,12 @@ export class MemorySearchDto { @ApiProperty({ type: 'integer', description: 'Number of memories to return' }) size?: number; - @ValidateEnum({ enum: AssetOrderWithRandom, name: 'MemorySearchOrder', optional: true }) + @ValidateEnum({ enum: AssetOrderWithRandom, name: 'MemorySearchOrder', description: 'Sort order', optional: true }) order?: AssetOrderWithRandom; } class OnThisDayDto { + @ApiProperty({ type: 'number', description: 'Year for on this day memory', minimum: 1 }) @IsInt() @IsPositive() year!: number; @@ -48,14 +49,16 @@ class OnThisDayDto { type MemoryData = OnThisDayDto; export class MemoryUpdateDto extends MemoryBaseDto { - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Memory date' }) memoryAt?: Date; } export class MemoryCreateDto extends MemoryBaseDto { - @ValidateEnum({ enum: MemoryType, name: 'MemoryType' }) + @ValidateEnum({ enum: MemoryType, name: 'MemoryType', description: 'Memory type' }) type!: MemoryType; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @IsObject() @ValidateNested() @Type((options) => { @@ -71,32 +74,46 @@ export class MemoryCreateDto extends MemoryBaseDto { }) data!: MemoryData; - @ValidateDate() + @ValidateDate({ description: 'Memory date' }) memoryAt!: Date; - @ValidateUUID({ optional: true, each: true }) + @ValidateUUID({ optional: true, each: true, description: 'Asset IDs to associate with memory' }) assetIds?: string[]; } export class MemoryStatisticsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of memories' }) total!: number; } export class MemoryResponseDto { + @ApiProperty({ description: 'Memory ID' }) id!: string; + @ValidateDate({ description: 'Creation date' }) createdAt!: Date; + @ValidateDate({ description: 'Last update date' }) updatedAt!: Date; + @ValidateDate({ optional: true, description: 'Deletion date' }) deletedAt?: Date; + @ValidateDate({ description: 'Memory date' }) memoryAt!: Date; + @ValidateDate({ optional: true, description: 'Date when memory was seen' }) seenAt?: Date; + @ValidateDate({ optional: true, description: 'Date when memory should be shown' }) showAt?: Date; + @ValidateDate({ optional: true, description: 'Date when memory should be hidden' }) hideAt?: Date; + @ApiProperty({ description: 'Owner user ID' }) ownerId!: string; - @ValidateEnum({ enum: MemoryType, name: 'MemoryType' }) + @ValidateEnum({ enum: MemoryType, name: 'MemoryType', description: 'Memory type' }) type!: MemoryType; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) data!: MemoryData; + @ApiProperty({ description: 'Is memory saved' }) isSaved!: boolean; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) assets!: AssetResponseDto[]; } diff --git a/server/src/dtos/model-config.dto.ts b/server/src/dtos/model-config.dto.ts index 527317346a265..a75808f95a59b 100644 --- a/server/src/dtos/model-config.dto.ts +++ b/server/src/dtos/model-config.dto.ts @@ -4,11 +4,12 @@ import { IsNotEmpty, IsNumber, IsString, Max, Min } from 'class-validator'; import { ValidateBoolean } from 'src/validation'; export class TaskConfig { - @ValidateBoolean() + @ValidateBoolean({ description: 'Whether the task is enabled' }) enabled!: boolean; } export class ModelConfig extends TaskConfig { + @ApiProperty({ description: 'Name of the model to use' }) @IsString() @IsNotEmpty() modelName!: string; @@ -21,7 +22,11 @@ export class DuplicateDetectionConfig extends TaskConfig { @Min(0.001) @Max(0.1) @Type(() => Number) - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ + type: 'number', + format: 'double', + description: 'Maximum distance threshold for duplicate detection', + }) maxDistance!: number; } @@ -30,20 +35,24 @@ export class FacialRecognitionConfig extends ModelConfig { @Min(0.1) @Max(1) @Type(() => Number) - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'Minimum confidence score for face detection' }) minScore!: number; @IsNumber() @Min(0.1) @Max(2) @Type(() => Number) - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ + type: 'number', + format: 'double', + description: 'Maximum distance threshold for face recognition', + }) maxDistance!: number; @IsNumber() @Min(1) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Minimum number of faces required for recognition' }) minFaces!: number; } @@ -51,20 +60,24 @@ export class OcrConfig extends ModelConfig { @IsNumber() @Min(1) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Maximum resolution for OCR processing' }) maxResolution!: number; @IsNumber() @Min(0.1) @Max(1) @Type(() => Number) - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'Minimum confidence score for text detection' }) minDetectionScore!: number; @IsNumber() @Min(0.1) @Max(1) @Type(() => Number) - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ + type: 'number', + format: 'double', + description: 'Minimum confidence score for text recognition', + }) minRecognitionScore!: number; } diff --git a/server/src/dtos/notification.dto.ts b/server/src/dtos/notification.dto.ts index e83ba7315f95c..5331db4e858d2 100644 --- a/server/src/dtos/notification.dto.ts +++ b/server/src/dtos/notification.dto.ts @@ -1,86 +1,115 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsString } from 'class-validator'; import { NotificationLevel, NotificationType } from 'src/enum'; import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateUUID } from 'src/validation'; export class TestEmailResponseDto { + @ApiProperty({ description: 'Email message ID' }) messageId!: string; } export class TemplateResponseDto { + @ApiProperty({ description: 'Template name' }) name!: string; + @ApiProperty({ description: 'Template HTML content' }) html!: string; } + export class TemplateDto { + @ApiProperty({ description: 'Template name' }) @IsString() template!: string; } export class NotificationDto { + @ApiProperty({ description: 'Notification ID' }) id!: string; - @ValidateDate() + @ValidateDate({ description: 'Creation date' }) createdAt!: Date; - @ValidateEnum({ enum: NotificationLevel, name: 'NotificationLevel' }) + @ValidateEnum({ enum: NotificationLevel, name: 'NotificationLevel', description: 'Notification level' }) level!: NotificationLevel; - @ValidateEnum({ enum: NotificationType, name: 'NotificationType' }) + @ValidateEnum({ enum: NotificationType, name: 'NotificationType', description: 'Notification type' }) type!: NotificationType; + @ApiProperty({ description: 'Notification title' }) title!: string; + @ApiPropertyOptional({ description: 'Notification description' }) description?: string; + @ApiPropertyOptional({ description: 'Additional notification data' }) data?: any; + @ApiPropertyOptional({ description: 'Date when notification was read', format: 'date-time' }) readAt?: Date; } export class NotificationSearchDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by notification ID' }) id?: string; - @ValidateEnum({ enum: NotificationLevel, name: 'NotificationLevel', optional: true }) + @ValidateEnum({ + enum: NotificationLevel, + name: 'NotificationLevel', + optional: true, + description: 'Filter by notification level', + }) level?: NotificationLevel; - @ValidateEnum({ enum: NotificationType, name: 'NotificationType', optional: true }) + @ValidateEnum({ + enum: NotificationType, + name: 'NotificationType', + optional: true, + description: 'Filter by notification type', + }) type?: NotificationType; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by unread status' }) unread?: boolean; } export class NotificationCreateDto { - @ValidateEnum({ enum: NotificationLevel, name: 'NotificationLevel', optional: true }) + @ValidateEnum({ + enum: NotificationLevel, + name: 'NotificationLevel', + optional: true, + description: 'Notification level', + }) level?: NotificationLevel; - @ValidateEnum({ enum: NotificationType, name: 'NotificationType', optional: true }) + @ValidateEnum({ enum: NotificationType, name: 'NotificationType', optional: true, description: 'Notification type' }) type?: NotificationType; + @ApiProperty({ description: 'Notification title' }) @IsString() title!: string; + @ApiPropertyOptional({ description: 'Notification description' }) @IsString() @Optional({ nullable: true }) description?: string | null; + @ApiPropertyOptional({ description: 'Additional notification data' }) @Optional({ nullable: true }) data?: any; - @ValidateDate({ optional: true, nullable: true }) + @ValidateDate({ optional: true, description: 'Date when notification was read' }) readAt?: Date | null; - @ValidateUUID() + @ValidateUUID({ description: 'User ID to send notification to' }) userId!: string; } export class NotificationUpdateDto { - @ValidateDate({ optional: true, nullable: true }) + @ValidateDate({ optional: true, description: 'Date when notification was read' }) readAt?: Date | null; } export class NotificationUpdateAllDto { - @ValidateUUID({ each: true, optional: true }) + @ValidateUUID({ each: true, optional: true, description: 'Notification IDs to update' }) ids!: string[]; - @ValidateDate({ optional: true, nullable: true }) + @ValidateDate({ optional: true, description: 'Date when notifications were read' }) readAt?: Date | null; } export class NotificationDeleteAllDto { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Notification IDs to delete' }) ids!: string[]; } diff --git a/server/src/dtos/onboarding.dto.ts b/server/src/dtos/onboarding.dto.ts index 47a3992784525..d2781c6b90a2f 100644 --- a/server/src/dtos/onboarding.dto.ts +++ b/server/src/dtos/onboarding.dto.ts @@ -1,7 +1,7 @@ import { ValidateBoolean } from 'src/validation'; export class OnboardingDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Is user onboarded' }) isOnboarded!: boolean; } diff --git a/server/src/dtos/partner.dto.ts b/server/src/dtos/partner.dto.ts index 599213f662f27..5b949326a4a5e 100644 --- a/server/src/dtos/partner.dto.ts +++ b/server/src/dtos/partner.dto.ts @@ -1,23 +1,26 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsNotEmpty } from 'class-validator'; import { UserResponseDto } from 'src/dtos/user.dto'; import { PartnerDirection } from 'src/repositories/partner.repository'; import { ValidateEnum, ValidateUUID } from 'src/validation'; export class PartnerCreateDto { - @ValidateUUID() + @ValidateUUID({ description: 'User ID to share with' }) sharedWithId!: string; } export class PartnerUpdateDto { + @ApiProperty({ description: 'Show partner assets in timeline' }) @IsNotEmpty() inTimeline!: boolean; } export class PartnerSearchDto { - @ValidateEnum({ enum: PartnerDirection, name: 'PartnerDirection' }) + @ValidateEnum({ enum: PartnerDirection, name: 'PartnerDirection', description: 'Partner direction' }) direction!: PartnerDirection; } export class PartnerResponseDto extends UserResponseDto { + @ApiPropertyOptional({ description: 'Show in timeline' }) inTimeline?: boolean; } diff --git a/server/src/dtos/person.dto.ts b/server/src/dtos/person.dto.ts index 5bf6854d3474e..983062afcf798 100644 --- a/server/src/dtos/person.dto.ts +++ b/server/src/dtos/person.dto.ts @@ -23,46 +23,37 @@ import { } from 'src/validation'; export class PersonCreateDto { - /** - * Person name. - */ + @ApiPropertyOptional({ description: 'Person name' }) @Optional() @IsString() name?: string; - /** - * Person date of birth. - * Note: the mobile app cannot currently set the birth date to null. - */ - @ApiProperty({ format: 'date' }) + // Note: the mobile app cannot currently set the birth date to null. + @ApiProperty({ format: 'date', description: 'Person date of birth', required: false }) @MaxDateString(() => DateTime.now(), { message: 'Birth date cannot be in the future' }) @IsDateStringFormat('yyyy-MM-dd') @Optional({ nullable: true, emptyToNull: true }) birthDate?: Date | null; - /** - * Person visibility - */ - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Person visibility (hidden)' }) isHidden?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Mark as favorite' }) isFavorite?: boolean; + @ApiPropertyOptional({ description: 'Person color (hex)' }) @Optional({ emptyToNull: true, nullable: true }) @ValidateHexColor() color?: string | null; } export class PersonUpdateDto extends PersonCreateDto { - /** - * Asset is used to get the feature face thumbnail. - */ - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Asset ID used for feature face thumbnail' }) featureFaceAssetId?: string; } export class PeopleUpdateDto { + @ApiProperty({ description: 'People to update' }) @IsArray() @ValidateNested({ each: true }) @Type(() => PeopleUpdateItem) @@ -70,36 +61,32 @@ export class PeopleUpdateDto { } export class PeopleUpdateItem extends PersonUpdateDto { - /** - * Person id. - */ + @ApiProperty({ description: 'Person ID' }) @IsString() @IsNotEmpty() id!: string; } export class MergePersonDto { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Person IDs to merge' }) ids!: string[]; } export class PersonSearchDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include hidden people' }) withHidden?: boolean; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Closest person ID for similarity search' }) closestPersonId?: string; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Closest asset ID for similarity search' }) closestAssetId?: string; - /** Page number for pagination */ - @ApiPropertyOptional() + @ApiPropertyOptional({ description: 'Page number for pagination', default: 1 }) @IsInt() @Min(1) @Type(() => Number) page: number = 1; - /** Number of items per page */ - @ApiPropertyOptional() + @ApiPropertyOptional({ description: 'Number of items per page', default: 500 }) @IsInt() @Min(1) @Max(1000) @@ -108,48 +95,55 @@ export class PersonSearchDto { } export class PersonResponseDto { + @ApiProperty({ description: 'Person ID' }) id!: string; + @ApiProperty({ description: 'Person name' }) name!: string; - @ApiProperty({ format: 'date' }) + @ApiProperty({ format: 'date', description: 'Person date of birth' }) birthDate!: string | null; + @ApiProperty({ description: 'Thumbnail path' }) thumbnailPath!: string; + @ApiProperty({ description: 'Is hidden' }) isHidden!: boolean; - @Property({ history: new HistoryBuilder().added('v1.107.0').stable('v2') }) + @Property({ description: 'Last update date', history: new HistoryBuilder().added('v1.107.0').stable('v2') }) updatedAt?: Date; - @Property({ history: new HistoryBuilder().added('v1.126.0').stable('v2') }) + @Property({ description: 'Is favorite', history: new HistoryBuilder().added('v1.126.0').stable('v2') }) isFavorite?: boolean; - @Property({ history: new HistoryBuilder().added('v1.126.0').stable('v2') }) + @Property({ description: 'Person color (hex)', history: new HistoryBuilder().added('v1.126.0').stable('v2') }) color?: string; } export class PersonWithFacesResponseDto extends PersonResponseDto { + @ApiProperty({ description: 'Face detections' }) faces!: AssetFaceWithoutPersonResponseDto[]; } export class AssetFaceWithoutPersonResponseDto { - @ValidateUUID() + @ValidateUUID({ description: 'Face ID' }) id!: string; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Image height in pixels' }) imageHeight!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Image width in pixels' }) imageWidth!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Bounding box X1 coordinate' }) boundingBoxX1!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Bounding box X2 coordinate' }) boundingBoxX2!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Bounding box Y1 coordinate' }) boundingBoxY1!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Bounding box Y2 coordinate' }) boundingBoxY2!: number; - @ValidateEnum({ enum: SourceType, name: 'SourceType' }) + @ValidateEnum({ enum: SourceType, name: 'SourceType', optional: true, description: 'Face detection source type' }) sourceType?: SourceType; } export class AssetFaceResponseDto extends AssetFaceWithoutPersonResponseDto { + @ApiProperty({ description: 'Person associated with face' }) person!: PersonResponseDto | null; } export class AssetFaceUpdateDto { + @ApiProperty({ description: 'Face update items' }) @IsArray() @ValidateNested({ each: true }) @Type(() => AssetFaceUpdateItem) @@ -157,69 +151,74 @@ export class AssetFaceUpdateDto { } export class FaceDto { - @ValidateUUID() + @ValidateUUID({ description: 'Face ID' }) id!: string; } export class AssetFaceUpdateItem { - @ValidateUUID() + @ValidateUUID({ description: 'Person ID' }) personId!: string; - @ValidateUUID() + @ValidateUUID({ description: 'Asset ID' }) assetId!: string; } export class AssetFaceCreateDto extends AssetFaceUpdateItem { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Image width in pixels' }) @IsNotEmpty() @IsNumber() imageWidth!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Image height in pixels' }) @IsNotEmpty() @IsNumber() imageHeight!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Face bounding box X coordinate' }) @IsNotEmpty() @IsNumber() x!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Face bounding box Y coordinate' }) @IsNotEmpty() @IsNumber() y!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Face bounding box width' }) @IsNotEmpty() @IsNumber() width!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Face bounding box height' }) @IsNotEmpty() @IsNumber() height!: number; } export class AssetFaceDeleteDto { + @ApiProperty({ description: 'Force delete even if person has other faces' }) @IsNotEmpty() force!: boolean; } export class PersonStatisticsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets' }) assets!: number; } export class PeopleResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of people' }) total!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of hidden people' }) hidden!: number; + @ApiProperty({ description: 'List of people' }) people!: PersonResponseDto[]; // TODO: make required after a few versions - @Property({ history: new HistoryBuilder().added('v1.110.0').stable('v2') }) + @Property({ + description: 'Whether there are more pages', + history: new HistoryBuilder().added('v1.110.0').stable('v2'), + }) hasNextPage?: boolean; } diff --git a/server/src/dtos/plugin-manifest.dto.ts b/server/src/dtos/plugin-manifest.dto.ts index fcb3ad4a221fa..d5d1c529970e2 100644 --- a/server/src/dtos/plugin-manifest.dto.ts +++ b/server/src/dtos/plugin-manifest.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { ArrayMinSize, @@ -16,58 +17,68 @@ import { JSONSchema } from 'src/types/plugin-schema.types'; import { ValidateEnum } from 'src/validation'; class PluginManifestWasmDto { + @ApiProperty({ description: 'WASM file path' }) @IsString() @IsNotEmpty() path!: string; } class PluginManifestFilterDto { + @ApiProperty({ description: 'Filter method name' }) @IsString() @IsNotEmpty() methodName!: string; + @ApiProperty({ description: 'Filter title' }) @IsString() @IsNotEmpty() title!: string; + @ApiProperty({ description: 'Filter description' }) @IsString() @IsNotEmpty() description!: string; + @ApiProperty({ description: 'Supported contexts', enum: PluginContext, isArray: true }) @IsArray() @ArrayMinSize(1) @IsEnum(PluginContext, { each: true }) supportedContexts!: PluginContext[]; + @ApiPropertyOptional({ description: 'Filter schema' }) @IsObject() @IsOptional() schema?: JSONSchema; } class PluginManifestActionDto { + @ApiProperty({ description: 'Action method name' }) @IsString() @IsNotEmpty() methodName!: string; + @ApiProperty({ description: 'Action title' }) @IsString() @IsNotEmpty() title!: string; + @ApiProperty({ description: 'Action description' }) @IsString() @IsNotEmpty() description!: string; - @IsArray() @ArrayMinSize(1) - @ValidateEnum({ enum: PluginContext, name: 'PluginContext', each: true }) + @ValidateEnum({ enum: PluginContext, name: 'PluginContext', each: true, description: 'Supported contexts' }) supportedContexts!: PluginContext[]; + @ApiPropertyOptional({ description: 'Action schema' }) @IsObject() @IsOptional() schema?: JSONSchema; } export class PluginManifestDto { + @ApiProperty({ description: 'Plugin name (lowercase, numbers, hyphens only)' }) @IsString() @IsNotEmpty() @Matches(/^[a-z0-9-]+[a-z0-9]$/, { @@ -75,33 +86,40 @@ export class PluginManifestDto { }) name!: string; + @ApiProperty({ description: 'Plugin version (semver)' }) @IsString() @IsNotEmpty() @IsSemVer() version!: string; + @ApiProperty({ description: 'Plugin title' }) @IsString() @IsNotEmpty() title!: string; + @ApiProperty({ description: 'Plugin description' }) @IsString() @IsNotEmpty() description!: string; + @ApiProperty({ description: 'Plugin author' }) @IsString() @IsNotEmpty() author!: string; + @ApiProperty({ description: 'WASM configuration' }) @ValidateNested() @Type(() => PluginManifestWasmDto) wasm!: PluginManifestWasmDto; + @ApiPropertyOptional({ description: 'Plugin filters' }) @IsArray() @ValidateNested({ each: true }) @Type(() => PluginManifestFilterDto) @IsOptional() filters?: PluginManifestFilterDto[]; + @ApiPropertyOptional({ description: 'Plugin actions' }) @IsArray() @ValidateNested({ each: true }) @Type(() => PluginManifestActionDto) diff --git a/server/src/dtos/plugin.dto.ts b/server/src/dtos/plugin.dto.ts index a802bb1201d35..de1f1b28d43af 100644 --- a/server/src/dtos/plugin.dto.ts +++ b/server/src/dtos/plugin.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString } from 'class-validator'; import { PluginAction, PluginFilter } from 'src/database'; import { PluginContext as PluginContextType, PluginTriggerType } from 'src/enum'; @@ -5,50 +6,73 @@ import type { JSONSchema } from 'src/types/plugin-schema.types'; import { ValidateEnum } from 'src/validation'; export class PluginTriggerResponseDto { - @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType' }) + @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType', description: 'Trigger type' }) type!: PluginTriggerType; - @ValidateEnum({ enum: PluginContextType, name: 'PluginContextType' }) + @ValidateEnum({ enum: PluginContextType, name: 'PluginContextType', description: 'Context type' }) contextType!: PluginContextType; } export class PluginResponseDto { + @ApiProperty({ description: 'Plugin ID' }) id!: string; + @ApiProperty({ description: 'Plugin name' }) name!: string; + @ApiProperty({ description: 'Plugin title' }) title!: string; + @ApiProperty({ description: 'Plugin description' }) description!: string; + @ApiProperty({ description: 'Plugin author' }) author!: string; + @ApiProperty({ description: 'Plugin version' }) version!: string; + @ApiProperty({ description: 'Creation date' }) createdAt!: string; + @ApiProperty({ description: 'Last update date' }) updatedAt!: string; + @ApiProperty({ description: 'Plugin filters' }) filters!: PluginFilterResponseDto[]; + @ApiProperty({ description: 'Plugin actions' }) actions!: PluginActionResponseDto[]; } export class PluginFilterResponseDto { + @ApiProperty({ description: 'Filter ID' }) id!: string; + @ApiProperty({ description: 'Plugin ID' }) pluginId!: string; + @ApiProperty({ description: 'Method name' }) methodName!: string; + @ApiProperty({ description: 'Filter title' }) title!: string; + @ApiProperty({ description: 'Filter description' }) description!: string; - @ValidateEnum({ enum: PluginContextType, name: 'PluginContextType' }) + @ValidateEnum({ enum: PluginContextType, name: 'PluginContextType', each: true, description: 'Supported contexts' }) supportedContexts!: PluginContextType[]; + @ApiProperty({ description: 'Filter schema' }) schema!: JSONSchema | null; } export class PluginActionResponseDto { + @ApiProperty({ description: 'Action ID' }) id!: string; + @ApiProperty({ description: 'Plugin ID' }) pluginId!: string; + @ApiProperty({ description: 'Method name' }) methodName!: string; + @ApiProperty({ description: 'Action title' }) title!: string; + @ApiProperty({ description: 'Action description' }) description!: string; - @ValidateEnum({ enum: PluginContextType, name: 'PluginContextType' }) + @ValidateEnum({ enum: PluginContextType, name: 'PluginContextType', each: true, description: 'Supported contexts' }) supportedContexts!: PluginContextType[]; + @ApiProperty({ description: 'Action schema' }) schema!: JSONSchema | null; } export class PluginInstallDto { + @ApiProperty({ description: 'Path to plugin manifest file' }) @IsString() @IsNotEmpty() manifestPath!: string; diff --git a/server/src/dtos/queue-legacy.dto.ts b/server/src/dtos/queue-legacy.dto.ts index e3b48fa869a79..993160a03b755 100644 --- a/server/src/dtos/queue-legacy.dto.ts +++ b/server/src/dtos/queue-legacy.dto.ts @@ -3,15 +3,19 @@ import { QueueResponseDto, QueueStatisticsDto } from 'src/dtos/queue.dto'; import { QueueName } from 'src/enum'; export class QueueStatusLegacyDto { + @ApiProperty({ description: 'Whether the queue is currently active (has running jobs)' }) isActive!: boolean; + @ApiProperty({ description: 'Whether the queue is paused' }) isPaused!: boolean; } export class QueueResponseLegacyDto { - @ApiProperty({ type: QueueStatusLegacyDto }) + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) queueStatus!: QueueStatusLegacyDto; - @ApiProperty({ type: QueueStatisticsDto }) + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) jobCounts!: QueueStatisticsDto; } diff --git a/server/src/dtos/queue.dto.ts b/server/src/dtos/queue.dto.ts index 38a4a4ac6b21c..789358144418d 100644 --- a/server/src/dtos/queue.dto.ts +++ b/server/src/dtos/queue.dto.ts @@ -1,29 +1,29 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { HistoryBuilder, Property } from 'src/decorators'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { HistoryBuilder } from 'src/decorators'; import { JobName, QueueCommand, QueueJobStatus, QueueName } from 'src/enum'; import { ValidateBoolean, ValidateEnum } from 'src/validation'; export class QueueNameParamDto { - @ValidateEnum({ enum: QueueName, name: 'QueueName' }) + @ValidateEnum({ enum: QueueName, name: 'QueueName', description: 'Queue name' }) name!: QueueName; } export class QueueCommandDto { - @ValidateEnum({ enum: QueueCommand, name: 'QueueCommand' }) + @ValidateEnum({ enum: QueueCommand, name: 'QueueCommand', description: 'Queue command to execute' }) command!: QueueCommand; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Force the command execution (if applicable)' }) force?: boolean; // TODO: this uses undefined as a third state, which should be refactored to be more explicit } export class QueueUpdateDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether to pause the queue' }) isPaused?: boolean; } export class QueueDeleteDto { - @ValidateBoolean({ optional: true }) - @Property({ + @ValidateBoolean({ + optional: true, description: 'If true, will also remove failed jobs from the queue.', history: new HistoryBuilder().added('v2.4.0').alpha('v2.4.0'), }) @@ -31,42 +31,52 @@ export class QueueDeleteDto { } export class QueueJobSearchDto { - @ValidateEnum({ enum: QueueJobStatus, name: 'QueueJobStatus', optional: true, each: true }) + @ValidateEnum({ + enum: QueueJobStatus, + name: 'QueueJobStatus', + optional: true, + each: true, + description: 'Filter jobs by status', + }) status?: QueueJobStatus[]; } export class QueueJobResponseDto { + @ApiPropertyOptional({ description: 'Job ID' }) id?: string; - @ValidateEnum({ enum: JobName, name: 'JobName' }) + @ValidateEnum({ enum: JobName, name: 'JobName', description: 'Job name' }) name!: JobName; + @ApiProperty({ description: 'Job data payload', type: Object }) data!: object; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Job creation timestamp' }) timestamp!: number; } -export class QueueResponseDto { - @ValidateEnum({ enum: QueueName, name: 'QueueName' }) - name!: QueueName; - - @ValidateBoolean() - isPaused!: boolean; - - statistics!: QueueStatisticsDto; -} - export class QueueStatisticsDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of active jobs' }) active!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of completed jobs' }) completed!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of failed jobs' }) failed!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of delayed jobs' }) delayed!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of waiting jobs' }) waiting!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of paused jobs' }) paused!: number; } + +export class QueueResponseDto { + @ValidateEnum({ enum: QueueName, name: 'QueueName', description: 'Queue name' }) + name!: QueueName; + + @ValidateBoolean({ description: 'Whether the queue is paused' }) + isPaused!: boolean; + + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) + statistics!: QueueStatisticsDto; +} diff --git a/server/src/dtos/search.dto.ts b/server/src/dtos/search.dto.ts index 068cd6630c091..59fddcc71c0e7 100644 --- a/server/src/dtos/search.dto.ts +++ b/server/src/dtos/search.dto.ts @@ -1,107 +1,116 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { IsInt, IsNotEmpty, IsString, Max, Min } from 'class-validator'; import { Place } from 'src/database'; -import { HistoryBuilder, Property } from 'src/decorators'; +import { HistoryBuilder } from 'src/decorators'; import { AlbumResponseDto } from 'src/dtos/album.dto'; import { AssetResponseDto } from 'src/dtos/asset-response.dto'; import { AssetOrder, AssetType, AssetVisibility } from 'src/enum'; import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateString, ValidateUUID } from 'src/validation'; class BaseSearchDto { - @ValidateUUID({ optional: true, nullable: true }) + @ValidateUUID({ optional: true, nullable: true, description: 'Library ID to filter by' }) libraryId?: string | null; + @ApiPropertyOptional({ description: 'Device ID to filter by' }) @IsString() @IsNotEmpty() @Optional() deviceId?: string; - @ValidateEnum({ enum: AssetType, name: 'AssetTypeEnum', optional: true }) + @ValidateEnum({ enum: AssetType, name: 'AssetTypeEnum', optional: true, description: 'Asset type filter' }) type?: AssetType; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by encoded status' }) isEncoded?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by favorite status' }) isFavorite?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by motion photo status' }) isMotion?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter by offline status' }) isOffline?: boolean; - @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', optional: true }) + @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', optional: true, description: 'Filter by visibility' }) visibility?: AssetVisibility; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by creation date (before)' }) createdBefore?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by creation date (after)' }) createdAfter?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by update date (before)' }) updatedBefore?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by update date (after)' }) updatedAfter?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by trash date (before)' }) trashedBefore?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by trash date (after)' }) trashedAfter?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by taken date (before)' }) takenBefore?: Date; - @ValidateDate({ optional: true }) + @ValidateDate({ optional: true, description: 'Filter by taken date (after)' }) takenAfter?: Date; + @ApiPropertyOptional({ description: 'Filter by city name' }) @IsString() @Optional({ nullable: true, emptyToNull: true }) city?: string | null; + @ApiPropertyOptional({ description: 'Filter by state/province name' }) @IsString() @Optional({ nullable: true, emptyToNull: true }) state?: string | null; + @ApiPropertyOptional({ description: 'Filter by country name' }) @IsString() @IsNotEmpty() @Optional({ nullable: true, emptyToNull: true }) country?: string | null; + @ApiPropertyOptional({ description: 'Filter by camera make' }) @IsString() @Optional({ nullable: true, emptyToNull: true }) make?: string; + @ApiPropertyOptional({ description: 'Filter by camera model' }) @IsString() @Optional({ nullable: true, emptyToNull: true }) model?: string | null; + @ApiPropertyOptional({ description: 'Filter by lens model' }) @IsString() @Optional({ nullable: true, emptyToNull: true }) lensModel?: string | null; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Filter assets not in any album' }) isNotInAlbum?: boolean; - @ValidateUUID({ each: true, optional: true }) + @ValidateUUID({ each: true, optional: true, description: 'Filter by person IDs' }) personIds?: string[]; - @ValidateUUID({ each: true, optional: true, nullable: true }) + @ValidateUUID({ each: true, optional: true, description: 'Filter by tag IDs' }) tagIds?: string[] | null; - @ValidateUUID({ each: true, optional: true }) + @ValidateUUID({ each: true, optional: true, description: 'Filter by album IDs' }) albumIds?: string[]; + @ApiPropertyOptional({ type: 'number', description: 'Filter by rating', minimum: -1, maximum: 5 }) @Optional() @IsInt() @Max(5) @Min(-1) rating?: number; + @ApiPropertyOptional({ description: 'Filter by OCR text content' }) @IsString() @IsNotEmpty() @Optional() @@ -109,12 +118,13 @@ class BaseSearchDto { } class BaseSearchWithResultsDto extends BaseSearchDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include deleted assets' }) withDeleted?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include EXIF data in response' }) withExif?: boolean; + @ApiPropertyOptional({ type: 'number', description: 'Number of results to return', minimum: 1, maximum: 1000 }) @IsInt() @Min(1) @Max(1000) @@ -124,65 +134,78 @@ class BaseSearchWithResultsDto extends BaseSearchDto { } export class RandomSearchDto extends BaseSearchWithResultsDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include stacked assets' }) withStacked?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include assets with people' }) withPeople?: boolean; } export class LargeAssetSearchDto extends BaseSearchWithResultsDto { + @ApiPropertyOptional({ type: 'integer', description: 'Minimum file size in bytes', minimum: 0 }) @Optional() @IsInt() @Min(0) @Type(() => Number) - @ApiProperty({ type: 'integer' }) minFileSize?: number; } export class MetadataSearchDto extends RandomSearchDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by asset ID' }) id?: string; + @ApiPropertyOptional({ description: 'Filter by device asset ID' }) @IsString() @IsNotEmpty() @Optional() deviceAssetId?: string; - @ValidateString({ optional: true, trim: true }) + @ValidateString({ optional: true, trim: true, description: 'Filter by description text' }) description?: string; + @ApiPropertyOptional({ description: 'Filter by file checksum' }) @IsString() @IsNotEmpty() @Optional() checksum?: string; - @ValidateString({ optional: true, trim: true }) + @ValidateString({ optional: true, trim: true, description: 'Filter by original file name' }) originalFileName?: string; + @ApiPropertyOptional({ description: 'Filter by original file path' }) @IsString() @IsNotEmpty() @Optional() originalPath?: string; + @ApiPropertyOptional({ description: 'Filter by preview file path' }) @IsString() @IsNotEmpty() @Optional() previewPath?: string; + @ApiPropertyOptional({ description: 'Filter by thumbnail file path' }) @IsString() @IsNotEmpty() @Optional() thumbnailPath?: string; + @ApiPropertyOptional({ description: 'Filter by encoded video file path' }) @IsString() @IsNotEmpty() @Optional() encodedVideoPath?: string; - @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', optional: true, default: AssetOrder.Desc }) + @ValidateEnum({ + enum: AssetOrder, + name: 'AssetOrder', + optional: true, + default: AssetOrder.Desc, + description: 'Sort order', + }) order?: AssetOrder; + @ApiPropertyOptional({ type: 'number', description: 'Page number', minimum: 1 }) @IsInt() @Min(1) @Type(() => Number) @@ -191,23 +214,24 @@ export class MetadataSearchDto extends RandomSearchDto { } export class StatisticsSearchDto extends BaseSearchDto { - @ValidateString({ optional: true, trim: true }) + @ValidateString({ optional: true, trim: true, description: 'Filter by description text' }) description?: string; } export class SmartSearchDto extends BaseSearchWithResultsDto { - @ValidateString({ optional: true, trim: true }) + @ValidateString({ optional: true, trim: true, description: 'Natural language search query' }) query?: string; - @ValidateUUID({ optional: true }) - @Optional() + @ValidateUUID({ optional: true, description: 'Asset ID to use as search reference' }) queryAssetId?: string; + @ApiPropertyOptional({ description: 'Search language code' }) @IsString() @IsNotEmpty() @Optional() language?: string; + @ApiPropertyOptional({ type: 'number', description: 'Page number', minimum: 1 }) @IsInt() @Min(1) @Type(() => Number) @@ -216,25 +240,32 @@ export class SmartSearchDto extends BaseSearchWithResultsDto { } export class SearchPlacesDto { + @ApiProperty({ description: 'Place name to search for' }) @IsString() @IsNotEmpty() name!: string; } export class SearchPeopleDto { + @ApiProperty({ description: 'Person name to search for' }) @IsString() @IsNotEmpty() name!: string; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include hidden people' }) withHidden?: boolean; } export class PlacesResponseDto { + @ApiProperty({ description: 'Place name' }) name!: string; + @ApiProperty({ type: 'number', description: 'Latitude coordinate' }) latitude!: number; + @ApiProperty({ type: 'number', description: 'Longitude coordinate' }) longitude!: number; + @ApiPropertyOptional({ description: 'Administrative level 1 name (state/province)' }) admin1name?: string; + @ApiPropertyOptional({ description: 'Administrative level 2 name (county/district)' }) admin2name?: string; } @@ -258,96 +289,126 @@ export enum SearchSuggestionType { } export class SearchSuggestionRequestDto { - @ValidateEnum({ enum: SearchSuggestionType, name: 'SearchSuggestionType' }) + @ValidateEnum({ enum: SearchSuggestionType, name: 'SearchSuggestionType', description: 'Suggestion type' }) type!: SearchSuggestionType; + @ApiPropertyOptional({ description: 'Filter by country' }) @IsString() @Optional() country?: string; + @ApiPropertyOptional({ description: 'Filter by state/province' }) @IsString() @Optional() state?: string; + @ApiPropertyOptional({ description: 'Filter by camera make' }) @IsString() @Optional() make?: string; + @ApiPropertyOptional({ description: 'Filter by camera model' }) @IsString() @Optional() model?: string; + @ApiPropertyOptional({ description: 'Filter by lens model' }) @IsString() @Optional() lensModel?: string; - @ValidateBoolean({ optional: true }) - @Property({ history: new HistoryBuilder().added('v1.111.0').stable('v2') }) + @ValidateBoolean({ + optional: true, + description: 'Include null values in suggestions', + history: new HistoryBuilder().added('v1.111.0').stable('v2'), + }) includeNull?: boolean; } class SearchFacetCountResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets with this facet value' }) count!: number; + @ApiProperty({ description: 'Facet value' }) value!: string; } class SearchFacetResponseDto { + @ApiProperty({ description: 'Facet field name' }) fieldName!: string; + @ApiProperty({ description: 'Facet counts' }) counts!: SearchFacetCountResponseDto[]; } class SearchAlbumResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of matching albums' }) total!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of albums in this page' }) count!: number; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) items!: AlbumResponseDto[]; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) facets!: SearchFacetResponseDto[]; } class SearchAssetResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of matching assets' }) total!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets in this page' }) count!: number; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) items!: AssetResponseDto[]; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) facets!: SearchFacetResponseDto[]; + @ApiProperty({ description: 'Next page token' }) nextPage!: string | null; } export class SearchResponseDto { + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) albums!: SearchAlbumResponseDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) assets!: SearchAssetResponseDto; } export class SearchStatisticsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of matching assets' }) total!: number; } class SearchExploreItem { + @ApiProperty({ description: 'Explore value' }) value!: string; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) data!: AssetResponseDto; } export class SearchExploreResponseDto { + @ApiProperty({ description: 'Explore field name' }) fieldName!: string; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) items!: SearchExploreItem[]; } export class MemoryLaneDto { + @ApiProperty({ type: 'integer', description: 'Day of month' }) @IsInt() @Type(() => Number) @Max(31) @Min(1) - @ApiProperty({ type: 'integer' }) day!: number; + @ApiProperty({ type: 'integer', description: 'Month' }) @IsInt() @Type(() => Number) @Max(12) @Min(1) - @ApiProperty({ type: 'integer' }) month!: number; } diff --git a/server/src/dtos/server.dto.ts b/server/src/dtos/server.dto.ts index e98cb2edf627d..626c94e40a1b3 100644 --- a/server/src/dtos/server.dto.ts +++ b/server/src/dtos/server.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional, ApiResponseProperty } from '@nestjs/swagger'; import { SemVer } from 'semver'; import { SystemConfigThemeDto } from 'src/dtos/system-config.dto'; @@ -8,66 +8,94 @@ export class ServerPingResponse { } export class ServerAboutResponseDto { + @ApiProperty({ description: 'Server version' }) version!: string; + @ApiProperty({ description: 'URL to version information' }) versionUrl!: string; + @ApiPropertyOptional({ description: 'Repository name' }) repository?: string; + @ApiPropertyOptional({ description: 'Repository URL' }) repositoryUrl?: string; + @ApiPropertyOptional({ description: 'Source reference (branch/tag)' }) sourceRef?: string; + @ApiPropertyOptional({ description: 'Source commit hash' }) sourceCommit?: string; + @ApiPropertyOptional({ description: 'Source URL' }) sourceUrl?: string; + @ApiPropertyOptional({ description: 'Build identifier' }) build?: string; + @ApiPropertyOptional({ description: 'Build URL' }) buildUrl?: string; + @ApiPropertyOptional({ description: 'Build image name' }) buildImage?: string; + @ApiPropertyOptional({ description: 'Build image URL' }) buildImageUrl?: string; + @ApiPropertyOptional({ description: 'Node.js version' }) nodejs?: string; + @ApiPropertyOptional({ description: 'FFmpeg version' }) ffmpeg?: string; + @ApiPropertyOptional({ description: 'ImageMagick version' }) imagemagick?: string; + @ApiPropertyOptional({ description: 'libvips version' }) libvips?: string; + @ApiPropertyOptional({ description: 'ExifTool version' }) exiftool?: string; + @ApiProperty({ description: 'Whether the server is licensed' }) licensed!: boolean; + @ApiPropertyOptional({ description: 'Third-party source URL' }) thirdPartySourceUrl?: string; + @ApiPropertyOptional({ description: 'Third-party bug/feature URL' }) thirdPartyBugFeatureUrl?: string; + @ApiPropertyOptional({ description: 'Third-party documentation URL' }) thirdPartyDocumentationUrl?: string; + @ApiPropertyOptional({ description: 'Third-party support URL' }) thirdPartySupportUrl?: string; } export class ServerApkLinksDto { + @ApiProperty({ description: 'APK download link for ARM64 v8a architecture' }) arm64v8a!: string; + @ApiProperty({ description: 'APK download link for ARM EABI v7a architecture' }) armeabiv7a!: string; + @ApiProperty({ description: 'APK download link for universal architecture' }) universal!: string; + @ApiProperty({ description: 'APK download link for x86_64 architecture' }) x86_64!: string; } export class ServerStorageResponseDto { + @ApiProperty({ description: 'Total disk size (human-readable format)' }) diskSize!: string; + @ApiProperty({ description: 'Used disk space (human-readable format)' }) diskUse!: string; + @ApiProperty({ description: 'Available disk space (human-readable format)' }) diskAvailable!: string; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Total disk size in bytes' }) diskSizeRaw!: number; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Used disk space in bytes' }) diskUseRaw!: number; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Available disk space in bytes' }) diskAvailableRaw!: number; - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'Disk usage percentage (0-100)' }) diskUsagePercentage!: number; } export class ServerVersionResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Major version number' }) major!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Minor version number' }) minor!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Patch version number' }) patch!: number; static fromSemVer(value: SemVer) { @@ -76,44 +104,52 @@ export class ServerVersionResponseDto { } export class ServerVersionHistoryResponseDto { + @ApiProperty({ description: 'Version history entry ID' }) id!: string; + @ApiProperty({ description: 'When this version was first seen', format: 'date-time' }) createdAt!: Date; + @ApiProperty({ description: 'Version string' }) version!: string; } export class UsageByUserDto { - @ApiProperty({ type: 'string' }) + @ApiProperty({ type: 'string', description: 'User ID' }) userId!: string; - @ApiProperty({ type: 'string' }) + @ApiProperty({ type: 'string', description: 'User name' }) userName!: string; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of photos' }) photos!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of videos' }) videos!: number; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Total storage usage in bytes' }) usage!: number; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage usage for photos in bytes' }) usagePhotos!: number; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage usage for videos in bytes' }) usageVideos!: number; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ + type: 'integer', + format: 'int64', + nullable: true, + description: 'User quota size in bytes (null if unlimited)', + }) quotaSizeInBytes!: number | null; } export class ServerStatsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of photos' }) photos = 0; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Total number of videos' }) videos = 0; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Total storage usage in bytes' }) usage = 0; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage usage for photos in bytes' }) usagePhotos = 0; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage usage for videos in bytes' }) usageVideos = 0; @ApiProperty({ @@ -134,44 +170,71 @@ export class ServerStatsResponseDto { } export class ServerMediaTypesResponseDto { + @ApiProperty({ description: 'Supported video MIME types' }) video!: string[]; + @ApiProperty({ description: 'Supported image MIME types' }) image!: string[]; + @ApiProperty({ description: 'Supported sidecar MIME types' }) sidecar!: string[]; } export class ServerThemeDto extends SystemConfigThemeDto {} export class ServerConfigDto { + @ApiProperty({ description: 'OAuth button text' }) oauthButtonText!: string; + @ApiProperty({ description: 'Login page message' }) loginPageMessage!: string; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of days before trashed assets are permanently deleted' }) trashDays!: number; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Delay in days before deleted users are permanently removed' }) userDeleteDelay!: number; + @ApiProperty({ description: 'Whether the server has been initialized' }) isInitialized!: boolean; + @ApiProperty({ description: 'Whether the admin has completed onboarding' }) isOnboarded!: boolean; + @ApiProperty({ description: 'External domain URL' }) externalDomain!: string; + @ApiProperty({ description: 'Whether public user registration is enabled' }) publicUsers!: boolean; + @ApiProperty({ description: 'Map dark style URL' }) mapDarkStyleUrl!: string; + @ApiProperty({ description: 'Map light style URL' }) mapLightStyleUrl!: string; + @ApiProperty({ description: 'Whether maintenance mode is active' }) maintenanceMode!: boolean; } export class ServerFeaturesDto { + @ApiProperty({ description: 'Whether smart search is enabled' }) smartSearch!: boolean; + @ApiProperty({ description: 'Whether duplicate detection is enabled' }) duplicateDetection!: boolean; + @ApiProperty({ description: 'Whether config file is available' }) configFile!: boolean; + @ApiProperty({ description: 'Whether facial recognition is enabled' }) facialRecognition!: boolean; + @ApiProperty({ description: 'Whether map feature is enabled' }) map!: boolean; + @ApiProperty({ description: 'Whether trash feature is enabled' }) trash!: boolean; + @ApiProperty({ description: 'Whether reverse geocoding is enabled' }) reverseGeocoding!: boolean; + @ApiProperty({ description: 'Whether face import is enabled' }) importFaces!: boolean; + @ApiProperty({ description: 'Whether OAuth is enabled' }) oauth!: boolean; + @ApiProperty({ description: 'Whether OAuth auto-launch is enabled' }) oauthAutoLaunch!: boolean; + @ApiProperty({ description: 'Whether password login is enabled' }) passwordLogin!: boolean; + @ApiProperty({ description: 'Whether sidecar files are supported' }) sidecar!: boolean; + @ApiProperty({ description: 'Whether search is enabled' }) search!: boolean; + @ApiProperty({ description: 'Whether email notifications are enabled' }) email!: boolean; + @ApiProperty({ description: 'Whether OCR is enabled' }) ocr!: boolean; } diff --git a/server/src/dtos/session.dto.ts b/server/src/dtos/session.dto.ts index 49351eda523f1..f918f0b3bb2c3 100644 --- a/server/src/dtos/session.dto.ts +++ b/server/src/dtos/session.dto.ts @@ -1,44 +1,55 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Equals, IsInt, IsPositive, IsString } from 'class-validator'; import { Session } from 'src/database'; import { Optional, ValidateBoolean } from 'src/validation'; export class SessionCreateDto { - /** - * session duration, in seconds - */ + @ApiPropertyOptional({ type: 'number', description: 'Session duration in seconds' }) @IsInt() @IsPositive() @Optional() duration?: number; + @ApiPropertyOptional({ description: 'Device type' }) @IsString() @Optional() deviceType?: string; + @ApiPropertyOptional({ description: 'Device OS' }) @IsString() @Optional() deviceOS?: string; } export class SessionUpdateDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Reset pending sync state' }) @Equals(true) isPendingSyncReset?: true; } export class SessionResponseDto { + @ApiProperty({ description: 'Session ID' }) id!: string; + @ApiProperty({ description: 'Creation date' }) createdAt!: string; + @ApiProperty({ description: 'Last update date' }) updatedAt!: string; + @ApiPropertyOptional({ description: 'Expiration date' }) expiresAt?: string; + @ApiProperty({ description: 'Is current session' }) current!: boolean; + @ApiProperty({ description: 'Device type' }) deviceType!: string; + @ApiProperty({ description: 'Device OS' }) deviceOS!: string; + @ApiProperty({ description: 'App version' }) appVersion!: string | null; + @ApiProperty({ description: 'Is pending sync reset' }) isPendingSyncReset!: boolean; } export class SessionCreateResponseDto extends SessionResponseDto { + @ApiProperty({ description: 'Session token' }) token!: string; } diff --git a/server/src/dtos/shared-link.dto.ts b/server/src/dtos/shared-link.dto.ts index 82698ebddc2a5..7b92f48e28b7d 100644 --- a/server/src/dtos/shared-link.dto.ts +++ b/server/src/dtos/shared-link.dto.ts @@ -1,119 +1,145 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsString } from 'class-validator'; import { SharedLink } from 'src/database'; -import { HistoryBuilder, Property } from 'src/decorators'; +import { HistoryBuilder } from 'src/decorators'; import { AlbumResponseDto, mapAlbumWithoutAssets } from 'src/dtos/album.dto'; import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto'; import { SharedLinkType } from 'src/enum'; import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateUUID } from 'src/validation'; export class SharedLinkSearchDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by album ID' }) albumId?: string; - @ValidateUUID({ optional: true }) - @Property({ history: new HistoryBuilder().added('v2.5.0') }) + @ValidateUUID({ + optional: true, + description: 'Filter by shared link ID', + history: new HistoryBuilder().added('v2.5.0'), + }) id?: string; } export class SharedLinkCreateDto { - @ValidateEnum({ enum: SharedLinkType, name: 'SharedLinkType' }) + @ValidateEnum({ enum: SharedLinkType, name: 'SharedLinkType', description: 'Shared link type' }) type!: SharedLinkType; - @ValidateUUID({ each: true, optional: true }) + @ValidateUUID({ each: true, optional: true, description: 'Asset IDs (for individual assets)' }) assetIds?: string[]; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Album ID (for album sharing)' }) albumId?: string; + @ApiPropertyOptional({ description: 'Link description' }) @Optional({ nullable: true, emptyToNull: true }) @IsString() description?: string | null; + @ApiPropertyOptional({ description: 'Link password' }) @Optional({ nullable: true, emptyToNull: true }) @IsString() password?: string | null; + @ApiPropertyOptional({ description: 'Custom URL slug' }) @Optional({ nullable: true, emptyToNull: true }) @IsString() slug?: string | null; - @ValidateDate({ optional: true, nullable: true }) + @ValidateDate({ optional: true, description: 'Expiration date' }) expiresAt?: Date | null = null; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Allow uploads' }) allowUpload?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Allow downloads', default: true }) allowDownload?: boolean = true; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Show metadata', default: true }) showMetadata?: boolean = true; } export class SharedLinkEditDto { + @ApiPropertyOptional({ description: 'Link description' }) @Optional({ nullable: true, emptyToNull: true }) @IsString() description?: string | null; + @ApiPropertyOptional({ description: 'Link password' }) @Optional({ nullable: true, emptyToNull: true }) @IsString() password?: string | null; + @ApiPropertyOptional({ description: 'Custom URL slug' }) @Optional({ nullable: true, emptyToNull: true }) @IsString() slug?: string | null; + @ApiPropertyOptional({ description: 'Expiration date' }) @Optional({ nullable: true }) expiresAt?: Date | null; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Allow uploads' }) allowUpload?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Allow downloads' }) allowDownload?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Show metadata' }) showMetadata?: boolean; - /** - * Few clients cannot send null to set the expiryTime to never. - * Setting this flag and not sending expiryAt is considered as null instead. - * Clients that can send null values can ignore this. - */ - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ + optional: true, + description: + 'Whether to change the expiry time. Few clients cannot send null to set the expiryTime to never. Setting this flag and not sending expiryAt is considered as null instead. Clients that can send null values can ignore this.', + }) changeExpiryTime?: boolean; } export class SharedLinkPasswordDto { + @ApiPropertyOptional({ example: 'password', description: 'Link password' }) @IsString() @Optional() - @ApiProperty({ example: 'password' }) password?: string; + @ApiPropertyOptional({ description: 'Access token' }) @IsString() @Optional() token?: string; } export class SharedLinkResponseDto { + @ApiProperty({ description: 'Shared link ID' }) id!: string; + @ApiProperty({ description: 'Link description' }) description!: string | null; + @ApiProperty({ description: 'Has password' }) password!: string | null; + @ApiPropertyOptional({ description: 'Access token' }) token?: string | null; + @ApiProperty({ description: 'Owner user ID' }) userId!: string; + @ApiProperty({ description: 'Encryption key (base64url)' }) key!: string; - @ValidateEnum({ enum: SharedLinkType, name: 'SharedLinkType' }) + @ValidateEnum({ enum: SharedLinkType, name: 'SharedLinkType', description: 'Shared link type' }) type!: SharedLinkType; + @ApiProperty({ description: 'Creation date' }) createdAt!: Date; + @ApiProperty({ description: 'Expiration date' }) expiresAt!: Date | null; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) assets!: AssetResponseDto[]; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) album?: AlbumResponseDto; + @ApiProperty({ description: 'Allow uploads' }) allowUpload!: boolean; + @ApiProperty({ description: 'Allow downloads' }) allowDownload!: boolean; + @ApiProperty({ description: 'Show metadata' }) showMetadata!: boolean; + @ApiProperty({ description: 'Custom URL slug' }) slug!: string | null; } diff --git a/server/src/dtos/stack.dto.ts b/server/src/dtos/stack.dto.ts index 17037dd892a2f..a76b35e08e73d 100644 --- a/server/src/dtos/stack.dto.ts +++ b/server/src/dtos/stack.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty } from '@nestjs/swagger'; import { ArrayMinSize } from 'class-validator'; import { Stack } from 'src/database'; import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto'; @@ -5,25 +6,27 @@ import { AuthDto } from 'src/dtos/auth.dto'; import { ValidateUUID } from 'src/validation'; export class StackCreateDto { - /** first asset becomes the primary */ - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Asset IDs (first becomes primary, min 2)' }) @ArrayMinSize(2) assetIds!: string[]; } export class StackSearchDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by primary asset ID' }) primaryAssetId?: string; } export class StackUpdateDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Primary asset ID' }) primaryAssetId?: string; } export class StackResponseDto { + @ApiProperty({ description: 'Stack ID' }) id!: string; + @ApiProperty({ description: 'Primary asset ID' }) primaryAssetId!: string; + @ApiProperty({ description: 'Stack assets' }) assets!: AssetResponseDto[]; } diff --git a/server/src/dtos/sync.dto.ts b/server/src/dtos/sync.dto.ts index 0d1ab0e74db45..59d7d373f011f 100644 --- a/server/src/dtos/sync.dto.ts +++ b/server/src/dtos/sync.dto.ts @@ -17,32 +17,35 @@ import { UserMetadata } from 'src/types'; import { ValidateBoolean, ValidateDate, ValidateEnum, ValidateUUID } from 'src/validation'; export class AssetFullSyncDto { - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Last asset ID (pagination)' }) lastId?: string; - @ValidateDate() + @ValidateDate({ description: 'Sync assets updated until this date' }) updatedUntil!: Date; + @ApiProperty({ type: 'integer', description: 'Maximum number of assets to return' }) @IsInt() @IsPositive() - @ApiProperty({ type: 'integer' }) limit!: number; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'Filter by user ID' }) userId?: string; } export class AssetDeltaSyncDto { - @ValidateDate() + @ValidateDate({ description: 'Sync assets updated after this date' }) updatedAfter!: Date; - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'User IDs to sync' }) userIds!: string[]; } export class AssetDeltaSyncResponseDto { + @ApiProperty({ description: 'Whether full sync is needed' }) needsFullSync!: boolean; + @ApiProperty({ description: 'Upserted assets' }) upserted!: AssetResponseDto[]; + @ApiProperty({ description: 'Deleted asset IDs' }) deleted!: string[]; } @@ -57,21 +60,31 @@ export const ExtraModel = (): ClassDecorator => { @ExtraModel() export class SyncUserV1 { + @ApiProperty({ description: 'User ID' }) id!: string; + @ApiProperty({ description: 'User name' }) name!: string; + @ApiProperty({ description: 'User email' }) email!: string; - @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', nullable: true }) + @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', description: 'User avatar color' }) avatarColor!: UserAvatarColor | null; + @ApiProperty({ description: 'User deleted at' }) deletedAt!: Date | null; + @ApiProperty({ description: 'User has profile image' }) hasProfileImage!: boolean; + @ApiProperty({ description: 'User profile changed at' }) profileChangedAt!: Date; } @ExtraModel() export class SyncAuthUserV1 extends SyncUserV1 { + @ApiProperty({ description: 'User is admin' }) isAdmin!: boolean; + @ApiProperty({ description: 'User pin code' }) pinCode!: string | null; + @ApiProperty({ description: 'User OAuth ID' }) oauthId!: string; + @ApiProperty({ description: 'User storage label' }) storageLabel!: string | null; @ApiProperty({ type: 'integer' }) quotaSizeInBytes!: number | null; @@ -81,135 +94,189 @@ export class SyncAuthUserV1 extends SyncUserV1 { @ExtraModel() export class SyncUserDeleteV1 { + @ApiProperty({ description: 'User ID' }) userId!: string; } @ExtraModel() export class SyncPartnerV1 { + @ApiProperty({ description: 'Shared by ID' }) sharedById!: string; + @ApiProperty({ description: 'Shared with ID' }) sharedWithId!: string; + @ApiProperty({ description: 'In timeline' }) inTimeline!: boolean; } @ExtraModel() export class SyncPartnerDeleteV1 { + @ApiProperty({ description: 'Shared by ID' }) sharedById!: string; + @ApiProperty({ description: 'Shared with ID' }) sharedWithId!: string; } @ExtraModel() export class SyncAssetV1 { + @ApiProperty({ description: 'Asset ID' }) id!: string; + @ApiProperty({ description: 'Owner ID' }) ownerId!: string; + @ApiProperty({ description: 'Original file name' }) originalFileName!: string; + @ApiProperty({ description: 'Thumbhash' }) thumbhash!: string | null; + @ApiProperty({ description: 'Checksum' }) checksum!: string; + @ApiProperty({ description: 'File created at' }) fileCreatedAt!: Date | null; + @ApiProperty({ description: 'File modified at' }) fileModifiedAt!: Date | null; + @ApiProperty({ description: 'Local date time' }) localDateTime!: Date | null; + @ApiProperty({ description: 'Duration' }) duration!: string | null; - @ValidateEnum({ enum: AssetType, name: 'AssetTypeEnum' }) + @ValidateEnum({ enum: AssetType, name: 'AssetTypeEnum', description: 'Asset type' }) type!: AssetType; + @ApiProperty({ description: 'Deleted at' }) deletedAt!: Date | null; + @ApiProperty({ description: 'Is favorite' }) isFavorite!: boolean; - @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility' }) + @ValidateEnum({ enum: AssetVisibility, name: 'AssetVisibility', description: 'Asset visibility' }) visibility!: AssetVisibility; + @ApiProperty({ description: 'Live photo video ID' }) livePhotoVideoId!: string | null; + @ApiProperty({ description: 'Stack ID' }) stackId!: string | null; + @ApiProperty({ description: 'Library ID' }) libraryId!: string | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Asset width' }) width!: number | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Asset height' }) height!: number | null; - @ApiProperty({ type: 'boolean' }) + @ApiProperty({ description: 'Is edited' }) isEdited!: boolean; } @ExtraModel() export class SyncAssetDeleteV1 { + @ApiProperty({ description: 'Asset ID' }) assetId!: string; } @ExtraModel() export class SyncAssetExifV1 { + @ApiProperty({ description: 'Asset ID' }) assetId!: string; + @ApiProperty({ description: 'Description' }) description!: string | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Exif image width' }) exifImageWidth!: number | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Exif image height' }) exifImageHeight!: number | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'File size in byte' }) fileSizeInByte!: number | null; + @ApiProperty({ description: 'Orientation' }) orientation!: string | null; + @ApiProperty({ description: 'Date time original' }) dateTimeOriginal!: Date | null; + @ApiProperty({ description: 'Modify date' }) modifyDate!: Date | null; + @ApiProperty({ description: 'Time zone' }) timeZone!: string | null; - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'Latitude' }) latitude!: number | null; - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'Longitude' }) longitude!: number | null; + @ApiProperty({ description: 'Projection type' }) projectionType!: string | null; + @ApiProperty({ description: 'City' }) city!: string | null; + @ApiProperty({ description: 'State' }) state!: string | null; + @ApiProperty({ description: 'Country' }) country!: string | null; + @ApiProperty({ description: 'Make' }) make!: string | null; + @ApiProperty({ description: 'Model' }) model!: string | null; + @ApiProperty({ description: 'Lens model' }) lensModel!: string | null; - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'F number' }) fNumber!: number | null; - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'Focal length' }) focalLength!: number | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'ISO' }) iso!: number | null; + @ApiProperty({ description: 'Exposure time' }) exposureTime!: string | null; + @ApiProperty({ description: 'Profile description' }) profileDescription!: string | null; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Rating' }) rating!: number | null; - @ApiProperty({ type: 'number', format: 'double' }) + @ApiProperty({ type: 'number', format: 'double', description: 'FPS' }) fps!: number | null; } @ExtraModel() export class SyncAssetMetadataV1 { + @ApiProperty({ description: 'Asset ID' }) assetId!: string; + @ApiProperty({ description: 'Key' }) key!: string; + @ApiProperty({ description: 'Value' }) value!: object; } @ExtraModel() export class SyncAssetMetadataDeleteV1 { + @ApiProperty({ description: 'Asset ID' }) assetId!: string; + @ApiProperty({ description: 'Key' }) key!: string; } @ExtraModel() export class SyncAlbumDeleteV1 { + @ApiProperty({ description: 'Album ID' }) albumId!: string; } @ExtraModel() export class SyncAlbumUserDeleteV1 { + @ApiProperty({ description: 'Album ID' }) albumId!: string; + @ApiProperty({ description: 'User ID' }) userId!: string; } @ExtraModel() export class SyncAlbumUserV1 { + @ApiProperty({ description: 'Album ID' }) albumId!: string; + @ApiProperty({ description: 'User ID' }) userId!: string; - @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole' }) + @ValidateEnum({ enum: AlbumUserRole, name: 'AlbumUserRole', description: 'Album user role' }) role!: AlbumUserRole; } @ExtraModel() export class SyncAlbumV1 { + @ApiProperty({ description: 'Album ID' }) id!: string; + @ApiProperty({ description: 'Owner ID' }) ownerId!: string; + @ApiProperty({ description: 'Album name' }) name!: string; + @ApiProperty({ description: 'Album description' }) description!: string; + @ApiProperty({ description: 'Created at' }) createdAt!: Date; + @ApiProperty({ description: 'Updated at' }) updatedAt!: Date; + @ApiProperty({ description: 'Thumbnail asset ID' }) thumbnailAssetId!: string | null; + @ApiProperty({ description: 'Is activity enabled' }) isActivityEnabled!: boolean; @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder' }) order!: AssetOrder; @@ -217,87 +284,127 @@ export class SyncAlbumV1 { @ExtraModel() export class SyncAlbumToAssetV1 { + @ApiProperty({ description: 'Album ID' }) albumId!: string; + @ApiProperty({ description: 'Asset ID' }) assetId!: string; } @ExtraModel() export class SyncAlbumToAssetDeleteV1 { + @ApiProperty({ description: 'Album ID' }) albumId!: string; + @ApiProperty({ description: 'Asset ID' }) assetId!: string; } @ExtraModel() export class SyncMemoryV1 { + @ApiProperty({ description: 'Memory ID' }) id!: string; + @ApiProperty({ description: 'Created at' }) createdAt!: Date; + @ApiProperty({ description: 'Updated at' }) updatedAt!: Date; + @ApiProperty({ description: 'Deleted at' }) deletedAt!: Date | null; + @ApiProperty({ description: 'Owner ID' }) ownerId!: string; - @ValidateEnum({ enum: MemoryType, name: 'MemoryType' }) + @ValidateEnum({ enum: MemoryType, name: 'MemoryType', description: 'Memory type' }) type!: MemoryType; + @ApiProperty({ description: 'Data' }) data!: object; + @ApiProperty({ description: 'Is saved' }) isSaved!: boolean; + @ApiProperty({ description: 'Memory at' }) memoryAt!: Date; + @ApiProperty({ description: 'Seen at' }) seenAt!: Date | null; + @ApiProperty({ description: 'Show at' }) showAt!: Date | null; + @ApiProperty({ description: 'Hide at' }) hideAt!: Date | null; } @ExtraModel() export class SyncMemoryDeleteV1 { + @ApiProperty({ description: 'Memory ID' }) memoryId!: string; } @ExtraModel() export class SyncMemoryAssetV1 { + @ApiProperty({ description: 'Memory ID' }) memoryId!: string; + @ApiProperty({ description: 'Asset ID' }) assetId!: string; } @ExtraModel() export class SyncMemoryAssetDeleteV1 { + @ApiProperty({ description: 'Memory ID' }) memoryId!: string; + @ApiProperty({ description: 'Asset ID' }) assetId!: string; } @ExtraModel() export class SyncStackV1 { + @ApiProperty({ description: 'Stack ID' }) id!: string; + @ApiProperty({ description: 'Created at' }) createdAt!: Date; + @ApiProperty({ description: 'Updated at' }) updatedAt!: Date; + @ApiProperty({ description: 'Primary asset ID' }) primaryAssetId!: string; + @ApiProperty({ description: 'Owner ID' }) ownerId!: string; } @ExtraModel() export class SyncStackDeleteV1 { + @ApiProperty({ description: 'Stack ID' }) stackId!: string; } @ExtraModel() export class SyncPersonV1 { + @ApiProperty({ description: 'Person ID' }) id!: string; + @ApiProperty({ description: 'Created at' }) createdAt!: Date; + @ApiProperty({ description: 'Updated at' }) updatedAt!: Date; + @ApiProperty({ description: 'Owner ID' }) ownerId!: string; + @ApiProperty({ description: 'Person name' }) name!: string; + @ApiProperty({ description: 'Birth date' }) birthDate!: Date | null; + @ApiProperty({ description: 'Is hidden' }) isHidden!: boolean; + @ApiProperty({ description: 'Is favorite' }) isFavorite!: boolean; + @ApiProperty({ description: 'Color' }) color!: string | null; + @ApiProperty({ description: 'Face asset ID' }) faceAssetId!: string | null; } @ExtraModel() export class SyncPersonDeleteV1 { + @ApiProperty({ description: 'Person ID' }) personId!: string; } @ExtraModel() export class SyncAssetFaceV1 { + @ApiProperty({ description: 'Asset face ID' }) id!: string; + @ApiProperty({ description: 'Asset ID' }) assetId!: string; + @ApiProperty({ description: 'Person ID' }) personId!: string | null; @ApiProperty({ type: 'integer' }) imageWidth!: number; @@ -311,26 +418,31 @@ export class SyncAssetFaceV1 { boundingBoxX2!: number; @ApiProperty({ type: 'integer' }) boundingBoxY2!: number; + @ApiProperty({ description: 'Source type' }) sourceType!: string; } @ExtraModel() export class SyncAssetFaceDeleteV1 { + @ApiProperty({ description: 'Asset face ID' }) assetFaceId!: string; } @ExtraModel() export class SyncUserMetadataV1 { + @ApiProperty({ description: 'User ID' }) userId!: string; - @ValidateEnum({ enum: UserMetadataKey, name: 'UserMetadataKey' }) + @ValidateEnum({ enum: UserMetadataKey, name: 'UserMetadataKey', description: 'User metadata key' }) key!: UserMetadataKey; + @ApiProperty({ description: 'User metadata value' }) value!: UserMetadata[UserMetadataKey]; } @ExtraModel() export class SyncUserMetadataDeleteV1 { + @ApiProperty({ description: 'User ID' }) userId!: string; - @ValidateEnum({ enum: UserMetadataKey, name: 'UserMetadataKey' }) + @ValidateEnum({ enum: UserMetadataKey, name: 'UserMetadataKey', description: 'User metadata key' }) key!: UserMetadataKey; } @@ -394,26 +506,34 @@ export type SyncItem = { }; export class SyncStreamDto { - @ValidateEnum({ enum: SyncRequestType, name: 'SyncRequestType', each: true }) + @ValidateEnum({ enum: SyncRequestType, name: 'SyncRequestType', each: true, description: 'Sync request types' }) types!: SyncRequestType[]; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Reset sync state' }) reset?: boolean; } export class SyncAckDto { - @ValidateEnum({ enum: SyncEntityType, name: 'SyncEntityType' }) + @ValidateEnum({ enum: SyncEntityType, name: 'SyncEntityType', description: 'Sync entity type' }) type!: SyncEntityType; + @ApiProperty({ description: 'Acknowledgment ID' }) ack!: string; } export class SyncAckSetDto { + @ApiProperty({ description: 'Acknowledgment IDs (max 1000)' }) @ArrayMaxSize(1000) @IsString({ each: true }) acks!: string[]; } export class SyncAckDeleteDto { - @ValidateEnum({ enum: SyncEntityType, name: 'SyncEntityType', optional: true, each: true }) + @ValidateEnum({ + enum: SyncEntityType, + name: 'SyncEntityType', + optional: true, + each: true, + description: 'Sync entity types to delete acks for', + }) types?: SyncEntityType[]; } diff --git a/server/src/dtos/system-config.dto.ts b/server/src/dtos/system-config.dto.ts index b0d5a0646d804..7a0dcb6f3ad02 100644 --- a/server/src/dtos/system-config.dto.ts +++ b/server/src/dtos/system-config.dto.ts @@ -40,18 +40,20 @@ const isEmailNotificationEnabled = (config: SystemConfigSmtpDto) => config.enabl const isDatabaseBackupEnabled = (config: DatabaseBackupConfig) => config.enabled; export class DatabaseBackupConfig { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @ValidateIf(isDatabaseBackupEnabled) @IsNotEmpty() @IsCronExpression() @IsString() + @ApiProperty({ description: 'Cron expression' }) cronExpression!: string; @IsInt() @IsPositive() @IsNotEmpty() + @ApiProperty({ description: 'Keep last amount' }) keepLastAmount!: number; } @@ -67,171 +69,179 @@ export class SystemConfigFFmpegDto { @Min(0) @Max(51) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'CRF' }) crf!: number; @IsInt() @Min(0) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Threads' }) threads!: number; @IsString() + @ApiProperty({ description: 'Preset' }) preset!: string; - @ValidateEnum({ enum: VideoCodec, name: 'VideoCodec' }) + @ValidateEnum({ enum: VideoCodec, name: 'VideoCodec', description: 'Target video codec' }) targetVideoCodec!: VideoCodec; - @ValidateEnum({ enum: VideoCodec, name: 'VideoCodec', each: true }) + @ValidateEnum({ enum: VideoCodec, name: 'VideoCodec', each: true, description: 'Accepted video codecs' }) acceptedVideoCodecs!: VideoCodec[]; - @ValidateEnum({ enum: AudioCodec, name: 'AudioCodec' }) + @ValidateEnum({ enum: AudioCodec, name: 'AudioCodec', description: 'Target audio codec' }) targetAudioCodec!: AudioCodec; - @ValidateEnum({ enum: AudioCodec, name: 'AudioCodec', each: true }) + @ValidateEnum({ enum: AudioCodec, name: 'AudioCodec', each: true, description: 'Accepted audio codecs' }) acceptedAudioCodecs!: AudioCodec[]; - @ValidateEnum({ enum: VideoContainer, name: 'VideoContainer', each: true }) + @ValidateEnum({ enum: VideoContainer, name: 'VideoContainer', each: true, description: 'Accepted containers' }) acceptedContainers!: VideoContainer[]; @IsString() + @ApiProperty({ description: 'Target resolution' }) targetResolution!: string; @IsString() + @ApiProperty({ description: 'Max bitrate' }) maxBitrate!: string; @IsInt() @Min(-1) @Max(16) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'B-frames' }) bframes!: number; @IsInt() @Min(0) @Max(6) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'References' }) refs!: number; @IsInt() @Min(0) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'GOP size' }) gopSize!: number; - @ValidateBoolean() + @ValidateBoolean({ description: 'Temporal AQ' }) temporalAQ!: boolean; - @ValidateEnum({ enum: CQMode, name: 'CQMode' }) + @ValidateEnum({ enum: CQMode, name: 'CQMode', description: 'CQ mode' }) cqMode!: CQMode; - @ValidateBoolean() + @ValidateBoolean({ description: 'Two pass' }) twoPass!: boolean; + @ApiProperty({ description: 'Preferred hardware device' }) @IsString() preferredHwDevice!: string; - @ValidateEnum({ enum: TranscodePolicy, name: 'TranscodePolicy' }) + @ValidateEnum({ enum: TranscodePolicy, name: 'TranscodePolicy', description: 'Transcode policy' }) transcode!: TranscodePolicy; - @ValidateEnum({ enum: TranscodeHardwareAcceleration, name: 'TranscodeHWAccel' }) + @ValidateEnum({ + enum: TranscodeHardwareAcceleration, + name: 'TranscodeHWAccel', + description: 'Transcode hardware acceleration', + }) accel!: TranscodeHardwareAcceleration; - @ValidateBoolean() + @ValidateBoolean({ description: 'Accelerated decode' }) accelDecode!: boolean; - @ValidateEnum({ enum: ToneMapping, name: 'ToneMapping' }) + @ValidateEnum({ enum: ToneMapping, name: 'ToneMapping', description: 'Tone mapping' }) tonemap!: ToneMapping; } class JobSettingsDto { @IsInt() @IsPositive() - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Concurrency' }) concurrency!: number; } class SystemConfigJobDto implements Record { - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.ThumbnailGeneration]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.MetadataExtraction]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.VideoConversion]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.SmartSearch]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Migration]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.BackgroundTask]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Search]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.FaceDetection]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Ocr]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Sidecar]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Library]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Notification]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) [QueueName.Workflow]!: JobSettingsDto; - @ApiProperty({ type: JobSettingsDto }) + @ApiProperty({ type: JobSettingsDto, description: undefined }) @ValidateNested() @IsObject() @Type(() => JobSettingsDto) @@ -239,7 +249,7 @@ class SystemConfigJobDto implements Record } class SystemConfigLibraryScanDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @ValidateIf(isLibraryScanEnabled) @@ -250,7 +260,7 @@ class SystemConfigLibraryScanDto { } class SystemConfigLibraryWatchDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; } @@ -267,7 +277,7 @@ class SystemConfigLibraryDto { } class SystemConfigLoggingDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @ValidateEnum({ enum: LogLevel, name: 'LogLevel' }) @@ -275,7 +285,7 @@ class SystemConfigLoggingDto { } class MachineLearningAvailabilityChecksDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @IsInt() @@ -286,7 +296,7 @@ class MachineLearningAvailabilityChecksDto { } class SystemConfigMachineLearningDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @IsUrl({ require_tld: false, allow_underscores: true }, { each: true }) @@ -332,7 +342,7 @@ export class MapThemeDto { } class SystemConfigMapDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @IsNotEmpty() @@ -345,7 +355,7 @@ class SystemConfigMapDto { } class SystemConfigNewVersionCheckDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; } @@ -353,72 +363,82 @@ class SystemConfigNightlyTasksDto { @IsDateStringFormat('HH:mm', { message: 'startTime must be in HH:mm format' }) startTime!: string; - @ValidateBoolean() + @ValidateBoolean({ description: 'Database cleanup' }) databaseCleanup!: boolean; - @ValidateBoolean() + @ValidateBoolean({ description: 'Missing thumbnails' }) missingThumbnails!: boolean; - @ValidateBoolean() + @ValidateBoolean({ description: 'Cluster new faces' }) clusterNewFaces!: boolean; - @ValidateBoolean() + @ValidateBoolean({ description: 'Generate memories' }) generateMemories!: boolean; - @ValidateBoolean() + @ValidateBoolean({ description: 'Sync quota usage' }) syncQuotaUsage!: boolean; } class SystemConfigOAuthDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Auto launch' }) autoLaunch!: boolean; - @ValidateBoolean() + @ValidateBoolean({ description: 'Auto register' }) autoRegister!: boolean; @IsString() + @ApiProperty({ description: 'Button text' }) buttonText!: string; @ValidateIf(isOAuthEnabled) @IsNotEmpty() @IsString() + @ApiProperty({ description: 'Client ID' }) clientId!: string; @ValidateIf(isOAuthEnabled) @IsString() + @ApiProperty({ description: 'Client secret' }) clientSecret!: string; - @ValidateEnum({ enum: OAuthTokenEndpointAuthMethod, name: 'OAuthTokenEndpointAuthMethod' }) + @ValidateEnum({ + enum: OAuthTokenEndpointAuthMethod, + name: 'OAuthTokenEndpointAuthMethod', + description: 'Token endpoint auth method', + }) tokenEndpointAuthMethod!: OAuthTokenEndpointAuthMethod; @IsInt() @IsPositive() @Optional() - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Timeout' }) timeout!: number; @IsNumber() @Min(0) @Optional({ nullable: true }) - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Default storage quota' }) defaultStorageQuota!: number | null; - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @ValidateIf(isOAuthEnabled) @IsNotEmpty() @IsString() + @ApiProperty({ description: 'Issuer URL' }) issuerUrl!: string; - @ValidateBoolean() + @ValidateBoolean({ description: 'Mobile override enabled' }) mobileOverrideEnabled!: boolean; @ValidateIf(isOAuthOverrideEnabled) @IsUrl() + @ApiProperty({ description: 'Mobile redirect URI' }) mobileRedirectUri!: string; @IsString() + @ApiProperty({ description: 'Scope' }) scope!: string; @IsString() @@ -427,30 +447,34 @@ class SystemConfigOAuthDto { @IsString() @IsNotEmpty() + @ApiProperty({ description: 'Profile signing algorithm' }) profileSigningAlgorithm!: string; @IsString() + @ApiProperty({ description: 'Storage label claim' }) storageLabelClaim!: string; @IsString() + @ApiProperty({ description: 'Storage quota claim' }) storageQuotaClaim!: string; @IsString() + @ApiProperty({ description: 'Role claim' }) roleClaim!: string; } class SystemConfigPasswordLoginDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; } class SystemConfigReverseGeocodingDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; } class SystemConfigFacesDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Import' }) import!: boolean; } @@ -464,51 +488,61 @@ class SystemConfigMetadataDto { class SystemConfigServerDto { @ValidateIf((_, value: string) => value !== '') @IsUrl({ require_tld: false, require_protocol: true, protocols: ['http', 'https'] }) + @ApiProperty({ description: 'External domain' }) externalDomain!: string; @IsString() + @ApiProperty({ description: 'Login page message' }) loginPageMessage!: string; - @ValidateBoolean() + @ValidateBoolean({ description: 'Public users' }) publicUsers!: boolean; } class SystemConfigSmtpTransportDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Whether to ignore SSL certificate errors' }) ignoreCert!: boolean; + @ApiProperty({ description: 'SMTP server hostname' }) @IsNotEmpty() @IsString() host!: string; + @ApiProperty({ description: 'SMTP server port', type: Number, minimum: 0, maximum: 65_535 }) @IsNumber() @Min(0) @Max(65_535) port!: number; - @ValidateBoolean() + @ValidateBoolean({ description: 'Whether to use secure connection (TLS/SSL)' }) secure!: boolean; + @ApiProperty({ description: 'SMTP username' }) @IsString() username!: string; + @ApiProperty({ description: 'SMTP password' }) @IsString() password!: string; } export class SystemConfigSmtpDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Whether SMTP email notifications are enabled' }) enabled!: boolean; + @ApiProperty({ description: 'Email address to send from' }) @ValidateIf(isEmailNotificationEnabled) @IsNotEmpty() @IsString() @IsNotEmpty() from!: string; + @ApiProperty({ description: 'Email address for replies' }) @IsString() replyTo!: string; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @ValidateIf(isEmailNotificationEnabled) @Type(() => SystemConfigSmtpTransportDto) @ValidateNested() @@ -542,48 +576,58 @@ class SystemConfigTemplatesDto { } class SystemConfigStorageTemplateDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; - @ValidateBoolean() + @ValidateBoolean({ description: 'Hash verification enabled' }) hashVerificationEnabled!: boolean; @IsNotEmpty() @IsString() + @ApiProperty({ description: 'Template' }) template!: string; } export class SystemConfigTemplateStorageOptionDto { + @ApiProperty({ description: 'Available year format options for storage template' }) yearOptions!: string[]; + @ApiProperty({ description: 'Available month format options for storage template' }) monthOptions!: string[]; + @ApiProperty({ description: 'Available week format options for storage template' }) weekOptions!: string[]; + @ApiProperty({ description: 'Available day format options for storage template' }) dayOptions!: string[]; + @ApiProperty({ description: 'Available hour format options for storage template' }) hourOptions!: string[]; + @ApiProperty({ description: 'Available minute format options for storage template' }) minuteOptions!: string[]; + @ApiProperty({ description: 'Available second format options for storage template' }) secondOptions!: string[]; + @ApiProperty({ description: 'Available preset template options' }) presetOptions!: string[]; } export class SystemConfigThemeDto { + @ApiProperty({ description: 'Custom CSS for theming' }) @IsString() customCss!: string; } class SystemConfigGeneratedImageDto { - @ValidateEnum({ enum: ImageFormat, name: 'ImageFormat' }) + @ValidateEnum({ enum: ImageFormat, name: 'ImageFormat', description: 'Image format' }) format!: ImageFormat; @IsInt() @Min(1) @Max(100) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Quality' }) quality!: number; @IsInt() @Min(1) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Size' }) size!: number; @ValidateBoolean({ optional: true, default: false }) @@ -591,20 +635,20 @@ class SystemConfigGeneratedImageDto { } class SystemConfigGeneratedFullsizeImageDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; - @ValidateEnum({ enum: ImageFormat, name: 'ImageFormat' }) + @ValidateEnum({ enum: ImageFormat, name: 'ImageFormat', description: 'Image format' }) format!: ImageFormat; @IsInt() @Min(1) @Max(100) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Quality' }) quality!: number; - @ValidateBoolean({ optional: true, default: false }) + @ValidateBoolean({ optional: true, default: false, description: 'Progressive' }) progressive?: boolean; } @@ -612,33 +656,39 @@ export class SystemConfigImageDto { @Type(() => SystemConfigGeneratedImageDto) @ValidateNested() @IsObject() + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) thumbnail!: SystemConfigGeneratedImageDto; @Type(() => SystemConfigGeneratedImageDto) @ValidateNested() @IsObject() + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) preview!: SystemConfigGeneratedImageDto; @Type(() => SystemConfigGeneratedFullsizeImageDto) @ValidateNested() @IsObject() + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) fullsize!: SystemConfigGeneratedFullsizeImageDto; - @ValidateEnum({ enum: Colorspace, name: 'Colorspace' }) + @ValidateEnum({ enum: Colorspace, name: 'Colorspace', description: 'Colorspace' }) colorspace!: Colorspace; - @ValidateBoolean() + @ValidateBoolean({ description: 'Extract embedded' }) extractEmbedded!: boolean; } class SystemConfigTrashDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Enabled' }) enabled!: boolean; @IsInt() @Min(0) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Days' }) days!: number; } @@ -646,111 +696,153 @@ class SystemConfigUserDto { @IsInt() @Min(1) @Type(() => Number) - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Delete delay' }) deleteDelay!: number; } export class SystemConfigDto implements SystemConfig { + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigBackupsDto) @ValidateNested() @IsObject() backup!: SystemConfigBackupsDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigFFmpegDto) @ValidateNested() @IsObject() ffmpeg!: SystemConfigFFmpegDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigLoggingDto) @ValidateNested() @IsObject() logging!: SystemConfigLoggingDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigMachineLearningDto) @ValidateNested() @IsObject() machineLearning!: SystemConfigMachineLearningDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigMapDto) @ValidateNested() @IsObject() map!: SystemConfigMapDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigNewVersionCheckDto) @ValidateNested() @IsObject() newVersionCheck!: SystemConfigNewVersionCheckDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigNightlyTasksDto) @ValidateNested() @IsObject() nightlyTasks!: SystemConfigNightlyTasksDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigOAuthDto) @ValidateNested() @IsObject() oauth!: SystemConfigOAuthDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigPasswordLoginDto) @ValidateNested() @IsObject() passwordLogin!: SystemConfigPasswordLoginDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigReverseGeocodingDto) @ValidateNested() @IsObject() reverseGeocoding!: SystemConfigReverseGeocodingDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigMetadataDto) @ValidateNested() @IsObject() metadata!: SystemConfigMetadataDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigStorageTemplateDto) @ValidateNested() @IsObject() storageTemplate!: SystemConfigStorageTemplateDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigJobDto) @ValidateNested() @IsObject() job!: SystemConfigJobDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigImageDto) @ValidateNested() @IsObject() image!: SystemConfigImageDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigTrashDto) @ValidateNested() @IsObject() trash!: SystemConfigTrashDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigThemeDto) @ValidateNested() @IsObject() theme!: SystemConfigThemeDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigLibraryDto) @ValidateNested() @IsObject() library!: SystemConfigLibraryDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigNotificationsDto) @ValidateNested() @IsObject() notifications!: SystemConfigNotificationsDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigTemplatesDto) @ValidateNested() @IsObject() templates!: SystemConfigTemplatesDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigServerDto) @ValidateNested() @IsObject() server!: SystemConfigServerDto; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) @Type(() => SystemConfigUserDto) @ValidateNested() @IsObject() diff --git a/server/src/dtos/system-metadata.dto.ts b/server/src/dtos/system-metadata.dto.ts index 0005aee7ebb29..0a4d55c9708cc 100644 --- a/server/src/dtos/system-metadata.dto.ts +++ b/server/src/dtos/system-metadata.dto.ts @@ -1,21 +1,26 @@ +import { ApiProperty } from '@nestjs/swagger'; import { ValidateBoolean } from 'src/validation'; export class AdminOnboardingUpdateDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Is admin onboarded' }) isOnboarded!: boolean; } export class AdminOnboardingResponseDto { - @ValidateBoolean() + @ValidateBoolean({ description: 'Is admin onboarded' }) isOnboarded!: boolean; } export class ReverseGeocodingStateResponseDto { + @ApiProperty({ description: 'Last update timestamp' }) lastUpdate!: string | null; + @ApiProperty({ description: 'Last import file name' }) lastImportFileName!: string | null; } export class VersionCheckStateResponseDto { + @ApiProperty({ description: 'Last check timestamp' }) checkedAt!: string | null; + @ApiProperty({ description: 'Release version' }) releaseVersion!: string | null; } diff --git a/server/src/dtos/tag.dto.ts b/server/src/dtos/tag.dto.ts index a35801d07e668..231e6cc50146a 100644 --- a/server/src/dtos/tag.dto.ts +++ b/server/src/dtos/tag.dto.ts @@ -1,53 +1,64 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsHexColor, IsNotEmpty, IsString } from 'class-validator'; import { Tag } from 'src/database'; import { Optional, ValidateHexColor, ValidateUUID } from 'src/validation'; export class TagCreateDto { + @ApiProperty({ description: 'Tag name' }) @IsString() @IsNotEmpty() name!: string; - @ValidateUUID({ optional: true, nullable: true }) + @ValidateUUID({ optional: true, description: 'Parent tag ID' }) parentId?: string | null; + @ApiPropertyOptional({ description: 'Tag color (hex)' }) @IsHexColor() @Optional({ nullable: true, emptyToNull: true }) color?: string; } export class TagUpdateDto { - @Optional({ emptyToNull: true, nullable: true }) + @ApiPropertyOptional({ description: 'Tag color (hex)' }) + @Optional({ emptyToNull: true }) @ValidateHexColor() color?: string | null; } export class TagUpsertDto { + @ApiProperty({ description: 'Tag names to upsert' }) @IsString({ each: true }) @IsNotEmpty({ each: true }) tags!: string[]; } export class TagBulkAssetsDto { - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Tag IDs' }) tagIds!: string[]; - @ValidateUUID({ each: true }) + @ValidateUUID({ each: true, description: 'Asset IDs' }) assetIds!: string[]; } export class TagBulkAssetsResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of assets tagged' }) count!: number; } export class TagResponseDto { + @ApiProperty({ description: 'Tag ID' }) id!: string; + @ApiPropertyOptional({ description: 'Parent tag ID' }) parentId?: string; + @ApiProperty({ description: 'Tag name' }) name!: string; + @ApiProperty({ description: 'Tag value (full path)' }) value!: string; + @ApiProperty({ description: 'Creation date' }) createdAt!: Date; + @ApiProperty({ description: 'Last update date' }) updatedAt!: Date; + @ApiPropertyOptional({ description: 'Tag color (hex)' }) color?: string; } diff --git a/server/src/dtos/time-bucket.dto.ts b/server/src/dtos/time-bucket.dto.ts index 58772da00b600..dfd474d88520e 100644 --- a/server/src/dtos/time-bucket.dto.ts +++ b/server/src/dtos/time-bucket.dto.ts @@ -132,7 +132,7 @@ export class TimeBucketAssetResponseDto { @ApiProperty({ type: 'array', items: { type: 'string' }, - description: 'Array of file creation timestamps in UTC (ISO 8601 format, without timezone)', + description: 'Array of file creation timestamps in UTC', }) fileCreatedAt!: string[]; diff --git a/server/src/dtos/trash.dto.ts b/server/src/dtos/trash.dto.ts index d8e139bff2858..f1d1f109f6142 100644 --- a/server/src/dtos/trash.dto.ts +++ b/server/src/dtos/trash.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class TrashResponseDto { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Number of items in trash' }) count!: number; } diff --git a/server/src/dtos/user-preferences.dto.ts b/server/src/dtos/user-preferences.dto.ts index 452384b423c7d..cce19940074fc 100644 --- a/server/src/dtos/user-preferences.dto.ts +++ b/server/src/dtos/user-preferences.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { IsDateString, IsInt, IsPositive, ValidateNested } from 'class-validator'; import { AssetOrder, UserAvatarColor } from 'src/enum'; @@ -6,71 +6,72 @@ import { UserPreferences } from 'src/types'; import { Optional, ValidateBoolean, ValidateEnum } from 'src/validation'; class AvatarUpdate { - @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true }) + @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, description: 'Avatar color' }) color?: UserAvatarColor; } class MemoriesUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether memories are enabled' }) enabled?: boolean; @Optional() @IsInt() @IsPositive() - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Memory duration in seconds' }) duration?: number; } class RatingsUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether ratings are enabled' }) enabled?: boolean; } +@ApiSchema({ description: 'Album preferences' }) class AlbumsUpdate { - @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', optional: true }) + @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', optional: true, description: 'Default asset order for albums' }) defaultAssetOrder?: AssetOrder; } class FoldersUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether folders are enabled' }) enabled?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether folders appear in web sidebar' }) sidebarWeb?: boolean; } class PeopleUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether people are enabled' }) enabled?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether people appear in web sidebar' }) sidebarWeb?: boolean; } class SharedLinksUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether shared links are enabled' }) enabled?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether shared links appear in web sidebar' }) sidebarWeb?: boolean; } class TagsUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether tags are enabled' }) enabled?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether tags appear in web sidebar' }) sidebarWeb?: boolean; } class EmailNotificationsUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether email notifications are enabled' }) enabled?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether to receive email notifications for album invites' }) albumInvite?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether to receive email notifications for album updates' }) albumUpdate?: boolean; } @@ -78,83 +79,108 @@ class DownloadUpdate implements Partial { @Optional() @IsInt() @IsPositive() - @ApiProperty({ type: 'integer' }) + @ApiPropertyOptional({ type: 'integer', description: 'Maximum archive size in bytes' }) archiveSize?: number; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether to include embedded videos in downloads' }) includeEmbeddedVideos?: boolean; } class PurchaseUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether to show support badge' }) showSupportBadge?: boolean; + @ApiPropertyOptional({ description: 'Date until which to hide buy button' }) @IsDateString() @Optional() hideBuyButtonUntil?: string; } class CastUpdate { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Whether Google Cast is enabled' }) gCastEnabled?: boolean; } export class UserPreferencesUpdateDto { + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => AlbumsUpdate) albums?: AlbumsUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => FoldersUpdate) folders?: FoldersUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => MemoriesUpdate) memories?: MemoriesUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => PeopleUpdate) people?: PeopleUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => RatingsUpdate) ratings?: RatingsUpdate; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined, required: false }) @Optional() @ValidateNested() @Type(() => SharedLinksUpdate) sharedLinks?: SharedLinksUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => TagsUpdate) tags?: TagsUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => AvatarUpdate) avatar?: AvatarUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => EmailNotificationsUpdate) emailNotifications?: EmailNotificationsUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => DownloadUpdate) download?: DownloadUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => PurchaseUpdate) purchase?: PurchaseUpdate; + // Description lives on schema to avoid duplication + @ApiPropertyOptional({ description: undefined }) @Optional() @ValidateNested() @Type(() => CastUpdate) @@ -162,74 +188,113 @@ export class UserPreferencesUpdateDto { } class AlbumsResponse { - @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder' }) + @ValidateEnum({ enum: AssetOrder, name: 'AssetOrder', description: 'Default asset order for albums' }) defaultAssetOrder: AssetOrder = AssetOrder.Desc; } class RatingsResponse { + @ApiProperty({ description: 'Whether ratings are enabled' }) enabled: boolean = false; } class MemoriesResponse { + @ApiProperty({ description: 'Whether memories are enabled' }) enabled: boolean = true; - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Memory duration in seconds' }) duration: number = 5; } class FoldersResponse { + @ApiProperty({ description: 'Whether folders are enabled' }) enabled: boolean = false; + @ApiProperty({ description: 'Whether folders appear in web sidebar' }) sidebarWeb: boolean = false; } class PeopleResponse { + @ApiProperty({ description: 'Whether people are enabled' }) enabled: boolean = true; + @ApiProperty({ description: 'Whether people appear in web sidebar' }) sidebarWeb: boolean = false; } class TagsResponse { + @ApiProperty({ description: 'Whether tags are enabled' }) enabled: boolean = true; + @ApiProperty({ description: 'Whether tags appear in web sidebar' }) sidebarWeb: boolean = true; } class SharedLinksResponse { + @ApiProperty({ description: 'Whether shared links are enabled' }) enabled: boolean = true; + @ApiProperty({ description: 'Whether shared links appear in web sidebar' }) sidebarWeb: boolean = false; } class EmailNotificationsResponse { + @ApiProperty({ description: 'Whether email notifications are enabled' }) enabled!: boolean; + @ApiProperty({ description: 'Whether to receive email notifications for album invites' }) albumInvite!: boolean; + @ApiProperty({ description: 'Whether to receive email notifications for album updates' }) albumUpdate!: boolean; } class DownloadResponse { - @ApiProperty({ type: 'integer' }) + @ApiProperty({ type: 'integer', description: 'Maximum archive size in bytes' }) archiveSize!: number; + @ApiProperty({ description: 'Whether to include embedded videos in downloads' }) includeEmbeddedVideos: boolean = false; } class PurchaseResponse { + @ApiProperty({ description: 'Whether to show support badge' }) showSupportBadge!: boolean; + @ApiProperty({ description: 'Date until which to hide buy button' }) hideBuyButtonUntil!: string; } class CastResponse { + @ApiProperty({ description: 'Whether Google Cast is enabled' }) gCastEnabled: boolean = false; } export class UserPreferencesResponseDto implements UserPreferences { + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) albums!: AlbumsResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) folders!: FoldersResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) memories!: MemoriesResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) people!: PeopleResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) ratings!: RatingsResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) sharedLinks!: SharedLinksResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) tags!: TagsResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) emailNotifications!: EmailNotificationsResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) download!: DownloadResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) purchase!: PurchaseResponse; + // Description lives on schema to avoid duplication + @ApiProperty({ description: undefined }) cast!: CastResponse; } diff --git a/server/src/dtos/user-profile.dto.ts b/server/src/dtos/user-profile.dto.ts index 16eea373e3458..6559dd052c031 100644 --- a/server/src/dtos/user-profile.dto.ts +++ b/server/src/dtos/user-profile.dto.ts @@ -2,12 +2,15 @@ import { ApiProperty } from '@nestjs/swagger'; import { UploadFieldName } from 'src/dtos/asset-media.dto'; export class CreateProfileImageDto { - @ApiProperty({ type: 'string', format: 'binary' }) + @ApiProperty({ type: 'string', format: 'binary', description: 'Profile image file' }) [UploadFieldName.PROFILE_DATA]!: Express.Multer.File; } export class CreateProfileImageResponseDto { + @ApiProperty({ description: 'User ID' }) userId!: string; + @ApiProperty({ description: 'Profile image change date', format: 'date-time' }) profileChangedAt!: Date; + @ApiProperty({ description: 'Profile image file path' }) profileImagePath!: string; } diff --git a/server/src/dtos/user.dto.ts b/server/src/dtos/user.dto.ts index c5067f3e8d351..598798dc4493c 100644 --- a/server/src/dtos/user.dto.ts +++ b/server/src/dtos/user.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; import { IsEmail, IsInt, IsNotEmpty, IsString, Min } from 'class-validator'; import { User, UserAdmin } from 'src/database'; @@ -7,39 +7,50 @@ import { UserMetadataItem } from 'src/types'; import { Optional, PinCode, ValidateBoolean, ValidateEnum, ValidateUUID, toEmail, toSanitized } from 'src/validation'; export class UserUpdateMeDto { + @ApiPropertyOptional({ description: 'User email' }) @Optional() @IsEmail({ require_tld: false }) @Transform(toEmail) email?: string; // TODO: migrate to the other change password endpoint + @ApiPropertyOptional({ description: 'User password (deprecated, use change password endpoint)' }) @Optional() @IsNotEmpty() @IsString() password?: string; + @ApiPropertyOptional({ description: 'User name' }) @Optional() @IsString() @IsNotEmpty() name?: string; - @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, nullable: true }) + @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, description: 'Avatar color' }) avatarColor?: UserAvatarColor | null; } export class UserResponseDto { + @ApiProperty({ description: 'User ID' }) id!: string; + @ApiProperty({ description: 'User name' }) name!: string; + @ApiProperty({ description: 'User email' }) email!: string; + @ApiProperty({ description: 'Profile image path' }) profileImagePath!: string; - @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor' }) + @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', description: 'Avatar color' }) avatarColor!: UserAvatarColor; + @ApiProperty({ description: 'Profile change date' }) profileChangedAt!: Date; } export class UserLicense { + @ApiProperty({ description: 'License key' }) licenseKey!: string; + @ApiProperty({ description: 'Activation key' }) activationKey!: string; + @ApiProperty({ description: 'Activation date' }) activatedAt!: Date; } @@ -63,108 +74,125 @@ export const mapUser = (entity: User | UserAdmin): UserResponseDto => { }; export class UserAdminSearchDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Include deleted users' }) withDeleted?: boolean; - @ValidateUUID({ optional: true }) + @ValidateUUID({ optional: true, description: 'User ID filter' }) id?: string; } export class UserAdminCreateDto { + @ApiProperty({ description: 'User email' }) @IsEmail({ require_tld: false }) @Transform(toEmail) email!: string; + @ApiProperty({ description: 'User password' }) @IsString() password!: string; + @ApiProperty({ description: 'User name' }) @IsNotEmpty() @IsString() name!: string; - @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, nullable: true }) + @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, description: 'Avatar color' }) avatarColor?: UserAvatarColor | null; + @ApiPropertyOptional({ description: 'Storage label' }) @Optional({ nullable: true }) @IsString() @Transform(toSanitized) storageLabel?: string | null; + @ApiPropertyOptional({ type: 'integer', format: 'int64', description: 'Storage quota in bytes' }) @Optional({ nullable: true }) @IsInt() @Min(0) - @ApiProperty({ type: 'integer', format: 'int64' }) quotaSizeInBytes?: number | null; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Require password change on next login' }) shouldChangePassword?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Send notification email' }) notify?: boolean; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Grant admin privileges' }) isAdmin?: boolean; } export class UserAdminUpdateDto { + @ApiPropertyOptional({ description: 'User email' }) @Optional() @IsEmail({ require_tld: false }) @Transform(toEmail) email?: string; + @ApiPropertyOptional({ description: 'User password' }) @Optional() @IsNotEmpty() @IsString() password?: string; - @PinCode({ optional: true, nullable: true, emptyToNull: true }) + @ApiPropertyOptional({ description: 'PIN code' }) + @PinCode({ optional: true, emptyToNull: true }) pinCode?: string | null; + @ApiPropertyOptional({ description: 'User name' }) @Optional() @IsString() @IsNotEmpty() name?: string; - @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, nullable: true }) + @ValidateEnum({ enum: UserAvatarColor, name: 'UserAvatarColor', optional: true, description: 'Avatar color' }) avatarColor?: UserAvatarColor | null; + @ApiPropertyOptional({ description: 'Storage label' }) @Optional({ nullable: true }) @IsString() @Transform(toSanitized) storageLabel?: string | null; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Require password change on next login' }) shouldChangePassword?: boolean; + @ApiPropertyOptional({ type: 'integer', format: 'int64', description: 'Storage quota in bytes' }) @Optional({ nullable: true }) @IsInt() @Min(0) - @ApiProperty({ type: 'integer', format: 'int64' }) quotaSizeInBytes?: number | null; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Grant admin privileges' }) isAdmin?: boolean; } export class UserAdminDeleteDto { - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Force delete even if user has assets' }) force?: boolean; } export class UserAdminResponseDto extends UserResponseDto { + @ApiProperty({ description: 'Storage label' }) storageLabel!: string | null; + @ApiProperty({ description: 'Require password change on next login' }) shouldChangePassword!: boolean; + @ApiProperty({ description: 'Is admin user' }) isAdmin!: boolean; + @ApiProperty({ description: 'Creation date' }) createdAt!: Date; + @ApiProperty({ description: 'Deletion date' }) deletedAt!: Date | null; + @ApiProperty({ description: 'Last update date' }) updatedAt!: Date; + @ApiProperty({ description: 'OAuth ID' }) oauthId!: string; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage quota in bytes' }) quotaSizeInBytes!: number | null; - @ApiProperty({ type: 'integer', format: 'int64' }) + @ApiProperty({ type: 'integer', format: 'int64', description: 'Storage usage in bytes' }) quotaUsageInBytes!: number | null; - @ValidateEnum({ enum: UserStatus, name: 'UserStatus' }) + @ValidateEnum({ enum: UserStatus, name: 'UserStatus', description: 'User status' }) status!: string; + @ApiProperty({ description: 'User license' }) license!: UserLicense | null; } diff --git a/server/src/dtos/workflow.dto.ts b/server/src/dtos/workflow.dto.ts index 2dbff3b5e4375..c4e5ac9c4c519 100644 --- a/server/src/dtos/workflow.dto.ts +++ b/server/src/dtos/workflow.dto.ts @@ -1,3 +1,4 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { IsNotEmpty, IsObject, IsString, IsUUID, ValidateNested } from 'class-validator'; import { WorkflowAction, WorkflowFilter } from 'src/database'; @@ -6,68 +7,85 @@ import type { ActionConfig, FilterConfig } from 'src/types/plugin-schema.types'; import { Optional, ValidateBoolean, ValidateEnum } from 'src/validation'; export class WorkflowFilterItemDto { + @ApiProperty({ description: 'Plugin filter ID' }) @IsUUID() pluginFilterId!: string; + @ApiPropertyOptional({ description: 'Filter configuration' }) @IsObject() @Optional() filterConfig?: FilterConfig; } export class WorkflowActionItemDto { + @ApiProperty({ description: 'Plugin action ID' }) @IsUUID() pluginActionId!: string; + @ApiPropertyOptional({ description: 'Action configuration' }) @IsObject() @Optional() actionConfig?: ActionConfig; } export class WorkflowCreateDto { - @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType' }) + @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType', description: 'Workflow trigger type' }) triggerType!: PluginTriggerType; + @ApiProperty({ description: 'Workflow name' }) @IsString() @IsNotEmpty() name!: string; + @ApiPropertyOptional({ description: 'Workflow description' }) @IsString() @Optional() description?: string; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Workflow enabled' }) enabled?: boolean; + @ApiProperty({ description: 'Workflow filters' }) @ValidateNested({ each: true }) @Type(() => WorkflowFilterItemDto) filters!: WorkflowFilterItemDto[]; + @ApiProperty({ description: 'Workflow actions' }) @ValidateNested({ each: true }) @Type(() => WorkflowActionItemDto) actions!: WorkflowActionItemDto[]; } export class WorkflowUpdateDto { - @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType', optional: true }) + @ValidateEnum({ + enum: PluginTriggerType, + name: 'PluginTriggerType', + optional: true, + description: 'Workflow trigger type', + }) triggerType?: PluginTriggerType; + @ApiPropertyOptional({ description: 'Workflow name' }) @IsString() @IsNotEmpty() @Optional() name?: string; + @ApiPropertyOptional({ description: 'Workflow description' }) @IsString() @Optional() description?: string; - @ValidateBoolean({ optional: true }) + @ValidateBoolean({ optional: true, description: 'Workflow enabled' }) enabled?: boolean; + @ApiPropertyOptional({ description: 'Workflow filters' }) @ValidateNested({ each: true }) @Type(() => WorkflowFilterItemDto) @Optional() filters?: WorkflowFilterItemDto[]; + @ApiPropertyOptional({ description: 'Workflow actions' }) @ValidateNested({ each: true }) @Type(() => WorkflowActionItemDto) @Optional() @@ -75,31 +93,49 @@ export class WorkflowUpdateDto { } export class WorkflowResponseDto { + @ApiProperty({ description: 'Workflow ID' }) id!: string; + @ApiProperty({ description: 'Owner user ID' }) ownerId!: string; - @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType' }) + @ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType', description: 'Workflow trigger type' }) triggerType!: PluginTriggerType; + @ApiProperty({ description: 'Workflow name' }) name!: string | null; + @ApiProperty({ description: 'Workflow description' }) description!: string; + @ApiProperty({ description: 'Creation date' }) createdAt!: string; + @ApiProperty({ description: 'Workflow enabled' }) enabled!: boolean; + @ApiProperty({ description: 'Workflow filters' }) filters!: WorkflowFilterResponseDto[]; + @ApiProperty({ description: 'Workflow actions' }) actions!: WorkflowActionResponseDto[]; } export class WorkflowFilterResponseDto { + @ApiProperty({ description: 'Filter ID' }) id!: string; + @ApiProperty({ description: 'Workflow ID' }) workflowId!: string; + @ApiProperty({ description: 'Plugin filter ID' }) pluginFilterId!: string; + @ApiProperty({ description: 'Filter configuration' }) filterConfig!: FilterConfig | null; + @ApiProperty({ description: 'Filter order', type: 'number' }) order!: number; } export class WorkflowActionResponseDto { + @ApiProperty({ description: 'Action ID' }) id!: string; + @ApiProperty({ description: 'Workflow ID' }) workflowId!: string; + @ApiProperty({ description: 'Plugin action ID' }) pluginActionId!: string; + @ApiProperty({ description: 'Action configuration' }) actionConfig!: ActionConfig | null; + @ApiProperty({ description: 'Action order', type: 'number' }) order!: number; } diff --git a/server/src/maintenance/maintenance-worker.service.ts b/server/src/maintenance/maintenance-worker.service.ts index 8ad92799cdf1e..6415693733f90 100644 --- a/server/src/maintenance/maintenance-worker.service.ts +++ b/server/src/maintenance/maintenance-worker.service.ts @@ -79,7 +79,7 @@ export class MaintenanceWorkerService { this.#secret = state.secret; this.#status = { active: true, - action: state.action.action, + action: state.action?.action ?? MaintenanceAction.Start, }; StorageCore.setMediaLocation(this.detectMediaLocation()); @@ -88,7 +88,10 @@ export class MaintenanceWorkerService { this.maintenanceWebsocketRepository.setStatusUpdateFn((status) => (this.#status = status)); await this.logSecret(); - void this.runAction(state.action); + + if (state.action) { + void this.runAction(state.action); + } } /** diff --git a/server/src/types.ts b/server/src/types.ts index f851ebd994fb7..3e9ea25957020 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -490,7 +490,7 @@ export interface MemoryData { export type VersionCheckMetadata = { checkedAt: string; releaseVersion: string }; export type SystemFlags = { mountChecks: Record }; export type MaintenanceModeState = - | { isMaintenanceMode: true; secret: string; action: SetMaintenanceModeDto } + | { isMaintenanceMode: true; secret: string; action?: SetMaintenanceModeDto } | { isMaintenanceMode: false }; export type MemoriesState = { /** memories have already been created through this date */ diff --git a/server/src/validation.ts b/server/src/validation.ts index 0a53e09ca5386..724c01ffe9d61 100644 --- a/server/src/validation.ts +++ b/server/src/validation.ts @@ -33,6 +33,7 @@ import { import { CronJob } from 'cron'; import { DateTime } from 'luxon'; import sanitize from 'sanitize-filename'; +import { Property, PropertyOptions } from 'src/decorators'; import { isIP, isIPRange } from 'validator'; @Injectable() @@ -66,7 +67,7 @@ export class FileNotEmptyValidator extends FileValidator { } type UUIDOptions = { optional?: boolean; each?: boolean; nullable?: boolean }; -export const ValidateUUID = (options?: UUIDOptions & ApiPropertyOptions) => { +export const ValidateUUID = (options?: UUIDOptions & PropertyOptions) => { const { optional, each, nullable, ...apiPropertyOptions } = { optional: false, each: false, @@ -75,7 +76,7 @@ export const ValidateUUID = (options?: UUIDOptions & ApiPropertyOptions) => { }; return applyDecorators( IsUUID('4', { each }), - ApiProperty({ format: 'uuid', ...apiPropertyOptions }), + Property({ format: 'uuid', ...apiPropertyOptions }), optional ? Optional({ nullable }) : IsNotEmpty(), each ? IsArray() : IsString(), ); @@ -277,10 +278,10 @@ export const ValidateString = (options?: StringOptions & ApiPropertyOptions) => }; type BooleanOptions = { optional?: boolean; nullable?: boolean }; -export const ValidateBoolean = (options?: BooleanOptions & ApiPropertyOptions) => { +export const ValidateBoolean = (options?: BooleanOptions & PropertyOptions) => { const { optional, nullable, ...apiPropertyOptions } = options || {}; const decorators = [ - ApiProperty(apiPropertyOptions), + Property(apiPropertyOptions), IsBoolean(), Transform(({ value }) => { if (value == 'true') { diff --git a/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte b/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte index d5841b47ed701..bdcacdf0ce8f4 100644 --- a/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte +++ b/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte @@ -302,6 +302,7 @@ case AssetAction.ARCHIVE: case AssetAction.DELETE: case AssetAction.TRASH: { + const nextAsset = assetCursor.nextAsset ?? assetCursor.previousAsset; assets.splice( assets.findIndex((currentAsset) => currentAsset.id === action.asset.id), 1, @@ -309,10 +310,8 @@ if (assets.length === 0) { return await goto(Route.photos()); } - if (assetCursor.nextAsset) { - await navigateToAsset(assetCursor.nextAsset); - } else if (assetCursor.previousAsset) { - await navigateToAsset(assetCursor.previousAsset); + if (nextAsset) { + await navigateToAsset(nextAsset); } break; } diff --git a/web/src/lib/modals/AlbumOptionsModal.svelte b/web/src/lib/modals/AlbumOptionsModal.svelte index 201c22af651bd..4553f022df7df 100644 --- a/web/src/lib/modals/AlbumOptionsModal.svelte +++ b/web/src/lib/modals/AlbumOptionsModal.svelte @@ -9,7 +9,6 @@ handleUpdateAlbum, handleUpdateUserAlbumRole, } from '$lib/services/album.service'; - import { user } from '$lib/stores/user.store'; import { AlbumUserRole, AssetOrder, @@ -108,9 +107,9 @@
- +
- {$user.name} + {album.owner.name}