mirror of
https://github.com/immich-app/immich.git
synced 2026-06-04 05:05:22 -04:00
bump to v7.22.0 and update patching
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:immich_mobile/utils/openapi_patching.dart';
|
||||
|
||||
void main() {
|
||||
group('Test OpenApi Patching', () {
|
||||
test('upgradeDto', () {
|
||||
dynamic value;
|
||||
String targetType;
|
||||
|
||||
targetType = 'UserPreferencesResponseDto';
|
||||
value = jsonDecode("""
|
||||
{
|
||||
"download": {
|
||||
"archiveSize": 4294967296,
|
||||
"includeEmbeddedVideos": false
|
||||
}
|
||||
}
|
||||
""");
|
||||
|
||||
upgradeDto(value, targetType);
|
||||
expect(value['tags'], TagsResponse(enabled: false, sidebarWeb: false).toJson());
|
||||
expect(value['download']['includeEmbeddedVideos'], false);
|
||||
});
|
||||
|
||||
test('addDefault', () {
|
||||
dynamic value = jsonDecode("""
|
||||
{
|
||||
"download": {
|
||||
"archiveSize": 4294967296,
|
||||
"includeEmbeddedVideos": false
|
||||
}
|
||||
}
|
||||
""");
|
||||
String keys = 'download.unknownKey';
|
||||
dynamic defaultValue = 69420;
|
||||
|
||||
addDefault(value, keys, defaultValue);
|
||||
expect(value['download']['unknownKey'], 69420);
|
||||
|
||||
keys = 'alpha.beta';
|
||||
defaultValue = 'gamma';
|
||||
addDefault(value, keys, defaultValue);
|
||||
expect(value['alpha']['beta'], 'gamma');
|
||||
});
|
||||
|
||||
test('addDefault with null', () {
|
||||
dynamic value = jsonDecode("""
|
||||
{
|
||||
"download": {
|
||||
"archiveSize": 4294967296,
|
||||
"includeEmbeddedVideos": false
|
||||
}
|
||||
}
|
||||
""");
|
||||
expect(value['download']['unknownKey'], isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,28 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
OPENAPI_GENERATOR_VERSION=v7.12.0
|
||||
OPENAPI_GENERATOR_VERSION=v7.22.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# usage: ./bin/generate-dart-sdk.sh
|
||||
|
||||
rm -rf ../mobile/openapi
|
||||
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
|
||||
patch --no-backup-if-mismatch -u native_class.mustache <native_class.mustache.patch
|
||||
patch --no-backup-if-mismatch -u native_class.mustache <native_class_nullable_items_in_arrays.patch
|
||||
cd ./templates/mobile
|
||||
|
||||
mkdir -p serialization/native
|
||||
wget -O serialization/native/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 serialization/native/native_class.mustache <../../patch/native_class.mustache.patch
|
||||
|
||||
cd ../../
|
||||
wget -O api.mustache https://raw.githubusercontent.com/OpenAPITools/openapi-generator/$OPENAPI_GENERATOR_VERSION/modules/openapi-generator/src/main/resources/dart2/api.mustache
|
||||
patch --no-backup-if-mismatch -u api.mustache <api.mustache.patch
|
||||
|
||||
cd ../../
|
||||
pnpm dlx --allow-build="" @openapitools/openapi-generator-cli generate -g dart -i ./immich-openapi-specs.json -o ../mobile/openapi -t ./templates/mobile
|
||||
pnpm dlx --allow-build="" @openapitools/openapi-generator-cli generate -g dart -i ./immich-openapi-specs.json -o ../mobile/openapi -t ./templates/mobile --additional-properties=useOptional=true
|
||||
|
||||
# Post generate patches
|
||||
patch --no-backup-if-mismatch -u ../mobile/openapi/lib/api_client.dart <./patch/api_client.dart.patch
|
||||
patch --no-backup-if-mismatch -u ../mobile/openapi/lib/api.dart <./patch/api.dart.patch
|
||||
patch --no-backup-if-mismatch -u ../mobile/openapi/pubspec.yaml <./patch/pubspec_immich_mobile.yaml.patch
|
||||
patch --no-backup-if-mismatch -u ../mobile/openapi/lib/model/asset_edit_action_item_dto.dart <./patch/asset_edit_action_item_dto.dart.patch
|
||||
patch --no-backup-if-mismatch -u ../mobile/openapi/lib/model/time_bucket_asset_response_dto.dart <./patch/time_bucket_asset_response_dto.dart.patch
|
||||
# Don't include analysis_options.yaml for the generated openapi files
|
||||
# so that language servers can properly exclude the mobile/openapi directory
|
||||
rm ../mobile/openapi/analysis_options.yaml
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
|
||||
"spaces": 2,
|
||||
"generator-cli": {
|
||||
"version": "7.8.0"
|
||||
"version": "7.22.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@@ -15,6 +15,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
+import 'package:flutter/foundation.dart';
|
||||
+import 'package:immich_mobile/utils/openapi_patching.dart';
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
@@ -143,19 +143,19 @@
|
||||
);
|
||||
}
|
||||
|
||||
- Future<dynamic> deserializeAsync(String value, String targetType, {bool growable = false,}) async =>
|
||||
+ Future<dynamic> deserializeAsync(String value, String targetType, {bool growable = false,}) =>
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
deserialize(value, targetType, growable: growable);
|
||||
|
||||
@Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.')
|
||||
- dynamic deserialize(String value, String targetType, {bool growable = false,}) {
|
||||
+ Future<dynamic> deserialize(String value, String targetType, {bool growable = false,}) async {
|
||||
// Remove all spaces. Necessary for regular expressions as well.
|
||||
targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments
|
||||
|
||||
// If the expected target type is String, nothing to do...
|
||||
return targetType == 'String'
|
||||
? value
|
||||
- : fromJson(json.decode(value), targetType, growable: growable);
|
||||
+ : fromJson(await compute((String j) => json.decode(j), value), targetType, growable: growable);
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
@@ -154,6 +154,7 @@
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static {{{classname}}}? fromJson(dynamic value) {
|
||||
+ upgradeDto(value, "{{{classname}}}");
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
@@ -195,48 +196,98 @@
|
||||
{{#complexType}}
|
||||
{{#isArray}}
|
||||
{{#items.isArray}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(json[r'{{{baseName}}}'] is List
|
||||
+ ? (json[r'{{{baseName}}}'] as List).map((e) =>
|
||||
+ {{#items.complexType}}
|
||||
+ e == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.complexType}}>[]{{/items.isNullable}} : {{items.complexType}}.listFromJson(e){{#uniqueItems}}.toSet(){{/uniqueItems}}
|
||||
+ {{/items.complexType}}
|
||||
+ {{^items.complexType}}
|
||||
+ e == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}>[]{{/items.isNullable}} : (e as List).map((value) => value as {{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}).toList(growable: false)
|
||||
+ {{/items.complexType}}
|
||||
+ ).toList()
|
||||
+ : {{#isNullable}}null{{/isNullable}}{{^isNullable}}const []{{/isNullable}}) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: json[r'{{{baseName}}}'] is List
|
||||
? (json[r'{{{baseName}}}'] as List).map((e) =>
|
||||
{{#items.complexType}}
|
||||
- {{items.complexType}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}}
|
||||
+ e == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.complexType}}>[]{{/items.isNullable}} : {{items.complexType}}.listFromJson(e){{#uniqueItems}}.toSet(){{/uniqueItems}}
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
- e == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}>[]{{/items.isNullable}} : (e as List).cast<{{items.items.dataType}}>()
|
||||
+ e == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}>[]{{/items.isNullable}} : (e as List).map((value) => value as {{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}).toList(growable: false)
|
||||
{{/items.complexType}}
|
||||
).toList()
|
||||
: {{#isNullable}}null{{/isNullable}}{{^isNullable}}const []{{/isNullable}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.isArray}}
|
||||
{{^items.isArray}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present({{{complexType}}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}}) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: {{{complexType}}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.isArray}}
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#isMap}}
|
||||
{{#items.isArray}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(json[r'{{{baseName}}}'] == null ? null
|
||||
+ {{#items.complexType}}
|
||||
+ : {{items.complexType}}.mapListFromJson(json[r'{{{baseName}}}'])) : const Optional.absent(),
|
||||
+ {{/items.complexType}}
|
||||
+ {{^items.complexType}}
|
||||
+ : (json[r'{{{baseName}}}'] as Map<String, dynamic>).map((k, v) => MapEntry(k, v == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}>[]{{/items.isNullable}} : (v as List).map((value) => value as {{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}).toList(growable: false)))) : const Optional.absent(),
|
||||
+ {{/items.complexType}}
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: json[r'{{{baseName}}}'] == null
|
||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||
- {{#items.complexType}}
|
||||
+ {{#items.complexType}}
|
||||
: {{items.complexType}}.mapListFromJson(json[r'{{{baseName}}}']),
|
||||
- {{/items.complexType}}
|
||||
- {{^items.complexType}}
|
||||
- : (json[r'{{{baseName}}}'] as Map<String, dynamic>).map((k, v) => MapEntry(k, v == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}>[]{{/items.isNullable}} : (v as List).cast<{{items.items.dataType}}>())),
|
||||
- {{/items.complexType}}
|
||||
+ {{/items.complexType}}
|
||||
+ {{^items.complexType}}
|
||||
+ : (json[r'{{{baseName}}}'] as Map<String, dynamic>).map((k, v) => MapEntry(k, v == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}>[]{{/items.isNullable}} : (v as List).map((value) => value as {{items.items.dataType}}{{#items.items.isNullable}}?{{/items.items.isNullable}}).toList(growable: false))),
|
||||
+ {{/items.complexType}}
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.isArray}}
|
||||
{{^items.isArray}}
|
||||
{{#items.isMap}}
|
||||
{{#items.complexType}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present({{items.complexType}}.mapFromJson(json[r'{{{baseName}}}'])) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: {{items.complexType}}.mapFromJson(json[r'{{{baseName}}}']),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(mapCastOfType<String, dynamic>(json, r'{{{baseName}}}')) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: mapCastOfType<String, dynamic>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.complexType}}
|
||||
{{/items.isMap}}
|
||||
{{^items.isMap}}
|
||||
{{#items.complexType}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present({{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}'])) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: {{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}']),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(mapCastOfType<String, {{items.dataType}}>(json, r'{{{baseName}}}')) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: mapCastOfType<String, {{items.dataType}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/items.complexType}}
|
||||
{{/items.isMap}}
|
||||
{{/items.isArray}}
|
||||
@@ -259,23 +310,45 @@
|
||||
{{^complexType}}
|
||||
{{#isArray}}
|
||||
{{#isEnum}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present({{{items.datatypeWithEnum}}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}}) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: {{{items.datatypeWithEnum}}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(json[r'{{{baseName}}}'] is Iterable
|
||||
+ ? (json[r'{{{baseName}}}'] as Iterable).cast<{{{items.datatype}}}>().{{#uniqueItems}}toSet(){{/uniqueItems}}{{^uniqueItems}}toList(growable: false){{/uniqueItems}}
|
||||
+ : {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: json[r'{{{baseName}}}'] is Iterable
|
||||
? (json[r'{{{baseName}}}'] as Iterable).cast<{{{items.datatype}}}>().{{#uniqueItems}}toSet(){{/uniqueItems}}{{^uniqueItems}}toList(growable: false){{/uniqueItems}}
|
||||
: {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/isEnum}}
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#isMap}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(mapCastOfType<String, {{{items.datatype}}}>(json, r'{{{baseName}}}')) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: mapCastOfType<String, {{{items.datatype}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/isMap}}
|
||||
{{^isMap}}
|
||||
{{#isNumber}}
|
||||
+ {{#vendorExtensions.x-is-optional}}
|
||||
+ {{{name}}}: json.containsKey(r'{{{baseName}}}') ? Optional.present(json[r'{{{baseName}}}'] == null ? null : num.parse('${json[r'{{{baseName}}}']}')) : const Optional.absent(),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
+ {{^vendorExtensions.x-is-optional}}
|
||||
{{{name}}}: {{#isNullable}}json[r'{{{baseName}}}'] == null
|
||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||
: {{/isNullable}}{{{datatypeWithEnum}}}.parse('${json[r'{{{baseName}}}']}'),
|
||||
+ {{/vendorExtensions.x-is-optional}}
|
||||
{{/isNumber}}
|
||||
{{^isNumber}}
|
||||
{{#vendorExtensions.x-original-is-integer}}
|
||||
@@ -0,0 +1,9 @@
|
||||
@@ -83,7 +83,7 @@
|
||||
List<num> ratio;
|
||||
|
||||
/// Array of stack information as [stackId, assetCount] tuples (null for non-stacked assets)
|
||||
- Optional<List<List<String>>?> stack;
|
||||
+ Optional<List<List<String>?>?> stack;
|
||||
|
||||
/// Array of BlurHash strings for generating asset previews (base64 encoded)
|
||||
List<String> thumbhash;
|
||||
@@ -1,5 +1,6 @@
|
||||
{{>header}}
|
||||
{{>part_of}}
|
||||
|
||||
{{#operations}}
|
||||
|
||||
class {{{classname}}} {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
--- api.mustache 2025-01-22 05:50:25
|
||||
+++ api.mustache.modified 2025-01-22 05:52:23
|
||||
@@ -51,7 +51,7 @@
|
||||
{{/allParams}}
|
||||
Future<Response> {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async {
|
||||
|
||||
@@ -1,296 +0,0 @@
|
||||
class {{{classname}}} {
|
||||
{{>dart_constructor}}
|
||||
{{#vars}}
|
||||
{{#description}}
|
||||
/// {{{.}}}
|
||||
{{/description}}
|
||||
{{^isEnum}}
|
||||
{{#minimum}}
|
||||
{{#description}}
|
||||
///
|
||||
{{/description}}
|
||||
/// Minimum value: {{{.}}}
|
||||
{{/minimum}}
|
||||
{{#maximum}}
|
||||
{{#description}}
|
||||
{{^minimum}}
|
||||
///
|
||||
{{/minimum}}
|
||||
{{/description}}
|
||||
/// Maximum value: {{{.}}}
|
||||
{{/maximum}}
|
||||
{{^isNullable}}
|
||||
{{^required}}
|
||||
{{^defaultValue}}
|
||||
///
|
||||
/// Please note: 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.
|
||||
///
|
||||
{{/defaultValue}}
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{/isEnum}}
|
||||
{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}<{{{items.dataType}}}{{#items.isNullable}}?{{/items.isNullable}}>{{/isArray}}{{^isArray}}{{{datatypeWithEnum}}}{{/isArray}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isNullable}} {{{name}}};
|
||||
|
||||
{{/vars}}
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is {{{classname}}} &&
|
||||
{{#vars}}
|
||||
{{#isMap}}_deepEquality.equals(other.{{{name}}}, {{{name}}}){{/isMap}}{{^isMap}}{{#isArray}}_deepEquality.equals(other.{{{name}}}, {{{name}}}){{/isArray}}{{^isArray}}other.{{{name}}} == {{{name}}}{{/isArray}}{{/isMap}}{{^-last}} &&{{/-last}}{{#-last}};{{/-last}}
|
||||
{{/vars}}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
{{#vars}}
|
||||
({{#isNullable}}{{{name}}} == null ? 0 : {{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}{{{name}}} == null ? 0 : {{/defaultValue}}{{/required}}{{/isNullable}}{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.hashCode){{^-last}} +{{/-last}}{{#-last}};{{/-last}}
|
||||
{{/vars}}
|
||||
|
||||
@override
|
||||
String toString() => '{{{classname}}}[{{#vars}}{{{name}}}=${{{name}}}{{^-last}}, {{/-last}}{{/vars}}]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
{{#vars}}
|
||||
{{#isNullable}}
|
||||
if (this.{{{name}}} != null) {
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
{{^required}}
|
||||
{{^defaultValue}}
|
||||
if (this.{{{name}}} != null) {
|
||||
{{/defaultValue}}
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{#isDateTime}}
|
||||
{{#pattern}}
|
||||
json[r'{{{baseName}}}'] = _isEpochMarker(r'{{{pattern}}}')
|
||||
? this.{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.millisecondsSinceEpoch
|
||||
: this.{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.toUtc().toIso8601String();
|
||||
{{/pattern}}
|
||||
{{^pattern}}
|
||||
json[r'{{{baseName}}}'] = this.{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.toUtc().toIso8601String();
|
||||
{{/pattern}}
|
||||
{{/isDateTime}}
|
||||
{{#isDate}}
|
||||
{{#pattern}}
|
||||
json[r'{{{baseName}}}'] = _isEpochMarker(r'{{{pattern}}}')
|
||||
? this.{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.millisecondsSinceEpoch
|
||||
: _dateFormatter.format(this.{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.toUtc());
|
||||
{{/pattern}}
|
||||
{{^pattern}}
|
||||
json[r'{{{baseName}}}'] = _dateFormatter.format(this.{{{name}}}{{#isNullable}}!{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}!{{/defaultValue}}{{/required}}{{/isNullable}}.toUtc());
|
||||
{{/pattern}}
|
||||
{{/isDate}}
|
||||
{{^isDateTime}}
|
||||
{{^isDate}}
|
||||
json[r'{{{baseName}}}'] = this.{{{name}}}{{#isArray}}{{#uniqueItems}}{{#isNullable}}!{{/isNullable}}.toList(growable: false){{/uniqueItems}}{{/isArray}};
|
||||
{{/isDate}}
|
||||
{{/isDateTime}}
|
||||
{{#isNullable}}
|
||||
} else {
|
||||
// json[r'{{{baseName}}}'] = null;
|
||||
}
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
{{^required}}
|
||||
{{^defaultValue}}
|
||||
} else {
|
||||
// json[r'{{{baseName}}}'] = null;
|
||||
}
|
||||
{{/defaultValue}}
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{/vars}}
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [{{{classname}}}] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static {{{classname}}}? fromJson(dynamic value) {
|
||||
upgradeDto(value, "{{{classname}}}");
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return {{{classname}}}(
|
||||
{{#vars}}
|
||||
{{#isDateTime}}
|
||||
{{{name}}}: mapDateTime(json, r'{{{baseName}}}', r'{{{pattern}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isDateTime}}
|
||||
{{#isDate}}
|
||||
{{{name}}}: mapDateTime(json, r'{{{baseName}}}', r'{{{pattern}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isDate}}
|
||||
{{^isDateTime}}
|
||||
{{^isDate}}
|
||||
{{#complexType}}
|
||||
{{#isArray}}
|
||||
{{#items.isArray}}
|
||||
{{{name}}}: json[r'{{{baseName}}}'] is List
|
||||
? (json[r'{{{baseName}}}'] as List).map((e) =>
|
||||
{{#items.complexType}}
|
||||
{{items.complexType}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}}
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
e == null ? {{#items.isNullable}}null{{/items.isNullable}}{{^items.isNullable}}const <{{items.items.dataType}}>[]{{/items.isNullable}} : (e as List).cast<{{items.items.dataType}}>()
|
||||
{{/items.complexType}}
|
||||
).toList()
|
||||
: {{#isNullable}}null{{/isNullable}}{{^isNullable}}const []{{/isNullable}},
|
||||
{{/items.isArray}}
|
||||
{{^items.isArray}}
|
||||
{{{name}}}: {{{complexType}}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}},
|
||||
{{/items.isArray}}
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#isMap}}
|
||||
{{#items.isArray}}
|
||||
{{{name}}}: json[r'{{{baseName}}}'] == null
|
||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||
{{#items.complexType}}
|
||||
: {{items.complexType}}.mapListFromJson(json[r'{{{baseName}}}']),
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
: mapCastOfType<String, List>(json, r'{{{baseName}}}'),
|
||||
{{/items.complexType}}
|
||||
{{/items.isArray}}
|
||||
{{^items.isArray}}
|
||||
{{#items.isMap}}
|
||||
{{#items.complexType}}
|
||||
{{{name}}}: {{items.complexType}}.mapFromJson(json[r'{{{baseName}}}']),
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
{{{name}}}: mapCastOfType<String, dynamic>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/items.complexType}}
|
||||
{{/items.isMap}}
|
||||
{{^items.isMap}}
|
||||
{{#items.complexType}}
|
||||
{{{name}}}: {{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}']),
|
||||
{{/items.complexType}}
|
||||
{{^items.complexType}}
|
||||
{{{name}}}: mapCastOfType<String, {{items.dataType}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/items.complexType}}
|
||||
{{/items.isMap}}
|
||||
{{/items.isArray}}
|
||||
{{/isMap}}
|
||||
{{^isMap}}
|
||||
{{#isBinary}}
|
||||
{{{name}}}: null, // No support for decoding binary content from JSON
|
||||
{{/isBinary}}
|
||||
{{^isBinary}}
|
||||
{{{name}}}: {{{complexType}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isBinary}}
|
||||
{{/isMap}}
|
||||
{{/isArray}}
|
||||
{{/complexType}}
|
||||
{{^complexType}}
|
||||
{{#isArray}}
|
||||
{{#isEnum}}
|
||||
{{{name}}}: {{{items.datatypeWithEnum}}}.listFromJson(json[r'{{{baseName}}}']){{#uniqueItems}}.toSet(){{/uniqueItems}},
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{{name}}}: json[r'{{{baseName}}}'] is Iterable
|
||||
? (json[r'{{{baseName}}}'] as Iterable).cast<{{{items.datatype}}}>().{{#uniqueItems}}toSet(){{/uniqueItems}}{{^uniqueItems}}toList(growable: false){{/uniqueItems}}
|
||||
: {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}},
|
||||
{{/isEnum}}
|
||||
{{/isArray}}
|
||||
{{^isArray}}
|
||||
{{#isMap}}
|
||||
{{{name}}}: mapCastOfType<String, {{{items.datatype}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isMap}}
|
||||
{{^isMap}}
|
||||
{{#isNumber}}
|
||||
{{{name}}}: {{#isNullable}}json[r'{{{baseName}}}'] == null
|
||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||
: {{/isNullable}}{{{datatypeWithEnum}}}.parse('${json[r'{{{baseName}}}']}'),
|
||||
{{/isNumber}}
|
||||
{{#isDouble}}
|
||||
{{{name}}}: (mapValueOfType<num>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}){{#isNullable}}?{{/isNullable}}.toDouble(),
|
||||
{{/isDouble}}
|
||||
{{^isDouble}}
|
||||
{{^isNumber}}
|
||||
{{^isEnum}}
|
||||
{{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isEnum}}
|
||||
{{#isEnum}}
|
||||
{{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isEnum}}
|
||||
{{/isNumber}}
|
||||
{{/isDouble}}
|
||||
{{/isMap}}
|
||||
{{/isArray}}
|
||||
{{/complexType}}
|
||||
{{/isDate}}
|
||||
{{/isDateTime}}
|
||||
{{/vars}}
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<{{{classname}}}> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <{{{classname}}}>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = {{{classname}}}.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, {{{classname}}}> mapFromJson(dynamic json) {
|
||||
final map = <String, {{{classname}}}>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = {{{classname}}}.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of {{{classname}}}-objects as value to a dart map
|
||||
static Map<String, List<{{{classname}}}>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<{{{classname}}}>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = {{{classname}}}.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
{{#vars}}
|
||||
{{#required}}
|
||||
'{{{baseName}}}',
|
||||
{{/required}}
|
||||
{{/vars}}
|
||||
};
|
||||
}
|
||||
{{#vars}}
|
||||
{{^isModel}}
|
||||
{{#isEnum}}
|
||||
{{^isContainer}}
|
||||
|
||||
{{>serialization/native/native_enum_inline}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#mostInnerItems}}
|
||||
|
||||
{{>serialization/native/native_enum_inline}}
|
||||
{{/mostInnerItems}}
|
||||
{{/isContainer}}
|
||||
{{/isEnum}}
|
||||
{{/isModel}}
|
||||
{{/vars}}
|
||||
@@ -1,60 +0,0 @@
|
||||
--- native_class.mustache 2025-07-01 08:29:23.968133163 +0800
|
||||
+++ native_class_temp.mustache 2025-07-01 08:29:44.225850583 +0800
|
||||
@@ -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}}
|
||||
@@ -111,20 +111,10 @@
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static {{{classname}}}? fromJson(dynamic value) {
|
||||
+ upgradeDto(value, "{{{classname}}}");
|
||||
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 +205,10 @@
|
||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||
: {{/isNullable}}{{{datatypeWithEnum}}}.parse('${json[r'{{{baseName}}}']}'),
|
||||
{{/isNumber}}
|
||||
+ {{#isDouble}}
|
||||
+ {{{name}}}: (mapValueOfType<num>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}){{#isNullable}}?{{/isNullable}}.toDouble(),
|
||||
+ {{/isDouble}}
|
||||
+ {{^isDouble}}
|
||||
{{^isNumber}}
|
||||
{{^isEnum}}
|
||||
{{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
@@ -223,6 +217,7 @@
|
||||
{{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||
{{/isEnum}}
|
||||
{{/isNumber}}
|
||||
+ {{/isDouble}}
|
||||
{{/isMap}}
|
||||
{{/isArray}}
|
||||
{{/complexType}}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
diff --git a/open-api/templates/mobile/serialization/native/native_class.mustache b/open-api/templates/mobile/serialization/native/native_class.mustache
|
||||
index 9a7b1439b..9f40d5b0b 100644
|
||||
--- a/open-api/templates/mobile/serialization/native/native_class.mustache
|
||||
+++ b/open-api/templates/mobile/serialization/native/native_class.mustache
|
||||
@@ -32,7 +32,7 @@ class {{{classname}}} {
|
||||
{{/required}}
|
||||
{{/isNullable}}
|
||||
{{/isEnum}}
|
||||
- {{{datatypeWithEnum}}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isNullable}} {{{name}}};
|
||||
+ {{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}<{{{items.dataType}}}{{#items.isNullable}}?{{/items.isNullable}}>{{/isArray}}{{^isArray}}{{{datatypeWithEnum}}}{{/isArray}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isNullable}} {{{name}}};
|
||||
|
||||
{{/vars}}
|
||||
@override
|
||||
Reference in New Issue
Block a user