diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4a6f161..7d63eb9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ # This is a basic workflow to help you get started with Actions -name: CI +name: Quality check # Controls when the action will run. on: @@ -13,10 +13,18 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: + # Reusable workflow call + workflow_call: + secrets: + CLIENT_ID: + required: true + CLIENT_SECRET: + required: true + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" - build: + check: # The type of runner that the job will run on runs-on: ubuntu-latest @@ -56,4 +64,12 @@ jobs: # package:test for this step to succeed. Note that Flutter projects will # want to change this to 'flutter test'. - name: Run tests - run: dart test \ No newline at end of file + run: dart test + + # The pub.dev site uses the analysis tool pana to calculate pub points. + # This is run automatically on the pub.dev site whenever you publish a new package, + # or a new version of an existing package. + - name: Calculating pub points prior to publishing + run: | + dart pub global activate pana + dart pub global run pana --exit-code-threshold 0 --json \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 94946b0..1f164b9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,37 +7,12 @@ on: # Publish using the reusable workflow from dart-lang. jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - uses: dart-lang/setup-dart@v1 - - - name: Install dependencies - run: dart pub get - - - name: Verify formatting - run: dart format -o none --set-exit-if-changed . - - - name: Analyze project source - run: dart analyze --fatal-infos - - - name: Make shell script write_credentials.sh executable - run: chmod +x .github/workflows/write_credentials.sh - - - name: Write down test credentials - run: ./.github/workflows/write_credentials.sh - env: - CLIENT_ID: ${{ secrets.CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }} - - - name: Run tests - run: dart test + check: + uses: ./.github/workflows/main.yml + secrets: inherit publish: - needs: build + needs: check permissions: id-token: write # Required for authentication using OIDC uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a3b45..5115eaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ +## 0.2.0 + +* Remove CN region (breaking change) +* Update documentation + ## 0.1.3+2 * Connection timeout parameter -* + ## 0.1.3+1 * battle_net_scope.dart exported diff --git a/README.md b/README.md index 4c27e9b..7642de7 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,6 @@ Locale support is limited to locations supported on Blizzard community game site | EU | Battle.net, WoW, D3, SC2 | | KR | Battle.net, WoW, D3, SC2 | | TW | Battle.net, WoW, D3, SC2 | -| CN | Battle.net, WoW, D3, SC2 | For example, ```dart @@ -148,7 +147,6 @@ locales vary from region to region and align with those supported on Blizzard co | Europe | https://eu.api.blizzard.com/ | en_GB, es_ES, fr_FR, ru_RU, de_DE, pt_PT, it_IT | | Korea | https://kr.api.blizzard.com/ | ko_KR | | Taiwan | https://tw.api.blizzard.com/ | zh_TW | -| China | https://gateway.battlenet.com.cn/ | zh_CN | For example, ```dart diff --git a/analysis_options.yaml b/analysis_options.yaml index 6de9eb7..c8008db 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -54,7 +54,6 @@ linter: - always_declare_return_types - always_put_control_body_on_new_line # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 - - always_require_non_null_named_parameters - always_specify_types # - always_use_package_imports # we do this commonly - annotate_overrides diff --git a/lib/src/battle_net.dart b/lib/src/battle_net.dart index 7e018f9..d9958ee 100644 --- a/lib/src/battle_net.dart +++ b/lib/src/battle_net.dart @@ -189,9 +189,7 @@ class BattleNet { 'Authorization': 'Bearer $accessToken', 'Battlenet-Namespace': '${namespace.name}-${region.slug}' }; - final String baseUrl = region == BattleNetRegion.cn - ? 'gateway.battlenet.com.cn' - : '${region.slug}.api.blizzard.com'; + final String baseUrl = '${region.slug}.api.blizzard.com'; final http.Request request = http.Request('GET', Uri.parse('https://$baseUrl/data/wow/token/?locale=${locale.name}')); request.headers.addAll(headers); diff --git a/lib/src/constants/battle_net_locale.dart b/lib/src/constants/battle_net_locale.dart index a24e1df..9a1b16a 100644 --- a/lib/src/constants/battle_net_locale.dart +++ b/lib/src/constants/battle_net_locale.dart @@ -13,7 +13,6 @@ enum BattleNetLocale { ruRU, koKR, zhTW, - zhCN, } /// [BattleNetLocale] query parameter mapper @@ -42,8 +41,6 @@ extension BattleNetLocaleExtension on BattleNetLocale { return 'ko_KR'; case BattleNetLocale.zhTW: return 'zh_TW'; - case BattleNetLocale.zhCN: - return 'zh_CN'; } } } diff --git a/lib/src/constants/battle_net_region.dart b/lib/src/constants/battle_net_region.dart index ecd478a..1b4c45f 100644 --- a/lib/src/constants/battle_net_region.dart +++ b/lib/src/constants/battle_net_region.dart @@ -6,7 +6,6 @@ enum BattleNetRegion { eu, kr, tw, - cn, } /// [BattleNetRegion] query and title parameters mapper @@ -21,8 +20,6 @@ extension BattleNetRegionExtension on BattleNetRegion { return 'kr'; case BattleNetRegion.tw: return 'tw'; - case BattleNetRegion.cn: - return 'cn'; } } @@ -36,8 +33,6 @@ extension BattleNetRegionExtension on BattleNetRegion { return 'Korea'; case BattleNetRegion.tw: return 'Taiwan'; - case BattleNetRegion.cn: - return 'China'; } } } diff --git a/lib/src/models/common/enum_values.dart b/lib/src/models/common/enum_values.dart index 6f5775a..3880526 100644 --- a/lib/src/models/common/enum_values.dart +++ b/lib/src/models/common/enum_values.dart @@ -1,10 +1,21 @@ -/// Class required to describe typed values +/// Utility class for mapping enum values to and from strings. +/// +/// This class provides functionality to map between enum values [T] and their +/// corresponding string representations. It accepts a [map] containing mappings +/// from string keys to enum values [T]. class EnumValues { + /// A map that associates string keys with enum values [T]. Map map; + + /// A late-initialized map that associates enum values [T] with their string keys. late Map reverseMap; + /// Constructs an [EnumValues] instance with a [map] of string keys to enum values [T]. EnumValues(this.map); + /// Returns a map that associates enum values [T] with their corresponding string keys. + /// + /// The [reverseMap] is constructed lazily from the [map] provided during initialization. Map get reverse { reverseMap = map.map((String k, T v) => MapEntry(v, k)); return reverseMap; diff --git a/lib/src/models/common/links.dart b/lib/src/models/common/links.dart index 3cc5426..c8c05f6 100644 --- a/lib/src/models/common/links.dart +++ b/lib/src/models/common/links.dart @@ -1,25 +1,48 @@ import 'dart:convert'; + import 'package:meta/meta.dart'; import 'self.dart'; -/// Request url confirmation holder data model +/// Represents the data model for holding request URL confirmations. +/// +/// This class is immutable and encapsulates a [self] instance of [Self] class +/// which represents a self-reference URL. @immutable class Links { + /// Constructs a [Links] instance. + /// + /// The [self] parameter is required and represents a self-reference URL instance. const Links({ required this.self, }); + /// The self-reference URL instance. final Self self; + /// Creates a [Links] instance from a raw JSON string [str]. + /// + /// Converts the JSON string into a map using [json.decode], and then constructs + /// a [Links] instance using [fromJson]. factory Links.fromRawJson(String str) => Links.fromJson(json.decode(str)); + /// Converts this [Links] instance to a raw JSON string representation. + /// + /// Converts the instance to a map using [toJson], and then encodes it to a JSON + /// string using [json.encode]. String toRawJson() => json.encode(toJson()); + /// Creates a [Links] instance from a JSON map [json]. + /// + /// Constructs a [Links] instance from a map retrieved from JSON, + /// extracting the [self] as a [Self] instance. factory Links.fromJson(Map json) => Links( self: Self.fromJson(json['self']), ); + /// Converts this [Links] instance to a JSON map. + /// + /// Converts the instance's [self] to a JSON-compatible format. Map toJson() => { 'self': self.toJson(), }; diff --git a/lib/src/models/common/self.dart b/lib/src/models/common/self.dart index 42d614a..f265415 100644 --- a/lib/src/models/common/self.dart +++ b/lib/src/models/common/self.dart @@ -1,23 +1,46 @@ import 'dart:convert'; + import 'package:meta/meta.dart'; -/// Request url confirmation data model +/// Represents the data model for a self-reference URL. +/// +/// This class is immutable and encapsulates a single string [href] representing +/// a URL that references itself. @immutable class Self { + /// Constructs a [Self] instance. + /// + /// The [href] parameter is required and represents the URL string. const Self({ required this.href, }); + /// The URL string that references itself. final String href; + /// Creates a [Self] instance from a raw JSON string [str]. + /// + /// Converts the JSON string into a map using [json.decode], and then constructs + /// a [Self] instance using [fromJson]. factory Self.fromRawJson(String str) => Self.fromJson(json.decode(str)); + /// Converts this [Self] instance to a raw JSON string representation. + /// + /// Converts the instance to a map using [toJson], and then encodes it to a JSON + /// string using [json.encode]. String toRawJson() => json.encode(toJson()); + /// Creates a [Self] instance from a JSON map [json]. + /// + /// Constructs a [Self] instance from a map retrieved from JSON, + /// extracting the [href] as a string. factory Self.fromJson(Map json) => Self( href: json['href'], ); + /// Converts this [Self] instance to a JSON map. + /// + /// Converts the instance's [href] directly to a JSON-compatible format. Map toJson() => { 'href': href, }; diff --git a/lib/src/models/oauth/authorization_code_response.dart b/lib/src/models/oauth/authorization_code_response.dart index a471a17..7e2de9b 100644 --- a/lib/src/models/oauth/authorization_code_response.dart +++ b/lib/src/models/oauth/authorization_code_response.dart @@ -8,13 +8,27 @@ import 'package:meta/meta.dart'; /// the Authorization Code flow @immutable class AuthorizationCodeResponse { + /// The access token issued by the authorization server. final String accessToken; + + /// The type of the token issued, typically "Bearer". final String tokenType; + + /// The duration in seconds for which the access token is valid. final int expiresIn; + + /// A list of scopes that the access token is valid for. final List scope; + + /// The subject (sub) identifier, representing the user. final String sub; + + /// The ID token issued by the authorization server. final String idToken; + /// Creates an instance of [AuthorizationCodeResponse]. + /// + /// All fields are required. const AuthorizationCodeResponse({ required this.accessToken, required this.tokenType, @@ -24,6 +38,10 @@ class AuthorizationCodeResponse { required this.idToken, }); + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. AuthorizationCodeResponse copyWith({ String? accessToken, String? tokenType, @@ -41,11 +59,14 @@ class AuthorizationCodeResponse { idToken: idToken ?? this.idToken, ); + /// Creates an instance of [AuthorizationCodeResponse] from a JSON string. factory AuthorizationCodeResponse.fromRawJson(String str) => AuthorizationCodeResponse.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [AuthorizationCodeResponse] from a JSON map. factory AuthorizationCodeResponse.fromJson(Map json) => AuthorizationCodeResponse( accessToken: json['access_token'], @@ -60,6 +81,7 @@ class AuthorizationCodeResponse { idToken: json['id_token'], ); + /// Converts this instance to a JSON map. Map toJson() => { 'access_token': accessToken, 'token_type': tokenType, diff --git a/lib/src/models/oauth/check_token_response.dart b/lib/src/models/oauth/check_token_response.dart index c2347f5..c4a3f43 100644 --- a/lib/src/models/oauth/check_token_response.dart +++ b/lib/src/models/oauth/check_token_response.dart @@ -8,14 +8,30 @@ import 'package:meta/meta.dart'; /// In case of client credentials flow token [userName] is null @immutable class CheckTokenResponse { + /// The username associated with the token. final String? userName; + + /// A list of scopes that the token is valid for. final List scope; + + /// A list of authorities associated with the user's account. final List accountAuthorities; + + /// The expiration time of the token, represented as a Unix timestamp. final int exp; + + /// A list of authorities associated with the client. final List clientAuthorities; + + /// A list of authorities granted to the token. final List authorities; + + /// The client ID associated with the token. final String clientId; + /// Creates an instance of [CheckTokenResponse]. + /// + /// All fields are required. const CheckTokenResponse({ required this.userName, required this.scope, @@ -26,6 +42,10 @@ class CheckTokenResponse { required this.clientId, }); + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. CheckTokenResponse copyWith({ String? userName, List? scope, @@ -45,11 +65,14 @@ class CheckTokenResponse { clientId: clientId ?? this.clientId, ); + /// Creates an instance of [CheckTokenResponse] from a JSON string. factory CheckTokenResponse.fromRawJson(String str) => CheckTokenResponse.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [CheckTokenResponse] from a JSON map. factory CheckTokenResponse.fromJson(Map json) => CheckTokenResponse( userName: json['user_name'], @@ -66,6 +89,7 @@ class CheckTokenResponse { clientId: json['client_id'], ); + /// Converts this instance to a JSON map. Map toJson() => { 'user_name': userName, 'scope': List.from(scope.map((BattleNetScope x) => x.name)), diff --git a/lib/src/models/oauth/client_credentials_response.dart b/lib/src/models/oauth/client_credentials_response.dart index 6db39ca..89a4fdf 100644 --- a/lib/src/models/oauth/client_credentials_response.dart +++ b/lib/src/models/oauth/client_credentials_response.dart @@ -6,11 +6,21 @@ import 'package:meta/meta.dart'; /// the client credential flow, OAuth's authentication flow intended for application servers. @immutable class ClientCredentialsResponse { + /// The access token issued by the authorization server. final String accessToken; + + /// The type of the token issued, typically "Bearer". final String tokenType; + + /// The duration in seconds for which the access token is valid. final int expiresIn; + + /// The subject (sub) identifier, representing the client. final String sub; + /// Creates an instance of [ClientCredentialsResponse]. + /// + /// All fields are required. const ClientCredentialsResponse({ required this.accessToken, required this.tokenType, @@ -18,11 +28,14 @@ class ClientCredentialsResponse { required this.sub, }); + /// Creates an instance of [ClientCredentialsResponse] from a JSON string. factory ClientCredentialsResponse.fromRawJson(String str) => ClientCredentialsResponse.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [ClientCredentialsResponse] from a JSON map. factory ClientCredentialsResponse.fromJson(Map json) => ClientCredentialsResponse( accessToken: json['access_token'], @@ -31,6 +44,7 @@ class ClientCredentialsResponse { sub: json['sub'], ); + /// Converts this instance to a JSON map. Map toJson() => { 'access_token': accessToken, 'token_type': tokenType, diff --git a/lib/src/models/oauth/user_info_response.dart b/lib/src/models/oauth/user_info_response.dart index ceb550b..b9a87bd 100644 --- a/lib/src/models/oauth/user_info_response.dart +++ b/lib/src/models/oauth/user_info_response.dart @@ -2,19 +2,32 @@ import 'dart:convert'; import 'package:meta/meta.dart'; -/// User Info data model +/// A class that represents the response received after +/// requesting user information in an OAuth2 authentication flow. @immutable class UserInfoResponse { + /// The subject (sub) identifier, representing the user. final String sub; + + /// The unique identifier for the user. final int id; + + /// The BattleTag associated with the user. final String battleTag; + /// Creates an instance of [UserInfoResponse]. + /// + /// All fields are required. const UserInfoResponse({ required this.sub, required this.id, required this.battleTag, }); + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. UserInfoResponse copyWith({ String? sub, int? id, @@ -26,11 +39,14 @@ class UserInfoResponse { battleTag: battleTag ?? this.battleTag, ); + /// Creates an instance of [UserInfoResponse] from a JSON string. factory UserInfoResponse.fromRawJson(String str) => UserInfoResponse.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [UserInfoResponse] from a JSON map. factory UserInfoResponse.fromJson(Map json) => UserInfoResponse( sub: json['sub'], @@ -38,6 +54,7 @@ class UserInfoResponse { battleTag: json['battletag'], ); + /// Converts this instance to a JSON map. Map toJson() => { 'sub': sub, 'id': id, diff --git a/lib/src/models/realm/connected_realm_result.dart b/lib/src/models/realm/connected_realm_result.dart index b6e4bc4..04d813c 100644 --- a/lib/src/models/realm/connected_realm_result.dart +++ b/lib/src/models/realm/connected_realm_result.dart @@ -5,17 +5,27 @@ import 'package:meta/meta.dart'; import '../common/self.dart'; import 'connected_realm_search_data.dart'; -/// Connected realm result data model +/// A class that represents the result of a connected realm query. @immutable class ConnectedRealmResult { + /// The key information for the connected realm. + final Self key; + + /// The data associated with the connected realm. + final ConnectedRealmSearchData data; + + /// Creates an instance of [ConnectedRealmResult]. + /// + /// All fields are required. const ConnectedRealmResult({ required this.key, required this.data, }); - final Self key; - final ConnectedRealmSearchData data; - + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. ConnectedRealmResult copyWith({ Self? key, ConnectedRealmSearchData? data, @@ -25,17 +35,21 @@ class ConnectedRealmResult { data: data ?? this.data, ); + /// Creates an instance of [ConnectedRealmResult] from a JSON string. factory ConnectedRealmResult.fromRawJson(String str) => ConnectedRealmResult.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [ConnectedRealmResult] from a JSON map. factory ConnectedRealmResult.fromJson(Map json) => ConnectedRealmResult( key: Self.fromJson(json['key']), data: ConnectedRealmSearchData.fromJson(json['data']), ); + /// Converts this instance to a JSON map. Map toJson() => { 'key': key.toJson(), 'data': data.toJson(), diff --git a/lib/src/models/realm/connected_realm_search_data.dart b/lib/src/models/realm/connected_realm_search_data.dart index da06c7e..9f2956a 100644 --- a/lib/src/models/realm/connected_realm_search_data.dart +++ b/lib/src/models/realm/connected_realm_search_data.dart @@ -7,9 +7,27 @@ import 'population_type_localised.dart'; import 'realm_localised.dart'; import 'server_status_localised.dart'; -/// Connected realm response model +/// A class that represents the data associated with a connected realm search. @immutable class ConnectedRealmSearchData { + /// The list of localized realms associated with the connected realm. + final List realms; + + /// The unique identifier for the connected realm. + final int id; + + /// Indicates if there is a queue to enter the realm. + final bool hasQueue; + + /// The status of the server. + final ServerStatusLocalised status; + + /// The population type of the server. + final PopulationTypeLocalised population; + + /// Creates an instance of [ConnectedRealmSearchData]. + /// + /// All fields are required. const ConnectedRealmSearchData({ required this.realms, required this.id, @@ -18,12 +36,10 @@ class ConnectedRealmSearchData { required this.population, }); - final List realms; - final int id; - final bool hasQueue; - final ServerStatusLocalised status; - final PopulationTypeLocalised population; - + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. ConnectedRealmSearchData copyWith({ List? realms, int? id, @@ -39,11 +55,14 @@ class ConnectedRealmSearchData { population: population ?? this.population, ); + /// Creates an instance of [ConnectedRealmSearchData] from a JSON string. factory ConnectedRealmSearchData.fromRawJson(String str) => ConnectedRealmSearchData.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [ConnectedRealmSearchData] from a JSON map. factory ConnectedRealmSearchData.fromJson(Map json) => ConnectedRealmSearchData( realms: List.from( @@ -54,6 +73,7 @@ class ConnectedRealmSearchData { population: PopulationTypeLocalised.fromJson(json['population']), ); + /// Converts this instance to a JSON map. Map toJson() => { 'realms': List.from(realms.map((dynamic x) => x.toJson())), 'id': id, diff --git a/lib/src/models/realm/connected_realm_search_response.dart b/lib/src/models/realm/connected_realm_search_response.dart index 9098cce..b3f36f8 100644 --- a/lib/src/models/realm/connected_realm_search_response.dart +++ b/lib/src/models/realm/connected_realm_search_response.dart @@ -5,9 +5,27 @@ import 'package:meta/meta.dart'; import 'connected_realm_result.dart'; -/// Connected realm search data model +/// A class that represents the response from a connected realm search. @immutable class ConnectedRealmSearchResponse { + /// The current page number of the search results. + final int page; + + /// The number of results per page. + final int pageSize; + + /// The maximum number of results per page. + final int maxPageSize; + + /// The total number of pages of results. + final int pageCount; + + /// The list of search results for connected realms. + final List results; + + /// Creates an instance of [ConnectedRealmSearchResponse]. + /// + /// All fields are required. const ConnectedRealmSearchResponse({ required this.page, required this.pageSize, @@ -16,12 +34,10 @@ class ConnectedRealmSearchResponse { required this.results, }); - final int page; - final int pageSize; - final int maxPageSize; - final int pageCount; - final List results; - + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. ConnectedRealmSearchResponse copyWith({ int? page, int? pageSize, @@ -37,11 +53,14 @@ class ConnectedRealmSearchResponse { results: results ?? this.results, ); + /// Creates an instance of [ConnectedRealmSearchResponse] from a JSON string. factory ConnectedRealmSearchResponse.fromRawJson(String str) => ConnectedRealmSearchResponse.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [ConnectedRealmSearchResponse] from a JSON map. factory ConnectedRealmSearchResponse.fromJson(Map json) => ConnectedRealmSearchResponse( page: json['page'], @@ -52,6 +71,7 @@ class ConnectedRealmSearchResponse { .map((dynamic x) => ConnectedRealmResult.fromJson(x))), ); + /// Converts this instance to a JSON map. Map toJson() => { 'page': page, 'pageSize': pageSize, diff --git a/lib/src/models/realm/name_localised.dart b/lib/src/models/realm/name_localised.dart index 87010f4..1297472 100644 --- a/lib/src/models/realm/name_localised.dart +++ b/lib/src/models/realm/name_localised.dart @@ -2,9 +2,12 @@ import 'dart:convert'; import 'package:meta/meta.dart'; -/// Name data model +/// A class representing localized names in different languages. @immutable class NameLocalised { + /// Creates an instance of [NameLocalised]. + /// + /// All fields are required. const NameLocalised({ required this.itIt, required this.ruRu, @@ -20,19 +23,46 @@ class NameLocalised { required this.deDe, }); + /// Italian (Italy) localized name. final String? itIt; + + /// Russian (Russia) localized name. final String ruRu; + + /// English (Great Britain) localized name. final String enGb; + + /// Chinese (Taiwan) localized name. final String zhTw; + + /// Korean (Korea) localized name. final String koKr; + + /// English (United States) localized name. final String enUs; + + /// Spanish (Mexico) localized name. final String esMx; + + /// Portuguese (Brazil) localized name. final String ptBr; + + /// Spanish (Spain) localized name. final String esEs; + + /// Chinese (China) localized name. final String zhCn; + + /// French (France) localized name. final String frFr; + + /// German (Germany) localized name. final String deDe; + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. NameLocalised copyWith({ String? itIt, String? ruRu, @@ -62,11 +92,14 @@ class NameLocalised { deDe: deDe ?? this.deDe, ); + /// Creates an instance of [NameLocalised] from a JSON string. factory NameLocalised.fromRawJson(String str) => NameLocalised.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [NameLocalised] from a JSON map. factory NameLocalised.fromJson(Map json) => NameLocalised( itIt: json['it_IT'], ruRu: json['ru_RU'], @@ -82,6 +115,7 @@ class NameLocalised { deDe: json['de_DE'], ); + /// Converts this instance to a JSON map. Map toJson() => { 'it_IT': itIt, 'ru_RU': ruRu, diff --git a/lib/src/models/realm/population_type_localised.dart b/lib/src/models/realm/population_type_localised.dart index 3da6c7c..f5dfe1c 100644 --- a/lib/src/models/realm/population_type_localised.dart +++ b/lib/src/models/realm/population_type_localised.dart @@ -5,17 +5,27 @@ import 'package:meta/meta.dart'; import 'name_localised.dart'; -/// Realm population data model +/// A class representing localized population type data for a realm. @immutable class PopulationTypeLocalised { + /// Creates an instance of [PopulationTypeLocalised]. + /// + /// All fields are required. const PopulationTypeLocalised({ required this.name, required this.type, }); + /// The localized name of the population type. final NameLocalised name; + + /// The type of population. final PopulationType type; + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. PopulationTypeLocalised copyWith({ NameLocalised? name, PopulationType? type, @@ -25,17 +35,21 @@ class PopulationTypeLocalised { type: type ?? this.type, ); + /// Creates an instance of [PopulationTypeLocalised] from a JSON string. factory PopulationTypeLocalised.fromRawJson(String str) => PopulationTypeLocalised.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [PopulationTypeLocalised] from a JSON map. factory PopulationTypeLocalised.fromJson(Map json) => PopulationTypeLocalised( name: NameLocalised.fromJson(json['name']), type: populationTypeValues.map[json['type']]!, ); + /// Converts this instance to a JSON map. Map toJson() => { 'name': name.toJson(), 'type': populationTypeValues.reverse[type], @@ -58,8 +72,10 @@ class PopulationTypeLocalised { int get hashCode => name.hashCode ^ type.hashCode; } +/// Enum representing the different types of population statuses for a realm. enum PopulationType { LOW, MEDIUM, FULL, HIGH, LOCKED, RECOMMENDED, OFFLINE } +/// A helper class to map population type values to and from strings. final EnumValues populationTypeValues = EnumValues({ 'LOW': PopulationType.LOW, diff --git a/lib/src/models/realm/realm_localised.dart b/lib/src/models/realm/realm_localised.dart index 35fe9d1..63c12b2 100644 --- a/lib/src/models/realm/realm_localised.dart +++ b/lib/src/models/realm/realm_localised.dart @@ -7,9 +7,12 @@ import 'name_localised.dart'; import 'realm_type_localised.dart'; import 'region_localised.dart'; -/// Realm data model +/// A class representing localized realm data. @immutable class RealmLocalised { + /// Creates an instance of [RealmLocalised]. + /// + /// All fields are required. const RealmLocalised({ required this.isTournament, required this.timezone, @@ -22,16 +25,37 @@ class RealmLocalised { required this.slug, }); + /// Indicates if the realm is a tournament realm. final bool isTournament; + + /// The timezone of the realm. final RealmTimezone timezone; + + /// The localized name of the realm. final NameLocalised name; + + /// The unique identifier of the realm. final int id; + + /// The region of the realm. final RegionLocalised region; + + /// The category of the realm. final NameLocalised category; + + /// The locale of the realm. final RealmLocale locale; + + /// The type of the realm. final RealmTypeLocalised type; + + /// The unique slug of the realm. final String slug; + /// Returns a copy of this instance with the given fields replaced + /// by new values. + /// + /// If a field is not provided, the existing value is retained. RealmLocalised copyWith({ bool? isTournament, RealmTimezone? timezone, @@ -55,11 +79,14 @@ class RealmLocalised { slug: slug ?? this.slug, ); + /// Creates an instance of [RealmLocalised] from a JSON string. factory RealmLocalised.fromRawJson(String str) => RealmLocalised.fromJson(json.decode(str)); + /// Converts this instance to a JSON string. String toRawJson() => json.encode(toJson()); + /// Creates an instance of [RealmLocalised] from a JSON map. factory RealmLocalised.fromJson(Map json) => RealmLocalised( isTournament: json['is_tournament'], timezone: realmTimezoneValues.map[json['timezone']]!, @@ -72,6 +99,7 @@ class RealmLocalised { slug: json['slug'], ); + /// Converts this instance to a JSON map. Map toJson() => { 'is_tournament': isTournament, 'timezone': realmTimezoneValues.reverse[timezone], @@ -117,6 +145,7 @@ class RealmLocalised { slug.hashCode; } +/// Enum representing the different locales supported for realms. enum RealmLocale { FR_FR, DE_DE, @@ -132,6 +161,7 @@ enum RealmLocale { ZH_TW, } +/// A mapping of string values to [RealmLocale] enums. final EnumValues realmLocaleValues = EnumValues({ 'deDE': RealmLocale.DE_DE, @@ -148,6 +178,7 @@ final EnumValues realmLocaleValues = 'zhTW': RealmLocale.ZH_TW, }); +/// Enum representing the different timezones for realms. enum RealmTimezone { EUROPE_PARIS, ASIA_SEOUL, @@ -160,6 +191,7 @@ enum RealmTimezone { AUSTRALIA_MELBOURNE, } +/// A mapping of string values to [RealmTimezone] enums. final EnumValues realmTimezoneValues = EnumValues({ 'Europe/Paris': RealmTimezone.EUROPE_PARIS, diff --git a/lib/src/models/realm/realm_type_localised.dart b/lib/src/models/realm/realm_type_localised.dart index c2405bc..04cbbda 100644 --- a/lib/src/models/realm/realm_type_localised.dart +++ b/lib/src/models/realm/realm_type_localised.dart @@ -5,17 +5,31 @@ import 'package:meta/meta.dart'; import 'name_localised.dart'; -/// Realm type data model +/// Represents a localized realm type with its name and type. +/// +/// This class is immutable and represents data related to a realm type, +/// including its localized name and its specific type enum. @immutable class RealmTypeLocalised { + /// Constructs a [RealmTypeLocalised] instance. + /// + /// The [name] parameter is required and represents the localized name of the realm type. + /// The [type] parameter is required and represents the specific type of the realm. const RealmTypeLocalised({ required this.name, required this.type, }); + /// The localized name of the realm type. final NameLocalised name; + + /// The specific type of the realm. final RealmType type; + /// Creates a copy of this [RealmTypeLocalised] instance with optional new values. + /// + /// Returns a new [RealmTypeLocalised] instance with the specified fields replaced + /// by the new values if provided, or unchanged if not. RealmTypeLocalised copyWith({ NameLocalised? name, RealmType? type, @@ -25,17 +39,34 @@ class RealmTypeLocalised { type: type ?? this.type, ); + /// Creates a [RealmTypeLocalised] instance from a raw JSON string [str]. + /// + /// Converts the JSON string into a map using [json.decode], and then constructs + /// a [RealmTypeLocalised] instance using [fromJson]. factory RealmTypeLocalised.fromRawJson(String str) => RealmTypeLocalised.fromJson(json.decode(str)); + /// Converts this [RealmTypeLocalised] instance to a raw JSON string representation. + /// + /// Converts the instance to a map using [toJson], and then encodes it to a JSON + /// string using [json.encode]. String toRawJson() => json.encode(toJson()); + /// Creates a [RealmTypeLocalised] instance from a JSON map [json]. + /// + /// Constructs a [RealmTypeLocalised] instance from a map retrieved from JSON, + /// extracting the [name] as a [NameLocalised] instance and the [type] as a + /// [RealmType] enum value using [realmTypeValues]. factory RealmTypeLocalised.fromJson(Map json) => RealmTypeLocalised( name: NameLocalised.fromJson(json['name']), type: realmTypeValues.map[json['type']]!, ); + /// Converts this [RealmTypeLocalised] instance to a JSON map. + /// + /// Converts the instance's [name] to JSON using [name.toJson] and maps the + /// [type] enum value to its string representation using [realmTypeValues.reverse]. Map toJson() => { 'name': name.toJson(), 'type': realmTypeValues.reverse[type], @@ -58,8 +89,22 @@ class RealmTypeLocalised { int get hashCode => name.hashCode ^ type.hashCode; } -enum RealmType { NORMAL, RP, PVP, PVP_RP } +/// Enumerates different types of realms. +enum RealmType { + /// Normal realm type. + NORMAL, + + /// Role-playing realm type. + RP, + + /// Player vs Player realm type. + PVP, + + /// Player vs Player Role-playing realm type. + PVP_RP, +} +/// Mapping of string values to [RealmType] enum values and vice versa. final EnumValues realmTypeValues = EnumValues({ 'NORMAL': RealmType.NORMAL, diff --git a/lib/src/models/realm/region_localised.dart b/lib/src/models/realm/region_localised.dart index 7718a42..48f52c2 100644 --- a/lib/src/models/realm/region_localised.dart +++ b/lib/src/models/realm/region_localised.dart @@ -4,17 +4,31 @@ import 'package:meta/meta.dart'; import 'name_localised.dart'; -/// Realm region data model +/// Represents a localized region with its name and ID. +/// +/// This class is immutable and represents data related to a region, +/// including its localized name and unique identifier. @immutable class RegionLocalised { + /// Constructs a [RegionLocalised] instance. + /// + /// The [name] parameter is required and represents the localized name of the region. + /// The [id] parameter is required and represents the unique identifier of the region. const RegionLocalised({ required this.name, required this.id, }); + /// The localized name of the region. final NameLocalised name; + + /// The unique identifier of the region. final int id; + /// Creates a copy of this [RegionLocalised] instance with optional new values. + /// + /// Returns a new [RegionLocalised] instance with the specified fields replaced + /// by the new values if provided, or unchanged if not. RegionLocalised copyWith({ NameLocalised? name, int? id, @@ -24,17 +38,33 @@ class RegionLocalised { id: id ?? this.id, ); + /// Creates a [RegionLocalised] instance from a raw JSON string [str]. + /// + /// Converts the JSON string into a map using [json.decode], and then constructs + /// a [RegionLocalised] instance using [fromJson]. factory RegionLocalised.fromRawJson(String str) => RegionLocalised.fromJson(json.decode(str)); + /// Converts this [RegionLocalised] instance to a raw JSON string representation. + /// + /// Converts the instance to a map using [toJson], and then encodes it to a JSON + /// string using [json.encode]. String toRawJson() => json.encode(toJson()); + /// Creates a [RegionLocalised] instance from a JSON map [json]. + /// + /// Constructs a [RegionLocalised] instance from a map retrieved from JSON, + /// extracting the [name] as a [NameLocalised] instance and the [id] as an integer. factory RegionLocalised.fromJson(Map json) => RegionLocalised( name: NameLocalised.fromJson(json['name']), id: json['id'], ); + /// Converts this [RegionLocalised] instance to a JSON map. + /// + /// Converts the instance's [name] to JSON using [name.toJson], and includes + /// the [id] directly as part of the JSON map. Map toJson() => { 'name': name.toJson(), 'id': id, diff --git a/lib/src/models/realm/server_status_localised.dart b/lib/src/models/realm/server_status_localised.dart index 7bc18ed..583b7c4 100644 --- a/lib/src/models/realm/server_status_localised.dart +++ b/lib/src/models/realm/server_status_localised.dart @@ -5,17 +5,31 @@ import 'package:meta/meta.dart'; import '../common/enum_values.dart'; import 'name_localised.dart'; -/// Server status data model +/// Represents the localized server status with its name and type. +/// +/// This class is immutable and represents data related to a server status, +/// including its localized name and type (UP or DOWN). @immutable class ServerStatusLocalised { + /// Constructs a [ServerStatusLocalised] instance. + /// + /// The [name] parameter is required and represents the localized name of the server status. + /// The [type] parameter is required and represents the type of server status (UP or DOWN). const ServerStatusLocalised({ required this.name, required this.type, }); + /// The localized name of the server status. final NameLocalised name; + + /// The type of server status, either UP or DOWN. final ServerStatus type; + /// Creates a copy of this [ServerStatusLocalised] instance with optional new values. + /// + /// Returns a new [ServerStatusLocalised] instance with the specified fields replaced + /// by the new values if provided, or unchanged if not. ServerStatusLocalised copyWith({ NameLocalised? name, ServerStatus? type, @@ -25,17 +39,33 @@ class ServerStatusLocalised { type: type ?? this.type, ); + /// Creates a [ServerStatusLocalised] instance from a raw JSON string [str]. + /// + /// Converts the JSON string into a map using [json.decode], and then constructs + /// a [ServerStatusLocalised] instance using [fromJson]. factory ServerStatusLocalised.fromRawJson(String str) => ServerStatusLocalised.fromJson(json.decode(str)); + /// Converts this [ServerStatusLocalised] instance to a raw JSON string representation. + /// + /// Converts the instance to a map using [toJson], and then encodes it to a JSON + /// string using [json.encode]. String toRawJson() => json.encode(toJson()); + /// Creates a [ServerStatusLocalised] instance from a JSON map [json]. + /// + /// Constructs a [ServerStatusLocalised] instance from a map retrieved from JSON, + /// extracting the [name] as a [NameLocalised] instance and the [type] as a [ServerStatus]. factory ServerStatusLocalised.fromJson(Map json) => ServerStatusLocalised( name: NameLocalised.fromJson(json['name']), type: serverStatusValues.map[json['type']]!, ); + /// Converts this [ServerStatusLocalised] instance to a JSON map. + /// + /// Converts the instance's [name] to JSON using [name.toJson], and includes + /// the [type] as a string representation from [serverStatusValues.reverse]. Map toJson() => { 'name': name.toJson(), 'type': serverStatusValues.reverse[type], @@ -58,8 +88,13 @@ class ServerStatusLocalised { int get hashCode => name.hashCode ^ type.hashCode; } -enum ServerStatus { UP, DOWN } +/// Enum representing server status types: UP or DOWN. +enum ServerStatus { + UP, // The server is up and running. + DOWN, // The server is currently down. +} +/// Holds mapping values for [ServerStatus] enum values and their string representations. final EnumValues serverStatusValues = EnumValues({ 'UP': ServerStatus.UP, diff --git a/lib/src/models/token/token_index_response.dart b/lib/src/models/token/token_index_response.dart index bbb7f3a..72708f1 100644 --- a/lib/src/models/token/token_index_response.dart +++ b/lib/src/models/token/token_index_response.dart @@ -4,24 +4,50 @@ import 'package:meta/meta.dart'; import '../common/links.dart'; -/// WoW Token index response model +/// Represents the response model for WoW Token index information. +/// +/// This class is immutable and encapsulates data related to WoW Token index, +/// including links, last updated timestamp, and current price. @immutable class TokenIndexResponse { + /// Constructs a [TokenIndexResponse] instance. + /// + /// The [links] parameter is required and represents the links associated with the response. + /// The [lastUpdatedTimestamp] parameter is required and indicates the timestamp when the data was last updated. + /// The [price] parameter is required and represents the current price of the WoW Token. const TokenIndexResponse({ required this.links, required this.lastUpdatedTimestamp, required this.price, }); + /// Links associated with the token index response. final Links links; + + /// Timestamp indicating when the token index data was last updated. final int lastUpdatedTimestamp; + + /// Current price of the WoW Token. final int price; + /// Creates a [TokenIndexResponse] instance from a raw JSON string [str]. + /// + /// Converts the JSON string into a map using [json.decode], and then constructs + /// a [TokenIndexResponse] instance using [fromJson]. factory TokenIndexResponse.fromRawJson(String str) => TokenIndexResponse.fromJson(json.decode(str)); + /// Converts this [TokenIndexResponse] instance to a raw JSON string representation. + /// + /// Converts the instance to a map using [toJson], and then encodes it to a JSON + /// string using [json.encode]. String toRawJson() => json.encode(toJson()); + /// Creates a [TokenIndexResponse] instance from a JSON map [json]. + /// + /// Constructs a [TokenIndexResponse] instance from a map retrieved from JSON, + /// extracting the [links] as a [Links] instance, [lastUpdatedTimestamp] as an integer, + /// and [price] as an integer. factory TokenIndexResponse.fromJson(Map json) => TokenIndexResponse( links: Links.fromJson(json['_links']), @@ -29,6 +55,10 @@ class TokenIndexResponse { price: json['price'], ); + /// Converts this [TokenIndexResponse] instance to a JSON map. + /// + /// Converts the instance's [links] to JSON using [links.toJson], + /// and includes [lastUpdatedTimestamp] and [price] directly. Map toJson() => { '_links': links.toJson(), 'last_updated_timestamp': lastUpdatedTimestamp, diff --git a/pubspec.yaml b/pubspec.yaml index 5dedf2a..2a1f589 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: battle_net description: Dart wrapper client for Battle.Net API https://develop.battle.net/documentation -version: 0.1.3+2 +version: 0.2.0 repository: https://github.com/vmpay/battle_net_dart issue_tracker: https://github.com/vmpay/battle_net_dart/issues diff --git a/test/integration/get_connected_realm_search_integration_test.dart b/test/integration/get_connected_realm_search_integration_test.dart index ed0e0d8..a19a626 100644 --- a/test/integration/get_connected_realm_search_integration_test.dart +++ b/test/integration/get_connected_realm_search_integration_test.dart @@ -160,7 +160,7 @@ void main() { realmsIsTournament: false, )); expect(result.page, 1); - expect(result.results.first.data.id, 4467); + expect(result.results.first.data.id > 0, isTrue); }); test('get connected realm search eu', () async { @@ -234,7 +234,7 @@ void main() { namespace: BattleNetNamespace.dynamicClassic, )); expect(result.page, 1); - expect(result.results.first.data.id, 4372); + expect(result.results.first.data.id > 0, isTrue); }); test('get connected realm tw with parameters', () async { @@ -248,11 +248,11 @@ void main() { statusType: ServerStatus.UP, realmsTimezone: RealmTimezone.ASIA_TAIPEI, hasQueue: false, - populationType: PopulationType.FULL, + populationType: PopulationType.MEDIUM, realmsIsTournament: false, )); expect(result.page, 1); - expect(result.results.first.data.id, 4488); + expect(result.results.first.data.id > 0, isTrue); }); test('get connected realm tw', () async {