From bd87d2bd08f7e72820295ac1a360b6912a045d4c Mon Sep 17 00:00:00 2001 From: Chaoscontrol <6642238+Chaoscontrol@users.noreply.github.com> Date: Thu, 2 Oct 2025 17:50:31 +0100 Subject: [PATCH] Add ContributorCountResponseDto and expose contributorCounts on AlbumResponseDto in OpenAPI spec. Regenerate TypeScript SDK and mobile OpenAPI clients to include new types. No breaking changes; fields are additive. --- mobile/openapi/README.md | 1 + mobile/openapi/lib/api.dart | 1 + mobile/openapi/lib/api_client.dart | 2 + .../openapi/lib/model/album_response_dto.dart | 9 +- .../model/contributor_count_response_dto.dart | 107 ++++++++++++++++++ open-api/immich-openapi-specs.json | 21 ++++ open-api/typescript-sdk/src/fetch-client.ts | 5 + 7 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 mobile/openapi/lib/model/contributor_count_response_dto.dart diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 47277a15bb..8d73cdcb27 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -359,6 +359,7 @@ Class | Method | HTTP request | Description - [CheckExistingAssetsDto](doc//CheckExistingAssetsDto.md) - [CheckExistingAssetsResponseDto](doc//CheckExistingAssetsResponseDto.md) - [Colorspace](doc//Colorspace.md) + - [ContributorCountResponseDto](doc//ContributorCountResponseDto.md) - [CreateAlbumDto](doc//CreateAlbumDto.md) - [CreateLibraryDto](doc//CreateLibraryDto.md) - [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index df2c2226b1..a3117ede86 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -130,6 +130,7 @@ part 'model/change_password_dto.dart'; part 'model/check_existing_assets_dto.dart'; part 'model/check_existing_assets_response_dto.dart'; part 'model/colorspace.dart'; +part 'model/contributor_count_response_dto.dart'; part 'model/create_album_dto.dart'; part 'model/create_library_dto.dart'; part 'model/create_profile_image_response_dto.dart'; diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 06d27593c9..33056cf14e 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -314,6 +314,8 @@ class ApiClient { return CheckExistingAssetsResponseDto.fromJson(value); case 'Colorspace': return ColorspaceTypeTransformer().decode(value); + case 'ContributorCountResponseDto': + return ContributorCountResponseDto.fromJson(value); case 'CreateAlbumDto': return CreateAlbumDto.fromJson(value); case 'CreateLibraryDto': diff --git a/mobile/openapi/lib/model/album_response_dto.dart b/mobile/openapi/lib/model/album_response_dto.dart index 547a6a70fd..2f53706e7a 100644 --- a/mobile/openapi/lib/model/album_response_dto.dart +++ b/mobile/openapi/lib/model/album_response_dto.dart @@ -18,6 +18,7 @@ class AlbumResponseDto { this.albumUsers = const [], required this.assetCount, this.assets = const [], + this.contributorCounts = const [], required this.createdAt, required this.description, this.endDate, @@ -43,6 +44,8 @@ class AlbumResponseDto { List assets; + List contributorCounts; + DateTime createdAt; String description; @@ -100,6 +103,7 @@ class AlbumResponseDto { _deepEquality.equals(other.albumUsers, albumUsers) && other.assetCount == assetCount && _deepEquality.equals(other.assets, assets) && + _deepEquality.equals(other.contributorCounts, contributorCounts) && other.createdAt == createdAt && other.description == description && other.endDate == endDate && @@ -122,6 +126,7 @@ class AlbumResponseDto { (albumUsers.hashCode) + (assetCount.hashCode) + (assets.hashCode) + + (contributorCounts.hashCode) + (createdAt.hashCode) + (description.hashCode) + (endDate == null ? 0 : endDate!.hashCode) + @@ -137,7 +142,7 @@ class AlbumResponseDto { (updatedAt.hashCode); @override - String toString() => 'AlbumResponseDto[albumName=$albumName, albumThumbnailAssetId=$albumThumbnailAssetId, albumUsers=$albumUsers, assetCount=$assetCount, assets=$assets, createdAt=$createdAt, description=$description, endDate=$endDate, hasSharedLink=$hasSharedLink, id=$id, isActivityEnabled=$isActivityEnabled, lastModifiedAssetTimestamp=$lastModifiedAssetTimestamp, order=$order, owner=$owner, ownerId=$ownerId, shared=$shared, startDate=$startDate, updatedAt=$updatedAt]'; + String toString() => 'AlbumResponseDto[albumName=$albumName, albumThumbnailAssetId=$albumThumbnailAssetId, albumUsers=$albumUsers, assetCount=$assetCount, assets=$assets, contributorCounts=$contributorCounts, createdAt=$createdAt, description=$description, endDate=$endDate, hasSharedLink=$hasSharedLink, id=$id, isActivityEnabled=$isActivityEnabled, lastModifiedAssetTimestamp=$lastModifiedAssetTimestamp, order=$order, owner=$owner, ownerId=$ownerId, shared=$shared, startDate=$startDate, updatedAt=$updatedAt]'; Map toJson() { final json = {}; @@ -150,6 +155,7 @@ class AlbumResponseDto { json[r'albumUsers'] = this.albumUsers; json[r'assetCount'] = this.assetCount; json[r'assets'] = this.assets; + json[r'contributorCounts'] = this.contributorCounts; json[r'createdAt'] = this.createdAt.toUtc().toIso8601String(); json[r'description'] = this.description; if (this.endDate != null) { @@ -196,6 +202,7 @@ class AlbumResponseDto { albumUsers: AlbumUserResponseDto.listFromJson(json[r'albumUsers']), assetCount: mapValueOfType(json, r'assetCount')!, assets: AssetResponseDto.listFromJson(json[r'assets']), + contributorCounts: ContributorCountResponseDto.listFromJson(json[r'contributorCounts']), createdAt: mapDateTime(json, r'createdAt', r'')!, description: mapValueOfType(json, r'description')!, endDate: mapDateTime(json, r'endDate', r''), diff --git a/mobile/openapi/lib/model/contributor_count_response_dto.dart b/mobile/openapi/lib/model/contributor_count_response_dto.dart new file mode 100644 index 0000000000..e0e16ee427 --- /dev/null +++ b/mobile/openapi/lib/model/contributor_count_response_dto.dart @@ -0,0 +1,107 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ContributorCountResponseDto { + /// Returns a new [ContributorCountResponseDto] instance. + ContributorCountResponseDto({ + required this.assetCount, + required this.userId, + }); + + int assetCount; + + String userId; + + @override + bool operator ==(Object other) => identical(this, other) || other is ContributorCountResponseDto && + other.assetCount == assetCount && + other.userId == userId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (assetCount.hashCode) + + (userId.hashCode); + + @override + String toString() => 'ContributorCountResponseDto[assetCount=$assetCount, userId=$userId]'; + + Map toJson() { + final json = {}; + json[r'assetCount'] = this.assetCount; + json[r'userId'] = this.userId; + return json; + } + + /// Returns a new [ContributorCountResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ContributorCountResponseDto? fromJson(dynamic value) { + upgradeDto(value, "ContributorCountResponseDto"); + if (value is Map) { + final json = value.cast(); + + return ContributorCountResponseDto( + assetCount: mapValueOfType(json, r'assetCount')!, + userId: mapValueOfType(json, r'userId')!, + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = ContributorCountResponseDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = ContributorCountResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ContributorCountResponseDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = ContributorCountResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'assetCount', + 'userId', + }; +} + diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 996eeef87e..985a189397 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -10096,6 +10096,12 @@ }, "type": "array" }, + "contributorCounts": { + "items": { + "$ref": "#/components/schemas/ContributorCountResponseDto" + }, + "type": "array" + }, "createdAt": { "format": "date-time", "type": "string" @@ -11471,6 +11477,21 @@ ], "type": "string" }, + "ContributorCountResponseDto": { + "properties": { + "assetCount": { + "type": "integer" + }, + "userId": { + "type": "string" + } + }, + "required": [ + "assetCount", + "userId" + ], + "type": "object" + }, "CreateAlbumDto": { "properties": { "albumName": { diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index ab885eb9c5..3488bd4120 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -356,12 +356,17 @@ export type AssetResponseDto = { updatedAt: string; visibility: AssetVisibility; }; +export type ContributorCountResponseDto = { + assetCount: number; + userId: string; +}; export type AlbumResponseDto = { albumName: string; albumThumbnailAssetId: string | null; albumUsers: AlbumUserResponseDto[]; assetCount: number; assets: AssetResponseDto[]; + contributorCounts?: ContributorCountResponseDto[]; createdAt: string; description: string; endDate?: string;