diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 4b62ee7877a1d..6b1f67c761e36 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -210,6 +210,7 @@ Class | Method | HTTP request | Description *QueuesApi* | [**getQueue**](doc//QueuesApi.md#getqueue) | **GET** /queues/{name} | Retrieve a queue *QueuesApi* | [**getQueueJobs**](doc//QueuesApi.md#getqueuejobs) | **GET** /queues/{name}/jobs | Retrieve queue jobs *QueuesApi* | [**getQueues**](doc//QueuesApi.md#getqueues) | **GET** /queues | List all queues +*QueuesApi* | [**queueJob**](doc//QueuesApi.md#queuejob) | **POST** /queues/job | Create a manual job *QueuesApi* | [**updateQueue**](doc//QueuesApi.md#updatequeue) | **PUT** /queues/{name} | Update a queue *SearchApi* | [**getAssetsByCity**](doc//SearchApi.md#getassetsbycity) | **GET** /search/cities | Retrieve assets by city *SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore | Retrieve explore data @@ -388,6 +389,7 @@ Class | Method | HTTP request | Description - [AudioCodec](doc//AudioCodec.md) - [AuthStatusResponseDto](doc//AuthStatusResponseDto.md) - [AvatarUpdate](doc//AvatarUpdate.md) + - [BaseJobData](doc//BaseJobData.md) - [BulkIdErrorReason](doc//BulkIdErrorReason.md) - [BulkIdResponseDto](doc//BulkIdResponseDto.md) - [BulkIdsDto](doc//BulkIdsDto.md) @@ -404,6 +406,7 @@ Class | Method | HTTP request | Description - [CreateLibraryDto](doc//CreateLibraryDto.md) - [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md) - [CropParameters](doc//CropParameters.md) + - [DatabaseBackup](doc//DatabaseBackup.md) - [DatabaseBackupConfig](doc//DatabaseBackupConfig.md) - [DownloadArchiveInfo](doc//DownloadArchiveInfo.md) - [DownloadInfoDto](doc//DownloadInfoDto.md) @@ -421,8 +424,14 @@ Class | Method | HTTP request | Description - [FoldersUpdate](doc//FoldersUpdate.md) - [ImageFormat](doc//ImageFormat.md) - [JobCreateDto](doc//JobCreateDto.md) + - [JobDatabaseBackup](doc//JobDatabaseBackup.md) + - [JobMemoryCleanup](doc//JobMemoryCleanup.md) + - [JobMemoryGenerate](doc//JobMemoryGenerate.md) - [JobName](doc//JobName.md) + - [JobPersonCleanup](doc//JobPersonCleanup.md) - [JobSettingsDto](doc//JobSettingsDto.md) + - [JobTagCleanup](doc//JobTagCleanup.md) + - [JobUserDeleteCheck](doc//JobUserDeleteCheck.md) - [LibraryResponseDto](doc//LibraryResponseDto.md) - [LibraryStatsResponseDto](doc//LibraryStatsResponseDto.md) - [LicenseKeyDto](doc//LicenseKeyDto.md) @@ -440,7 +449,9 @@ Class | Method | HTTP request | Description - [MapReverseGeocodeResponseDto](doc//MapReverseGeocodeResponseDto.md) - [MemoriesResponse](doc//MemoriesResponse.md) - [MemoriesUpdate](doc//MemoriesUpdate.md) + - [MemoryCleanup](doc//MemoryCleanup.md) - [MemoryCreateDto](doc//MemoryCreateDto.md) + - [MemoryGenerate](doc//MemoryGenerate.md) - [MemoryResponseDto](doc//MemoryResponseDto.md) - [MemorySearchOrder](doc//MemorySearchOrder.md) - [MemoryStatisticsResponseDto](doc//MemoryStatisticsResponseDto.md) @@ -475,6 +486,7 @@ Class | Method | HTTP request | Description - [PeopleUpdateDto](doc//PeopleUpdateDto.md) - [PeopleUpdateItem](doc//PeopleUpdateItem.md) - [Permission](doc//Permission.md) + - [PersonCleanup](doc//PersonCleanup.md) - [PersonCreateDto](doc//PersonCreateDto.md) - [PersonResponseDto](doc//PersonResponseDto.md) - [PersonStatisticsResponseDto](doc//PersonStatisticsResponseDto.md) @@ -495,6 +507,8 @@ Class | Method | HTTP request | Description - [QueueCommand](doc//QueueCommand.md) - [QueueCommandDto](doc//QueueCommandDto.md) - [QueueDeleteDto](doc//QueueDeleteDto.md) + - [QueueJobCreateDto](doc//QueueJobCreateDto.md) + - [QueueJobCreateDtoJob](doc//QueueJobCreateDtoJob.md) - [QueueJobResponseDto](doc//QueueJobResponseDto.md) - [QueueJobStatus](doc//QueueJobStatus.md) - [QueueName](doc//QueueName.md) @@ -617,6 +631,7 @@ Class | Method | HTTP request | Description - [SystemConfigUserDto](doc//SystemConfigUserDto.md) - [TagBulkAssetsDto](doc//TagBulkAssetsDto.md) - [TagBulkAssetsResponseDto](doc//TagBulkAssetsResponseDto.md) + - [TagCleanup](doc//TagCleanup.md) - [TagCreateDto](doc//TagCreateDto.md) - [TagResponseDto](doc//TagResponseDto.md) - [TagUpdateDto](doc//TagUpdateDto.md) @@ -642,6 +657,7 @@ Class | Method | HTTP request | Description - [UserAdminResponseDto](doc//UserAdminResponseDto.md) - [UserAdminUpdateDto](doc//UserAdminUpdateDto.md) - [UserAvatarColor](doc//UserAvatarColor.md) + - [UserDeleteCheck](doc//UserDeleteCheck.md) - [UserLicense](doc//UserLicense.md) - [UserMetadataKey](doc//UserMetadataKey.md) - [UserPreferencesResponseDto](doc//UserPreferencesResponseDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index 50120d96a6a8f..caf2071608430 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -134,6 +134,7 @@ part 'model/asset_visibility.dart'; part 'model/audio_codec.dart'; part 'model/auth_status_response_dto.dart'; part 'model/avatar_update.dart'; +part 'model/base_job_data.dart'; part 'model/bulk_id_error_reason.dart'; part 'model/bulk_id_response_dto.dart'; part 'model/bulk_ids_dto.dart'; @@ -150,6 +151,7 @@ part 'model/create_album_dto.dart'; part 'model/create_library_dto.dart'; part 'model/create_profile_image_response_dto.dart'; part 'model/crop_parameters.dart'; +part 'model/database_backup.dart'; part 'model/database_backup_config.dart'; part 'model/download_archive_info.dart'; part 'model/download_info_dto.dart'; @@ -167,8 +169,14 @@ part 'model/folders_response.dart'; part 'model/folders_update.dart'; part 'model/image_format.dart'; part 'model/job_create_dto.dart'; +part 'model/job_database_backup.dart'; +part 'model/job_memory_cleanup.dart'; +part 'model/job_memory_generate.dart'; part 'model/job_name.dart'; +part 'model/job_person_cleanup.dart'; part 'model/job_settings_dto.dart'; +part 'model/job_tag_cleanup.dart'; +part 'model/job_user_delete_check.dart'; part 'model/library_response_dto.dart'; part 'model/library_stats_response_dto.dart'; part 'model/license_key_dto.dart'; @@ -186,7 +194,9 @@ part 'model/map_marker_response_dto.dart'; part 'model/map_reverse_geocode_response_dto.dart'; part 'model/memories_response.dart'; part 'model/memories_update.dart'; +part 'model/memory_cleanup.dart'; part 'model/memory_create_dto.dart'; +part 'model/memory_generate.dart'; part 'model/memory_response_dto.dart'; part 'model/memory_search_order.dart'; part 'model/memory_statistics_response_dto.dart'; @@ -221,6 +231,7 @@ part 'model/people_update.dart'; part 'model/people_update_dto.dart'; part 'model/people_update_item.dart'; part 'model/permission.dart'; +part 'model/person_cleanup.dart'; part 'model/person_create_dto.dart'; part 'model/person_response_dto.dart'; part 'model/person_statistics_response_dto.dart'; @@ -241,6 +252,8 @@ part 'model/purchase_update.dart'; part 'model/queue_command.dart'; part 'model/queue_command_dto.dart'; part 'model/queue_delete_dto.dart'; +part 'model/queue_job_create_dto.dart'; +part 'model/queue_job_create_dto_job.dart'; part 'model/queue_job_response_dto.dart'; part 'model/queue_job_status.dart'; part 'model/queue_name.dart'; @@ -363,6 +376,7 @@ part 'model/system_config_trash_dto.dart'; part 'model/system_config_user_dto.dart'; part 'model/tag_bulk_assets_dto.dart'; part 'model/tag_bulk_assets_response_dto.dart'; +part 'model/tag_cleanup.dart'; part 'model/tag_create_dto.dart'; part 'model/tag_response_dto.dart'; part 'model/tag_update_dto.dart'; @@ -388,6 +402,7 @@ part 'model/user_admin_delete_dto.dart'; part 'model/user_admin_response_dto.dart'; part 'model/user_admin_update_dto.dart'; part 'model/user_avatar_color.dart'; +part 'model/user_delete_check.dart'; part 'model/user_license.dart'; part 'model/user_metadata_key.dart'; part 'model/user_preferences_response_dto.dart'; diff --git a/mobile/openapi/lib/api/queues_api.dart b/mobile/openapi/lib/api/queues_api.dart index 50575ed706322..d72035e76f775 100644 --- a/mobile/openapi/lib/api/queues_api.dart +++ b/mobile/openapi/lib/api/queues_api.dart @@ -245,6 +245,54 @@ class QueuesApi { return null; } + /// Create a manual job + /// + /// Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup. + /// + /// Note: This method returns the HTTP [Response]. + /// + /// Parameters: + /// + /// * [QueueJobCreateDto] queueJobCreateDto (required): + Future queueJobWithHttpInfo(QueueJobCreateDto queueJobCreateDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/queues/job'; + + // ignore: prefer_final_locals + Object? postBody = queueJobCreateDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Create a manual job + /// + /// Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup. + /// + /// Parameters: + /// + /// * [QueueJobCreateDto] queueJobCreateDto (required): + Future queueJob(QueueJobCreateDto queueJobCreateDto,) async { + final response = await queueJobWithHttpInfo(queueJobCreateDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + /// Update a queue /// /// Change the paused status of a specific queue. diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 9d13b3e034197..ca7f232b22936 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -316,6 +316,8 @@ class ApiClient { return AuthStatusResponseDto.fromJson(value); case 'AvatarUpdate': return AvatarUpdate.fromJson(value); + case 'BaseJobData': + return BaseJobData.fromJson(value); case 'BulkIdErrorReason': return BulkIdErrorReasonTypeTransformer().decode(value); case 'BulkIdResponseDto': @@ -348,6 +350,8 @@ class ApiClient { return CreateProfileImageResponseDto.fromJson(value); case 'CropParameters': return CropParameters.fromJson(value); + case 'DatabaseBackup': + return DatabaseBackupTypeTransformer().decode(value); case 'DatabaseBackupConfig': return DatabaseBackupConfig.fromJson(value); case 'DownloadArchiveInfo': @@ -382,10 +386,22 @@ class ApiClient { return ImageFormatTypeTransformer().decode(value); case 'JobCreateDto': return JobCreateDto.fromJson(value); + case 'JobDatabaseBackup': + return JobDatabaseBackup.fromJson(value); + case 'JobMemoryCleanup': + return JobMemoryCleanup.fromJson(value); + case 'JobMemoryGenerate': + return JobMemoryGenerate.fromJson(value); case 'JobName': return JobNameTypeTransformer().decode(value); + case 'JobPersonCleanup': + return JobPersonCleanup.fromJson(value); case 'JobSettingsDto': return JobSettingsDto.fromJson(value); + case 'JobTagCleanup': + return JobTagCleanup.fromJson(value); + case 'JobUserDeleteCheck': + return JobUserDeleteCheck.fromJson(value); case 'LibraryResponseDto': return LibraryResponseDto.fromJson(value); case 'LibraryStatsResponseDto': @@ -420,8 +436,12 @@ class ApiClient { return MemoriesResponse.fromJson(value); case 'MemoriesUpdate': return MemoriesUpdate.fromJson(value); + case 'MemoryCleanup': + return MemoryCleanupTypeTransformer().decode(value); case 'MemoryCreateDto': return MemoryCreateDto.fromJson(value); + case 'MemoryGenerate': + return MemoryGenerateTypeTransformer().decode(value); case 'MemoryResponseDto': return MemoryResponseDto.fromJson(value); case 'MemorySearchOrder': @@ -490,6 +510,8 @@ class ApiClient { return PeopleUpdateItem.fromJson(value); case 'Permission': return PermissionTypeTransformer().decode(value); + case 'PersonCleanup': + return PersonCleanupTypeTransformer().decode(value); case 'PersonCreateDto': return PersonCreateDto.fromJson(value); case 'PersonResponseDto': @@ -530,6 +552,10 @@ class ApiClient { return QueueCommandDto.fromJson(value); case 'QueueDeleteDto': return QueueDeleteDto.fromJson(value); + case 'QueueJobCreateDto': + return QueueJobCreateDto.fromJson(value); + case 'QueueJobCreateDtoJob': + return QueueJobCreateDtoJob.fromJson(value); case 'QueueJobResponseDto': return QueueJobResponseDto.fromJson(value); case 'QueueJobStatus': @@ -774,6 +800,8 @@ class ApiClient { return TagBulkAssetsDto.fromJson(value); case 'TagBulkAssetsResponseDto': return TagBulkAssetsResponseDto.fromJson(value); + case 'TagCleanup': + return TagCleanupTypeTransformer().decode(value); case 'TagCreateDto': return TagCreateDto.fromJson(value); case 'TagResponseDto': @@ -824,6 +852,8 @@ class ApiClient { return UserAdminUpdateDto.fromJson(value); case 'UserAvatarColor': return UserAvatarColorTypeTransformer().decode(value); + case 'UserDeleteCheck': + return UserDeleteCheckTypeTransformer().decode(value); case 'UserLicense': return UserLicense.fromJson(value); case 'UserMetadataKey': diff --git a/mobile/openapi/lib/api_helper.dart b/mobile/openapi/lib/api_helper.dart index 18fa3d5e31528..20ecc3f0f9c3f 100644 --- a/mobile/openapi/lib/api_helper.dart +++ b/mobile/openapi/lib/api_helper.dart @@ -91,6 +91,9 @@ String parameterToString(dynamic value) { if (value is Colorspace) { return ColorspaceTypeTransformer().encode(value).toString(); } + if (value is DatabaseBackup) { + return DatabaseBackupTypeTransformer().encode(value).toString(); + } if (value is ImageFormat) { return ImageFormatTypeTransformer().encode(value).toString(); } @@ -106,6 +109,12 @@ String parameterToString(dynamic value) { if (value is ManualJobName) { return ManualJobNameTypeTransformer().encode(value).toString(); } + if (value is MemoryCleanup) { + return MemoryCleanupTypeTransformer().encode(value).toString(); + } + if (value is MemoryGenerate) { + return MemoryGenerateTypeTransformer().encode(value).toString(); + } if (value is MemorySearchOrder) { return MemorySearchOrderTypeTransformer().encode(value).toString(); } @@ -130,6 +139,9 @@ String parameterToString(dynamic value) { if (value is Permission) { return PermissionTypeTransformer().encode(value).toString(); } + if (value is PersonCleanup) { + return PersonCleanupTypeTransformer().encode(value).toString(); + } if (value is PluginContextType) { return PluginContextTypeTypeTransformer().encode(value).toString(); } @@ -166,6 +178,9 @@ String parameterToString(dynamic value) { if (value is SyncRequestType) { return SyncRequestTypeTypeTransformer().encode(value).toString(); } + if (value is TagCleanup) { + return TagCleanupTypeTransformer().encode(value).toString(); + } if (value is ToneMapping) { return ToneMappingTypeTransformer().encode(value).toString(); } @@ -178,6 +193,9 @@ String parameterToString(dynamic value) { if (value is UserAvatarColor) { return UserAvatarColorTypeTransformer().encode(value).toString(); } + if (value is UserDeleteCheck) { + return UserDeleteCheckTypeTransformer().encode(value).toString(); + } if (value is UserMetadataKey) { return UserMetadataKeyTypeTransformer().encode(value).toString(); } diff --git a/mobile/openapi/lib/model/base_job_data.dart b/mobile/openapi/lib/model/base_job_data.dart new file mode 100644 index 0000000000000..f8dd50c3b18b6 --- /dev/null +++ b/mobile/openapi/lib/model/base_job_data.dart @@ -0,0 +1,108 @@ +// +// 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 BaseJobData { + /// Returns a new [BaseJobData] instance. + BaseJobData({ + this.force, + }); + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? force; + + @override + bool operator ==(Object other) => identical(this, other) || other is BaseJobData && + other.force == force; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (force == null ? 0 : force!.hashCode); + + @override + String toString() => 'BaseJobData[force=$force]'; + + Map toJson() { + final json = {}; + if (this.force != null) { + json[r'force'] = this.force; + } else { + // json[r'force'] = null; + } + return json; + } + + /// Returns a new [BaseJobData] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static BaseJobData? fromJson(dynamic value) { + upgradeDto(value, "BaseJobData"); + if (value is Map) { + final json = value.cast(); + + return BaseJobData( + force: mapValueOfType(json, r'force'), + ); + } + 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 = BaseJobData.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 = BaseJobData.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of BaseJobData-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] = BaseJobData.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/database_backup.dart b/mobile/openapi/lib/model/database_backup.dart new file mode 100644 index 0000000000000..3a08078574f7a --- /dev/null +++ b/mobile/openapi/lib/model/database_backup.dart @@ -0,0 +1,82 @@ +// +// 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 DatabaseBackup { + /// Instantiate a new enum with the provided [value]. + const DatabaseBackup._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const databaseBackup = DatabaseBackup._(r'DatabaseBackup'); + + /// List of all possible values in this [enum][DatabaseBackup]. + static const values = [ + databaseBackup, + ]; + + static DatabaseBackup? fromJson(dynamic value) => DatabaseBackupTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = DatabaseBackup.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [DatabaseBackup] to String, +/// and [decode] dynamic data back to [DatabaseBackup]. +class DatabaseBackupTypeTransformer { + factory DatabaseBackupTypeTransformer() => _instance ??= const DatabaseBackupTypeTransformer._(); + + const DatabaseBackupTypeTransformer._(); + + String encode(DatabaseBackup data) => data.value; + + /// Decodes a [dynamic value][data] to a DatabaseBackup. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + DatabaseBackup? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'DatabaseBackup': return DatabaseBackup.databaseBackup; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [DatabaseBackupTypeTransformer] instance. + static DatabaseBackupTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/job_database_backup.dart b/mobile/openapi/lib/model/job_database_backup.dart new file mode 100644 index 0000000000000..c1c8a92b5cfd0 --- /dev/null +++ b/mobile/openapi/lib/model/job_database_backup.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 JobDatabaseBackup { + /// Returns a new [JobDatabaseBackup] instance. + JobDatabaseBackup({ + required this.data, + required this.name, + }); + + BaseJobData data; + + DatabaseBackup name; + + @override + bool operator ==(Object other) => identical(this, other) || other is JobDatabaseBackup && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'JobDatabaseBackup[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [JobDatabaseBackup] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static JobDatabaseBackup? fromJson(dynamic value) { + upgradeDto(value, "JobDatabaseBackup"); + if (value is Map) { + final json = value.cast(); + + return JobDatabaseBackup( + data: BaseJobData.fromJson(json[r'data'])!, + name: DatabaseBackup.fromJson(json[r'name'])!, + ); + } + 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 = JobDatabaseBackup.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 = JobDatabaseBackup.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of JobDatabaseBackup-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] = JobDatabaseBackup.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/job_memory_cleanup.dart b/mobile/openapi/lib/model/job_memory_cleanup.dart new file mode 100644 index 0000000000000..af36a3e6db721 --- /dev/null +++ b/mobile/openapi/lib/model/job_memory_cleanup.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 JobMemoryCleanup { + /// Returns a new [JobMemoryCleanup] instance. + JobMemoryCleanup({ + required this.data, + required this.name, + }); + + BaseJobData data; + + MemoryCleanup name; + + @override + bool operator ==(Object other) => identical(this, other) || other is JobMemoryCleanup && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'JobMemoryCleanup[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [JobMemoryCleanup] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static JobMemoryCleanup? fromJson(dynamic value) { + upgradeDto(value, "JobMemoryCleanup"); + if (value is Map) { + final json = value.cast(); + + return JobMemoryCleanup( + data: BaseJobData.fromJson(json[r'data'])!, + name: MemoryCleanup.fromJson(json[r'name'])!, + ); + } + 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 = JobMemoryCleanup.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 = JobMemoryCleanup.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of JobMemoryCleanup-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] = JobMemoryCleanup.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/job_memory_generate.dart b/mobile/openapi/lib/model/job_memory_generate.dart new file mode 100644 index 0000000000000..a78cf274e58d8 --- /dev/null +++ b/mobile/openapi/lib/model/job_memory_generate.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 JobMemoryGenerate { + /// Returns a new [JobMemoryGenerate] instance. + JobMemoryGenerate({ + required this.data, + required this.name, + }); + + BaseJobData data; + + MemoryGenerate name; + + @override + bool operator ==(Object other) => identical(this, other) || other is JobMemoryGenerate && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'JobMemoryGenerate[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [JobMemoryGenerate] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static JobMemoryGenerate? fromJson(dynamic value) { + upgradeDto(value, "JobMemoryGenerate"); + if (value is Map) { + final json = value.cast(); + + return JobMemoryGenerate( + data: BaseJobData.fromJson(json[r'data'])!, + name: MemoryGenerate.fromJson(json[r'name'])!, + ); + } + 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 = JobMemoryGenerate.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 = JobMemoryGenerate.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of JobMemoryGenerate-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] = JobMemoryGenerate.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/job_person_cleanup.dart b/mobile/openapi/lib/model/job_person_cleanup.dart new file mode 100644 index 0000000000000..6bd9a8f644992 --- /dev/null +++ b/mobile/openapi/lib/model/job_person_cleanup.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 JobPersonCleanup { + /// Returns a new [JobPersonCleanup] instance. + JobPersonCleanup({ + required this.data, + required this.name, + }); + + BaseJobData data; + + PersonCleanup name; + + @override + bool operator ==(Object other) => identical(this, other) || other is JobPersonCleanup && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'JobPersonCleanup[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [JobPersonCleanup] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static JobPersonCleanup? fromJson(dynamic value) { + upgradeDto(value, "JobPersonCleanup"); + if (value is Map) { + final json = value.cast(); + + return JobPersonCleanup( + data: BaseJobData.fromJson(json[r'data'])!, + name: PersonCleanup.fromJson(json[r'name'])!, + ); + } + 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 = JobPersonCleanup.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 = JobPersonCleanup.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of JobPersonCleanup-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] = JobPersonCleanup.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/job_tag_cleanup.dart b/mobile/openapi/lib/model/job_tag_cleanup.dart new file mode 100644 index 0000000000000..455f3f7540656 --- /dev/null +++ b/mobile/openapi/lib/model/job_tag_cleanup.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 JobTagCleanup { + /// Returns a new [JobTagCleanup] instance. + JobTagCleanup({ + required this.data, + required this.name, + }); + + BaseJobData data; + + TagCleanup name; + + @override + bool operator ==(Object other) => identical(this, other) || other is JobTagCleanup && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'JobTagCleanup[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [JobTagCleanup] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static JobTagCleanup? fromJson(dynamic value) { + upgradeDto(value, "JobTagCleanup"); + if (value is Map) { + final json = value.cast(); + + return JobTagCleanup( + data: BaseJobData.fromJson(json[r'data'])!, + name: TagCleanup.fromJson(json[r'name'])!, + ); + } + 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 = JobTagCleanup.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 = JobTagCleanup.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of JobTagCleanup-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] = JobTagCleanup.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/job_user_delete_check.dart b/mobile/openapi/lib/model/job_user_delete_check.dart new file mode 100644 index 0000000000000..8c7b501a0857f --- /dev/null +++ b/mobile/openapi/lib/model/job_user_delete_check.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 JobUserDeleteCheck { + /// Returns a new [JobUserDeleteCheck] instance. + JobUserDeleteCheck({ + required this.data, + required this.name, + }); + + BaseJobData data; + + UserDeleteCheck name; + + @override + bool operator ==(Object other) => identical(this, other) || other is JobUserDeleteCheck && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'JobUserDeleteCheck[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [JobUserDeleteCheck] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static JobUserDeleteCheck? fromJson(dynamic value) { + upgradeDto(value, "JobUserDeleteCheck"); + if (value is Map) { + final json = value.cast(); + + return JobUserDeleteCheck( + data: BaseJobData.fromJson(json[r'data'])!, + name: UserDeleteCheck.fromJson(json[r'name'])!, + ); + } + 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 = JobUserDeleteCheck.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 = JobUserDeleteCheck.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of JobUserDeleteCheck-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] = JobUserDeleteCheck.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/memory_cleanup.dart b/mobile/openapi/lib/model/memory_cleanup.dart new file mode 100644 index 0000000000000..6988ef38a7196 --- /dev/null +++ b/mobile/openapi/lib/model/memory_cleanup.dart @@ -0,0 +1,82 @@ +// +// 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 MemoryCleanup { + /// Instantiate a new enum with the provided [value]. + const MemoryCleanup._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const memoryCleanup = MemoryCleanup._(r'MemoryCleanup'); + + /// List of all possible values in this [enum][MemoryCleanup]. + static const values = [ + memoryCleanup, + ]; + + static MemoryCleanup? fromJson(dynamic value) => MemoryCleanupTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = MemoryCleanup.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [MemoryCleanup] to String, +/// and [decode] dynamic data back to [MemoryCleanup]. +class MemoryCleanupTypeTransformer { + factory MemoryCleanupTypeTransformer() => _instance ??= const MemoryCleanupTypeTransformer._(); + + const MemoryCleanupTypeTransformer._(); + + String encode(MemoryCleanup data) => data.value; + + /// Decodes a [dynamic value][data] to a MemoryCleanup. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + MemoryCleanup? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'MemoryCleanup': return MemoryCleanup.memoryCleanup; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [MemoryCleanupTypeTransformer] instance. + static MemoryCleanupTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/memory_generate.dart b/mobile/openapi/lib/model/memory_generate.dart new file mode 100644 index 0000000000000..d4c2f48544bff --- /dev/null +++ b/mobile/openapi/lib/model/memory_generate.dart @@ -0,0 +1,82 @@ +// +// 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 MemoryGenerate { + /// Instantiate a new enum with the provided [value]. + const MemoryGenerate._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const memoryGenerate = MemoryGenerate._(r'MemoryGenerate'); + + /// List of all possible values in this [enum][MemoryGenerate]. + static const values = [ + memoryGenerate, + ]; + + static MemoryGenerate? fromJson(dynamic value) => MemoryGenerateTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = MemoryGenerate.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [MemoryGenerate] to String, +/// and [decode] dynamic data back to [MemoryGenerate]. +class MemoryGenerateTypeTransformer { + factory MemoryGenerateTypeTransformer() => _instance ??= const MemoryGenerateTypeTransformer._(); + + const MemoryGenerateTypeTransformer._(); + + String encode(MemoryGenerate data) => data.value; + + /// Decodes a [dynamic value][data] to a MemoryGenerate. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + MemoryGenerate? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'MemoryGenerate': return MemoryGenerate.memoryGenerate; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [MemoryGenerateTypeTransformer] instance. + static MemoryGenerateTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/person_cleanup.dart b/mobile/openapi/lib/model/person_cleanup.dart new file mode 100644 index 0000000000000..14da901b1268a --- /dev/null +++ b/mobile/openapi/lib/model/person_cleanup.dart @@ -0,0 +1,82 @@ +// +// 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 PersonCleanup { + /// Instantiate a new enum with the provided [value]. + const PersonCleanup._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const personCleanup = PersonCleanup._(r'PersonCleanup'); + + /// List of all possible values in this [enum][PersonCleanup]. + static const values = [ + personCleanup, + ]; + + static PersonCleanup? fromJson(dynamic value) => PersonCleanupTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = PersonCleanup.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [PersonCleanup] to String, +/// and [decode] dynamic data back to [PersonCleanup]. +class PersonCleanupTypeTransformer { + factory PersonCleanupTypeTransformer() => _instance ??= const PersonCleanupTypeTransformer._(); + + const PersonCleanupTypeTransformer._(); + + String encode(PersonCleanup data) => data.value; + + /// Decodes a [dynamic value][data] to a PersonCleanup. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + PersonCleanup? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'PersonCleanup': return PersonCleanup.personCleanup; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [PersonCleanupTypeTransformer] instance. + static PersonCleanupTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/queue_job_create_dto.dart b/mobile/openapi/lib/model/queue_job_create_dto.dart new file mode 100644 index 0000000000000..f9505ac7104e9 --- /dev/null +++ b/mobile/openapi/lib/model/queue_job_create_dto.dart @@ -0,0 +1,99 @@ +// +// 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 QueueJobCreateDto { + /// Returns a new [QueueJobCreateDto] instance. + QueueJobCreateDto({ + required this.job, + }); + + QueueJobCreateDtoJob job; + + @override + bool operator ==(Object other) => identical(this, other) || other is QueueJobCreateDto && + other.job == job; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (job.hashCode); + + @override + String toString() => 'QueueJobCreateDto[job=$job]'; + + Map toJson() { + final json = {}; + json[r'job'] = this.job; + return json; + } + + /// Returns a new [QueueJobCreateDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static QueueJobCreateDto? fromJson(dynamic value) { + upgradeDto(value, "QueueJobCreateDto"); + if (value is Map) { + final json = value.cast(); + + return QueueJobCreateDto( + job: QueueJobCreateDtoJob.fromJson(json[r'job'])!, + ); + } + 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 = QueueJobCreateDto.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 = QueueJobCreateDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of QueueJobCreateDto-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] = QueueJobCreateDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'job', + }; +} + diff --git a/mobile/openapi/lib/model/queue_job_create_dto_job.dart b/mobile/openapi/lib/model/queue_job_create_dto_job.dart new file mode 100644 index 0000000000000..ad45f1725689c --- /dev/null +++ b/mobile/openapi/lib/model/queue_job_create_dto_job.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 QueueJobCreateDtoJob { + /// Returns a new [QueueJobCreateDtoJob] instance. + QueueJobCreateDtoJob({ + required this.data, + required this.name, + }); + + BaseJobData data; + + DatabaseBackup name; + + @override + bool operator ==(Object other) => identical(this, other) || other is QueueJobCreateDtoJob && + other.data == data && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (data.hashCode) + + (name.hashCode); + + @override + String toString() => 'QueueJobCreateDtoJob[data=$data, name=$name]'; + + Map toJson() { + final json = {}; + json[r'data'] = this.data; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [QueueJobCreateDtoJob] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static QueueJobCreateDtoJob? fromJson(dynamic value) { + upgradeDto(value, "QueueJobCreateDtoJob"); + if (value is Map) { + final json = value.cast(); + + return QueueJobCreateDtoJob( + data: BaseJobData.fromJson(json[r'data'])!, + name: DatabaseBackup.fromJson(json[r'name'])!, + ); + } + 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 = QueueJobCreateDtoJob.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 = QueueJobCreateDtoJob.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of QueueJobCreateDtoJob-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] = QueueJobCreateDtoJob.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'data', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/tag_cleanup.dart b/mobile/openapi/lib/model/tag_cleanup.dart new file mode 100644 index 0000000000000..e7e322a66e555 --- /dev/null +++ b/mobile/openapi/lib/model/tag_cleanup.dart @@ -0,0 +1,82 @@ +// +// 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 TagCleanup { + /// Instantiate a new enum with the provided [value]. + const TagCleanup._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const tagCleanup = TagCleanup._(r'TagCleanup'); + + /// List of all possible values in this [enum][TagCleanup]. + static const values = [ + tagCleanup, + ]; + + static TagCleanup? fromJson(dynamic value) => TagCleanupTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = TagCleanup.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [TagCleanup] to String, +/// and [decode] dynamic data back to [TagCleanup]. +class TagCleanupTypeTransformer { + factory TagCleanupTypeTransformer() => _instance ??= const TagCleanupTypeTransformer._(); + + const TagCleanupTypeTransformer._(); + + String encode(TagCleanup data) => data.value; + + /// Decodes a [dynamic value][data] to a TagCleanup. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + TagCleanup? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'TagCleanup': return TagCleanup.tagCleanup; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [TagCleanupTypeTransformer] instance. + static TagCleanupTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/user_delete_check.dart b/mobile/openapi/lib/model/user_delete_check.dart new file mode 100644 index 0000000000000..66b3d3373cb5e --- /dev/null +++ b/mobile/openapi/lib/model/user_delete_check.dart @@ -0,0 +1,82 @@ +// +// 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 UserDeleteCheck { + /// Instantiate a new enum with the provided [value]. + const UserDeleteCheck._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const userDeleteCheck = UserDeleteCheck._(r'UserDeleteCheck'); + + /// List of all possible values in this [enum][UserDeleteCheck]. + static const values = [ + userDeleteCheck, + ]; + + static UserDeleteCheck? fromJson(dynamic value) => UserDeleteCheckTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = UserDeleteCheck.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [UserDeleteCheck] to String, +/// and [decode] dynamic data back to [UserDeleteCheck]. +class UserDeleteCheckTypeTransformer { + factory UserDeleteCheckTypeTransformer() => _instance ??= const UserDeleteCheckTypeTransformer._(); + + const UserDeleteCheckTypeTransformer._(); + + String encode(UserDeleteCheck data) => data.value; + + /// Decodes a [dynamic value][data] to a UserDeleteCheck. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + UserDeleteCheck? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'UserDeleteCheck': return UserDeleteCheck.userDeleteCheck; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [UserDeleteCheckTypeTransformer] instance. + static UserDeleteCheckTypeTransformer? _instance; +} + diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 2f160e6beda19..fd6dffa8bf0d7 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -8476,6 +8476,56 @@ "x-immich-state": "Alpha" } }, + "/queues/job": { + "post": { + "description": "Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup.", + "operationId": "queueJob", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueueJobCreateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Create a manual job", + "tags": [ + "Queues" + ], + "x-immich-admin-only": true, + "x-immich-history": [ + { + "version": "v2.5.0", + "state": "Added" + }, + { + "version": "v2.5.0", + "state": "Alpha" + } + ], + "x-immich-permission": "job.create", + "x-immich-state": "Alpha" + } + }, "/queues/{name}": { "get": { "description": "Retrieves a specific queue by its name.", @@ -16525,6 +16575,14 @@ }, "type": "object" }, + "BaseJobData": { + "properties": { + "force": { + "type": "boolean" + } + }, + "type": "object" + }, "BulkIdErrorReason": { "enum": [ "duplicate", @@ -16814,6 +16872,12 @@ ], "type": "object" }, + "DatabaseBackup": { + "enum": [ + "DatabaseBackup" + ], + "type": "string" + }, "DatabaseBackupConfig": { "properties": { "cronExpression": { @@ -17205,6 +17269,63 @@ ], "type": "object" }, + "JobDatabaseBackup": { + "properties": { + "data": { + "$ref": "#/components/schemas/BaseJobData" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/DatabaseBackup" + } + ] + } + }, + "required": [ + "data", + "name" + ], + "type": "object" + }, + "JobMemoryCleanup": { + "properties": { + "data": { + "$ref": "#/components/schemas/BaseJobData" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/MemoryCleanup" + } + ] + } + }, + "required": [ + "data", + "name" + ], + "type": "object" + }, + "JobMemoryGenerate": { + "properties": { + "data": { + "$ref": "#/components/schemas/BaseJobData" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/MemoryGenerate" + } + ] + } + }, + "required": [ + "data", + "name" + ], + "type": "object" + }, "JobName": { "enum": [ "AssetDelete", @@ -17266,6 +17387,25 @@ ], "type": "string" }, + "JobPersonCleanup": { + "properties": { + "data": { + "$ref": "#/components/schemas/BaseJobData" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/PersonCleanup" + } + ] + } + }, + "required": [ + "data", + "name" + ], + "type": "object" + }, "JobSettingsDto": { "properties": { "concurrency": { @@ -17278,6 +17418,44 @@ ], "type": "object" }, + "JobTagCleanup": { + "properties": { + "data": { + "$ref": "#/components/schemas/BaseJobData" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/TagCleanup" + } + ] + } + }, + "required": [ + "data", + "name" + ], + "type": "object" + }, + "JobUserDeleteCheck": { + "properties": { + "data": { + "$ref": "#/components/schemas/BaseJobData" + }, + "name": { + "allOf": [ + { + "$ref": "#/components/schemas/UserDeleteCheck" + } + ] + } + }, + "required": [ + "data", + "name" + ], + "type": "object" + }, "LibraryResponseDto": { "properties": { "assetCount": { @@ -17622,6 +17800,12 @@ }, "type": "object" }, + "MemoryCleanup": { + "enum": [ + "MemoryCleanup" + ], + "type": "string" + }, "MemoryCreateDto": { "properties": { "assetIds": { @@ -17660,6 +17844,12 @@ ], "type": "object" }, + "MemoryGenerate": { + "enum": [ + "MemoryGenerate" + ], + "type": "string" + }, "MemoryResponseDto": { "properties": { "assets": { @@ -18605,6 +18795,12 @@ ], "type": "string" }, + "PersonCleanup": { + "enum": [ + "PersonCleanup" + ], + "type": "string" + }, "PersonCreateDto": { "properties": { "birthDate": { @@ -19135,6 +19331,36 @@ }, "type": "object" }, + "QueueJobCreateDto": { + "properties": { + "job": { + "oneOf": [ + { + "$ref": "#/components/schemas/JobTagCleanup" + }, + { + "$ref": "#/components/schemas/JobPersonCleanup" + }, + { + "$ref": "#/components/schemas/JobUserDeleteCheck" + }, + { + "$ref": "#/components/schemas/JobMemoryCleanup" + }, + { + "$ref": "#/components/schemas/JobMemoryGenerate" + }, + { + "$ref": "#/components/schemas/JobDatabaseBackup" + } + ] + } + }, + "required": [ + "job" + ], + "type": "object" + }, "QueueJobResponseDto": { "properties": { "data": { @@ -22828,6 +23054,12 @@ ], "type": "object" }, + "TagCleanup": { + "enum": [ + "TagCleanup" + ], + "type": "string" + }, "TagCreateDto": { "properties": { "color": { @@ -23549,6 +23781,12 @@ ], "type": "string" }, + "UserDeleteCheck": { + "enum": [ + "UserDeleteCheck" + ], + "type": "string" + }, "UserLicense": { "properties": { "activatedAt": { diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index 496e6906a2c4c..3722b0337b639 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -1038,6 +1038,36 @@ export type QueueResponseDto = { name: QueueName; statistics: QueueStatisticsDto; }; +export type BaseJobData = { + force?: boolean; +}; +export type JobTagCleanup = { + data: BaseJobData; + name: TagCleanup; +}; +export type JobPersonCleanup = { + data: BaseJobData; + name: PersonCleanup; +}; +export type JobUserDeleteCheck = { + data: BaseJobData; + name: UserDeleteCheck; +}; +export type JobMemoryCleanup = { + data: BaseJobData; + name: MemoryCleanup; +}; +export type JobMemoryGenerate = { + data: BaseJobData; + name: MemoryGenerate; +}; +export type JobDatabaseBackup = { + data: BaseJobData; + name: DatabaseBackup; +}; +export type QueueJobCreateDto = { + job: JobTagCleanup | JobPersonCleanup | JobUserDeleteCheck | JobMemoryCleanup | JobMemoryGenerate | JobDatabaseBackup; +}; export type QueueUpdateDto = { isPaused?: boolean; }; @@ -3834,6 +3864,18 @@ export function getQueues(opts?: Oazapfts.RequestOpts) { ...opts })); } +/** + * Create a manual job + */ +export function queueJob({ queueJobCreateDto }: { + queueJobCreateDto: QueueJobCreateDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/queues/job", oazapfts.json({ + ...opts, + method: "POST", + body: queueJobCreateDto + }))); +} /** * Retrieve a queue */ @@ -5594,6 +5636,24 @@ export enum PluginTriggerType { AssetCreate = "AssetCreate", PersonRecognized = "PersonRecognized" } +export enum TagCleanup { + TagCleanup = "TagCleanup" +} +export enum PersonCleanup { + PersonCleanup = "PersonCleanup" +} +export enum UserDeleteCheck { + UserDeleteCheck = "UserDeleteCheck" +} +export enum MemoryCleanup { + MemoryCleanup = "MemoryCleanup" +} +export enum MemoryGenerate { + MemoryGenerate = "MemoryGenerate" +} +export enum DatabaseBackup { + DatabaseBackup = "DatabaseBackup" +} export enum QueueJobStatus { Active = "active", Failed = "failed", diff --git a/server/src/controllers/queue.controller.ts b/server/src/controllers/queue.controller.ts index 1d8d918c5f778..2d9f6e67a30ac 100644 --- a/server/src/controllers/queue.controller.ts +++ b/server/src/controllers/queue.controller.ts @@ -1,9 +1,10 @@ -import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Put, Query } from '@nestjs/common'; +import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Endpoint, HistoryBuilder } from 'src/decorators'; import { AuthDto } from 'src/dtos/auth.dto'; import { QueueDeleteDto, + QueueJobCreateDto, QueueJobResponseDto, QueueJobSearchDto, QueueNameParamDto, @@ -19,6 +20,19 @@ import { QueueService } from 'src/services/queue.service'; export class QueueController { constructor(private service: QueueService) {} + @Post('job') + @Authenticated({ permission: Permission.JobCreate, admin: true }) + @HttpCode(HttpStatus.NO_CONTENT) + @Endpoint({ + summary: 'Create a manual job', + description: + 'Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup.', + history: new HistoryBuilder().added('v2.5.0').alpha('v2.5.0'), + }) + queueJob(@Body() dto: QueueJobCreateDto): Promise { + return this.service.createJob(dto); + } + @Get() @Authenticated({ permission: Permission.QueueRead, admin: true }) @Endpoint({ diff --git a/server/src/dtos/queue.dto.ts b/server/src/dtos/queue.dto.ts index 38a4a4ac6b21c..3fa225723de39 100644 --- a/server/src/dtos/queue.dto.ts +++ b/server/src/dtos/queue.dto.ts @@ -1,7 +1,85 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiExtraModels, ApiProperty, getSchemaPath } from '@nestjs/swagger'; +import { ClassConstructor, Transform, Type } from 'class-transformer'; +import { Equals, IsBoolean, IsDefined, IsOptional, ValidateNested } from 'class-validator'; import { HistoryBuilder, Property } from 'src/decorators'; import { JobName, QueueCommand, QueueJobStatus, QueueName } from 'src/enum'; -import { ValidateBoolean, ValidateEnum } from 'src/validation'; +import { transformToOneOf, ValidateBoolean, ValidateEnum } from 'src/validation'; + +class BaseJobData { + @IsOptional() + @IsBoolean() + force?: boolean; +} + +class BaseJob { + @ValidateNested() + @Type(() => BaseJobData) + data!: BaseJobData; +} + +class JobTagCleanup extends BaseJob { + @ApiProperty({ enumName: JobName.TagCleanup, enum: [JobName.TagCleanup] }) + @Equals(JobName.TagCleanup) + name!: JobName.TagCleanup; +} + +class JobPersonCleanup extends BaseJob { + @ApiProperty({ enumName: JobName.PersonCleanup, enum: [JobName.PersonCleanup] }) + @Equals(JobName.PersonCleanup) + name!: JobName.PersonCleanup; +} + +class JobUserDeleteCheck extends BaseJob { + @ApiProperty({ enumName: JobName.UserDeleteCheck, enum: [JobName.UserDeleteCheck] }) + @Equals(JobName.UserDeleteCheck) + name!: JobName.UserDeleteCheck; +} + +class JobMemoryCleanup extends BaseJob { + @ApiProperty({ enumName: JobName.MemoryCleanup, enum: [JobName.MemoryCleanup] }) + @Equals(JobName.MemoryCleanup) + name!: JobName.MemoryCleanup; +} + +class JobMemoryGenerate extends BaseJob { + @ApiProperty({ enumName: JobName.MemoryGenerate, enum: [JobName.MemoryGenerate] }) + @Equals(JobName.MemoryGenerate) + name!: JobName.MemoryGenerate; +} + +class JobDatabaseBackup extends BaseJob { + @ApiProperty({ enumName: JobName.DatabaseBackup, enum: [JobName.DatabaseBackup] }) + @Equals(JobName.DatabaseBackup) + name!: JobName.DatabaseBackup; +} + +const JOB_MAP: Record> = { + [JobName.TagCleanup]: JobTagCleanup, + [JobName.PersonCleanup]: JobPersonCleanup, + [JobName.UserDeleteCheck]: JobUserDeleteCheck, + [JobName.MemoryCleanup]: JobMemoryCleanup, + [JobName.MemoryGenerate]: JobMemoryGenerate, + [JobName.DatabaseBackup]: JobDatabaseBackup, +}; + +@ApiExtraModels(...Object.values(JOB_MAP)) +export class QueueJobCreateDto { + @ApiProperty({ + oneOf: Object.values(JOB_MAP).map((job) => ({ $ref: getSchemaPath(job) })), + }) + @ValidateNested() + @Transform(transformToOneOf(JOB_MAP)) + @IsDefined({ + message: `job.name must be one of ${Object.keys(JOB_MAP)}`, + }) + job!: + | JobTagCleanup + | JobPersonCleanup + | JobUserDeleteCheck + | JobMemoryCleanup + | JobMemoryGenerate + | JobDatabaseBackup; +} export class QueueNameParamDto { @ValidateEnum({ enum: QueueName, name: 'QueueName' }) diff --git a/server/src/services/queue.service.ts b/server/src/services/queue.service.ts index cdfa2ad2ed224..1c941c1e59235 100644 --- a/server/src/services/queue.service.ts +++ b/server/src/services/queue.service.ts @@ -12,6 +12,7 @@ import { import { QueueCommandDto, QueueDeleteDto, + QueueJobCreateDto, QueueJobResponseDto, QueueJobSearchDto, QueueResponseDto, @@ -100,6 +101,10 @@ export class QueueService extends BaseService { this.services = services; } + createJob(dto: QueueJobCreateDto): Promise { + return this.jobRepository.queue(dto.job); + } + async runCommandLegacy(name: QueueName, dto: QueueCommandDto): Promise { this.logger.debug(`Handling command: queue=${name},command=${dto.command},force=${dto.force}`); diff --git a/server/src/validation.ts b/server/src/validation.ts index 1ac21020c5146..5634a6f661bd2 100644 --- a/server/src/validation.ts +++ b/server/src/validation.ts @@ -7,7 +7,7 @@ import { applyDecorators, } from '@nestjs/common'; import { ApiProperty, ApiPropertyOptions } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; +import { ClassConstructor, Transform, TransformFnParams, plainToInstance } from 'class-transformer'; import { IsArray, IsBoolean, @@ -417,3 +417,8 @@ export function IsIPRange(options: IsIPRangeOptions, validationOptions?: Validat validationOptions, ); } + +export const transformToOneOf = + >>(map: T) => + ({ value }: TransformFnParams) => + value && typeof value === 'object' && map[value.name] ? plainToInstance(map[value.name], value) : null;