mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
MUST NOT validation
This commit is contained in:
parent
2666ee2b4f
commit
bc84486668
9 changed files with 273 additions and 37 deletions
1
mobile/openapi/README.md
generated
1
mobile/openapi/README.md
generated
|
|
@ -584,6 +584,7 @@ Class | Method | HTTP request | Description
|
||||||
- [UpdateAlbumUserDto](doc//UpdateAlbumUserDto.md)
|
- [UpdateAlbumUserDto](doc//UpdateAlbumUserDto.md)
|
||||||
- [UpdateAssetDto](doc//UpdateAssetDto.md)
|
- [UpdateAssetDto](doc//UpdateAssetDto.md)
|
||||||
- [UpdateLibraryDto](doc//UpdateLibraryDto.md)
|
- [UpdateLibraryDto](doc//UpdateLibraryDto.md)
|
||||||
|
- [UploadOkDto](doc//UploadOkDto.md)
|
||||||
- [UsageByUserDto](doc//UsageByUserDto.md)
|
- [UsageByUserDto](doc//UsageByUserDto.md)
|
||||||
- [UserAdminCreateDto](doc//UserAdminCreateDto.md)
|
- [UserAdminCreateDto](doc//UserAdminCreateDto.md)
|
||||||
- [UserAdminDeleteDto](doc//UserAdminDeleteDto.md)
|
- [UserAdminDeleteDto](doc//UserAdminDeleteDto.md)
|
||||||
|
|
|
||||||
1
mobile/openapi/lib/api.dart
generated
1
mobile/openapi/lib/api.dart
generated
|
|
@ -348,6 +348,7 @@ part 'model/update_album_dto.dart';
|
||||||
part 'model/update_album_user_dto.dart';
|
part 'model/update_album_user_dto.dart';
|
||||||
part 'model/update_asset_dto.dart';
|
part 'model/update_asset_dto.dart';
|
||||||
part 'model/update_library_dto.dart';
|
part 'model/update_library_dto.dart';
|
||||||
|
part 'model/upload_ok_dto.dart';
|
||||||
part 'model/usage_by_user_dto.dart';
|
part 'model/usage_by_user_dto.dart';
|
||||||
part 'model/user_admin_create_dto.dart';
|
part 'model/user_admin_create_dto.dart';
|
||||||
part 'model/user_admin_delete_dto.dart';
|
part 'model/user_admin_delete_dto.dart';
|
||||||
|
|
|
||||||
8
mobile/openapi/lib/api/upload_api.dart
generated
8
mobile/openapi/lib/api/upload_api.dart
generated
|
|
@ -259,7 +259,7 @@ class UploadApi {
|
||||||
/// * [String] key:
|
/// * [String] key:
|
||||||
///
|
///
|
||||||
/// * [String] slug:
|
/// * [String] slug:
|
||||||
Future<Object?> resumeUpload(String contentLength, String id, String uploadComplete, String uploadDraftInteropVersion, String uploadOffset, { String? key, String? slug, }) async {
|
Future<UploadOkDto?> resumeUpload(String contentLength, String id, String uploadComplete, String uploadDraftInteropVersion, String uploadOffset, { String? key, String? slug, }) async {
|
||||||
final response = await resumeUploadWithHttpInfo(contentLength, id, uploadComplete, uploadDraftInteropVersion, uploadOffset, key: key, slug: slug, );
|
final response = await resumeUploadWithHttpInfo(contentLength, id, uploadComplete, uploadDraftInteropVersion, uploadOffset, key: key, slug: slug, );
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
|
@ -268,7 +268,7 @@ class UploadApi {
|
||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
// FormatException when trying to decode an empty string.
|
// FormatException when trying to decode an empty string.
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object;
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UploadOkDto',) as UploadOkDto;
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -358,7 +358,7 @@ class UploadApi {
|
||||||
/// * [String] key:
|
/// * [String] key:
|
||||||
///
|
///
|
||||||
/// * [String] slug:
|
/// * [String] slug:
|
||||||
Future<Object?> startUpload(String contentLength, String reprDigest, String uploadComplete, String uploadDraftInteropVersion, String xImmichAssetData, { String? key, String? slug, }) async {
|
Future<UploadOkDto?> startUpload(String contentLength, String reprDigest, String uploadComplete, String uploadDraftInteropVersion, String xImmichAssetData, { String? key, String? slug, }) async {
|
||||||
final response = await startUploadWithHttpInfo(contentLength, reprDigest, uploadComplete, uploadDraftInteropVersion, xImmichAssetData, key: key, slug: slug, );
|
final response = await startUploadWithHttpInfo(contentLength, reprDigest, uploadComplete, uploadDraftInteropVersion, xImmichAssetData, key: key, slug: slug, );
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
|
|
@ -367,7 +367,7 @@ class UploadApi {
|
||||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||||
// FormatException when trying to decode an empty string.
|
// FormatException when trying to decode an empty string.
|
||||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object;
|
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UploadOkDto',) as UploadOkDto;
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
2
mobile/openapi/lib/api_client.dart
generated
2
mobile/openapi/lib/api_client.dart
generated
|
|
@ -748,6 +748,8 @@ class ApiClient {
|
||||||
return UpdateAssetDto.fromJson(value);
|
return UpdateAssetDto.fromJson(value);
|
||||||
case 'UpdateLibraryDto':
|
case 'UpdateLibraryDto':
|
||||||
return UpdateLibraryDto.fromJson(value);
|
return UpdateLibraryDto.fromJson(value);
|
||||||
|
case 'UploadOkDto':
|
||||||
|
return UploadOkDto.fromJson(value);
|
||||||
case 'UsageByUserDto':
|
case 'UsageByUserDto':
|
||||||
return UsageByUserDto.fromJson(value);
|
return UsageByUserDto.fromJson(value);
|
||||||
case 'UserAdminCreateDto':
|
case 'UserAdminCreateDto':
|
||||||
|
|
|
||||||
99
mobile/openapi/lib/model/upload_ok_dto.dart
generated
Normal file
99
mobile/openapi/lib/model/upload_ok_dto.dart
generated
Normal file
|
|
@ -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 UploadOkDto {
|
||||||
|
/// Returns a new [UploadOkDto] instance.
|
||||||
|
UploadOkDto({
|
||||||
|
required this.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is UploadOkDto &&
|
||||||
|
other.id == id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(id.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'UploadOkDto[id=$id]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
json[r'id'] = this.id;
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [UploadOkDto] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static UploadOkDto? fromJson(dynamic value) {
|
||||||
|
upgradeDto(value, "UploadOkDto");
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return UploadOkDto(
|
||||||
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<UploadOkDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <UploadOkDto>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = UploadOkDto.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, UploadOkDto> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, UploadOkDto>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = UploadOkDto.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of UploadOkDto-objects as value to a dart map
|
||||||
|
static Map<String, List<UploadOkDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<UploadOkDto>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = UploadOkDto.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'id',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -18059,7 +18059,14 @@
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"UploadOkDto": {
|
"UploadOkDto": {
|
||||||
"properties": {},
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"UsageByUserDto": {
|
"UsageByUserDto": {
|
||||||
|
|
|
||||||
|
|
@ -1654,7 +1654,9 @@ export type TimeBucketsResponseDto = {
|
||||||
export type TrashResponseDto = {
|
export type TrashResponseDto = {
|
||||||
count: number;
|
count: number;
|
||||||
};
|
};
|
||||||
export type UploadOkDto = {};
|
export type UploadOkDto = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
export type UserUpdateMeDto = {
|
export type UserUpdateMeDto = {
|
||||||
avatarColor?: (UserAvatarColor) | null;
|
avatarColor?: (UserAvatarColor) | null;
|
||||||
email?: string;
|
email?: string;
|
||||||
|
|
|
||||||
153
pnpm-lock.yaml
generated
153
pnpm-lock.yaml
generated
|
|
@ -67,7 +67,7 @@ importers:
|
||||||
version: 22.18.13
|
version: 22.18.13
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
byte-size:
|
byte-size:
|
||||||
specifier: ^9.0.0
|
specifier: ^9.0.0
|
||||||
version: 9.0.1
|
version: 9.0.1
|
||||||
|
|
@ -115,10 +115,10 @@ importers:
|
||||||
version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
vitest-fetch-mock:
|
vitest-fetch-mock:
|
||||||
specifier: ^0.4.0
|
specifier: ^0.4.0
|
||||||
version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
yaml:
|
yaml:
|
||||||
specifier: ^2.3.1
|
specifier: ^2.3.1
|
||||||
version: 2.8.1
|
version: 2.8.1
|
||||||
|
|
@ -620,7 +620,7 @@ importers:
|
||||||
version: 13.15.3
|
version: 13.15.3
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.14.0
|
specifier: ^9.14.0
|
||||||
version: 9.38.0(jiti@2.6.1)
|
version: 9.38.0(jiti@2.6.1)
|
||||||
|
|
@ -677,7 +677,7 @@ importers:
|
||||||
version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
|
||||||
web:
|
web:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -731,7 +731,7 @@ importers:
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
fabric:
|
fabric:
|
||||||
specifier: ^6.5.4
|
specifier: ^6.5.4
|
||||||
version: 6.7.1(encoding@0.1.13)
|
version: 6.7.1
|
||||||
geo-coordinates-parser:
|
geo-coordinates-parser:
|
||||||
specifier: ^1.7.4
|
specifier: ^1.7.4
|
||||||
version: 1.7.4
|
version: 1.7.4
|
||||||
|
|
@ -822,7 +822,7 @@ importers:
|
||||||
version: 6.9.1
|
version: 6.9.1
|
||||||
'@testing-library/svelte':
|
'@testing-library/svelte':
|
||||||
specifier: ^5.2.8
|
specifier: ^5.2.8
|
||||||
version: 5.2.8(svelte@5.41.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 5.2.8(svelte@5.41.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
'@testing-library/user-event':
|
'@testing-library/user-event':
|
||||||
specifier: ^14.5.2
|
specifier: ^14.5.2
|
||||||
version: 14.6.1(@testing-library/dom@10.4.0)
|
version: 14.6.1(@testing-library/dom@10.4.0)
|
||||||
|
|
@ -846,7 +846,7 @@ importers:
|
||||||
version: 1.5.6
|
version: 1.5.6
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^17.0.0
|
specifier: ^17.0.0
|
||||||
version: 17.2.3
|
version: 17.2.3
|
||||||
|
|
@ -909,7 +909,7 @@ importers:
|
||||||
version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
|
@ -14658,6 +14658,22 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
mapbox-gl: 1.13.3
|
mapbox-gl: 1.13.3
|
||||||
|
|
||||||
|
'@mapbox/node-pre-gyp@1.0.11':
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 2.1.2
|
||||||
|
https-proxy-agent: 5.0.1
|
||||||
|
make-dir: 3.1.0
|
||||||
|
node-fetch: 2.7.0
|
||||||
|
nopt: 5.0.0
|
||||||
|
npmlog: 5.0.1
|
||||||
|
rimraf: 3.0.2
|
||||||
|
semver: 7.7.3
|
||||||
|
tar: 6.2.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
- supports-color
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)':
|
'@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)':
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-libc: 2.1.2
|
detect-libc: 2.1.2
|
||||||
|
|
@ -16156,13 +16172,13 @@ snapshots:
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
redent: 3.0.0
|
redent: 3.0.0
|
||||||
|
|
||||||
'@testing-library/svelte@5.2.8(svelte@5.41.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
|
'@testing-library/svelte@5.2.8(svelte@5.41.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@testing-library/dom': 10.4.0
|
'@testing-library/dom': 10.4.0
|
||||||
svelte: 5.41.3
|
svelte: 5.41.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
|
||||||
'@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)':
|
'@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -16735,7 +16751,7 @@ snapshots:
|
||||||
|
|
||||||
'@vercel/oidc@3.0.3': {}
|
'@vercel/oidc@3.0.3': {}
|
||||||
|
|
||||||
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
|
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ampproject/remapping': 2.3.0
|
'@ampproject/remapping': 2.3.0
|
||||||
'@bcoe/v8-coverage': 1.0.2
|
'@bcoe/v8-coverage': 1.0.2
|
||||||
|
|
@ -16750,11 +16766,11 @@ snapshots:
|
||||||
std-env: 3.10.0
|
std-env: 3.10.0
|
||||||
test-exclude: 7.0.1
|
test-exclude: 7.0.1
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
|
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ampproject/remapping': 2.3.0
|
'@ampproject/remapping': 2.3.0
|
||||||
'@bcoe/v8-coverage': 1.0.2
|
'@bcoe/v8-coverage': 1.0.2
|
||||||
|
|
@ -16769,7 +16785,7 @@ snapshots:
|
||||||
std-env: 3.10.0
|
std-env: 3.10.0
|
||||||
test-exclude: 7.0.1
|
test-exclude: 7.0.1
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
|
@ -17487,6 +17503,16 @@ snapshots:
|
||||||
|
|
||||||
caniuse-lite@1.0.30001751: {}
|
caniuse-lite@1.0.30001751: {}
|
||||||
|
|
||||||
|
canvas@2.11.2:
|
||||||
|
dependencies:
|
||||||
|
'@mapbox/node-pre-gyp': 1.0.11
|
||||||
|
nan: 2.23.0
|
||||||
|
simple-get: 3.1.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
- supports-color
|
||||||
|
optional: true
|
||||||
|
|
||||||
canvas@2.11.2(encoding@0.1.13):
|
canvas@2.11.2(encoding@0.1.13):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13)
|
'@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13)
|
||||||
|
|
@ -18883,10 +18909,10 @@ snapshots:
|
||||||
|
|
||||||
extend@3.0.2: {}
|
extend@3.0.2: {}
|
||||||
|
|
||||||
fabric@6.7.1(encoding@0.1.13):
|
fabric@6.7.1:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
canvas: 2.11.2(encoding@0.1.13)
|
canvas: 2.11.2
|
||||||
jsdom: 20.0.3(canvas@2.11.2(encoding@0.1.13))
|
jsdom: 20.0.3(canvas@2.11.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- encoding
|
- encoding
|
||||||
|
|
@ -20004,7 +20030,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse: 2.0.1
|
argparse: 2.0.1
|
||||||
|
|
||||||
jsdom@20.0.3(canvas@2.11.2(encoding@0.1.13)):
|
jsdom@20.0.3(canvas@2.11.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
abab: 2.0.6
|
abab: 2.0.6
|
||||||
acorn: 8.15.0
|
acorn: 8.15.0
|
||||||
|
|
@ -20033,7 +20059,7 @@ snapshots:
|
||||||
ws: 8.18.3
|
ws: 8.18.3
|
||||||
xml-name-validator: 4.0.0
|
xml-name-validator: 4.0.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
canvas: 2.11.2(encoding@0.1.13)
|
canvas: 2.11.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
@ -20070,6 +20096,36 @@ snapshots:
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
jsdom@26.1.0(canvas@2.11.2):
|
||||||
|
dependencies:
|
||||||
|
cssstyle: 4.6.0
|
||||||
|
data-urls: 5.0.0
|
||||||
|
decimal.js: 10.6.0
|
||||||
|
html-encoding-sniffer: 4.0.0
|
||||||
|
http-proxy-agent: 7.0.2
|
||||||
|
https-proxy-agent: 7.0.6
|
||||||
|
is-potential-custom-element-name: 1.0.1
|
||||||
|
nwsapi: 2.2.22
|
||||||
|
parse5: 7.3.0
|
||||||
|
rrweb-cssom: 0.8.0
|
||||||
|
saxes: 6.0.0
|
||||||
|
symbol-tree: 3.2.4
|
||||||
|
tough-cookie: 5.1.2
|
||||||
|
w3c-xmlserializer: 5.0.0
|
||||||
|
webidl-conversions: 7.0.0
|
||||||
|
whatwg-encoding: 3.1.1
|
||||||
|
whatwg-mimetype: 4.0.0
|
||||||
|
whatwg-url: 14.2.0
|
||||||
|
ws: 8.18.3
|
||||||
|
xml-name-validator: 5.0.0
|
||||||
|
optionalDependencies:
|
||||||
|
canvas: 2.11.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
optional: true
|
||||||
|
|
||||||
jsesc@3.0.2: {}
|
jsesc@3.0.2: {}
|
||||||
|
|
||||||
jsesc@3.1.0: {}
|
jsesc@3.1.0: {}
|
||||||
|
|
@ -21220,6 +21276,11 @@ snapshots:
|
||||||
emojilib: 2.4.0
|
emojilib: 2.4.0
|
||||||
skin-tone: 2.0.0
|
skin-tone: 2.0.0
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 5.0.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
node-fetch@2.7.0(encoding@0.1.13):
|
node-fetch@2.7.0(encoding@0.1.13):
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-url: 5.0.0
|
whatwg-url: 5.0.0
|
||||||
|
|
@ -24246,9 +24307,9 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
|
||||||
vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)):
|
vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)):
|
||||||
dependencies:
|
dependencies:
|
||||||
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
|
||||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
|
vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -24294,7 +24355,51 @@ snapshots:
|
||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
|
vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.13)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
|
||||||
|
dependencies:
|
||||||
|
'@types/chai': 5.2.2
|
||||||
|
'@vitest/expect': 3.2.4
|
||||||
|
'@vitest/mocker': 3.2.4(vite@7.1.12(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
|
||||||
|
'@vitest/pretty-format': 3.2.4
|
||||||
|
'@vitest/runner': 3.2.4
|
||||||
|
'@vitest/snapshot': 3.2.4
|
||||||
|
'@vitest/spy': 3.2.4
|
||||||
|
'@vitest/utils': 3.2.4
|
||||||
|
chai: 5.2.0
|
||||||
|
debug: 4.4.3
|
||||||
|
expect-type: 1.2.1
|
||||||
|
magic-string: 0.30.21
|
||||||
|
pathe: 2.0.3
|
||||||
|
picomatch: 4.0.3
|
||||||
|
std-env: 3.10.0
|
||||||
|
tinybench: 2.9.0
|
||||||
|
tinyexec: 0.3.2
|
||||||
|
tinyglobby: 0.2.15
|
||||||
|
tinypool: 1.1.1
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
vite: 7.1.12(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
vite-node: 3.2.4(@types/node@22.18.13)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
|
||||||
|
why-is-node-running: 2.3.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/debug': 4.1.12
|
||||||
|
'@types/node': 22.18.13
|
||||||
|
happy-dom: 20.0.8
|
||||||
|
jsdom: 26.1.0(canvas@2.11.2)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- jiti
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- msw
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
- tsx
|
||||||
|
- yaml
|
||||||
|
|
||||||
|
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.2)(happy-dom@20.0.8)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/chai': 5.2.2
|
'@types/chai': 5.2.2
|
||||||
'@vitest/expect': 3.2.4
|
'@vitest/expect': 3.2.4
|
||||||
|
|
@ -24323,7 +24428,7 @@ snapshots:
|
||||||
'@types/debug': 4.1.12
|
'@types/debug': 4.1.12
|
||||||
'@types/node': 24.9.2
|
'@types/node': 24.9.2
|
||||||
happy-dom: 20.0.8
|
happy-dom: 20.0.8
|
||||||
jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13))
|
jsdom: 26.1.0(canvas@2.11.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- jiti
|
- jiti
|
||||||
- less
|
- less
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Expose, plainToInstance, Transform, Type } from 'class-transformer';
|
import { Expose, plainToInstance, Transform, Type } from 'class-transformer';
|
||||||
import { Equals, IsEnum, IsInt, IsNotEmpty, IsString, Min, ValidateIf, ValidateNested } from 'class-validator';
|
import { Equals, IsEmpty, IsEnum, IsInt, IsNotEmpty, IsString, Min, ValidateIf, ValidateNested } from 'class-validator';
|
||||||
import { ImmichHeader } from 'src/enum';
|
import { ImmichHeader } from 'src/enum';
|
||||||
import { Optional, ValidateBoolean, ValidateDate } from 'src/validation';
|
import { Optional, ValidateBoolean, ValidateDate } from 'src/validation';
|
||||||
import { parseDictionary } from 'structured-headers';
|
import { parseDictionary } from 'structured-headers';
|
||||||
|
|
@ -39,13 +40,14 @@ export enum StructuredBoolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum UploadHeader {
|
export enum UploadHeader {
|
||||||
UploadOffset = 'upload-offset',
|
|
||||||
ContentLength = 'content-length',
|
ContentLength = 'content-length',
|
||||||
UploadLength = 'upload-length',
|
ContentType = 'content-type',
|
||||||
UploadComplete = 'upload-complete',
|
|
||||||
UploadIncomplete = 'upload-incomplete',
|
|
||||||
InteropVersion = 'upload-draft-interop-version',
|
InteropVersion = 'upload-draft-interop-version',
|
||||||
ReprDigest = 'repr-digest',
|
ReprDigest = 'repr-digest',
|
||||||
|
UploadComplete = 'upload-complete',
|
||||||
|
UploadIncomplete = 'upload-incomplete',
|
||||||
|
UploadLength = 'upload-length',
|
||||||
|
UploadOffset = 'upload-offset',
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseRufhHeadersDto {
|
class BaseRufhHeadersDto {
|
||||||
|
|
@ -126,10 +128,14 @@ export class StartUploadDto extends BaseUploadHeadersDto {
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
uploadLength!: number;
|
uploadLength!: number;
|
||||||
|
|
||||||
|
@Expose({ name: UploadHeader.UploadOffset })
|
||||||
|
@IsEmpty()
|
||||||
|
uploadOffset: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeUploadDto extends BaseUploadHeadersDto {
|
export class ResumeUploadDto extends BaseUploadHeadersDto {
|
||||||
@Expose({ name: 'content-type' })
|
@Expose({ name: UploadHeader.ContentType })
|
||||||
@ValidateIf((o) => o.version && o.version >= 6)
|
@ValidateIf((o) => o.version && o.version >= 6)
|
||||||
@Equals('application/partial-upload')
|
@Equals('application/partial-upload')
|
||||||
contentType!: string;
|
contentType!: string;
|
||||||
|
|
@ -148,8 +154,21 @@ export class ResumeUploadDto extends BaseUploadHeadersDto {
|
||||||
uploadOffset!: number;
|
uploadOffset!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetUploadStatusDto extends BaseRufhHeadersDto {}
|
export class GetUploadStatusDto extends BaseRufhHeadersDto {
|
||||||
|
@Expose({ name: UploadHeader.UploadComplete })
|
||||||
|
@IsEmpty()
|
||||||
|
uploadComplete: string | undefined;
|
||||||
|
|
||||||
|
@Expose({ name: UploadHeader.UploadIncomplete })
|
||||||
|
@IsEmpty()
|
||||||
|
uploadIncomplete: string | undefined;
|
||||||
|
|
||||||
|
@Expose({ name: UploadHeader.UploadOffset })
|
||||||
|
@IsEmpty()
|
||||||
|
uploadOffset: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export class UploadOkDto {
|
export class UploadOkDto {
|
||||||
|
@ApiProperty()
|
||||||
id!: string;
|
id!: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue