mirror of
https://github.com/immich-app/immich.git
synced 2025-05-31 12:15:47 -04:00
fix: use openapi_patching from v1
This commit is contained in:
parent
9f29bce308
commit
a09710ec7b
4
Makefile
4
Makefile
@ -27,8 +27,8 @@ open-api:
|
|||||||
open-api-dart:
|
open-api-dart:
|
||||||
cd ./open-api && bash ./bin/generate-open-api.sh dart
|
cd ./open-api && bash ./bin/generate-open-api.sh dart
|
||||||
|
|
||||||
open-api-dart-dio:
|
open-api-dart-2:
|
||||||
cd ./open-api && bash ./bin/generate-open-api.sh dart-dio
|
cd ./open-api && bash ./bin/generate-open-api.sh dart-2
|
||||||
|
|
||||||
open-api-typescript:
|
open-api-typescript:
|
||||||
cd ./open-api && bash ./bin/generate-open-api.sh typescript
|
cd ./open-api && bash ./bin/generate-open-api.sh typescript
|
||||||
|
@ -127,7 +127,14 @@ class LoginService with LogMixin {
|
|||||||
/// Set token to interceptor
|
/// Set token to interceptor
|
||||||
await di<ImmichApiClient>().init(accessToken: accessToken);
|
await di<ImmichApiClient>().init(accessToken: accessToken);
|
||||||
|
|
||||||
final user = await di<UserService>().getMyUser();
|
final user = await di<UserService>().getMyUser().timeout(
|
||||||
|
const Duration(seconds: 10),
|
||||||
|
// ignore: function-always-returns-null
|
||||||
|
onTimeout: () {
|
||||||
|
log.w("Timedout while fetching user details using saved credentials");
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
@ -66,53 +64,6 @@ class ImmichApiClient extends ApiClient with LogMixin {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore: avoid-dynamic
|
|
||||||
static dynamic _patchDto(dynamic value, String targetType) {
|
|
||||||
switch (targetType) {
|
|
||||||
case 'UserPreferencesResponseDto':
|
|
||||||
if (value is Map && value['rating'] == null) {
|
|
||||||
value['rating'] = RatingResponse().toJson();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore: avoid-dynamic
|
|
||||||
static dynamic fromJson(
|
|
||||||
// ignore: avoid-dynamic
|
|
||||||
dynamic value,
|
|
||||||
String targetType, {
|
|
||||||
bool growable = false,
|
|
||||||
}) {
|
|
||||||
_patchDto(value, targetType);
|
|
||||||
return ApiClient.fromJson(value, targetType, growable: growable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
// ignore: avoid-dynamic
|
|
||||||
Future<dynamic> deserializeAsync(
|
|
||||||
String value,
|
|
||||||
String targetType, {
|
|
||||||
bool growable = false,
|
|
||||||
}) =>
|
|
||||||
deserialize(value, targetType, growable: growable);
|
|
||||||
|
|
||||||
@override
|
|
||||||
// ignore: avoid-dynamic
|
|
||||||
Future<dynamic> deserialize(
|
|
||||||
String value,
|
|
||||||
String targetType, {
|
|
||||||
bool growable = false,
|
|
||||||
}) async {
|
|
||||||
targetType = targetType.replaceAll(' ', '');
|
|
||||||
return targetType == 'String'
|
|
||||||
? value
|
|
||||||
: fromJson(
|
|
||||||
await compute((String j) => json.decode(j), value),
|
|
||||||
targetType,
|
|
||||||
growable: growable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UsersApi getUsersApi() => UsersApi(this);
|
UsersApi getUsersApi() => UsersApi(this);
|
||||||
ServerApi getServerApi() => ServerApi(this);
|
ServerApi getServerApi() => ServerApi(this);
|
||||||
AuthenticationApi getAuthenticationApi() => AuthenticationApi(this);
|
AuthenticationApi getAuthenticationApi() => AuthenticationApi(this);
|
||||||
|
53
mobile-v2/lib/utils/openapi_patching.dart
Normal file
53
mobile-v2/lib/utils/openapi_patching.dart
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// ignore_for_file: avoid-dynamic, avoid-unsafe-collection-methods
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
|
dynamic upgradeDto(dynamic value, String targetType) {
|
||||||
|
switch (targetType) {
|
||||||
|
case 'UserPreferencesResponseDto':
|
||||||
|
if (value is Map) {
|
||||||
|
addDefault(value, 'download.includeEmbeddedVideos', false);
|
||||||
|
addDefault(value, 'folders', FoldersResponse().toJson());
|
||||||
|
addDefault(value, 'memories', MemoriesResponse().toJson());
|
||||||
|
addDefault(value, 'ratings', RatingsResponse().toJson());
|
||||||
|
addDefault(value, 'people', PeopleResponse().toJson());
|
||||||
|
addDefault(value, 'tags', TagsResponse().toJson());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ServerConfigDto':
|
||||||
|
if (value is Map) {
|
||||||
|
addDefault(
|
||||||
|
value,
|
||||||
|
'mapLightStyleUrl',
|
||||||
|
'https://tiles.immich.cloud/v1/style/light.json',
|
||||||
|
);
|
||||||
|
addDefault(
|
||||||
|
value,
|
||||||
|
'mapDarkStyleUrl',
|
||||||
|
'https://tiles.immich.cloud/v1/style/dark.json',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case 'UserResponseDto' || 'UserAdminResponseDto':
|
||||||
|
if (value is Map) {
|
||||||
|
addDefault(value, 'profileChangedAt', DateTime.now().toIso8601String());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addDefault(dynamic value, String keys, dynamic defaultValue) {
|
||||||
|
// Loop through the keys and assign the default value if the key is not present
|
||||||
|
List<String> keyList = keys.split('.');
|
||||||
|
dynamic current = value;
|
||||||
|
|
||||||
|
for (int i = 0; i < keyList.length - 1; i++) {
|
||||||
|
if (current[keyList[i]] == null) {
|
||||||
|
current[keyList[i]] = {};
|
||||||
|
}
|
||||||
|
current = current[keyList[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current[keyList.last] == null) {
|
||||||
|
current[keyList.last] = defaultValue;
|
||||||
|
}
|
||||||
|
}
|
@ -56,11 +56,6 @@ dependencies:
|
|||||||
openapi:
|
openapi:
|
||||||
path: openapi
|
path: openapi
|
||||||
|
|
||||||
dependency_overrides:
|
|
||||||
# openapi uses an older version of http for backward compatibility. New versions do not have
|
|
||||||
# a breaking change so it is safer to override it and use the latest version for the app
|
|
||||||
http: ^1.2.1
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
@ -22,18 +22,19 @@ function dart {
|
|||||||
rm ../mobile/openapi/analysis_options.yaml
|
rm ../mobile/openapi/analysis_options.yaml
|
||||||
}
|
}
|
||||||
|
|
||||||
function dartDio {
|
function dart2 {
|
||||||
rm -rf ../mobile-v2/openapi
|
rm -rf ../mobile-v2/openapi
|
||||||
cd ./templates/mobile-v2/serialization/native
|
cd ./templates/mobile/serialization/native
|
||||||
wget -O native_class.mustache https://raw.githubusercontent.com/OpenAPITools/openapi-generator/$OPENAPI_GENERATOR_VERSION/modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache
|
wget -O native_class.mustache https://raw.githubusercontent.com/OpenAPITools/openapi-generator/$OPENAPI_GENERATOR_VERSION/modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache
|
||||||
patch --no-backup-if-mismatch -u native_class.mustache < native_class.mustache.patch
|
patch --no-backup-if-mismatch -u native_class.mustache < native_class.mustache.patch
|
||||||
cd ../../../../
|
cd ../../../../
|
||||||
|
|
||||||
npx --yes @openapitools/openapi-generator-cli generate -g dart -i ./immich-openapi-specs.json -o ../mobile-v2/openapi -t ./templates/mobile-v2
|
npx --yes @openapitools/openapi-generator-cli generate -g dart -i ./immich-openapi-specs.json -o ../mobile-v2/openapi -t ./templates/mobile
|
||||||
|
|
||||||
# Post generate patches
|
# Post generate patches
|
||||||
patch --no-backup-if-mismatch -u ../mobile-v2/openapi/lib/api_client.dart <./patch/api_client.dart.patch
|
patch --no-backup-if-mismatch -u ../mobile-v2/openapi/lib/api_client.dart < ./patch/api_client.dart.patch
|
||||||
patch --no-backup-if-mismatch -u ../mobile-v2/openapi/lib/api.dart <./patch/api-v2.dart.patch
|
patch --no-backup-if-mismatch -u ../mobile-v2/openapi/lib/api.dart < ./patch/api.dart.patch
|
||||||
|
patch --no-backup-if-mismatch -u ../mobile-v2/openapi/pubspec.yaml < ./patch/pubspec_immich_mobile.yaml.patch
|
||||||
# Don't include analysis_options.yaml for the generated openapi files
|
# Don't include analysis_options.yaml for the generated openapi files
|
||||||
# so that language servers can properly exclude the mobile/openapi directory
|
# so that language servers can properly exclude the mobile/openapi directory
|
||||||
rm ../mobile-v2/openapi/analysis_options.yaml
|
rm ../mobile-v2/openapi/analysis_options.yaml
|
||||||
@ -49,8 +50,8 @@ npm run sync:open-api --prefix=../server
|
|||||||
|
|
||||||
if [[ $1 == 'dart' ]]; then
|
if [[ $1 == 'dart' ]]; then
|
||||||
dart
|
dart
|
||||||
elif [[ $1 == 'dart-dio' ]]; then
|
elif [[ $1 == 'dart-2' ]]; then
|
||||||
dartDio
|
dart2
|
||||||
elif [[ $1 == 'typescript' ]]; then
|
elif [[ $1 == 'typescript' ]]; then
|
||||||
typescript
|
typescript
|
||||||
else
|
else
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
--- native_class.mustache 2023-08-31 23:09:59.584269162 +0200
|
|
||||||
+++ native_class1.mustache 2023-08-31 22:59:53.633083270 +0200
|
|
||||||
@@ -91,14 +91,14 @@
|
|
||||||
{{/isDateTime}}
|
|
||||||
{{#isNullable}}
|
|
||||||
} else {
|
|
||||||
- json[r'{{{baseName}}}'] = null;
|
|
||||||
+ // json[r'{{{baseName}}}'] = null;
|
|
||||||
}
|
|
||||||
{{/isNullable}}
|
|
||||||
{{^isNullable}}
|
|
||||||
{{^required}}
|
|
||||||
{{^defaultValue}}
|
|
||||||
} else {
|
|
||||||
- json[r'{{{baseName}}}'] = null;
|
|
||||||
+ // json[r'{{{baseName}}}'] = null;
|
|
||||||
}
|
|
||||||
{{/defaultValue}}
|
|
||||||
{{/required}}
|
|
||||||
@@ -114,17 +114,6 @@
|
|
||||||
if (value is Map) {
|
|
||||||
final json = value.cast<String, dynamic>();
|
|
||||||
|
|
||||||
- // Ensure that the map contains the required keys.
|
|
||||||
- // Note 1: the values aren't checked for validity beyond being non-null.
|
|
||||||
- // Note 2: this code is stripped in release mode!
|
|
||||||
- assert(() {
|
|
||||||
- requiredKeys.forEach((key) {
|
|
||||||
- assert(json.containsKey(key), 'Required key "{{{classname}}}[$key]" is missing from JSON.');
|
|
||||||
- assert(json[key] != null, 'Required key "{{{classname}}}[$key]" has a null value in JSON.');
|
|
||||||
- });
|
|
||||||
- return true;
|
|
||||||
- }());
|
|
||||||
-
|
|
||||||
return {{{classname}}}(
|
|
||||||
{{#vars}}
|
|
||||||
{{#isDateTime}}
|
|
||||||
@@ -215,6 +204,10 @@
|
|
||||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
|
||||||
: {{{datatypeWithEnum}}}.parse(json[r'{{{baseName}}}'].toString()),
|
|
||||||
{{/isNumber}}
|
|
||||||
+ {{#isDouble}}
|
|
||||||
+ {{{name}}}: (mapValueOfType<num>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}).toDouble(),
|
|
||||||
+ {{/isDouble}}
|
|
||||||
+ {{^isDouble}}
|
|
||||||
{{^isNumber}}
|
|
||||||
{{^isEnum}}
|
|
||||||
{{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
|
||||||
@@ -223,6 +216,7 @@
|
|
||||||
{{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
|
||||||
{{/isEnum}}
|
|
||||||
{{/isNumber}}
|
|
||||||
+ {{/isDouble}}
|
|
||||||
{{/isMap}}
|
|
||||||
{{/isArray}}
|
|
||||||
{{/complexType}}
|
|
Loading…
x
Reference in New Issue
Block a user