From c3bfa4b67dc0e3c23e327f253d7d685a1964ce46 Mon Sep 17 00:00:00 2001 From: Gunnar Oledal Date: Fri, 5 Mar 2021 15:56:44 +0100 Subject: [PATCH 001/195] Added details about querying for users How to use the ParseUser.forQuery() function --- packages/flutter/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/flutter/README.md b/packages/flutter/README.md index b4ff272bf..667b53488 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -253,6 +253,19 @@ if (dietPlan.success) { print(ApplicationConstants.keyAppName + ": " + dietPlan.exception.message); } ``` +To query for user objects, you could use the function ```ParseUser.forQuery()``` like this: +```dart +var queryBuilder = QueryBuilder(ParseUser.forQuery()) + ..whereEqualTo('activated', true); + +var response = await queryBuilder.query(); + +if (response.success) { + print(response.results); +} else { + print(response.exception.message); +} +``` ## Complex queries You can create complex queries to really put your database to the test: From a9dbafbe7088bfd247e3b66b4b662ccdb4e5f88d Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 12:54:32 +0100 Subject: [PATCH 002/195] Add official flutter .gitignore --- .gitignore | 107 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 89f6918e8..56909ccd3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,14 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp .DS_Store -.dart_tool/ +.atom/ +.buildlog/ .history -.packages -.pub/ -pubspec.lock -.example/lib/application_constants.dart +.svn/ # IntelliJ related *.iml @@ -12,6 +16,49 @@ pubspec.lock *.iws .idea/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/ + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + # Android related **/android/**/gradle-wrapper.jar **/android/.gradle @@ -20,16 +67,52 @@ pubspec.lock **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* -build/ -.idea -example/ios/Frameworks/ -example/lib/ui/ +# macOS +**/macos/Flutter/GeneratedPluginRegistrant.swift -example_livelist/lib/application_constants.dart +# Coverage +coverage/ -.flutter-plugins-dependencies +# Symbols +app.*.symbols -.vscode/ +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock From be4914837720712a09d23fb4d57edee63c0899ae Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 12:58:51 +0100 Subject: [PATCH 003/195] Remove .gitignored files --- packages/flutter/example/android/.project | 17 ---- .../org.eclipse.buildship.core.prefs | 2 - .../flutter/example/android/app/.classpath | 6 -- packages/flutter/example/android/app/.project | 23 ------ .../org.eclipse.buildship.core.prefs | 2 - packages/flutter/example/ios/Podfile.lock | 46 ----------- .../flutter/example_livelist/ios/Podfile.lock | 77 ------------------- 7 files changed, 173 deletions(-) delete mode 100644 packages/flutter/example/android/.project delete mode 100644 packages/flutter/example/android/.settings/org.eclipse.buildship.core.prefs delete mode 100644 packages/flutter/example/android/app/.classpath delete mode 100644 packages/flutter/example/android/app/.project delete mode 100644 packages/flutter/example/android/app/.settings/org.eclipse.buildship.core.prefs delete mode 100644 packages/flutter/example/ios/Podfile.lock delete mode 100644 packages/flutter/example_livelist/ios/Podfile.lock diff --git a/packages/flutter/example/android/.project b/packages/flutter/example/android/.project deleted file mode 100644 index 3964dd3f5..000000000 --- a/packages/flutter/example/android/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - android - Project android created by Buildship. - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.buildship.core.gradleprojectnature - - diff --git a/packages/flutter/example/android/.settings/org.eclipse.buildship.core.prefs b/packages/flutter/example/android/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index e8895216f..000000000 --- a/packages/flutter/example/android/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -connection.project.dir= -eclipse.preferences.version=1 diff --git a/packages/flutter/example/android/app/.classpath b/packages/flutter/example/android/app/.classpath deleted file mode 100644 index 8d8d85f14..000000000 --- a/packages/flutter/example/android/app/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/packages/flutter/example/android/app/.project b/packages/flutter/example/android/app/.project deleted file mode 100644 index ac485d7c3..000000000 --- a/packages/flutter/example/android/app/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - app - Project app created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - diff --git a/packages/flutter/example/android/app/.settings/org.eclipse.buildship.core.prefs b/packages/flutter/example/android/app/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index b1886adb4..000000000 --- a/packages/flutter/example/android/app/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -connection.project.dir=.. -eclipse.preferences.version=1 diff --git a/packages/flutter/example/ios/Podfile.lock b/packages/flutter/example/ios/Podfile.lock deleted file mode 100644 index 82fdc71c4..000000000 --- a/packages/flutter/example/ios/Podfile.lock +++ /dev/null @@ -1,46 +0,0 @@ -PODS: - - devicelocale (0.0.1): - - Flutter - - Flutter (1.0.0) - - flutter_stetho (0.0.1): - - Flutter - - package_info (0.0.1): - - Flutter - - path_provider (0.0.1): - - Flutter - - shared_preferences (0.0.1): - - Flutter - -DEPENDENCIES: - - devicelocale (from `.symlinks/plugins/devicelocale/ios`) - - Flutter (from `.symlinks/flutter/ios`) - - flutter_stetho (from `.symlinks/plugins/flutter_stetho/ios`) - - package_info (from `.symlinks/plugins/package_info/ios`) - - path_provider (from `.symlinks/plugins/path_provider/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - -EXTERNAL SOURCES: - devicelocale: - :path: ".symlinks/plugins/devicelocale/ios" - Flutter: - :path: ".symlinks/flutter/ios" - flutter_stetho: - :path: ".symlinks/plugins/flutter_stetho/ios" - package_info: - :path: ".symlinks/plugins/package_info/ios" - path_provider: - :path: ".symlinks/plugins/path_provider/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - -SPEC CHECKSUMS: - devicelocale: c1be0ad8a4bc50c184faf25bf8abe318e9bd69ba - Flutter: 9d0fac939486c9aba2809b7982dfdbb47a7b0296 - flutter_stetho: 21464137ea9bb03914912de8916a7acfdcbfc0a5 - package_info: d7c98b64f60add4c2908b9d94d82a45d3c8827ad - path_provider: 09407919825bfe3c2deae39453b7a5b44f467873 - shared_preferences: 5a1d487c427ee18fcd3ea1f2a131569481834b53 - -PODFILE CHECKSUM: aff02bfeed411c636180d6812254b2daeea14d09 - -COCOAPODS: 1.5.3 diff --git a/packages/flutter/example_livelist/ios/Podfile.lock b/packages/flutter/example_livelist/ios/Podfile.lock deleted file mode 100644 index 9c84f5c0e..000000000 --- a/packages/flutter/example_livelist/ios/Podfile.lock +++ /dev/null @@ -1,77 +0,0 @@ -PODS: - - connectivity (0.0.1): - - Flutter - - Reachability - - connectivity_macos (0.0.1): - - Flutter - - devicelocale (0.0.1): - - Flutter - - Flutter (1.0.0) - - package_info (0.0.1): - - Flutter - - path_provider (0.0.1): - - Flutter - - path_provider_macos (0.0.1): - - Flutter - - Reachability (3.2) - - shared_preferences (0.0.1): - - Flutter - - shared_preferences_macos (0.0.1): - - Flutter - - shared_preferences_web (0.0.1): - - Flutter - -DEPENDENCIES: - - connectivity (from `.symlinks/plugins/connectivity/ios`) - - connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`) - - devicelocale (from `.symlinks/plugins/devicelocale/ios`) - - Flutter (from `Flutter`) - - package_info (from `.symlinks/plugins/package_info/ios`) - - path_provider (from `.symlinks/plugins/path_provider/ios`) - - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) - - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - -SPEC REPOS: - trunk: - - Reachability - -EXTERNAL SOURCES: - connectivity: - :path: ".symlinks/plugins/connectivity/ios" - connectivity_macos: - :path: ".symlinks/plugins/connectivity_macos/ios" - devicelocale: - :path: ".symlinks/plugins/devicelocale/ios" - Flutter: - :path: Flutter - package_info: - :path: ".symlinks/plugins/package_info/ios" - path_provider: - :path: ".symlinks/plugins/path_provider/ios" - path_provider_macos: - :path: ".symlinks/plugins/path_provider_macos/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - shared_preferences_macos: - :path: ".symlinks/plugins/shared_preferences_macos/ios" - shared_preferences_web: - :path: ".symlinks/plugins/shared_preferences_web/ios" - -SPEC CHECKSUMS: - connectivity: 6e94255659cc86dcbef1d452ad3e0491bb1b3e75 - connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 - devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00 - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - package_info: 48b108e75b8802c2d5e126f208ef540561c98aef - path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d - path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01 - shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 - shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 - -PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a - -COCOAPODS: 1.9.1 From 08619599fb67ab4c44cd2a40a3babd30a017b2b0 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 13:03:11 +0100 Subject: [PATCH 004/195] dart: Update dependencies to null-safety --- packages/dart/pubspec.yaml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 75ee25518..89215f18f 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,30 +1,30 @@ name: parse_server_sdk description: Dart plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 2.1.0 +version: 3.0.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: - sdk: ">=2.2.2 <3.0.0" + sdk: '>=2.7.0 <3.0.0' dependencies: # Networking - dio: ^3.0.10 - http: ^0.12.2 - web_socket_channel: ^1.2.0 + dio: ^4.0.0-beta7 + http: ^0.13.0 + web_socket_channel: ^2.0.0 #Database - sembast: ^2.4.9 - sembast_web: ^1.2.0+1 - xxtea: ^2.0.3 + sembast: ^3.0.0+4 + sembast_web: ^2.0.0+2 + xxtea: ^2.1.0 # Utils - uuid: ^2.2.2 - meta: ^1.2.4 - path: ^1.7.0 - mime_type: ^0.3.2 + uuid: ^3.0.1 + meta: ^1.3.0 + path: ^1.8.0 + mime_type: ^1.0.0 dev_dependencies: # Testing - test: ^1.15.7 - mockito: ^4.1.3 + mockito: ^5.0.1 + test: ^1.16.8 From d50b93224b8683d6cd7e84560fd687ee0831ec0b Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 13:09:49 +0100 Subject: [PATCH 005/195] dart: Use relative imports for our files --- packages/dart/lib/parse_server_sdk.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index 89aec7bcd..983f80cb1 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -8,9 +8,6 @@ import 'dart:typed_data'; import 'package:meta/meta.dart'; import 'package:mime_type/mime_type.dart'; -import 'package:parse_server_sdk/src/network/parse_http_client.dart'; -import 'package:parse_server_sdk/src/network/parse_websocket.dart' - as parse_web_socket; import 'package:path/path.dart' as path; import 'package:sembast/sembast.dart'; import 'package:sembast/sembast_io.dart'; @@ -19,6 +16,9 @@ import 'package:uuid/uuid.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:xxtea/xxtea.dart'; +import 'src/network/parse_http_client.dart'; +import 'src/network/parse_websocket.dart' as parse_web_socket; + export 'src/network/parse_dio_client.dart'; export 'src/network/parse_http_client.dart'; From 06f62475cfeb42c0cf052dc5d57c781e24c10e89 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 13:12:09 +0100 Subject: [PATCH 006/195] dart: Fix breaking http change: String -> Uri --- .../dart/lib/src/network/parse_http_client.dart | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index 950ee908e..b72d3c962 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -23,7 +23,7 @@ class ParseHTTPClient extends ParseClient { ProgressCallback onReceiveProgress, }) async { final http.Response response = await _client.get( - path, + Uri.parse(path), headers: options?.headers, ); return ParseNetworkResponse( @@ -37,7 +37,7 @@ class ParseHTTPClient extends ParseClient { ProgressCallback onReceiveProgress, }) async { final http.Response response = await _client.get( - path, + Uri.parse(path), headers: options?.headers, ); return ParseNetworkByteResponse( @@ -51,7 +51,7 @@ class ParseHTTPClient extends ParseClient { ParseNetworkOptions options, }) async { final http.Response response = await _client.put( - path, + Uri.parse(path), body: data, headers: options?.headers, ); @@ -66,7 +66,7 @@ class ParseHTTPClient extends ParseClient { ParseNetworkOptions options, }) async { final http.Response response = await _client.post( - path, + Uri.parse(path), body: data, headers: options?.headers, ); @@ -82,9 +82,10 @@ class ParseHTTPClient extends ParseClient { ProgressCallback onSendProgress, }) async { final http.Response response = await _client.post( - path, + Uri.parse(path), //Convert the stream to a list - body: await data.fold>([], (List previous, List element) => previous..addAll(element)), + body: await data.fold>([], + (List previous, List element) => previous..addAll(element)), headers: options?.headers, ); return ParseNetworkResponse( @@ -95,7 +96,7 @@ class ParseHTTPClient extends ParseClient { Future delete(String path, {ParseNetworkOptions options}) async { final http.Response response = await _client.delete( - path, + Uri.parse(path), headers: options?.headers, ); return ParseNetworkResponse( From 66e9183c5f1e94e70468d803e5f6f21ced1ccbfe Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 13:47:08 +0100 Subject: [PATCH 007/195] dart: Remove unused variable --- packages/dart/lib/parse_server_sdk.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index 983f80cb1..a0f671403 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -67,7 +67,6 @@ part 'src/utils/parse_login_helpers.dart'; part 'src/utils/parse_utils.dart'; class Parse { - ParseCoreData data; bool _hasBeenInitialized = false; /// To initialize Parse Server in your application From 7ab54d2c87e45208152539b5dfe18ed08e7ca9ec Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:08:05 +0100 Subject: [PATCH 008/195] dart: constants: Update version --- packages/dart/lib/src/base/parse_constants.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/base/parse_constants.dart b/packages/dart/lib/src/base/parse_constants.dart index 49789d679..d1a5dc428 100644 --- a/packages/dart/lib/src/base/parse_constants.dart +++ b/packages/dart/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '2.1.0'; +const String keySdkVersion = '3.0.0'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points From 4e227398b0ad93b66428f4dc28f65e4ad4b42fa8 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:11:10 +0100 Subject: [PATCH 009/195] dart: Make debug, autoSendSessionId required ParseCoreData is only initialized by Parse. Parse sets default values for debug and autoSendSessionId So we can just pipe them down to ParseCoreData --- packages/dart/lib/parse_server_sdk.dart | 11 +++-------- packages/dart/lib/src/data/parse_core_data.dart | 13 +++++++------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index a0f671403..36cfd86a7 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -139,10 +139,8 @@ class Parse { bool hasParseBeenInitialized() => _hasBeenInitialized; - Future healthCheck( + Future healthCheck( {bool debug, ParseClient client, bool sendSessionIdByDefault}) async { - ParseResponse parseResponse; - final bool _debug = isDebugEnabled(objectLevelDebug: debug); final ParseClient _client = client ?? @@ -157,12 +155,9 @@ class Parse { try { final ParseNetworkResponse response = await _client.get('${ParseCoreData().serverUrl}$keyEndPointHealth'); - parseResponse = - handleResponse(null, response, type, _debug, className); + return handleResponse(null, response, type, _debug, className); } on Exception catch (e) { - parseResponse = handleException(e, type, _debug, className); + return handleException(e, type, _debug, className); } - - return parseResponse; } } diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index b2e5af40f..0f2d07d3d 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -17,7 +17,7 @@ class ParseCoreData { static Future init( String appId, String serverUrl, { - bool debug, + bool/*!*/ debug, String appName, String appVersion, String appPackageName, @@ -26,7 +26,7 @@ class ParseCoreData { String masterKey, String clientKey, String sessionId, - bool autoSendSessionId, + bool/*!*/ autoSendSessionId, SecurityContext securityContext, CoreStore store, Map registeredSubClassMap, @@ -115,17 +115,18 @@ class ParseCoreData { String masterKey; String clientKey; String sessionId; - bool autoSendSessionId; + bool/*!*/ autoSendSessionId; SecurityContext securityContext; - bool debug; + bool/*!*/ debug; CoreStore storage; ParseSubClassHandler _subClassHandler; List liveListRetryIntervals; ParseConnectivityProvider connectivityProvider; String fileDirectory; Stream appResumedStream; - ParseClientCreator clientCreator = - ({bool sendSessionId, SecurityContext securityContext}) => ParseHTTPClient( + ParseClientCreator clientCreator = ( + {bool sendSessionId, SecurityContext securityContext}) => + ParseHTTPClient( sendSessionId: sendSessionId, securityContext: securityContext); void registerSubClass( From 397afd0c9640f4af27b7ccfd005743975a3ba421 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:32:34 +0100 Subject: [PATCH 010/195] dart(CoreData): No need to check for null The class members are only set in the init function and the init function is not called at a later point in time. ==> Each variable, if it is not set, is null anyway --- .../dart/lib/src/data/parse_core_data.dart | 75 +++++-------------- 1 file changed, 18 insertions(+), 57 deletions(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 0f2d07d3d..f5cf97c53 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -41,68 +41,29 @@ class ParseCoreData { _instance = ParseCoreData._init(appId, serverUrl); _instance.storage ??= store ?? CoreStoreMemoryImp(); - - if (debug != null) { - _instance.debug = debug; - } - if (appName != null) { - _instance.appName = appName; - } - if (appVersion != null) { - _instance.appVersion = appVersion; - } - if (appPackageName != null) { - _instance.appPackageName = appPackageName; - } - if (locale != null) { - _instance.locale = locale; - } - if (liveQueryUrl != null) { - _instance.liveQueryURL = liveQueryUrl; - } - if (clientKey != null) { - _instance.clientKey = clientKey; - } - if (masterKey != null) { - _instance.masterKey = masterKey; - } - if (sessionId != null) { - _instance.sessionId = sessionId; - } - if (autoSendSessionId != null) { - _instance.autoSendSessionId = autoSendSessionId; - } - if (securityContext != null) { - _instance.securityContext = securityContext; - } - if (liveListRetryIntervals != null) { - _instance.liveListRetryIntervals = liveListRetryIntervals; - } else { - _instance.liveListRetryIntervals = parseIsWeb - ? [0, 500, 1000, 2000, 5000] - : [0, 500, 1000, 2000, 5000, 10000]; - } - + _instance.debug = debug; + _instance.appName = appName; + _instance.appVersion = appVersion; + _instance.appPackageName = appPackageName; + _instance.locale = locale; + _instance.liveQueryURL = liveQueryUrl; + _instance.clientKey = clientKey; + _instance.masterKey = masterKey; + _instance.sessionId = sessionId; + _instance.autoSendSessionId = autoSendSessionId; + _instance.securityContext = securityContext; + _instance.liveListRetryIntervals = liveListRetryIntervals ?? parseIsWeb + ? [0, 500, 1000, 2000, 5000] + : [0, 500, 1000, 2000, 5000, 10000]; _instance._subClassHandler = ParseSubClassHandler( registeredSubClassMap: registeredSubClassMap, parseUserConstructor: parseUserConstructor, parseFileConstructor: parseFileConstructor, ); - if (connectivityProvider != null) { - _instance.connectivityProvider = connectivityProvider; - } - - if (fileDirectory != null) { - _instance.fileDirectory = fileDirectory; - } - - if (appResumedStream != null) { - _instance.appResumedStream = appResumedStream; - } - - if (clientCreator != null) { - _instance.clientCreator = clientCreator; - } + _instance.connectivityProvider = connectivityProvider; + _instance.fileDirectory = fileDirectory; + _instance.appResumedStream = appResumedStream; + _instance.clientCreator = clientCreator; } String appName; From 8b69703e8a06b7de14ef8de0e0adbefedca588dc Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:33:13 +0100 Subject: [PATCH 011/195] dart(CoreData): liveListRetryIntervals always set Should use late keyword --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index f5cf97c53..5a2d1cb51 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -81,7 +81,7 @@ class ParseCoreData { bool/*!*/ debug; CoreStore storage; ParseSubClassHandler _subClassHandler; - List liveListRetryIntervals; + List /*!*/ liveListRetryIntervals; ParseConnectivityProvider connectivityProvider; String fileDirectory; Stream appResumedStream; From 636766f3df30f3afc4271ee9f2c9eec206c6d540 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:35:11 +0100 Subject: [PATCH 012/195] Change order of vars --- packages/dart/lib/src/data/parse_core_data.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 5a2d1cb51..afe192364 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -17,7 +17,7 @@ class ParseCoreData { static Future init( String appId, String serverUrl, { - bool/*!*/ debug, + bool /*!*/ debug, String appName, String appVersion, String appPackageName, @@ -26,7 +26,7 @@ class ParseCoreData { String masterKey, String clientKey, String sessionId, - bool/*!*/ autoSendSessionId, + bool /*!*/ autoSendSessionId, SecurityContext securityContext, CoreStore store, Map registeredSubClassMap, @@ -66,19 +66,19 @@ class ParseCoreData { _instance.clientCreator = clientCreator; } + String applicationId; + String serverUrl; String appName; String appVersion; String appPackageName; - String applicationId; String locale; - String serverUrl; String liveQueryURL; String masterKey; String clientKey; String sessionId; - bool/*!*/ autoSendSessionId; + bool /*!*/ autoSendSessionId; SecurityContext securityContext; - bool/*!*/ debug; + bool /*!*/ debug; CoreStore storage; ParseSubClassHandler _subClassHandler; List /*!*/ liveListRetryIntervals; From bad4f7c99156938a406e1a4b7ee6aa5d2e510460 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:41:12 +0100 Subject: [PATCH 013/195] dart(CoreData): Storage is never set outside It is always null when executing init --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index afe192364..5452f02f5 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -40,7 +40,7 @@ class ParseCoreData { }) async { _instance = ParseCoreData._init(appId, serverUrl); - _instance.storage ??= store ?? CoreStoreMemoryImp(); + _instance.storage = store ?? CoreStoreMemoryImp(); _instance.debug = debug; _instance.appName = appName; _instance.appVersion = appVersion; From 84122dad2279580f1178bae425a5b9490493aa36 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:43:27 +0100 Subject: [PATCH 014/195] dart(CoreData): storage is never null Should use late keyword --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 5452f02f5..5f1c2d6fb 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -79,7 +79,7 @@ class ParseCoreData { bool /*!*/ autoSendSessionId; SecurityContext securityContext; bool /*!*/ debug; - CoreStore storage; + CoreStore/*!*/ storage; ParseSubClassHandler _subClassHandler; List /*!*/ liveListRetryIntervals; ParseConnectivityProvider connectivityProvider; From d63a231b52f5b8c500ab990a4346e76e2d90284f Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:44:01 +0100 Subject: [PATCH 015/195] clientCreator is initialized, so never null --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 5f1c2d6fb..0e91752f0 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -85,7 +85,7 @@ class ParseCoreData { ParseConnectivityProvider connectivityProvider; String fileDirectory; Stream appResumedStream; - ParseClientCreator clientCreator = ( + ParseClientCreator /*!*/ clientCreator = ( {bool sendSessionId, SecurityContext securityContext}) => ParseHTTPClient( sendSessionId: sendSessionId, securityContext: securityContext); From 8fa8b91d26da68191992af740a24110e3fef3d9b Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 14:44:18 +0100 Subject: [PATCH 016/195] Do not use a setter and then provide a nullable --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 0e91752f0..a7a0af3dc 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -121,7 +121,7 @@ class ParseCoreData { /// /// This is generated when a users logs in, or calls currentUser to update /// their keys - void setSessionId(String sessionId) { + void setSessionId(String /*!*/ sessionId) { this.sessionId = sessionId; } From 27982f30f44af8bea9431d96ecb8e3a9f794fdae Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 15:01:55 +0100 Subject: [PATCH 017/195] dart: Annotate ParseClient --- packages/dart/lib/src/network/parse_client.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_client.dart b/packages/dart/lib/src/network/parse_client.dart index 0067bc4e8..3122ec5e8 100644 --- a/packages/dart/lib/src/network/parse_client.dart +++ b/packages/dart/lib/src/network/parse_client.dart @@ -24,7 +24,7 @@ abstract class ParseClient { Future postBytes( String path, { - Stream> data, + Stream /*!*/ > data, ParseNetworkOptions options, ProgressCallback onSendProgress, }); @@ -79,7 +79,7 @@ abstract class ParseClient { typedef ProgressCallback = void Function(int count, int total); class ParseNetworkResponse { - final String data; + final String/*!*/ data; final int statusCode; ParseNetworkResponse({ From 420ca1dc4a07b366825d13d5358d79ad09e23f74 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 15:21:16 +0100 Subject: [PATCH 018/195] dart: Headers are always Map --- packages/dart/lib/src/network/options.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/options.dart b/packages/dart/lib/src/network/options.dart index 05e31d3d5..40d3b9436 100644 --- a/packages/dart/lib/src/network/options.dart +++ b/packages/dart/lib/src/network/options.dart @@ -3,7 +3,7 @@ part of flutter_parse_sdk; class ParseNetworkOptions { ParseNetworkOptions({this.headers}); - final Map headers; + final Map headers; // final ParseNetworkResponseType responseType; } From 9f478894aec83c690b0dc72e5987c5a07412d647 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 15:30:30 +0100 Subject: [PATCH 019/195] data could be null, use null-safe operator --- packages/dart/lib/src/network/parse_http_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index b72d3c962..109132a7d 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -84,7 +84,7 @@ class ParseHTTPClient extends ParseClient { final http.Response response = await _client.post( Uri.parse(path), //Convert the stream to a list - body: await data.fold>([], + body: await data?.fold>([], (List previous, List element) => previous..addAll(element)), headers: options?.headers, ); From f03ab44c3db26574fd9676b3938ee05f51554c20 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 15:31:39 +0100 Subject: [PATCH 020/195] HTTP header value should always be set --- packages/dart/lib/src/network/options.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/options.dart b/packages/dart/lib/src/network/options.dart index 40d3b9436..6c31e1bb4 100644 --- a/packages/dart/lib/src/network/options.dart +++ b/packages/dart/lib/src/network/options.dart @@ -3,7 +3,7 @@ part of flutter_parse_sdk; class ParseNetworkOptions { ParseNetworkOptions({this.headers}); - final Map headers; + final Map headers; // final ParseNetworkResponseType responseType; } From 8193d212db796e978b3fd8b1e4c3a94fab533436 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 15:54:17 +0100 Subject: [PATCH 021/195] sendSessionId has to be set or defaults to false --- packages/dart/lib/src/network/parse_client.dart | 2 +- packages/dart/lib/src/network/parse_dio_client.dart | 4 ++-- packages/dart/lib/src/network/parse_http_client.dart | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dart/lib/src/network/parse_client.dart b/packages/dart/lib/src/network/parse_client.dart index 3122ec5e8..da1e8a1de 100644 --- a/packages/dart/lib/src/network/parse_client.dart +++ b/packages/dart/lib/src/network/parse_client.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; typedef ParseClientCreator = ParseClient Function( - {bool sendSessionId, SecurityContext securityContext}); + {bool/*!*/ sendSessionId, SecurityContext securityContext}); abstract class ParseClient { Future get( diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index fb11a4cd9..6a9c5871d 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -9,7 +9,7 @@ class ParseDioClient extends ParseClient { _ParseDioClient _client; ParseDioClient( - {bool sendSessionId = false, SecurityContext securityContext}) { + {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) { _client = _ParseDioClient( sendSessionId: sendSessionId, securityContext: securityContext, @@ -128,7 +128,7 @@ class ParseDioClient extends ParseClient { /// Creates a custom version of HTTP Client that has Parse Data Preset class _ParseDioClient with dio.DioMixin implements dio.Dio { - _ParseDioClient({bool sendSessionId = false, SecurityContext securityContext}) + _ParseDioClient({bool/*!*/ sendSessionId = false, SecurityContext securityContext}) : _sendSessionId = sendSessionId { options = dio.BaseOptions(); httpClientAdapter = createHttpClientAdapter(securityContext); diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index 109132a7d..c9c0899f6 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -9,7 +9,7 @@ class ParseHTTPClient extends ParseClient { _ParseHTTPClient _client; ParseHTTPClient( - {bool sendSessionId = false, SecurityContext securityContext}) { + {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) { _client = _ParseHTTPClient( sendSessionId: sendSessionId, securityContext: securityContext, @@ -107,7 +107,7 @@ class ParseHTTPClient extends ParseClient { /// Creates a custom version of HTTP Client that has Parse Data Preset class _ParseHTTPClient extends http.BaseClient { _ParseHTTPClient( - {bool sendSessionId = false, SecurityContext securityContext}) + {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) : _sendSessionId = sendSessionId, _client = securityContext != null ? IOClient(HttpClient(context: securityContext)) From 261554b17a884b72e81a8817cad237b2bafa7d80 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:00:14 +0100 Subject: [PATCH 022/195] additionalHeaders is null, if not overriden --- packages/dart/lib/src/network/parse_dio_client.dart | 2 +- packages/dart/lib/src/network/parse_http_client.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 6a9c5871d..76decf51f 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -137,7 +137,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { final bool _sendSessionId; final String _userAgent = '$keyLibraryName $keySdkVersion'; ParseCoreData data = ParseCoreData(); - Map additionalHeaders; + Map/*?*/ additionalHeaders; /// Overrides the call method for HTTP Client and adds custom headers @override diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index c9c0899f6..2c6eb981d 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -117,7 +117,7 @@ class _ParseHTTPClient extends http.BaseClient { final bool _sendSessionId; final String _userAgent = '$keyLibraryName $keySdkVersion'; ParseCoreData data = ParseCoreData(); - Map additionalHeaders; + Map/*?*/ additionalHeaders; /// Overrides the call method for HTTP Client and adds custom headers @override From eaca9f74b9e88781ab5bc88249b173dde492dee9 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:07:42 +0100 Subject: [PATCH 023/195] Rename data -> parseCoreData --- .../lib/src/network/parse_http_client.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index 2c6eb981d..326156724 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -116,7 +116,7 @@ class _ParseHTTPClient extends http.BaseClient { final http.Client _client; final bool _sendSessionId; final String _userAgent = '$keyLibraryName $keySdkVersion'; - ParseCoreData data = ParseCoreData(); + ParseCoreData parseCoreData = ParseCoreData(); Map/*?*/ additionalHeaders; /// Overrides the call method for HTTP Client and adds custom headers @@ -125,16 +125,16 @@ class _ParseHTTPClient extends http.BaseClient { if (!identical(0, 0.0)) { request.headers[keyHeaderUserAgent] = _userAgent; } - request.headers[keyHeaderApplicationId] = data.applicationId; + request.headers[keyHeaderApplicationId] = parseCoreData.applicationId; if ((_sendSessionId == true) && - (data.sessionId != null) && + (parseCoreData.sessionId != null) && (request.headers[keyHeaderSessionToken] == null)) - request.headers[keyHeaderSessionToken] = data.sessionId; + request.headers[keyHeaderSessionToken] = parseCoreData.sessionId; - if (data.clientKey != null) - request.headers[keyHeaderClientKey] = data.clientKey; - if (data.masterKey != null) - request.headers[keyHeaderMasterKey] = data.masterKey; + if (parseCoreData.clientKey != null) + request.headers[keyHeaderClientKey] = parseCoreData.clientKey; + if (parseCoreData.masterKey != null) + request.headers[keyHeaderMasterKey] = parseCoreData.masterKey; /// If developer wants to add custom headers, extend this class and add headers needed. if (additionalHeaders != null && additionalHeaders.isNotEmpty) { @@ -142,7 +142,7 @@ class _ParseHTTPClient extends http.BaseClient { .forEach((String key, String value) => request.headers[key] = value); } - if (data.debug) { + if (parseCoreData.debug) { _logCUrl(request); } From 402efc68d31146f2500632a92a49ac735821da10 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:09:29 +0100 Subject: [PATCH 024/195] Remove unnecessary parantheses and == true check --- packages/dart/lib/src/network/parse_http_client.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index 326156724..551fa0ab3 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -126,9 +126,9 @@ class _ParseHTTPClient extends http.BaseClient { request.headers[keyHeaderUserAgent] = _userAgent; } request.headers[keyHeaderApplicationId] = parseCoreData.applicationId; - if ((_sendSessionId == true) && - (parseCoreData.sessionId != null) && - (request.headers[keyHeaderSessionToken] == null)) + if (_sendSessionId && + parseCoreData.sessionId != null && + request.headers[keyHeaderSessionToken] == null) request.headers[keyHeaderSessionToken] = parseCoreData.sessionId; if (parseCoreData.clientKey != null) From fd1e7144c091db81ed8ce7aaf250f7bdd76bb478 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:14:10 +0100 Subject: [PATCH 025/195] Change to BaseRequest --- packages/dart/lib/src/network/parse_http_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index 551fa0ab3..d9eb4db86 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -149,7 +149,7 @@ class _ParseHTTPClient extends http.BaseClient { return _client.send(request); } - void _logCUrl(http.Request request) { + void _logCUrl(http.BaseRequest request) { String curlCmd = 'curl'; curlCmd += ' -X ' + request.method; bool compressed = false; From 822d69fab59811611a6ef3f3dfdf26a6516628ce Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:14:23 +0100 Subject: [PATCH 026/195] Name and value are never null --- packages/dart/lib/src/network/parse_http_client.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index d9eb4db86..be78a0a59 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -154,8 +154,8 @@ class _ParseHTTPClient extends http.BaseClient { curlCmd += ' -X ' + request.method; bool compressed = false; request.headers.forEach((String name, String value) { - if (name?.toLowerCase() == 'accept-encoding' && - value?.toLowerCase() == 'gzip') { + if (name.toLowerCase() == 'accept-encoding' && + value.toLowerCase() == 'gzip') { compressed = true; } curlCmd += ' -H \'$name: $value\''; From e4af180189ebac713817cc111c6504d7208f385a Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:27:44 +0100 Subject: [PATCH 027/195] Rename data -> parseCoreData --- .../dart/lib/src/network/parse_dio_client.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 76decf51f..07b5adc61 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -136,7 +136,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { final bool _sendSessionId; final String _userAgent = '$keyLibraryName $keySdkVersion'; - ParseCoreData data = ParseCoreData(); + ParseCoreData parseCoreData = ParseCoreData(); Map/*?*/ additionalHeaders; /// Overrides the call method for HTTP Client and adds custom headers @@ -154,16 +154,16 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { if (!identical(0, 0.0)) { options.headers[keyHeaderUserAgent] = _userAgent; } - options.headers[keyHeaderApplicationId] = this.data.applicationId; + options.headers[keyHeaderApplicationId] = this.parseCoreData.applicationId; if ((_sendSessionId == true) && - (this.data.sessionId != null) && + (this.parseCoreData.sessionId != null) && (options.headers[keyHeaderSessionToken] == null)) - options.headers[keyHeaderSessionToken] = this.data.sessionId; + options.headers[keyHeaderSessionToken] = this.parseCoreData.sessionId; - if (this.data.clientKey != null) - options.headers[keyHeaderClientKey] = this.data.clientKey; - if (this.data.masterKey != null) - options.headers[keyHeaderMasterKey] = this.data.masterKey; + if (this.parseCoreData.clientKey != null) + options.headers[keyHeaderClientKey] = this.parseCoreData.clientKey; + if (this.parseCoreData.masterKey != null) + options.headers[keyHeaderMasterKey] = this.parseCoreData.masterKey; /// If developer wants to add custom headers, extend this class and add headers needed. if (additionalHeaders != null && additionalHeaders.isNotEmpty) { @@ -171,7 +171,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { .forEach((String key, String value) => options.headers[key] = value); } - if (this.data.debug) { + if (this.parseCoreData.debug) { _logCUrl(options, data, path); } From 5852ae55144b79e52af2589672182add41fa93eb Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:28:15 +0100 Subject: [PATCH 028/195] Remove unnecessary this --- .../dart/lib/src/network/parse_dio_client.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 07b5adc61..61b18dedf 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -154,16 +154,16 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { if (!identical(0, 0.0)) { options.headers[keyHeaderUserAgent] = _userAgent; } - options.headers[keyHeaderApplicationId] = this.parseCoreData.applicationId; + options.headers[keyHeaderApplicationId] = parseCoreData.applicationId; if ((_sendSessionId == true) && - (this.parseCoreData.sessionId != null) && + (parseCoreData.sessionId != null) && (options.headers[keyHeaderSessionToken] == null)) - options.headers[keyHeaderSessionToken] = this.parseCoreData.sessionId; + options.headers[keyHeaderSessionToken] = parseCoreData.sessionId; - if (this.parseCoreData.clientKey != null) - options.headers[keyHeaderClientKey] = this.parseCoreData.clientKey; - if (this.parseCoreData.masterKey != null) - options.headers[keyHeaderMasterKey] = this.parseCoreData.masterKey; + if (parseCoreData.clientKey != null) + options.headers[keyHeaderClientKey] = parseCoreData.clientKey; + if (parseCoreData.masterKey != null) + options.headers[keyHeaderMasterKey] = parseCoreData.masterKey; /// If developer wants to add custom headers, extend this class and add headers needed. if (additionalHeaders != null && additionalHeaders.isNotEmpty) { From bb4bfef34f3503b914c16da7bcd9dc6ff81e96bf Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:28:46 +0100 Subject: [PATCH 029/195] Remove unnecessary parantheses --- packages/dart/lib/src/network/parse_dio_client.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 61b18dedf..eadcab37f 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -155,9 +155,9 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { options.headers[keyHeaderUserAgent] = _userAgent; } options.headers[keyHeaderApplicationId] = parseCoreData.applicationId; - if ((_sendSessionId == true) && - (parseCoreData.sessionId != null) && - (options.headers[keyHeaderSessionToken] == null)) + if (_sendSessionId && + parseCoreData.sessionId != null && + options.headers[keyHeaderSessionToken] == null) options.headers[keyHeaderSessionToken] = parseCoreData.sessionId; if (parseCoreData.clientKey != null) From 4e87a39915202a6e436007823ecbac30e7cdf8f8 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:44:33 +0100 Subject: [PATCH 030/195] Make sure headers is never null --- packages/dart/lib/src/network/parse_dio_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index eadcab37f..e6f1a8be2 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -150,7 +150,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { ProgressCallback onSendProgress, ProgressCallback onReceiveProgress, }) { - options ??= dio.Options(); + options ??= dio.Options(headers: Map()); if (!identical(0, 0.0)) { options.headers[keyHeaderUserAgent] = _userAgent; } From ebcdebbec312654bdc4940c805729c2769f8116b Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 16:47:46 +0100 Subject: [PATCH 031/195] Name is never null --- packages/dart/lib/src/network/parse_dio_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index e6f1a8be2..5acb07650 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -191,7 +191,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { curlCmd += ' -X ' + options.method; bool compressed = false; options.headers.forEach((String name, dynamic value) { - if (name?.toLowerCase() == 'accept-encoding' && + if (name.toLowerCase() == 'accept-encoding' && value?.toString()?.toLowerCase() == 'gzip') { compressed = true; } From 80343825841c31a9d18d5e4edbf6d8eb7e47b8ff Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:15:34 +0100 Subject: [PATCH 032/195] parseClassName must be set A lot in e.g. ParseObject requires className, and would break if it is null --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- packages/dart/lib/src/objects/parse_base.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index a7a0af3dc..21e93ed3d 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -103,7 +103,7 @@ class ParseCoreData { _subClassHandler.registerFileSubClass(parseFileConstructor); } - ParseObject createObject(String classname) { + ParseObject createObject(String/*!*/ classname) { return _subClassHandler.createObject(classname); } diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 9565138d7..2d5be5cf2 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; abstract class ParseBase { - String parseClassName; + String/*!*/ parseClassName; Type type; final bool _dirty = false; // reserved property final Map _unsavedChanges = Map(); From 18b3afd4577e935371ac560257e7f1096d81bffd Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:24:32 +0100 Subject: [PATCH 033/195] list will never be null --- packages/dart/lib/src/network/parse_query.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 118bb9cfd..923857086 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -9,17 +9,15 @@ class QueryBuilder { : this(ParseCoreData.instance.createObject(classname)); QueryBuilder.or(this.object, List> list) { - if (list != null) { - String query = '"\$or":['; - for (int i = 0; i < list.length; ++i) { - if (i > 0) { - query += ','; - } - query += '{' + list[i].buildQueries(list[i].queries) + '}'; + String query = '"\$or":['; + for (int i = 0; i < list.length; ++i) { + if (i > 0) { + query += ','; } - query += ']'; - queries.add(MapEntry(_NO_OPERATOR_NEEDED, query)); + query += '{' + list[i].buildQueries(list[i].queries) + '}'; } + query += ']'; + queries.add(MapEntry(_NO_OPERATOR_NEEDED, query)); } QueryBuilder.copy(QueryBuilder query) { From e80924f622913b5728db13d2cee56423491a124b Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:34:13 +0100 Subject: [PATCH 034/195] dart(Query): Specifu compound query type Before should have worked as well, but required ignoring a lint --- packages/dart/lib/src/network/parse_query.dart | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 923857086..ac5eea5d0 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -284,8 +284,7 @@ class QueryBuilder { } // Add a constraint to the query that requires a particular key's value match another QueryBuilder - // ignore: always_specify_types - void whereMatchesQuery(String column, QueryBuilder query) { + void whereMatchesQuery(String column, QueryBuilder query) { final String inQuery = query._buildQueryRelational(query.object.parseClassName); @@ -294,8 +293,7 @@ class QueryBuilder { } //Add a constraint to the query that requires a particular key's value does not match another QueryBuilder - // ignore: always_specify_types - void whereDoesNotMatchQuery(String column, QueryBuilder query) { + void whereDoesNotMatchQuery(String column, QueryBuilder query) { final String inQuery = query._buildQueryRelational(query.object.parseClassName); @@ -304,9 +302,8 @@ class QueryBuilder { } // Add a constraint to the query that requires a particular key's value matches a value for a key in the results of another ParseQuery. - // ignore: always_specify_types - void whereMatchesKeyInQuery( - String column, String keyInQuery, QueryBuilder query) { + void whereMatchesKeyInQuery( + String column, String keyInQuery, QueryBuilder query) { if (query.queries.isEmpty) { throw ArgumentError('query conditions is required'); } @@ -325,9 +322,8 @@ class QueryBuilder { } // Add a constraint to the query that requires a particular key's value does not match any value for a key in the results of another ParseQuery - // ignore: always_specify_types - void whereDoesNotMatchKeyInQuery( - String column, String keyInQuery, QueryBuilder query) { + void whereDoesNotMatchKeyInQuery( + String column, String keyInQuery, QueryBuilder query) { if (query.queries.isEmpty) { throw ArgumentError('query conditions is required'); } From b08a5190d5388ff5ef7ffebf564205a702956dbb Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:44:44 +0100 Subject: [PATCH 035/195] dart(lint): Use collection literals --- packages/dart/lib/src/network/parse_query.dart | 4 ++-- packages/dart/lib/src/objects/parse_object.dart | 8 ++++---- .../lib/src/objects/response/parse_response_builder.dart | 4 ++-- packages/dart/lib/src/utils/parse_live_list.dart | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index ac5eea5d0..dfa6ddbc5 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -444,8 +444,8 @@ class QueryBuilder { List> _checkForMultipleColumnInstances( List> queries) { final List> sanitizedQueries = - List>(); - final List keysAlreadyCompacted = List(); + >[]; + final List keysAlreadyCompacted = []; // Run through each query for (final MapEntry query in queries) { diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index ab9d53d12..8da77a77b 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -141,16 +141,16 @@ class ParseObject extends ParseBase implements ParseCloneable { } } List remaining = uniqueObjects.toList(); - final List finished = List(); + final List finished = []; final ParseResponse totalResponse = ParseResponse() ..success = true - ..results = List() + ..results = [] ..statusCode = 200; while (remaining.isNotEmpty) { /* Partition the objects into two sets: those that can be save immediately, and those that rely on other objects to be created first. */ - final List current = List(); - final List nextBatch = List(); + final List current = []; + final List nextBatch = []; for (ParseObject object in remaining) { if (object._canbeSerialized(finished)) { current.add(object); diff --git a/packages/dart/lib/src/objects/response/parse_response_builder.dart b/packages/dart/lib/src/objects/response/parse_response_builder.dart index 22663165e..5917a884e 100644 --- a/packages/dart/lib/src/objects/response/parse_response_builder.dart +++ b/packages/dart/lib/src/objects/response/parse_response_builder.dart @@ -70,7 +70,7 @@ class _ParseResponseBuilder { final List list = result; if (object is List && object.length == list.length) { response.count = object.length; - response.results = List(); + response.results = []; for (int i = 0; i < object.length; i++) { final Map objectResult = list[i]; if (objectResult.containsKey('success')) { @@ -119,7 +119,7 @@ class _ParseResponseBuilder { /// Handles a response with a multiple result object List _handleMultipleResults(T object, List data) { - final List resultsList = List(); + final List resultsList = []; for (dynamic value in data) { resultsList.add(_handleSingleResult(object, value, true)); } diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index fd29f9235..6577a2fe6 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -36,7 +36,7 @@ class ParseLiveList { final bool _lazyLoading; final List _preloadedColumns; - List> _list = List>(); + List> _list = >[]; StreamController> _eventStreamController; int _nextID = 0; bool _debug; @@ -46,7 +46,7 @@ class ParseLiveList { /// is object1 listed after object2? /// can return null bool after(T object1, T object2) { - List fields = List(); + List fields = []; if (_query.limiters.containsKey('order')) { fields = _query.limiters['order'].toString().split(','); @@ -159,7 +159,7 @@ class ParseLiveList { updatedSubItems: _listeningIncludes, loaded: !_lazyLoading)) ?.toList() ?? - List>(); + >[]; } LiveQuery() @@ -202,7 +202,7 @@ class ParseLiveList { List> tasks = >[]; final ParseResponse parseResponse = await _runQuery(); if (parseResponse.success) { - final List newList = parseResponse.results ?? List(); + final List newList = parseResponse.results ?? []; //update List for (int i = 0; i < _list.length; i++) { From 359180333bfb8f4f38dab491ce13754d05f9c6ec Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:45:32 +0100 Subject: [PATCH 036/195] dart(lint): Prefer const constructor --- packages/dart/lib/src/objects/parse_installation.dart | 2 +- packages/dart/lib/src/objects/parse_user.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index 865f1247a..eee64672a 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -149,7 +149,7 @@ class ParseInstallation extends ParseObject { /// Assumes that this is called because there is no previous installation /// so it creates and sets the static current installation UUID static Future _createInstallation() async { - _currentInstallationId ??= Uuid().v4(); + _currentInstallationId ??= const Uuid().v4(); final ParseInstallation installation = ParseInstallation(); installation._installationId = _currentInstallationId; diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 234118670..6971b249a 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -243,7 +243,7 @@ class ParseUser extends ParseObject implements ParseCloneable { forgetLocalSession(); try { final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); - final Uuid uuid = Uuid(); + const Uuid uuid = Uuid(); final String installationId = await _getInstallationId(); final ParseNetworkResponse response = await _client.post( From fb5efad23094d233457a15ab27c25b40e195006e Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:48:29 +0100 Subject: [PATCH 037/195] dart(lint): Fix sort constuctors and others --- packages/dart/lib/src/network/parse_client.dart | 10 +++++----- packages/dart/lib/src/network/parse_dio_client.dart | 6 +++--- packages/dart/lib/src/network/parse_http_client.dart | 4 ++-- packages/dart/lib/src/objects/parse_user.dart | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/dart/lib/src/network/parse_client.dart b/packages/dart/lib/src/network/parse_client.dart index da1e8a1de..f30f8ca7f 100644 --- a/packages/dart/lib/src/network/parse_client.dart +++ b/packages/dart/lib/src/network/parse_client.dart @@ -79,18 +79,16 @@ abstract class ParseClient { typedef ProgressCallback = void Function(int count, int total); class ParseNetworkResponse { - final String/*!*/ data; - final int statusCode; - ParseNetworkResponse({ this.data, this.statusCode = -1, }); + + final String/*!*/ data; + final int statusCode; } class ParseNetworkByteResponse extends ParseNetworkResponse { - final List bytes; - ParseNetworkByteResponse({ this.bytes, final String data = 'byte response', @@ -99,4 +97,6 @@ class ParseNetworkByteResponse extends ParseNetworkResponse { data: data, statusCode: statusCode, ); + + final List bytes; } diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 5acb07650..05ee9d5ee 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -6,8 +6,6 @@ import 'package:parse_server_sdk/parse_server_sdk.dart'; import 'dio_adapter_io.dart' if (dart.library.js) 'dio_adapter_js.dart'; class ParseDioClient extends ParseClient { - _ParseDioClient _client; - ParseDioClient( {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) { _client = _ParseDioClient( @@ -16,6 +14,8 @@ class ParseDioClient extends ParseClient { ); } + _ParseDioClient _client; + @override Future get( String path, { @@ -171,7 +171,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { .forEach((String key, String value) => options.headers[key] = value); } - if (this.parseCoreData.debug) { + if (parseCoreData.debug) { _logCUrl(options, data, path); } diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index be78a0a59..0a7fc61b1 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -6,8 +6,6 @@ import 'package:http/io_client.dart'; import 'package:parse_server_sdk/parse_server_sdk.dart'; class ParseHTTPClient extends ParseClient { - _ParseHTTPClient _client; - ParseHTTPClient( {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) { _client = _ParseHTTPClient( @@ -16,6 +14,8 @@ class ParseHTTPClient extends ParseClient { ); } + _ParseHTTPClient _client; + @override Future get( String path, { diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 6971b249a..24c84ffe7 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -51,7 +51,8 @@ class ParseUser extends ParseObject implements ParseCloneable { set password(String password) { if (_password != password) { _password = password; - if (password != null) _unsavedChanges[keyVarPassword] = password; + if (password != null) + _unsavedChanges[keyVarPassword] = password; } } From 04ed7aca0c88aad81ddfec86ffefb0ccbc131329 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 17:49:56 +0100 Subject: [PATCH 038/195] dart(lint): Future -> Future --- packages/dart/lib/src/network/parse_websocket_html.dart | 2 +- packages/dart/lib/src/network/parse_websocket_io.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_websocket_html.dart b/packages/dart/lib/src/network/parse_websocket_html.dart index aeab1d27c..1ad8a3007 100644 --- a/packages/dart/lib/src/network/parse_websocket_html.dart +++ b/packages/dart/lib/src/network/parse_websocket_html.dart @@ -23,7 +23,7 @@ class WebSocket { int get readyState => _webSocket.readyState; - Future close() async { + Future close() async { return _webSocket.close(); } diff --git a/packages/dart/lib/src/network/parse_websocket_io.dart b/packages/dart/lib/src/network/parse_websocket_io.dart index 37206dd49..fb69bd5fa 100644 --- a/packages/dart/lib/src/network/parse_websocket_io.dart +++ b/packages/dart/lib/src/network/parse_websocket_io.dart @@ -21,7 +21,7 @@ class WebSocket { int get readyState => _webSocket.readyState; - Future close() { + Future close() { return _webSocket.close(); } From b5182acf594154aea45d1220e58c1e7f598655ba Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 20:43:45 +0100 Subject: [PATCH 039/195] _requestSubScription => _requestSubscription --- .../dart/lib/src/network/parse_live_query.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 656911054..70147c8d5 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -167,7 +167,7 @@ class LiveQueryClient { Stream _clientEventStream; LiveQueryReconnectingController reconnectingController; - final Map _requestSubScription = {}; + final Map _requestSubscription = {}; Future reconnect({bool userInitialized = false}) async { await _connect(userInitialized: userInitialized); @@ -197,7 +197,7 @@ class LiveQueryClient { await _channel.sink.close(); _channel = null; } - _requestSubScription.values.toList().forEach((Subscription subscription) { + _requestSubscription.values.toList().forEach((Subscription subscription) { subscription._enabled = false; }); _connecting = false; @@ -216,7 +216,7 @@ class LiveQueryClient { final int requestId = _requestIdGenerator(); final Subscription subscription = Subscription(query, requestId, copyObject: copyObject); - _requestSubScription[requestId] = subscription; + _requestSubscription[requestId] = subscription; //After a client connects to the LiveQuery server, //it can send a subscribe message to subscribe a ParseQuery. _subscribeLiveQuery(subscription); @@ -235,7 +235,7 @@ class LiveQueryClient { } _channel.sink.add(jsonEncode(unsubscribeMessage)); subscription._enabled = false; - _requestSubScription.remove(subscription.requestId); + _requestSubscription.remove(subscription.requestId); } } @@ -371,16 +371,16 @@ class LiveQueryClient { Subscription subscription; if (actionData.containsKey('op') && actionData['op'] == 'connected') { - print('ReSubScription:$_requestSubScription'); + print('ReSubScription:$_requestSubscription'); - _requestSubScription.values.toList().forEach((Subscription subcription) { + _requestSubscription.values.toList().forEach((Subscription subcription) { _subscribeLiveQuery(subcription); }); _clientEventStreamController.sink.add(LiveQueryClientEvent.CONNECTED); return; } if (actionData.containsKey('requestId')) { - subscription = _requestSubScription[actionData['requestId']]; + subscription = _requestSubscription[actionData['requestId']]; } if (subscription == null) { return; From 8955f463446eb4300b645366c4a5ea4732a465c3 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 22:30:07 +0100 Subject: [PATCH 040/195] dart: LiveQueryClient._getInstance never null --- packages/dart/lib/src/network/parse_live_query.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 70147c8d5..73457cb4c 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -146,7 +146,7 @@ class LiveQueryClient { } static LiveQueryClient get instance => _getInstance(); static LiveQueryClient _instance; - static LiveQueryClient _getInstance( + static LiveQueryClient/*!*/ _getInstance( {bool debug, ParseClient client, bool autoSendSessionId}) { _instance ??= LiveQueryClient._internal( debug: debug, autoSendSessionId: autoSendSessionId); From f80d18d334491c41adc1c99fdc4fece389913889 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 22:34:29 +0100 Subject: [PATCH 041/195] dart(LiveQuery): ParseClient is never used --- .../dart/lib/src/network/parse_live_query.dart | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 73457cb4c..6752eea8c 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -147,7 +147,7 @@ class LiveQueryClient { static LiveQueryClient get instance => _getInstance(); static LiveQueryClient _instance; static LiveQueryClient/*!*/ _getInstance( - {bool debug, ParseClient client, bool autoSendSessionId}) { + {bool debug, bool autoSendSessionId}) { _instance ??= LiveQueryClient._internal( debug: debug, autoSendSessionId: autoSendSessionId); return _instance; @@ -408,21 +408,14 @@ class LiveQueryClient { } class LiveQuery { - LiveQuery({bool debug, ParseClient client, bool autoSendSessionId}) { - _client = client ?? - ParseCoreData().clientCreator( - sendSessionId: - autoSendSessionId ?? ParseCoreData().autoSendSessionId, - securityContext: ParseCoreData().securityContext); - + LiveQuery({bool debug, bool autoSendSessionId}) { _debug = isDebugEnabled(objectLevelDebug: debug); _sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true; - this.client = LiveQueryClient._getInstance( - client: _client, debug: _debug, autoSendSessionId: _sendSessionId); + client = LiveQueryClient._getInstance( + debug: _debug, autoSendSessionId: _sendSessionId); } - ParseClient _client; bool _debug; bool _sendSessionId; Subscription _latestSubscription; From 17d35f743559d6b71fb4a4725e7956aca9d58075 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 22:44:47 +0100 Subject: [PATCH 042/195] dart(LiveQuery): Remove deprecated code --- .../lib/src/network/parse_live_query.dart | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 6752eea8c..c2945c4f1 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -410,30 +410,12 @@ class LiveQueryClient { class LiveQuery { LiveQuery({bool debug, bool autoSendSessionId}) { _debug = isDebugEnabled(objectLevelDebug: debug); - _sendSessionId = - autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true; + _sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId; client = LiveQueryClient._getInstance( debug: _debug, autoSendSessionId: _sendSessionId); } bool _debug; bool _sendSessionId; - Subscription _latestSubscription; LiveQueryClient client; - - @deprecated - Future subscribe(QueryBuilder query) async { - _latestSubscription = await client.subscribe(query); - return _latestSubscription; - } - - @deprecated - Future unSubscribe() async { - client.unSubscribe(_latestSubscription); - } - - @deprecated - void on(LiveQueryEvent op, Function callback) { - _latestSubscription.on(op, callback); - } } From daf5ca554c40dcaa77ac6189c076225c5bda19ac Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 22:45:20 +0100 Subject: [PATCH 043/195] dart(LiveQuery): _clientEventStream is never null Use late keyword --- packages/dart/lib/src/network/parse_live_query.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index c2945c4f1..4e1554cfe 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -164,7 +164,7 @@ class LiveQueryClient { String _liveQueryURL; bool _connecting = false; StreamController _clientEventStreamController; - Stream _clientEventStream; + Stream/*!*/ _clientEventStream; LiveQueryReconnectingController reconnectingController; final Map _requestSubscription = {}; From 3cb0e47e8d275c53b72c4e546ee34009c4fb7014 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 22:50:32 +0100 Subject: [PATCH 044/195] dart(utils): No need to assing, just return --- packages/dart/lib/src/utils/parse_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/utils/parse_utils.dart b/packages/dart/lib/src/utils/parse_utils.dart index 4c46ad7c4..478204f5e 100644 --- a/packages/dart/lib/src/utils/parse_utils.dart +++ b/packages/dart/lib/src/utils/parse_utils.dart @@ -5,7 +5,7 @@ part of flutter_parse_sdk; /// Debug can be set in 2 places, one global param in the Parse.initialize, and /// then can be overwritten class by class bool isDebugEnabled({bool objectLevelDebug}) { - return objectLevelDebug ??= ParseCoreData().debug; + return objectLevelDebug ?? ParseCoreData().debug; } /// Converts the object to the correct value for JSON, From f63f61d69bfe441a8787c5df0bfc372588b7197a Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:02:13 +0100 Subject: [PATCH 045/195] dart(LiveQuery): Add assert if liveQueryUrl set This informs the user to set liveQueryUrl before using liveQueries --- packages/dart/lib/src/network/parse_live_query.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 4e1554cfe..d2b8062dc 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -135,6 +135,8 @@ class LiveQueryClient { _sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true; _liveQueryURL = ParseCoreData().liveQueryURL; + assert(_liveQueryURL != null, + 'liveQueryUrl is not set. For how to setup Live Queries, see https://github.com/parse-community/Parse-SDK-Flutter/tree/master/packages/flutter#live-queries.'); if (_liveQueryURL.contains('https')) { _liveQueryURL = _liveQueryURL.replaceAll('https', 'wss'); } else if (_liveQueryURL.contains('http')) { From 5294522c01359768143237108297137abe8205eb Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:04:29 +0100 Subject: [PATCH 046/195] dart(LiveQuery): _debug is never null --- packages/dart/lib/src/network/parse_live_query.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index d2b8062dc..036460876 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -160,7 +160,7 @@ class LiveQueryClient { } parse_web_socket.WebSocket _webSocket; - bool _debug; + bool/*!*/ _debug; bool _sendSessionId; WebSocketChannel _channel; String _liveQueryURL; From 1fbc50bd0531f1e11de5a6c36a4b5a62254d7386 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:13:14 +0100 Subject: [PATCH 047/195] dart(LiveQuery): reconnectingController is never null --- packages/dart/lib/src/network/parse_live_query.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 036460876..4a458eb03 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -167,7 +167,7 @@ class LiveQueryClient { bool _connecting = false; StreamController _clientEventStreamController; Stream/*!*/ _clientEventStream; - LiveQueryReconnectingController reconnectingController; + LiveQueryReconnectingController/*!*/ reconnectingController; final Map _requestSubscription = {}; From 41e004eaa84bb45ee298626f4b79da54b1e37b15 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:29:20 +0100 Subject: [PATCH 048/195] dart(LiveQuery): Add more not nullable annotation --- packages/dart/lib/src/network/parse_live_query.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 4a458eb03..6d8a56693 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -307,7 +307,7 @@ class LiveQueryClient { } //The connect message is sent from a client to the LiveQuery server. //It should be the first message sent from a client after the WebSocket connection is established. - final Map connectMessage = { + final Map connectMessage = { 'op': 'connect', 'applicationId': ParseCoreData().applicationId }; @@ -338,7 +338,7 @@ class LiveQueryClient { final String _where = query.buildQuery().replaceAll('where=', ''); //Convert where condition to Map - Map _whereMap = Map(); + Map/*!*/ _whereMap = Map(); if (_where != '') { _whereMap = json.decode(_where); } From 0c4d6dfb6106ccbe95e5f362c40e44ab56f63f3d Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:31:49 +0100 Subject: [PATCH 049/195] dart(CoreData): instance is always set --- packages/dart/lib/src/data/parse_core_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 21e93ed3d..9903dae37 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -8,7 +8,7 @@ class ParseCoreData { static ParseCoreData _instance; - static ParseCoreData get instance => _instance; + static ParseCoreData/*!*/ get instance => _instance; /// Creates an instance of Parse Server /// From ceecef7d607e72e8e22958cd809d4de7789a16af Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:41:48 +0100 Subject: [PATCH 050/195] dart(ACL): No need to check for null --- packages/dart/lib/src/objects/parse_acl.dart | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index 8ab3d9ec5..040c8a0be 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -52,9 +52,6 @@ class ParseACL { ///Set whether the given user id is allowed to read this object. void setReadAccess({@required String userId, bool allowed = true}) { - if (userId == null) { - throw 'cannot setReadAccess for null userId'; - } final bool writePermission = getWriteAccess(userId: userId); _setPermissionsIfNonEmpty( userId: userId, @@ -66,18 +63,12 @@ class ParseACL { /// [false], the user may still be able to access it if getPublicReadAccess returns /// [true] or a role that the user belongs to has read access. bool getReadAccess({@required String userId}) { - if (userId == null) { - throw 'cannot getReadAccess for null userId'; - } final _ACLPermissions _permissions = _permissionsById[userId]; return _permissions != null && _permissions.getReadPermission(); } ///Set whether the given user id is allowed to write this object. void setWriteAccess({@required String userId, bool allowed = true}) { - if (userId == null) { - throw 'cannot setWriteAccess for null userId'; - } final bool readPermission = getReadAccess(userId: userId); _setPermissionsIfNonEmpty( userId: userId, @@ -89,9 +80,6 @@ class ParseACL { ///returns [false], the user may still be able to write it if getPublicWriteAccess returns ///[true] or a role that the user belongs to has write access. bool getWriteAccess({@required String userId}) { - if (userId == null) { - throw 'cannot getWriteAccess for null userId'; - } final _ACLPermissions _permissions = _permissionsById[userId]; return _permissions != null && _permissions.getWritePermission(); } From 9bc4be30c209d6ce3f5e47d994a4f026592ab42c Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:53:44 +0100 Subject: [PATCH 051/195] dart(ACL): Improve toJson --- packages/dart/lib/src/objects/parse_acl.dart | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index 040c8a0be..712311e06 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -125,14 +125,8 @@ class _ACLPermissions { return _writePermission; } - Map toJson() { - final Map map = {}; - if (_readPermission) { - map[_keyReadPermission] = true; - } - if (_writePermission) { - map[_keyWritePermission] = true; - } - return map; - } + Map toJson() => { + _keyReadPermission: _readPermission, + _keyWritePermission: _writePermission + }; } From b5fd6747d066e5dd616283b77564d642dd73c32b Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:54:16 +0100 Subject: [PATCH 052/195] dart(ACL): Make internal function params required --- packages/dart/lib/src/objects/parse_acl.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index 712311e06..db36fd002 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -21,7 +21,9 @@ class ParseACL { /// Helper for setting stuff void _setPermissionsIfNonEmpty( - {@required String userId, bool readPermission, bool writePermission}) { + {@required String userId, + @required bool readPermission, + @required bool writePermission}) { if (!(readPermission || writePermission)) { _permissionsById.remove(userId); } else { From c82c4aa7e29bf2e877679c65f28cafb10d2e8883 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Wed, 17 Mar 2021 23:54:43 +0100 Subject: [PATCH 053/195] dart(ACL): writePermissions is always set --- packages/dart/lib/src/objects/parse_acl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index db36fd002..94bb22205 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -117,7 +117,7 @@ class _ACLPermissions { final String _keyReadPermission = 'read'; final String _keyWritePermission = 'write'; final bool _readPermission; - final bool _writePermission; + final bool/*!*/ _writePermission; bool getReadPermission() { return _readPermission; From 7f8b7e6497a24ac69592894fb708f6bd4938add3 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 00:06:05 +0100 Subject: [PATCH 054/195] dart(ACL): Simplify code --- packages/dart/lib/src/objects/parse_acl.dart | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index 94bb22205..0906ffe03 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -65,8 +65,7 @@ class ParseACL { /// [false], the user may still be able to access it if getPublicReadAccess returns /// [true] or a role that the user belongs to has read access. bool getReadAccess({@required String userId}) { - final _ACLPermissions _permissions = _permissionsById[userId]; - return _permissions != null && _permissions.getReadPermission(); + return _permissionsById[userId]?.readPermission ?? false; } ///Set whether the given user id is allowed to write this object. @@ -82,8 +81,7 @@ class ParseACL { ///returns [false], the user may still be able to write it if getPublicWriteAccess returns ///[true] or a role that the user belongs to has write access. bool getWriteAccess({@required String userId}) { - final _ACLPermissions _permissions = _permissionsById[userId]; - return _permissions != null && _permissions.getWritePermission(); + return _permissionsById[userId]?.writePermission ?? false; } Map toJson() { @@ -119,16 +117,12 @@ class _ACLPermissions { final bool _readPermission; final bool/*!*/ _writePermission; - bool getReadPermission() { - return _readPermission; - } + bool get readPermission => _readPermission; - bool getWritePermission() { - return _writePermission; - } + bool get writePermission => _writePermission; Map toJson() => { - _keyReadPermission: _readPermission, - _keyWritePermission: _writePermission - }; + _keyReadPermission: _readPermission, + _keyWritePermission: _writePermission + }; } From 6fe987f6380928666fed024f2aea1b317ef20630 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 00:06:34 +0100 Subject: [PATCH 055/195] dart(ACL): Set to non-nullable --- packages/dart/lib/src/objects/parse_acl.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index 0906ffe03..ad7794fb3 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -21,9 +21,9 @@ class ParseACL { /// Helper for setting stuff void _setPermissionsIfNonEmpty( - {@required String userId, + {@required String/*!*/ userId, @required bool readPermission, - @required bool writePermission}) { + @required bool/*!*/ writePermission}) { if (!(readPermission || writePermission)) { _permissionsById.remove(userId); } else { From 34862ab2bab7f1f844b8a30bae10496d98e730ca Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 01:02:10 +0100 Subject: [PATCH 056/195] dart(Base): _objectData is never null --- packages/dart/lib/src/objects/parse_base.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 2d5be5cf2..f4919b3ef 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -163,8 +163,7 @@ abstract class ParseBase { /// Returns the objects variables @protected - Map _getObjectData() => - _objectData ?? Map(); + Map _getObjectData() => _objectData; bool containsValue(Object value) { return _getObjectData().containsValue(value); From 569c26e38c24d3ef1379834343df46282b42c1ce Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 01:09:06 +0100 Subject: [PATCH 057/195] dart(Base): Fix returning after first passthrough --- packages/dart/lib/src/objects/parse_base.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index f4919b3ef..90df4d324 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -46,7 +46,6 @@ abstract class ParseBase { if (value is ParseObject && value._areChildrenDirty(seenObjects)) { match = true; } - return false; }); return match; } From b77ea0a5f2893b02b06e3db622487fe9b9e3bf2b Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:05:58 +0100 Subject: [PATCH 058/195] dart(base): Type type is never assigned or used --- packages/dart/lib/src/objects/parse_base.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 90df4d324..53925d9f1 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -2,7 +2,6 @@ part of flutter_parse_sdk; abstract class ParseBase { String/*!*/ parseClassName; - Type type; final bool _dirty = false; // reserved property final Map _unsavedChanges = Map(); final Map _savingChanges = Map(); From b9f15fc575bf6d77c5cc1725ecb174a8cf9c90cb Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:13:38 +0100 Subject: [PATCH 059/195] dart(base): Can only be String and nothing else --- packages/dart/lib/src/objects/parse_base.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 53925d9f1..07f6f890c 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -167,11 +167,11 @@ abstract class ParseBase { return _getObjectData().containsValue(value); } - bool containsKey(Object key) { + bool containsKey(String key) { return _getObjectData().containsKey(key); } - dynamic operator [](Object key) { + dynamic operator [](String key) { return get(key); } From d2ad107641e8d953451e28e4f4498a0ab21fda7d Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:19:26 +0100 Subject: [PATCH 060/195] dart(base): generic type T cannot be null --- packages/dart/lib/src/objects/parse_base.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 07f6f890c..118e9ac82 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -230,7 +230,7 @@ abstract class ParseBase { /// provided T get(String key, {T defaultValue}) { if (_getObjectData().containsKey(key)) { - if (T != null && _getObjectData()[key] is T) { + if (_getObjectData()[key] is T) { final T data = _getObjectData()[key]; return data; } else { From 0b879905eb7a0efdea36900be337b0dbca9e0af6 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:24:35 +0100 Subject: [PATCH 061/195] dart(base): This will always be casted to T --- packages/dart/analysis_options.yaml | 0 packages/dart/lib/src/objects/parse_base.dart | 7 +------ 2 files changed, 1 insertion(+), 6 deletions(-) create mode 100644 packages/dart/analysis_options.yaml diff --git a/packages/dart/analysis_options.yaml b/packages/dart/analysis_options.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 118e9ac82..5cc400392 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -230,12 +230,7 @@ abstract class ParseBase { /// provided T get(String key, {T defaultValue}) { if (_getObjectData().containsKey(key)) { - if (_getObjectData()[key] is T) { - final T data = _getObjectData()[key]; - return data; - } else { - return _getObjectData()[key]; - } + return _getObjectData()[key] as T; } else { return defaultValue; } From 6f1448305f45bd25abf0b716792fbd8fd5a8ab2a Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:45:08 +0100 Subject: [PATCH 062/195] dart: Default full=false for toJson,parseEncode --- packages/dart/lib/src/objects/parse_base.dart | 2 +- packages/dart/lib/src/utils/parse_encoder.dart | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 5cc400392..a67102a56 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -72,7 +72,7 @@ abstract class ParseBase { /// Converts object to [String] in JSON format @protected Map toJson({ - bool full, + bool full = false, bool forApiRQ = false, bool allowCustomObjectId = false, }) { diff --git a/packages/dart/lib/src/utils/parse_encoder.dart b/packages/dart/lib/src/utils/parse_encoder.dart index 50e8e7f82..66ff7d558 100644 --- a/packages/dart/lib/src/utils/parse_encoder.dart +++ b/packages/dart/lib/src/utils/parse_encoder.dart @@ -9,9 +9,7 @@ dynamic dateTimeEncoder(dynamic item) { } /// Custom json encoder for types related to parse -dynamic parseEncode(dynamic value, {bool full}) { - full ??= false; - +dynamic parseEncode(dynamic value, {bool full = false}) { if (value is Uint8List) { return _encodeUint8List(value); } From 16e0ad283142ba1eb006906b4fd3445342995a57 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:48:27 +0100 Subject: [PATCH 063/195] dart(base): fromJson expects non-null --- packages/dart/lib/src/objects/parse_base.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index a67102a56..e7637bf5d 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -119,10 +119,6 @@ abstract class ParseBase { String toString() => json.encode(toJson()); dynamic fromJson(Map objectData) { - if (objectData == null) { - return this; - } - objectData.forEach((String key, dynamic value) { if (key == parseClassName || key == '__type') { // NO OP From c9e6354e2af4f4a418759a061f505a86c279eda8 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:51:47 +0100 Subject: [PATCH 064/195] dart(base): value cannot be null anymore --- packages/dart/lib/src/objects/parse_base.dart | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index e7637bf5d..81c1c0179 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -190,19 +190,17 @@ abstract class ParseBase { /// To set an int, call setType and an int will be saved /// [bool] forceUpdate is always true, if unsure as to whether an item is /// needed or not, set to false - void set(String key, T value, {bool forceUpdate = true}) { - if (value != null) { - if (_getObjectData().containsKey(key)) { - if (_getObjectData()[key] == value && !forceUpdate) { - return; - } - _getObjectData()[key] = - ParseMergeTool().mergeWithPrevious(_unsavedChanges[key], value); - } else { - _getObjectData()[key] = value; + void set(String/*!*/ key, T value, {bool forceUpdate = true}) { + if (_getObjectData().containsKey(key)) { + if (_getObjectData()[key] == value && !forceUpdate) { + return; } - _unsavedChanges[key] = _getObjectData()[key]; + _getObjectData()[key] = + ParseMergeTool().mergeWithPrevious(_unsavedChanges[key], value); + } else { + _getObjectData()[key] = value; } + _unsavedChanges[key] = _getObjectData()[key]; } ///Set the [ParseACL] governing this object. From 603f95aa16ef1c63fbc4c39eeab7b710a6835ec5 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 13:53:47 +0100 Subject: [PATCH 065/195] dart(base): Reorder methods --- packages/dart/lib/src/objects/parse_base.dart | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 81c1c0179..041d4e051 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -203,20 +203,6 @@ abstract class ParseBase { _unsavedChanges[key] = _getObjectData()[key]; } - ///Set the [ParseACL] governing this object. - void setACL(ParseACL acl) { - set(keyVarAcl, acl); - } - - ///Access the [ParseACL] governing this object. - ParseACL getACL() { - if (_getObjectData().containsKey(keyVarAcl)) { - return _getObjectData()[keyVarAcl]; - } else { - return ParseACL(); - } - } - /// Gets type [T] from objectData /// /// Returns null or [defaultValue] if provided. To get an int, call @@ -274,6 +260,20 @@ abstract class ParseBase { Map toPointer() => encodeObject(parseClassName, objectId); + ///Set the [ParseACL] governing this object. + void setACL(ParseACL acl) { + set(keyVarAcl, acl); + } + + ///Access the [ParseACL] governing this object. + ParseACL getACL() { + if (_getObjectData().containsKey(keyVarAcl)) { + return _getObjectData()[keyVarAcl]; + } else { + return ParseACL(); + } + } + /// Deprecated @Deprecated('Prefer to use parseClassName') String className; From 1f37479ad039815f56593878ea285d70ee5e6307 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:08:24 +0100 Subject: [PATCH 066/195] dart(base): Remove deprecated getObjectData() etc. --- packages/dart/lib/src/objects/parse_base.dart | 21 ------------------- .../dart/lib/src/utils/parse_live_list.dart | 8 +++---- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 041d4e051..db5684971 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -273,25 +273,4 @@ abstract class ParseBase { return ParseACL(); } } - - /// Deprecated - @Deprecated('Prefer to use parseClassName') - String className; - - @Deprecated('Prefer to use parseClassName') - String getClassName() => parseClassName; - - @Deprecated('Prefer to use parseClassName') - String setClassName(String className) => parseClassName = className; - - @protected - @Deprecated( - 'Prefer to use _getObjectData method, or operator [] for certain key.') - Map getObjectData() => _getObjectData(); - - @protected - @Deprecated( - 'Prefer to use _setObjectData method, or operator [] for certain key.') - void setObjectData(Map objectData) => - _setObjectData(objectData); } diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 6577a2fe6..0265cb5f8 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -288,13 +288,13 @@ class ParseLiveList { if (parseResponse.success && parseResponse.results.length == 1) { // ignore: deprecated_member_use_from_same_package - object.getObjectData()[key] = parseResponse.results[0]; + object[key] = parseResponse.results[0]; } })); continue; } else { // ignore: deprecated_member_use_from_same_package - object.getObjectData()[key] = includedObject; + object[key] = includedObject; //recursion loadingNodes .add(_loadIncludes(includedObject, paths: paths[key])); @@ -311,7 +311,7 @@ class ParseLiveList { queryBuilder.query().then((ParseResponse parseResponse) { if (parseResponse.success && parseResponse.results.length == 1) { // ignore: deprecated_member_use_from_same_package - object.getObjectData()[key] = parseResponse.results[0]; + object[key] = parseResponse.results[0]; } })); continue; @@ -626,7 +626,7 @@ class ParseLiveListElement { await ParseLiveList._loadIncludes(newObject, oldObject: subObject, paths: _toKeyMap(path)); // ignore: deprecated_member_use_from_same_package - parentObject.getObjectData()[currentKey.key] = newObject; + parentObject[currentKey.key] = newObject; if (!_streamController.isClosed) { _streamController ?.add(_object?.clone(_object?.toJson(full: true))); From bad599e0b1c59f000bdffc5c1564f5f0ea9e4e73 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:10:00 +0100 Subject: [PATCH 067/195] dart(base): Finish null-safety annotation --- packages/dart/lib/src/objects/parse_base.dart | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index db5684971..34975af2a 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -3,11 +3,11 @@ part of flutter_parse_sdk; abstract class ParseBase { String/*!*/ parseClassName; final bool _dirty = false; // reserved property - final Map _unsavedChanges = Map(); - final Map _savingChanges = Map(); + final Map _unsavedChanges = Map(); + final Map _savingChanges = Map(); /// Stores all the values of a class - Map _objectData = Map(); + Map/*!*/ _objectData = Map(); /// Returns [String] objectId String get objectId => get(keyVarObjectId); @@ -52,8 +52,8 @@ abstract class ParseBase { /// Returns [DateTime] createdAt DateTime get createdAt { if (get(keyVarCreatedAt) is String) { - final String dateAsString = get(keyVarCreatedAt); - return _parseDateFormat.parse(dateAsString); + final String/*?*/ dateAsString = get(keyVarCreatedAt); + return dateAsString != null ? _parseDateFormat.parse(dateAsString) : null; } else { return get(keyVarCreatedAt); } @@ -62,8 +62,8 @@ abstract class ParseBase { /// Returns [DateTime] updatedAt DateTime get updatedAt { if (get(keyVarUpdatedAt) is String) { - final String dateAsString = get(keyVarUpdatedAt); - return _parseDateFormat.parse(dateAsString); + final String/*?*/ dateAsString = get(keyVarUpdatedAt); + return dateAsString != null ? _parseDateFormat.parse(dateAsString) : null; } else { return get(keyVarUpdatedAt); } @@ -157,7 +157,7 @@ abstract class ParseBase { /// Returns the objects variables @protected - Map _getObjectData() => _objectData; + Map _getObjectData() => _objectData; bool containsValue(Object value) { return _getObjectData().containsValue(value); @@ -247,14 +247,12 @@ abstract class ParseBase { /// /// Replicates Android SDK pin process and saves object to storage dynamic fromPin(String objectId) async { - if (objectId != null) { final CoreStore coreStore = ParseCoreData().getStore(); final String itemFromStore = await coreStore.getString(objectId); if (itemFromStore != null) { return fromJson(json.decode(itemFromStore)); } - } return null; } @@ -266,7 +264,7 @@ abstract class ParseBase { } ///Access the [ParseACL] governing this object. - ParseACL getACL() { + ParseACL/*!*/ getACL() { if (_getObjectData().containsKey(keyVarAcl)) { return _getObjectData()[keyVarAcl]; } else { From df8fefee804cc3dc5257684424e9205c95a81acd Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:22:46 +0100 Subject: [PATCH 068/195] dart(clonable): Map needs to be not null --- packages/dart/lib/src/objects/parse_cloneable.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_cloneable.dart b/packages/dart/lib/src/objects/parse_cloneable.dart index 589b60149..7fe65ae8f 100644 --- a/packages/dart/lib/src/objects/parse_cloneable.dart +++ b/packages/dart/lib/src/objects/parse_cloneable.dart @@ -2,5 +2,5 @@ part of flutter_parse_sdk; /// Creates method which can be used to deep clone objects abstract class ParseCloneable { - dynamic clone(Map map); + dynamic clone(Map/*!*/ map); } From 57229faa8e7d594c47e9936c98d495fc579e1752 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:27:50 +0100 Subject: [PATCH 069/195] dart(object): GetObject needs objectId --- packages/dart/lib/src/objects/parse_object.dart | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index 8da77a77b..ecb190039 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -34,15 +34,10 @@ class ParseObject extends ParseBase implements ParseCloneable { ParseClient _client; /// Gets an object from the server using it's [String] objectId - Future getObject(String objectId) async { + Future getObject(String/*!*/ objectId) async { try { - String uri = _path; - - if (objectId != null) { - uri += '/$objectId'; - } - - final Uri url = getSanitisedUri(_client, '$uri'); + final String uri = '$_path/$objectId'; + final Uri url = getSanitisedUri(_client, uri); final ParseNetworkResponse result = await _client.get(url.toString()); return handleResponse( From f34a18867528c515ba5c04dedd2edc41b9c87b89 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:36:04 +0100 Subject: [PATCH 070/195] dart(response): Add null-safe annotations --- packages/dart/lib/src/objects/parse_response.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_response.dart b/packages/dart/lib/src/objects/parse_response.dart index d278bbdd1..83135eb16 100644 --- a/packages/dart/lib/src/objects/parse_response.dart +++ b/packages/dart/lib/src/objects/parse_response.dart @@ -2,7 +2,7 @@ part of flutter_parse_sdk; class ParseResponse { bool success = false; - int statusCode = -1; + int/*!*/ statusCode = -1; /// If result is a singular result, i.e. getByObjectID /// @@ -13,6 +13,6 @@ class ParseResponse { /// All results stored as a list - Even if only one response is returned // ignore: always_specify_types List results; - int count = 0; + int/*!*/ count = 0; ParseError error; } From e4acc3204951ff48b3db88f29f8c14f6fe8b2971 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:39:49 +0100 Subject: [PATCH 071/195] dart(object): Remove deprecated methods --- .../dart/lib/src/objects/parse_object.dart | 110 ------------------ 1 file changed, 110 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index ecb190039..3f068c72c 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -314,61 +314,21 @@ class ParseObject extends ParseBase implements ParseCloneable { return ParseRelation(parent: this, key: key); } - /// Removes an element from an Array - @Deprecated('Prefer to use the setRemove() method in save()') - Future remove(String key, dynamic values) async { - if (key != null) { - return await _sortArrays(ParseApiRQ.remove, 'Remove', key, values); - } else { - return null; - } - } - /// Removes an element from an Array void setRemove(String key, dynamic value) { _arrayOperation('Remove', key, [value]); } - /// Remove multiple elements from an array of an object - @Deprecated('Prefer to use the setRemoveAll() method in save()') - Future removeAll(String key, List values) async { - if (key != null) { - return await _sortArrays(ParseApiRQ.removeAll, 'Remove', key, values); - } else { - return null; - } - } - /// Remove multiple elements from an array of an object void setRemoveAll(String key, List values) { _arrayOperation('Remove', key, values); } - /// Add a multiple elements to an array of an object - @Deprecated('Prefer to use the setAddAll() method in save()') - Future addAll(String key, List values) async { - if (key != null) { - return await _sortArrays(ParseApiRQ.addAll, 'Add', key, values); - } else { - return null; - } - } - /// Add a multiple elements to an array of an object void setAddAll(String key, List values) { _arrayOperation('Add', key, values); } - /// Add a multiple elements to an array of an object, but only when they are unique - @Deprecated('Prefer to use the setAddAll() method in save()') - Future addUnique(String key, List values) async { - if (key != null) { - return await _sortArrays(ParseApiRQ.addUnique, 'AddUnique', key, values); - } else { - return null; - } - } - void setAddUnique(String key, dynamic value) { _arrayOperation('AddUnique', key, [value]); } @@ -378,16 +338,6 @@ class ParseObject extends ParseBase implements ParseCloneable { _arrayOperation('AddUnique', key, values); } - /// Add a single element to an array of an object - @Deprecated('Prefer to use the setAdd() method in save()') - Future add(String key, dynamic values) async { - if (key != null) { - return await _sortArrays(ParseApiRQ.add, 'Add', key, values); - } else { - return null; - } - } - /// Add a single element to an array of an object void setAdd(String key, dynamic value) { _arrayOperation('Add', key, [value]); @@ -401,26 +351,6 @@ class ParseObject extends ParseBase implements ParseCloneable { _arrayOperation('RemoveRelation', key, values); } - /// Can be used to add arrays to a given type - Future _sortArrays(ParseApiRQ apiRQType, String arrayAction, - String key, List values) async { - try { - if (objectId != null) { - final Uri url = getSanitisedUri(_client, '$_path/$objectId'); - final String body = - '{\"$key\":{\"__op\":\"$arrayAction\",\"objects\":${json.encode(parseEncode(values))}}}'; - final ParseNetworkResponse result = - await _client.put(url.toString(), data: body); - return handleResponse( - this, result, apiRQType, _debug, parseClassName); - } else { - return null; - } - } on Exception catch (e) { - return handleException(e, apiRQType, _debug, parseClassName); - } - } - /// Used in array Operations in save() method void _arrayOperation(String arrayAction, String key, List values) { // TODO(yulingtianxia): Array operations should be incremental. Merge add and remove operation. @@ -428,58 +358,18 @@ class ParseObject extends ParseBase implements ParseCloneable { key, {'__op': arrayAction, 'objects': values}); } - /// Increases a num of an object by x amount - @Deprecated('Prefer to use the setIncrement() method in save()') - Future increment(String key, num amount) async { - if (key != null) { - return await _increment(ParseApiRQ.increment, 'Increment', key, amount); - } else { - return null; - } - } - /// Increases a num of an object by x amount void setIncrement(String key, num amount) { set>( key, {'__op': 'Increment', 'amount': amount}); } - /// Decreases a num of an object by x amount - @Deprecated('Prefer to use the setDecrement() method in save()') - Future decrement(String key, num amount) async { - if (key != null) { - return await _increment(ParseApiRQ.decrement, 'Increment', key, -amount); - } else { - return null; - } - } - /// Decreases a num of an object by x amount void setDecrement(String key, num amount) { set>( key, {'__op': 'Increment', 'amount': -amount}); } - /// Can be used to add arrays to a given type - Future _increment( - ParseApiRQ apiRQType, String countAction, String key, num amount) async { - try { - if (objectId != null) { - final Uri url = getSanitisedUri(_client, '$_path/$objectId'); - final String body = - '{\"$key\":{\"__op\":\"$countAction\",\"amount\":$amount}}'; - final ParseNetworkResponse result = - await _client.put(url.toString(), data: body); - return handleResponse( - this, result, apiRQType, _debug, parseClassName); - } else { - return null; - } - } on Exception catch (e) { - return handleException(e, apiRQType, _debug, parseClassName); - } - } - /// Can be used set an objects variable to undefined rather than null /// /// If object is not saved remotely, set offlineOnly to true to avoid api calls. From a6a84d8ad57a2eba77f0ea819295f0ab693241d5 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:46:42 +0100 Subject: [PATCH 072/195] dart(object): Add null-safe annotations --- packages/dart/lib/src/objects/parse_object.dart | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index 3f068c72c..4806140a1 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -1,6 +1,5 @@ part of flutter_parse_sdk; -// ignore_for_file: always_specify_types class ParseObject extends ParseBase implements ParseCloneable { /// Creates a new Parse Object /// @@ -28,10 +27,10 @@ class ParseObject extends ParseBase implements ParseCloneable { dynamic clone(Map map) => ParseObject.clone(parseClassName)..fromJson(map); - String _path; - String _aggregatepath; + String/*!*/ _path; + String/*!*/ _aggregatepath; bool _debug; - ParseClient _client; + ParseClient/*!*/ _client; /// Gets an object from the server using it's [String] objectId Future getObject(String/*!*/ objectId) async { @@ -78,7 +77,7 @@ class ParseObject extends ParseBase implements ParseCloneable { } } - Future update() async { + Future update() async { try { final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final String body = json.encode(toJson(forApiRQ: true)); @@ -96,7 +95,7 @@ class ParseObject extends ParseBase implements ParseCloneable { } /// Saves the current object online - Future save() async { + Future save() async { final ParseResponse childrenResponse = await _saveChildren(this); if (childrenResponse.success) { ParseResponse response; From f4ce24e27e67614cb595b9d44cd41b3fc4c501e4 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 14:53:02 +0100 Subject: [PATCH 073/195] dart(error): Annotate null-safety --- packages/dart/lib/src/objects/parse_error.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_error.dart b/packages/dart/lib/src/objects/parse_error.dart index 59cc29ef9..a7c7bf471 100644 --- a/packages/dart/lib/src/objects/parse_error.dart +++ b/packages/dart/lib/src/objects/parse_error.dart @@ -7,14 +7,13 @@ class ParseError { this.message = 'Unknown error', this.exception, bool debug = false}) { - type = exceptions[code]; + type = _exceptions[code]; if (debug) { print(toString()); } } - // ignore: always_specify_types - Map exceptions = { + Map _exceptions = { -1: 'UnknownError', // SDK errors / Errors @@ -68,7 +67,7 @@ class ParseError { 252: 'UnsupportedService' }; - final int code; + final int/*!*/ code; final String message; final Exception exception; String type; From 9f92545729d6ac0d35a95f33ebf1958470ec4527 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:00:56 +0100 Subject: [PATCH 074/195] dart(relation): Annotate null-safety --- .../dart/lib/src/objects/parse_relation.dart | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_relation.dart b/packages/dart/lib/src/objects/parse_relation.dart index 9747d56c0..334f1f0f4 100644 --- a/packages/dart/lib/src/objects/parse_relation.dart +++ b/packages/dart/lib/src/objects/parse_relation.dart @@ -17,19 +17,15 @@ class ParseRelation { } void add(T object) { - if (object != null) { - _targetClass = object.parseClassName; - _objects.add(object); - _parent.addRelation(_key, _objects.toList()); - } + _targetClass = object.parseClassName; + _objects.add(object); + _parent?.addRelation(_key, _objects.toList()); } void remove(T object) { - if (object != null) { - _targetClass = object.parseClassName; - _objects.remove(object); - _parent.removeRelation(_key, _objects.toList()); - } + _targetClass = object.parseClassName; + _objects.remove(object); + _parent?.removeRelation(_key, _objects.toList()); } Map toJson() => { From 8a50b5e20704bee2c5bbfcbcf0c3d74ad53c4996 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:07:05 +0100 Subject: [PATCH 075/195] dart(client): statusCode should always be set --- packages/dart/lib/src/network/parse_client.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_client.dart b/packages/dart/lib/src/network/parse_client.dart index f30f8ca7f..8afa3cd19 100644 --- a/packages/dart/lib/src/network/parse_client.dart +++ b/packages/dart/lib/src/network/parse_client.dart @@ -85,14 +85,14 @@ class ParseNetworkResponse { }); final String/*!*/ data; - final int statusCode; + final int/*!*/ statusCode; } class ParseNetworkByteResponse extends ParseNetworkResponse { ParseNetworkByteResponse({ this.bytes, final String data = 'byte response', - final int statusCode, + final int statusCode = -1, }) : super( data: data, statusCode: statusCode, From 2685fc7980181ba125ee200f994da7d82283f36f Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:09:12 +0100 Subject: [PATCH 076/195] dart(error_response): Migrate --- .../dart/lib/src/objects/response/parse_error_response.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/dart/lib/src/objects/response/parse_error_response.dart b/packages/dart/lib/src/objects/response/parse_error_response.dart index d2fd8b341..5f8deaa53 100644 --- a/packages/dart/lib/src/objects/response/parse_error_response.dart +++ b/packages/dart/lib/src/objects/response/parse_error_response.dart @@ -3,10 +3,6 @@ part of flutter_parse_sdk; /// Handles any errors returned in response ParseResponse buildErrorResponse( ParseResponse response, ParseNetworkResponse apiResponse) { - if (apiResponse.data == null) { - return null; - } - final Map responseData = json.decode(apiResponse.data); response.error = ParseError( code: responseData[keyCode], message: responseData[keyError].toString()); From 94f228ee638374e8129024581cccc4109469bfda Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:13:48 +0100 Subject: [PATCH 077/195] dart(store): Annotate --- packages/dart/lib/src/storage/core_store.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/storage/core_store.dart b/packages/dart/lib/src/storage/core_store.dart index b7d2fe450..e4cc64648 100644 --- a/packages/dart/lib/src/storage/core_store.dart +++ b/packages/dart/lib/src/storage/core_store.dart @@ -21,11 +21,11 @@ abstract class CoreStore { Future setDouble(String key, double value); - Future setString(String key, String value); + Future setString(String/*!*/ key, String value); Future setStringList(String key, List values); - Future remove(String key); + Future remove(String/*!*/ key); Future clear(); } From beae2277a64a08bb67762de46e1948d5c1520cba Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:30:10 +0100 Subject: [PATCH 078/195] dart(utils): Annotate --- packages/dart/lib/src/objects/parse_response.dart | 2 +- packages/dart/lib/src/utils/parse_utils.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_response.dart b/packages/dart/lib/src/objects/parse_response.dart index 83135eb16..f27ebd2da 100644 --- a/packages/dart/lib/src/objects/parse_response.dart +++ b/packages/dart/lib/src/objects/parse_response.dart @@ -14,5 +14,5 @@ class ParseResponse { // ignore: always_specify_types List results; int/*!*/ count = 0; - ParseError error; + ParseError/*?*/ error; } diff --git a/packages/dart/lib/src/utils/parse_utils.dart b/packages/dart/lib/src/utils/parse_utils.dart index 478204f5e..4dd749d2d 100644 --- a/packages/dart/lib/src/utils/parse_utils.dart +++ b/packages/dart/lib/src/utils/parse_utils.dart @@ -86,6 +86,6 @@ Future batchRequest( } } -Stream _createStreamError(Object error) async* { +Stream _createStreamError(Object/*!*/ error) async* { throw error; } From f7840edd26b13b9888de2c572e367d853731c344 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:48:41 +0100 Subject: [PATCH 079/195] dart(function): Migrate --- packages/dart/lib/src/objects/parse_function.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_function.dart b/packages/dart/lib/src/objects/parse_function.dart index 137f745fc..c84037339 100644 --- a/packages/dart/lib/src/objects/parse_function.dart +++ b/packages/dart/lib/src/objects/parse_function.dart @@ -28,7 +28,8 @@ class ParseCloudFunction extends ParseObject { /// /// To add the parameters, create an object and call [set](value to set) Future execute( - {Map parameters, Map headers}) async { + {Map parameters, + Map headers = const {}}) async { final String uri = '${ParseCoreData().serverUrl}$_path'; if (parameters != null) { _setObjectData(parameters); @@ -48,7 +49,8 @@ class ParseCloudFunction extends ParseObject { /// /// To add the parameters, create an object and call [set](value to set) Future executeObjectFunction( - {Map parameters, Map headers}) async { + {Map parameters, + Map headers = const {}}) async { final String uri = '${ParseCoreData().serverUrl}$_path'; if (parameters != null) { _setObjectData(parameters); From 507e358d84821506c36835dc4da1312b27a47c9f Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:55:52 +0100 Subject: [PATCH 080/195] dart(session): Annotate --- packages/dart/lib/src/objects/parse_session.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_session.dart b/packages/dart/lib/src/objects/parse_session.dart index b7c37aa90..369a94024 100644 --- a/packages/dart/lib/src/objects/parse_session.dart +++ b/packages/dart/lib/src/objects/parse_session.dart @@ -15,18 +15,18 @@ class ParseSession extends ParseObject implements ParseCloneable { return fromJson(map); } - String get sessionToken => super.get(keyVarSessionToken); + String/*!*/ get sessionToken => super.get(keyVarSessionToken); - ParseObject get user => super.get(keyVarUser); + ParseObject/*!*/ get user => super.get(keyVarUser); - Map get createdWith => + Map/*!*/ get createdWith => super.get>(keyVarCreatedWith); - bool get restricted => super.get(keyVarRestricted); + bool/*!*/ get restricted => super.get(keyVarRestricted); - DateTime get expiresAt => super.get(keyVarExpiresAt); + DateTime/*!*/ get expiresAt => super.get(keyVarExpiresAt); - String get installationId => super.get(keyVarInstallationId); + String/*!*/ get installationId => super.get(keyVarInstallationId); set installationId(String installationId) => set(keyVarInstallationId, installationId); From 82555b7f14f7f5f7a993f8ce9913fe1de2b80545 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 15:59:58 +0100 Subject: [PATCH 081/195] dart: parse_file_extensions is deprecated --- packages/dart/lib/parse_server_sdk.dart | 1 - .../lib/src/utils/parse_file_extensions.dart | 5490 ----------------- 2 files changed, 5491 deletions(-) delete mode 100644 packages/dart/lib/src/utils/parse_file_extensions.dart diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index 36cfd86a7..663793eca 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -60,7 +60,6 @@ part 'src/storage/xxtea_codec.dart'; part 'src/utils/parse_date_format.dart'; part 'src/utils/parse_decoder.dart'; part 'src/utils/parse_encoder.dart'; -part 'src/utils/parse_file_extensions.dart'; part 'src/utils/parse_live_list.dart'; part 'src/utils/parse_logger.dart'; part 'src/utils/parse_login_helpers.dart'; diff --git a/packages/dart/lib/src/utils/parse_file_extensions.dart b/packages/dart/lib/src/utils/parse_file_extensions.dart deleted file mode 100644 index d0454b691..000000000 --- a/packages/dart/lib/src/utils/parse_file_extensions.dart +++ /dev/null @@ -1,5490 +0,0 @@ -part of flutter_parse_sdk; - -// ignore_for_file: always_specify_types - -/// Get the extension type of the file -@deprecated -String getExtension(String contentType) { - if (_extensions.containsKey(contentType) && - _extensions[contentType].containsKey('extensions')) { - return _extensions[contentType]['extensions'].first; - } - return null; -} - -/// Get the content type based on -@deprecated -String getContentType(String extension) { - final Map extensions = _queryExtensions(); - if (extension.lastIndexOf('.') >= 0) { - extension = extension.substring(extension.lastIndexOf('.') + 1); - } - - String contentType = extensions[extension.toLowerCase()]; - - contentType ??= 'application/octet-stream'; - - return contentType; -} - -/// Add content types based on extension to a map -@deprecated -Map _queryExtensions() { - Map extensions = Map(); - - if (extensions == null) { - extensions = {}; - _extensions.forEach((dynamic type, dynamic typeInfo) { - if (typeInfo.containsKey('extensions')) { - for (String ext in typeInfo['extensions']) { - _extensions[ext] = type; - } - } - }); - } - - return extensions; -} - -@deprecated -final Map _extensions = { - 'application/1d-interleaved-parityfec': {'source': 'iana'}, - 'application/3gpdash-qoe-report+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/3gpp-ims+xml': {'source': 'iana', 'compressible': true}, - 'application/a2l': {'source': 'iana'}, - 'application/activemessage': {'source': 'iana'}, - 'application/activity+json': {'source': 'iana', 'compressible': true}, - 'application/alto-costmap+json': {'source': 'iana', 'compressible': true}, - 'application/alto-costmapfilter+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/alto-directory+json': {'source': 'iana', 'compressible': true}, - 'application/alto-endpointcost+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/alto-endpointcostparams+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/alto-endpointprop+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/alto-endpointpropparams+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/alto-error+json': {'source': 'iana', 'compressible': true}, - 'application/alto-networkmap+json': {'source': 'iana', 'compressible': true}, - 'application/alto-networkmapfilter+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/aml': {'source': 'iana'}, - 'application/andrew-inset': { - 'source': 'iana', - 'extensions': ['ez'] - }, - 'application/applefile': {'source': 'iana'}, - 'application/applixware': { - 'source': 'apache', - 'extensions': ['aw'] - }, - 'application/atf': {'source': 'iana'}, - 'application/atfx': {'source': 'iana'}, - 'application/atom+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['atom'] - }, - 'application/atomcat+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['atomcat'] - }, - 'application/atomdeleted+xml': {'source': 'iana', 'compressible': true}, - 'application/atomicmail': {'source': 'iana'}, - 'application/atomsvc+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['atomsvc'] - }, - 'application/atxml': {'source': 'iana'}, - 'application/auth-policy+xml': {'source': 'iana', 'compressible': true}, - 'application/bacnet-xdd+zip': {'source': 'iana', 'compressible': false}, - 'application/batch-smtp': {'source': 'iana'}, - 'application/bdoc': { - 'compressible': false, - 'extensions': ['bdoc'] - }, - 'application/beep+xml': {'source': 'iana', 'compressible': true}, - 'application/calendar+json': {'source': 'iana', 'compressible': true}, - 'application/calendar+xml': {'source': 'iana', 'compressible': true}, - 'application/call-completion': {'source': 'iana'}, - 'application/cals-1840': {'source': 'iana'}, - 'application/cbor': {'source': 'iana'}, - 'application/cccex': {'source': 'iana'}, - 'application/ccmp+xml': {'source': 'iana', 'compressible': true}, - 'application/ccxml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['ccxml'] - }, - 'application/cdfx+xml': {'source': 'iana', 'compressible': true}, - 'application/cdmi-capability': { - 'source': 'iana', - 'extensions': ['cdmia'] - }, - 'application/cdmi-container': { - 'source': 'iana', - 'extensions': ['cdmic'] - }, - 'application/cdmi-domain': { - 'source': 'iana', - 'extensions': ['cdmid'] - }, - 'application/cdmi-object': { - 'source': 'iana', - 'extensions': ['cdmio'] - }, - 'application/cdmi-queue': { - 'source': 'iana', - 'extensions': ['cdmiq'] - }, - 'application/cdni': {'source': 'iana'}, - 'application/cea': {'source': 'iana'}, - 'application/cea-2018+xml': {'source': 'iana', 'compressible': true}, - 'application/cellml+xml': {'source': 'iana', 'compressible': true}, - 'application/cfw': {'source': 'iana'}, - 'application/clue_info+xml': {'source': 'iana', 'compressible': true}, - 'application/cms': {'source': 'iana'}, - 'application/cnrp+xml': {'source': 'iana', 'compressible': true}, - 'application/coap-group+json': {'source': 'iana', 'compressible': true}, - 'application/coap-payload': {'source': 'iana'}, - 'application/commonground': {'source': 'iana'}, - 'application/conference-info+xml': {'source': 'iana', 'compressible': true}, - 'application/cose': {'source': 'iana'}, - 'application/cose-key': {'source': 'iana'}, - 'application/cose-key-set': {'source': 'iana'}, - 'application/cpl+xml': {'source': 'iana', 'compressible': true}, - 'application/csrattrs': {'source': 'iana'}, - 'application/csta+xml': {'source': 'iana', 'compressible': true}, - 'application/cstadata+xml': {'source': 'iana', 'compressible': true}, - 'application/csvm+json': {'source': 'iana', 'compressible': true}, - 'application/cu-seeme': { - 'source': 'apache', - 'extensions': ['cu'] - }, - 'application/cwt': {'source': 'iana'}, - 'application/cybercash': {'source': 'iana'}, - 'application/dart': {'compressible': true}, - 'application/dash+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mpd'] - }, - 'application/dashdelta': {'source': 'iana'}, - 'application/davmount+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['davmount'] - }, - 'application/dca-rft': {'source': 'iana'}, - 'application/dcd': {'source': 'iana'}, - 'application/dec-dx': {'source': 'iana'}, - 'application/dialog-info+xml': {'source': 'iana', 'compressible': true}, - 'application/dicom': {'source': 'iana'}, - 'application/dicom+json': {'source': 'iana', 'compressible': true}, - 'application/dicom+xml': {'source': 'iana', 'compressible': true}, - 'application/dii': {'source': 'iana'}, - 'application/dit': {'source': 'iana'}, - 'application/dns': {'source': 'iana'}, - 'application/dns+json': {'source': 'iana', 'compressible': true}, - 'application/dns-message': {'source': 'iana'}, - 'application/docbook+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['dbk'] - }, - 'application/dskpp+xml': {'source': 'iana', 'compressible': true}, - 'application/dssc+der': { - 'source': 'iana', - 'extensions': ['dssc'] - }, - 'application/dssc+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xdssc'] - }, - 'application/dvcs': {'source': 'iana'}, - 'application/ecmascript': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['ecma', 'es'] - }, - 'application/edi-consent': {'source': 'iana'}, - 'application/edi-x12': {'source': 'iana', 'compressible': false}, - 'application/edifact': {'source': 'iana', 'compressible': false}, - 'application/efi': {'source': 'iana'}, - 'application/emergencycalldata.comment+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emergencycalldata.control+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emergencycalldata.deviceinfo+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emergencycalldata.ecall.msd': {'source': 'iana'}, - 'application/emergencycalldata.providerinfo+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emergencycalldata.serviceinfo+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emergencycalldata.subscriberinfo+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emergencycalldata.veds+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/emma+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['emma'] - }, - 'application/emotionml+xml': {'source': 'iana', 'compressible': true}, - 'application/encaprtp': {'source': 'iana'}, - 'application/epp+xml': {'source': 'iana', 'compressible': true}, - 'application/epub+zip': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['epub'] - }, - 'application/eshop': {'source': 'iana'}, - 'application/exi': { - 'source': 'iana', - 'extensions': ['exi'] - }, - 'application/fastinfoset': {'source': 'iana'}, - 'application/fastsoap': {'source': 'iana'}, - 'application/fdt+xml': {'source': 'iana', 'compressible': true}, - 'application/fhir+json': {'source': 'iana', 'compressible': true}, - 'application/fhir+xml': {'source': 'iana', 'compressible': true}, - 'application/fido.trusted-apps+json': {'compressible': true}, - 'application/fits': {'source': 'iana'}, - 'application/font-sfnt': {'source': 'iana'}, - 'application/font-tdpfr': { - 'source': 'iana', - 'extensions': ['pfr'] - }, - 'application/font-woff': {'source': 'iana', 'compressible': false}, - 'application/framework-attributes+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/geo+json': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['geojson'] - }, - 'application/geo+json-seq': {'source': 'iana'}, - 'application/geopackage+sqlite3': {'source': 'iana'}, - 'application/geoxacml+xml': {'source': 'iana', 'compressible': true}, - 'application/gltf-buffer': {'source': 'iana'}, - 'application/gml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['gml'] - }, - 'application/gpx+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['gpx'] - }, - 'application/gxf': { - 'source': 'apache', - 'extensions': ['gxf'] - }, - 'application/gzip': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['gz'] - }, - 'application/h224': {'source': 'iana'}, - 'application/held+xml': {'source': 'iana', 'compressible': true}, - 'application/hjson': { - 'extensions': ['hjson'] - }, - 'application/http': {'source': 'iana'}, - 'application/hyperstudio': { - 'source': 'iana', - 'extensions': ['stk'] - }, - 'application/ibe-key-request+xml': {'source': 'iana', 'compressible': true}, - 'application/ibe-pkg-reply+xml': {'source': 'iana', 'compressible': true}, - 'application/ibe-pp-data': {'source': 'iana'}, - 'application/iges': {'source': 'iana'}, - 'application/im-iscomposing+xml': {'source': 'iana', 'compressible': true}, - 'application/index': {'source': 'iana'}, - 'application/index.cmd': {'source': 'iana'}, - 'application/index.obj': {'source': 'iana'}, - 'application/index.response': {'source': 'iana'}, - 'application/index.vnd': {'source': 'iana'}, - 'application/inkml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['ink', 'inkml'] - }, - 'application/iotp': {'source': 'iana'}, - 'application/ipfix': { - 'source': 'iana', - 'extensions': ['ipfix'] - }, - 'application/ipp': {'source': 'iana'}, - 'application/isup': {'source': 'iana'}, - 'application/its+xml': {'source': 'iana', 'compressible': true}, - 'application/java-archive': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['jar', 'war', 'ear'] - }, - 'application/java-serialized-object': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['ser'] - }, - 'application/java-vm': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['class'] - }, - 'application/javascript': { - 'source': 'iana', - 'charset': 'UTF-8', - 'compressible': true, - 'extensions': ['js', 'mjs'] - }, - 'application/jf2feed+json': {'source': 'iana', 'compressible': true}, - 'application/jose': {'source': 'iana'}, - 'application/jose+json': {'source': 'iana', 'compressible': true}, - 'application/jrd+json': {'source': 'iana', 'compressible': true}, - 'application/json': { - 'source': 'iana', - 'charset': 'UTF-8', - 'compressible': true, - 'extensions': ['json', 'map'] - }, - 'application/json-patch+json': {'source': 'iana', 'compressible': true}, - 'application/json-seq': {'source': 'iana'}, - 'application/json5': { - 'extensions': ['json5'] - }, - 'application/jsonml+json': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['jsonml'] - }, - 'application/jwk+json': {'source': 'iana', 'compressible': true}, - 'application/jwk-set+json': {'source': 'iana', 'compressible': true}, - 'application/jwt': {'source': 'iana'}, - 'application/kpml-request+xml': {'source': 'iana', 'compressible': true}, - 'application/kpml-response+xml': {'source': 'iana', 'compressible': true}, - 'application/ld+json': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['jsonld'] - }, - 'application/lgr+xml': {'source': 'iana', 'compressible': true}, - 'application/link-format': {'source': 'iana'}, - 'application/load-control+xml': {'source': 'iana', 'compressible': true}, - 'application/lost+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['lostxml'] - }, - 'application/lostsync+xml': {'source': 'iana', 'compressible': true}, - 'application/lxf': {'source': 'iana'}, - 'application/mac-binhex40': { - 'source': 'iana', - 'extensions': ['hqx'] - }, - 'application/mac-compactpro': { - 'source': 'apache', - 'extensions': ['cpt'] - }, - 'application/macwriteii': {'source': 'iana'}, - 'application/mads+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mads'] - }, - 'application/manifest+json': { - 'charset': 'UTF-8', - 'compressible': true, - 'extensions': ['webmanifest'] - }, - 'application/marc': { - 'source': 'iana', - 'extensions': ['mrc'] - }, - 'application/marcxml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mrcx'] - }, - 'application/mathematica': { - 'source': 'iana', - 'extensions': ['ma', 'nb', 'mb'] - }, - 'application/mathml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mathml'] - }, - 'application/mathml-content+xml': {'source': 'iana', 'compressible': true}, - 'application/mathml-presentation+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/mbms-associated-procedure-description+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/mbms-deregister+xml': {'source': 'iana', 'compressible': true}, - 'application/mbms-envelope+xml': {'source': 'iana', 'compressible': true}, - 'application/mbms-msk+xml': {'source': 'iana', 'compressible': true}, - 'application/mbms-msk-response+xml': {'source': 'iana', 'compressible': true}, - 'application/mbms-protection-description+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/mbms-reception-report+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/mbms-register+xml': {'source': 'iana', 'compressible': true}, - 'application/mbms-register-response+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/mbms-schedule+xml': {'source': 'iana', 'compressible': true}, - 'application/mbms-user-service-description+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/mbox': { - 'source': 'iana', - 'extensions': ['mbox'] - }, - 'application/media-policy-dataset+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/media_control+xml': {'source': 'iana', 'compressible': true}, - 'application/mediaservercontrol+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mscml'] - }, - 'application/merge-patch+json': {'source': 'iana', 'compressible': true}, - 'application/metalink+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['metalink'] - }, - 'application/metalink4+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['meta4'] - }, - 'application/mets+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mets'] - }, - 'application/mf4': {'source': 'iana'}, - 'application/mikey': {'source': 'iana'}, - 'application/mmt-usd+xml': {'source': 'iana', 'compressible': true}, - 'application/mods+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mods'] - }, - 'application/moss-keys': {'source': 'iana'}, - 'application/moss-signature': {'source': 'iana'}, - 'application/mosskey-data': {'source': 'iana'}, - 'application/mosskey-request': {'source': 'iana'}, - 'application/mp21': { - 'source': 'iana', - 'extensions': ['m21', 'mp21'] - }, - 'application/mp4': { - 'source': 'iana', - 'extensions': ['mp4s', 'm4p'] - }, - 'application/mpeg4-generic': {'source': 'iana'}, - 'application/mpeg4-iod': {'source': 'iana'}, - 'application/mpeg4-iod-xmt': {'source': 'iana'}, - 'application/mrb-consumer+xml': {'source': 'iana', 'compressible': true}, - 'application/mrb-publish+xml': {'source': 'iana', 'compressible': true}, - 'application/msc-ivr+xml': {'source': 'iana', 'compressible': true}, - 'application/msc-mixer+xml': {'source': 'iana', 'compressible': true}, - 'application/msword': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['doc', 'dot'] - }, - 'application/mud+json': {'source': 'iana', 'compressible': true}, - 'application/mxf': { - 'source': 'iana', - 'extensions': ['mxf'] - }, - 'application/n-quads': {'source': 'iana'}, - 'application/n-triples': {'source': 'iana'}, - 'application/nasdata': {'source': 'iana'}, - 'application/news-checkgroups': {'source': 'iana'}, - 'application/news-groupinfo': {'source': 'iana'}, - 'application/news-transmission': {'source': 'iana'}, - 'application/nlsml+xml': {'source': 'iana', 'compressible': true}, - 'application/node': {'source': 'iana'}, - 'application/nss': {'source': 'iana'}, - 'application/ocsp-request': {'source': 'iana'}, - 'application/ocsp-response': {'source': 'iana'}, - 'application/octet-stream': { - 'source': 'iana', - 'compressible': false, - 'extensions': [ - 'bin', - 'dms', - 'lrf', - 'mar', - 'so', - 'dist', - 'distz', - 'pkg', - 'bpk', - 'dump', - 'elc', - 'deploy', - 'exe', - 'dll', - 'deb', - 'dmg', - 'iso', - 'img', - 'msi', - 'msp', - 'msm', - 'buffer' - ] - }, - 'application/oda': { - 'source': 'iana', - 'extensions': ['oda'] - }, - 'application/odx': {'source': 'iana'}, - 'application/oebps-package+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['opf'] - }, - 'application/ogg': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['ogx'] - }, - 'application/omdoc+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['omdoc'] - }, - 'application/onenote': { - 'source': 'apache', - 'extensions': ['onetoc', 'onetoc2', 'onetmp', 'onepkg'] - }, - 'application/oxps': { - 'source': 'iana', - 'extensions': ['oxps'] - }, - 'application/p2p-overlay+xml': {'source': 'iana', 'compressible': true}, - 'application/parityfec': {'source': 'iana'}, - 'application/passport': {'source': 'iana'}, - 'application/patch-ops-error+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xer'] - }, - 'application/pdf': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['pdf'] - }, - 'application/pdx': {'source': 'iana'}, - 'application/pgp-encrypted': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['pgp'] - }, - 'application/pgp-keys': {'source': 'iana'}, - 'application/pgp-signature': { - 'source': 'iana', - 'extensions': ['asc', 'sig'] - }, - 'application/pics-rules': { - 'source': 'apache', - 'extensions': ['prf'] - }, - 'application/pidf+xml': {'source': 'iana', 'compressible': true}, - 'application/pidf-diff+xml': {'source': 'iana', 'compressible': true}, - 'application/pkcs10': { - 'source': 'iana', - 'extensions': ['p10'] - }, - 'application/pkcs12': {'source': 'iana'}, - 'application/pkcs7-mime': { - 'source': 'iana', - 'extensions': ['p7m', 'p7c'] - }, - 'application/pkcs7-signature': { - 'source': 'iana', - 'extensions': ['p7s'] - }, - 'application/pkcs8': { - 'source': 'iana', - 'extensions': ['p8'] - }, - 'application/pkcs8-encrypted': {'source': 'iana'}, - 'application/pkix-attr-cert': { - 'source': 'iana', - 'extensions': ['ac'] - }, - 'application/pkix-cert': { - 'source': 'iana', - 'extensions': ['cer'] - }, - 'application/pkix-crl': { - 'source': 'iana', - 'extensions': ['crl'] - }, - 'application/pkix-pkipath': { - 'source': 'iana', - 'extensions': ['pkipath'] - }, - 'application/pkixcmp': { - 'source': 'iana', - 'extensions': ['pki'] - }, - 'application/pls+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['pls'] - }, - 'application/poc-settings+xml': {'source': 'iana', 'compressible': true}, - 'application/postscript': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['ai', 'eps', 'ps'] - }, - 'application/ppsp-tracker+json': {'source': 'iana', 'compressible': true}, - 'application/problem+json': {'source': 'iana', 'compressible': true}, - 'application/problem+xml': {'source': 'iana', 'compressible': true}, - 'application/provenance+xml': {'source': 'iana', 'compressible': true}, - 'application/prs.alvestrand.titrax-sheet': {'source': 'iana'}, - 'application/prs.cww': { - 'source': 'iana', - 'extensions': ['cww'] - }, - 'application/prs.hpub+zip': {'source': 'iana', 'compressible': false}, - 'application/prs.nprend': {'source': 'iana'}, - 'application/prs.plucker': {'source': 'iana'}, - 'application/prs.rdf-xml-crypt': {'source': 'iana'}, - 'application/prs.xsf+xml': {'source': 'iana', 'compressible': true}, - 'application/pskc+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['pskcxml'] - }, - 'application/qsig': {'source': 'iana'}, - 'application/raml+yaml': { - 'compressible': true, - 'extensions': ['raml'] - }, - 'application/raptorfec': {'source': 'iana'}, - 'application/rdap+json': {'source': 'iana', 'compressible': true}, - 'application/rdf+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rdf', 'owl'] - }, - 'application/reginfo+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rif'] - }, - 'application/relax-ng-compact-syntax': { - 'source': 'iana', - 'extensions': ['rnc'] - }, - 'application/remote-printing': {'source': 'iana'}, - 'application/reputon+json': {'source': 'iana', 'compressible': true}, - 'application/resource-lists+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rl'] - }, - 'application/resource-lists-diff+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rld'] - }, - 'application/rfc+xml': {'source': 'iana', 'compressible': true}, - 'application/riscos': {'source': 'iana'}, - 'application/rlmi+xml': {'source': 'iana', 'compressible': true}, - 'application/rls-services+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rs'] - }, - 'application/route-apd+xml': {'source': 'iana', 'compressible': true}, - 'application/route-s-tsid+xml': {'source': 'iana', 'compressible': true}, - 'application/route-usd+xml': {'source': 'iana', 'compressible': true}, - 'application/rpki-ghostbusters': { - 'source': 'iana', - 'extensions': ['gbr'] - }, - 'application/rpki-manifest': { - 'source': 'iana', - 'extensions': ['mft'] - }, - 'application/rpki-publication': {'source': 'iana'}, - 'application/rpki-roa': { - 'source': 'iana', - 'extensions': ['roa'] - }, - 'application/rpki-updown': {'source': 'iana'}, - 'application/rsd+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['rsd'] - }, - 'application/rss+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['rss'] - }, - 'application/rtf': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rtf'] - }, - 'application/rtploopback': {'source': 'iana'}, - 'application/rtx': {'source': 'iana'}, - 'application/samlassertion+xml': {'source': 'iana', 'compressible': true}, - 'application/samlmetadata+xml': {'source': 'iana', 'compressible': true}, - 'application/sbml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['sbml'] - }, - 'application/scaip+xml': {'source': 'iana', 'compressible': true}, - 'application/scim+json': {'source': 'iana', 'compressible': true}, - 'application/scvp-cv-request': { - 'source': 'iana', - 'extensions': ['scq'] - }, - 'application/scvp-cv-response': { - 'source': 'iana', - 'extensions': ['scs'] - }, - 'application/scvp-vp-request': { - 'source': 'iana', - 'extensions': ['spq'] - }, - 'application/scvp-vp-response': { - 'source': 'iana', - 'extensions': ['spp'] - }, - 'application/sdp': { - 'source': 'iana', - 'extensions': ['sdp'] - }, - 'application/secevent+jwt': {'source': 'iana'}, - 'application/senml+cbor': {'source': 'iana'}, - 'application/senml+json': {'source': 'iana', 'compressible': true}, - 'application/senml+xml': {'source': 'iana', 'compressible': true}, - 'application/senml-exi': {'source': 'iana'}, - 'application/sensml+cbor': {'source': 'iana'}, - 'application/sensml+json': {'source': 'iana', 'compressible': true}, - 'application/sensml+xml': {'source': 'iana', 'compressible': true}, - 'application/sensml-exi': {'source': 'iana'}, - 'application/sep+xml': {'source': 'iana', 'compressible': true}, - 'application/sep-exi': {'source': 'iana'}, - 'application/session-info': {'source': 'iana'}, - 'application/set-payment': {'source': 'iana'}, - 'application/set-payment-initiation': { - 'source': 'iana', - 'extensions': ['setpay'] - }, - 'application/set-registration': {'source': 'iana'}, - 'application/set-registration-initiation': { - 'source': 'iana', - 'extensions': ['setreg'] - }, - 'application/sgml': {'source': 'iana'}, - 'application/sgml-open-catalog': {'source': 'iana'}, - 'application/shf+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['shf'] - }, - 'application/sieve': {'source': 'iana'}, - 'application/simple-filter+xml': {'source': 'iana', 'compressible': true}, - 'application/simple-message-summary': {'source': 'iana'}, - 'application/simplesymbolcontainer': {'source': 'iana'}, - 'application/slate': {'source': 'iana'}, - 'application/smil': {'source': 'iana'}, - 'application/smil+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['smi', 'smil'] - }, - 'application/smpte336m': {'source': 'iana'}, - 'application/soap+fastinfoset': {'source': 'iana'}, - 'application/soap+xml': {'source': 'iana', 'compressible': true}, - 'application/sparql-query': { - 'source': 'iana', - 'extensions': ['rq'] - }, - 'application/sparql-results+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['srx'] - }, - 'application/spirits-event+xml': {'source': 'iana', 'compressible': true}, - 'application/sql': {'source': 'iana'}, - 'application/srgs': { - 'source': 'iana', - 'extensions': ['gram'] - }, - 'application/srgs+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['grxml'] - }, - 'application/sru+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['sru'] - }, - 'application/ssdl+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['ssdl'] - }, - 'application/ssml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['ssml'] - }, - 'application/stix+json': {'source': 'iana', 'compressible': true}, - 'application/tamp-apex-update': {'source': 'iana'}, - 'application/tamp-apex-update-confirm': {'source': 'iana'}, - 'application/tamp-community-update': {'source': 'iana'}, - 'application/tamp-community-update-confirm': {'source': 'iana'}, - 'application/tamp-error': {'source': 'iana'}, - 'application/tamp-sequence-adjust': {'source': 'iana'}, - 'application/tamp-sequence-adjust-confirm': {'source': 'iana'}, - 'application/tamp-status-query': {'source': 'iana'}, - 'application/tamp-status-response': {'source': 'iana'}, - 'application/tamp-update': {'source': 'iana'}, - 'application/tamp-update-confirm': {'source': 'iana'}, - 'application/tar': {'compressible': true}, - 'application/taxii+json': {'source': 'iana', 'compressible': true}, - 'application/tei+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['tei', 'teicorpus'] - }, - 'application/thraud+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['tfi'] - }, - 'application/timestamp-query': {'source': 'iana'}, - 'application/timestamp-reply': {'source': 'iana'}, - 'application/timestamped-data': { - 'source': 'iana', - 'extensions': ['tsd'] - }, - 'application/tlsrpt+gzip': {'source': 'iana'}, - 'application/tlsrpt+json': {'source': 'iana', 'compressible': true}, - 'application/tnauthlist': {'source': 'iana'}, - 'application/trickle-ice-sdpfrag': {'source': 'iana'}, - 'application/trig': {'source': 'iana'}, - 'application/ttml+xml': {'source': 'iana', 'compressible': true}, - 'application/tve-trigger': {'source': 'iana'}, - 'application/ulpfec': {'source': 'iana'}, - 'application/urc-grpsheet+xml': {'source': 'iana', 'compressible': true}, - 'application/urc-ressheet+xml': {'source': 'iana', 'compressible': true}, - 'application/urc-targetdesc+xml': {'source': 'iana', 'compressible': true}, - 'application/urc-uisocketdesc+xml': {'source': 'iana', 'compressible': true}, - 'application/vcard+json': {'source': 'iana', 'compressible': true}, - 'application/vcard+xml': {'source': 'iana', 'compressible': true}, - 'application/vemmi': {'source': 'iana'}, - 'application/vividence.scriptfile': {'source': 'apache'}, - 'application/vnd.1000minds.decision-model+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp-prose+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.3gpp-prose-pc3ch+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp-v2x-local-service-information': {'source': 'iana'}, - 'application/vnd.3gpp.access-transfer-events+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.bsf+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.3gpp.gmop+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.3gpp.mc-signalling-ear': {'source': 'iana'}, - 'application/vnd.3gpp.mcdata-payload': {'source': 'iana'}, - 'application/vnd.3gpp.mcdata-signalling': {'source': 'iana'}, - 'application/vnd.3gpp.mcptt-affiliation-command+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.mcptt-floor-request+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.mcptt-info+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.mcptt-location-info+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.mcptt-mbms-usage-info+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.mcptt-signed+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.mid-call+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.3gpp.pic-bw-large': { - 'source': 'iana', - 'extensions': ['plb'] - }, - 'application/vnd.3gpp.pic-bw-small': { - 'source': 'iana', - 'extensions': ['psb'] - }, - 'application/vnd.3gpp.pic-bw-var': { - 'source': 'iana', - 'extensions': ['pvb'] - }, - 'application/vnd.3gpp.sms': {'source': 'iana'}, - 'application/vnd.3gpp.sms+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.3gpp.srvcc-ext+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.srvcc-info+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.state-and-event-info+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp.ussd+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.3gpp2.bcmcsinfo+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.3gpp2.sms': {'source': 'iana'}, - 'application/vnd.3gpp2.tcap': { - 'source': 'iana', - 'extensions': ['tcap'] - }, - 'application/vnd.3lightssoftware.imagescal': {'source': 'iana'}, - 'application/vnd.3m.post-it-notes': { - 'source': 'iana', - 'extensions': ['pwn'] - }, - 'application/vnd.accpac.simply.aso': { - 'source': 'iana', - 'extensions': ['aso'] - }, - 'application/vnd.accpac.simply.imp': { - 'source': 'iana', - 'extensions': ['imp'] - }, - 'application/vnd.acucobol': { - 'source': 'iana', - 'extensions': ['acu'] - }, - 'application/vnd.acucorp': { - 'source': 'iana', - 'extensions': ['atc', 'acutc'] - }, - 'application/vnd.adobe.air-application-installer-package+zip': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['air'] - }, - 'application/vnd.adobe.flash.movie': {'source': 'iana'}, - 'application/vnd.adobe.formscentral.fcdt': { - 'source': 'iana', - 'extensions': ['fcdt'] - }, - 'application/vnd.adobe.fxp': { - 'source': 'iana', - 'extensions': ['fxp', 'fxpl'] - }, - 'application/vnd.adobe.partial-upload': {'source': 'iana'}, - 'application/vnd.adobe.xdp+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xdp'] - }, - 'application/vnd.adobe.xfdf': { - 'source': 'iana', - 'extensions': ['xfdf'] - }, - 'application/vnd.aether.imp': {'source': 'iana'}, - 'application/vnd.afpc.afplinedata': {'source': 'iana'}, - 'application/vnd.afpc.modca': {'source': 'iana'}, - 'application/vnd.ah-barcode': {'source': 'iana'}, - 'application/vnd.ahead.space': { - 'source': 'iana', - 'extensions': ['ahead'] - }, - 'application/vnd.airzip.filesecure.azf': { - 'source': 'iana', - 'extensions': ['azf'] - }, - 'application/vnd.airzip.filesecure.azs': { - 'source': 'iana', - 'extensions': ['azs'] - }, - 'application/vnd.amadeus+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.amazon.ebook': { - 'source': 'apache', - 'extensions': ['azw'] - }, - 'application/vnd.amazon.mobi8-ebook': {'source': 'iana'}, - 'application/vnd.americandynamics.acc': { - 'source': 'iana', - 'extensions': ['acc'] - }, - 'application/vnd.amiga.ami': { - 'source': 'iana', - 'extensions': ['ami'] - }, - 'application/vnd.amundsen.maze+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.android.package-archive': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['apk'] - }, - 'application/vnd.anki': {'source': 'iana'}, - 'application/vnd.anser-web-certificate-issue-initiation': { - 'source': 'iana', - 'extensions': ['cii'] - }, - 'application/vnd.anser-web-funds-transfer-initiation': { - 'source': 'apache', - 'extensions': ['fti'] - }, - 'application/vnd.antix.game-component': { - 'source': 'iana', - 'extensions': ['atx'] - }, - 'application/vnd.apache.thrift.binary': {'source': 'iana'}, - 'application/vnd.apache.thrift.compact': {'source': 'iana'}, - 'application/vnd.apache.thrift.json': {'source': 'iana'}, - 'application/vnd.api+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.apothekende.reservation+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.apple.installer+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mpkg'] - }, - 'application/vnd.apple.keynote': { - 'source': 'iana', - 'extensions': ['keynote'] - }, - 'application/vnd.apple.mpegurl': { - 'source': 'iana', - 'extensions': ['m3u8'] - }, - 'application/vnd.apple.numbers': { - 'source': 'iana', - 'extensions': ['numbers'] - }, - 'application/vnd.apple.pages': { - 'source': 'iana', - 'extensions': ['pages'] - }, - 'application/vnd.apple.pkpass': { - 'compressible': false, - 'extensions': ['pkpass'] - }, - 'application/vnd.arastra.swi': {'source': 'iana'}, - 'application/vnd.aristanetworks.swi': { - 'source': 'iana', - 'extensions': ['swi'] - }, - 'application/vnd.artisan+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.artsquare': {'source': 'iana'}, - 'application/vnd.astraea-software.iota': { - 'source': 'iana', - 'extensions': ['iota'] - }, - 'application/vnd.audiograph': { - 'source': 'iana', - 'extensions': ['aep'] - }, - 'application/vnd.autopackage': {'source': 'iana'}, - 'application/vnd.avalon+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.avistar+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.balsamiq.bmml+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.balsamiq.bmpr': {'source': 'iana'}, - 'application/vnd.banana-accounting': {'source': 'iana'}, - 'application/vnd.bbf.usp.msg': {'source': 'iana'}, - 'application/vnd.bbf.usp.msg+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.bekitzur-stech+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.bint.med-content': {'source': 'iana'}, - 'application/vnd.biopax.rdf+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.blink-idb-value-wrapper': {'source': 'iana'}, - 'application/vnd.blueice.multipass': { - 'source': 'iana', - 'extensions': ['mpm'] - }, - 'application/vnd.bluetooth.ep.oob': {'source': 'iana'}, - 'application/vnd.bluetooth.le.oob': {'source': 'iana'}, - 'application/vnd.bmi': { - 'source': 'iana', - 'extensions': ['bmi'] - }, - 'application/vnd.businessobjects': { - 'source': 'iana', - 'extensions': ['rep'] - }, - 'application/vnd.byu.uapi+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.cab-jscript': {'source': 'iana'}, - 'application/vnd.canon-cpdl': {'source': 'iana'}, - 'application/vnd.canon-lips': {'source': 'iana'}, - 'application/vnd.capasystems-pg+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.cendio.thinlinc.clientconf': {'source': 'iana'}, - 'application/vnd.century-systems.tcp_stream': {'source': 'iana'}, - 'application/vnd.chemdraw+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['cdxml'] - }, - 'application/vnd.chess-pgn': {'source': 'iana'}, - 'application/vnd.chipnuts.karaoke-mmd': { - 'source': 'iana', - 'extensions': ['mmd'] - }, - 'application/vnd.cinderella': { - 'source': 'iana', - 'extensions': ['cdy'] - }, - 'application/vnd.cirpack.isdn-ext': {'source': 'iana'}, - 'application/vnd.citationstyles.style+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['csl'] - }, - 'application/vnd.claymore': { - 'source': 'iana', - 'extensions': ['cla'] - }, - 'application/vnd.cloanto.rp9': { - 'source': 'iana', - 'extensions': ['rp9'] - }, - 'application/vnd.clonk.c4group': { - 'source': 'iana', - 'extensions': ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'] - }, - 'application/vnd.cluetrust.cartomobile-config': { - 'source': 'iana', - 'extensions': ['c11amc'] - }, - 'application/vnd.cluetrust.cartomobile-config-pkg': { - 'source': 'iana', - 'extensions': ['c11amz'] - }, - 'application/vnd.coffeescript': {'source': 'iana'}, - 'application/vnd.collabio.xodocuments.document': {'source': 'iana'}, - 'application/vnd.collabio.xodocuments.document-template': {'source': 'iana'}, - 'application/vnd.collabio.xodocuments.presentation': {'source': 'iana'}, - 'application/vnd.collabio.xodocuments.presentation-template': { - 'source': 'iana' - }, - 'application/vnd.collabio.xodocuments.spreadsheet': {'source': 'iana'}, - 'application/vnd.collabio.xodocuments.spreadsheet-template': { - 'source': 'iana' - }, - 'application/vnd.collection+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.collection.doc+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.collection.next+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.comicbook+zip': {'source': 'iana', 'compressible': false}, - 'application/vnd.comicbook-rar': {'source': 'iana'}, - 'application/vnd.commerce-battelle': {'source': 'iana'}, - 'application/vnd.commonspace': { - 'source': 'iana', - 'extensions': ['csp'] - }, - 'application/vnd.contact.cmsg': { - 'source': 'iana', - 'extensions': ['cdbcmsg'] - }, - 'application/vnd.coreos.ignition+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.cosmocaller': { - 'source': 'iana', - 'extensions': ['cmc'] - }, - 'application/vnd.crick.clicker': { - 'source': 'iana', - 'extensions': ['clkx'] - }, - 'application/vnd.crick.clicker.keyboard': { - 'source': 'iana', - 'extensions': ['clkk'] - }, - 'application/vnd.crick.clicker.palette': { - 'source': 'iana', - 'extensions': ['clkp'] - }, - 'application/vnd.crick.clicker.template': { - 'source': 'iana', - 'extensions': ['clkt'] - }, - 'application/vnd.crick.clicker.wordbank': { - 'source': 'iana', - 'extensions': ['clkw'] - }, - 'application/vnd.criticaltools.wbs+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['wbs'] - }, - 'application/vnd.ctc-posml': { - 'source': 'iana', - 'extensions': ['pml'] - }, - 'application/vnd.ctct.ws+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.cups-pdf': {'source': 'iana'}, - 'application/vnd.cups-postscript': {'source': 'iana'}, - 'application/vnd.cups-ppd': { - 'source': 'iana', - 'extensions': ['ppd'] - }, - 'application/vnd.cups-raster': {'source': 'iana'}, - 'application/vnd.cups-raw': {'source': 'iana'}, - 'application/vnd.curl': {'source': 'iana'}, - 'application/vnd.curl.car': { - 'source': 'apache', - 'extensions': ['car'] - }, - 'application/vnd.curl.pcurl': { - 'source': 'apache', - 'extensions': ['pcurl'] - }, - 'application/vnd.cyan.dean.root+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.cybank': {'source': 'iana'}, - 'application/vnd.d2l.coursepackage1p0+zip': { - 'source': 'iana', - 'compressible': false - }, - 'application/vnd.dart': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['dart'] - }, - 'application/vnd.data-vision.rdz': { - 'source': 'iana', - 'extensions': ['rdz'] - }, - 'application/vnd.datapackage+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.dataresource+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.debian.binary-package': {'source': 'iana'}, - 'application/vnd.dece.data': { - 'source': 'iana', - 'extensions': ['uvf', 'uvvf', 'uvd', 'uvvd'] - }, - 'application/vnd.dece.ttml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['uvt', 'uvvt'] - }, - 'application/vnd.dece.unspecified': { - 'source': 'iana', - 'extensions': ['uvx', 'uvvx'] - }, - 'application/vnd.dece.zip': { - 'source': 'iana', - 'extensions': ['uvz', 'uvvz'] - }, - 'application/vnd.denovo.fcselayout-link': { - 'source': 'iana', - 'extensions': ['fe_launch'] - }, - 'application/vnd.desmume.movie': {'source': 'iana'}, - 'application/vnd.dir-bi.plate-dl-nosuffix': {'source': 'iana'}, - 'application/vnd.dm.delegation+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.dna': { - 'source': 'iana', - 'extensions': ['dna'] - }, - 'application/vnd.document+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.dolby.mlp': { - 'source': 'apache', - 'extensions': ['mlp'] - }, - 'application/vnd.dolby.mobile.1': {'source': 'iana'}, - 'application/vnd.dolby.mobile.2': {'source': 'iana'}, - 'application/vnd.doremir.scorecloud-binary-document': {'source': 'iana'}, - 'application/vnd.dpgraph': { - 'source': 'iana', - 'extensions': ['dpg'] - }, - 'application/vnd.dreamfactory': { - 'source': 'iana', - 'extensions': ['dfac'] - }, - 'application/vnd.drive+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.ds-keypoint': { - 'source': 'apache', - 'extensions': ['kpxx'] - }, - 'application/vnd.dtg.local': {'source': 'iana'}, - 'application/vnd.dtg.local.flash': {'source': 'iana'}, - 'application/vnd.dtg.local.html': {'source': 'iana'}, - 'application/vnd.dvb.ait': { - 'source': 'iana', - 'extensions': ['ait'] - }, - 'application/vnd.dvb.dvbj': {'source': 'iana'}, - 'application/vnd.dvb.esgcontainer': {'source': 'iana'}, - 'application/vnd.dvb.ipdcdftnotifaccess': {'source': 'iana'}, - 'application/vnd.dvb.ipdcesgaccess': {'source': 'iana'}, - 'application/vnd.dvb.ipdcesgaccess2': {'source': 'iana'}, - 'application/vnd.dvb.ipdcesgpdd': {'source': 'iana'}, - 'application/vnd.dvb.ipdcroaming': {'source': 'iana'}, - 'application/vnd.dvb.iptv.alfec-base': {'source': 'iana'}, - 'application/vnd.dvb.iptv.alfec-enhancement': {'source': 'iana'}, - 'application/vnd.dvb.notif-aggregate-root+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.notif-container+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.notif-generic+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.notif-ia-msglist+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.notif-ia-registration-request+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.notif-ia-registration-response+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.notif-init+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.dvb.pfr': {'source': 'iana'}, - 'application/vnd.dvb.service': { - 'source': 'iana', - 'extensions': ['svc'] - }, - 'application/vnd.dxr': {'source': 'iana'}, - 'application/vnd.dynageo': { - 'source': 'iana', - 'extensions': ['geo'] - }, - 'application/vnd.dzr': {'source': 'iana'}, - 'application/vnd.easykaraoke.cdgdownload': {'source': 'iana'}, - 'application/vnd.ecdis-update': {'source': 'iana'}, - 'application/vnd.ecip.rlp': {'source': 'iana'}, - 'application/vnd.ecowin.chart': { - 'source': 'iana', - 'extensions': ['mag'] - }, - 'application/vnd.ecowin.filerequest': {'source': 'iana'}, - 'application/vnd.ecowin.fileupdate': {'source': 'iana'}, - 'application/vnd.ecowin.series': {'source': 'iana'}, - 'application/vnd.ecowin.seriesrequest': {'source': 'iana'}, - 'application/vnd.ecowin.seriesupdate': {'source': 'iana'}, - 'application/vnd.efi.img': {'source': 'iana'}, - 'application/vnd.efi.iso': {'source': 'iana'}, - 'application/vnd.emclient.accessrequest+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.enliven': { - 'source': 'iana', - 'extensions': ['nml'] - }, - 'application/vnd.enphase.envoy': {'source': 'iana'}, - 'application/vnd.eprints.data+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.epson.esf': { - 'source': 'iana', - 'extensions': ['esf'] - }, - 'application/vnd.epson.msf': { - 'source': 'iana', - 'extensions': ['msf'] - }, - 'application/vnd.epson.quickanime': { - 'source': 'iana', - 'extensions': ['qam'] - }, - 'application/vnd.epson.salt': { - 'source': 'iana', - 'extensions': ['slt'] - }, - 'application/vnd.epson.ssf': { - 'source': 'iana', - 'extensions': ['ssf'] - }, - 'application/vnd.ericsson.quickcall': {'source': 'iana'}, - 'application/vnd.espass-espass+zip': { - 'source': 'iana', - 'compressible': false - }, - 'application/vnd.eszigno3+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['es3', 'et3'] - }, - 'application/vnd.etsi.aoc+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.asic-e+zip': {'source': 'iana', 'compressible': false}, - 'application/vnd.etsi.asic-s+zip': {'source': 'iana', 'compressible': false}, - 'application/vnd.etsi.cug+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.iptvcommand+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvdiscovery+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvprofile+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvsad-bc+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvsad-cod+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvsad-npvr+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvservice+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.iptvsync+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.iptvueprofile+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.mcid+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.mheg5': {'source': 'iana'}, - 'application/vnd.etsi.overload-control-policy-dataset+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.etsi.pstn+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.sci+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.simservs+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.timestamp-token': {'source': 'iana'}, - 'application/vnd.etsi.tsl+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.etsi.tsl.der': {'source': 'iana'}, - 'application/vnd.eudora.data': {'source': 'iana'}, - 'application/vnd.evolv.ecig.profile': {'source': 'iana'}, - 'application/vnd.evolv.ecig.settings': {'source': 'iana'}, - 'application/vnd.evolv.ecig.theme': {'source': 'iana'}, - 'application/vnd.exstream-empower+zip': { - 'source': 'iana', - 'compressible': false - }, - 'application/vnd.ezpix-album': { - 'source': 'iana', - 'extensions': ['ez2'] - }, - 'application/vnd.ezpix-package': { - 'source': 'iana', - 'extensions': ['ez3'] - }, - 'application/vnd.f-secure.mobile': {'source': 'iana'}, - 'application/vnd.fastcopy-disk-image': {'source': 'iana'}, - 'application/vnd.fdf': { - 'source': 'iana', - 'extensions': ['fdf'] - }, - 'application/vnd.fdsn.mseed': { - 'source': 'iana', - 'extensions': ['mseed'] - }, - 'application/vnd.fdsn.seed': { - 'source': 'iana', - 'extensions': ['seed', 'dataless'] - }, - 'application/vnd.ffsns': {'source': 'iana'}, - 'application/vnd.filmit.zfc': {'source': 'iana'}, - 'application/vnd.fints': {'source': 'iana'}, - 'application/vnd.firemonkeys.cloudcell': {'source': 'iana'}, - 'application/vnd.flographit': { - 'source': 'iana', - 'extensions': ['gph'] - }, - 'application/vnd.fluxtime.clip': { - 'source': 'iana', - 'extensions': ['ftc'] - }, - 'application/vnd.font-fontforge-sfd': {'source': 'iana'}, - 'application/vnd.framemaker': { - 'source': 'iana', - 'extensions': ['fm', 'frame', 'maker', 'book'] - }, - 'application/vnd.frogans.fnc': { - 'source': 'iana', - 'extensions': ['fnc'] - }, - 'application/vnd.frogans.ltf': { - 'source': 'iana', - 'extensions': ['ltf'] - }, - 'application/vnd.fsc.weblaunch': { - 'source': 'iana', - 'extensions': ['fsc'] - }, - 'application/vnd.fujitsu.oasys': { - 'source': 'iana', - 'extensions': ['oas'] - }, - 'application/vnd.fujitsu.oasys2': { - 'source': 'iana', - 'extensions': ['oa2'] - }, - 'application/vnd.fujitsu.oasys3': { - 'source': 'iana', - 'extensions': ['oa3'] - }, - 'application/vnd.fujitsu.oasysgp': { - 'source': 'iana', - 'extensions': ['fg5'] - }, - 'application/vnd.fujitsu.oasysprs': { - 'source': 'iana', - 'extensions': ['bh2'] - }, - 'application/vnd.fujixerox.art-ex': {'source': 'iana'}, - 'application/vnd.fujixerox.art4': {'source': 'iana'}, - 'application/vnd.fujixerox.ddd': { - 'source': 'iana', - 'extensions': ['ddd'] - }, - 'application/vnd.fujixerox.docuworks': { - 'source': 'iana', - 'extensions': ['xdw'] - }, - 'application/vnd.fujixerox.docuworks.binder': { - 'source': 'iana', - 'extensions': ['xbd'] - }, - 'application/vnd.fujixerox.docuworks.container': {'source': 'iana'}, - 'application/vnd.fujixerox.hbpl': {'source': 'iana'}, - 'application/vnd.fut-misnet': {'source': 'iana'}, - 'application/vnd.futoin+cbor': {'source': 'iana'}, - 'application/vnd.futoin+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.fuzzysheet': { - 'source': 'iana', - 'extensions': ['fzs'] - }, - 'application/vnd.genomatix.tuxedo': { - 'source': 'iana', - 'extensions': ['txd'] - }, - 'application/vnd.geo+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.geocube+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.geogebra.file': { - 'source': 'iana', - 'extensions': ['ggb'] - }, - 'application/vnd.geogebra.tool': { - 'source': 'iana', - 'extensions': ['ggt'] - }, - 'application/vnd.geometry-explorer': { - 'source': 'iana', - 'extensions': ['gex', 'gre'] - }, - 'application/vnd.geonext': { - 'source': 'iana', - 'extensions': ['gxt'] - }, - 'application/vnd.geoplan': { - 'source': 'iana', - 'extensions': ['g2w'] - }, - 'application/vnd.geospace': { - 'source': 'iana', - 'extensions': ['g3w'] - }, - 'application/vnd.gerber': {'source': 'iana'}, - 'application/vnd.globalplatform.card-content-mgt': {'source': 'iana'}, - 'application/vnd.globalplatform.card-content-mgt-response': { - 'source': 'iana' - }, - 'application/vnd.gmx': { - 'source': 'iana', - 'extensions': ['gmx'] - }, - 'application/vnd.google-apps.document': { - 'compressible': false, - 'extensions': ['gdoc'] - }, - 'application/vnd.google-apps.presentation': { - 'compressible': false, - 'extensions': ['gslides'] - }, - 'application/vnd.google-apps.spreadsheet': { - 'compressible': false, - 'extensions': ['gsheet'] - }, - 'application/vnd.google-earth.kml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['kml'] - }, - 'application/vnd.google-earth.kmz': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['kmz'] - }, - 'application/vnd.gov.sk.e-form+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.gov.sk.e-form+zip': { - 'source': 'iana', - 'compressible': false - }, - 'application/vnd.gov.sk.xmldatacontainer+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.grafeq': { - 'source': 'iana', - 'extensions': ['gqf', 'gqs'] - }, - 'application/vnd.gridmp': {'source': 'iana'}, - 'application/vnd.groove-account': { - 'source': 'iana', - 'extensions': ['gac'] - }, - 'application/vnd.groove-help': { - 'source': 'iana', - 'extensions': ['ghf'] - }, - 'application/vnd.groove-identity-message': { - 'source': 'iana', - 'extensions': ['gim'] - }, - 'application/vnd.groove-injector': { - 'source': 'iana', - 'extensions': ['grv'] - }, - 'application/vnd.groove-tool-message': { - 'source': 'iana', - 'extensions': ['gtm'] - }, - 'application/vnd.groove-tool-template': { - 'source': 'iana', - 'extensions': ['tpl'] - }, - 'application/vnd.groove-vcard': { - 'source': 'iana', - 'extensions': ['vcg'] - }, - 'application/vnd.hal+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.hal+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['hal'] - }, - 'application/vnd.handheld-entertainment+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['zmm'] - }, - 'application/vnd.hbci': { - 'source': 'iana', - 'extensions': ['hbci'] - }, - 'application/vnd.hc+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.hcl-bireports': {'source': 'iana'}, - 'application/vnd.hdt': {'source': 'iana'}, - 'application/vnd.heroku+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.hhe.lesson-player': { - 'source': 'iana', - 'extensions': ['les'] - }, - 'application/vnd.hp-hpgl': { - 'source': 'iana', - 'extensions': ['hpgl'] - }, - 'application/vnd.hp-hpid': { - 'source': 'iana', - 'extensions': ['hpid'] - }, - 'application/vnd.hp-hps': { - 'source': 'iana', - 'extensions': ['hps'] - }, - 'application/vnd.hp-jlyt': { - 'source': 'iana', - 'extensions': ['jlt'] - }, - 'application/vnd.hp-pcl': { - 'source': 'iana', - 'extensions': ['pcl'] - }, - 'application/vnd.hp-pclxl': { - 'source': 'iana', - 'extensions': ['pclxl'] - }, - 'application/vnd.httphone': {'source': 'iana'}, - 'application/vnd.hydrostatix.sof-data': { - 'source': 'iana', - 'extensions': ['sfd-hdstx'] - }, - 'application/vnd.hyper+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.hyper-item+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.hyperdrive+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.hzn-3d-crossword': {'source': 'iana'}, - 'application/vnd.ibm.afplinedata': {'source': 'iana'}, - 'application/vnd.ibm.electronic-media': {'source': 'iana'}, - 'application/vnd.ibm.minipay': { - 'source': 'iana', - 'extensions': ['mpy'] - }, - 'application/vnd.ibm.modcap': { - 'source': 'iana', - 'extensions': ['afp', 'listafp', 'list3820'] - }, - 'application/vnd.ibm.rights-management': { - 'source': 'iana', - 'extensions': ['irm'] - }, - 'application/vnd.ibm.secure-container': { - 'source': 'iana', - 'extensions': ['sc'] - }, - 'application/vnd.iccprofile': { - 'source': 'iana', - 'extensions': ['icc', 'icm'] - }, - 'application/vnd.ieee.1905': {'source': 'iana'}, - 'application/vnd.igloader': { - 'source': 'iana', - 'extensions': ['igl'] - }, - 'application/vnd.imagemeter.folder+zip': { - 'source': 'iana', - 'compressible': false - }, - 'application/vnd.imagemeter.image+zip': { - 'source': 'iana', - 'compressible': false - }, - 'application/vnd.immervision-ivp': { - 'source': 'iana', - 'extensions': ['ivp'] - }, - 'application/vnd.immervision-ivu': { - 'source': 'iana', - 'extensions': ['ivu'] - }, - 'application/vnd.ims.imsccv1p1': {'source': 'iana'}, - 'application/vnd.ims.imsccv1p2': {'source': 'iana'}, - 'application/vnd.ims.imsccv1p3': {'source': 'iana'}, - 'application/vnd.ims.lis.v2.result+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ims.lti.v2.toolconsumerprofile+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ims.lti.v2.toolproxy+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ims.lti.v2.toolproxy.id+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ims.lti.v2.toolsettings+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ims.lti.v2.toolsettings.simple+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.informedcontrol.rms+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.informix-visionary': {'source': 'iana'}, - 'application/vnd.infotech.project': {'source': 'iana'}, - 'application/vnd.infotech.project+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.innopath.wamp.notification': {'source': 'iana'}, - 'application/vnd.insors.igm': { - 'source': 'iana', - 'extensions': ['igm'] - }, - 'application/vnd.intercon.formnet': { - 'source': 'iana', - 'extensions': ['xpw', 'xpx'] - }, - 'application/vnd.intergeo': { - 'source': 'iana', - 'extensions': ['i2g'] - }, - 'application/vnd.intertrust.digibox': {'source': 'iana'}, - 'application/vnd.intertrust.nncp': {'source': 'iana'}, - 'application/vnd.intu.qbo': { - 'source': 'iana', - 'extensions': ['qbo'] - }, - 'application/vnd.intu.qfx': { - 'source': 'iana', - 'extensions': ['qfx'] - }, - 'application/vnd.iptc.g2.catalogitem+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.iptc.g2.conceptitem+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.iptc.g2.knowledgeitem+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.iptc.g2.newsitem+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.iptc.g2.newsmessage+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.iptc.g2.packageitem+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.iptc.g2.planningitem+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ipunplugged.rcprofile': { - 'source': 'iana', - 'extensions': ['rcprofile'] - }, - 'application/vnd.irepository.package+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['irp'] - }, - 'application/vnd.is-xpr': { - 'source': 'iana', - 'extensions': ['xpr'] - }, - 'application/vnd.isac.fcs': { - 'source': 'iana', - 'extensions': ['fcs'] - }, - 'application/vnd.jam': { - 'source': 'iana', - 'extensions': ['jam'] - }, - 'application/vnd.japannet-directory-service': {'source': 'iana'}, - 'application/vnd.japannet-jpnstore-wakeup': {'source': 'iana'}, - 'application/vnd.japannet-payment-wakeup': {'source': 'iana'}, - 'application/vnd.japannet-registration': {'source': 'iana'}, - 'application/vnd.japannet-registration-wakeup': {'source': 'iana'}, - 'application/vnd.japannet-setstore-wakeup': {'source': 'iana'}, - 'application/vnd.japannet-verification': {'source': 'iana'}, - 'application/vnd.japannet-verification-wakeup': {'source': 'iana'}, - 'application/vnd.jcp.javame.midlet-rms': { - 'source': 'iana', - 'extensions': ['rms'] - }, - 'application/vnd.jisp': { - 'source': 'iana', - 'extensions': ['jisp'] - }, - 'application/vnd.joost.joda-archive': { - 'source': 'iana', - 'extensions': ['joda'] - }, - 'application/vnd.jsk.isdn-ngn': {'source': 'iana'}, - 'application/vnd.kahootz': { - 'source': 'iana', - 'extensions': ['ktz', 'ktr'] - }, - 'application/vnd.kde.karbon': { - 'source': 'iana', - 'extensions': ['karbon'] - }, - 'application/vnd.kde.kchart': { - 'source': 'iana', - 'extensions': ['chrt'] - }, - 'application/vnd.kde.kformula': { - 'source': 'iana', - 'extensions': ['kfo'] - }, - 'application/vnd.kde.kivio': { - 'source': 'iana', - 'extensions': ['flw'] - }, - 'application/vnd.kde.kontour': { - 'source': 'iana', - 'extensions': ['kon'] - }, - 'application/vnd.kde.kpresenter': { - 'source': 'iana', - 'extensions': ['kpr', 'kpt'] - }, - 'application/vnd.kde.kspread': { - 'source': 'iana', - 'extensions': ['ksp'] - }, - 'application/vnd.kde.kword': { - 'source': 'iana', - 'extensions': ['kwd', 'kwt'] - }, - 'application/vnd.kenameaapp': { - 'source': 'iana', - 'extensions': ['htke'] - }, - 'application/vnd.kidspiration': { - 'source': 'iana', - 'extensions': ['kia'] - }, - 'application/vnd.kinar': { - 'source': 'iana', - 'extensions': ['kne', 'knp'] - }, - 'application/vnd.koan': { - 'source': 'iana', - 'extensions': ['skp', 'skd', 'skt', 'skm'] - }, - 'application/vnd.kodak-descriptor': { - 'source': 'iana', - 'extensions': ['sse'] - }, - 'application/vnd.las.las+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.las.las+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['lasxml'] - }, - 'application/vnd.leap+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.liberty-request+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.llamagraphics.life-balance.desktop': { - 'source': 'iana', - 'extensions': ['lbd'] - }, - 'application/vnd.llamagraphics.life-balance.exchange+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['lbe'] - }, - 'application/vnd.lotus-1-2-3': { - 'source': 'iana', - 'extensions': ['123'] - }, - 'application/vnd.lotus-approach': { - 'source': 'iana', - 'extensions': ['apr'] - }, - 'application/vnd.lotus-freelance': { - 'source': 'iana', - 'extensions': ['pre'] - }, - 'application/vnd.lotus-notes': { - 'source': 'iana', - 'extensions': ['nsf'] - }, - 'application/vnd.lotus-organizer': { - 'source': 'iana', - 'extensions': ['org'] - }, - 'application/vnd.lotus-screencam': { - 'source': 'iana', - 'extensions': ['scm'] - }, - 'application/vnd.lotus-wordpro': { - 'source': 'iana', - 'extensions': ['lwp'] - }, - 'application/vnd.macports.portpkg': { - 'source': 'iana', - 'extensions': ['portpkg'] - }, - 'application/vnd.mapbox-vector-tile': {'source': 'iana'}, - 'application/vnd.marlin.drm.actiontoken+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.marlin.drm.conftoken+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.marlin.drm.license+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.marlin.drm.mdcf': {'source': 'iana'}, - 'application/vnd.mason+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.maxmind.maxmind-db': {'source': 'iana'}, - 'application/vnd.mcd': { - 'source': 'iana', - 'extensions': ['mcd'] - }, - 'application/vnd.medcalcdata': { - 'source': 'iana', - 'extensions': ['mc1'] - }, - 'application/vnd.mediastation.cdkey': { - 'source': 'iana', - 'extensions': ['cdkey'] - }, - 'application/vnd.meridian-slingshot': {'source': 'iana'}, - 'application/vnd.mfer': { - 'source': 'iana', - 'extensions': ['mwf'] - }, - 'application/vnd.mfmp': { - 'source': 'iana', - 'extensions': ['mfm'] - }, - 'application/vnd.micro+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.micrografx.flo': { - 'source': 'iana', - 'extensions': ['flo'] - }, - 'application/vnd.micrografx.igx': { - 'source': 'iana', - 'extensions': ['igx'] - }, - 'application/vnd.microsoft.portable-executable': {'source': 'iana'}, - 'application/vnd.microsoft.windows.thumbnail-cache': {'source': 'iana'}, - 'application/vnd.miele+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.mif': { - 'source': 'iana', - 'extensions': ['mif'] - }, - 'application/vnd.minisoft-hp3000-save': {'source': 'iana'}, - 'application/vnd.mitsubishi.misty-guard.trustweb': {'source': 'iana'}, - 'application/vnd.mobius.daf': { - 'source': 'iana', - 'extensions': ['daf'] - }, - 'application/vnd.mobius.dis': { - 'source': 'iana', - 'extensions': ['dis'] - }, - 'application/vnd.mobius.mbk': { - 'source': 'iana', - 'extensions': ['mbk'] - }, - 'application/vnd.mobius.mqy': { - 'source': 'iana', - 'extensions': ['mqy'] - }, - 'application/vnd.mobius.msl': { - 'source': 'iana', - 'extensions': ['msl'] - }, - 'application/vnd.mobius.plc': { - 'source': 'iana', - 'extensions': ['plc'] - }, - 'application/vnd.mobius.txf': { - 'source': 'iana', - 'extensions': ['txf'] - }, - 'application/vnd.mophun.application': { - 'source': 'iana', - 'extensions': ['mpn'] - }, - 'application/vnd.mophun.certificate': { - 'source': 'iana', - 'extensions': ['mpc'] - }, - 'application/vnd.motorola.flexsuite': {'source': 'iana'}, - 'application/vnd.motorola.flexsuite.adsi': {'source': 'iana'}, - 'application/vnd.motorola.flexsuite.fis': {'source': 'iana'}, - 'application/vnd.motorola.flexsuite.gotap': {'source': 'iana'}, - 'application/vnd.motorola.flexsuite.kmr': {'source': 'iana'}, - 'application/vnd.motorola.flexsuite.ttc': {'source': 'iana'}, - 'application/vnd.motorola.flexsuite.wem': {'source': 'iana'}, - 'application/vnd.motorola.iprm': {'source': 'iana'}, - 'application/vnd.mozilla.xul+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xul'] - }, - 'application/vnd.ms-3mfdocument': {'source': 'iana'}, - 'application/vnd.ms-artgalry': { - 'source': 'iana', - 'extensions': ['cil'] - }, - 'application/vnd.ms-asf': {'source': 'iana'}, - 'application/vnd.ms-cab-compressed': { - 'source': 'iana', - 'extensions': ['cab'] - }, - 'application/vnd.ms-color.iccprofile': {'source': 'apache'}, - 'application/vnd.ms-excel': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw'] - }, - 'application/vnd.ms-excel.addin.macroenabled.12': { - 'source': 'iana', - 'extensions': ['xlam'] - }, - 'application/vnd.ms-excel.sheet.binary.macroenabled.12': { - 'source': 'iana', - 'extensions': ['xlsb'] - }, - 'application/vnd.ms-excel.sheet.macroenabled.12': { - 'source': 'iana', - 'extensions': ['xlsm'] - }, - 'application/vnd.ms-excel.template.macroenabled.12': { - 'source': 'iana', - 'extensions': ['xltm'] - }, - 'application/vnd.ms-fontobject': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['eot'] - }, - 'application/vnd.ms-htmlhelp': { - 'source': 'iana', - 'extensions': ['chm'] - }, - 'application/vnd.ms-ims': { - 'source': 'iana', - 'extensions': ['ims'] - }, - 'application/vnd.ms-lrm': { - 'source': 'iana', - 'extensions': ['lrm'] - }, - 'application/vnd.ms-office.activex+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ms-officetheme': { - 'source': 'iana', - 'extensions': ['thmx'] - }, - 'application/vnd.ms-opentype': {'source': 'apache', 'compressible': true}, - 'application/vnd.ms-outlook': { - 'compressible': false, - 'extensions': ['msg'] - }, - 'application/vnd.ms-package.obfuscated-opentype': {'source': 'apache'}, - 'application/vnd.ms-pki.seccat': { - 'source': 'apache', - 'extensions': ['cat'] - }, - 'application/vnd.ms-pki.stl': { - 'source': 'apache', - 'extensions': ['stl'] - }, - 'application/vnd.ms-playready.initiator+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ms-powerpoint': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['ppt', 'pps', 'pot'] - }, - 'application/vnd.ms-powerpoint.addin.macroenabled.12': { - 'source': 'iana', - 'extensions': ['ppam'] - }, - 'application/vnd.ms-powerpoint.presentation.macroenabled.12': { - 'source': 'iana', - 'extensions': ['pptm'] - }, - 'application/vnd.ms-powerpoint.slide.macroenabled.12': { - 'source': 'iana', - 'extensions': ['sldm'] - }, - 'application/vnd.ms-powerpoint.slideshow.macroenabled.12': { - 'source': 'iana', - 'extensions': ['ppsm'] - }, - 'application/vnd.ms-powerpoint.template.macroenabled.12': { - 'source': 'iana', - 'extensions': ['potm'] - }, - 'application/vnd.ms-printdevicecapabilities+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ms-printing.printticket+xml': { - 'source': 'apache', - 'compressible': true - }, - 'application/vnd.ms-printschematicket+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.ms-project': { - 'source': 'iana', - 'extensions': ['mpp', 'mpt'] - }, - 'application/vnd.ms-tnef': {'source': 'iana'}, - 'application/vnd.ms-windows.devicepairing': {'source': 'iana'}, - 'application/vnd.ms-windows.nwprinting.oob': {'source': 'iana'}, - 'application/vnd.ms-windows.printerpairing': {'source': 'iana'}, - 'application/vnd.ms-windows.wsd.oob': {'source': 'iana'}, - 'application/vnd.ms-wmdrm.lic-chlg-req': {'source': 'iana'}, - 'application/vnd.ms-wmdrm.lic-resp': {'source': 'iana'}, - 'application/vnd.ms-wmdrm.meter-chlg-req': {'source': 'iana'}, - 'application/vnd.ms-wmdrm.meter-resp': {'source': 'iana'}, - 'application/vnd.ms-word.document.macroenabled.12': { - 'source': 'iana', - 'extensions': ['docm'] - }, - 'application/vnd.ms-word.template.macroenabled.12': { - 'source': 'iana', - 'extensions': ['dotm'] - }, - 'application/vnd.ms-works': { - 'source': 'iana', - 'extensions': ['wps', 'wks', 'wcm', 'wdb'] - }, - 'application/vnd.ms-wpl': { - 'source': 'iana', - 'extensions': ['wpl'] - }, - 'application/vnd.ms-xpsdocument': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['xps'] - }, - 'application/vnd.msa-disk-image': {'source': 'iana'}, - 'application/vnd.mseq': { - 'source': 'iana', - 'extensions': ['mseq'] - }, - 'application/vnd.msign': {'source': 'iana'}, - 'application/vnd.multiad.creator': {'source': 'iana'}, - 'application/vnd.multiad.creator.cif': {'source': 'iana'}, - 'application/vnd.music-niff': {'source': 'iana'}, - 'application/vnd.musician': { - 'source': 'iana', - 'extensions': ['mus'] - }, - 'application/vnd.muvee.style': { - 'source': 'iana', - 'extensions': ['msty'] - }, - 'application/vnd.mynfc': { - 'source': 'iana', - 'extensions': ['taglet'] - }, - 'application/vnd.ncd.control': {'source': 'iana'}, - 'application/vnd.ncd.reference': {'source': 'iana'}, - 'application/vnd.nearst.inv+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.nervana': {'source': 'iana'}, - 'application/vnd.netfpx': {'source': 'iana'}, - 'application/vnd.neurolanguage.nlu': { - 'source': 'iana', - 'extensions': ['nlu'] - }, - 'application/vnd.nimn': {'source': 'iana'}, - 'application/vnd.nintendo.nitro.rom': {'source': 'iana'}, - 'application/vnd.nintendo.snes.rom': {'source': 'iana'}, - 'application/vnd.nitf': { - 'source': 'iana', - 'extensions': ['ntf', 'nitf'] - }, - 'application/vnd.noblenet-directory': { - 'source': 'iana', - 'extensions': ['nnd'] - }, - 'application/vnd.noblenet-sealer': { - 'source': 'iana', - 'extensions': ['nns'] - }, - 'application/vnd.noblenet-web': { - 'source': 'iana', - 'extensions': ['nnw'] - }, - 'application/vnd.nokia.catalogs': {'source': 'iana'}, - 'application/vnd.nokia.conml+wbxml': {'source': 'iana'}, - 'application/vnd.nokia.conml+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.nokia.iptv.config+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.nokia.isds-radio-presets': {'source': 'iana'}, - 'application/vnd.nokia.landmark+wbxml': {'source': 'iana'}, - 'application/vnd.nokia.landmark+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.nokia.landmarkcollection+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.nokia.n-gage.ac+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.nokia.n-gage.data': { - 'source': 'iana', - 'extensions': ['ngdat'] - }, - 'application/vnd.nokia.n-gage.symbian.install': { - 'source': 'iana', - 'extensions': ['n-gage'] - }, - 'application/vnd.nokia.ncd': {'source': 'iana'}, - 'application/vnd.nokia.pcd+wbxml': {'source': 'iana'}, - 'application/vnd.nokia.pcd+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.nokia.radio-preset': { - 'source': 'iana', - 'extensions': ['rpst'] - }, - 'application/vnd.nokia.radio-presets': { - 'source': 'iana', - 'extensions': ['rpss'] - }, - 'application/vnd.novadigm.edm': { - 'source': 'iana', - 'extensions': ['edm'] - }, - 'application/vnd.novadigm.edx': { - 'source': 'iana', - 'extensions': ['edx'] - }, - 'application/vnd.novadigm.ext': { - 'source': 'iana', - 'extensions': ['ext'] - }, - 'application/vnd.ntt-local.content-share': {'source': 'iana'}, - 'application/vnd.ntt-local.file-transfer': {'source': 'iana'}, - 'application/vnd.ntt-local.ogw_remote-access': {'source': 'iana'}, - 'application/vnd.ntt-local.sip-ta_remote': {'source': 'iana'}, - 'application/vnd.ntt-local.sip-ta_tcp_stream': {'source': 'iana'}, - 'application/vnd.oasis.opendocument.chart': { - 'source': 'iana', - 'extensions': ['odc'] - }, - 'application/vnd.oasis.opendocument.chart-template': { - 'source': 'iana', - 'extensions': ['otc'] - }, - 'application/vnd.oasis.opendocument.database': { - 'source': 'iana', - 'extensions': ['odb'] - }, - 'application/vnd.oasis.opendocument.formula': { - 'source': 'iana', - 'extensions': ['odf'] - }, - 'application/vnd.oasis.opendocument.formula-template': { - 'source': 'iana', - 'extensions': ['odft'] - }, - 'application/vnd.oasis.opendocument.graphics': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['odg'] - }, - 'application/vnd.oasis.opendocument.graphics-template': { - 'source': 'iana', - 'extensions': ['otg'] - }, - 'application/vnd.oasis.opendocument.image': { - 'source': 'iana', - 'extensions': ['odi'] - }, - 'application/vnd.oasis.opendocument.image-template': { - 'source': 'iana', - 'extensions': ['oti'] - }, - 'application/vnd.oasis.opendocument.presentation': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['odp'] - }, - 'application/vnd.oasis.opendocument.presentation-template': { - 'source': 'iana', - 'extensions': ['otp'] - }, - 'application/vnd.oasis.opendocument.spreadsheet': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['ods'] - }, - 'application/vnd.oasis.opendocument.spreadsheet-template': { - 'source': 'iana', - 'extensions': ['ots'] - }, - 'application/vnd.oasis.opendocument.text': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['odt'] - }, - 'application/vnd.oasis.opendocument.text-master': { - 'source': 'iana', - 'extensions': ['odm'] - }, - 'application/vnd.oasis.opendocument.text-template': { - 'source': 'iana', - 'extensions': ['ott'] - }, - 'application/vnd.oasis.opendocument.text-web': { - 'source': 'iana', - 'extensions': ['oth'] - }, - 'application/vnd.obn': {'source': 'iana'}, - 'application/vnd.ocf+cbor': {'source': 'iana'}, - 'application/vnd.oftn.l10n+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.oipf.contentaccessdownload+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oipf.contentaccessstreaming+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oipf.cspg-hexbinary': {'source': 'iana'}, - 'application/vnd.oipf.dae.svg+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oipf.dae.xhtml+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oipf.mippvcontrolmessage+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oipf.pae.gem': {'source': 'iana'}, - 'application/vnd.oipf.spdiscovery+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oipf.spdlist+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oipf.ueprofile+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oipf.userprofile+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.olpc-sugar': { - 'source': 'iana', - 'extensions': ['xo'] - }, - 'application/vnd.oma-scws-config': {'source': 'iana'}, - 'application/vnd.oma-scws-http-request': {'source': 'iana'}, - 'application/vnd.oma-scws-http-response': {'source': 'iana'}, - 'application/vnd.oma.bcast.associated-procedure-parameter+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.bcast.drm-trigger+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.bcast.imd+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oma.bcast.ltkm': {'source': 'iana'}, - 'application/vnd.oma.bcast.notification+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.bcast.provisioningtrigger': {'source': 'iana'}, - 'application/vnd.oma.bcast.sgboot': {'source': 'iana'}, - 'application/vnd.oma.bcast.sgdd+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.bcast.sgdu': {'source': 'iana'}, - 'application/vnd.oma.bcast.simple-symbol-container': {'source': 'iana'}, - 'application/vnd.oma.bcast.smartcard-trigger+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.bcast.sprov+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.bcast.stkm': {'source': 'iana'}, - 'application/vnd.oma.cab-address-book+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.cab-feature-handler+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.cab-pcc+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oma.cab-subs-invite+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.cab-user-prefs+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.dcd': {'source': 'iana'}, - 'application/vnd.oma.dcdc': {'source': 'iana'}, - 'application/vnd.oma.dd2+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['dd2'] - }, - 'application/vnd.oma.drm.risd+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oma.group-usage-list+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.lwm2m+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.oma.lwm2m+tlv': {'source': 'iana'}, - 'application/vnd.oma.pal+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oma.poc.detailed-progress-report+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.poc.final-report+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.poc.groups+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.poc.invocation-descriptor+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.poc.optimized-progress-report+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.push': {'source': 'iana'}, - 'application/vnd.oma.scidm.messages+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oma.xcap-directory+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.omads-email+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.omads-file+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.omads-folder+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.omaloc-supl-init': {'source': 'iana'}, - 'application/vnd.onepager': {'source': 'iana'}, - 'application/vnd.onepagertamp': {'source': 'iana'}, - 'application/vnd.onepagertamx': {'source': 'iana'}, - 'application/vnd.onepagertat': {'source': 'iana'}, - 'application/vnd.onepagertatp': {'source': 'iana'}, - 'application/vnd.onepagertatx': {'source': 'iana'}, - 'application/vnd.openblox.game+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.openblox.game-binary': {'source': 'iana'}, - 'application/vnd.openeye.oeb': {'source': 'iana'}, - 'application/vnd.openofficeorg.extension': { - 'source': 'apache', - 'extensions': ['oxt'] - }, - 'application/vnd.openstreetmap.data+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.custom-properties+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.customxmlproperties+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawing+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.extended-properties+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.comments+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.presentation': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['pptx'] - }, - 'application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.presprops+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.slide': { - 'source': 'iana', - 'extensions': ['sldx'] - }, - 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.slideshow': { - 'source': 'iana', - 'extensions': ['ppsx'] - }, - 'application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.tags+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.presentationml.template': { - 'source': 'iana', - 'extensions': ['potx'] - }, - 'application/vnd.openxmlformats-officedocument.presentationml.template.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['xlsx'] - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.template': { - 'source': 'iana', - 'extensions': ['xltx'] - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.theme+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.themeoverride+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.vmldrawing': { - 'source': 'iana' - }, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['docx'] - }, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': { - 'source': 'iana', - 'extensions': ['dotx'] - }, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml': - {'source': 'iana', 'compressible': true}, - 'application/vnd.openxmlformats-package.core-properties+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.openxmlformats-package.relationships+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.oracle.resource+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.orange.indata': {'source': 'iana'}, - 'application/vnd.osa.netdeploy': {'source': 'iana'}, - 'application/vnd.osgeo.mapguide.package': { - 'source': 'iana', - 'extensions': ['mgp'] - }, - 'application/vnd.osgi.bundle': {'source': 'iana'}, - 'application/vnd.osgi.dp': { - 'source': 'iana', - 'extensions': ['dp'] - }, - 'application/vnd.osgi.subsystem': { - 'source': 'iana', - 'extensions': ['esa'] - }, - 'application/vnd.otps.ct-kip+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.oxli.countgraph': {'source': 'iana'}, - 'application/vnd.pagerduty+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.palm': { - 'source': 'iana', - 'extensions': ['pdb', 'pqa', 'oprc'] - }, - 'application/vnd.panoply': {'source': 'iana'}, - 'application/vnd.paos.xml': {'source': 'iana'}, - 'application/vnd.patentdive': {'source': 'iana'}, - 'application/vnd.pawaafile': { - 'source': 'iana', - 'extensions': ['paw'] - }, - 'application/vnd.pcos': {'source': 'iana'}, - 'application/vnd.pg.format': { - 'source': 'iana', - 'extensions': ['str'] - }, - 'application/vnd.pg.osasli': { - 'source': 'iana', - 'extensions': ['ei6'] - }, - 'application/vnd.piaccess.application-licence': {'source': 'iana'}, - 'application/vnd.picsel': { - 'source': 'iana', - 'extensions': ['efif'] - }, - 'application/vnd.pmi.widget': { - 'source': 'iana', - 'extensions': ['wg'] - }, - 'application/vnd.poc.group-advertisement+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.pocketlearn': { - 'source': 'iana', - 'extensions': ['plf'] - }, - 'application/vnd.powerbuilder6': { - 'source': 'iana', - 'extensions': ['pbd'] - }, - 'application/vnd.powerbuilder6-s': {'source': 'iana'}, - 'application/vnd.powerbuilder7': {'source': 'iana'}, - 'application/vnd.powerbuilder7-s': {'source': 'iana'}, - 'application/vnd.powerbuilder75': {'source': 'iana'}, - 'application/vnd.powerbuilder75-s': {'source': 'iana'}, - 'application/vnd.preminet': {'source': 'iana'}, - 'application/vnd.previewsystems.box': { - 'source': 'iana', - 'extensions': ['box'] - }, - 'application/vnd.proteus.magazine': { - 'source': 'iana', - 'extensions': ['mgz'] - }, - 'application/vnd.psfs': {'source': 'iana'}, - 'application/vnd.publishare-delta-tree': { - 'source': 'iana', - 'extensions': ['qps'] - }, - 'application/vnd.pvi.ptid1': { - 'source': 'iana', - 'extensions': ['ptid'] - }, - 'application/vnd.pwg-multiplexed': {'source': 'iana'}, - 'application/vnd.pwg-xhtml-print+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.qualcomm.brew-app-res': {'source': 'iana'}, - 'application/vnd.quarantainenet': {'source': 'iana'}, - 'application/vnd.quark.quarkxpress': { - 'source': 'iana', - 'extensions': ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb'] - }, - 'application/vnd.quobject-quoxdocument': {'source': 'iana'}, - 'application/vnd.radisys.moml+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.radisys.msml+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.radisys.msml-audit+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-audit-conf+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-audit-conn+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-audit-dialog+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-audit-stream+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-conf+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog-base+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog-fax-detect+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog-fax-sendrecv+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog-group+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog-speech+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.radisys.msml-dialog-transform+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.rainstor.data': {'source': 'iana'}, - 'application/vnd.rapid': {'source': 'iana'}, - 'application/vnd.rar': {'source': 'iana'}, - 'application/vnd.realvnc.bed': { - 'source': 'iana', - 'extensions': ['bed'] - }, - 'application/vnd.recordare.musicxml': { - 'source': 'iana', - 'extensions': ['mxl'] - }, - 'application/vnd.recordare.musicxml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['musicxml'] - }, - 'application/vnd.renlearn.rlprint': {'source': 'iana'}, - 'application/vnd.restful+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.rig.cryptonote': { - 'source': 'iana', - 'extensions': ['cryptonote'] - }, - 'application/vnd.rim.cod': { - 'source': 'apache', - 'extensions': ['cod'] - }, - 'application/vnd.rn-realmedia': { - 'source': 'apache', - 'extensions': ['rm'] - }, - 'application/vnd.rn-realmedia-vbr': { - 'source': 'apache', - 'extensions': ['rmvb'] - }, - 'application/vnd.route66.link66+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['link66'] - }, - 'application/vnd.rs-274x': {'source': 'iana'}, - 'application/vnd.ruckus.download': {'source': 'iana'}, - 'application/vnd.s3sms': {'source': 'iana'}, - 'application/vnd.sailingtracker.track': { - 'source': 'iana', - 'extensions': ['st'] - }, - 'application/vnd.sbm.cid': {'source': 'iana'}, - 'application/vnd.sbm.mid2': {'source': 'iana'}, - 'application/vnd.scribus': {'source': 'iana'}, - 'application/vnd.sealed.3df': {'source': 'iana'}, - 'application/vnd.sealed.csf': {'source': 'iana'}, - 'application/vnd.sealed.doc': {'source': 'iana'}, - 'application/vnd.sealed.eml': {'source': 'iana'}, - 'application/vnd.sealed.mht': {'source': 'iana'}, - 'application/vnd.sealed.net': {'source': 'iana'}, - 'application/vnd.sealed.ppt': {'source': 'iana'}, - 'application/vnd.sealed.tiff': {'source': 'iana'}, - 'application/vnd.sealed.xls': {'source': 'iana'}, - 'application/vnd.sealedmedia.softseal.html': {'source': 'iana'}, - 'application/vnd.sealedmedia.softseal.pdf': {'source': 'iana'}, - 'application/vnd.seemail': { - 'source': 'iana', - 'extensions': ['see'] - }, - 'application/vnd.sema': { - 'source': 'iana', - 'extensions': ['sema'] - }, - 'application/vnd.semd': { - 'source': 'iana', - 'extensions': ['semd'] - }, - 'application/vnd.semf': { - 'source': 'iana', - 'extensions': ['semf'] - }, - 'application/vnd.shana.informed.formdata': { - 'source': 'iana', - 'extensions': ['ifm'] - }, - 'application/vnd.shana.informed.formtemplate': { - 'source': 'iana', - 'extensions': ['itp'] - }, - 'application/vnd.shana.informed.interchange': { - 'source': 'iana', - 'extensions': ['iif'] - }, - 'application/vnd.shana.informed.package': { - 'source': 'iana', - 'extensions': ['ipk'] - }, - 'application/vnd.shootproof+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.sigrok.session': {'source': 'iana'}, - 'application/vnd.simtech-mindmapper': { - 'source': 'iana', - 'extensions': ['twd', 'twds'] - }, - 'application/vnd.siren+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.smaf': { - 'source': 'iana', - 'extensions': ['mmf'] - }, - 'application/vnd.smart.notebook': {'source': 'iana'}, - 'application/vnd.smart.teacher': { - 'source': 'iana', - 'extensions': ['teacher'] - }, - 'application/vnd.software602.filler.form+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.software602.filler.form-xml-zip': {'source': 'iana'}, - 'application/vnd.solent.sdkm+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['sdkm', 'sdkd'] - }, - 'application/vnd.spotfire.dxp': { - 'source': 'iana', - 'extensions': ['dxp'] - }, - 'application/vnd.spotfire.sfs': { - 'source': 'iana', - 'extensions': ['sfs'] - }, - 'application/vnd.sqlite3': {'source': 'iana'}, - 'application/vnd.sss-cod': {'source': 'iana'}, - 'application/vnd.sss-dtf': {'source': 'iana'}, - 'application/vnd.sss-ntf': {'source': 'iana'}, - 'application/vnd.stardivision.calc': { - 'source': 'apache', - 'extensions': ['sdc'] - }, - 'application/vnd.stardivision.draw': { - 'source': 'apache', - 'extensions': ['sda'] - }, - 'application/vnd.stardivision.impress': { - 'source': 'apache', - 'extensions': ['sdd'] - }, - 'application/vnd.stardivision.math': { - 'source': 'apache', - 'extensions': ['smf'] - }, - 'application/vnd.stardivision.writer': { - 'source': 'apache', - 'extensions': ['sdw', 'vor'] - }, - 'application/vnd.stardivision.writer-global': { - 'source': 'apache', - 'extensions': ['sgl'] - }, - 'application/vnd.stepmania.package': { - 'source': 'iana', - 'extensions': ['smzip'] - }, - 'application/vnd.stepmania.stepchart': { - 'source': 'iana', - 'extensions': ['sm'] - }, - 'application/vnd.street-stream': {'source': 'iana'}, - 'application/vnd.sun.wadl+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['wadl'] - }, - 'application/vnd.sun.xml.calc': { - 'source': 'apache', - 'extensions': ['sxc'] - }, - 'application/vnd.sun.xml.calc.template': { - 'source': 'apache', - 'extensions': ['stc'] - }, - 'application/vnd.sun.xml.draw': { - 'source': 'apache', - 'extensions': ['sxd'] - }, - 'application/vnd.sun.xml.draw.template': { - 'source': 'apache', - 'extensions': ['std'] - }, - 'application/vnd.sun.xml.impress': { - 'source': 'apache', - 'extensions': ['sxi'] - }, - 'application/vnd.sun.xml.impress.template': { - 'source': 'apache', - 'extensions': ['sti'] - }, - 'application/vnd.sun.xml.math': { - 'source': 'apache', - 'extensions': ['sxm'] - }, - 'application/vnd.sun.xml.writer': { - 'source': 'apache', - 'extensions': ['sxw'] - }, - 'application/vnd.sun.xml.writer.global': { - 'source': 'apache', - 'extensions': ['sxg'] - }, - 'application/vnd.sun.xml.writer.template': { - 'source': 'apache', - 'extensions': ['stw'] - }, - 'application/vnd.sus-calendar': { - 'source': 'iana', - 'extensions': ['sus', 'susp'] - }, - 'application/vnd.svd': { - 'source': 'iana', - 'extensions': ['svd'] - }, - 'application/vnd.swiftview-ics': {'source': 'iana'}, - 'application/vnd.symbian.install': { - 'source': 'apache', - 'extensions': ['sis', 'sisx'] - }, - 'application/vnd.syncml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xsm'] - }, - 'application/vnd.syncml.dm+wbxml': { - 'source': 'iana', - 'extensions': ['bdm'] - }, - 'application/vnd.syncml.dm+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xdm'] - }, - 'application/vnd.syncml.dm.notification': {'source': 'iana'}, - 'application/vnd.syncml.dmddf+wbxml': {'source': 'iana'}, - 'application/vnd.syncml.dmddf+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.syncml.dmtnds+wbxml': {'source': 'iana'}, - 'application/vnd.syncml.dmtnds+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.syncml.ds.notification': {'source': 'iana'}, - 'application/vnd.tableschema+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.tao.intent-module-archive': { - 'source': 'iana', - 'extensions': ['tao'] - }, - 'application/vnd.tcpdump.pcap': { - 'source': 'iana', - 'extensions': ['pcap', 'cap', 'dmp'] - }, - 'application/vnd.think-cell.ppttc+json': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.tmd.mediaflex.api+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/vnd.tml': {'source': 'iana'}, - 'application/vnd.tmobile-livetv': { - 'source': 'iana', - 'extensions': ['tmo'] - }, - 'application/vnd.tri.onesource': {'source': 'iana'}, - 'application/vnd.trid.tpt': { - 'source': 'iana', - 'extensions': ['tpt'] - }, - 'application/vnd.triscape.mxs': { - 'source': 'iana', - 'extensions': ['mxs'] - }, - 'application/vnd.trueapp': { - 'source': 'iana', - 'extensions': ['tra'] - }, - 'application/vnd.truedoc': {'source': 'iana'}, - 'application/vnd.ubisoft.webplayer': {'source': 'iana'}, - 'application/vnd.ufdl': { - 'source': 'iana', - 'extensions': ['ufd', 'ufdl'] - }, - 'application/vnd.uiq.theme': { - 'source': 'iana', - 'extensions': ['utz'] - }, - 'application/vnd.umajin': { - 'source': 'iana', - 'extensions': ['umj'] - }, - 'application/vnd.unity': { - 'source': 'iana', - 'extensions': ['unityweb'] - }, - 'application/vnd.uoml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['uoml'] - }, - 'application/vnd.uplanet.alert': {'source': 'iana'}, - 'application/vnd.uplanet.alert-wbxml': {'source': 'iana'}, - 'application/vnd.uplanet.bearer-choice': {'source': 'iana'}, - 'application/vnd.uplanet.bearer-choice-wbxml': {'source': 'iana'}, - 'application/vnd.uplanet.cacheop': {'source': 'iana'}, - 'application/vnd.uplanet.cacheop-wbxml': {'source': 'iana'}, - 'application/vnd.uplanet.channel': {'source': 'iana'}, - 'application/vnd.uplanet.channel-wbxml': {'source': 'iana'}, - 'application/vnd.uplanet.list': {'source': 'iana'}, - 'application/vnd.uplanet.list-wbxml': {'source': 'iana'}, - 'application/vnd.uplanet.listcmd': {'source': 'iana'}, - 'application/vnd.uplanet.listcmd-wbxml': {'source': 'iana'}, - 'application/vnd.uplanet.signal': {'source': 'iana'}, - 'application/vnd.uri-map': {'source': 'iana'}, - 'application/vnd.valve.source.material': {'source': 'iana'}, - 'application/vnd.vcx': { - 'source': 'iana', - 'extensions': ['vcx'] - }, - 'application/vnd.vd-study': {'source': 'iana'}, - 'application/vnd.vectorworks': {'source': 'iana'}, - 'application/vnd.vel+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.verimatrix.vcas': {'source': 'iana'}, - 'application/vnd.vidsoft.vidconference': {'source': 'iana'}, - 'application/vnd.visio': { - 'source': 'iana', - 'extensions': ['vsd', 'vst', 'vss', 'vsw'] - }, - 'application/vnd.visionary': { - 'source': 'iana', - 'extensions': ['vis'] - }, - 'application/vnd.vividence.scriptfile': {'source': 'iana'}, - 'application/vnd.vsf': { - 'source': 'iana', - 'extensions': ['vsf'] - }, - 'application/vnd.wap.sic': {'source': 'iana'}, - 'application/vnd.wap.slc': {'source': 'iana'}, - 'application/vnd.wap.wbxml': { - 'source': 'iana', - 'extensions': ['wbxml'] - }, - 'application/vnd.wap.wmlc': { - 'source': 'iana', - 'extensions': ['wmlc'] - }, - 'application/vnd.wap.wmlscriptc': { - 'source': 'iana', - 'extensions': ['wmlsc'] - }, - 'application/vnd.webturbo': { - 'source': 'iana', - 'extensions': ['wtb'] - }, - 'application/vnd.wfa.p2p': {'source': 'iana'}, - 'application/vnd.wfa.wsc': {'source': 'iana'}, - 'application/vnd.windows.devicepairing': {'source': 'iana'}, - 'application/vnd.wmc': {'source': 'iana'}, - 'application/vnd.wmf.bootstrap': {'source': 'iana'}, - 'application/vnd.wolfram.mathematica': {'source': 'iana'}, - 'application/vnd.wolfram.mathematica.package': {'source': 'iana'}, - 'application/vnd.wolfram.player': { - 'source': 'iana', - 'extensions': ['nbp'] - }, - 'application/vnd.wordperfect': { - 'source': 'iana', - 'extensions': ['wpd'] - }, - 'application/vnd.wqd': { - 'source': 'iana', - 'extensions': ['wqd'] - }, - 'application/vnd.wrq-hp3000-labelled': {'source': 'iana'}, - 'application/vnd.wt.stf': { - 'source': 'iana', - 'extensions': ['stf'] - }, - 'application/vnd.wv.csp+wbxml': {'source': 'iana'}, - 'application/vnd.wv.csp+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.wv.ssp+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.xacml+json': {'source': 'iana', 'compressible': true}, - 'application/vnd.xara': { - 'source': 'iana', - 'extensions': ['xar'] - }, - 'application/vnd.xfdl': { - 'source': 'iana', - 'extensions': ['xfdl'] - }, - 'application/vnd.xfdl.webform': {'source': 'iana'}, - 'application/vnd.xmi+xml': {'source': 'iana', 'compressible': true}, - 'application/vnd.xmpie.cpkg': {'source': 'iana'}, - 'application/vnd.xmpie.dpkg': {'source': 'iana'}, - 'application/vnd.xmpie.plan': {'source': 'iana'}, - 'application/vnd.xmpie.ppkg': {'source': 'iana'}, - 'application/vnd.xmpie.xlim': {'source': 'iana'}, - 'application/vnd.yamaha.hv-dic': { - 'source': 'iana', - 'extensions': ['hvd'] - }, - 'application/vnd.yamaha.hv-script': { - 'source': 'iana', - 'extensions': ['hvs'] - }, - 'application/vnd.yamaha.hv-voice': { - 'source': 'iana', - 'extensions': ['hvp'] - }, - 'application/vnd.yamaha.openscoreformat': { - 'source': 'iana', - 'extensions': ['osf'] - }, - 'application/vnd.yamaha.openscoreformat.osfpvg+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['osfpvg'] - }, - 'application/vnd.yamaha.remote-setup': {'source': 'iana'}, - 'application/vnd.yamaha.smaf-audio': { - 'source': 'iana', - 'extensions': ['saf'] - }, - 'application/vnd.yamaha.smaf-phrase': { - 'source': 'iana', - 'extensions': ['spf'] - }, - 'application/vnd.yamaha.through-ngn': {'source': 'iana'}, - 'application/vnd.yamaha.tunnel-udpencap': {'source': 'iana'}, - 'application/vnd.yaoweme': {'source': 'iana'}, - 'application/vnd.yellowriver-custom-menu': { - 'source': 'iana', - 'extensions': ['cmp'] - }, - 'application/vnd.youtube.yt': {'source': 'iana'}, - 'application/vnd.zul': { - 'source': 'iana', - 'extensions': ['zir', 'zirz'] - }, - 'application/vnd.zzazz.deck+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['zaz'] - }, - 'application/voicexml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['vxml'] - }, - 'application/voucher-cms+json': {'source': 'iana', 'compressible': true}, - 'application/vq-rtcpxr': {'source': 'iana'}, - 'application/wasm': { - 'compressible': true, - 'extensions': ['wasm'] - }, - 'application/watcherinfo+xml': {'source': 'iana', 'compressible': true}, - 'application/webpush-options+json': {'source': 'iana', 'compressible': true}, - 'application/whoispp-query': {'source': 'iana'}, - 'application/whoispp-response': {'source': 'iana'}, - 'application/widget': { - 'source': 'iana', - 'extensions': ['wgt'] - }, - 'application/winhlp': { - 'source': 'apache', - 'extensions': ['hlp'] - }, - 'application/wita': {'source': 'iana'}, - 'application/wordperfect5.1': {'source': 'iana'}, - 'application/wsdl+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['wsdl'] - }, - 'application/wspolicy+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['wspolicy'] - }, - 'application/x-7z-compressed': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['7z'] - }, - 'application/x-abiword': { - 'source': 'apache', - 'extensions': ['abw'] - }, - 'application/x-ace-compressed': { - 'source': 'apache', - 'extensions': ['ace'] - }, - 'application/x-amf': {'source': 'apache'}, - 'application/x-apple-diskimage': { - 'source': 'apache', - 'extensions': ['dmg'] - }, - 'application/x-arj': { - 'compressible': false, - 'extensions': ['arj'] - }, - 'application/x-authorware-bin': { - 'source': 'apache', - 'extensions': ['aab', 'x32', 'u32', 'vox'] - }, - 'application/x-authorware-map': { - 'source': 'apache', - 'extensions': ['aam'] - }, - 'application/x-authorware-seg': { - 'source': 'apache', - 'extensions': ['aas'] - }, - 'application/x-bcpio': { - 'source': 'apache', - 'extensions': ['bcpio'] - }, - 'application/x-bdoc': { - 'compressible': false, - 'extensions': ['bdoc'] - }, - 'application/x-bittorrent': { - 'source': 'apache', - 'extensions': ['torrent'] - }, - 'application/x-blorb': { - 'source': 'apache', - 'extensions': ['blb', 'blorb'] - }, - 'application/x-bzip': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['bz'] - }, - 'application/x-bzip2': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['bz2', 'boz'] - }, - 'application/x-cbr': { - 'source': 'apache', - 'extensions': ['cbr', 'cba', 'cbt', 'cbz', 'cb7'] - }, - 'application/x-cdlink': { - 'source': 'apache', - 'extensions': ['vcd'] - }, - 'application/x-cfs-compressed': { - 'source': 'apache', - 'extensions': ['cfs'] - }, - 'application/x-chat': { - 'source': 'apache', - 'extensions': ['chat'] - }, - 'application/x-chess-pgn': { - 'source': 'apache', - 'extensions': ['pgn'] - }, - 'application/x-chrome-extension': { - 'extensions': ['crx'] - }, - 'application/x-cocoa': { - 'source': 'nginx', - 'extensions': ['cco'] - }, - 'application/x-compress': {'source': 'apache'}, - 'application/x-conference': { - 'source': 'apache', - 'extensions': ['nsc'] - }, - 'application/x-cpio': { - 'source': 'apache', - 'extensions': ['cpio'] - }, - 'application/x-csh': { - 'source': 'apache', - 'extensions': ['csh'] - }, - 'application/x-deb': {'compressible': false}, - 'application/x-debian-package': { - 'source': 'apache', - 'extensions': ['deb', 'udeb'] - }, - 'application/x-dgc-compressed': { - 'source': 'apache', - 'extensions': ['dgc'] - }, - 'application/x-director': { - 'source': 'apache', - 'extensions': [ - 'dir', - 'dcr', - 'dxr', - 'cst', - 'cct', - 'cxt', - 'w3d', - 'fgd', - 'swa' - ] - }, - 'application/x-doom': { - 'source': 'apache', - 'extensions': ['wad'] - }, - 'application/x-dtbncx+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['ncx'] - }, - 'application/x-dtbook+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['dtb'] - }, - 'application/x-dtbresource+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['res'] - }, - 'application/x-dvi': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['dvi'] - }, - 'application/x-envoy': { - 'source': 'apache', - 'extensions': ['evy'] - }, - 'application/x-eva': { - 'source': 'apache', - 'extensions': ['eva'] - }, - 'application/x-font-bdf': { - 'source': 'apache', - 'extensions': ['bdf'] - }, - 'application/x-font-dos': {'source': 'apache'}, - 'application/x-font-framemaker': {'source': 'apache'}, - 'application/x-font-ghostscript': { - 'source': 'apache', - 'extensions': ['gsf'] - }, - 'application/x-font-libgrx': {'source': 'apache'}, - 'application/x-font-linux-psf': { - 'source': 'apache', - 'extensions': ['psf'] - }, - 'application/x-font-pcf': { - 'source': 'apache', - 'extensions': ['pcf'] - }, - 'application/x-font-snf': { - 'source': 'apache', - 'extensions': ['snf'] - }, - 'application/x-font-speedo': {'source': 'apache'}, - 'application/x-font-sunos-news': {'source': 'apache'}, - 'application/x-font-type1': { - 'source': 'apache', - 'extensions': ['pfa', 'pfb', 'pfm', 'afm'] - }, - 'application/x-font-vfont': {'source': 'apache'}, - 'application/x-freearc': { - 'source': 'apache', - 'extensions': ['arc'] - }, - 'application/x-futuresplash': { - 'source': 'apache', - 'extensions': ['spl'] - }, - 'application/x-gca-compressed': { - 'source': 'apache', - 'extensions': ['gca'] - }, - 'application/x-glulx': { - 'source': 'apache', - 'extensions': ['ulx'] - }, - 'application/x-gnumeric': { - 'source': 'apache', - 'extensions': ['gnumeric'] - }, - 'application/x-gramps-xml': { - 'source': 'apache', - 'extensions': ['gramps'] - }, - 'application/x-gtar': { - 'source': 'apache', - 'extensions': ['gtar'] - }, - 'application/x-gzip': {'source': 'apache'}, - 'application/x-hdf': { - 'source': 'apache', - 'extensions': ['hdf'] - }, - 'application/x-httpd-php': { - 'compressible': true, - 'extensions': ['php'] - }, - 'application/x-install-instructions': { - 'source': 'apache', - 'extensions': ['install'] - }, - 'application/x-iso9660-image': { - 'source': 'apache', - 'extensions': ['iso'] - }, - 'application/x-java-archive-diff': { - 'source': 'nginx', - 'extensions': ['jardiff'] - }, - 'application/x-java-jnlp-file': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['jnlp'] - }, - 'application/x-javascript': {'compressible': true}, - 'application/x-latex': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['latex'] - }, - 'application/x-lua-bytecode': { - 'extensions': ['luac'] - }, - 'application/x-lzh-compressed': { - 'source': 'apache', - 'extensions': ['lzh', 'lha'] - }, - 'application/x-makeself': { - 'source': 'nginx', - 'extensions': ['run'] - }, - 'application/x-mie': { - 'source': 'apache', - 'extensions': ['mie'] - }, - 'application/x-mobipocket-ebook': { - 'source': 'apache', - 'extensions': ['prc', 'mobi'] - }, - 'application/x-mpegurl': {'compressible': false}, - 'application/x-ms-application': { - 'source': 'apache', - 'extensions': ['application'] - }, - 'application/x-ms-shortcut': { - 'source': 'apache', - 'extensions': ['lnk'] - }, - 'application/x-ms-wmd': { - 'source': 'apache', - 'extensions': ['wmd'] - }, - 'application/x-ms-wmz': { - 'source': 'apache', - 'extensions': ['wmz'] - }, - 'application/x-ms-xbap': { - 'source': 'apache', - 'extensions': ['xbap'] - }, - 'application/x-msaccess': { - 'source': 'apache', - 'extensions': ['mdb'] - }, - 'application/x-msbinder': { - 'source': 'apache', - 'extensions': ['obd'] - }, - 'application/x-mscardfile': { - 'source': 'apache', - 'extensions': ['crd'] - }, - 'application/x-msclip': { - 'source': 'apache', - 'extensions': ['clp'] - }, - 'application/x-msdos-program': { - 'extensions': ['exe'] - }, - 'application/x-msdownload': { - 'source': 'apache', - 'extensions': ['exe', 'dll', 'com', 'bat', 'msi'] - }, - 'application/x-msmediaview': { - 'source': 'apache', - 'extensions': ['mvb', 'm13', 'm14'] - }, - 'application/x-msmetafile': { - 'source': 'apache', - 'extensions': ['wmf', 'wmz', 'emf', 'emz'] - }, - 'application/x-msmoney': { - 'source': 'apache', - 'extensions': ['mny'] - }, - 'application/x-mspublisher': { - 'source': 'apache', - 'extensions': ['pub'] - }, - 'application/x-msschedule': { - 'source': 'apache', - 'extensions': ['scd'] - }, - 'application/x-msterminal': { - 'source': 'apache', - 'extensions': ['trm'] - }, - 'application/x-mswrite': { - 'source': 'apache', - 'extensions': ['wri'] - }, - 'application/x-netcdf': { - 'source': 'apache', - 'extensions': ['nc', 'cdf'] - }, - 'application/x-ns-proxy-autoconfig': { - 'compressible': true, - 'extensions': ['pac'] - }, - 'application/x-nzb': { - 'source': 'apache', - 'extensions': ['nzb'] - }, - 'application/x-perl': { - 'source': 'nginx', - 'extensions': ['pl', 'pm'] - }, - 'application/x-pilot': { - 'source': 'nginx', - 'extensions': ['prc', 'pdb'] - }, - 'application/x-pkcs12': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['p12', 'pfx'] - }, - 'application/x-pkcs7-certificates': { - 'source': 'apache', - 'extensions': ['p7b', 'spc'] - }, - 'application/x-pkcs7-certreqresp': { - 'source': 'apache', - 'extensions': ['p7r'] - }, - 'application/x-rar-compressed': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['rar'] - }, - 'application/x-redhat-package-manager': { - 'source': 'nginx', - 'extensions': ['rpm'] - }, - 'application/x-research-info-systems': { - 'source': 'apache', - 'extensions': ['ris'] - }, - 'application/x-sea': { - 'source': 'nginx', - 'extensions': ['sea'] - }, - 'application/x-sh': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['sh'] - }, - 'application/x-shar': { - 'source': 'apache', - 'extensions': ['shar'] - }, - 'application/x-shockwave-flash': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['swf'] - }, - 'application/x-silverlight-app': { - 'source': 'apache', - 'extensions': ['xap'] - }, - 'application/x-sql': { - 'source': 'apache', - 'extensions': ['sql'] - }, - 'application/x-stuffit': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['sit'] - }, - 'application/x-stuffitx': { - 'source': 'apache', - 'extensions': ['sitx'] - }, - 'application/x-subrip': { - 'source': 'apache', - 'extensions': ['srt'] - }, - 'application/x-sv4cpio': { - 'source': 'apache', - 'extensions': ['sv4cpio'] - }, - 'application/x-sv4crc': { - 'source': 'apache', - 'extensions': ['sv4crc'] - }, - 'application/x-t3vm-image': { - 'source': 'apache', - 'extensions': ['t3'] - }, - 'application/x-tads': { - 'source': 'apache', - 'extensions': ['gam'] - }, - 'application/x-tar': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['tar'] - }, - 'application/x-tcl': { - 'source': 'apache', - 'extensions': ['tcl', 'tk'] - }, - 'application/x-tex': { - 'source': 'apache', - 'extensions': ['tex'] - }, - 'application/x-tex-tfm': { - 'source': 'apache', - 'extensions': ['tfm'] - }, - 'application/x-texinfo': { - 'source': 'apache', - 'extensions': ['texinfo', 'texi'] - }, - 'application/x-tgif': { - 'source': 'apache', - 'extensions': ['obj'] - }, - 'application/x-ustar': { - 'source': 'apache', - 'extensions': ['ustar'] - }, - 'application/x-virtualbox-hdd': { - 'compressible': true, - 'extensions': ['hdd'] - }, - 'application/x-virtualbox-ova': { - 'compressible': true, - 'extensions': ['ova'] - }, - 'application/x-virtualbox-ovf': { - 'compressible': true, - 'extensions': ['ovf'] - }, - 'application/x-virtualbox-vbox': { - 'compressible': true, - 'extensions': ['vbox'] - }, - 'application/x-virtualbox-vbox-extpack': { - 'compressible': false, - 'extensions': ['vbox-extpack'] - }, - 'application/x-virtualbox-vdi': { - 'compressible': true, - 'extensions': ['vdi'] - }, - 'application/x-virtualbox-vhd': { - 'compressible': true, - 'extensions': ['vhd'] - }, - 'application/x-virtualbox-vmdk': { - 'compressible': true, - 'extensions': ['vmdk'] - }, - 'application/x-wais-source': { - 'source': 'apache', - 'extensions': ['src'] - }, - 'application/x-web-app-manifest+json': { - 'compressible': true, - 'extensions': ['webapp'] - }, - 'application/x-www-form-urlencoded': {'source': 'iana', 'compressible': true}, - 'application/x-x509-ca-cert': { - 'source': 'apache', - 'extensions': ['der', 'crt', 'pem'] - }, - 'application/x-xfig': { - 'source': 'apache', - 'extensions': ['fig'] - }, - 'application/x-xliff+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['xlf'] - }, - 'application/x-xpinstall': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['xpi'] - }, - 'application/x-xz': { - 'source': 'apache', - 'extensions': ['xz'] - }, - 'application/x-zmachine': { - 'source': 'apache', - 'extensions': ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'] - }, - 'application/x400-bp': {'source': 'iana'}, - 'application/xacml+xml': {'source': 'iana', 'compressible': true}, - 'application/xaml+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['xaml'] - }, - 'application/xcap-att+xml': {'source': 'iana', 'compressible': true}, - 'application/xcap-caps+xml': {'source': 'iana', 'compressible': true}, - 'application/xcap-diff+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xdf'] - }, - 'application/xcap-el+xml': {'source': 'iana', 'compressible': true}, - 'application/xcap-error+xml': {'source': 'iana', 'compressible': true}, - 'application/xcap-ns+xml': {'source': 'iana', 'compressible': true}, - 'application/xcon-conference-info+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/xcon-conference-info-diff+xml': { - 'source': 'iana', - 'compressible': true - }, - 'application/xenc+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xenc'] - }, - 'application/xhtml+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xhtml', 'xht'] - }, - 'application/xhtml-voice+xml': {'source': 'apache', 'compressible': true}, - 'application/xliff+xml': {'source': 'iana', 'compressible': true}, - 'application/xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xml', 'xsl', 'xsd', 'rng'] - }, - 'application/xml-dtd': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['dtd'] - }, - 'application/xml-external-parsed-entity': {'source': 'iana'}, - 'application/xml-patch+xml': {'source': 'iana', 'compressible': true}, - 'application/xmpp+xml': {'source': 'iana', 'compressible': true}, - 'application/xop+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xop'] - }, - 'application/xproc+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['xpl'] - }, - 'application/xslt+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xslt'] - }, - 'application/xspf+xml': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['xspf'] - }, - 'application/xv+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['mxml', 'xhvml', 'xvml', 'xvm'] - }, - 'application/yang': { - 'source': 'iana', - 'extensions': ['yang'] - }, - 'application/yang-data+json': {'source': 'iana', 'compressible': true}, - 'application/yang-data+xml': {'source': 'iana', 'compressible': true}, - 'application/yang-patch+json': {'source': 'iana', 'compressible': true}, - 'application/yang-patch+xml': {'source': 'iana', 'compressible': true}, - 'application/yin+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['yin'] - }, - 'application/zip': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['zip'] - }, - 'application/zlib': {'source': 'iana'}, - 'application/zstd': {'source': 'iana'}, - 'audio/1d-interleaved-parityfec': {'source': 'iana'}, - 'audio/32kadpcm': {'source': 'iana'}, - 'audio/3gpp': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['3gpp'] - }, - 'audio/3gpp2': {'source': 'iana'}, - 'audio/aac': {'source': 'iana'}, - 'audio/ac3': {'source': 'iana'}, - 'audio/adpcm': { - 'source': 'apache', - 'extensions': ['adp'] - }, - 'audio/amr': {'source': 'iana'}, - 'audio/amr-wb': {'source': 'iana'}, - 'audio/amr-wb+': {'source': 'iana'}, - 'audio/aptx': {'source': 'iana'}, - 'audio/asc': {'source': 'iana'}, - 'audio/atrac-advanced-lossless': {'source': 'iana'}, - 'audio/atrac-x': {'source': 'iana'}, - 'audio/atrac3': {'source': 'iana'}, - 'audio/basic': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['au', 'snd'] - }, - 'audio/bv16': {'source': 'iana'}, - 'audio/bv32': {'source': 'iana'}, - 'audio/clearmode': {'source': 'iana'}, - 'audio/cn': {'source': 'iana'}, - 'audio/dat12': {'source': 'iana'}, - 'audio/dls': {'source': 'iana'}, - 'audio/dsr-es201108': {'source': 'iana'}, - 'audio/dsr-es202050': {'source': 'iana'}, - 'audio/dsr-es202211': {'source': 'iana'}, - 'audio/dsr-es202212': {'source': 'iana'}, - 'audio/dv': {'source': 'iana'}, - 'audio/dvi4': {'source': 'iana'}, - 'audio/eac3': {'source': 'iana'}, - 'audio/encaprtp': {'source': 'iana'}, - 'audio/evrc': {'source': 'iana'}, - 'audio/evrc-qcp': {'source': 'iana'}, - 'audio/evrc0': {'source': 'iana'}, - 'audio/evrc1': {'source': 'iana'}, - 'audio/evrcb': {'source': 'iana'}, - 'audio/evrcb0': {'source': 'iana'}, - 'audio/evrcb1': {'source': 'iana'}, - 'audio/evrcnw': {'source': 'iana'}, - 'audio/evrcnw0': {'source': 'iana'}, - 'audio/evrcnw1': {'source': 'iana'}, - 'audio/evrcwb': {'source': 'iana'}, - 'audio/evrcwb0': {'source': 'iana'}, - 'audio/evrcwb1': {'source': 'iana'}, - 'audio/evs': {'source': 'iana'}, - 'audio/fwdred': {'source': 'iana'}, - 'audio/g711-0': {'source': 'iana'}, - 'audio/g719': {'source': 'iana'}, - 'audio/g722': {'source': 'iana'}, - 'audio/g7221': {'source': 'iana'}, - 'audio/g723': {'source': 'iana'}, - 'audio/g726-16': {'source': 'iana'}, - 'audio/g726-24': {'source': 'iana'}, - 'audio/g726-32': {'source': 'iana'}, - 'audio/g726-40': {'source': 'iana'}, - 'audio/g728': {'source': 'iana'}, - 'audio/g729': {'source': 'iana'}, - 'audio/g7291': {'source': 'iana'}, - 'audio/g729d': {'source': 'iana'}, - 'audio/g729e': {'source': 'iana'}, - 'audio/gsm': {'source': 'iana'}, - 'audio/gsm-efr': {'source': 'iana'}, - 'audio/gsm-hr-08': {'source': 'iana'}, - 'audio/ilbc': {'source': 'iana'}, - 'audio/ip-mr_v2.5': {'source': 'iana'}, - 'audio/isac': {'source': 'apache'}, - 'audio/l16': {'source': 'iana'}, - 'audio/l20': {'source': 'iana'}, - 'audio/l24': {'source': 'iana', 'compressible': false}, - 'audio/l8': {'source': 'iana'}, - 'audio/lpc': {'source': 'iana'}, - 'audio/melp': {'source': 'iana'}, - 'audio/melp1200': {'source': 'iana'}, - 'audio/melp2400': {'source': 'iana'}, - 'audio/melp600': {'source': 'iana'}, - 'audio/midi': { - 'source': 'apache', - 'extensions': ['mid', 'midi', 'kar', 'rmi'] - }, - 'audio/mobile-xmf': {'source': 'iana'}, - 'audio/mp3': { - 'compressible': false, - 'extensions': ['mp3'] - }, - 'audio/mp4': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['m4a', 'mp4a'] - }, - 'audio/mp4a-latm': {'source': 'iana'}, - 'audio/mpa': {'source': 'iana'}, - 'audio/mpa-robust': {'source': 'iana'}, - 'audio/mpeg': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['mpga', 'mp2', 'mp2a', 'mp3', 'm2a', 'm3a'] - }, - 'audio/mpeg4-generic': {'source': 'iana'}, - 'audio/musepack': {'source': 'apache'}, - 'audio/ogg': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['oga', 'ogg', 'spx'] - }, - 'audio/opus': {'source': 'iana'}, - 'audio/parityfec': {'source': 'iana'}, - 'audio/pcma': {'source': 'iana'}, - 'audio/pcma-wb': {'source': 'iana'}, - 'audio/pcmu': {'source': 'iana'}, - 'audio/pcmu-wb': {'source': 'iana'}, - 'audio/prs.sid': {'source': 'iana'}, - 'audio/qcelp': {'source': 'iana'}, - 'audio/raptorfec': {'source': 'iana'}, - 'audio/red': {'source': 'iana'}, - 'audio/rtp-enc-aescm128': {'source': 'iana'}, - 'audio/rtp-midi': {'source': 'iana'}, - 'audio/rtploopback': {'source': 'iana'}, - 'audio/rtx': {'source': 'iana'}, - 'audio/s3m': { - 'source': 'apache', - 'extensions': ['s3m'] - }, - 'audio/silk': { - 'source': 'apache', - 'extensions': ['sil'] - }, - 'audio/smv': {'source': 'iana'}, - 'audio/smv-qcp': {'source': 'iana'}, - 'audio/smv0': {'source': 'iana'}, - 'audio/sp-midi': {'source': 'iana'}, - 'audio/speex': {'source': 'iana'}, - 'audio/t140c': {'source': 'iana'}, - 'audio/t38': {'source': 'iana'}, - 'audio/telephone-event': {'source': 'iana'}, - 'audio/tone': {'source': 'iana'}, - 'audio/uemclip': {'source': 'iana'}, - 'audio/ulpfec': {'source': 'iana'}, - 'audio/usac': {'source': 'iana'}, - 'audio/vdvi': {'source': 'iana'}, - 'audio/vmr-wb': {'source': 'iana'}, - 'audio/vnd.3gpp.iufp': {'source': 'iana'}, - 'audio/vnd.4sb': {'source': 'iana'}, - 'audio/vnd.audiokoz': {'source': 'iana'}, - 'audio/vnd.celp': {'source': 'iana'}, - 'audio/vnd.cisco.nse': {'source': 'iana'}, - 'audio/vnd.cmles.radio-events': {'source': 'iana'}, - 'audio/vnd.cns.anp1': {'source': 'iana'}, - 'audio/vnd.cns.inf1': {'source': 'iana'}, - 'audio/vnd.dece.audio': { - 'source': 'iana', - 'extensions': ['uva', 'uvva'] - }, - 'audio/vnd.digital-winds': { - 'source': 'iana', - 'extensions': ['eol'] - }, - 'audio/vnd.dlna.adts': {'source': 'iana'}, - 'audio/vnd.dolby.heaac.1': {'source': 'iana'}, - 'audio/vnd.dolby.heaac.2': {'source': 'iana'}, - 'audio/vnd.dolby.mlp': {'source': 'iana'}, - 'audio/vnd.dolby.mps': {'source': 'iana'}, - 'audio/vnd.dolby.pl2': {'source': 'iana'}, - 'audio/vnd.dolby.pl2x': {'source': 'iana'}, - 'audio/vnd.dolby.pl2z': {'source': 'iana'}, - 'audio/vnd.dolby.pulse.1': {'source': 'iana'}, - 'audio/vnd.dra': { - 'source': 'iana', - 'extensions': ['dra'] - }, - 'audio/vnd.dts': { - 'source': 'iana', - 'extensions': ['dts'] - }, - 'audio/vnd.dts.hd': { - 'source': 'iana', - 'extensions': ['dtshd'] - }, - 'audio/vnd.dvb.file': {'source': 'iana'}, - 'audio/vnd.everad.plj': {'source': 'iana'}, - 'audio/vnd.hns.audio': {'source': 'iana'}, - 'audio/vnd.lucent.voice': { - 'source': 'iana', - 'extensions': ['lvp'] - }, - 'audio/vnd.ms-playready.media.pya': { - 'source': 'iana', - 'extensions': ['pya'] - }, - 'audio/vnd.nokia.mobile-xmf': {'source': 'iana'}, - 'audio/vnd.nortel.vbk': {'source': 'iana'}, - 'audio/vnd.nuera.ecelp4800': { - 'source': 'iana', - 'extensions': ['ecelp4800'] - }, - 'audio/vnd.nuera.ecelp7470': { - 'source': 'iana', - 'extensions': ['ecelp7470'] - }, - 'audio/vnd.nuera.ecelp9600': { - 'source': 'iana', - 'extensions': ['ecelp9600'] - }, - 'audio/vnd.octel.sbc': {'source': 'iana'}, - 'audio/vnd.presonus.multitrack': {'source': 'iana'}, - 'audio/vnd.qcelp': {'source': 'iana'}, - 'audio/vnd.rhetorex.32kadpcm': {'source': 'iana'}, - 'audio/vnd.rip': { - 'source': 'iana', - 'extensions': ['rip'] - }, - 'audio/vnd.rn-realaudio': {'compressible': false}, - 'audio/vnd.sealedmedia.softseal.mpeg': {'source': 'iana'}, - 'audio/vnd.vmx.cvsd': {'source': 'iana'}, - 'audio/vnd.wave': {'compressible': false}, - 'audio/vorbis': {'source': 'iana', 'compressible': false}, - 'audio/vorbis-config': {'source': 'iana'}, - 'audio/wav': { - 'compressible': false, - 'extensions': ['wav'] - }, - 'audio/wave': { - 'compressible': false, - 'extensions': ['wav'] - }, - 'audio/webm': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['weba'] - }, - 'audio/x-aac': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['aac'] - }, - 'audio/x-aiff': { - 'source': 'apache', - 'extensions': ['aif', 'aiff', 'aifc'] - }, - 'audio/x-caf': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['caf'] - }, - 'audio/x-flac': { - 'source': 'apache', - 'extensions': ['flac'] - }, - 'audio/x-m4a': { - 'source': 'nginx', - 'extensions': ['m4a'] - }, - 'audio/x-matroska': { - 'source': 'apache', - 'extensions': ['mka'] - }, - 'audio/x-mpegurl': { - 'source': 'apache', - 'extensions': ['m3u'] - }, - 'audio/x-ms-wax': { - 'source': 'apache', - 'extensions': ['wax'] - }, - 'audio/x-ms-wma': { - 'source': 'apache', - 'extensions': ['wma'] - }, - 'audio/x-pn-realaudio': { - 'source': 'apache', - 'extensions': ['ram', 'ra'] - }, - 'audio/x-pn-realaudio-plugin': { - 'source': 'apache', - 'extensions': ['rmp'] - }, - 'audio/x-realaudio': { - 'source': 'nginx', - 'extensions': ['ra'] - }, - 'audio/x-tta': {'source': 'apache'}, - 'audio/x-wav': { - 'source': 'apache', - 'extensions': ['wav'] - }, - 'audio/xm': { - 'source': 'apache', - 'extensions': ['xm'] - }, - 'chemical/x-cdx': { - 'source': 'apache', - 'extensions': ['cdx'] - }, - 'chemical/x-cif': { - 'source': 'apache', - 'extensions': ['cif'] - }, - 'chemical/x-cmdf': { - 'source': 'apache', - 'extensions': ['cmdf'] - }, - 'chemical/x-cml': { - 'source': 'apache', - 'extensions': ['cml'] - }, - 'chemical/x-csml': { - 'source': 'apache', - 'extensions': ['csml'] - }, - 'chemical/x-pdb': {'source': 'apache'}, - 'chemical/x-xyz': { - 'source': 'apache', - 'extensions': ['xyz'] - }, - 'font/collection': { - 'source': 'iana', - 'extensions': ['ttc'] - }, - 'font/otf': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['otf'] - }, - 'font/sfnt': {'source': 'iana'}, - 'font/ttf': { - 'source': 'iana', - 'extensions': ['ttf'] - }, - 'font/woff': { - 'source': 'iana', - 'extensions': ['woff'] - }, - 'font/woff2': { - 'source': 'iana', - 'extensions': ['woff2'] - }, - 'image/aces': { - 'source': 'iana', - 'extensions': ['exr'] - }, - 'image/apng': { - 'compressible': false, - 'extensions': ['apng'] - }, - 'image/avci': {'source': 'iana'}, - 'image/avcs': {'source': 'iana'}, - 'image/bmp': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['bmp'] - }, - 'image/cgm': { - 'source': 'iana', - 'extensions': ['cgm'] - }, - 'image/dicom-rle': { - 'source': 'iana', - 'extensions': ['drle'] - }, - 'image/emf': { - 'source': 'iana', - 'extensions': ['emf'] - }, - 'image/fits': { - 'source': 'iana', - 'extensions': ['fits'] - }, - 'image/g3fax': { - 'source': 'iana', - 'extensions': ['g3'] - }, - 'image/gif': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['gif'] - }, - 'image/heic': { - 'source': 'iana', - 'extensions': ['heic'] - }, - 'image/heic-sequence': { - 'source': 'iana', - 'extensions': ['heics'] - }, - 'image/heif': { - 'source': 'iana', - 'extensions': ['heif'] - }, - 'image/heif-sequence': { - 'source': 'iana', - 'extensions': ['heifs'] - }, - 'image/ief': { - 'source': 'iana', - 'extensions': ['ief'] - }, - 'image/jls': { - 'source': 'iana', - 'extensions': ['jls'] - }, - 'image/jp2': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['jp2', 'jpg2'] - }, - 'image/jpeg': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['jpeg', 'jpg', 'jpe'] - }, - 'image/jpm': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['jpm'] - }, - 'image/jpx': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['jpx', 'jpf'] - }, - 'image/ktx': { - 'source': 'iana', - 'extensions': ['ktx'] - }, - 'image/naplps': {'source': 'iana'}, - 'image/pjpeg': {'compressible': false}, - 'image/png': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['png'] - }, - 'image/prs.btif': { - 'source': 'iana', - 'extensions': ['btif'] - }, - 'image/prs.pti': { - 'source': 'iana', - 'extensions': ['pti'] - }, - 'image/pwg-raster': {'source': 'iana'}, - 'image/sgi': { - 'source': 'apache', - 'extensions': ['sgi'] - }, - 'image/svg+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['svg', 'svgz'] - }, - 'image/t38': { - 'source': 'iana', - 'extensions': ['t38'] - }, - 'image/tiff': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['tif', 'tiff'] - }, - 'image/tiff-fx': { - 'source': 'iana', - 'extensions': ['tfx'] - }, - 'image/vnd.adobe.photoshop': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['psd'] - }, - 'image/vnd.airzip.accelerator.azv': { - 'source': 'iana', - 'extensions': ['azv'] - }, - 'image/vnd.cns.inf2': {'source': 'iana'}, - 'image/vnd.dece.graphic': { - 'source': 'iana', - 'extensions': ['uvi', 'uvvi', 'uvg', 'uvvg'] - }, - 'image/vnd.djvu': { - 'source': 'iana', - 'extensions': ['djvu', 'djv'] - }, - 'image/vnd.dvb.subtitle': { - 'source': 'iana', - 'extensions': ['sub'] - }, - 'image/vnd.dwg': { - 'source': 'iana', - 'extensions': ['dwg'] - }, - 'image/vnd.dxf': { - 'source': 'iana', - 'extensions': ['dxf'] - }, - 'image/vnd.fastbidsheet': { - 'source': 'iana', - 'extensions': ['fbs'] - }, - 'image/vnd.fpx': { - 'source': 'iana', - 'extensions': ['fpx'] - }, - 'image/vnd.fst': { - 'source': 'iana', - 'extensions': ['fst'] - }, - 'image/vnd.fujixerox.edmics-mmr': { - 'source': 'iana', - 'extensions': ['mmr'] - }, - 'image/vnd.fujixerox.edmics-rlc': { - 'source': 'iana', - 'extensions': ['rlc'] - }, - 'image/vnd.globalgraphics.pgb': {'source': 'iana'}, - 'image/vnd.microsoft.icon': { - 'source': 'iana', - 'extensions': ['ico'] - }, - 'image/vnd.mix': {'source': 'iana'}, - 'image/vnd.mozilla.apng': {'source': 'iana'}, - 'image/vnd.ms-modi': { - 'source': 'iana', - 'extensions': ['mdi'] - }, - 'image/vnd.ms-photo': { - 'source': 'apache', - 'extensions': ['wdp'] - }, - 'image/vnd.net-fpx': { - 'source': 'iana', - 'extensions': ['npx'] - }, - 'image/vnd.radiance': {'source': 'iana'}, - 'image/vnd.sealed.png': {'source': 'iana'}, - 'image/vnd.sealedmedia.softseal.gif': {'source': 'iana'}, - 'image/vnd.sealedmedia.softseal.jpg': {'source': 'iana'}, - 'image/vnd.svf': {'source': 'iana'}, - 'image/vnd.tencent.tap': { - 'source': 'iana', - 'extensions': ['tap'] - }, - 'image/vnd.valve.source.texture': { - 'source': 'iana', - 'extensions': ['vtf'] - }, - 'image/vnd.wap.wbmp': { - 'source': 'iana', - 'extensions': ['wbmp'] - }, - 'image/vnd.xiff': { - 'source': 'iana', - 'extensions': ['xif'] - }, - 'image/vnd.zbrush.pcx': { - 'source': 'iana', - 'extensions': ['pcx'] - }, - 'image/webp': { - 'source': 'apache', - 'extensions': ['webp'] - }, - 'image/wmf': { - 'source': 'iana', - 'extensions': ['wmf'] - }, - 'image/x-3ds': { - 'source': 'apache', - 'extensions': ['3ds'] - }, - 'image/x-cmu-raster': { - 'source': 'apache', - 'extensions': ['ras'] - }, - 'image/x-cmx': { - 'source': 'apache', - 'extensions': ['cmx'] - }, - 'image/x-freehand': { - 'source': 'apache', - 'extensions': ['fh', 'fhc', 'fh4', 'fh5', 'fh7'] - }, - 'image/x-icon': { - 'source': 'apache', - 'compressible': true, - 'extensions': ['ico'] - }, - 'image/x-jng': { - 'source': 'nginx', - 'extensions': ['jng'] - }, - 'image/x-mrsid-image': { - 'source': 'apache', - 'extensions': ['sid'] - }, - 'image/x-ms-bmp': { - 'source': 'nginx', - 'compressible': true, - 'extensions': ['bmp'] - }, - 'image/x-pcx': { - 'source': 'apache', - 'extensions': ['pcx'] - }, - 'image/x-pict': { - 'source': 'apache', - 'extensions': ['pic', 'pct'] - }, - 'image/x-portable-anymap': { - 'source': 'apache', - 'extensions': ['pnm'] - }, - 'image/x-portable-bitmap': { - 'source': 'apache', - 'extensions': ['pbm'] - }, - 'image/x-portable-graymap': { - 'source': 'apache', - 'extensions': ['pgm'] - }, - 'image/x-portable-pixmap': { - 'source': 'apache', - 'extensions': ['ppm'] - }, - 'image/x-rgb': { - 'source': 'apache', - 'extensions': ['rgb'] - }, - 'image/x-tga': { - 'source': 'apache', - 'extensions': ['tga'] - }, - 'image/x-xbitmap': { - 'source': 'apache', - 'extensions': ['xbm'] - }, - 'image/x-xcf': {'compressible': false}, - 'image/x-xpixmap': { - 'source': 'apache', - 'extensions': ['xpm'] - }, - 'image/x-xwindowdump': { - 'source': 'apache', - 'extensions': ['xwd'] - }, - 'message/cpim': {'source': 'iana'}, - 'message/delivery-status': {'source': 'iana'}, - 'message/disposition-notification': { - 'source': 'iana', - 'extensions': ['disposition-notification'] - }, - 'message/external-body': {'source': 'iana'}, - 'message/feedback-report': {'source': 'iana'}, - 'message/global': { - 'source': 'iana', - 'extensions': ['u8msg'] - }, - 'message/global-delivery-status': { - 'source': 'iana', - 'extensions': ['u8dsn'] - }, - 'message/global-disposition-notification': { - 'source': 'iana', - 'extensions': ['u8mdn'] - }, - 'message/global-headers': { - 'source': 'iana', - 'extensions': ['u8hdr'] - }, - 'message/http': {'source': 'iana', 'compressible': false}, - 'message/imdn+xml': {'source': 'iana', 'compressible': true}, - 'message/news': {'source': 'iana'}, - 'message/partial': {'source': 'iana', 'compressible': false}, - 'message/rfc822': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['eml', 'mime'] - }, - 'message/s-http': {'source': 'iana'}, - 'message/sip': {'source': 'iana'}, - 'message/sipfrag': {'source': 'iana'}, - 'message/tracking-status': {'source': 'iana'}, - 'message/vnd.si.simp': {'source': 'iana'}, - 'message/vnd.wfa.wsc': { - 'source': 'iana', - 'extensions': ['wsc'] - }, - 'model/3mf': {'source': 'iana'}, - 'model/gltf+json': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['gltf'] - }, - 'model/gltf-binary': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['glb'] - }, - 'model/iges': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['igs', 'iges'] - }, - 'model/mesh': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['msh', 'mesh', 'silo'] - }, - 'model/stl': {'source': 'iana'}, - 'model/vnd.collada+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['dae'] - }, - 'model/vnd.dwf': { - 'source': 'iana', - 'extensions': ['dwf'] - }, - 'model/vnd.flatland.3dml': {'source': 'iana'}, - 'model/vnd.gdl': { - 'source': 'iana', - 'extensions': ['gdl'] - }, - 'model/vnd.gs-gdl': {'source': 'apache'}, - 'model/vnd.gs.gdl': {'source': 'iana'}, - 'model/vnd.gtw': { - 'source': 'iana', - 'extensions': ['gtw'] - }, - 'model/vnd.moml+xml': {'source': 'iana', 'compressible': true}, - 'model/vnd.mts': { - 'source': 'iana', - 'extensions': ['mts'] - }, - 'model/vnd.opengex': {'source': 'iana'}, - 'model/vnd.parasolid.transmit.binary': {'source': 'iana'}, - 'model/vnd.parasolid.transmit.text': {'source': 'iana'}, - 'model/vnd.rosette.annotated-data-model': {'source': 'iana'}, - 'model/vnd.usdz+zip': {'source': 'iana', 'compressible': false}, - 'model/vnd.valve.source.compiled-map': {'source': 'iana'}, - 'model/vnd.vtu': { - 'source': 'iana', - 'extensions': ['vtu'] - }, - 'model/vrml': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['wrl', 'vrml'] - }, - 'model/x3d+binary': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['x3db', 'x3dbz'] - }, - 'model/x3d+fastinfoset': {'source': 'iana'}, - 'model/x3d+vrml': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['x3dv', 'x3dvz'] - }, - 'model/x3d+xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['x3d', 'x3dz'] - }, - 'model/x3d-vrml': {'source': 'iana'}, - 'multipart/alternative': {'source': 'iana', 'compressible': false}, - 'multipart/appledouble': {'source': 'iana'}, - 'multipart/byteranges': {'source': 'iana'}, - 'multipart/digest': {'source': 'iana'}, - 'multipart/encrypted': {'source': 'iana', 'compressible': false}, - 'multipart/form-data': {'source': 'iana', 'compressible': false}, - 'multipart/header-set': {'source': 'iana'}, - 'multipart/mixed': {'source': 'iana', 'compressible': false}, - 'multipart/multilingual': {'source': 'iana'}, - 'multipart/parallel': {'source': 'iana'}, - 'multipart/related': {'source': 'iana', 'compressible': false}, - 'multipart/report': {'source': 'iana'}, - 'multipart/signed': {'source': 'iana', 'compressible': false}, - 'multipart/vnd.bint.med-plus': {'source': 'iana'}, - 'multipart/voice-message': {'source': 'iana'}, - 'multipart/x-mixed-replace': {'source': 'iana'}, - 'text/1d-interleaved-parityfec': {'source': 'iana'}, - 'text/cache-manifest': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['appcache', 'manifest'] - }, - 'text/calendar': { - 'source': 'iana', - 'extensions': ['ics', 'ifb'] - }, - 'text/calender': {'compressible': true}, - 'text/cmd': {'compressible': true}, - 'text/coffeescript': { - 'extensions': ['coffee', 'litcoffee'] - }, - 'text/css': { - 'source': 'iana', - 'charset': 'UTF-8', - 'compressible': true, - 'extensions': ['css'] - }, - 'text/csv': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['csv'] - }, - 'text/csv-schema': {'source': 'iana'}, - 'text/directory': {'source': 'iana'}, - 'text/dns': {'source': 'iana'}, - 'text/ecmascript': {'source': 'iana'}, - 'text/encaprtp': {'source': 'iana'}, - 'text/enriched': {'source': 'iana'}, - 'text/fwdred': {'source': 'iana'}, - 'text/grammar-ref-list': {'source': 'iana'}, - 'text/html': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['html', 'htm', 'shtml'] - }, - 'text/jade': { - 'extensions': ['jade'] - }, - 'text/javascript': {'source': 'iana', 'compressible': true}, - 'text/jcr-cnd': {'source': 'iana'}, - 'text/jsx': { - 'compressible': true, - 'extensions': ['jsx'] - }, - 'text/less': { - 'extensions': ['less'] - }, - 'text/markdown': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['markdown', 'md'] - }, - 'text/mathml': { - 'source': 'nginx', - 'extensions': ['mml'] - }, - 'text/mizar': {'source': 'iana'}, - 'text/n3': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['n3'] - }, - 'text/parameters': {'source': 'iana'}, - 'text/parityfec': {'source': 'iana'}, - 'text/plain': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'] - }, - 'text/provenance-notation': {'source': 'iana'}, - 'text/prs.fallenstein.rst': {'source': 'iana'}, - 'text/prs.lines.tag': { - 'source': 'iana', - 'extensions': ['dsc'] - }, - 'text/prs.prop.logic': {'source': 'iana'}, - 'text/raptorfec': {'source': 'iana'}, - 'text/red': {'source': 'iana'}, - 'text/rfc822-headers': {'source': 'iana'}, - 'text/richtext': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rtx'] - }, - 'text/rtf': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['rtf'] - }, - 'text/rtp-enc-aescm128': {'source': 'iana'}, - 'text/rtploopback': {'source': 'iana'}, - 'text/rtx': {'source': 'iana'}, - 'text/sgml': { - 'source': 'iana', - 'extensions': ['sgml', 'sgm'] - }, - 'text/shex': { - 'extensions': ['shex'] - }, - 'text/slim': { - 'extensions': ['slim', 'slm'] - }, - 'text/strings': {'source': 'iana'}, - 'text/stylus': { - 'extensions': ['stylus', 'styl'] - }, - 'text/t140': {'source': 'iana'}, - 'text/tab-separated-values': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['tsv'] - }, - 'text/troff': { - 'source': 'iana', - 'extensions': ['t', 'tr', 'roff', 'man', 'me', 'ms'] - }, - 'text/turtle': { - 'source': 'iana', - 'charset': 'UTF-8', - 'extensions': ['ttl'] - }, - 'text/ulpfec': {'source': 'iana'}, - 'text/uri-list': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['uri', 'uris', 'urls'] - }, - 'text/vcard': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['vcard'] - }, - 'text/vnd.a': {'source': 'iana'}, - 'text/vnd.abc': {'source': 'iana'}, - 'text/vnd.ascii-art': {'source': 'iana'}, - 'text/vnd.curl': { - 'source': 'iana', - 'extensions': ['curl'] - }, - 'text/vnd.curl.dcurl': { - 'source': 'apache', - 'extensions': ['dcurl'] - }, - 'text/vnd.curl.mcurl': { - 'source': 'apache', - 'extensions': ['mcurl'] - }, - 'text/vnd.curl.scurl': { - 'source': 'apache', - 'extensions': ['scurl'] - }, - 'text/vnd.debian.copyright': {'source': 'iana'}, - 'text/vnd.dmclientscript': {'source': 'iana'}, - 'text/vnd.dvb.subtitle': { - 'source': 'iana', - 'extensions': ['sub'] - }, - 'text/vnd.esmertec.theme-descriptor': {'source': 'iana'}, - 'text/vnd.fly': { - 'source': 'iana', - 'extensions': ['fly'] - }, - 'text/vnd.fmi.flexstor': { - 'source': 'iana', - 'extensions': ['flx'] - }, - 'text/vnd.gml': {'source': 'iana'}, - 'text/vnd.graphviz': { - 'source': 'iana', - 'extensions': ['gv'] - }, - 'text/vnd.hgl': {'source': 'iana'}, - 'text/vnd.in3d.3dml': { - 'source': 'iana', - 'extensions': ['3dml'] - }, - 'text/vnd.in3d.spot': { - 'source': 'iana', - 'extensions': ['spot'] - }, - 'text/vnd.iptc.newsml': {'source': 'iana'}, - 'text/vnd.iptc.nitf': {'source': 'iana'}, - 'text/vnd.latex-z': {'source': 'iana'}, - 'text/vnd.motorola.reflex': {'source': 'iana'}, - 'text/vnd.ms-mediapackage': {'source': 'iana'}, - 'text/vnd.net2phone.commcenter.command': {'source': 'iana'}, - 'text/vnd.radisys.msml-basic-layout': {'source': 'iana'}, - 'text/vnd.si.uricatalogue': {'source': 'iana'}, - 'text/vnd.sun.j2me.app-descriptor': { - 'source': 'iana', - 'extensions': ['jad'] - }, - 'text/vnd.trolltech.linguist': {'source': 'iana'}, - 'text/vnd.wap.si': {'source': 'iana'}, - 'text/vnd.wap.sl': {'source': 'iana'}, - 'text/vnd.wap.wml': { - 'source': 'iana', - 'extensions': ['wml'] - }, - 'text/vnd.wap.wmlscript': { - 'source': 'iana', - 'extensions': ['wmls'] - }, - 'text/vtt': { - 'charset': 'UTF-8', - 'compressible': true, - 'extensions': ['vtt'] - }, - 'text/x-asm': { - 'source': 'apache', - 'extensions': ['s', 'asm'] - }, - 'text/x-c': { - 'source': 'apache', - 'extensions': ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'] - }, - 'text/x-component': { - 'source': 'nginx', - 'extensions': ['htc'] - }, - 'text/x-fortran': { - 'source': 'apache', - 'extensions': ['f', 'for', 'f77', 'f90'] - }, - 'text/x-gwt-rpc': {'compressible': true}, - 'text/x-handlebars-template': { - 'extensions': ['hbs'] - }, - 'text/x-java-source': { - 'source': 'apache', - 'extensions': ['java'] - }, - 'text/x-jquery-tmpl': {'compressible': true}, - 'text/x-lua': { - 'extensions': ['lua'] - }, - 'text/x-markdown': { - 'compressible': true, - 'extensions': ['mkd'] - }, - 'text/x-nfo': { - 'source': 'apache', - 'extensions': ['nfo'] - }, - 'text/x-opml': { - 'source': 'apache', - 'extensions': ['opml'] - }, - 'text/x-org': { - 'compressible': true, - 'extensions': ['org'] - }, - 'text/x-pascal': { - 'source': 'apache', - 'extensions': ['p', 'pas'] - }, - 'text/x-processing': { - 'compressible': true, - 'extensions': ['pde'] - }, - 'text/x-sass': { - 'extensions': ['sass'] - }, - 'text/x-scss': { - 'extensions': ['scss'] - }, - 'text/x-setext': { - 'source': 'apache', - 'extensions': ['etx'] - }, - 'text/x-sfv': { - 'source': 'apache', - 'extensions': ['sfv'] - }, - 'text/x-suse-ymp': { - 'compressible': true, - 'extensions': ['ymp'] - }, - 'text/x-uuencode': { - 'source': 'apache', - 'extensions': ['uu'] - }, - 'text/x-vcalendar': { - 'source': 'apache', - 'extensions': ['vcs'] - }, - 'text/x-vcard': { - 'source': 'apache', - 'extensions': ['vcf'] - }, - 'text/xml': { - 'source': 'iana', - 'compressible': true, - 'extensions': ['xml'] - }, - 'text/xml-external-parsed-entity': {'source': 'iana'}, - 'text/yaml': { - 'extensions': ['yaml', 'yml'] - }, - 'video/1d-interleaved-parityfec': {'source': 'iana'}, - 'video/3gpp': { - 'source': 'iana', - 'extensions': ['3gp', '3gpp'] - }, - 'video/3gpp-tt': {'source': 'iana'}, - 'video/3gpp2': { - 'source': 'iana', - 'extensions': ['3g2'] - }, - 'video/bmpeg': {'source': 'iana'}, - 'video/bt656': {'source': 'iana'}, - 'video/celb': {'source': 'iana'}, - 'video/dv': {'source': 'iana'}, - 'video/encaprtp': {'source': 'iana'}, - 'video/h261': { - 'source': 'iana', - 'extensions': ['h261'] - }, - 'video/h263': { - 'source': 'iana', - 'extensions': ['h263'] - }, - 'video/h263-1998': {'source': 'iana'}, - 'video/h263-2000': {'source': 'iana'}, - 'video/h264': { - 'source': 'iana', - 'extensions': ['h264'] - }, - 'video/h264-rcdo': {'source': 'iana'}, - 'video/h264-svc': {'source': 'iana'}, - 'video/h265': {'source': 'iana'}, - 'video/iso.segment': {'source': 'iana'}, - 'video/jpeg': { - 'source': 'iana', - 'extensions': ['jpgv'] - }, - 'video/jpeg2000': {'source': 'iana'}, - 'video/jpm': { - 'source': 'apache', - 'extensions': ['jpm', 'jpgm'] - }, - 'video/mj2': { - 'source': 'iana', - 'extensions': ['mj2', 'mjp2'] - }, - 'video/mp1s': {'source': 'iana'}, - 'video/mp2p': {'source': 'iana'}, - 'video/mp2t': { - 'source': 'iana', - 'extensions': ['ts'] - }, - 'video/mp4': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['mp4', 'mp4v', 'mpg4'] - }, - 'video/mp4v-es': {'source': 'iana'}, - 'video/mpeg': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'] - }, - 'video/mpeg4-generic': {'source': 'iana'}, - 'video/mpv': {'source': 'iana'}, - 'video/nv': {'source': 'iana'}, - 'video/ogg': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['ogv'] - }, - 'video/parityfec': {'source': 'iana'}, - 'video/pointer': {'source': 'iana'}, - 'video/quicktime': { - 'source': 'iana', - 'compressible': false, - 'extensions': ['qt', 'mov'] - }, - 'video/raptorfec': {'source': 'iana'}, - 'video/raw': {'source': 'iana'}, - 'video/rtp-enc-aescm128': {'source': 'iana'}, - 'video/rtploopback': {'source': 'iana'}, - 'video/rtx': {'source': 'iana'}, - 'video/smpte291': {'source': 'iana'}, - 'video/smpte292m': {'source': 'iana'}, - 'video/ulpfec': {'source': 'iana'}, - 'video/vc1': {'source': 'iana'}, - 'video/vc2': {'source': 'iana'}, - 'video/vnd.cctv': {'source': 'iana'}, - 'video/vnd.dece.hd': { - 'source': 'iana', - 'extensions': ['uvh', 'uvvh'] - }, - 'video/vnd.dece.mobile': { - 'source': 'iana', - 'extensions': ['uvm', 'uvvm'] - }, - 'video/vnd.dece.mp4': {'source': 'iana'}, - 'video/vnd.dece.pd': { - 'source': 'iana', - 'extensions': ['uvp', 'uvvp'] - }, - 'video/vnd.dece.sd': { - 'source': 'iana', - 'extensions': ['uvs', 'uvvs'] - }, - 'video/vnd.dece.video': { - 'source': 'iana', - 'extensions': ['uvv', 'uvvv'] - }, - 'video/vnd.directv.mpeg': {'source': 'iana'}, - 'video/vnd.directv.mpeg-tts': {'source': 'iana'}, - 'video/vnd.dlna.mpeg-tts': {'source': 'iana'}, - 'video/vnd.dvb.file': { - 'source': 'iana', - 'extensions': ['dvb'] - }, - 'video/vnd.fvt': { - 'source': 'iana', - 'extensions': ['fvt'] - }, - 'video/vnd.hns.video': {'source': 'iana'}, - 'video/vnd.iptvforum.1dparityfec-1010': {'source': 'iana'}, - 'video/vnd.iptvforum.1dparityfec-2005': {'source': 'iana'}, - 'video/vnd.iptvforum.2dparityfec-1010': {'source': 'iana'}, - 'video/vnd.iptvforum.2dparityfec-2005': {'source': 'iana'}, - 'video/vnd.iptvforum.ttsavc': {'source': 'iana'}, - 'video/vnd.iptvforum.ttsmpeg2': {'source': 'iana'}, - 'video/vnd.motorola.video': {'source': 'iana'}, - 'video/vnd.motorola.videop': {'source': 'iana'}, - 'video/vnd.mpegurl': { - 'source': 'iana', - 'extensions': ['mxu', 'm4u'] - }, - 'video/vnd.ms-playready.media.pyv': { - 'source': 'iana', - 'extensions': ['pyv'] - }, - 'video/vnd.nokia.interleaved-multimedia': {'source': 'iana'}, - 'video/vnd.nokia.mp4vr': {'source': 'iana'}, - 'video/vnd.nokia.videovoip': {'source': 'iana'}, - 'video/vnd.objectvideo': {'source': 'iana'}, - 'video/vnd.radgamettools.bink': {'source': 'iana'}, - 'video/vnd.radgamettools.smacker': {'source': 'iana'}, - 'video/vnd.sealed.mpeg1': {'source': 'iana'}, - 'video/vnd.sealed.mpeg4': {'source': 'iana'}, - 'video/vnd.sealed.swf': {'source': 'iana'}, - 'video/vnd.sealedmedia.softseal.mov': {'source': 'iana'}, - 'video/vnd.uvvu.mp4': { - 'source': 'iana', - 'extensions': ['uvu', 'uvvu'] - }, - 'video/vnd.vivo': { - 'source': 'iana', - 'extensions': ['viv'] - }, - 'video/vp8': {'source': 'iana'}, - 'video/webm': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['webm'] - }, - 'video/x-f4v': { - 'source': 'apache', - 'extensions': ['f4v'] - }, - 'video/x-fli': { - 'source': 'apache', - 'extensions': ['fli'] - }, - 'video/x-flv': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['flv'] - }, - 'video/x-m4v': { - 'source': 'apache', - 'extensions': ['m4v'] - }, - 'video/x-matroska': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['mkv', 'mk3d', 'mks'] - }, - 'video/x-mng': { - 'source': 'apache', - 'extensions': ['mng'] - }, - 'video/x-ms-asf': { - 'source': 'apache', - 'extensions': ['asf', 'asx'] - }, - 'video/x-ms-vob': { - 'source': 'apache', - 'extensions': ['vob'] - }, - 'video/x-ms-wm': { - 'source': 'apache', - 'extensions': ['wm'] - }, - 'video/x-ms-wmv': { - 'source': 'apache', - 'compressible': false, - 'extensions': ['wmv'] - }, - 'video/x-ms-wmx': { - 'source': 'apache', - 'extensions': ['wmx'] - }, - 'video/x-ms-wvx': { - 'source': 'apache', - 'extensions': ['wvx'] - }, - 'video/x-msvideo': { - 'source': 'apache', - 'extensions': ['avi'] - }, - 'video/x-sgi-movie': { - 'source': 'apache', - 'extensions': ['movie'] - }, - 'video/x-smv': { - 'source': 'apache', - 'extensions': ['smv'] - }, - 'x-conference/x-cooltalk': { - 'source': 'apache', - 'extensions': ['ice'] - }, - 'x-shader/x-fragment': {'compressible': true}, - 'x-shader/x-vertex': {'compressible': true} -}; From f8c5820417effe0ee702ab0d157cd1cea62ac6fb Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 16:04:52 +0100 Subject: [PATCH 082/195] dart(encoder): Annotate --- packages/dart/lib/src/utils/parse_encoder.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/utils/parse_encoder.dart b/packages/dart/lib/src/utils/parse_encoder.dart index 66ff7d558..30c924e73 100644 --- a/packages/dart/lib/src/utils/parse_encoder.dart +++ b/packages/dart/lib/src/utils/parse_encoder.dart @@ -68,7 +68,7 @@ Map _encodeDate(DateTime date) { }; } -Map encodeObject(String className, String objectId) { +Map encodeObject(String className, String/*!*/ objectId) { return { '__type': 'Pointer', keyVarClassName: className, From 2ac739106427ac008ba9305a42ec7e659e3a3f22 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 16:08:21 +0100 Subject: [PATCH 083/195] dart(res_builder): response cannot be null --- .../response/parse_response_builder.dart | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/dart/lib/src/objects/response/parse_response_builder.dart b/packages/dart/lib/src/objects/response/parse_response_builder.dart index 5917a884e..1343f12ce 100644 --- a/packages/dart/lib/src/objects/response/parse_response_builder.dart +++ b/packages/dart/lib/src/objects/response/parse_response_builder.dart @@ -12,27 +12,21 @@ class _ParseResponseBuilder { dynamic object, ParseNetworkResponse apiResponse, ParseApiRQ type) { final ParseResponse parseResponse = ParseResponse(); final bool returnAsResult = shouldReturnAsABaseResult(type); - if (apiResponse != null) { - parseResponse.statusCode = apiResponse.statusCode; + parseResponse.statusCode = apiResponse.statusCode; - if (isUnsuccessfulResponse(apiResponse)) { - return buildErrorResponse(parseResponse, apiResponse); - } else if (isHealthCheck(apiResponse)) { - parseResponse.success = true; - return parseResponse; - } else if (isSuccessButNoResults(apiResponse)) { - return buildSuccessResponseWithNoResults( - parseResponse, 1, 'Successful request, but no results found'); - } else if (returnAsResult) { - return _handleSuccessWithoutParseObject( - parseResponse, object, apiResponse.data); - } else { - return _handleSuccess(parseResponse, object, apiResponse.data, type); - } - } else { - parseResponse.error = ParseError( - message: 'Error reaching server, or server response was null'); + if (isUnsuccessfulResponse(apiResponse)) { + return buildErrorResponse(parseResponse, apiResponse); + } else if (isHealthCheck(apiResponse)) { + parseResponse.success = true; return parseResponse; + } else if (isSuccessButNoResults(apiResponse)) { + return buildSuccessResponseWithNoResults( + parseResponse, 1, 'Successful request, but no results found'); + } else if (returnAsResult) { + return _handleSuccessWithoutParseObject( + parseResponse, object, apiResponse.data); + } else { + return _handleSuccess(parseResponse, object, apiResponse.data, type); } } From a023b8a364b1f4e66a63c4560b9bbfc837bf72ad Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 16:16:21 +0100 Subject: [PATCH 084/195] dart(res_builder): Annotate --- .../src/objects/response/parse_response_builder.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/dart/lib/src/objects/response/parse_response_builder.dart b/packages/dart/lib/src/objects/response/parse_response_builder.dart index 1343f12ce..88172b8aa 100644 --- a/packages/dart/lib/src/objects/response/parse_response_builder.dart +++ b/packages/dart/lib/src/objects/response/parse_response_builder.dart @@ -90,18 +90,18 @@ class _ParseResponseBuilder { response.result = results; response.count = results.length; } else { - final List items = _handleMultipleResults(object, results); + final List items = _handleMultipleResults(object, results); response.results = items; response.result = items; response.count = items.length; } } else if (map != null && map.length == 2 && map.containsKey('count')) { - final List results = [map['count']]; + final List results = [map['count']]; response.results = results; response.result = results; response.count = map['count']; } else { - final T item = _handleSingleResult(object, map, false); + final T item = _handleSingleResult(object, map, false); response.count = 1; response.result = item; response.results = [item]; @@ -112,8 +112,8 @@ class _ParseResponseBuilder { } /// Handles a response with a multiple result object - List _handleMultipleResults(T object, List data) { - final List resultsList = []; + List _handleMultipleResults(T/*!*/ object, List data) { + final List resultsList = []; for (dynamic value in data) { resultsList.add(_handleSingleResult(object, value, true)); } @@ -122,7 +122,7 @@ class _ParseResponseBuilder { /// Handles a response with a single result object T _handleSingleResult( - T object, Map map, bool createNewObject) { + T/*!*/ object, Map/*!*/ map, bool createNewObject) { if (createNewObject && object is ParseCloneable) { return object.clone(map); } else if (object is ParseObject) { From cef907ed71066e5f7965d269917a4f80466a9716 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 16:25:02 +0100 Subject: [PATCH 085/195] dart(xxtea): Annotate --- packages/dart/lib/src/storage/xxtea_codec.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/storage/xxtea_codec.dart b/packages/dart/lib/src/storage/xxtea_codec.dart index 863bb063f..06ecd3abf 100644 --- a/packages/dart/lib/src/storage/xxtea_codec.dart +++ b/packages/dart/lib/src/storage/xxtea_codec.dart @@ -6,7 +6,7 @@ class _XXTeaEncoder extends Converter, String> { final String key; @override - String convert(Map input) => + String/*!*/ convert(Map input) => xxtea.encryptToString(json.encode(input), key); } From 8203cd7d85751d7cbc2112c9a5d56c695efec9d9 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 16:33:33 +0100 Subject: [PATCH 086/195] dart(SembastStore): Annotate --- packages/dart/lib/src/storage/core_store_sem_impl.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/storage/core_store_sem_impl.dart b/packages/dart/lib/src/storage/core_store_sem_impl.dart index 4346e182d..2971507cd 100644 --- a/packages/dart/lib/src/storage/core_store_sem_impl.dart +++ b/packages/dart/lib/src/storage/core_store_sem_impl.dart @@ -6,7 +6,7 @@ class CoreStoreSembastImp implements CoreStore { static CoreStoreSembastImp _instance; - static Future getInstance(String dbPath, + static Future getInstance(String dbPath, {DatabaseFactory factory, String password = 'flutter_sdk'}) async { if (_instance == null) { factory ??= !parseIsWeb ? databaseFactoryIo : databaseFactoryWeb; @@ -42,7 +42,7 @@ class CoreStoreSembastImp implements CoreStore { final StoreRef _store; @override - Future clear() { + Future clear() { return _store.drop(_database); } From eea21cd448bb91c6a6175fb6eda6dce3f02ff564 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 16:57:24 +0100 Subject: [PATCH 087/195] dart(file_base): Annotate --- packages/dart/lib/src/objects/parse_file_base.dart | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_file_base.dart b/packages/dart/lib/src/objects/parse_file_base.dart index f1102d70f..f483cf9a5 100644 --- a/packages/dart/lib/src/objects/parse_file_base.dart +++ b/packages/dart/lib/src/objects/parse_file_base.dart @@ -5,8 +5,8 @@ abstract class ParseFileBase extends ParseObject { /// /// {https://docs.parseplatform.org/rest/guide/#files/} ParseFileBase( - {@required String name, - String url, + {@required String/*!*/ name, + String/*?*/ url, bool debug, ParseClient client, bool autoSendSessionId}) @@ -16,14 +16,16 @@ abstract class ParseFileBase extends ParseObject { client: client) { _path = '/files/$name'; this.name = name; - this.url = url; + if(url != null) + this.url = url; + } String get name => super.get(keyVarName); - set name(String name) => set(keyVarName, name); + set name(String/*!*/ name) => set(keyVarName, name); - String get url => super.get(keyVarURL); - set url(String url) => set(keyVarURL, url); + String/*?*/ get url => super.get(keyVarURL); + set url(String/*!*/ url) => set(keyVarURL, url); bool get saved => url != null; From 0cd124a92dc16d4e455092a5ad5e5ada42f65bc7 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 17:10:53 +0100 Subject: [PATCH 088/195] dart(file): name is required and not null --- packages/dart/lib/src/objects/parse_file.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_file.dart b/packages/dart/lib/src/objects/parse_file.dart index 75d700def..ba910a2bf 100644 --- a/packages/dart/lib/src/objects/parse_file.dart +++ b/packages/dart/lib/src/objects/parse_file.dart @@ -21,11 +21,6 @@ class ParseFile extends ParseFileBase { File file; Future loadStorage() async { - if (name == null) { - file = null; - return this; - } - final File possibleFile = File('${ParseCoreData().fileDirectory}/$name'); // ignore: avoid_slow_async_io final bool exists = await possibleFile.exists(); From d65aac8931138ea607d0379a5309354a1fcb219a Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 17:13:32 +0100 Subject: [PATCH 089/195] dart(file): Migrate/Anotate file classes --- packages/dart/lib/src/objects/parse_file.dart | 2 +- packages/dart/lib/src/objects/parse_file_web.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_file.dart b/packages/dart/lib/src/objects/parse_file.dart index ba910a2bf..6f30348eb 100644 --- a/packages/dart/lib/src/objects/parse_file.dart +++ b/packages/dart/lib/src/objects/parse_file.dart @@ -57,7 +57,7 @@ class ParseFile extends ParseFileBase { if (saved) { //Creates a Fake Response to return the correct result final Map response = { - 'url': url, + 'url': url/*!*/, 'name': name }; return handleResponse( diff --git a/packages/dart/lib/src/objects/parse_file_web.dart b/packages/dart/lib/src/objects/parse_file_web.dart index a18c8bef7..3d227d401 100644 --- a/packages/dart/lib/src/objects/parse_file_web.dart +++ b/packages/dart/lib/src/objects/parse_file_web.dart @@ -37,7 +37,7 @@ class ParseWebFile extends ParseFileBase { if (saved) { //Creates a Fake Response to return the correct result final Map response = { - 'url': url, + 'url': url/*!*/, 'name': name }; return handleResponse( @@ -57,7 +57,7 @@ class ParseWebFile extends ParseFileBase { final ParseNetworkResponse response = await _client.postBytes( uri, options: ParseNetworkOptions(headers: headers), - data: Stream>.fromIterable(>[file]), + data: Stream>.fromIterable(/*!*/>[file]), onSendProgress: progressCallback, ); if (response.statusCode == 201) { From 3e37da1122b547edb481a561ef9e9ac8ae583d0a Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 20:10:23 +0100 Subject: [PATCH 090/195] dart(installation): Simplify --- packages/dart/lib/src/objects/parse_installation.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index eee64672a..9b818919f 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -60,9 +60,7 @@ class ParseInstallation extends ParseObject { /// Gets the current installation from storage static Future currentInstallation() async { - ParseInstallation installation = await _getFromLocalStore(); - installation ??= await _createInstallation(); - return installation; + return (await _getFromLocalStore()) ?? (await _createInstallation()); } /// Updates the installation with current device data From 836d6e3ec72af06862207920e6aa2be917cc7e79 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 20:34:56 +0100 Subject: [PATCH 091/195] dart(inst): Make getSubscribedChannels safer Based on @RodrigoSMarques --- packages/dart/lib/src/objects/parse_installation.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index 9b818919f..4354a1e15 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -235,10 +235,10 @@ class ParseInstallation extends ParseObject { if (apiResponse.success) { final ParseObject installation = apiResponse.result; - return Future>.value( - installation.get>('channels')); + return Future>.value(installation + .get>('channels', defaultValue: [])); } else { - return null; + return []; } } } From d6d810f8782df51754136b0bc6d57ce6e61f3030 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 20:36:02 +0100 Subject: [PATCH 092/195] dart(logger): Handle appName=null --- packages/dart/lib/src/utils/parse_logger.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_logger.dart b/packages/dart/lib/src/utils/parse_logger.dart index cfc05929e..976492463 100644 --- a/packages/dart/lib/src/utils/parse_logger.dart +++ b/packages/dart/lib/src/utils/parse_logger.dart @@ -34,10 +34,7 @@ void logAPIResponse( void logRequest( String appName, String className, String type, String uri, String body) { String requestString = ' \n'; - String name = appName; - if (name.isNotEmpty) { - name = '$appName '; - } + final String name = appName != null ? '$appName ' : ''; requestString += '----\n${name}API Request ($className : $type) :'; requestString += '\nUri: $uri'; requestString += '\nBody: $body'; From d6669dc2a966244b6b82bdfc04290471c9db06f4 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 20:36:38 +0100 Subject: [PATCH 093/195] dart(inst): Annotate --- packages/dart/lib/src/objects/parse_installation.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index 4354a1e15..aaf68d5db 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -27,14 +27,15 @@ class ParseInstallation extends ParseObject { static String _currentInstallationId; //Getters/setters - Map get acl => super.get>(keyVarAcl); + Map /*!*/ get acl => super + .get>(keyVarAcl, defaultValue: {}); set acl(Map acl) => set>(keyVarAcl, acl); - String get deviceToken => super.get(keyDeviceToken); + String/*?*/ get deviceToken => super.get(keyDeviceToken); - set deviceToken(String deviceToken) => + set deviceToken(String/*!*/ deviceToken) => set(keyDeviceToken, deviceToken); String get deviceType => super.get(keyDeviceType); @@ -53,7 +54,7 @@ class ParseInstallation extends ParseObject { String get parseVersion => super.get(keyParseVersion); static Future isCurrent(ParseInstallation installation) async { - _currentInstallationId ??= (await _getFromLocalStore()).installationId; + _currentInstallationId ??= (await _getFromLocalStore())?.installationId; return _currentInstallationId != null && installation.installationId == _currentInstallationId; } From 287404625537f019e54230e2d71a87de724d2067 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 20:46:34 +0100 Subject: [PATCH 094/195] Redundant call --- packages/dart/lib/src/objects/parse_user.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 24c84ffe7..d2694fead 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -335,7 +335,6 @@ class ParseUser extends ParseObject implements ParseCloneable { void forgetLocalSession() { ParseCoreData().sessionId = null; - ParseCoreData().setSessionId(null); } /// Delete the local user data. From 464d20256d2ed8d84c17ff320bbe77cef877e904 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 21:14:41 +0100 Subject: [PATCH 095/195] dart(user): Anntotate --- packages/dart/lib/src/objects/parse_user.dart | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index d2694fead..271098472 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -56,7 +56,8 @@ class ParseUser extends ParseObject implements ParseCloneable { } } - Map get acl => super.get>(keyVarAcl); + Map/*!*/ get acl => super + .get>(keyVarAcl, defaultValue: {}); set acl(Map acl) => set>(keyVarAcl, acl); @@ -122,7 +123,7 @@ class ParseUser extends ParseObject implements ParseCloneable { return null; } - final Map headers = {}; + final Map headers = {}; if (sessionToken != null) { headers[keyHeaderSessionToken] = sessionToken; } @@ -212,7 +213,7 @@ class ParseUser extends ParseObject implements ParseCloneable { forgetLocalSession(); try { - final Map queryParams = { + final Map queryParams = { keyVarUsername: username, keyVarPassword: password }; @@ -340,7 +341,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Delete the local user data. Future deleteLocalUserData() async { await unpin(key: keyParseStoreUser); - _setObjectData(null); + _setObjectData({}); } /// Sends a verification email to the users email address @@ -451,7 +452,7 @@ class ParseUser extends ParseObject implements ParseCloneable { final String userJson = await coreStore.getString(keyParseStoreUser); if (userJson != null) { - final Map userMap = json.decode(userJson); + final Map/*!*/ userMap = json.decode(userJson); if (cloneable != null) { return cloneable.clone(userMap); } else { @@ -488,7 +489,7 @@ class ParseUser extends ParseObject implements ParseCloneable { return parseResponse; } else { final ParseUser user = parseResponse.result; - await user?._onResponseSuccess(); + await user._onResponseSuccess(); return parseResponse; } } @@ -499,6 +500,6 @@ class ParseUser extends ParseObject implements ParseCloneable { static Future _getInstallationId() async { final ParseInstallation parseInstallation = await ParseInstallation.currentInstallation(); - return parseInstallation?.installationId; + return parseInstallation.installationId; } } From 34268a56699b121011d42a32f4136946111ca3fd Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 22:23:54 +0100 Subject: [PATCH 096/195] dart(liveQueryList): Migrate --- .../dart/lib/src/utils/parse_live_list.dart | 85 ++++++++++--------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 0265cb5f8..696e203e8 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -3,7 +3,7 @@ part of flutter_parse_sdk; // ignore_for_file: invalid_use_of_protected_member class ParseLiveList { ParseLiveList._(this._query, this._listeningIncludes, this._lazyLoading, - {List preloadedColumns = const []}) + {List/*!*/ preloadedColumns = const []}) : _preloadedColumns = preloadedColumns { _debug = isDebugEnabled(); } @@ -13,13 +13,13 @@ class ParseLiveList { bool listenOnAllSubItems, List listeningIncludes, bool lazyLoading = true, - List preloadedColumns, + List preloadedColumns = const [], }) { final ParseLiveList parseLiveList = ParseLiveList._( _query, listenOnAllSubItems == true ? _toIncludeMap( - _query.limiters['include']?.toString()?.split(',') ?? []) + _query.limiters['include']?.toString().split(',') ?? []) : _toIncludeMap(listeningIncludes ?? []), lazyLoading, preloadedColumns: preloadedColumns, @@ -36,8 +36,8 @@ class ParseLiveList { final bool _lazyLoading; final List _preloadedColumns; - List> _list = >[]; - StreamController> _eventStreamController; + List> _list = >[]; + StreamController> _eventStreamController; int _nextID = 0; bool _debug; @@ -102,7 +102,7 @@ class ParseLiveList { } List get includes => - _query.limiters['include']?.toString()?.split(',') ?? []; + _query.limiters['include']?.toString().split(',') ?? []; Map get _includePaths { return _toIncludeMap(includes); @@ -113,7 +113,7 @@ class ParseLiveList { for (String includeString in includes) { final List pathParts = includeString.split('.'); - Map root = includesMap; + Map/*!*/ root = includesMap; for (String pathPart in pathParts) { root.putIfAbsent(pathPart, () => {}); root = root[pathPart]; @@ -133,7 +133,7 @@ class ParseLiveList { if (_debug) print('ParseLiveList: lazyLoading is ${_lazyLoading ? 'on' : 'off'}'); if (_lazyLoading) { - final List keys = _preloadedColumns?.toList() ?? []; + final List keys = _preloadedColumns; if (_lazyLoading && query.limiters.containsKey('order')) keys.addAll( query.limiters['order'].toString().split(',').map((String string) { @@ -158,7 +158,7 @@ class ParseLiveList { ParseLiveListElement(element, updatedSubItems: _listeningIncludes, loaded: !_lazyLoading)) - ?.toList() ?? + .toList() ?? >[]; } @@ -202,12 +202,12 @@ class ParseLiveList { List> tasks = >[]; final ParseResponse parseResponse = await _runQuery(); if (parseResponse.success) { - final List newList = parseResponse.results ?? []; + final List newList = parseResponse.results ?? []; //update List for (int i = 0; i < _list.length; i++) { final ParseObject currentObject = _list[i].object; - final String currentObjectId = + final String/*!*/ currentObjectId = currentObject.get(keyVarObjectId); bool stillInList = false; @@ -347,7 +347,7 @@ class ParseLiveList { {bool loaded = true, bool fetchedIncludes = false}) async { //This line seems unnecessary, but without this, weird things happen. //(Hide first element, hide second, view first, view second => second is displayed twice) - object = object?.clone(object?.toJson(full: true)); + object = object.clone(object.toJson(full: true)); if (!fetchedIncludes) { await _loadIncludes(object, paths: _includePaths); @@ -359,29 +359,29 @@ class ParseLiveList { ParseLiveListElement(object, loaded: loaded, updatedSubItems: _listeningIncludes)); _eventStreamController.sink.add(ParseLiveListAddEvent( - i, object?.clone(object?.toJson(full: true)))); + i, object.clone(object.toJson(full: true)))); return; } } _list.add(ParseLiveListElement(object, loaded: loaded, updatedSubItems: _listeningIncludes)); _eventStreamController.sink.add(ParseLiveListAddEvent( - _list.length - 1, object?.clone(object?.toJson(full: true)))); + _list.length - 1, object.clone(object.toJson(full: true)))); } - Future _objectUpdated(T object) async { + Future _objectUpdated(T/*!*/ object) async { for (int i = 0; i < _list.length; i++) { if (_list[i].object.get(keyVarObjectId) == object.get(keyVarObjectId)) { await _loadIncludes(object, oldObject: _list[i].object, paths: _includePaths); if (after(_list[i].object, object) == null) { - _list[i].object = object?.clone(object?.toJson(full: true)); + _list[i].object = object.clone(object.toJson(full: true)); } else { _list.removeAt(i).dispose(); _eventStreamController.sink.add(ParseLiveListDeleteEvent( - i, object?.clone(object?.toJson(full: true)))); - await _objectAdded(object?.clone(object?.toJson(full: true)), + i, object.clone(object.toJson(full: true)))); + await _objectAdded(object.clone(object.toJson(full: true)), fetchedIncludes: true); } break; @@ -397,7 +397,7 @@ class ParseLiveList { oldObject: _list[i].object, paths: _includePaths); _list.removeAt(i).dispose(); _eventStreamController.sink.add(ParseLiveListDeleteEvent( - i, object?.clone(object?.toJson(full: true)))); + i, object.clone(object.toJson(full: true)))); break; } } @@ -431,7 +431,7 @@ class ParseLiveList { } } - String idOf(int index) { + String/*!*/ idOf(int index) { if (index < _list.length) { return _list[index].object.get(keyVarObjectId); } @@ -477,15 +477,18 @@ class ParseLiveList { } class ParseLiveElement extends ParseLiveListElement { - ParseLiveElement(T object, {bool loaded = false, List includeObject}) + ParseLiveElement(T object, + {bool loaded = false, List/*?*/ includeObject}) : super(object, - loaded: loaded, - updatedSubItems: - ParseLiveList._toIncludeMap(includeObject ?? [])) { + loaded: loaded, + updatedSubItems: + ParseLiveList._toIncludeMap(includeObject ?? [])) { _includes = ParseLiveList._toIncludeMap(includeObject ?? []); - queryBuilder = QueryBuilder(object.clone(null)) - ..includeObject(includeObject) + queryBuilder = QueryBuilder(object.clone({})) ..whereEqualTo(keyVarObjectId, object.objectId); + if (includeObject != null) { + queryBuilder.includeObject(includeObject); + } _init(object, loaded: loaded, includeObject: includeObject); } @@ -504,7 +507,7 @@ class ParseLiveElement extends ParseLiveListElement { _subscription = await LiveQuery().client.subscribe( QueryBuilder.copy(queryBuilder), - copyObject: object.clone(null)); + copyObject: object.clone({})); _subscription.on(LiveQueryEvent.update, (T newObject) async { await ParseLiveList._loadIncludes(newObject, @@ -540,7 +543,7 @@ class ParseLiveElement extends ParseLiveListElement { } } -class ParseLiveListElement { +class ParseLiveListElement { ParseLiveListElement(this._object, {bool loaded = false, Map updatedSubItems}) { if (_object != null) { @@ -554,16 +557,15 @@ class ParseLiveListElement { } } - final StreamController _streamController = StreamController.broadcast(); + final StreamController _streamController = StreamController.broadcast(); T _object; bool _loaded = false; Map _updatedSubItems; LiveQuery _liveQuery; final Future _subscriptionQueue = Future.value(); - Stream get stream => _streamController?.stream; + Stream get stream => _streamController.stream; - // ignore: invalid_use_of_protected_member T get object => _object?.clone(_object?.toJson(full: true)); Map _toSubscriptionMap(Map map) { @@ -605,9 +607,9 @@ class ParseLiveListElement { } } - Future _subscribeSubItem(ParseObject parentObject, PathKey currentKey, - ParseObject subObject, Map path) async { - if (_liveQuery != null && subObject != null) { + Future _subscribeSubItem(ParseObject/*!*/ parentObject, PathKey currentKey, + ParseObject/*!*/ subObject, Map/*!*/ path) async { + if (_liveQuery != null) { final List> tasks = >[]; for (PathKey key in path.keys) { tasks.add(_subscribeSubItem( @@ -629,7 +631,7 @@ class ParseLiveListElement { parentObject[currentKey.key] = newObject; if (!_streamController.isClosed) { _streamController - ?.add(_object?.clone(_object?.toJson(full: true))); + .add(_object?.clone(_object?.toJson(full: true))); //Resubscribe subitems // TODO(any): only resubscribe on changed pointers _unsubscribe(path); @@ -651,8 +653,7 @@ class ParseLiveListElement { _object = value; _unsubscribe(_updatedSubItems); _subscribe(); - // ignore: invalid_use_of_protected_member - _streamController?.add(_object?.clone(_object?.toJson(full: true))); + _streamController.add(_object?.clone(_object?.toJson(full: true))); } bool get loaded => _loaded; @@ -666,7 +667,7 @@ class ParseLiveListElement { if (loaded) { _subscriptionQueue.whenComplete(() async { await _updateSubItems(_object, _updatedSubItems); -// _streamController?.add(_object?.clone(_object?.toJson(full: true))); +// _streamController.add(_object?.clone(_object?.toJson(full: true))); }); } } @@ -682,11 +683,11 @@ class ParseLiveListElement { } Future _updateSubItems( - ParseObject root, Map path) async { + ParseObject/*!*/ root, Map path) async { final List> tasks = >[]; for (PathKey key in path.keys) { - ParseObject subObject = root.get(key.key); - if (subObject?.containsKey(keyVarUpdatedAt) == true) { + ParseObject/*!*/ subObject = root.get(key.key); + if (subObject.containsKey(keyVarUpdatedAt) == true) { final QueryBuilder queryBuilder = QueryBuilder(subObject) ..keysToReturn([keyVarUpdatedAt]) @@ -700,7 +701,7 @@ class ParseLiveListElement { if (parseResponse.success) { subObject = parseResponse.result.first; // root.getObjectData()[key.key] = subObject; - if (key.subscription?.eventCallbacks?.containsKey('update') == + if (key.subscription?.eventCallbacks.containsKey('update') == true) { key.subscription.eventCallbacks['update'](subObject); } From 9ea3727aaa47975ab3cf4331fd53442e5401c668 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 22:28:38 +0100 Subject: [PATCH 097/195] dart: Upgrade dependencies --- packages/dart/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 89215f18f..869dfe728 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: # Networking - dio: ^4.0.0-beta7 + dio: ^4.0.0-prev2 http: ^0.13.0 web_socket_channel: ^2.0.0 @@ -26,5 +26,5 @@ dependencies: dev_dependencies: # Testing - mockito: ^5.0.1 + mockito: ^5.0.2 test: ^1.16.8 From 7914319a30b535626a36c5370514fcd0c3de8868 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Thu, 18 Mar 2021 22:34:11 +0100 Subject: [PATCH 098/195] dart: Remove unnecessary operators --- packages/dart/lib/src/network/parse_dio_client.dart | 2 +- packages/dart/lib/src/network/parse_query.dart | 8 ++------ packages/dart/lib/src/objects/parse_relation.dart | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 05ee9d5ee..7b5f99385 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -192,7 +192,7 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { bool compressed = false; options.headers.forEach((String name, dynamic value) { if (name.toLowerCase() == 'accept-encoding' && - value?.toString()?.toLowerCase() == 'gzip') { + value?.toString().toLowerCase() == 'gzip') { compressed = true; } curlCmd += ' -H \'$name: $value\''; diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index dfa6ddbc5..738c35e70 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -496,11 +496,7 @@ class QueryBuilder { String getLimiters(Map map) { String result = ''; map.forEach((String key, dynamic value) { - if (result != null) { - result = result + '&$key=$value'; - } else { - result = '&$key=$value'; - } + result = result + '&$key=$value'; }); return result; } @@ -509,7 +505,7 @@ class QueryBuilder { String getLimitersRelational(Map map) { String result = ''; map.forEach((String key, dynamic value) { - if (result != null) { + if (result.isNotEmpty) { result = result + ',\"$key":$value'; } else { result = '\"$key\":$value'; diff --git a/packages/dart/lib/src/objects/parse_relation.dart b/packages/dart/lib/src/objects/parse_relation.dart index 334f1f0f4..2632be791 100644 --- a/packages/dart/lib/src/objects/parse_relation.dart +++ b/packages/dart/lib/src/objects/parse_relation.dart @@ -30,7 +30,7 @@ class ParseRelation { Map toJson() => { '__type': keyRelation, - 'className': _objects?.first?.parseClassName, + 'className': _objects?.first.parseClassName, 'objects': parseEncode(_objects?.toList()) }; From 3aeda9c6bd065bd2e6f7ac98f3b9b04df3be6829 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 01:04:36 +0100 Subject: [PATCH 099/195] dart(user): throw error when email is null Instead of returning null. This actually returns a valid ParseResponse with an error provided, therefore the return is not nullable --- packages/dart/lib/src/objects/parse_user.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 271098472..8009e039f 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -174,7 +174,7 @@ class ParseUser extends ParseObject implements ParseCloneable { '`ParseUser().signUp()` failed, because the email is not set. If you want to allow signUp without a set email, you should run `ParseUser().signUp(allowWithoutEmail = true)`'); return true; }()); - return null; + throw '`signUp` failed, because `emailAddress` of ParseUser was not provided and `allowWithoutEmail` was `false`'; } else { assert(() { print( From d47a6ea0ee8d22ca55a68b83fa1497144b78a52f Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 01:26:25 +0100 Subject: [PATCH 100/195] dart: Annotate getBytes path as nonnullable --- packages/dart/lib/src/network/parse_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_client.dart b/packages/dart/lib/src/network/parse_client.dart index 8afa3cd19..6764df140 100644 --- a/packages/dart/lib/src/network/parse_client.dart +++ b/packages/dart/lib/src/network/parse_client.dart @@ -35,7 +35,7 @@ abstract class ParseClient { }); Future getBytes( - String path, { + String/*!*/ path, { ParseNetworkOptions options, ProgressCallback onReceiveProgress, }); From 80ee77d17db6007ea35c6f9da4a9b50042ac59c3 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 01:26:59 +0100 Subject: [PATCH 101/195] dart(core): Annotate late init of vars --- packages/dart/lib/src/data/parse_core_data.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 9903dae37..e7351afc2 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -76,12 +76,12 @@ class ParseCoreData { String masterKey; String clientKey; String sessionId; - bool /*!*/ autoSendSessionId; + /*late*/bool /*!*/ autoSendSessionId; SecurityContext securityContext; - bool /*!*/ debug; - CoreStore/*!*/ storage; + /*late*/bool /*!*/ debug; + /*late*/CoreStore/*!*/ storage; ParseSubClassHandler _subClassHandler; - List /*!*/ liveListRetryIntervals; + /*late*/List /*!*/ liveListRetryIntervals; ParseConnectivityProvider connectivityProvider; String fileDirectory; Stream appResumedStream; From 715c708f25970a0ff1944f78c2400fa27cf1b8c7 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 01:57:23 +0100 Subject: [PATCH 102/195] dart(base): Set parseClassName=ParseBase --- packages/dart/lib/src/objects/parse_base.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 34975af2a..05dd30748 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; abstract class ParseBase { - String/*!*/ parseClassName; + String/*!*/ parseClassName = 'ParseBase'; final bool _dirty = false; // reserved property final Map _unsavedChanges = Map(); final Map _savingChanges = Map(); From c4ff700d7966b4634dc6c4b66bc3f2dcd9de5202 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 01:57:44 +0100 Subject: [PATCH 103/195] dart(coreData): Make sure clientCreator is optional --- packages/dart/lib/src/data/parse_core_data.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index e7351afc2..3e8f4c01a 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -63,7 +63,10 @@ class ParseCoreData { _instance.connectivityProvider = connectivityProvider; _instance.fileDirectory = fileDirectory; _instance.appResumedStream = appResumedStream; - _instance.clientCreator = clientCreator; + _instance.clientCreator = clientCreator ?? + ({bool sendSessionId, SecurityContext securityContext}) => + ParseHTTPClient( + sendSessionId: sendSessionId, securityContext: securityContext); } String applicationId; @@ -85,10 +88,7 @@ class ParseCoreData { ParseConnectivityProvider connectivityProvider; String fileDirectory; Stream appResumedStream; - ParseClientCreator /*!*/ clientCreator = ( - {bool sendSessionId, SecurityContext securityContext}) => - ParseHTTPClient( - sendSessionId: sendSessionId, securityContext: securityContext); + ParseClientCreator clientCreator; void registerSubClass( String className, ParseObjectConstructor objectConstructor) { From 69946e734a1e21d5b17f09ef98eae19906234e68 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:00:06 +0100 Subject: [PATCH 104/195] dart(liveQuery): Remove unneded true --- packages/dart/lib/src/network/parse_live_query.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 6d8a56693..b8fa717e4 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -133,7 +133,7 @@ class LiveQueryClient { _debug = isDebugEnabled(objectLevelDebug: debug); _sendSessionId = - autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true; + autoSendSessionId ?? ParseCoreData().autoSendSessionId; _liveQueryURL = ParseCoreData().liveQueryURL; assert(_liveQueryURL != null, 'liveQueryUrl is not set. For how to setup Live Queries, see https://github.com/parse-community/Parse-SDK-Flutter/tree/master/packages/flutter#live-queries.'); From 0c4fc357679666912e3ee78eb70b10d3f7566132 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:00:30 +0100 Subject: [PATCH 105/195] dart(LiveQuery): add missing late inits --- packages/dart/lib/src/network/parse_live_query.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index b8fa717e4..b6d299e49 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -160,13 +160,13 @@ class LiveQueryClient { } parse_web_socket.WebSocket _webSocket; - bool/*!*/ _debug; + /*late*/bool/*!*/ _debug; bool _sendSessionId; WebSocketChannel _channel; String _liveQueryURL; bool _connecting = false; StreamController _clientEventStreamController; - Stream/*!*/ _clientEventStream; + /*late*/Stream/*!*/ _clientEventStream; LiveQueryReconnectingController/*!*/ reconnectingController; final Map _requestSubscription = {}; From 0c79302cc212e488c8ac8bc5c2f516ecf9ac3bea Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:01:52 +0100 Subject: [PATCH 106/195] dart(object): Add missing late inits --- packages/dart/lib/src/objects/parse_object.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index 4806140a1..f9a29a55d 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -27,10 +27,10 @@ class ParseObject extends ParseBase implements ParseCloneable { dynamic clone(Map map) => ParseObject.clone(parseClassName)..fromJson(map); - String/*!*/ _path; - String/*!*/ _aggregatepath; + /*late*/String/*!*/ _path; + /*late*/String/*!*/ _aggregatepath; bool _debug; - ParseClient/*!*/ _client; + /*late*/ParseClient/*!*/ _client; /// Gets an object from the server using it's [String] objectId Future getObject(String/*!*/ objectId) async { From 5c84a6676946fa0c95d7f1284dfa45072e00de6e Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:07:27 +0100 Subject: [PATCH 107/195] dart: Fix getter setter need same type --- packages/dart/lib/src/objects/parse_file_base.dart | 4 ++-- packages/dart/lib/src/objects/parse_installation.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_file_base.dart b/packages/dart/lib/src/objects/parse_file_base.dart index f483cf9a5..10d6bba73 100644 --- a/packages/dart/lib/src/objects/parse_file_base.dart +++ b/packages/dart/lib/src/objects/parse_file_base.dart @@ -24,8 +24,8 @@ abstract class ParseFileBase extends ParseObject { String get name => super.get(keyVarName); set name(String/*!*/ name) => set(keyVarName, name); - String/*?*/ get url => super.get(keyVarURL); - set url(String/*!*/ url) => set(keyVarURL, url); + String get url => super.get(keyVarURL); + set url(String url) => set(keyVarURL, url); bool get saved => url != null; diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index aaf68d5db..e934e85f6 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -33,9 +33,9 @@ class ParseInstallation extends ParseObject { set acl(Map acl) => set>(keyVarAcl, acl); - String/*?*/ get deviceToken => super.get(keyDeviceToken); + String get deviceToken => super.get(keyDeviceToken); - set deviceToken(String/*!*/ deviceToken) => + set deviceToken(String deviceToken) => set(keyDeviceToken, deviceToken); String get deviceType => super.get(keyDeviceType); From 3960a7da636012d7fc26ac2e98c1f77955e4667e Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:07:43 +0100 Subject: [PATCH 108/195] dart(user): SessionId needs to be present on logout --- packages/dart/lib/src/objects/parse_user.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 8009e039f..4884fddc4 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -311,7 +311,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// server. Will also delete the local user data unless /// deleteLocalUserData is false. Future logout({bool deleteLocalUserData = true}) async { - final String sessionId = ParseCoreData().sessionId; + final String/*!*/ sessionId = ParseCoreData().sessionId; forgetLocalSession(); From 7731b6cb448767533b36ca166be56ed9e03860e7 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:12:22 +0100 Subject: [PATCH 109/195] dart: Upgrade http 0.13.1 --- packages/dart/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 869dfe728..e838fec44 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: # Networking dio: ^4.0.0-prev2 - http: ^0.13.0 + http: ^0.13.1 web_socket_channel: ^2.0.0 #Database From 4a54d15601deae6a7e1fe5cd3307e925a499ef33 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:21:12 +0100 Subject: [PATCH 110/195] dart: Fix null-safety access --- packages/dart/lib/src/data/parse_core_data.dart | 7 ++++--- packages/dart/lib/src/network/parse_dio_client.dart | 12 ++++++------ packages/dart/lib/src/utils/parse_live_list.dart | 10 +++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 3e8f4c01a..73bd10f79 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -52,9 +52,10 @@ class ParseCoreData { _instance.sessionId = sessionId; _instance.autoSendSessionId = autoSendSessionId; _instance.securityContext = securityContext; - _instance.liveListRetryIntervals = liveListRetryIntervals ?? parseIsWeb - ? [0, 500, 1000, 2000, 5000] - : [0, 500, 1000, 2000, 5000, 10000]; + _instance.liveListRetryIntervals = liveListRetryIntervals ?? + (parseIsWeb + ? [0, 500, 1000, 2000, 5000] + : [0, 500, 1000, 2000, 5000, 10000]); _instance._subClassHandler = ParseSubClassHandler( registeredSubClassMap: registeredSubClassMap, parseUserConstructor: parseUserConstructor, diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 7b5f99385..7b7053515 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -31,7 +31,7 @@ class ParseDioClient extends ParseClient { data: dioResponse.data, statusCode: dioResponse.statusCode); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response?.statusCode); + data: error.response?.data, statusCode: error.response.statusCode); } } @@ -51,7 +51,7 @@ class ParseDioClient extends ParseClient { bytes: dioResponse.data, statusCode: dioResponse.statusCode); } on dio.DioError catch (error) { return ParseNetworkByteResponse( - data: error.response?.data, statusCode: error.response?.statusCode); + data: error.response?.data, statusCode: error.response.statusCode); } } @@ -68,7 +68,7 @@ class ParseDioClient extends ParseClient { data: dioResponse.data, statusCode: dioResponse.statusCode); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response?.statusCode); + data: error.response?.data, statusCode: error.response.statusCode); } } @@ -85,7 +85,7 @@ class ParseDioClient extends ParseClient { data: dioResponse.data, statusCode: dioResponse.statusCode); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response?.statusCode); + data: error.response?.data, statusCode: error.response.statusCode); } } @@ -105,7 +105,7 @@ class ParseDioClient extends ParseClient { data: dioResponse.data, statusCode: dioResponse.statusCode); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response?.statusCode); + data: error.response?.data, statusCode: error.response.statusCode); } } @@ -121,7 +121,7 @@ class ParseDioClient extends ParseClient { data: dioResponse.data, statusCode: dioResponse.statusCode); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response?.statusCode); + data: error.response?.data, statusCode: error.response.statusCode); } } } diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 696e203e8..556f405de 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -441,7 +441,7 @@ class ParseLiveList { String getIdentifier(int index) { if (index < _list.length) { return _list[index].object.get(keyVarObjectId) + - _list[index].object.get(keyVarUpdatedAt)?.toString() ?? + _list[index].object.get(keyVarUpdatedAt).toString() ?? ''; } return 'NotFound'; @@ -566,7 +566,7 @@ class ParseLiveListElement { Stream get stream => _streamController.stream; - T get object => _object?.clone(_object?.toJson(full: true)); + T get object => _object?.clone(_object.toJson(full: true)); Map _toSubscriptionMap(Map map) { final Map result = Map(); @@ -631,7 +631,7 @@ class ParseLiveListElement { parentObject[currentKey.key] = newObject; if (!_streamController.isClosed) { _streamController - .add(_object?.clone(_object?.toJson(full: true))); + .add(_object?.clone(_object.toJson(full: true))); //Resubscribe subitems // TODO(any): only resubscribe on changed pointers _unsubscribe(path); @@ -653,7 +653,7 @@ class ParseLiveListElement { _object = value; _unsubscribe(_updatedSubItems); _subscribe(); - _streamController.add(_object?.clone(_object?.toJson(full: true))); + _streamController.add(_object?.clone(_object.toJson(full: true))); } bool get loaded => _loaded; @@ -667,7 +667,7 @@ class ParseLiveListElement { if (loaded) { _subscriptionQueue.whenComplete(() async { await _updateSubItems(_object, _updatedSubItems); -// _streamController.add(_object?.clone(_object?.toJson(full: true))); +// _streamController.add(_object?.clone(_object.toJson(full: true))); }); } } From def8edd2914fba3b6fd346fc4b7f2799229f0972 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:27:52 +0100 Subject: [PATCH 111/195] dart: Apply null-safety migration --- packages/dart/lib/parse_server_sdk.dart | 40 ++--- .../dart/lib/src/data/parse_core_data.dart | 94 +++++------ .../lib/src/data/parse_subclass_handler.dart | 30 ++-- .../dart/lib/src/network/dio_adapter_io.dart | 2 +- packages/dart/lib/src/network/options.dart | 2 +- .../dart/lib/src/network/parse_client.dart | 36 ++-- .../lib/src/network/parse_dio_client.dart | 110 ++++++------ .../lib/src/network/parse_http_client.dart | 42 ++--- .../lib/src/network/parse_live_query.dart | 110 ++++++------ .../dart/lib/src/network/parse_query.dart | 20 +-- packages/dart/lib/src/objects/parse_acl.dart | 26 +-- packages/dart/lib/src/objects/parse_base.dart | 48 +++--- .../dart/lib/src/objects/parse_cloneable.dart | 2 +- .../dart/lib/src/objects/parse_config.dart | 6 +- .../dart/lib/src/objects/parse_error.dart | 6 +- packages/dart/lib/src/objects/parse_file.dart | 30 ++-- .../dart/lib/src/objects/parse_file_base.dart | 24 +-- .../dart/lib/src/objects/parse_file_web.dart | 24 +-- .../dart/lib/src/objects/parse_function.dart | 12 +- .../lib/src/objects/parse_installation.dart | 52 +++--- .../dart/lib/src/objects/parse_merge.dart | 14 +- .../dart/lib/src/objects/parse_object.dart | 26 +-- .../dart/lib/src/objects/parse_relation.dart | 22 +-- .../dart/lib/src/objects/parse_response.dart | 8 +- .../dart/lib/src/objects/parse_session.dart | 18 +- packages/dart/lib/src/objects/parse_user.dart | 96 +++++------ .../response/parse_response_builder.dart | 30 ++-- .../response/parse_response_utils.dart | 2 +- packages/dart/lib/src/storage/core_store.dart | 14 +- .../lib/src/storage/core_store_memory.dart | 10 +- .../lib/src/storage/core_store_sem_impl.dart | 32 ++-- .../dart/lib/src/storage/xxtea_codec.dart | 12 +- .../dart/lib/src/utils/parse_date_format.dart | 2 +- .../dart/lib/src/utils/parse_decoder.dart | 2 +- .../dart/lib/src/utils/parse_encoder.dart | 2 +- .../dart/lib/src/utils/parse_live_list.dart | 158 +++++++++--------- packages/dart/lib/src/utils/parse_logger.dart | 10 +- packages/dart/lib/src/utils/parse_utils.dart | 10 +- packages/dart/pubspec.yaml | 2 +- packages/dart/test/parse_query_test.dart | 2 +- 40 files changed, 594 insertions(+), 594 deletions(-) diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index 663793eca..1924f189d 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -84,25 +84,25 @@ class Parse { String appId, String serverUrl, { bool debug = false, - String appName, - String appVersion, - String appPackageName, - String locale, - String liveQueryUrl, - String clientKey, - String masterKey, - String sessionId, + String? appName, + String? appVersion, + String? appPackageName, + String? locale, + String? liveQueryUrl, + String? clientKey, + String? masterKey, + String? sessionId, bool autoSendSessionId = true, - SecurityContext securityContext, - CoreStore coreStore, - Map registeredSubClassMap, - ParseUserConstructor parseUserConstructor, - ParseFileConstructor parseFileConstructor, - List liveListRetryIntervals, - ParseConnectivityProvider connectivityProvider, - String fileDirectory, - Stream appResumedStream, - ParseClientCreator clientCreator, + SecurityContext? securityContext, + CoreStore? coreStore, + Map? registeredSubClassMap, + ParseUserConstructor? parseUserConstructor, + ParseFileConstructor? parseFileConstructor, + List? liveListRetryIntervals, + ParseConnectivityProvider? connectivityProvider, + String? fileDirectory, + Stream? appResumedStream, + ParseClientCreator? clientCreator, }) async { final String url = removeTrailingSlash(serverUrl); @@ -138,8 +138,8 @@ class Parse { bool hasParseBeenInitialized() => _hasBeenInitialized; - Future healthCheck( - {bool debug, ParseClient client, bool sendSessionIdByDefault}) async { + Future healthCheck( + {bool? debug, ParseClient? client, bool? sendSessionIdByDefault}) async { final bool _debug = isDebugEnabled(objectLevelDebug: debug); final ParseClient _client = client ?? diff --git a/packages/dart/lib/src/data/parse_core_data.dart b/packages/dart/lib/src/data/parse_core_data.dart index 73bd10f79..82e3a73c4 100644 --- a/packages/dart/lib/src/data/parse_core_data.dart +++ b/packages/dart/lib/src/data/parse_core_data.dart @@ -6,9 +6,9 @@ class ParseCoreData { ParseCoreData._init(this.applicationId, this.serverUrl); - static ParseCoreData _instance; + static late ParseCoreData _instance; - static ParseCoreData/*!*/ get instance => _instance; + static ParseCoreData get instance => _instance; /// Creates an instance of Parse Server /// @@ -17,26 +17,26 @@ class ParseCoreData { static Future init( String appId, String serverUrl, { - bool /*!*/ debug, - String appName, - String appVersion, - String appPackageName, - String locale, - String liveQueryUrl, - String masterKey, - String clientKey, - String sessionId, - bool /*!*/ autoSendSessionId, - SecurityContext securityContext, - CoreStore store, - Map registeredSubClassMap, - ParseUserConstructor parseUserConstructor, - ParseFileConstructor parseFileConstructor, - List liveListRetryIntervals, - ParseConnectivityProvider connectivityProvider, - String fileDirectory, - Stream appResumedStream, - ParseClientCreator clientCreator, + required bool debug, + String? appName, + String? appVersion, + String? appPackageName, + String? locale, + String? liveQueryUrl, + String? masterKey, + String? clientKey, + String? sessionId, + required bool autoSendSessionId, + SecurityContext? securityContext, + CoreStore? store, + Map? registeredSubClassMap, + ParseUserConstructor? parseUserConstructor, + ParseFileConstructor? parseFileConstructor, + List? liveListRetryIntervals, + ParseConnectivityProvider? connectivityProvider, + String? fileDirectory, + Stream? appResumedStream, + ParseClientCreator? clientCreator, }) async { _instance = ParseCoreData._init(appId, serverUrl); @@ -65,31 +65,31 @@ class ParseCoreData { _instance.fileDirectory = fileDirectory; _instance.appResumedStream = appResumedStream; _instance.clientCreator = clientCreator ?? - ({bool sendSessionId, SecurityContext securityContext}) => + (({required bool sendSessionId, SecurityContext? securityContext}) => ParseHTTPClient( - sendSessionId: sendSessionId, securityContext: securityContext); + sendSessionId: sendSessionId, securityContext: securityContext)); } String applicationId; String serverUrl; - String appName; - String appVersion; - String appPackageName; - String locale; - String liveQueryURL; - String masterKey; - String clientKey; - String sessionId; - /*late*/bool /*!*/ autoSendSessionId; - SecurityContext securityContext; - /*late*/bool /*!*/ debug; - /*late*/CoreStore/*!*/ storage; - ParseSubClassHandler _subClassHandler; - /*late*/List /*!*/ liveListRetryIntervals; - ParseConnectivityProvider connectivityProvider; - String fileDirectory; - Stream appResumedStream; - ParseClientCreator clientCreator; + String? appName; + String? appVersion; + String? appPackageName; + String? locale; + String? liveQueryURL; + String? masterKey; + String? clientKey; + String? sessionId; + late bool autoSendSessionId; + SecurityContext? securityContext; + late bool debug; + late CoreStore storage; + late ParseSubClassHandler _subClassHandler; + late List liveListRetryIntervals; + ParseConnectivityProvider? connectivityProvider; + String? fileDirectory; + Stream? appResumedStream; + late ParseClientCreator clientCreator; void registerSubClass( String className, ParseObjectConstructor objectConstructor) { @@ -104,25 +104,25 @@ class ParseCoreData { _subClassHandler.registerFileSubClass(parseFileConstructor); } - ParseObject createObject(String/*!*/ classname) { + ParseObject createObject(String classname) { return _subClassHandler.createObject(classname); } ParseUser createParseUser( - String username, String password, String emailAddress, - {String sessionToken, bool debug, ParseClient client}) { + String? username, String? password, String? emailAddress, + {String? sessionToken, bool? debug, ParseClient? client}) { return _subClassHandler.createParseUser(username, password, emailAddress, sessionToken: sessionToken, debug: debug, client: client); } - ParseFileBase createFile({String url, String name}) => + ParseFileBase createFile({String? url, String? name}) => _subClassHandler.createFile(name: name, url: url); /// Sets the current sessionId. /// /// This is generated when a users logs in, or calls currentUser to update /// their keys - void setSessionId(String /*!*/ sessionId) { + void setSessionId(String sessionId) { this.sessionId = sessionId; } diff --git a/packages/dart/lib/src/data/parse_subclass_handler.dart b/packages/dart/lib/src/data/parse_subclass_handler.dart index be58429ec..2205abc7c 100644 --- a/packages/dart/lib/src/data/parse_subclass_handler.dart +++ b/packages/dart/lib/src/data/parse_subclass_handler.dart @@ -2,16 +2,16 @@ part of flutter_parse_sdk; typedef ParseObjectConstructor = ParseObject Function(); typedef ParseUserConstructor = ParseUser Function( - String username, String password, String emailAddress, - {String sessionToken, bool debug, ParseClient client}); + String? username, String? password, String? emailAddress, + {String? sessionToken, bool? debug, ParseClient? client}); typedef ParseFileConstructor = ParseFileBase Function( - {String name, String url}); + {String? name, String? url}); class ParseSubClassHandler { ParseSubClassHandler( - {Map registeredSubClassMap, - ParseUserConstructor parseUserConstructor, - ParseFileConstructor parseFileConstructor}) { + {Map? registeredSubClassMap, + ParseUserConstructor? parseUserConstructor, + ParseFileConstructor? parseFileConstructor}) { _subClassMap = registeredSubClassMap ?? Map(); _parseUserConstructor = parseUserConstructor; @@ -19,11 +19,11 @@ class ParseSubClassHandler { _parseFileConstructor = parseFileConstructor; } - Map _subClassMap; - ParseUserConstructor _parseUserConstructor; - ParseFileConstructor _parseFileConstructor = ({String name, String url}) { + late Map _subClassMap; + ParseUserConstructor? _parseUserConstructor; + ParseFileConstructor _parseFileConstructor = ({String? name, String? url}) { if (parseIsWeb) { - return ParseWebFile(null, name: name, url: url); + return ParseWebFile(null, name: name!, url: url); } else { return ParseFile(null, name: name, url: url); } @@ -51,21 +51,21 @@ class ParseSubClassHandler { return createParseUser(null, null, null); } if (_subClassMap.containsKey(classname)) { - return _subClassMap[classname](); + return _subClassMap[classname]!(); } return ParseObject(classname); } ParseUser createParseUser( - String username, String password, String emailAddress, - {String sessionToken, bool debug, ParseClient client}) { + String? username, String? password, String? emailAddress, + {String? sessionToken, bool? debug, ParseClient? client}) { return _parseUserConstructor != null - ? _parseUserConstructor(username, password, emailAddress, + ? _parseUserConstructor!(username, password, emailAddress, sessionToken: sessionToken, debug: debug, client: client) : ParseUser(username, password, emailAddress, sessionToken: sessionToken, debug: debug, client: client); } - ParseFileBase createFile({String name, String url}) => + ParseFileBase createFile({String? name, String? url}) => _parseFileConstructor(name: name, url: url); } diff --git a/packages/dart/lib/src/network/dio_adapter_io.dart b/packages/dart/lib/src/network/dio_adapter_io.dart index c5f87a175..e8e509560 100644 --- a/packages/dart/lib/src/network/dio_adapter_io.dart +++ b/packages/dart/lib/src/network/dio_adapter_io.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:dio/adapter.dart'; import 'package:dio/dio.dart'; -HttpClientAdapter createHttpClientAdapter(SecurityContext securityContext) { +HttpClientAdapter createHttpClientAdapter(SecurityContext? securityContext) { final DefaultHttpClientAdapter defaultHttpClientAdapter = DefaultHttpClientAdapter(); diff --git a/packages/dart/lib/src/network/options.dart b/packages/dart/lib/src/network/options.dart index 6c31e1bb4..7f33a5c6c 100644 --- a/packages/dart/lib/src/network/options.dart +++ b/packages/dart/lib/src/network/options.dart @@ -3,7 +3,7 @@ part of flutter_parse_sdk; class ParseNetworkOptions { ParseNetworkOptions({this.headers}); - final Map headers; + final Map? headers; // final ParseNetworkResponseType responseType; } diff --git a/packages/dart/lib/src/network/parse_client.dart b/packages/dart/lib/src/network/parse_client.dart index 6764df140..9f540bbb3 100644 --- a/packages/dart/lib/src/network/parse_client.dart +++ b/packages/dart/lib/src/network/parse_client.dart @@ -1,43 +1,43 @@ part of flutter_parse_sdk; typedef ParseClientCreator = ParseClient Function( - {bool/*!*/ sendSessionId, SecurityContext securityContext}); + {required bool sendSessionId, SecurityContext? securityContext}); abstract class ParseClient { Future get( String path, { - ParseNetworkOptions options, - ProgressCallback onReceiveProgress, + ParseNetworkOptions? options, + ProgressCallback? onReceiveProgress, }); Future put( String path, { - String data, - ParseNetworkOptions options, + String? data, + ParseNetworkOptions? options, }); Future post( String path, { - String data, - ParseNetworkOptions options, + String? data, + ParseNetworkOptions? options, }); Future postBytes( String path, { - Stream /*!*/ > data, - ParseNetworkOptions options, - ProgressCallback onSendProgress, + Stream >? data, + ParseNetworkOptions? options, + ProgressCallback? onSendProgress, }); Future delete( String path, { - ParseNetworkOptions options, + ParseNetworkOptions? options, }); Future getBytes( - String/*!*/ path, { - ParseNetworkOptions options, - ProgressCallback onReceiveProgress, + String path, { + ParseNetworkOptions? options, + ProgressCallback? onReceiveProgress, }); // Future putBytes( @@ -80,12 +80,12 @@ typedef ProgressCallback = void Function(int count, int total); class ParseNetworkResponse { ParseNetworkResponse({ - this.data, + required this.data, this.statusCode = -1, }); - final String/*!*/ data; - final int/*!*/ statusCode; + final String data; + final int statusCode; } class ParseNetworkByteResponse extends ParseNetworkResponse { @@ -98,5 +98,5 @@ class ParseNetworkByteResponse extends ParseNetworkResponse { statusCode: statusCode, ); - final List bytes; + final List? bytes; } diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index 7b7053515..cefed3c07 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -7,20 +7,20 @@ import 'dio_adapter_io.dart' if (dart.library.js) 'dio_adapter_js.dart'; class ParseDioClient extends ParseClient { ParseDioClient( - {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) { + {bool sendSessionId = false, SecurityContext? securityContext}) { _client = _ParseDioClient( sendSessionId: sendSessionId, securityContext: securityContext, ); } - _ParseDioClient _client; + late _ParseDioClient _client; @override Future get( String path, { - ParseNetworkOptions options, - ProgressCallback onReceiveProgress, + ParseNetworkOptions? options, + ProgressCallback? onReceiveProgress, }) async { try { final dio.Response dioResponse = await _client.get( @@ -28,18 +28,18 @@ class ParseDioClient extends ParseClient { options: _Options(headers: options?.headers), ); return ParseNetworkResponse( - data: dioResponse.data, statusCode: dioResponse.statusCode); + data: dioResponse.data!, statusCode: dioResponse.statusCode!); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response.statusCode); + data: error.response?.data, statusCode: error.response!.statusCode!); } } @override Future getBytes( String path, { - ParseNetworkOptions options, - ProgressCallback onReceiveProgress, + ParseNetworkOptions? options, + ProgressCallback? onReceiveProgress, }) async { try { final dio.Response> dioResponse = await _client.get>( @@ -48,16 +48,16 @@ class ParseDioClient extends ParseClient { headers: options?.headers, responseType: dio.ResponseType.bytes), ); return ParseNetworkByteResponse( - bytes: dioResponse.data, statusCode: dioResponse.statusCode); + bytes: dioResponse.data, statusCode: dioResponse.statusCode!); } on dio.DioError catch (error) { return ParseNetworkByteResponse( - data: error.response?.data, statusCode: error.response.statusCode); + data: error.response?.data, statusCode: error.response!.statusCode!); } } @override Future put(String path, - {String data, ParseNetworkOptions options}) async { + {String? data, ParseNetworkOptions? options}) async { try { final dio.Response dioResponse = await _client.put( path, @@ -65,16 +65,16 @@ class ParseDioClient extends ParseClient { options: _Options(headers: options?.headers), ); return ParseNetworkResponse( - data: dioResponse.data, statusCode: dioResponse.statusCode); + data: dioResponse.data!, statusCode: dioResponse.statusCode!); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response.statusCode); + data: error.response?.data, statusCode: error.response!.statusCode!); } } @override Future post(String path, - {String data, ParseNetworkOptions options}) async { + {String? data, ParseNetworkOptions? options}) async { try { final dio.Response dioResponse = await _client.post( path, @@ -82,18 +82,18 @@ class ParseDioClient extends ParseClient { options: _Options(headers: options?.headers), ); return ParseNetworkResponse( - data: dioResponse.data, statusCode: dioResponse.statusCode); + data: dioResponse.data!, statusCode: dioResponse.statusCode!); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response.statusCode); + data: error.response?.data, statusCode: error.response!.statusCode!); } } @override Future postBytes(String path, - {Stream> data, - ParseNetworkOptions options, - ProgressCallback onSendProgress}) async { + {Stream>? data, + ParseNetworkOptions? options, + ProgressCallback? onSendProgress}) async { try { final dio.Response dioResponse = await _client.post( path, @@ -102,33 +102,33 @@ class ParseDioClient extends ParseClient { onSendProgress: onSendProgress, ); return ParseNetworkResponse( - data: dioResponse.data, statusCode: dioResponse.statusCode); + data: dioResponse.data!, statusCode: dioResponse.statusCode!); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response.statusCode); + data: error.response?.data, statusCode: error.response!.statusCode!); } } @override Future delete(String path, - {ParseNetworkOptions options}) async { + {ParseNetworkOptions? options}) async { try { final dio.Response dioResponse = await _client.delete( path, options: _Options(headers: options?.headers), ); return ParseNetworkResponse( - data: dioResponse.data, statusCode: dioResponse.statusCode); + data: dioResponse.data!, statusCode: dioResponse.statusCode!); } on dio.DioError catch (error) { return ParseNetworkResponse( - data: error.response?.data, statusCode: error.response.statusCode); + data: error.response?.data, statusCode: error.response!.statusCode!); } } } /// Creates a custom version of HTTP Client that has Parse Data Preset class _ParseDioClient with dio.DioMixin implements dio.Dio { - _ParseDioClient({bool/*!*/ sendSessionId = false, SecurityContext securityContext}) + _ParseDioClient({bool sendSessionId = false, SecurityContext? securityContext}) : _sendSessionId = sendSessionId { options = dio.BaseOptions(); httpClientAdapter = createHttpClientAdapter(securityContext); @@ -137,38 +137,38 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { final bool _sendSessionId; final String _userAgent = '$keyLibraryName $keySdkVersion'; ParseCoreData parseCoreData = ParseCoreData(); - Map/*?*/ additionalHeaders; + Map? additionalHeaders; /// Overrides the call method for HTTP Client and adds custom headers @override Future> request( String path, { dynamic data, - Map queryParameters, - dio.CancelToken cancelToken, - dio.Options options, - ProgressCallback onSendProgress, - ProgressCallback onReceiveProgress, + Map? queryParameters, + dio.CancelToken? cancelToken, + dio.Options? options, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, }) { options ??= dio.Options(headers: Map()); if (!identical(0, 0.0)) { - options.headers[keyHeaderUserAgent] = _userAgent; + options.headers![keyHeaderUserAgent] = _userAgent; } - options.headers[keyHeaderApplicationId] = parseCoreData.applicationId; + options.headers![keyHeaderApplicationId] = parseCoreData.applicationId; if (_sendSessionId && parseCoreData.sessionId != null && - options.headers[keyHeaderSessionToken] == null) - options.headers[keyHeaderSessionToken] = parseCoreData.sessionId; + options.headers![keyHeaderSessionToken] == null) + options.headers![keyHeaderSessionToken] = parseCoreData.sessionId; if (parseCoreData.clientKey != null) - options.headers[keyHeaderClientKey] = parseCoreData.clientKey; + options.headers![keyHeaderClientKey] = parseCoreData.clientKey; if (parseCoreData.masterKey != null) - options.headers[keyHeaderMasterKey] = parseCoreData.masterKey; + options.headers![keyHeaderMasterKey] = parseCoreData.masterKey; /// If developer wants to add custom headers, extend this class and add headers needed. - if (additionalHeaders != null && additionalHeaders.isNotEmpty) { - additionalHeaders - .forEach((String key, String value) => options.headers[key] = value); + if (additionalHeaders != null && additionalHeaders!.isNotEmpty) { + additionalHeaders! + .forEach((String key, String value) => options!.headers![key] = value); } if (parseCoreData.debug) { @@ -188,9 +188,9 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { void _logCUrl(dio.Options options, dynamic data, String url) { String curlCmd = 'curl'; - curlCmd += ' -X ' + options.method; + curlCmd += ' -X ' + options.method!; bool compressed = false; - options.headers.forEach((String name, dynamic value) { + options.headers!.forEach((String name, dynamic value) { if (name.toLowerCase() == 'accept-encoding' && value?.toString().toLowerCase() == 'gzip') { compressed = true; @@ -216,19 +216,19 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { class _Options extends dio.Options { _Options({ - String method, - int sendTimeout, - int receiveTimeout, - Map extra, - Map headers, - dio.ResponseType responseType, - String contentType, - dio.ValidateStatus validateStatus, - bool receiveDataWhenStatusError, - bool followRedirects, - int maxRedirects, - dio.RequestEncoder requestEncoder, - dio.ResponseDecoder responseDecoder, + String? method, + int? sendTimeout, + int? receiveTimeout, + Map? extra, + Map? headers, + dio.ResponseType? responseType, + String? contentType, + dio.ValidateStatus? validateStatus, + bool? receiveDataWhenStatusError, + bool? followRedirects, + int? maxRedirects, + dio.RequestEncoder? requestEncoder, + dio.ResponseDecoder? responseDecoder, }) : super( method: method, sendTimeout: sendTimeout, diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index 0a7fc61b1..e2481afe3 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -7,20 +7,20 @@ import 'package:parse_server_sdk/parse_server_sdk.dart'; class ParseHTTPClient extends ParseClient { ParseHTTPClient( - {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) { + {bool sendSessionId = false, SecurityContext? securityContext}) { _client = _ParseHTTPClient( sendSessionId: sendSessionId, securityContext: securityContext, ); } - _ParseHTTPClient _client; + late _ParseHTTPClient _client; @override Future get( String path, { - ParseNetworkOptions options, - ProgressCallback onReceiveProgress, + ParseNetworkOptions? options, + ProgressCallback? onReceiveProgress, }) async { final http.Response response = await _client.get( Uri.parse(path), @@ -33,8 +33,8 @@ class ParseHTTPClient extends ParseClient { @override Future getBytes( String path, { - ParseNetworkOptions options, - ProgressCallback onReceiveProgress, + ParseNetworkOptions? options, + ProgressCallback? onReceiveProgress, }) async { final http.Response response = await _client.get( Uri.parse(path), @@ -47,8 +47,8 @@ class ParseHTTPClient extends ParseClient { @override Future put( String path, { - String data, - ParseNetworkOptions options, + String? data, + ParseNetworkOptions? options, }) async { final http.Response response = await _client.put( Uri.parse(path), @@ -62,8 +62,8 @@ class ParseHTTPClient extends ParseClient { @override Future post( String path, { - String data, - ParseNetworkOptions options, + String? data, + ParseNetworkOptions? options, }) async { final http.Response response = await _client.post( Uri.parse(path), @@ -77,9 +77,9 @@ class ParseHTTPClient extends ParseClient { @override Future postBytes( String path, { - Stream> data, - ParseNetworkOptions options, - ProgressCallback onSendProgress, + Stream>? data, + ParseNetworkOptions? options, + ProgressCallback? onSendProgress, }) async { final http.Response response = await _client.post( Uri.parse(path), @@ -94,7 +94,7 @@ class ParseHTTPClient extends ParseClient { @override Future delete(String path, - {ParseNetworkOptions options}) async { + {ParseNetworkOptions? options}) async { final http.Response response = await _client.delete( Uri.parse(path), headers: options?.headers, @@ -107,7 +107,7 @@ class ParseHTTPClient extends ParseClient { /// Creates a custom version of HTTP Client that has Parse Data Preset class _ParseHTTPClient extends http.BaseClient { _ParseHTTPClient( - {bool/*!*/ sendSessionId = false, SecurityContext securityContext}) + {bool sendSessionId = false, SecurityContext? securityContext}) : _sendSessionId = sendSessionId, _client = securityContext != null ? IOClient(HttpClient(context: securityContext)) @@ -117,7 +117,7 @@ class _ParseHTTPClient extends http.BaseClient { final bool _sendSessionId; final String _userAgent = '$keyLibraryName $keySdkVersion'; ParseCoreData parseCoreData = ParseCoreData(); - Map/*?*/ additionalHeaders; + Map? additionalHeaders; /// Overrides the call method for HTTP Client and adds custom headers @override @@ -129,16 +129,16 @@ class _ParseHTTPClient extends http.BaseClient { if (_sendSessionId && parseCoreData.sessionId != null && request.headers[keyHeaderSessionToken] == null) - request.headers[keyHeaderSessionToken] = parseCoreData.sessionId; + request.headers[keyHeaderSessionToken] = parseCoreData.sessionId!; if (parseCoreData.clientKey != null) - request.headers[keyHeaderClientKey] = parseCoreData.clientKey; + request.headers[keyHeaderClientKey] = parseCoreData.clientKey!; if (parseCoreData.masterKey != null) - request.headers[keyHeaderMasterKey] = parseCoreData.masterKey; + request.headers[keyHeaderMasterKey] = parseCoreData.masterKey!; /// If developer wants to add custom headers, extend this class and add headers needed. - if (additionalHeaders != null && additionalHeaders.isNotEmpty) { - additionalHeaders + if (additionalHeaders != null && additionalHeaders!.isNotEmpty) { + additionalHeaders! .forEach((String key, String value) => request.headers[key] = value); } diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index b6d299e49..16389586a 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -5,12 +5,12 @@ enum LiveQueryEvent { create, enter, update, leave, delete, error } const String _printConstLiveQuery = 'LiveQuery: '; class Subscription { - Subscription(this.query, this.requestId, {T copyObject}) { + Subscription(this.query, this.requestId, {T? copyObject}) { _copyObject = copyObject; } QueryBuilder query; - T _copyObject; + T? _copyObject; int requestId; bool _enabled = false; final List _liveQueryEvent = [ @@ -26,7 +26,7 @@ class Subscription { eventCallbacks[_liveQueryEvent[op.index]] = callback; } - T get copyObject { + T? get copyObject { return _copyObject; } } @@ -39,7 +39,7 @@ class LiveQueryReconnectingController { this._eventStream, this.debug, ) { - final ParseConnectivityProvider connectivityProvider = + final ParseConnectivityProvider? connectivityProvider = ParseCoreData().connectivityProvider; if (connectivityProvider != null) { connectivityProvider.checkConnectivity().then(_connectivityChanged); @@ -62,7 +62,7 @@ class LiveQueryReconnectingController { case LiveQueryClientEvent.USER_DISCONNECTED: _userDisconnected = true; if (_currentTimer != null) { - _currentTimer.cancel(); + _currentTimer!.cancel(); _currentTimer = null; } break; @@ -87,7 +87,7 @@ class LiveQueryReconnectingController { bool _isConnected = false; bool _userDisconnected = false; - Timer _currentTimer; + Timer? _currentTimer; void _connectivityChanged(ParseConnectivityResult state) { if (!_isOnline && state != ParseConnectivityResult.none) { @@ -126,7 +126,7 @@ class LiveQueryReconnectingController { class LiveQueryClient { factory LiveQueryClient() => _getInstance(); - LiveQueryClient._internal({bool debug, bool autoSendSessionId}) { + LiveQueryClient._internal({bool? debug, bool? autoSendSessionId}) { _clientEventStreamController = StreamController(); _clientEventStream = _clientEventStreamController.stream.asBroadcastStream(); @@ -137,37 +137,37 @@ class LiveQueryClient { _liveQueryURL = ParseCoreData().liveQueryURL; assert(_liveQueryURL != null, 'liveQueryUrl is not set. For how to setup Live Queries, see https://github.com/parse-community/Parse-SDK-Flutter/tree/master/packages/flutter#live-queries.'); - if (_liveQueryURL.contains('https')) { - _liveQueryURL = _liveQueryURL.replaceAll('https', 'wss'); - } else if (_liveQueryURL.contains('http')) { - _liveQueryURL = _liveQueryURL.replaceAll('http', 'ws'); + if (_liveQueryURL!.contains('https')) { + _liveQueryURL = _liveQueryURL!.replaceAll('https', 'wss'); + } else if (_liveQueryURL!.contains('http')) { + _liveQueryURL = _liveQueryURL!.replaceAll('http', 'ws'); } reconnectingController = LiveQueryReconnectingController( () => reconnect(userInitialized: false), getClientEventStream, _debug); } static LiveQueryClient get instance => _getInstance(); - static LiveQueryClient _instance; - static LiveQueryClient/*!*/ _getInstance( - {bool debug, bool autoSendSessionId}) { + static LiveQueryClient? _instance; + static LiveQueryClient _getInstance( + {bool? debug, bool? autoSendSessionId}) { _instance ??= LiveQueryClient._internal( debug: debug, autoSendSessionId: autoSendSessionId); - return _instance; + return _instance!; } Stream get getClientEventStream { return _clientEventStream; } - parse_web_socket.WebSocket _webSocket; - /*late*/bool/*!*/ _debug; - bool _sendSessionId; - WebSocketChannel _channel; - String _liveQueryURL; + parse_web_socket.WebSocket? _webSocket; + late bool _debug; + late bool _sendSessionId; + WebSocketChannel? _channel; + String? _liveQueryURL; bool _connecting = false; - StreamController _clientEventStreamController; - /*late*/Stream/*!*/ _clientEventStream; - LiveQueryReconnectingController/*!*/ reconnectingController; + late StreamController _clientEventStreamController; + late Stream _clientEventStream; + late LiveQueryReconnectingController reconnectingController; final Map _requestSubscription = {}; @@ -178,25 +178,25 @@ class LiveQueryClient { int readyState() { if (_webSocket != null) { - return _webSocket.readyState; + return _webSocket!.readyState; } return parse_web_socket.WebSocket.CONNECTING; } Future disconnect({bool userInitialized = false}) async { if (_webSocket != null && - _webSocket.readyState == parse_web_socket.WebSocket.OPEN) { + _webSocket!.readyState == parse_web_socket.WebSocket.OPEN) { if (_debug) { print('$_printConstLiveQuery: Socket closed'); } - await _webSocket.close(); + await _webSocket!.close(); _webSocket = null; } - if (_channel != null && _channel.sink != null) { + if (_channel != null && _channel!.sink != null) { if (_debug) { print('$_printConstLiveQuery: close'); } - await _channel.sink.close(); + await _channel!.sink.close(); _channel = null; } _requestSubscription.values.toList().forEach((Subscription subscription) { @@ -210,7 +210,7 @@ class LiveQueryClient { Future> subscribe( QueryBuilder query, - {T copyObject}) async { + {T? copyObject}) async { if (_webSocket == null) { await _clientEventStream.any((LiveQueryClientEvent event) => event == LiveQueryClientEvent.CONNECTED); @@ -231,11 +231,11 @@ class LiveQueryClient { 'op': 'unsubscribe', 'requestId': subscription.requestId, }; - if (_channel != null && _channel.sink != null) { + if (_channel != null && _channel!.sink != null) { if (_debug) { print('$_printConstLiveQuery: UnsubscribeMessage: $unsubscribeMessage'); } - _channel.sink.add(jsonEncode(unsubscribeMessage)); + _channel!.sink.add(jsonEncode(unsubscribeMessage)); subscription._enabled = false; _requestSubscription.remove(subscription.requestId); } @@ -256,10 +256,10 @@ class LiveQueryClient { _connecting = true; try { - _webSocket = await parse_web_socket.WebSocket.connect(_liveQueryURL); + _webSocket = await parse_web_socket.WebSocket.connect(_liveQueryURL!); _connecting = false; if (_webSocket != null && - _webSocket.readyState == parse_web_socket.WebSocket.OPEN) { + _webSocket!.readyState == parse_web_socket.WebSocket.OPEN) { if (_debug) { print('$_printConstLiveQuery: Socket opened'); } @@ -269,8 +269,8 @@ class LiveQueryClient { } return Future.value(null); } - _channel = _webSocket.createWebSocketChannel(); - _channel.stream.listen((dynamic message) { + _channel = _webSocket!.createWebSocketChannel(); + _channel!.stream.listen((dynamic message) { _handleMessage(message); }, onDone: () { _clientEventStreamController.sink @@ -302,29 +302,29 @@ class LiveQueryClient { } void _connectLiveQuery() { - if (_channel == null || _channel.sink == null) { + if (_channel == null || _channel!.sink == null) { return; } //The connect message is sent from a client to the LiveQuery server. //It should be the first message sent from a client after the WebSocket connection is established. - final Map connectMessage = { + final Map connectMessage = { 'op': 'connect', 'applicationId': ParseCoreData().applicationId }; if (_sendSessionId && ParseCoreData().sessionId != null) { - connectMessage['sessionToken'] = ParseCoreData().sessionId; + connectMessage['sessionToken'] = ParseCoreData().sessionId!; } if (ParseCoreData().clientKey != null) - connectMessage['clientKey'] = ParseCoreData().clientKey; + connectMessage['clientKey'] = ParseCoreData().clientKey!; if (ParseCoreData().masterKey != null) - connectMessage['masterKey'] = ParseCoreData().masterKey; + connectMessage['masterKey'] = ParseCoreData().masterKey!; if (_debug) { print('$_printConstLiveQuery: ConnectMessage: $connectMessage'); } - _channel.sink.add(jsonEncode(connectMessage)); + _channel!.sink.add(jsonEncode(connectMessage)); } void _subscribeLiveQuery(Subscription subscription) { @@ -333,12 +333,12 @@ class LiveQueryClient { } subscription._enabled = true; final QueryBuilder query = subscription.query; - final List keysToReturn = query.limiters['keys']?.split(','); + final List? keysToReturn = query.limiters['keys']?.split(','); query.limiters.clear(); //Remove limits in LiveQuery final String _where = query.buildQuery().replaceAll('where=', ''); //Convert where condition to Map - Map/*!*/ _whereMap = Map(); + Map _whereMap = Map(); if (_where != '') { _whereMap = json.decode(_where); } @@ -347,7 +347,7 @@ class LiveQueryClient { 'op': 'subscribe', 'requestId': subscription.requestId, 'query': { - 'className': query.object.parseClassName, + 'className': query.object!.parseClassName, 'where': _whereMap, if (keysToReturn != null && keysToReturn.isNotEmpty) 'fields': keysToReturn @@ -361,7 +361,7 @@ class LiveQueryClient { print('$_printConstLiveQuery: SubscribeMessage: $subscribeMessage'); } - _channel.sink.add(jsonEncode(subscribeMessage)); + _channel!.sink.add(jsonEncode(subscribeMessage)); } void _handleMessage(String message) { @@ -371,7 +371,7 @@ class LiveQueryClient { final Map actionData = jsonDecode(message); - Subscription subscription; + Subscription? subscription; if (actionData.containsKey('op') && actionData['op'] == 'connected') { print('ReSubScription:$_requestSubscription'); @@ -390,34 +390,34 @@ class LiveQueryClient { if (subscription.eventCallbacks.containsKey(actionData['op'])) { if (actionData.containsKey('object')) { final Map map = actionData['object']; - final String className = map['className']; + final String? className = map['className']; if (className == keyClassUser) { - subscription.eventCallbacks[actionData['op']]( + subscription.eventCallbacks[actionData['op']]!( (subscription.copyObject ?? ParseCoreData.instance.createParseUser(null, null, null)) .fromJson(map)); } else { - subscription.eventCallbacks[actionData['op']]( + subscription.eventCallbacks[actionData['op']]!( (subscription.copyObject ?? - ParseCoreData.instance.createObject(className)) + ParseCoreData.instance.createObject(className!)) .fromJson(map)); } } else { - subscription.eventCallbacks[actionData['op']](actionData); + subscription.eventCallbacks[actionData['op']]!(actionData); } } } } class LiveQuery { - LiveQuery({bool debug, bool autoSendSessionId}) { + LiveQuery({bool? debug, bool? autoSendSessionId}) { _debug = isDebugEnabled(objectLevelDebug: debug); _sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId; client = LiveQueryClient._getInstance( debug: _debug, autoSendSessionId: _sendSessionId); } - bool _debug; - bool _sendSessionId; - LiveQueryClient client; + bool? _debug; + bool? _sendSessionId; + late LiveQueryClient client; } diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 738c35e70..4165adac0 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -6,7 +6,7 @@ class QueryBuilder { QueryBuilder(this.object) : super(); QueryBuilder.name(String classname) - : this(ParseCoreData.instance.createObject(classname)); + : this(ParseCoreData.instance.createObject(classname) as T?); QueryBuilder.or(this.object, List> list) { String query = '"\$or":['; @@ -33,7 +33,7 @@ class QueryBuilder { static const String _NO_OPERATOR_NEEDED = 'NO_OP'; static const String _SINGLE_QUERY = 'SINGLE_QUERY'; - T object; + T? object; List> queries = >[]; final Map limiters = Map(); @@ -286,7 +286,7 @@ class QueryBuilder { // Add a constraint to the query that requires a particular key's value match another QueryBuilder void whereMatchesQuery(String column, QueryBuilder query) { final String inQuery = - query._buildQueryRelational(query.object.parseClassName); + query._buildQueryRelational(query.object!.parseClassName); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$inQuery\":$inQuery}')); @@ -295,7 +295,7 @@ class QueryBuilder { //Add a constraint to the query that requires a particular key's value does not match another QueryBuilder void whereDoesNotMatchQuery(String column, QueryBuilder query) { final String inQuery = - query._buildQueryRelational(query.object.parseClassName); + query._buildQueryRelational(query.object!.parseClassName); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$notInQuery\":$inQuery}')); @@ -315,7 +315,7 @@ class QueryBuilder { } final String inQuery = - query._buildQueryRelationalKey(query.object.parseClassName, keyInQuery); + query._buildQueryRelationalKey(query.object!.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$select\":$inQuery}')); @@ -335,7 +335,7 @@ class QueryBuilder { } final String inQuery = - query._buildQueryRelationalKey(query.object.parseClassName, keyInQuery); + query._buildQueryRelationalKey(query.object!.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$dontSelect\":$inQuery}')); @@ -345,8 +345,8 @@ class QueryBuilder { /// /// Make sure to call this after defining your queries Future query( - {ProgressCallback progressCallback}) async { - return object.query( + {ProgressCallback? progressCallback}) async { + return object!.query( buildQuery(), progressCallback: progressCallback, ); @@ -355,12 +355,12 @@ class QueryBuilder { Future distinct( String className) async { final String queryString = 'distinct=$className'; - return object.distinct(queryString); + return object!.distinct(queryString); } ///Counts the number of objects that match this query Future count() async { - return object.query(_buildQueryCount()); + return object!.query(_buildQueryCount()); } /// Builds the query for Parse diff --git a/packages/dart/lib/src/objects/parse_acl.dart b/packages/dart/lib/src/objects/parse_acl.dart index ad7794fb3..618b86c5f 100644 --- a/packages/dart/lib/src/objects/parse_acl.dart +++ b/packages/dart/lib/src/objects/parse_acl.dart @@ -8,10 +8,10 @@ part of flutter_parse_sdk; class ParseACL { ///Creates an ACL where only the provided user has access. ///[owner] The only user that can read or write objects governed by this ACL. - ParseACL({ParseUser owner}) { + ParseACL({ParseUser? owner}) { if (owner != null) { - setReadAccess(userId: owner.objectId, allowed: true); - setWriteAccess(userId: owner.objectId, allowed: true); + setReadAccess(userId: owner.objectId!, allowed: true); + setWriteAccess(userId: owner.objectId!, allowed: true); } } @@ -21,9 +21,9 @@ class ParseACL { /// Helper for setting stuff void _setPermissionsIfNonEmpty( - {@required String/*!*/ userId, - @required bool readPermission, - @required bool/*!*/ writePermission}) { + {required String userId, + required bool readPermission, + required bool writePermission}) { if (!(readPermission || writePermission)) { _permissionsById.remove(userId); } else { @@ -38,7 +38,7 @@ class ParseACL { } ///Set whether the public is allowed to read this object. - void setPublicReadAccess({@required bool allowed}) { + void setPublicReadAccess({required bool allowed}) { setReadAccess(userId: _publicKEY, allowed: allowed); } @@ -48,12 +48,12 @@ class ParseACL { } ///Set whether the public is allowed to write this object. - void setPublicWriteAccess({@required bool allowed}) { + void setPublicWriteAccess({required bool allowed}) { setWriteAccess(userId: _publicKEY, allowed: allowed); } ///Set whether the given user id is allowed to read this object. - void setReadAccess({@required String userId, bool allowed = true}) { + void setReadAccess({required String userId, bool allowed = true}) { final bool writePermission = getWriteAccess(userId: userId); _setPermissionsIfNonEmpty( userId: userId, @@ -64,12 +64,12 @@ class ParseACL { /// Get whether the given user id is *explicitly* allowed to read this object. Even if this returns /// [false], the user may still be able to access it if getPublicReadAccess returns /// [true] or a role that the user belongs to has read access. - bool getReadAccess({@required String userId}) { + bool getReadAccess({required String userId}) { return _permissionsById[userId]?.readPermission ?? false; } ///Set whether the given user id is allowed to write this object. - void setWriteAccess({@required String userId, bool allowed = true}) { + void setWriteAccess({required String userId, bool allowed = true}) { final bool readPermission = getReadAccess(userId: userId); _setPermissionsIfNonEmpty( userId: userId, @@ -80,7 +80,7 @@ class ParseACL { ///Get whether the given user id is *explicitly* allowed to write this object. Even if this ///returns [false], the user may still be able to write it if getPublicWriteAccess returns ///[true] or a role that the user belongs to has write access. - bool getWriteAccess({@required String userId}) { + bool getWriteAccess({required String userId}) { return _permissionsById[userId]?.writePermission ?? false; } @@ -115,7 +115,7 @@ class _ACLPermissions { final String _keyReadPermission = 'read'; final String _keyWritePermission = 'write'; final bool _readPermission; - final bool/*!*/ _writePermission; + final bool _writePermission; bool get readPermission => _readPermission; diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 05dd30748..a9cff1a0c 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -1,20 +1,20 @@ part of flutter_parse_sdk; abstract class ParseBase { - String/*!*/ parseClassName = 'ParseBase'; + String parseClassName = 'ParseBase'; final bool _dirty = false; // reserved property - final Map _unsavedChanges = Map(); - final Map _savingChanges = Map(); + final Map _unsavedChanges = Map(); + final Map _savingChanges = Map(); /// Stores all the values of a class - Map/*!*/ _objectData = Map(); + Map _objectData = Map(); /// Returns [String] objectId - String get objectId => get(keyVarObjectId); + String? get objectId => get(keyVarObjectId); - set objectId(String objectId) => set(keyVarObjectId, objectId); + set objectId(String? objectId) => set(keyVarObjectId, objectId); - bool isDirty({String key}) { + bool isDirty({String? key}) { if (key != null) { return _unsavedChanges[key] != null; } @@ -50,9 +50,9 @@ abstract class ParseBase { } /// Returns [DateTime] createdAt - DateTime get createdAt { + DateTime? get createdAt { if (get(keyVarCreatedAt) is String) { - final String/*?*/ dateAsString = get(keyVarCreatedAt); + final String? dateAsString = get(keyVarCreatedAt); return dateAsString != null ? _parseDateFormat.parse(dateAsString) : null; } else { return get(keyVarCreatedAt); @@ -60,9 +60,9 @@ abstract class ParseBase { } /// Returns [DateTime] updatedAt - DateTime get updatedAt { + DateTime? get updatedAt { if (get(keyVarUpdatedAt) is String) { - final String/*?*/ dateAsString = get(keyVarUpdatedAt); + final String? dateAsString = get(keyVarUpdatedAt); return dateAsString != null ? _parseDateFormat.parse(dateAsString) : null; } else { return get(keyVarUpdatedAt); @@ -85,11 +85,11 @@ abstract class ParseBase { } if (createdAt != null) { - map[keyVarCreatedAt] = _parseDateFormat.format(createdAt); + map[keyVarCreatedAt] = _parseDateFormat.format(createdAt!); } if (updatedAt != null) { - map[keyVarUpdatedAt] = _parseDateFormat.format(updatedAt); + map[keyVarUpdatedAt] = _parseDateFormat.format(updatedAt!); } final Map target = @@ -157,7 +157,7 @@ abstract class ParseBase { /// Returns the objects variables @protected - Map _getObjectData() => _objectData; + Map _getObjectData() => _objectData; bool containsValue(Object value) { return _getObjectData().containsValue(value); @@ -190,7 +190,7 @@ abstract class ParseBase { /// To set an int, call setType and an int will be saved /// [bool] forceUpdate is always true, if unsure as to whether an item is /// needed or not, set to false - void set(String/*!*/ key, T value, {bool forceUpdate = true}) { + void set(String key, T value, {bool forceUpdate = true}) { if (_getObjectData().containsKey(key)) { if (_getObjectData()[key] == value && !forceUpdate) { return; @@ -208,9 +208,9 @@ abstract class ParseBase { /// Returns null or [defaultValue] if provided. To get an int, call /// getType and an int will be returned, null, or a defaultValue if /// provided - T get(String key, {T defaultValue}) { + T? get(String key, {T? defaultValue}) { if (_getObjectData().containsKey(key)) { - return _getObjectData()[key] as T; + return _getObjectData()[key] as T?; } else { return defaultValue; } @@ -222,9 +222,9 @@ abstract class ParseBase { Future pin() async { if (objectId != null) { await unpin(); - final Map objectMap = parseEncode(this, full: true); + final Map? objectMap = parseEncode(this, full: true); final String json = jsonEncode(objectMap); - await ParseCoreData().getStore().setString(objectId, json); + await ParseCoreData().getStore().setString(objectId!, json); return true; } else { return false; @@ -234,9 +234,9 @@ abstract class ParseBase { /// Saves item to simple key pair value storage /// /// Replicates Android SDK pin process and saves object to storage - Future unpin({String key}) async { + Future unpin({String? key}) async { if (objectId != null) { - await ParseCoreData().getStore().remove(key ?? objectId); + await ParseCoreData().getStore().remove(key ?? objectId!); return true; } @@ -248,7 +248,7 @@ abstract class ParseBase { /// Replicates Android SDK pin process and saves object to storage dynamic fromPin(String objectId) async { final CoreStore coreStore = ParseCoreData().getStore(); - final String itemFromStore = await coreStore.getString(objectId); + final String? itemFromStore = await coreStore.getString(objectId); if (itemFromStore != null) { return fromJson(json.decode(itemFromStore)); @@ -256,7 +256,7 @@ abstract class ParseBase { return null; } - Map toPointer() => encodeObject(parseClassName, objectId); + Map toPointer() => encodeObject(parseClassName, objectId!); ///Set the [ParseACL] governing this object. void setACL(ParseACL acl) { @@ -264,7 +264,7 @@ abstract class ParseBase { } ///Access the [ParseACL] governing this object. - ParseACL/*!*/ getACL() { + ParseACL getACL() { if (_getObjectData().containsKey(keyVarAcl)) { return _getObjectData()[keyVarAcl]; } else { diff --git a/packages/dart/lib/src/objects/parse_cloneable.dart b/packages/dart/lib/src/objects/parse_cloneable.dart index 7fe65ae8f..589b60149 100644 --- a/packages/dart/lib/src/objects/parse_cloneable.dart +++ b/packages/dart/lib/src/objects/parse_cloneable.dart @@ -2,5 +2,5 @@ part of flutter_parse_sdk; /// Creates method which can be used to deep clone objects abstract class ParseCloneable { - dynamic clone(Map/*!*/ map); + dynamic clone(Map map); } diff --git a/packages/dart/lib/src/objects/parse_config.dart b/packages/dart/lib/src/objects/parse_config.dart index 0e7f9ecc1..1e0d85640 100644 --- a/packages/dart/lib/src/objects/parse_config.dart +++ b/packages/dart/lib/src/objects/parse_config.dart @@ -3,9 +3,9 @@ part of flutter_parse_sdk; class ParseConfig extends ParseObject { /// Creates an instance of ParseConfig so that you can grab all configs from the server ParseConfig({ - bool debug, - ParseClient client, - bool autoSendSessionId, + bool? debug, + ParseClient? client, + bool? autoSendSessionId, }) : super( 'config', debug: debug, diff --git a/packages/dart/lib/src/objects/parse_error.dart b/packages/dart/lib/src/objects/parse_error.dart index a7c7bf471..d450ba737 100644 --- a/packages/dart/lib/src/objects/parse_error.dart +++ b/packages/dart/lib/src/objects/parse_error.dart @@ -67,10 +67,10 @@ class ParseError { 252: 'UnsupportedService' }; - final int/*!*/ code; + final int code; final String message; - final Exception exception; - String type; + final Exception? exception; + String? type; @override String toString() { diff --git a/packages/dart/lib/src/objects/parse_file.dart b/packages/dart/lib/src/objects/parse_file.dart index 6f30348eb..35ed5c8fd 100644 --- a/packages/dart/lib/src/objects/parse_file.dart +++ b/packages/dart/lib/src/objects/parse_file.dart @@ -5,20 +5,20 @@ class ParseFile extends ParseFileBase { /// /// {https://docs.parseplatform.org/rest/guide/#files/} ParseFile(this.file, - {String name, - String url, - bool debug, - ParseClient client, - bool autoSendSessionId}) + {String? name, + String? url, + bool? debug, + ParseClient? client, + bool? autoSendSessionId}) : super( - name: file != null ? path.basename(file.path) : name, + name: file != null ? path.basename(file.path) : name!, url: url, debug: debug, client: client, autoSendSessionId: autoSendSessionId, ); - File file; + File? file; Future loadStorage() async { final File possibleFile = File('${ParseCoreData().fileDirectory}/$name'); @@ -35,29 +35,29 @@ class ParseFile extends ParseFileBase { } @override - Future download({ProgressCallback progressCallback}) async { + Future download({ProgressCallback? progressCallback}) async { if (url == null) { return this; } file = File('${ParseCoreData().fileDirectory}/$name'); - await file.create(); + await file!.create(); final ParseNetworkByteResponse response = await _client.getBytes( - url, + url!, onReceiveProgress: progressCallback, ); - await file.writeAsBytes(response.bytes); + await file!.writeAsBytes(response.bytes!); return this; } /// Uploads a file to Parse Server @override - Future upload({ProgressCallback progressCallback}) async { + Future upload({ProgressCallback? progressCallback}) async { if (saved) { //Creates a Fake Response to return the correct result final Map response = { - 'url': url/*!*/, + 'url': url!, 'name': name }; return handleResponse( @@ -70,14 +70,14 @@ class ParseFile extends ParseFileBase { final Map headers = { HttpHeaders.contentTypeHeader: - mime(file.path) ?? 'application/octet-stream', + mime(file!.path) ?? 'application/octet-stream', }; try { final String uri = ParseCoreData().serverUrl + '$_path'; final ParseNetworkResponse response = await _client.postBytes( uri, options: ParseNetworkOptions(headers: headers), - data: file.openRead(), + data: file!.openRead(), onSendProgress: progressCallback, ); if (response.statusCode == 201) { diff --git a/packages/dart/lib/src/objects/parse_file_base.dart b/packages/dart/lib/src/objects/parse_file_base.dart index 10d6bba73..6eecec459 100644 --- a/packages/dart/lib/src/objects/parse_file_base.dart +++ b/packages/dart/lib/src/objects/parse_file_base.dart @@ -5,11 +5,11 @@ abstract class ParseFileBase extends ParseObject { /// /// {https://docs.parseplatform.org/rest/guide/#files/} ParseFileBase( - {@required String/*!*/ name, - String/*?*/ url, - bool debug, - ParseClient client, - bool autoSendSessionId}) + {required String name, + String? url, + bool? debug, + ParseClient? client, + bool? autoSendSessionId}) : super(keyFileClassname, debug: debug, autoSendSessionId: autoSendSessionId, @@ -21,11 +21,11 @@ abstract class ParseFileBase extends ParseObject { } - String get name => super.get(keyVarName); - set name(String/*!*/ name) => set(keyVarName, name); + String get name => super.get(keyVarName)!; + set name(String name) => set(keyVarName, name); - String get url => super.get(keyVarURL); - set url(String url) => set(keyVarURL, url); + String? get url => super.get(keyVarURL); + set url(String? url) => set(keyVarURL, url); bool get saved => url != null; @@ -35,7 +35,7 @@ abstract class ParseFileBase extends ParseObject { bool forApiRQ = false, bool allowCustomObjectId = false, }) => - {'__type': keyFile, 'name': name, 'url': url}; + {'__type': keyFile, 'name': name, 'url': url}; @override String toString() => json.encode(toJson(full: true)); @@ -47,7 +47,7 @@ abstract class ParseFileBase extends ParseObject { } /// Uploads a file to Parse Server - Future upload({ProgressCallback progressCallback}); + Future upload({ProgressCallback? progressCallback}); - Future download({ProgressCallback progressCallback}); + Future download({ProgressCallback? progressCallback}); } diff --git a/packages/dart/lib/src/objects/parse_file_web.dart b/packages/dart/lib/src/objects/parse_file_web.dart index 3d227d401..3a6a57398 100644 --- a/packages/dart/lib/src/objects/parse_file_web.dart +++ b/packages/dart/lib/src/objects/parse_file_web.dart @@ -2,11 +2,11 @@ part of flutter_parse_sdk; class ParseWebFile extends ParseFileBase { ParseWebFile(this.file, - {@required String name, - String url, - bool debug, - ParseClient client, - bool autoSendSessionId}) + {required String name, + String? url, + bool? debug, + ParseClient? client, + bool? autoSendSessionId}) : super( name: name, url: url, @@ -15,29 +15,29 @@ class ParseWebFile extends ParseFileBase { autoSendSessionId: autoSendSessionId, ); - Uint8List file; + Uint8List? file; @override - Future download({ProgressCallback progressCallback}) async { + Future download({ProgressCallback? progressCallback}) async { if (url == null) { return this; } final ParseNetworkByteResponse response = await _client.getBytes( - url, + url!, onReceiveProgress: progressCallback, ); - file = response.bytes; + file = response.bytes as Uint8List?; return this; } @override - Future upload({ProgressCallback progressCallback}) async { + Future upload({ProgressCallback? progressCallback}) async { if (saved) { //Creates a Fake Response to return the correct result final Map response = { - 'url': url/*!*/, + 'url': url!, 'name': name }; return handleResponse( @@ -57,7 +57,7 @@ class ParseWebFile extends ParseFileBase { final ParseNetworkResponse response = await _client.postBytes( uri, options: ParseNetworkOptions(headers: headers), - data: Stream>.fromIterable(/*!*/>[file]), + data: Stream>.fromIterable(>[file!]), onSendProgress: progressCallback, ); if (response.statusCode == 201) { diff --git a/packages/dart/lib/src/objects/parse_function.dart b/packages/dart/lib/src/objects/parse_function.dart index c84037339..073e04e7b 100644 --- a/packages/dart/lib/src/objects/parse_function.dart +++ b/packages/dart/lib/src/objects/parse_function.dart @@ -6,9 +6,9 @@ class ParseCloudFunction extends ParseObject { /// {https://docs.parseplatform.org/cloudcode/guide/} ParseCloudFunction( this.functionName, { - bool debug, - ParseClient client, - bool autoSendSessionId, + bool? debug, + ParseClient? client, + bool? autoSendSessionId, }) : super( functionName, client: client, @@ -22,13 +22,13 @@ class ParseCloudFunction extends ParseObject { @override // ignore: overridden_fields - String _path; + late String _path; /// Executes a cloud function /// /// To add the parameters, create an object and call [set](value to set) Future execute( - {Map parameters, + {Map? parameters, Map headers = const {}}) async { final String uri = '${ParseCoreData().serverUrl}$_path'; if (parameters != null) { @@ -49,7 +49,7 @@ class ParseCloudFunction extends ParseObject { /// /// To add the parameters, create an object and call [set](value to set) Future executeObjectFunction( - {Map parameters, + {Map? parameters, Map headers = const {}}) async { final String uri = '${ParseCoreData().serverUrl}$_path'; if (parameters != null) { diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index e934e85f6..a79d0b2b5 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -3,9 +3,9 @@ part of flutter_parse_sdk; class ParseInstallation extends ParseObject { /// Creates an instance of ParseInstallation ParseInstallation({ - bool debug, - ParseClient client, - bool autoSendSessionId, + bool? debug, + ParseClient? client, + bool? autoSendSessionId, }) : super( keyClassInstallation, client: client, @@ -24,34 +24,34 @@ class ParseInstallation extends ParseObject { keyAppIdentifier, keyParseVersion ]; - static String _currentInstallationId; + static String? _currentInstallationId; //Getters/setters - Map /*!*/ get acl => super - .get>(keyVarAcl, defaultValue: {}); + Map get acl => super + .get>(keyVarAcl, defaultValue: {})!; set acl(Map acl) => set>(keyVarAcl, acl); - String get deviceToken => super.get(keyDeviceToken); + String? get deviceToken => super.get(keyDeviceToken); - set deviceToken(String deviceToken) => - set(keyDeviceToken, deviceToken); + set deviceToken(String? deviceToken) => + set(keyDeviceToken, deviceToken); - String get deviceType => super.get(keyDeviceType); + String? get deviceType => super.get(keyDeviceType); - String get installationId => super.get(keyInstallationId); + String? get installationId => super.get(keyInstallationId); - set _installationId(String installationId) => - set(keyInstallationId, installationId); + set _installationId(String? installationId) => + set(keyInstallationId, installationId); - String get appName => super.get(keyAppName); + String? get appName => super.get(keyAppName); - String get appVersion => super.get(keyAppVersion); + String? get appVersion => super.get(keyAppVersion); - String get appIdentifier => super.get(keyAppIdentifier); + String? get appIdentifier => super.get(keyAppIdentifier); - String get parseVersion => super.get(keyParseVersion); + String? get parseVersion => super.get(keyParseVersion); static Future isCurrent(ParseInstallation installation) async { _currentInstallationId ??= (await _getFromLocalStore())?.installationId; @@ -61,7 +61,7 @@ class ParseInstallation extends ParseObject { /// Gets the current installation from storage static Future currentInstallation() async { - return (await _getFromLocalStore()) ?? (await _createInstallation()); + return (await (_getFromLocalStore() as FutureOr?)) ?? (await _createInstallation()); } /// Updates the installation with current device data @@ -82,14 +82,14 @@ class ParseInstallation extends ParseObject { } //Locale - set(keyLocaleIdentifier, ParseCoreData().locale); + set(keyLocaleIdentifier, ParseCoreData().locale); //Timezone //App info - set(keyAppName, ParseCoreData().appName); - set(keyAppVersion, ParseCoreData().appVersion); - set(keyAppIdentifier, ParseCoreData().appPackageName); + set(keyAppName, ParseCoreData().appName); + set(keyAppVersion, ParseCoreData().appVersion); + set(keyAppIdentifier, ParseCoreData().appPackageName); set(keyParseVersion, keySdkVersion); } @@ -126,14 +126,14 @@ class ParseInstallation extends ParseObject { } /// Gets the locally stored installation - static Future _getFromLocalStore() async { + static Future _getFromLocalStore() async { final CoreStore coreStore = ParseCoreData().getStore(); - final String installationJson = + final String? installationJson = await coreStore.getString(keyParseStoreInstallation); if (installationJson != null) { - final Map installationMap = + final Map? installationMap = json.decode(installationJson); if (installationMap != null) { @@ -232,7 +232,7 @@ class ParseInstallation extends ParseObject { Future> getSubscribedChannels() async { print('getSubscribedChannels'); final ParseResponse apiResponse = - await ParseObject(keyClassInstallation).getObject(objectId); + await ParseObject(keyClassInstallation).getObject(objectId!); if (apiResponse.success) { final ParseObject installation = apiResponse.result; diff --git a/packages/dart/lib/src/objects/parse_merge.dart b/packages/dart/lib/src/objects/parse_merge.dart index a8184f01b..f0cfe7381 100644 --- a/packages/dart/lib/src/objects/parse_merge.dart +++ b/packages/dart/lib/src/objects/parse_merge.dart @@ -6,7 +6,7 @@ class ParseMergeTool { if (previous == null) { return values; } - String previousAction = 'Set'; + String? previousAction = 'Set'; if (previous is Map) { previousAction = previous['__op']; } @@ -32,7 +32,7 @@ class ParseMergeTool { // Add operation Merge dynamic _mergeWithPreviousAdd( - String previousAction, dynamic previous, dynamic values) { + String? previousAction, dynamic previous, dynamic values) { if (previousAction == 'Set') { if (previous is List) { return List.from(previous)..addAll(values['objects']); @@ -68,7 +68,7 @@ class ParseMergeTool { // Remove operation Merge dynamic _mergeWithPreviousRemove( - String previousAction, dynamic previous, dynamic values) { + String? previousAction, dynamic previous, dynamic values) { if (previousAction == 'Set') { return previous; } @@ -100,7 +100,7 @@ class ParseMergeTool { // Increment operation Merge dynamic _mergeWithPreviousIncrement( - String previousAction, dynamic previous, dynamic values) { + String? previousAction, dynamic previous, dynamic values) { if (previousAction == 'Set') { if (previous is num) { values['amount'] += previous; @@ -131,7 +131,7 @@ class ParseMergeTool { // AddUnique operation Merge dynamic _mergeWithPreviousAddUnique( - String previousAction, dynamic previous, dynamic values) { + String? previousAction, dynamic previous, dynamic values) { if (previousAction == 'Set') { if (previous is List) { return _applyToValueAddUnique(previous, values['objects']); @@ -164,7 +164,7 @@ class ParseMergeTool { // AddRelation operation Merge dynamic _mergeWithPreviousAddRelation( - String previousAction, dynamic previous, dynamic values) { + String? previousAction, dynamic previous, dynamic values) { if (previousAction == 'AddRelation') { if (values['objects'].length == 1) { previous['objects'].add(values['objects'].first); @@ -196,7 +196,7 @@ class ParseMergeTool { // RemoveRelation operation Merge dynamic _mergeWithPreviousRemoveRelation( - String previousAction, dynamic previous, dynamic values) { + String? previousAction, dynamic previous, dynamic values) { if (previousAction == 'RemoveRelation') { if (values['objects'].length == 1) { previous['objects'].add(values['objects'].first); diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index f9a29a55d..2c0a64ffa 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -7,7 +7,7 @@ class ParseObject extends ParseBase implements ParseCloneable { /// [bool] debug will overwrite the current default debug settings and /// [ParseHttpClient] can be overwritten to create your own HTTP Client ParseObject(String className, - {bool debug, ParseClient client, bool autoSendSessionId}) + {bool? debug, ParseClient? client, bool? autoSendSessionId}) : super() { parseClassName = className; _path = '$keyEndPointClasses$className'; @@ -27,13 +27,13 @@ class ParseObject extends ParseBase implements ParseCloneable { dynamic clone(Map map) => ParseObject.clone(parseClassName)..fromJson(map); - /*late*/String/*!*/ _path; - /*late*/String/*!*/ _aggregatepath; - bool _debug; - /*late*/ParseClient/*!*/ _client; + late String _path; + late String _aggregatepath; + late bool _debug; + late ParseClient _client; /// Gets an object from the server using it's [String] objectId - Future getObject(String/*!*/ objectId) async { + Future getObject(String objectId) async { try { final String uri = '$_path/$objectId'; final Uri url = getSanitisedUri(_client, uri); @@ -77,7 +77,7 @@ class ParseObject extends ParseBase implements ParseCloneable { } } - Future update() async { + Future update() async { try { final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final String body = json.encode(toJson(forApiRQ: true)); @@ -95,10 +95,10 @@ class ParseObject extends ParseBase implements ParseCloneable { } /// Saves the current object online - Future save() async { + Future save() async { final ParseResponse childrenResponse = await _saveChildren(this); if (childrenResponse.success) { - ParseResponse response; + ParseResponse? response; if (objectId == null) { response = await create(); } else if (_isDirty(false)) { @@ -172,10 +172,10 @@ class ParseObject extends ParseBase implements ParseCloneable { final ParseResponse response = await batchRequest(requests, chunk); totalResponse.success &= response.success; if (response.success) { - totalResponse.results.addAll(response.results); + totalResponse.results!.addAll(response.results!); totalResponse.count += response.count; for (int i = 0; i < response.count; i++) { - if (response.results[i] is ParseError) { + if (response.results![i] is ParseError) { // Batch request succeed, but part of batch failed. chunk[i]._revertSavingChanges(); } else { @@ -409,7 +409,7 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Can be used to create custom queries Future query(String query, - {ProgressCallback progressCallback}) async { + {ProgressCallback? progressCallback}) async { try { final Uri url = getSanitisedUri(_client, '$_path', query: query); final ParseNetworkResponse result = await _client.get( @@ -436,7 +436,7 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Deletes the current object locally and online Future delete( - {String id, String path}) async { + {String? id, String? path}) async { try { path ??= _path; id ??= objectId; diff --git a/packages/dart/lib/src/objects/parse_relation.dart b/packages/dart/lib/src/objects/parse_relation.dart index 2632be791..048f78123 100644 --- a/packages/dart/lib/src/objects/parse_relation.dart +++ b/packages/dart/lib/src/objects/parse_relation.dart @@ -2,33 +2,33 @@ part of flutter_parse_sdk; // ignore_for_file: always_specify_types class ParseRelation { - ParseRelation({ParseObject parent, String key}) { + ParseRelation({ParseObject? parent, String? key}) { _parent = parent; _key = key; } - String _targetClass; - ParseObject _parent; - String _key; - Set _objects = Set(); + String? _targetClass; + ParseObject? _parent; + String? _key; + Set? _objects = Set(); QueryBuilder getQuery() { - return QueryBuilder(ParseObject(_targetClass)); + return QueryBuilder(ParseObject(_targetClass!)); } void add(T object) { _targetClass = object.parseClassName; - _objects.add(object); - _parent?.addRelation(_key, _objects.toList()); + _objects!.add(object); + _parent?.addRelation(_key!, _objects!.toList()); } void remove(T object) { _targetClass = object.parseClassName; - _objects.remove(object); - _parent?.removeRelation(_key, _objects.toList()); + _objects!.remove(object); + _parent?.removeRelation(_key!, _objects!.toList()); } - Map toJson() => { + Map toJson() => { '__type': keyRelation, 'className': _objects?.first.parseClassName, 'objects': parseEncode(_objects?.toList()) diff --git a/packages/dart/lib/src/objects/parse_response.dart b/packages/dart/lib/src/objects/parse_response.dart index f27ebd2da..7806efdc0 100644 --- a/packages/dart/lib/src/objects/parse_response.dart +++ b/packages/dart/lib/src/objects/parse_response.dart @@ -2,7 +2,7 @@ part of flutter_parse_sdk; class ParseResponse { bool success = false; - int/*!*/ statusCode = -1; + int statusCode = -1; /// If result is a singular result, i.e. getByObjectID /// @@ -12,7 +12,7 @@ class ParseResponse { /// All results stored as a list - Even if only one response is returned // ignore: always_specify_types - List results; - int/*!*/ count = 0; - ParseError/*?*/ error; + List? results; + int count = 0; + ParseError? error; } diff --git a/packages/dart/lib/src/objects/parse_session.dart b/packages/dart/lib/src/objects/parse_session.dart index 369a94024..2be307542 100644 --- a/packages/dart/lib/src/objects/parse_session.dart +++ b/packages/dart/lib/src/objects/parse_session.dart @@ -2,8 +2,8 @@ part of flutter_parse_sdk; class ParseSession extends ParseObject implements ParseCloneable { ParseSession({ - bool debug, - ParseClient client, + bool? debug, + ParseClient? client, }) : super( keyClassSession, client: client, @@ -15,18 +15,18 @@ class ParseSession extends ParseObject implements ParseCloneable { return fromJson(map); } - String/*!*/ get sessionToken => super.get(keyVarSessionToken); + String get sessionToken => super.get(keyVarSessionToken)!; - ParseObject/*!*/ get user => super.get(keyVarUser); + ParseObject get user => super.get(keyVarUser)!; - Map/*!*/ get createdWith => - super.get>(keyVarCreatedWith); + Map get createdWith => + super.get>(keyVarCreatedWith)!; - bool/*!*/ get restricted => super.get(keyVarRestricted); + bool get restricted => super.get(keyVarRestricted)!; - DateTime/*!*/ get expiresAt => super.get(keyVarExpiresAt); + DateTime get expiresAt => super.get(keyVarExpiresAt)!; - String/*!*/ get installationId => super.get(keyVarInstallationId); + String get installationId => super.get(keyVarInstallationId)!; set installationId(String installationId) => set(keyVarInstallationId, installationId); diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 4884fddc4..5fba17a8d 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -12,12 +12,12 @@ class ParseUser extends ParseObject implements ParseCloneable { /// is required as well to create a full new user object on ParseServer. Only /// username and password is required to login ParseUser( - String username, - String password, - String emailAddress, { - String sessionToken, - bool debug, - ParseClient client, + String? username, + String? password, + String? emailAddress, { + String? sessionToken, + bool? debug, + ParseClient? client, }) : super( keyClassUser, client: client, @@ -44,11 +44,11 @@ class ParseUser extends ParseObject implements ParseCloneable { static const String keyEmailAddress = 'email'; static const String path = '$keyEndPointClasses$keyClassUser'; - String _password; + String? _password; - String get password => _password; + String? get password => _password; - set password(String password) { + set password(String? password) { if (_password != password) { _password = password; if (password != null) @@ -56,39 +56,39 @@ class ParseUser extends ParseObject implements ParseCloneable { } } - Map/*!*/ get acl => super - .get>(keyVarAcl, defaultValue: {}); + Map get acl => super + .get>(keyVarAcl, defaultValue: {})!; set acl(Map acl) => set>(keyVarAcl, acl); - bool get emailVerified => super.get(keyEmailVerified); + bool? get emailVerified => super.get(keyEmailVerified); - set emailVerified(bool emailVerified) => - set(keyEmailVerified, emailVerified); + set emailVerified(bool? emailVerified) => + set(keyEmailVerified, emailVerified); - String get username => super.get(keyVarUsername); + String? get username => super.get(keyVarUsername); - set username(String username) => set(keyVarUsername, username); + set username(String? username) => set(keyVarUsername, username); - String get emailAddress => super.get(keyVarEmail); + String? get emailAddress => super.get(keyVarEmail); - set emailAddress(String emailAddress) => - set(keyVarEmail, emailAddress); + set emailAddress(String? emailAddress) => + set(keyVarEmail, emailAddress); - String get sessionToken => super.get(keyVarSessionToken); + String? get sessionToken => super.get(keyVarSessionToken); - set sessionToken(String sessionToken) => - set(keyVarSessionToken, sessionToken); + set sessionToken(String? sessionToken) => + set(keyVarSessionToken, sessionToken); - Map get authData => + Map? get authData => super.get>(keyVarAuthData); - set authData(Map authData) => - set>(keyVarAuthData, authData); + set authData(Map? authData) => + set?>(keyVarAuthData, authData); static ParseUser createUser( - [String username, String password, String emailAddress]) { + [String? username, String? password, String? emailAddress]) { return ParseCoreData.instance .createParseUser(username, password, emailAddress); } @@ -100,8 +100,8 @@ class ParseUser extends ParseObject implements ParseCloneable { /// returned. /// /// NOTE: If using custom ParseUserObject create instance and user [getUpdatedUser] - static Future getCurrentUserFromServer(String token, - {bool debug, ParseClient client}) async { + static Future getCurrentUserFromServer(String token, + {bool? debug, ParseClient? client}) async { final ParseUser user = _getEmptyUser(); user.sessionToken = token; return user.getUpdatedUser(debug: debug, client: client); @@ -111,7 +111,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// /// Uses token to get the latest version of the user. Prefer this to [getCurrentUserFromServer] /// if using custom ParseUser object - Future getUpdatedUser({bool debug, ParseClient client}) async { + Future getUpdatedUser({bool? debug, ParseClient? client}) async { final bool _debug = isDebugEnabled(objectLevelDebug: debug); final ParseClient _client = client ?? ParseCoreData().clientCreator( @@ -123,9 +123,9 @@ class ParseUser extends ParseObject implements ParseCloneable { return null; } - final Map headers = {}; + final Map headers = {}; if (sessionToken != null) { - headers[keyHeaderSessionToken] = sessionToken; + headers[keyHeaderSessionToken] = sessionToken!; } try { @@ -146,7 +146,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Current user is stored locally, but in case of a server update [bool] /// fromServer can be called and an updated version of the [User] object will be /// returned - static Future currentUser({ParseCloneable customUserObject}) async { + static Future currentUser({ParseCloneable? customUserObject}) async { if (customUserObject != null) { return await _getUserFromLocalStore(cloneable: customUserObject); } else { @@ -187,7 +187,7 @@ class ParseUser extends ParseObject implements ParseCloneable { final Uri url = getSanitisedUri(_client, '$path'); final String body = json.encode(toJson(forApiRQ: true)); _saveChanges(); - final String installationId = await _getInstallationId(); + final String? installationId = await _getInstallationId(); final ParseNetworkResponse response = await _client.post(url.toString(), options: ParseNetworkOptions(headers: { keyHeaderRevocableSession: '1', @@ -213,11 +213,11 @@ class ParseUser extends ParseObject implements ParseCloneable { forgetLocalSession(); try { - final Map queryParams = { - keyVarUsername: username, - keyVarPassword: password + final Map queryParams = { + keyVarUsername: username!, + keyVarPassword: password! }; - final String installationId = await _getInstallationId(); + final String? installationId = await _getInstallationId(); final Uri url = getSanitisedUri(_client, '$keyEndPointLogin'); _saveChanges(); final ParseNetworkResponse response = await _client.post( @@ -246,7 +246,7 @@ class ParseUser extends ParseObject implements ParseCloneable { try { final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); const Uuid uuid = Uuid(); - final String installationId = await _getInstallationId(); + final String? installationId = await _getInstallationId(); final ParseNetworkResponse response = await _client.post( url.toString(), @@ -274,7 +274,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Set [doNotSendInstallationID] to 'true' in order to prevent the SDK from sending the installationID to the Server. /// This option is especially useful if you are running you application on web and you don't have permission to add 'X-Parse-Installation-Id' as an allowed header on your parse-server. static Future loginWith(String provider, Object authData, - {bool doNotSendInstallationID = false, String username, String password, String email}) async { + {bool doNotSendInstallationID = false, String? username, String? password, String? email}) async { final ParseUser user = ParseUser.createUser(username, password, email); final ParseResponse response = await user._loginWith(provider, authData, doNotSendInstallationID: doNotSendInstallationID); @@ -287,7 +287,7 @@ class ParseUser extends ParseObject implements ParseCloneable { {bool doNotSendInstallationID = false}) async { try { final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); - final String installationId = await _getInstallationId(); + final String? installationId = await _getInstallationId(); final Map body = toJson(forApiRQ: true); body['authData'] = {provider: authData}; final ParseNetworkResponse response = await _client.post( @@ -311,7 +311,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// server. Will also delete the local user data unless /// deleteLocalUserData is false. Future logout({bool deleteLocalUserData = true}) async { - final String/*!*/ sessionId = ParseCoreData().sessionId; + final String sessionId = ParseCoreData().sessionId!; forgetLocalSession(); @@ -409,7 +409,7 @@ class ParseUser extends ParseObject implements ParseCloneable { } /// Removes a user from Parse Server locally and online - Future destroy() async { + Future destroy() async { if (objectId != null) { try { final Uri url = getSanitisedUri(_client, '$_path/$objectId'); @@ -426,7 +426,7 @@ class ParseUser extends ParseObject implements ParseCloneable { } /// Gets a list of all users (limited return) - static Future all({bool debug, ParseClient client}) async { + static Future all({bool? debug, ParseClient? client}) async { final ParseUser emptyUser = _getEmptyUser(); final bool _debug = isDebugEnabled(objectLevelDebug: debug); @@ -447,12 +447,12 @@ class ParseUser extends ParseObject implements ParseCloneable { } static Future _getUserFromLocalStore( - {ParseCloneable cloneable}) async { + {ParseCloneable? cloneable}) async { final CoreStore coreStore = ParseCoreData().getStore(); - final String userJson = await coreStore.getString(keyParseStoreUser); + final String? userJson = await coreStore.getString(keyParseStoreUser); if (userJson != null) { - final Map/*!*/ userMap = json.decode(userJson); + final Map userMap = json.decode(userJson); if (cloneable != null) { return cloneable.clone(userMap); } else { @@ -477,7 +477,7 @@ class ParseUser extends ParseObject implements ParseCloneable { final Map responseData = jsonDecode(response.data); if (responseData.containsKey(keyVarObjectId)) { user.sessionToken = responseData[keyParamSessionToken]; - ParseCoreData().setSessionId(user.sessionToken); + ParseCoreData().setSessionId(user.sessionToken!); } if ((parseResponse.statusCode != 200 && parseResponse.statusCode != 201) || @@ -497,7 +497,7 @@ class ParseUser extends ParseObject implements ParseCloneable { static ParseUser _getEmptyUser() => ParseCoreData.instance.createParseUser(null, null, null); - static Future _getInstallationId() async { + static Future _getInstallationId() async { final ParseInstallation parseInstallation = await ParseInstallation.currentInstallation(); return parseInstallation.installationId; diff --git a/packages/dart/lib/src/objects/response/parse_response_builder.dart b/packages/dart/lib/src/objects/response/parse_response_builder.dart index 88172b8aa..dec3e91b9 100644 --- a/packages/dart/lib/src/objects/response/parse_response_builder.dart +++ b/packages/dart/lib/src/objects/response/parse_response_builder.dart @@ -61,26 +61,26 @@ class _ParseResponseBuilder { final dynamic result = json.decode(responseBody); if (type == ParseApiRQ.batch) { - final List list = result; - if (object is List && object.length == list.length) { + final List? list = result; + if (object is List && object.length == list!.length) { response.count = object.length; response.results = []; for (int i = 0; i < object.length; i++) { final Map objectResult = list[i]; if (objectResult.containsKey('success')) { - final T item = _handleSingleResult( + final T? item = _handleSingleResult( object[i], objectResult['success'], false); - response.results.add(item); + response.results!.add(item); } else { final ParseError error = ParseError( code: objectResult[keyCode], message: objectResult[keyError].toString()); - response.results.add(error); + response.results!.add(error); } } } } else if (result is Map) { - final Map map = result; + final Map map = result as Map; if (object is Parse) { response.result = map; } else if (map != null && map.length == 1 && map.containsKey('results')) { @@ -90,21 +90,21 @@ class _ParseResponseBuilder { response.result = results; response.count = results.length; } else { - final List items = _handleMultipleResults(object, results); + final List items = _handleMultipleResults(object, results); response.results = items; response.result = items; response.count = items.length; } } else if (map != null && map.length == 2 && map.containsKey('count')) { - final List results = [map['count']]; + final List results = [map['count']]; response.results = results; response.result = results; response.count = map['count']; } else { - final T item = _handleSingleResult(object, map, false); + final T? item = _handleSingleResult(object, map, false); response.count = 1; response.result = item; - response.results = [item]; + response.results = [item]; } } @@ -112,17 +112,17 @@ class _ParseResponseBuilder { } /// Handles a response with a multiple result object - List _handleMultipleResults(T/*!*/ object, List data) { - final List resultsList = []; + List _handleMultipleResults(T object, List data) { + final List resultsList = []; for (dynamic value in data) { - resultsList.add(_handleSingleResult(object, value, true)); + resultsList.add(_handleSingleResult(object, value, true)!); } return resultsList; } /// Handles a response with a single result object - T _handleSingleResult( - T/*!*/ object, Map/*!*/ map, bool createNewObject) { + T? _handleSingleResult( + T object, Map map, bool createNewObject) { if (createNewObject && object is ParseCloneable) { return object.clone(map); } else if (object is ParseObject) { diff --git a/packages/dart/lib/src/objects/response/parse_response_utils.dart b/packages/dart/lib/src/objects/response/parse_response_utils.dart index 0be1cbefa..f125c321a 100644 --- a/packages/dart/lib/src/objects/response/parse_response_utils.dart +++ b/packages/dart/lib/src/objects/response/parse_response_utils.dart @@ -51,7 +51,7 @@ bool isUnsuccessfulResponse(ParseNetworkResponse apiResponse) => bool isSuccessButNoResults(ParseNetworkResponse apiResponse) { final dynamic decodedResponse = jsonDecode(apiResponse.data); - List results; + List? results; if (decodedResponse is Map) { results = decodedResponse['results']; } else if (decodedResponse is List) { diff --git a/packages/dart/lib/src/storage/core_store.dart b/packages/dart/lib/src/storage/core_store.dart index e4cc64648..5b06c2d2f 100644 --- a/packages/dart/lib/src/storage/core_store.dart +++ b/packages/dart/lib/src/storage/core_store.dart @@ -5,15 +5,15 @@ abstract class CoreStore { Future get(String key); - Future getBool(String key); + Future getBool(String key); - Future getInt(String key); + Future getInt(String key); - Future getDouble(String key); + Future getDouble(String key); - Future getString(String key); + Future getString(String key); - Future> getStringList(String key); + Future?> getStringList(String key); Future setBool(String key, bool value); @@ -21,11 +21,11 @@ abstract class CoreStore { Future setDouble(String key, double value); - Future setString(String/*!*/ key, String value); + Future setString(String key, String value); Future setStringList(String key, List values); - Future remove(String/*!*/ key); + Future remove(String key); Future clear(); } diff --git a/packages/dart/lib/src/storage/core_store_memory.dart b/packages/dart/lib/src/storage/core_store_memory.dart index 238c2ffd0..b35c10322 100644 --- a/packages/dart/lib/src/storage/core_store_memory.dart +++ b/packages/dart/lib/src/storage/core_store_memory.dart @@ -19,27 +19,27 @@ class CoreStoreMemoryImp implements CoreStore { } @override - Future getBool(String key) async { + Future getBool(String key) async { return _data[key]; } @override - Future getDouble(String key) async { + Future getDouble(String key) async { return _data[key]; } @override - Future getInt(String key) async { + Future getInt(String key) async { return _data[key]; } @override - Future getString(String key) async { + Future getString(String key) async { return _data[key]; } @override - Future> getStringList(String key) async { + Future?> getStringList(String key) async { return _data[key]; } diff --git a/packages/dart/lib/src/storage/core_store_sem_impl.dart b/packages/dart/lib/src/storage/core_store_sem_impl.dart index 2971507cd..3aa39bd83 100644 --- a/packages/dart/lib/src/storage/core_store_sem_impl.dart +++ b/packages/dart/lib/src/storage/core_store_sem_impl.dart @@ -4,10 +4,10 @@ part of flutter_parse_sdk; class CoreStoreSembastImp implements CoreStore { CoreStoreSembastImp._internal(this._database, this._store); - static CoreStoreSembastImp _instance; + static CoreStoreSembastImp? _instance; - static Future getInstance(String dbPath, - {DatabaseFactory factory, String password = 'flutter_sdk'}) async { + static Future getInstance(String dbPath, + {DatabaseFactory? factory, String password = 'flutter_sdk'}) async { if (_instance == null) { factory ??= !parseIsWeb ? databaseFactoryIo : databaseFactoryWeb; assert(() { @@ -35,15 +35,15 @@ class CoreStoreSembastImp implements CoreStore { CoreStoreSembastImp._internal(db, StoreRef.main()); } - return _instance; + return _instance!; } final Database _database; final StoreRef _store; @override - Future clear() { - return _store.drop(_database); + Future clear() { + return _store.drop(_database) as Future; } @override @@ -57,32 +57,32 @@ class CoreStoreSembastImp implements CoreStore { } @override - Future getBool(String key) async { - final bool storedItem = await get(key); + Future getBool(String key) async { + final bool? storedItem = await (get(key) as FutureOr); return storedItem; } @override - Future getDouble(String key) async { - final double storedItem = await get(key); + Future getDouble(String key) async { + final double? storedItem = await (get(key) as FutureOr); return storedItem; } @override - Future getInt(String key) async { - final int storedItem = await get(key); + Future getInt(String key) async { + final int? storedItem = await (get(key) as FutureOr); return storedItem; } @override - Future getString(String key) async { - final String storedItem = await get(key); + Future getString(String key) async { + final String? storedItem = await (get(key) as FutureOr); return storedItem; } @override - Future> getStringList(String key) async { - final List storedItem = await get(key); + Future?> getStringList(String key) async { + final List? storedItem = await (get(key) as FutureOr?>); return storedItem; } diff --git a/packages/dart/lib/src/storage/xxtea_codec.dart b/packages/dart/lib/src/storage/xxtea_codec.dart index 06ecd3abf..11753cf01 100644 --- a/packages/dart/lib/src/storage/xxtea_codec.dart +++ b/packages/dart/lib/src/storage/xxtea_codec.dart @@ -6,8 +6,8 @@ class _XXTeaEncoder extends Converter, String> { final String key; @override - String/*!*/ convert(Map input) => - xxtea.encryptToString(json.encode(input), key); + String convert(Map input) => + xxtea.encryptToString(json.encode(input), key)!; } class _XXTeaDecoder extends Converter> { @@ -17,7 +17,7 @@ class _XXTeaDecoder extends Converter> { @override Map convert(String input) { - final dynamic result = json.decode(xxtea.decryptToString(input, key)); + final dynamic result = json.decode(xxtea.decryptToString(input, key)!); if (result is Map) { return result.cast(); } @@ -34,8 +34,8 @@ class _XXTeaCodec extends Codec, String> { _decoder = _XXTeaDecoder(password); } - _XXTeaEncoder _encoder; - _XXTeaDecoder _decoder; + late _XXTeaEncoder _encoder; + late _XXTeaDecoder _decoder; @override Converter> get decoder => _decoder; @@ -56,5 +56,5 @@ class _XXTeaCodec extends Codec, String> { /// /// // ...your database is ready to use as encrypted /// ``` -SembastCodec getXXTeaSembastCodec({@required String password}) => +SembastCodec getXXTeaSembastCodec({required String password}) => SembastCodec(signature: 'xxtea', codec: _XXTeaCodec(password)); diff --git a/packages/dart/lib/src/utils/parse_date_format.dart b/packages/dart/lib/src/utils/parse_date_format.dart index c025878d7..427829357 100644 --- a/packages/dart/lib/src/utils/parse_date_format.dart +++ b/packages/dart/lib/src/utils/parse_date_format.dart @@ -7,7 +7,7 @@ class _ParseDateFormat { _ParseDateFormat._internal(); /// Deserialize an ISO-8601 full-precision extended format representation of date string into [DateTime]. - DateTime parse(String strDate) { + DateTime? parse(String strDate) { try { return DateTime.parse(strDate); } on FormatException { diff --git a/packages/dart/lib/src/utils/parse_decoder.dart b/packages/dart/lib/src/utils/parse_decoder.dart index f2d0d929e..a49c92e1f 100644 --- a/packages/dart/lib/src/utils/parse_decoder.dart +++ b/packages/dart/lib/src/utils/parse_decoder.dart @@ -42,7 +42,7 @@ dynamic parseDecode(dynamic value) { return value; } - final Map map = value; + final Map map = value as Map; if (!map.containsKey('__type') && !map.containsKey('className')) { return _convertJSONObjectToMap(map); diff --git a/packages/dart/lib/src/utils/parse_encoder.dart b/packages/dart/lib/src/utils/parse_encoder.dart index 30c924e73..66ff7d558 100644 --- a/packages/dart/lib/src/utils/parse_encoder.dart +++ b/packages/dart/lib/src/utils/parse_encoder.dart @@ -68,7 +68,7 @@ Map _encodeDate(DateTime date) { }; } -Map encodeObject(String className, String/*!*/ objectId) { +Map encodeObject(String className, String objectId) { return { '__type': 'Pointer', keyVarClassName: className, diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 556f405de..4d096a245 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -3,15 +3,15 @@ part of flutter_parse_sdk; // ignore_for_file: invalid_use_of_protected_member class ParseLiveList { ParseLiveList._(this._query, this._listeningIncludes, this._lazyLoading, - {List/*!*/ preloadedColumns = const []}) + {List preloadedColumns = const []}) : _preloadedColumns = preloadedColumns { _debug = isDebugEnabled(); } static Future> create( QueryBuilder _query, { - bool listenOnAllSubItems, - List listeningIncludes, + bool? listenOnAllSubItems, + List? listeningIncludes, bool lazyLoading = true, List preloadedColumns = const [], }) { @@ -36,16 +36,16 @@ class ParseLiveList { final bool _lazyLoading; final List _preloadedColumns; - List> _list = >[]; - StreamController> _eventStreamController; + List> _list = >[]; + late StreamController> _eventStreamController; int _nextID = 0; - bool _debug; + late bool _debug; int get nextID => _nextID++; /// is object1 listed after object2? /// can return null - bool after(T object1, T object2) { + bool? after(T? object1, T? object2) { List fields = []; if (_query.limiters.containsKey('order')) { @@ -58,8 +58,8 @@ class ParseLiveList { reverse = true; key = key.substring(1); } - final dynamic val1 = object1.get(key); - final dynamic val2 = object2.get(key); + final dynamic val1 = object1!.get(key); + final dynamic val2 = object2!.get(key); if (val1 == null && val2 == null) { break; @@ -113,7 +113,7 @@ class ParseLiveList { for (String includeString in includes) { final List pathParts = includeString.split('.'); - Map/*!*/ root = includesMap; + Map root = includesMap; for (String pathPart in pathParts) { root.putIfAbsent(pathPart, () => {}); root = root[pathPart]; @@ -124,8 +124,8 @@ class ParseLiveList { } Stream> get stream => _eventStreamController.stream; - Subscription _liveQuerySubscription; - StreamSubscription _liveQueryClientEventSubscription; + Subscription? _liveQuerySubscription; + StreamSubscription? _liveQueryClientEventSubscription; final Future _updateQueue = Future.value(); Future _runQuery() async { @@ -165,7 +165,7 @@ class ParseLiveList { LiveQuery() .client .subscribe(QueryBuilder.copy(_query), - copyObject: _query.object.clone(_query.object.toJson())) + copyObject: _query.object!.clone(_query.object!.toJson())) .then((Subscription subscription) { _liveQuerySubscription = subscription; @@ -202,13 +202,13 @@ class ParseLiveList { List> tasks = >[]; final ParseResponse parseResponse = await _runQuery(); if (parseResponse.success) { - final List newList = parseResponse.results ?? []; + final List newList = parseResponse.results as List? ?? []; //update List for (int i = 0; i < _list.length; i++) { - final ParseObject currentObject = _list[i].object; - final String/*!*/ currentObjectId = - currentObject.get(keyVarObjectId); + final ParseObject currentObject = _list[i].object!; + final String currentObjectId = + currentObject.get(keyVarObjectId)!; bool stillInList = false; @@ -216,8 +216,8 @@ class ParseLiveList { if (newList[j].get(keyVarObjectId) == currentObjectId) { stillInList = true; if (newList[j] - .get(keyVarUpdatedAt) - .isAfter(currentObject.get(keyVarUpdatedAt))) { + .get(keyVarUpdatedAt)! + .isAfter(currentObject.get(keyVarUpdatedAt)!)) { final QueryBuilder queryBuilder = QueryBuilder.copy(_query) ..whereEqualTo(keyVarObjectId, currentObjectId); @@ -225,7 +225,7 @@ class ParseLiveList { .query() .then((ParseResponse result) async { if (result.success && result.results != null) { - await _objectUpdated(result.results.first); + await _objectUpdated(result.results!.first); } })); } @@ -235,7 +235,7 @@ class ParseLiveList { } } if (!stillInList) { - _objectDeleted(currentObject); + _objectDeleted(currentObject as T); i--; } } @@ -255,8 +255,8 @@ class ParseLiveList { }); } - static Future _loadIncludes(ParseObject object, - {ParseObject oldObject, Map paths}) async { + static Future _loadIncludes(ParseObject? object, + {ParseObject? oldObject, Map? paths}) async { if (object == null || paths == null || paths.isEmpty) { return; } @@ -265,17 +265,17 @@ class ParseLiveList { for (String key in paths.keys) { if (object.containsKey(key)) { - ParseObject includedObject = object.get(key); + ParseObject includedObject = object.get(key)!; //If the object is not fetched if (!includedObject.containsKey(keyVarUpdatedAt)) { //See if oldObject contains key if (oldObject != null && oldObject.containsKey(key)) { - includedObject = oldObject.get(key); + includedObject = oldObject.get(key)!; //If the object is not fetched || the ids don't match / the pointer changed if (!includedObject.containsKey(keyVarUpdatedAt) || includedObject.objectId != - object.get(key).objectId) { - includedObject = object.get(key); + object.get(key)!.objectId) { + includedObject = object.get(key)!; //fetch from web including sub objects //same as down there final QueryBuilder queryBuilder = QueryBuilder< @@ -286,9 +286,9 @@ class ParseLiveList { .query() .then((ParseResponse parseResponse) { if (parseResponse.success && - parseResponse.results.length == 1) { + parseResponse.results!.length == 1) { // ignore: deprecated_member_use_from_same_package - object[key] = parseResponse.results[0]; + object[key] = parseResponse.results![0]; } })); continue; @@ -309,9 +309,9 @@ class ParseLiveList { ..includeObject(_toIncludeStringList(paths[key])); loadingNodes.add( queryBuilder.query().then((ParseResponse parseResponse) { - if (parseResponse.success && parseResponse.results.length == 1) { + if (parseResponse.success && parseResponse.results!.length == 1) { // ignore: deprecated_member_use_from_same_package - object[key] = parseResponse.results[0]; + object[key] = parseResponse.results![0]; } })); continue; @@ -369,9 +369,9 @@ class ParseLiveList { _list.length - 1, object.clone(object.toJson(full: true)))); } - Future _objectUpdated(T/*!*/ object) async { + Future _objectUpdated(T object) async { for (int i = 0; i < _list.length; i++) { - if (_list[i].object.get(keyVarObjectId) == + if (_list[i].object!.get(keyVarObjectId) == object.get(keyVarObjectId)) { await _loadIncludes(object, oldObject: _list[i].object, paths: _includePaths); @@ -391,7 +391,7 @@ class ParseLiveList { Future _objectDeleted(T object) async { for (int i = 0; i < _list.length; i++) { - if (_list[i].object.get(keyVarObjectId) == + if (_list[i].object!.get(keyVarObjectId) == object.get(keyVarObjectId)) { await _loadIncludes(object, oldObject: _list[i].object, paths: _includePaths); @@ -408,7 +408,7 @@ class ParseLiveList { if (!_list[index].loaded) { final QueryBuilder queryBuilder = QueryBuilder.copy(_query) ..whereEqualTo( - keyVarObjectId, _list[index].object.get(keyVarObjectId)) + keyVarObjectId, _list[index].object!.get(keyVarObjectId)) ..setLimit(1); final ParseResponse response = await queryBuilder.query(); if (_list.isEmpty) { @@ -420,41 +420,41 @@ class ParseLiveList { _list[index].object = response.results?.first; } else { _list[index].object = null; - yield* _createStreamError(response.error); + yield* _createStreamError(response.error!); return; } } // just for testing // await Future.delayed(const Duration(seconds: 2)); - yield _list[index].object; + yield _list[index].object!; yield* _list[index].stream; } } - String/*!*/ idOf(int index) { + String idOf(int index) { if (index < _list.length) { - return _list[index].object.get(keyVarObjectId); + return _list[index].object!.get(keyVarObjectId)!; } return 'NotFound'; } String getIdentifier(int index) { if (index < _list.length) { - return _list[index].object.get(keyVarObjectId) + - _list[index].object.get(keyVarUpdatedAt).toString() ?? + return _list[index].object!.get(keyVarObjectId)! + + _list[index].object!.get(keyVarUpdatedAt).toString() ?? ''; } return 'NotFound'; } - T getLoadedAt(int index) { + T? getLoadedAt(int index) { if (index < _list.length && _list[index].loaded) { return _list[index].object; } return null; } - T getPreLoadedAt(int index) { + T? getPreLoadedAt(int index) { if (index < _list.length) { return _list[index].object; } @@ -463,11 +463,11 @@ class ParseLiveList { void dispose() { if (_liveQuerySubscription != null) { - LiveQuery().client.unSubscribe(_liveQuerySubscription); + LiveQuery().client.unSubscribe(_liveQuerySubscription!); _liveQuerySubscription = null; } if (_liveQueryClientEventSubscription != null) { - _liveQueryClientEventSubscription.cancel(); + _liveQueryClientEventSubscription!.cancel(); _liveQueryClientEventSubscription = null; } while (_list.isNotEmpty) { @@ -478,7 +478,7 @@ class ParseLiveList { class ParseLiveElement extends ParseLiveListElement { ParseLiveElement(T object, - {bool loaded = false, List/*?*/ includeObject}) + {bool loaded = false, List? includeObject}) : super(object, loaded: loaded, updatedSubItems: @@ -492,12 +492,12 @@ class ParseLiveElement extends ParseLiveListElement { _init(object, loaded: loaded, includeObject: includeObject); } - Subscription _subscription; - Map _includes; - QueryBuilder queryBuilder; + Subscription? _subscription; + Map? _includes; + late QueryBuilder queryBuilder; Future _init(T object, - {bool loaded = false, List includeObject}) async { + {bool loaded = false, List? includeObject}) async { if (!loaded) { final ParseResponse parseResponse = await queryBuilder.query(); if (parseResponse.success) { @@ -509,7 +509,7 @@ class ParseLiveElement extends ParseLiveListElement { QueryBuilder.copy(queryBuilder), copyObject: object.clone({})); - _subscription.on(LiveQueryEvent.update, (T newObject) async { + _subscription!.on(LiveQueryEvent.update, (T newObject) async { await ParseLiveList._loadIncludes(newObject, oldObject: super.object, paths: _includes); super.object = newObject; @@ -536,16 +536,16 @@ class ParseLiveElement extends ParseLiveListElement { @override void dispose() { if (_subscription != null) { - LiveQuery().client.unSubscribe(_subscription); + LiveQuery().client.unSubscribe(_subscription!); _subscription = null; } super.dispose(); } } -class ParseLiveListElement { +class ParseLiveListElement { ParseLiveListElement(this._object, - {bool loaded = false, Map updatedSubItems}) { + {bool loaded = false, Map? updatedSubItems}) { if (_object != null) { _loaded = loaded; } @@ -557,16 +557,16 @@ class ParseLiveListElement { } } - final StreamController _streamController = StreamController.broadcast(); - T _object; + final StreamController _streamController = StreamController.broadcast(); + T? _object; bool _loaded = false; - Map _updatedSubItems; - LiveQuery _liveQuery; + late Map _updatedSubItems; + LiveQuery? _liveQuery; final Future _subscriptionQueue = Future.value(); Stream get stream => _streamController.stream; - T get object => _object?.clone(_object.toJson(full: true)); + T? get object => _object?.clone(_object!.toJson(full: true)); Map _toSubscriptionMap(Map map) { final Map result = Map(); @@ -589,8 +589,8 @@ class ParseLiveListElement { if (_updatedSubItems.isNotEmpty && _object != null) { final List> tasks = >[]; for (PathKey key in _updatedSubItems.keys) { - tasks.add(_subscribeSubItem(_object, key, - _object.get(key.key), _updatedSubItems[key])); + tasks.add(_subscribeSubItem(_object!, key, + _object!.get(key.key)!, _updatedSubItems[key])); } await Future.wait(tasks); } @@ -600,26 +600,26 @@ class ParseLiveListElement { void _unsubscribe(Map subscriptions) { for (PathKey key in subscriptions.keys) { if (_liveQuery != null && key.subscription != null) { - _liveQuery.client.unSubscribe(key.subscription); + _liveQuery!.client.unSubscribe(key.subscription!); key.subscription = null; } _unsubscribe(subscriptions[key]); } } - Future _subscribeSubItem(ParseObject/*!*/ parentObject, PathKey currentKey, - ParseObject/*!*/ subObject, Map/*!*/ path) async { + Future _subscribeSubItem(ParseObject parentObject, PathKey currentKey, + ParseObject subObject, Map path) async { if (_liveQuery != null) { final List> tasks = >[]; for (PathKey key in path.keys) { tasks.add(_subscribeSubItem( - subObject, key, subObject.get(key.key), path[key])); + subObject, key, subObject.get(key.key)!, path[key])); } final QueryBuilder queryBuilder = QueryBuilder(subObject) ..whereEqualTo(keyVarObjectId, subObject.objectId); - tasks.add(_liveQuery.client + tasks.add(_liveQuery!.client .subscribe(queryBuilder) .then((Subscription subscription) { currentKey.subscription = subscription; @@ -631,13 +631,13 @@ class ParseLiveListElement { parentObject[currentKey.key] = newObject; if (!_streamController.isClosed) { _streamController - .add(_object?.clone(_object.toJson(full: true))); + .add(_object?.clone(_object!.toJson(full: true))); //Resubscribe subitems // TODO(any): only resubscribe on changed pointers _unsubscribe(path); for (PathKey key in path.keys) { tasks.add(_subscribeSubItem(newObject, key, - newObject.get(key.key), path[key])); + newObject.get(key.key)!, path[key])); } } await Future.wait(tasks); @@ -648,12 +648,12 @@ class ParseLiveListElement { } } - set object(T value) { + set object(T? value) { _loaded = true; _object = value; _unsubscribe(_updatedSubItems); _subscribe(); - _streamController.add(_object?.clone(_object.toJson(full: true))); + _streamController.add(_object?.clone(_object!.toJson(full: true))); } bool get loaded => _loaded; @@ -666,7 +666,7 @@ class ParseLiveListElement { Future reconnected() async { if (loaded) { _subscriptionQueue.whenComplete(() async { - await _updateSubItems(_object, _updatedSubItems); + await _updateSubItems(_object!, _updatedSubItems); // _streamController.add(_object?.clone(_object.toJson(full: true))); }); } @@ -683,10 +683,10 @@ class ParseLiveListElement { } Future _updateSubItems( - ParseObject/*!*/ root, Map path) async { + ParseObject root, Map path) async { final List> tasks = >[]; for (PathKey key in path.keys) { - ParseObject/*!*/ subObject = root.get(key.key); + ParseObject subObject = root.get(key.key)!; if (subObject.containsKey(keyVarUpdatedAt) == true) { final QueryBuilder queryBuilder = QueryBuilder(subObject) @@ -694,7 +694,7 @@ class ParseLiveListElement { ..whereEqualTo(keyVarObjectId, subObject.objectId); final ParseResponse parseResponse = await queryBuilder.query(); if (parseResponse.success && - parseResponse.results.first.updatedAt != subObject.updatedAt) { + parseResponse.results!.first.updatedAt != subObject.updatedAt) { queryBuilder.limiters.remove('keys'); queryBuilder.includeObject(_getIncludeList(path[key])); final ParseResponse parseResponse = await queryBuilder.query(); @@ -703,7 +703,7 @@ class ParseLiveListElement { // root.getObjectData()[key.key] = subObject; if (key.subscription?.eventCallbacks.containsKey('update') == true) { - key.subscription.eventCallbacks['update'](subObject); + key.subscription!.eventCallbacks['update']!(subObject); } // key.subscription.eventCallbacks["update"](subObject); break; @@ -720,7 +720,7 @@ class PathKey { PathKey(this.key, {this.subscription}); final String key; - Subscription subscription; + Subscription? subscription; @override String toString() { return 'PathKey(key: $key, subscription: ${subscription?.requestId})'; @@ -755,10 +755,10 @@ class ParseLiveListElementSnapshot { ParseLiveListElementSnapshot( {this.loadedData, this.error, this.preLoadedData}); - final T loadedData; - final T preLoadedData; + final T? loadedData; + final T? preLoadedData; - final ParseError error; + final ParseError? error; bool get hasData => loadedData != null; diff --git a/packages/dart/lib/src/utils/parse_logger.dart b/packages/dart/lib/src/utils/parse_logger.dart index 976492463..0e3f507f5 100644 --- a/packages/dart/lib/src/utils/parse_logger.dart +++ b/packages/dart/lib/src/utils/parse_logger.dart @@ -17,13 +17,13 @@ void logAPIResponse( responseString += '\nReponse: OK'; } } else if (!parseResponse.success) { - responseString += '\nStatus Code: ${parseResponse.error.code}'; - responseString += '\nType: ${parseResponse.error.type}'; + responseString += '\nStatus Code: ${parseResponse.error!.code}'; + responseString += '\nType: ${parseResponse.error!.type}'; final String errorOrException = - parseResponse.error.exception != null ? 'Exception' : 'Error'; + parseResponse.error!.exception != null ? 'Exception' : 'Error'; - responseString += '\n$errorOrException: ${parseResponse.error.message}'; + responseString += '\n$errorOrException: ${parseResponse.error!.message}'; } responseString += '\nâ•°-- \n'; @@ -32,7 +32,7 @@ void logAPIResponse( } void logRequest( - String appName, String className, String type, String uri, String body) { + String? appName, String className, String type, String uri, String body) { String requestString = ' \n'; final String name = appName != null ? '$appName ' : ''; requestString += '----\n${name}API Request ($className : $type) :'; diff --git a/packages/dart/lib/src/utils/parse_utils.dart b/packages/dart/lib/src/utils/parse_utils.dart index 4dd749d2d..39bff368f 100644 --- a/packages/dart/lib/src/utils/parse_utils.dart +++ b/packages/dart/lib/src/utils/parse_utils.dart @@ -4,7 +4,7 @@ part of flutter_parse_sdk; /// /// Debug can be set in 2 places, one global param in the Parse.initialize, and /// then can be overwritten class by class -bool isDebugEnabled({bool objectLevelDebug}) { +bool isDebugEnabled({bool? objectLevelDebug}) { return objectLevelDebug ?? ParseCoreData().debug; } @@ -25,7 +25,7 @@ dynamic convertValueToCorrectType(dynamic value) { /// Sanitises a url Uri getSanitisedUri(ParseClient client, String pathToAppend, - {Map queryParams, String query}) { + {Map? queryParams, String? query}) { final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); final Uri url = Uri( @@ -41,7 +41,7 @@ Uri getSanitisedUri(ParseClient client, String pathToAppend, /// Sanitises a url Uri getCustomUri(ParseClient client, String path, - {Map queryParams, String query}) { + {Map? queryParams, String? query}) { final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); final Uri url = Uri( @@ -67,7 +67,7 @@ String removeTrailingSlash(String serverUrl) { Future batchRequest( List requests, List objects, - {ParseClient client, bool debug}) async { + {ParseClient? client, bool? debug}) async { debug = isDebugEnabled(objectLevelDebug: debug); client = client ?? ParseCoreData().clientCreator( @@ -86,6 +86,6 @@ Future batchRequest( } } -Stream _createStreamError(Object/*!*/ error) async* { +Stream _createStreamError(Object error) async* { throw error; } diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index e838fec44..6774e1314 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -4,7 +4,7 @@ version: 3.0.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: - sdk: '>=2.7.0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: diff --git a/packages/dart/test/parse_query_test.dart b/packages/dart/test/parse_query_test.dart index 56c9e0422..ca49b3995 100644 --- a/packages/dart/test/parse_query_test.dart +++ b/packages/dart/test/parse_query_test.dart @@ -31,7 +31,7 @@ void main() { await queryBuilder.query(); final Uri result = - Uri.parse(verify(client.get(captureAny)).captured.single); + Uri.parse(verify(client.get(captureAny!)).captured.single); expect(result.path, '/classes/_User'); From 3bd68f37e67db8f77805602fa2bdf5a0368024bc Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:34:38 +0100 Subject: [PATCH 112/195] Adapt Readme with input from @RodrigoSMarques --- packages/flutter/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/flutter/README.md b/packages/flutter/README.md index b4ff272bf..ebaeca3dd 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -58,8 +58,6 @@ Due to Cross-origin resource sharing (CORS) restrictions, this requires adding ` When running directly via docker, set the env var `PARSE_SERVER_ALLOW_HEADERS=X-Parse-Installation-Id`. When running via express, set [ParseServerOptions](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html) `allowHeaders: ['X-Parse-Installation-Id']`. -Be aware that for web ParseInstallation does include app name, version or package identifier automatically. You should manually provide this data as described [here](https://github.com/parse-community/Parse-SDK-Flutter/blob/master/docs/migrate-1-0-28.md#optional-provide-app-information-on-web); - #### Network client By default, this SDK uses the `ParseHTTPClient`. Another option is use `ParseDioClient`. This client supports the most features (for example a progress callback at the file upload), but a benchmark has shown, that dio is slower than http on web. @@ -69,7 +67,7 @@ you can provide a custom `ParseClientCreator` at the initialization of the SDK. ```dart await Parse().initialize( //... - clientCreator: ({bool sendSessionId, SecurityContext securityContext}) => ParseDioClient(sendSessionId: sendSessionId, securityContext: securityContext), + clientCreator: ({bool? sendSessionId, SecurityContext? securityContext}) => ParseDioClient(sendSessionId: sendSessionId, securityContext: securityContext), ); ``` From ec147a79d284ad780fbc2021f89f793bd65de165 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 02:44:23 +0100 Subject: [PATCH 113/195] flutter: Upgrade dependencies for null-safety --- packages/flutter/pubspec.yaml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 4804594ca..a1cddb61d 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk_flutter description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 2.1.0 +version: 3.0.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: @@ -11,26 +11,27 @@ dependencies: sdk: flutter parse_server_sdk: - git: - url: git://github.com/parse-community/Parse-SDK-Flutter.git - ref: development - path: packages/dart + path: ../dart +# git: +# url: git://github.com/parse-community/Parse-SDK-Flutter.git +# ref: development +# path: packages/dart # Networking - dio: ^3.0.10 - connectivity: ^2.0.2 # only used in the flutter part + dio: ^4.0.0-prev2 + connectivity: ^3.0.3 # only used in the flutter part #Database - shared_preferences: ^0.5.12+4 # only used in the flutter part + shared_preferences: ^2.0.5 # only used in the flutter part # Utils - path_provider: ^1.6.27 # only used in the flutter part - package_info: ^0.4.3+4 # only used in the flutter part - sembast: ^2.4.9 # required for transitive use only - path: ^1.7.0 # required for transitive use only + path_provider: ^2.0.1 # only used in the flutter part + package_info_plus: ^1.0.0 # only used in the flutter part + sembast: ^3.0.0+4 # required for transitive use only + path: ^1.8.0 # required for transitive use only dev_dependencies: # Testing flutter_test: sdk: flutter - mockito: ^4.1.4 + mockito: ^5.0.2 \ No newline at end of file From 66fd83d3c2792bf3b28c60700edc756ad4460ca4 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 12:38:58 +0100 Subject: [PATCH 114/195] flutter: Upgrade example dependecies --- packages/flutter/example/pubspec.yaml | 44 +++++-------------- .../flutter/example_livelist/pubspec.yaml | 31 +++---------- 2 files changed, 17 insertions(+), 58 deletions(-) diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index df572b618..3a0b0179d 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,52 +1,30 @@ name: flutter_plugin_example description: Demonstrates how to use the flutter_plugin plugin. +publish_to: none + +environment: + sdk: ">=2.2.2 <3.0.0" dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.0 - sembast: ^2.4.8+1 - shared_preferences: ^0.5.12+4 - - path_provider: ^1.6.27 - -dev_dependencies: + cupertino_icons: ^1.0.2 parse_server_sdk_flutter: path: ../ + path_provider: ^2.0.1 + sembast: ^3.0.0+4 + shared_preferences: ^2.0.5 + +dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.3 + mockito: ^5.0.2 -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: assets: - # - images/a_dot_burr.jpeg - assets/parse.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: fonts: - family: Roboto fonts: diff --git a/packages/flutter/example_livelist/pubspec.yaml b/packages/flutter/example_livelist/pubspec.yaml index 339842141..028b56a05 100644 --- a/packages/flutter/example_livelist/pubspec.yaml +++ b/packages/flutter/example_livelist/pubspec.yaml @@ -1,48 +1,29 @@ name: flutterpluginexample_livelist description: A simple example for using ParseLiveQuery. +publish_to: none version: 1.0.0+1 +environment: + sdk: ">=2.2.2 <3.0.0" + dependencies: flutter: sdk: flutter parse_server_sdk_flutter: path: ../ - cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec + mockito: ^5.0.2 -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: assets: - # - images/a_dot_burr.jpeg - assets/parse.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: fonts: - family: Roboto fonts: From c8b9a34548da5dcba0065f93d1a93a988a5f3375 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 12:42:37 +0100 Subject: [PATCH 115/195] flutter: Switch to package_info_plus --- packages/flutter/lib/parse_server_sdk.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 7f934f5bd..c60f09e69 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -7,7 +7,7 @@ import 'dart:ui' as ui; import 'package:connectivity/connectivity.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:package_info/package_info.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:parse_server_sdk/parse_server_sdk.dart' as sdk; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; From 14194f6f6a9b0ba691c770b81fb5e558cc491dab Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 12:45:01 +0100 Subject: [PATCH 116/195] flutter(sdk): Return parent class sdk.Parse class Since this is returned anyway --- packages/flutter/lib/parse_server_sdk.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index c60f09e69..107ad28e2 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -39,7 +39,7 @@ class Parse extends sdk.Parse /// [appName], [appVersion] and [appPackageName] are automatically set on Android and IOS, if they are not defined. You should provide a value on web. /// [fileDirectory] is not used on web @override - Future initialize( + Future initialize( String appId, String serverUrl, { bool debug = false, From aa89e891bcee12ccb325d02a8aa1270560effde0 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 12:50:52 +0100 Subject: [PATCH 117/195] flutter: package_info_plus has web support --- packages/flutter/lib/parse_server_sdk.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 107ad28e2..4a1359878 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -63,8 +63,7 @@ class Parse extends sdk.Parse Stream appResumedStream, sdk.ParseClientCreator clientCreator, }) async { - if (!sdk.parseIsWeb && - (appName == null || appVersion == null || appPackageName == null)) { + if (appName == null || appVersion == null || appPackageName == null) { final PackageInfo packageInfo = await PackageInfo.fromPlatform(); appName ??= packageInfo.appName; appVersion ??= packageInfo.version; From 995a11cd18d6ee7c3884400283037232f51e3d1f Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 12:53:07 +0100 Subject: [PATCH 118/195] flutter: Add correct parantheses --- packages/flutter/lib/parse_server_sdk.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 4a1359878..ddb63b970 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -77,9 +77,8 @@ class Parse extends sdk.Parse appName: appName, appVersion: appVersion, appPackageName: appPackageName, - locale: locale ?? sdk.parseIsWeb - ? ui.window.locale.toString() - : Platform.localeName, + locale: locale ?? + (sdk.parseIsWeb ? ui.window.locale.toString() : Platform.localeName), liveQueryUrl: liveQueryUrl, clientKey: clientKey, masterKey: masterKey, From e665549bf146e722e3527a149f95862007b95912 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 12:53:27 +0100 Subject: [PATCH 119/195] flutter: SharedPrefStore does not support password --- packages/flutter/lib/parse_server_sdk.dart | 3 +-- packages/flutter/lib/src/storage/core_store_sp_impl.dart | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index ddb63b970..191e46836 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -85,8 +85,7 @@ class Parse extends sdk.Parse sessionId: sessionId, autoSendSessionId: autoSendSessionId, securityContext: securityContext, - coreStore: coreStore ?? - await CoreStoreSharedPrefsImp.getInstance(password: masterKey), + coreStore: coreStore ?? await CoreStoreSharedPrefsImp.getInstance(), registeredSubClassMap: registeredSubClassMap, parseUserConstructor: parseUserConstructor, parseFileConstructor: parseFileConstructor, diff --git a/packages/flutter/lib/src/storage/core_store_sp_impl.dart b/packages/flutter/lib/src/storage/core_store_sp_impl.dart index 63f54de44..0610a52e7 100644 --- a/packages/flutter/lib/src/storage/core_store_sp_impl.dart +++ b/packages/flutter/lib/src/storage/core_store_sp_impl.dart @@ -5,8 +5,7 @@ class CoreStoreSharedPrefsImp implements sdk.CoreStore { static CoreStoreSharedPrefsImp _instance; - static Future getInstance( - {SharedPreferences store, String password = 'flutter_sdk'}) async { + static Future getInstance({SharedPreferences store}) async { if (_instance == null) { store ??= await SharedPreferences.getInstance(); _instance = CoreStoreSharedPrefsImp._internal(store); From ad4a85af89a9a513dd9d1f1f1206b9e967d49d9e Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:02:23 +0100 Subject: [PATCH 120/195] flutter: connectivity now supported on web --- packages/flutter/lib/parse_server_sdk.dart | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 191e46836..10e03352b 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -103,18 +103,16 @@ class Parse extends sdk.Parse @override Future checkConnectivity() async { - //Connectivity works differently on web - if (!sdk.parseIsWeb) { - switch (await Connectivity().checkConnectivity()) { - case ConnectivityResult.wifi: - return sdk.ParseConnectivityResult.wifi; - case ConnectivityResult.mobile: - return sdk.ParseConnectivityResult.mobile; - case ConnectivityResult.none: - return sdk.ParseConnectivityResult.none; - } + switch (await Connectivity().checkConnectivity()) { + case ConnectivityResult.wifi: + return sdk.ParseConnectivityResult.wifi; + case ConnectivityResult.mobile: + return sdk.ParseConnectivityResult.mobile; + case ConnectivityResult.none: + return sdk.ParseConnectivityResult.none; + default: + return sdk.ParseConnectivityResult.wifi; } - return sdk.ParseConnectivityResult.wifi; } @override From 8b30290b21a3763f843240c23dd6a5b126dee610 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:06:21 +0100 Subject: [PATCH 121/195] flutter: No need to provide a default password here --- packages/flutter/lib/parse_server_sdk.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 10e03352b..d44c2b81b 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -141,7 +141,7 @@ class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { static sdk.CoreStoreSembastImp _sembastImp; static Future getInstance( - {DatabaseFactory factory, String password = 'flutter_sdk'}) async { + {DatabaseFactory factory, String password}) async { if (_sembastImp == null) { String dbDirectory = ''; if (!sdk.parseIsWeb && From 23a0a43e19dbe4f9933e4448a39b38a3100e10ef Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:06:41 +0100 Subject: [PATCH 122/195] flutter: path_provider supports linux and windows --- packages/flutter/lib/parse_server_sdk.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index d44c2b81b..42663f6ee 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -145,7 +145,11 @@ class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { if (_sembastImp == null) { String dbDirectory = ''; if (!sdk.parseIsWeb && - (Platform.isIOS || Platform.isAndroid || Platform.isMacOS)) + (Platform.isIOS || + Platform.isAndroid || + Platform.isMacOS || + Platform.isLinux || + Platform.isWindows)) dbDirectory = (await getApplicationDocumentsDirectory()).path; final String dbPath = path.join('$dbDirectory/parse', 'parse.db'); _sembastImp ??= await sdk.CoreStoreSembastImp.getInstance(dbPath, From 05124cd7f30a0a0cccd3bcb674822d6c75cfe626 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:13:56 +0100 Subject: [PATCH 123/195] flutter(CoreSharedPref): Improve code --- .../lib/src/storage/core_store_sp_impl.dart | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/flutter/lib/src/storage/core_store_sp_impl.dart b/packages/flutter/lib/src/storage/core_store_sp_impl.dart index 0610a52e7..8da50fdd6 100644 --- a/packages/flutter/lib/src/storage/core_store_sp_impl.dart +++ b/packages/flutter/lib/src/storage/core_store_sp_impl.dart @@ -23,47 +23,43 @@ class CoreStoreSharedPrefsImp implements sdk.CoreStore { @override Future containsKey(String key) async { - return Future.value(_store.containsKey(key)); + return _store.containsKey(key); } @override Future get(String key) async { - return await _store.get(key); + return _store.get(key); } @override Future getBool(String key) async { - final bool storedItem = await _store.get(key); - return storedItem; + return _store.getBool(key); } @override Future getDouble(String key) async { - final double storedItem = await _store.get(key); - return storedItem; + return _store.getDouble(key); } @override Future getInt(String key) async { - final int storedItem = await _store.get(key); - return storedItem; + return _store.getInt(key); } @override Future getString(String key) async { - final String storedItem = await _store.get(key); - return storedItem; + return _store.getString(key); } @override Future> getStringList(String key) async { - final List storedItem = await _store.get(key); - return storedItem; + return _store.getStringList(key); } + @override Future remove(String key) async { - return await _store.remove(key); + return _store.remove(key); } @override From 92139913c9263de6456824e6d1b698f40ab44105 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:25:33 +0100 Subject: [PATCH 124/195] flutter(SharedPrefStore): Always returns a value --- packages/flutter/lib/src/storage/core_store_sp_impl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/storage/core_store_sp_impl.dart b/packages/flutter/lib/src/storage/core_store_sp_impl.dart index 8da50fdd6..8f0e2e3fd 100644 --- a/packages/flutter/lib/src/storage/core_store_sp_impl.dart +++ b/packages/flutter/lib/src/storage/core_store_sp_impl.dart @@ -5,7 +5,7 @@ class CoreStoreSharedPrefsImp implements sdk.CoreStore { static CoreStoreSharedPrefsImp _instance; - static Future getInstance({SharedPreferences store}) async { + static Future getInstance({SharedPreferences store}) async { if (_instance == null) { store ??= await SharedPreferences.getInstance(); _instance = CoreStoreSharedPrefsImp._internal(store); From 50dc5ed0025ec9cff7495b78aa9e3fab43300bc6 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:43:27 +0100 Subject: [PATCH 125/195] flutter: Split dbDirectory from CoreStoreSembastImp --- packages/flutter/lib/parse_server_sdk.dart | 32 ++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 42663f6ee..ba6c89852 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -135,26 +135,30 @@ class Parse extends sdk.Parse } } +Future dbDirectory() async { + String dbDirectory = ''; + if (!sdk.parseIsWeb && + (Platform.isIOS || + Platform.isAndroid || + Platform.isMacOS || + Platform.isLinux || + Platform.isWindows)) { + dbDirectory = (await getApplicationDocumentsDirectory()).path; + } + return path.join('$dbDirectory/parse', 'parse.db'); +} + class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { CoreStoreSembastImp._(); static sdk.CoreStoreSembastImp _sembastImp; - static Future getInstance( + static Future getInstance(String dbPath, {DatabaseFactory factory, String password}) async { - if (_sembastImp == null) { - String dbDirectory = ''; - if (!sdk.parseIsWeb && - (Platform.isIOS || - Platform.isAndroid || - Platform.isMacOS || - Platform.isLinux || - Platform.isWindows)) - dbDirectory = (await getApplicationDocumentsDirectory()).path; - final String dbPath = path.join('$dbDirectory/parse', 'parse.db'); - _sembastImp ??= await sdk.CoreStoreSembastImp.getInstance(dbPath, - factory: factory, password: password); - } + _sembastImp ??= await sdk.CoreStoreSembastImp.getInstance( + await dbDirectory(), + factory: factory, + password: password); return CoreStoreSembastImp._(); } From a2ded5a08098c05fb38f2496bd126044d206891d Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 13:48:43 +0100 Subject: [PATCH 126/195] dart(SemStore): Better way to set default password --- packages/dart/lib/src/storage/core_store_sem_impl.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/storage/core_store_sem_impl.dart b/packages/dart/lib/src/storage/core_store_sem_impl.dart index 3aa39bd83..8c9ebd9e8 100644 --- a/packages/dart/lib/src/storage/core_store_sem_impl.dart +++ b/packages/dart/lib/src/storage/core_store_sem_impl.dart @@ -7,7 +7,7 @@ class CoreStoreSembastImp implements CoreStore { static CoreStoreSembastImp? _instance; static Future getInstance(String dbPath, - {DatabaseFactory? factory, String password = 'flutter_sdk'}) async { + {DatabaseFactory? factory, String? password}) async { if (_instance == null) { factory ??= !parseIsWeb ? databaseFactoryIo : databaseFactoryWeb; assert(() { @@ -30,7 +30,9 @@ class CoreStoreSembastImp implements CoreStore { return true; }()); final Database db = await factory.openDatabase(dbPath, - codec: !parseIsWeb ? getXXTeaSembastCodec(password: password) : null); + codec: !parseIsWeb + ? getXXTeaSembastCodec(password: password = 'flutter_sdk') + : null); _instance = CoreStoreSembastImp._internal(db, StoreRef.main()); } From 5291b281400d636ed4642dc392f08de86e09b25d Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:01:42 +0100 Subject: [PATCH 127/195] flutter: widget is never null --- .../flutter/lib/src/utils/parse_live_list.dart | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index cd9fbfdc2..470414844 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -235,25 +235,16 @@ class _ParseLiveListElementWidgetState if (stream != null) { _streamSubscription = stream().listen( (T data) { - if (widget != null) { - setState(() { - _snapshot = sdk.ParseLiveListElementSnapshot( - loadedData: data, preLoadedData: data); - }); - } else { + setState(() { _snapshot = sdk.ParseLiveListElementSnapshot( loadedData: data, preLoadedData: data); - } + }); }, onError: (Object error) { if (error is sdk.ParseError) { - if (widget != null) { - setState(() { - _snapshot = sdk.ParseLiveListElementSnapshot(error: error); - }); - } else { + setState(() { _snapshot = sdk.ParseLiveListElementSnapshot(error: error); - } + }); } }, cancelOnError: false, From 8804ae21256693e0b442201e0ca7316f517e03d5 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:09:25 +0100 Subject: [PATCH 128/195] flutter: Pass _liveList as parameter --- .../flutter/lib/src/utils/parse_live_list.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 470414844..d80fef4e1 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -154,7 +154,7 @@ class _ParseLiveListWidgetState ? widget.listLoadingElement ?? Container() : noData ? widget.queryEmptyElement ?? Container() - : buildAnimatedList(); + : buildAnimatedList(_liveList); } @override @@ -164,7 +164,7 @@ class _ParseLiveListWidgetState } } - Widget buildAnimatedList() { + Widget buildAnimatedList(sdk.ParseLiveList liveList) { return AnimatedList( key: _animatedListKey, physics: widget.scrollPhysics, @@ -174,15 +174,15 @@ class _ParseLiveListWidgetState primary: widget.primary, reverse: widget.reverse, shrinkWrap: widget.shrinkWrap, - initialItemCount: _liveList?.size, + initialItemCount: liveList.size, itemBuilder: (BuildContext context, int index, Animation animation) { return ParseLiveListElementWidget( key: ValueKey( - _liveList?.getIdentifier(index) ?? '_NotFound'), - stream: () => _liveList?.getAt(index), - loadedData: () => _liveList?.getLoadedAt(index), - preLoadedData: () => _liveList?.getPreLoadedAt(index), + liveList.getIdentifier(index) ?? '_NotFound'), + stream: () => liveList.getAt(index), + loadedData: () => liveList.getLoadedAt(index), + preLoadedData: () => liveList.getPreLoadedAt(index), sizeFactor: animation, duration: widget.duration, childBuilder: From dba58b4555f5619cc4482a91463b7f9a0bd3c60f Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:11:33 +0100 Subject: [PATCH 129/195] flutter: Less confusing ternary operators --- packages/flutter/lib/src/utils/parse_live_list.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index d80fef4e1..58f9733c5 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -150,11 +150,13 @@ class _ParseLiveListWidgetState @override Widget build(BuildContext context) { - return _liveList == null - ? widget.listLoadingElement ?? Container() - : noData - ? widget.queryEmptyElement ?? Container() - : buildAnimatedList(_liveList); + if (_liveList == null) { + return widget.listLoadingElement ?? Container(); + } + if (noData) { + return widget.queryEmptyElement ?? Container(); + } + return buildAnimatedList(_liveList); } @override From 57146d77551dd8850f48dc40cb94439c9aa310bd Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:36:24 +0100 Subject: [PATCH 130/195] dart(liveList): Make preloaded column param nullable --- packages/dart/lib/src/utils/parse_live_list.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 4d096a245..e00d2b66e 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -3,8 +3,8 @@ part of flutter_parse_sdk; // ignore_for_file: invalid_use_of_protected_member class ParseLiveList { ParseLiveList._(this._query, this._listeningIncludes, this._lazyLoading, - {List preloadedColumns = const []}) - : _preloadedColumns = preloadedColumns { + {List? preloadedColumns}) + : _preloadedColumns = preloadedColumns ?? const [] { _debug = isDebugEnabled(); } @@ -13,7 +13,7 @@ class ParseLiveList { bool? listenOnAllSubItems, List? listeningIncludes, bool lazyLoading = true, - List preloadedColumns = const [], + List? preloadedColumns, }) { final ParseLiveList parseLiveList = ParseLiveList._( _query, @@ -22,7 +22,7 @@ class ParseLiveList { _query.limiters['include']?.toString().split(',') ?? []) : _toIncludeMap(listeningIncludes ?? []), lazyLoading, - preloadedColumns: preloadedColumns, + preloadedColumns: preloadedColumns ?? const [], ); return parseLiveList._init().then((_) { From 57bacfec511a73d2736375168ec7593097448713 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:39:58 +0100 Subject: [PATCH 131/195] flutter: Add null check for pre/loadedData --- packages/flutter/lib/src/utils/parse_live_list.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 58f9733c5..067365caf 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -233,7 +233,9 @@ class _ParseLiveListElementWidgetState _ParseLiveListElementWidgetState(sdk.DataGetter loadedDataGetter, sdk.DataGetter preLoadedDataGetter, sdk.StreamGetter stream) { _snapshot = sdk.ParseLiveListElementSnapshot( - loadedData: loadedDataGetter(), preLoadedData: preLoadedDataGetter()); + loadedData: loadedDataGetter != null ? loadedDataGetter() : null, + preLoadedData: + preLoadedDataGetter != null ? preLoadedDataGetter() : null); if (stream != null) { _streamSubscription = stream().listen( (T data) { From bcfbfb078584a54a40be08b530f58682e8a6afcb Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:43:30 +0100 Subject: [PATCH 132/195] flutter: Remove unreachable case --- packages/flutter/lib/src/utils/parse_live_list.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 067365caf..c0e97010b 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -180,8 +180,7 @@ class _ParseLiveListWidgetState itemBuilder: (BuildContext context, int index, Animation animation) { return ParseLiveListElementWidget( - key: ValueKey( - liveList.getIdentifier(index) ?? '_NotFound'), + key: ValueKey(liveList.getIdentifier(index)), stream: () => liveList.getAt(index), loadedData: () => liveList.getLoadedAt(index), preLoadedData: () => liveList.getPreLoadedAt(index), From 852a5be7e73e330c6bff63c9bb713071001dd202 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:46:11 +0100 Subject: [PATCH 133/195] flutter(LiveList): Usually we start with noData --- packages/flutter/lib/src/utils/parse_live_list.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index c0e97010b..410750366 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -146,7 +146,7 @@ class _ParseLiveListWidgetState final GlobalKey _animatedListKey = GlobalKey(); final ChildBuilder removedItemBuilder; - bool noData = false; + bool noData = true; @override Widget build(BuildContext context) { From 92a90f1901c9fa7ae44a58be2e42b0013c232ea5 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:52:52 +0100 Subject: [PATCH 134/195] flutter(LiveList): Annotate --- .../flutter/lib/src/utils/parse_live_list.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 410750366..545155730 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -25,7 +25,7 @@ class ParseLiveListWidget extends StatefulWidget { this.preloadedColumns, }) : super(key: key); - final sdk.QueryBuilder query; + final sdk.QueryBuilder/*!*/ query; final Widget listLoadingElement; final Widget queryEmptyElement; final Duration duration; @@ -115,7 +115,7 @@ class _ParseLiveListWidgetState event.index, (BuildContext context, Animation animation) => ParseLiveListElementWidget( - key: ValueKey(event.object?.get( + key: ValueKey(event.object.get( sdk.keyVarObjectId, defaultValue: 'removingItem')), childBuilder: widget.childBuilder ?? @@ -145,7 +145,7 @@ class _ParseLiveListWidgetState sdk.ParseLiveList _liveList; final GlobalKey _animatedListKey = GlobalKey(); - final ChildBuilder removedItemBuilder; + final ChildBuilder/*!*/ removedItemBuilder; bool noData = true; @override @@ -200,7 +200,7 @@ class _ParseLiveListWidgetState } } -class ParseLiveListElementWidget +class ParseLiveListElementWidget extends StatefulWidget { const ParseLiveListElementWidget( {Key key, @@ -213,8 +213,8 @@ class ParseLiveListElementWidget : super(key: key); final sdk.StreamGetter stream; - final sdk.DataGetter loadedData; - final sdk.DataGetter preLoadedData; + final sdk.DataGetter loadedData; + final sdk.DataGetter preLoadedData; final Animation sizeFactor; final Duration duration; final ChildBuilder childBuilder; @@ -226,7 +226,7 @@ class ParseLiveListElementWidget } } -class _ParseLiveListElementWidgetState +class _ParseLiveListElementWidgetState extends State> with SingleTickerProviderStateMixin { _ParseLiveListElementWidgetState(sdk.DataGetter loadedDataGetter, @@ -255,7 +255,7 @@ class _ParseLiveListElementWidgetState } } - sdk.ParseLiveListElementSnapshot _snapshot; + sdk.ParseLiveListElementSnapshot/*!*/ _snapshot; StreamSubscription _streamSubscription; From 6981cc4fa0b8af98761c1591d5f141094c4df098 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 14:55:33 +0100 Subject: [PATCH 135/195] flutter: Remove unused variables --- packages/flutter/lib/src/utils/parse_live_grid.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_grid.dart b/packages/flutter/lib/src/utils/parse_live_grid.dart index 75f970adb..e509920c4 100644 --- a/packages/flutter/lib/src/utils/parse_live_grid.dart +++ b/packages/flutter/lib/src/utils/parse_live_grid.dart @@ -125,8 +125,6 @@ class _ParseLiveGridWidgetState final sdk.QueryBuilder query; sdk.ParseLiveList _liveGrid; - final GlobalKey _animatedListKey = - GlobalKey(); final ChildBuilder removedItemBuilder; bool noData = false; @@ -147,7 +145,6 @@ class _ParseLiveGridWidgetState } Widget buildAnimatedGrid() { - AnimationController controller; Animation boxAnimation; boxAnimation = Tween( begin: 0.0, From 73ecf08257837b0466d7b732385c139f635cc572 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:00:12 +0100 Subject: [PATCH 136/195] flutter(LiveGrid): replicate LiveList improvements --- .../lib/src/utils/parse_live_grid.dart | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_grid.dart b/packages/flutter/lib/src/utils/parse_live_grid.dart index e509920c4..a0476ee6a 100644 --- a/packages/flutter/lib/src/utils/parse_live_grid.dart +++ b/packages/flutter/lib/src/utils/parse_live_grid.dart @@ -126,15 +126,17 @@ class _ParseLiveGridWidgetState final sdk.QueryBuilder query; sdk.ParseLiveList _liveGrid; final ChildBuilder removedItemBuilder; - bool noData = false; + bool noData = true; @override Widget build(BuildContext context) { - return _liveGrid == null - ? widget.gridLoadingElement ?? Container() - : noData - ? widget.queryEmptyElement ?? Container() - : buildAnimatedGrid(); + if (_liveGrid == null) { + return widget.gridLoadingElement ?? Container(); + } + if (noData) { + return widget.queryEmptyElement ?? Container(); + } + return buildAnimatedGrid(_liveGrid); } @override @@ -144,7 +146,7 @@ class _ParseLiveGridWidgetState } } - Widget buildAnimatedGrid() { + Widget buildAnimatedGrid(sdk.ParseLiveList liveGrid) { Animation boxAnimation; boxAnimation = Tween( begin: 0.0, @@ -160,7 +162,7 @@ class _ParseLiveGridWidgetState ), ); return GridView.builder( - itemCount: _liveGrid?.size, + itemCount: liveGrid.size, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: widget.crossAxisCount, crossAxisSpacing: widget.crossAxisSpacing, @@ -171,11 +173,10 @@ class _ParseLiveGridWidgetState int index, ) { return ParseLiveListElementWidget( - key: ValueKey( - _liveGrid?.getIdentifier(index) ?? '_NotFound'), - stream: () => _liveGrid?.getAt(index), - loadedData: () => _liveGrid?.getLoadedAt(index), - preLoadedData: () => _liveGrid?.getPreLoadedAt(index), + key: ValueKey(liveGrid.getIdentifier(index)), + stream: () => liveGrid.getAt(index), + loadedData: () => liveGrid.getLoadedAt(index), + preLoadedData: () => liveGrid.getPreLoadedAt(index), sizeFactor: boxAnimation, duration: widget.duration, childBuilder: From e0fb9e975b6e1a219d5e3e0cf5a7069c9ba35170 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:06:21 +0100 Subject: [PATCH 137/195] flutter(LiveGrid): Add todo --- packages/flutter/lib/src/utils/parse_live_grid.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/flutter/lib/src/utils/parse_live_grid.dart b/packages/flutter/lib/src/utils/parse_live_grid.dart index a0476ee6a..5b567f7d4 100644 --- a/packages/flutter/lib/src/utils/parse_live_grid.dart +++ b/packages/flutter/lib/src/utils/parse_live_grid.dart @@ -153,6 +153,7 @@ class _ParseLiveGridWidgetState end: 1.0, ).animate( CurvedAnimation( + // TODO: AnimationController is always null, so this breaks parent: widget.animationController, curve: const Interval( 0, From e154aa27d56eedab5fa07e55771a39906c4fd5ec Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:10:06 +0100 Subject: [PATCH 138/195] flutter: Apply migration --- .../flutter/example_livelist/lib/main.dart | 34 +++---- packages/flutter/lib/generated/i18n.dart | 10 +- packages/flutter/lib/parse_server_sdk.dart | 74 +++++++-------- .../lib/src/storage/core_store_sp_impl.dart | 17 ++-- .../lib/src/utils/parse_live_grid.dart | 54 +++++------ .../lib/src/utils/parse_live_list.dart | 92 +++++++++---------- packages/flutter/pubspec.yaml | 2 +- packages/flutter/test/parse_query_test.dart | 2 +- 8 files changed, 142 insertions(+), 143 deletions(-) diff --git a/packages/flutter/example_livelist/lib/main.dart b/packages/flutter/example_livelist/lib/main.dart index d27d57330..27da1c64c 100644 --- a/packages/flutter/example_livelist/lib/main.dart +++ b/packages/flutter/example_livelist/lib/main.dart @@ -11,9 +11,9 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - bool initFailed; + bool? initFailed; - QueryBuilder _queryBuilder; + late QueryBuilder _queryBuilder; @override void initState() { @@ -87,14 +87,14 @@ class _MyAppState extends State { children: [ Flexible( child: Text( - snapshot.loadedData.get('order').toString()), + snapshot.loadedData!.get('order').toString()), flex: 1, ), Flexible( child: Container( alignment: Alignment.center, child: Text( - snapshot.loadedData.get('text'), + snapshot.loadedData!.get('text')!, ), ), flex: 10, @@ -102,7 +102,7 @@ class _MyAppState extends State { ], ), onLongPress: () { - objectFormKey.currentState.setObject(snapshot.loadedData); + objectFormKey.currentState!.setObject(snapshot.loadedData); }, ); } else { @@ -124,17 +124,17 @@ class _MyAppState extends State { } class ObjectForm extends StatefulWidget { - const ObjectForm({Key key}) : super(key: key); + const ObjectForm({Key? key}) : super(key: key); @override _ObjectFormState createState() => _ObjectFormState(); } class _ObjectFormState extends State { - ParseObject _currentObject; + ParseObject? _currentObject; final GlobalKey _formKey = GlobalKey(); - void setObject(ParseObject object) { + void setObject(ParseObject? object) { setState(() { _currentObject = object; }); @@ -153,19 +153,19 @@ class _ObjectFormState extends State { Flexible( flex: 1, child: TextFormField( - initialValue: _currentObject.get('order').toString(), + initialValue: _currentObject!.get('order').toString(), keyboardType: TextInputType.number, - onSaved: (String value) { - _currentObject.set('order', int.parse(value)); + onSaved: (String? value) { + _currentObject!.set('order', int.parse(value!)); }, ), ), Flexible( flex: 10, child: TextFormField( - initialValue: _currentObject.get('text'), - onSaved: (String value) { - _currentObject.set('text', value); + initialValue: _currentObject!.get('text'), + onSaved: (String? value) { + _currentObject!.set('text', value); }, ), ) @@ -175,12 +175,12 @@ class _ObjectFormState extends State { icon: const Icon(Icons.save), onPressed: () { setState(() { - _formKey.currentState.save(); - final ParseObject object = _currentObject; + _formKey.currentState!.save(); + final ParseObject? object = _currentObject; //Delay to highlight the animation. Future.delayed(const Duration(seconds: 1)) .then((_) { - object.save(); + object!.save(); }); _currentObject = null; }); diff --git a/packages/flutter/lib/generated/i18n.dart b/packages/flutter/lib/generated/i18n.dart index b4dfaf509..a4ee41961 100644 --- a/packages/flutter/lib/generated/i18n.dart +++ b/packages/flutter/lib/generated/i18n.dart @@ -15,7 +15,7 @@ class S implements WidgetsLocalizations { static const GeneratedLocalizationsDelegate delegate = GeneratedLocalizationsDelegate(); - static S of(BuildContext context) => + static S? of(BuildContext context) => Localizations.of(context, WidgetsLocalizations); @override @@ -36,9 +36,9 @@ class GeneratedLocalizationsDelegate ]; } - LocaleResolutionCallback resolution({Locale fallback}) { - return (Locale locale, Iterable supported) { - final Locale languageLocale = Locale(locale.languageCode, ""); + LocaleResolutionCallback resolution({Locale? fallback}) { + return (Locale? locale, Iterable supported) { + final Locale languageLocale = Locale(locale!.languageCode, ""); if (supported.contains(locale)) return locale; else if (supported.contains(languageLocale)) @@ -69,6 +69,6 @@ class GeneratedLocalizationsDelegate bool shouldReload(GeneratedLocalizationsDelegate old) => false; } -String getLang(Locale l) => l.countryCode != null && l.countryCode.isEmpty +String getLang(Locale l) => l.countryCode != null && l.countryCode!.isEmpty ? l.languageCode : l.toString(); diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index ba6c89852..b5ae0a87e 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -43,25 +43,25 @@ class Parse extends sdk.Parse String appId, String serverUrl, { bool debug = false, - String appName, - String appVersion, - String appPackageName, - String locale, - String liveQueryUrl, - String clientKey, - String masterKey, - String sessionId, + String? appName, + String? appVersion, + String? appPackageName, + String? locale, + String? liveQueryUrl, + String? clientKey, + String? masterKey, + String? sessionId, bool autoSendSessionId = true, - SecurityContext securityContext, - sdk.CoreStore coreStore, - Map registeredSubClassMap, - sdk.ParseUserConstructor parseUserConstructor, - sdk.ParseFileConstructor parseFileConstructor, - List liveListRetryIntervals, - sdk.ParseConnectivityProvider connectivityProvider, - String fileDirectory, - Stream appResumedStream, - sdk.ParseClientCreator clientCreator, + SecurityContext? securityContext, + sdk.CoreStore? coreStore, + Map? registeredSubClassMap, + sdk.ParseUserConstructor? parseUserConstructor, + sdk.ParseFileConstructor? parseFileConstructor, + List? liveListRetryIntervals, + sdk.ParseConnectivityProvider? connectivityProvider, + String? fileDirectory, + Stream? appResumedStream, + sdk.ParseClientCreator? clientCreator, }) async { if (appName == null || appVersion == null || appPackageName == null) { final PackageInfo packageInfo = await PackageInfo.fromPlatform(); @@ -151,61 +151,61 @@ Future dbDirectory() async { class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { CoreStoreSembastImp._(); - static sdk.CoreStoreSembastImp _sembastImp; + static sdk.CoreStoreSembastImp? _sembastImp; static Future getInstance(String dbPath, - {DatabaseFactory factory, String password}) async { - _sembastImp ??= await sdk.CoreStoreSembastImp.getInstance( + {DatabaseFactory? factory, String? password}) async { + _sembastImp ??= await (sdk.CoreStoreSembastImp.getInstance( await dbDirectory(), factory: factory, - password: password); + password: password) as FutureOr); return CoreStoreSembastImp._(); } @override - Future clear() => _sembastImp.clear(); + Future clear() => _sembastImp!.clear(); @override - Future containsKey(String key) => _sembastImp.containsKey(key); + Future containsKey(String key) => _sembastImp!.containsKey(key); @override - Future get(String key) => _sembastImp.get(key); + Future get(String key) => _sembastImp!.get(key); @override - Future getBool(String key) => _sembastImp.getBool(key); + Future getBool(String key) => _sembastImp!.getBool(key); @override - Future getDouble(String key) => _sembastImp.getDouble(key); + Future getDouble(String key) => _sembastImp!.getDouble(key); @override - Future getInt(String key) => _sembastImp.getInt(key); + Future getInt(String key) => _sembastImp!.getInt(key); @override - Future getString(String key) => _sembastImp.getString(key); + Future getString(String key) => _sembastImp!.getString(key); @override - Future> getStringList(String key) => - _sembastImp.getStringList(key); + Future?> getStringList(String key) => + _sembastImp!.getStringList(key); @override - Future remove(String key) => _sembastImp.remove(key); + Future remove(String key) => _sembastImp!.remove(key); @override Future setBool(String key, bool value) => - _sembastImp.setBool(key, value); + _sembastImp!.setBool(key, value); @override Future setDouble(String key, double value) => - _sembastImp.setDouble(key, value); + _sembastImp!.setDouble(key, value); @override - Future setInt(String key, int value) => _sembastImp.setInt(key, value); + Future setInt(String key, int value) => _sembastImp!.setInt(key, value); @override Future setString(String key, String value) => - _sembastImp.setString(key, value); + _sembastImp!.setString(key, value); @override Future setStringList(String key, List values) => - _sembastImp.setStringList(key, values); + _sembastImp!.setStringList(key, values); } diff --git a/packages/flutter/lib/src/storage/core_store_sp_impl.dart b/packages/flutter/lib/src/storage/core_store_sp_impl.dart index 8f0e2e3fd..150233cb4 100644 --- a/packages/flutter/lib/src/storage/core_store_sp_impl.dart +++ b/packages/flutter/lib/src/storage/core_store_sp_impl.dart @@ -3,15 +3,15 @@ part of flutter_parse_sdk_flutter; class CoreStoreSharedPrefsImp implements sdk.CoreStore { CoreStoreSharedPrefsImp._internal(this._store); - static CoreStoreSharedPrefsImp _instance; + static CoreStoreSharedPrefsImp? _instance; - static Future getInstance({SharedPreferences store}) async { + static Future getInstance({SharedPreferences? store}) async { if (_instance == null) { store ??= await SharedPreferences.getInstance(); _instance = CoreStoreSharedPrefsImp._internal(store); } - return _instance; + return _instance!; } final SharedPreferences _store; @@ -32,31 +32,30 @@ class CoreStoreSharedPrefsImp implements sdk.CoreStore { } @override - Future getBool(String key) async { + Future getBool(String key) async { return _store.getBool(key); } @override - Future getDouble(String key) async { + Future getDouble(String key) async { return _store.getDouble(key); } @override - Future getInt(String key) async { + Future getInt(String key) async { return _store.getInt(key); } @override - Future getString(String key) async { + Future getString(String key) async { return _store.getString(key); } @override - Future> getStringList(String key) async { + Future?> getStringList(String key) async { return _store.getStringList(key); } - @override Future remove(String key) async { return _store.remove(key); diff --git a/packages/flutter/lib/src/utils/parse_live_grid.dart b/packages/flutter/lib/src/utils/parse_live_grid.dart index 5b567f7d4..9c5c335ba 100644 --- a/packages/flutter/lib/src/utils/parse_live_grid.dart +++ b/packages/flutter/lib/src/utils/parse_live_grid.dart @@ -2,8 +2,8 @@ part of flutter_parse_sdk_flutter; class ParseLiveGridWidget extends StatefulWidget { const ParseLiveGridWidget({ - Key key, - @required this.query, + Key? key, + required this.query, this.gridLoadingElement, this.queryEmptyElement, this.duration = const Duration(milliseconds: 300), @@ -28,28 +28,28 @@ class ParseLiveGridWidget extends StatefulWidget { }) : super(key: key); final sdk.QueryBuilder query; - final Widget gridLoadingElement; - final Widget queryEmptyElement; + final Widget? gridLoadingElement; + final Widget? queryEmptyElement; final Duration duration; - final ScrollPhysics scrollPhysics; - final ScrollController scrollController; + final ScrollPhysics? scrollPhysics; + final ScrollController? scrollController; final Axis scrollDirection; - final EdgeInsetsGeometry padding; - final bool primary; + final EdgeInsetsGeometry? padding; + final bool? primary; final bool reverse; final bool shrinkWrap; - final ChildBuilder childBuilder; - final ChildBuilder removedItemBuilder; + final ChildBuilder? childBuilder; + final ChildBuilder? removedItemBuilder; - final bool listenOnAllSubItems; - final List listeningIncludes; + final bool? listenOnAllSubItems; + final List? listeningIncludes; final bool lazyLoading; - final List preloadedColumns; + final List? preloadedColumns; - final AnimationController animationController; + final AnimationController? animationController; final int crossAxisCount; final double crossAxisSpacing; @@ -74,7 +74,7 @@ class ParseLiveGridWidget extends StatefulWidget { } else if (snapshot.hasData) { child = ListTile( title: Text( - snapshot.loadedData.get(sdk.keyVarObjectId), + snapshot.loadedData!.get(sdk.keyVarObjectId), ), ); } else { @@ -89,12 +89,12 @@ class ParseLiveGridWidget extends StatefulWidget { class _ParseLiveGridWidgetState extends State> { _ParseLiveGridWidgetState( - {@required this.query, - @required this.removedItemBuilder, - bool listenOnAllSubItems, - List listeningIncludes, + {required this.query, + required this.removedItemBuilder, + bool? listenOnAllSubItems, + List? listeningIncludes, bool lazyLoading = true, - List preloadedColumns}) { + List? preloadedColumns}) { sdk.ParseLiveList.create( query, listenOnAllSubItems: listenOnAllSubItems, @@ -113,7 +113,7 @@ class _ParseLiveGridWidgetState } setState(() { _liveGrid = value; - _liveGrid.stream + _liveGrid!.stream .listen((sdk.ParseLiveListEvent event) { if (mounted) { setState(() {}); @@ -124,8 +124,8 @@ class _ParseLiveGridWidgetState } final sdk.QueryBuilder query; - sdk.ParseLiveList _liveGrid; - final ChildBuilder removedItemBuilder; + sdk.ParseLiveList? _liveGrid; + final ChildBuilder? removedItemBuilder; bool noData = true; @override @@ -136,7 +136,7 @@ class _ParseLiveGridWidgetState if (noData) { return widget.queryEmptyElement ?? Container(); } - return buildAnimatedGrid(_liveGrid); + return buildAnimatedGrid(_liveGrid!); } @override @@ -154,7 +154,7 @@ class _ParseLiveGridWidgetState ).animate( CurvedAnimation( // TODO: AnimationController is always null, so this breaks - parent: widget.animationController, + parent: widget.animationController!, curve: const Interval( 0, 0.5, @@ -176,8 +176,8 @@ class _ParseLiveGridWidgetState return ParseLiveListElementWidget( key: ValueKey(liveGrid.getIdentifier(index)), stream: () => liveGrid.getAt(index), - loadedData: () => liveGrid.getLoadedAt(index), - preLoadedData: () => liveGrid.getPreLoadedAt(index), + loadedData: () => liveGrid.getLoadedAt(index)!, + preLoadedData: () => liveGrid.getPreLoadedAt(index)!, sizeFactor: boxAnimation, duration: widget.duration, childBuilder: diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 545155730..9ad3f1ac5 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -5,8 +5,8 @@ typedef ChildBuilder = Widget Function( class ParseLiveListWidget extends StatefulWidget { const ParseLiveListWidget({ - Key key, - @required this.query, + Key? key, + required this.query, this.listLoadingElement, this.queryEmptyElement, this.duration = const Duration(milliseconds: 300), @@ -25,32 +25,32 @@ class ParseLiveListWidget extends StatefulWidget { this.preloadedColumns, }) : super(key: key); - final sdk.QueryBuilder/*!*/ query; - final Widget listLoadingElement; - final Widget queryEmptyElement; + final sdk.QueryBuilder query; + final Widget? listLoadingElement; + final Widget? queryEmptyElement; final Duration duration; - final ScrollPhysics scrollPhysics; - final ScrollController scrollController; + final ScrollPhysics? scrollPhysics; + final ScrollController? scrollController; final Axis scrollDirection; - final EdgeInsetsGeometry padding; - final bool primary; + final EdgeInsetsGeometry? padding; + final bool? primary; final bool reverse; final bool shrinkWrap; - final ChildBuilder childBuilder; - final ChildBuilder removedItemBuilder; + final ChildBuilder? childBuilder; + final ChildBuilder? removedItemBuilder; - final bool listenOnAllSubItems; - final List listeningIncludes; + final bool? listenOnAllSubItems; + final List? listeningIncludes; final bool lazyLoading; - final List preloadedColumns; + final List? preloadedColumns; @override _ParseLiveListWidgetState createState() => _ParseLiveListWidgetState( query: query, - removedItemBuilder: removedItemBuilder, + removedItemBuilder: removedItemBuilder!, listenOnAllSubItems: listenOnAllSubItems, listeningIncludes: listeningIncludes, lazyLoading: lazyLoading, @@ -65,7 +65,7 @@ class ParseLiveListWidget extends StatefulWidget { } else if (snapshot.hasData) { child = ListTile( title: Text( - snapshot.loadedData.get(sdk.keyVarObjectId), + snapshot.loadedData!.get(sdk.keyVarObjectId), ), ); } else { @@ -80,12 +80,12 @@ class ParseLiveListWidget extends StatefulWidget { class _ParseLiveListWidgetState extends State> { _ParseLiveListWidgetState( - {@required this.query, - @required this.removedItemBuilder, - bool listenOnAllSubItems, - List listeningIncludes, + {required this.query, + required this.removedItemBuilder, + bool? listenOnAllSubItems, + List? listeningIncludes, bool lazyLoading = true, - List preloadedColumns}) { + List? preloadedColumns}) { sdk.ParseLiveList.create( query, listenOnAllSubItems: listenOnAllSubItems, @@ -104,26 +104,26 @@ class _ParseLiveListWidgetState } setState(() { _liveList = value; - _liveList.stream + _liveList!.stream .listen((sdk.ParseLiveListEvent event) { if (event is sdk.ParseLiveListAddEvent) { if (_animatedListKey.currentState != null) - _animatedListKey.currentState + _animatedListKey.currentState! .insertItem(event.index, duration: widget.duration); } else if (event is sdk.ParseLiveListDeleteEvent) { - _animatedListKey.currentState.removeItem( + _animatedListKey.currentState!.removeItem( event.index, (BuildContext context, Animation animation) => ParseLiveListElementWidget( - key: ValueKey(event.object.get( + key: ValueKey(event.object.get( sdk.keyVarObjectId, - defaultValue: 'removingItem')), + defaultValue: 'removingItem')!), childBuilder: widget.childBuilder ?? ParseLiveListWidget.defaultChildBuilder, sizeFactor: animation, duration: widget.duration, - loadedData: () => event.object, - preLoadedData: () => event.object, + loadedData: () => event.object as T, + preLoadedData: () => event.object as T, ), duration: widget.duration); if (value.size > 0) { @@ -142,10 +142,10 @@ class _ParseLiveListWidgetState } final sdk.QueryBuilder query; - sdk.ParseLiveList _liveList; + sdk.ParseLiveList? _liveList; final GlobalKey _animatedListKey = GlobalKey(); - final ChildBuilder/*!*/ removedItemBuilder; + final ChildBuilder removedItemBuilder; bool noData = true; @override @@ -156,7 +156,7 @@ class _ParseLiveListWidgetState if (noData) { return widget.queryEmptyElement ?? Container(); } - return buildAnimatedList(_liveList); + return buildAnimatedList(_liveList!); } @override @@ -182,8 +182,8 @@ class _ParseLiveListWidgetState return ParseLiveListElementWidget( key: ValueKey(liveList.getIdentifier(index)), stream: () => liveList.getAt(index), - loadedData: () => liveList.getLoadedAt(index), - preLoadedData: () => liveList.getPreLoadedAt(index), + loadedData: () => liveList.getLoadedAt(index)!, + preLoadedData: () => liveList.getPreLoadedAt(index)!, sizeFactor: animation, duration: widget.duration, childBuilder: @@ -200,21 +200,21 @@ class _ParseLiveListWidgetState } } -class ParseLiveListElementWidget +class ParseLiveListElementWidget extends StatefulWidget { const ParseLiveListElementWidget( - {Key key, + {Key? key, this.stream, this.loadedData, this.preLoadedData, - @required this.sizeFactor, - @required this.duration, - @required this.childBuilder}) + required this.sizeFactor, + required this.duration, + required this.childBuilder}) : super(key: key); - final sdk.StreamGetter stream; - final sdk.DataGetter loadedData; - final sdk.DataGetter preLoadedData; + final sdk.StreamGetter? stream; + final sdk.DataGetter? loadedData; + final sdk.DataGetter? preLoadedData; final Animation sizeFactor; final Duration duration; final ChildBuilder childBuilder; @@ -226,11 +226,11 @@ class ParseLiveListElementWidget } } -class _ParseLiveListElementWidgetState +class _ParseLiveListElementWidgetState extends State> with SingleTickerProviderStateMixin { - _ParseLiveListElementWidgetState(sdk.DataGetter loadedDataGetter, - sdk.DataGetter preLoadedDataGetter, sdk.StreamGetter stream) { + _ParseLiveListElementWidgetState(sdk.DataGetter? loadedDataGetter, + sdk.DataGetter? preLoadedDataGetter, sdk.StreamGetter? stream) { _snapshot = sdk.ParseLiveListElementSnapshot( loadedData: loadedDataGetter != null ? loadedDataGetter() : null, preLoadedData: @@ -255,9 +255,9 @@ class _ParseLiveListElementWidgetState } } - sdk.ParseLiveListElementSnapshot/*!*/ _snapshot; + sdk.ParseLiveListElementSnapshot _snapshot; - StreamSubscription _streamSubscription; + StreamSubscription? _streamSubscription; @override void setState(VoidCallback fn) { diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index a1cddb61d..021e817f6 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -4,7 +4,7 @@ version: 3.0.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: - sdk: ">=2.2.2 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: diff --git a/packages/flutter/test/parse_query_test.dart b/packages/flutter/test/parse_query_test.dart index 4c6ab9e5f..9285f04a7 100644 --- a/packages/flutter/test/parse_query_test.dart +++ b/packages/flutter/test/parse_query_test.dart @@ -34,7 +34,7 @@ void main() { await queryBuilder.query(); final Uri result = - Uri.parse(verify(client.get(captureAny)).captured.single); + Uri.parse(verify(client.get(captureAny!)).captured.single); expect(result.path, '/classes/_User'); From 28386456d1f20f6985c7bb203bb2ac3332c30184 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:12:06 +0100 Subject: [PATCH 139/195] flutter: Fix errors after migration --- packages/flutter/lib/src/storage/core_store_sp_impl.dart | 2 +- packages/flutter/lib/src/utils/parse_live_grid.dart | 2 +- packages/flutter/lib/src/utils/parse_live_list.dart | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/flutter/lib/src/storage/core_store_sp_impl.dart b/packages/flutter/lib/src/storage/core_store_sp_impl.dart index 150233cb4..126ec1228 100644 --- a/packages/flutter/lib/src/storage/core_store_sp_impl.dart +++ b/packages/flutter/lib/src/storage/core_store_sp_impl.dart @@ -57,7 +57,7 @@ class CoreStoreSharedPrefsImp implements sdk.CoreStore { } @override - Future remove(String key) async { + Future remove(String key) async { return _store.remove(key); } diff --git a/packages/flutter/lib/src/utils/parse_live_grid.dart b/packages/flutter/lib/src/utils/parse_live_grid.dart index 9c5c335ba..646f5735d 100644 --- a/packages/flutter/lib/src/utils/parse_live_grid.dart +++ b/packages/flutter/lib/src/utils/parse_live_grid.dart @@ -74,7 +74,7 @@ class ParseLiveGridWidget extends StatefulWidget { } else if (snapshot.hasData) { child = ListTile( title: Text( - snapshot.loadedData!.get(sdk.keyVarObjectId), + snapshot.loadedData!.get(sdk.keyVarObjectId)!, ), ); } else { diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 9ad3f1ac5..5fae4024d 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -65,7 +65,7 @@ class ParseLiveListWidget extends StatefulWidget { } else if (snapshot.hasData) { child = ListTile( title: Text( - snapshot.loadedData!.get(sdk.keyVarObjectId), + snapshot.loadedData!.get(sdk.keyVarObjectId)!, ), ); } else { @@ -255,7 +255,7 @@ class _ParseLiveListElementWidgetState } } - sdk.ParseLiveListElementSnapshot _snapshot; + late sdk.ParseLiveListElementSnapshot _snapshot; StreamSubscription? _streamSubscription; From a00d4a44b5eaf4a9b51a2e8c70a889d3ed11e4c5 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:25:48 +0100 Subject: [PATCH 140/195] Upgrade dio to 4.0.0-prev3 --- packages/dart/pubspec.yaml | 2 +- packages/flutter/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 6774e1314..9e2fd6aec 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: # Networking - dio: ^4.0.0-prev2 + dio: ^4.0.0-prev3 http: ^0.13.1 web_socket_channel: ^2.0.0 diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 021e817f6..25a4f8bb0 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # path: packages/dart # Networking - dio: ^4.0.0-prev2 + dio: ^4.0.0-prev3 connectivity: ^3.0.3 # only used in the flutter part #Database From 56ebcc1dcd46a2b8195bbba1093024b388d2cc36 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:35:47 +0100 Subject: [PATCH 141/195] Can never be null --- packages/dart/lib/src/utils/parse_live_list.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index e00d2b66e..8cf640e53 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -441,8 +441,7 @@ class ParseLiveList { String getIdentifier(int index) { if (index < _list.length) { return _list[index].object!.get(keyVarObjectId)! + - _list[index].object!.get(keyVarUpdatedAt).toString() ?? - ''; + _list[index].object!.get(keyVarUpdatedAt).toString(); } return 'NotFound'; } From bece32e45bff05f313067a63c76d071d4031e1ef Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 15:52:39 +0100 Subject: [PATCH 142/195] dart(DioClient): Make sure headers != null --- packages/dart/lib/src/network/parse_dio_client.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_dio_client.dart b/packages/dart/lib/src/network/parse_dio_client.dart index cefed3c07..6a55e5bd6 100644 --- a/packages/dart/lib/src/network/parse_dio_client.dart +++ b/packages/dart/lib/src/network/parse_dio_client.dart @@ -150,7 +150,8 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio { ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress, }) { - options ??= dio.Options(headers: Map()); + options ??= dio.Options(); + options.headers ??= {}; if (!identical(0, 0.0)) { options.headers![keyHeaderUserAgent] = _userAgent; } From 87c587697945487c3e5faa113fe05c73d626b6ed Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sat, 20 Mar 2021 17:42:25 +0100 Subject: [PATCH 143/195] dart: Fix Web support by migrating dio_adapter_js Fixes #588 --- packages/dart/lib/src/network/dio_adapter_js.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/dio_adapter_js.dart b/packages/dart/lib/src/network/dio_adapter_js.dart index e7158e0de..d4dec6b7a 100644 --- a/packages/dart/lib/src/network/dio_adapter_js.dart +++ b/packages/dart/lib/src/network/dio_adapter_js.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:dio/adapter_browser.dart'; import 'package:dio/dio.dart'; -HttpClientAdapter createHttpClientAdapter(SecurityContext securityContext) { +HttpClientAdapter createHttpClientAdapter(SecurityContext? securityContext) { final BrowserHttpClientAdapter browserHttpClientAdapter = BrowserHttpClientAdapter(); return browserHttpClientAdapter; From f8549e7bbb04dd865166536714f62be2fd72693d Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Sun, 21 Mar 2021 18:34:58 +0100 Subject: [PATCH 144/195] fix(dart): Fix default password typo --- packages/dart/lib/src/storage/core_store_sem_impl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/storage/core_store_sem_impl.dart b/packages/dart/lib/src/storage/core_store_sem_impl.dart index 8c9ebd9e8..bf2f97212 100644 --- a/packages/dart/lib/src/storage/core_store_sem_impl.dart +++ b/packages/dart/lib/src/storage/core_store_sem_impl.dart @@ -31,7 +31,7 @@ class CoreStoreSembastImp implements CoreStore { }()); final Database db = await factory.openDatabase(dbPath, codec: !parseIsWeb - ? getXXTeaSembastCodec(password: password = 'flutter_sdk') + ? getXXTeaSembastCodec(password: password ?? 'flutter_sdk') : null); _instance = CoreStoreSembastImp._internal(db, StoreRef.main()); From 743a4a487f980656330ea305787a9e894b31bf07 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Mon, 22 Mar 2021 14:54:32 +0100 Subject: [PATCH 145/195] flutter: Removed dbPath added by mistake --- packages/flutter/lib/parse_server_sdk.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index b5ae0a87e..2f1e5571f 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -153,7 +153,7 @@ class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { static sdk.CoreStoreSembastImp? _sembastImp; - static Future getInstance(String dbPath, + static Future getInstance( {DatabaseFactory? factory, String? password}) async { _sembastImp ??= await (sdk.CoreStoreSembastImp.getInstance( await dbDirectory(), From ebafe4ef0d055938d57b540a26e071e4e5751055 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Mon, 22 Mar 2021 15:45:06 +0100 Subject: [PATCH 146/195] dart: Fix and improve DioError extraction --- packages/dart/lib/parse_server_sdk.dart | 1 + .../dart/lib/src/objects/parse_response.dart | 4 ++ .../response/parse_exception_response.dart | 39 ++++++++----------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index 1924f189d..ff6556b15 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -6,6 +6,7 @@ import 'dart:io'; import 'dart:math'; import 'dart:typed_data'; +import 'package:dio/dio.dart'; import 'package:meta/meta.dart'; import 'package:mime_type/mime_type.dart'; import 'package:path/path.dart' as path; diff --git a/packages/dart/lib/src/objects/parse_response.dart b/packages/dart/lib/src/objects/parse_response.dart index 7806efdc0..41a6950bb 100644 --- a/packages/dart/lib/src/objects/parse_response.dart +++ b/packages/dart/lib/src/objects/parse_response.dart @@ -1,6 +1,10 @@ part of flutter_parse_sdk; class ParseResponse { + ParseResponse({ + this.error, + }); + bool success = false; int statusCode = -1; diff --git a/packages/dart/lib/src/objects/response/parse_exception_response.dart b/packages/dart/lib/src/objects/response/parse_exception_response.dart index c62b452c1..f2e6faf19 100644 --- a/packages/dart/lib/src/objects/response/parse_exception_response.dart +++ b/packages/dart/lib/src/objects/response/parse_exception_response.dart @@ -2,32 +2,27 @@ part of flutter_parse_sdk; /// Handles exception instead of throwing an exception ParseResponse buildParseResponseWithException(Exception exception) { - final ParseResponse response = ParseResponse(); if (exception is DioError) { + Map errorResponse = {}; try { - Map errorResponse; + errorResponse = json.decode(exception.response?.data?.toString() ?? '{}'); + } on FormatException catch (_) {} - try { - errorResponse = - json.decode(exception.response?.data?.toString() ?? '{}'); - } catch (_) {} + final errorMessage = + errorResponse['error']?.toString() ?? exception.response?.statusMessage; - errorResponse ??= {}; + final errorCode = + int.tryParse(errorResponse['code']) ?? exception.response?.statusCode; - response.error = ParseError( - message: errorResponse['error']?.toString() ?? - exception.response?.statusMessage, - exception: exception, - code: errorResponse['code'] ?? exception.response?.statusCode, - ); - } catch (error) { - response.error = ParseError( - message: "Failed to build ParseResponse with exception", - exception: error); - } - } else { - response.error = - ParseError(message: exception.toString(), exception: exception); + return ParseResponse( + error: ParseError( + message: errorMessage ?? exception.toString(), + exception: exception, + code: errorCode ?? -1, + )); } - return response; + + return ParseResponse( + error: ParseError(message: exception.toString(), exception: exception)); + ; } From b3830d02513ea0f37c5ff762911e2c3a9862a2b6 Mon Sep 17 00:00:00 2001 From: Nils Strelow Date: Tue, 23 Mar 2021 01:19:53 +0100 Subject: [PATCH 147/195] Remove unused AppInfo class --- packages/dart/lib/src/data/app_info.dart | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 packages/dart/lib/src/data/app_info.dart diff --git a/packages/dart/lib/src/data/app_info.dart b/packages/dart/lib/src/data/app_info.dart deleted file mode 100644 index 1c4289473..000000000 --- a/packages/dart/lib/src/data/app_info.dart +++ /dev/null @@ -1,13 +0,0 @@ -part of flutter_parse_sdk; - -abstract class AppInfo { - Future getLanguage(); - - Future getAppName(); - - Future getPackageName(); - - Future getVersion(); - - Future getBuildNumber(); -} From 7ea52dcf38980f98902475e6fc379397cb3c6e5d Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Tue, 23 Mar 2021 22:30:45 -0300 Subject: [PATCH 148/195] Nullsafety fixes - Fix Parse Function call - Fix Parse Relation - Fix CoreStoreSembastImp - Updated uuid dependency version --- .../dart/lib/src/objects/parse_function.dart | 6 +-- .../dart/lib/src/objects/parse_relation.dart | 41 +++++++++++-------- .../lib/src/storage/core_store_sem_impl.dart | 16 ++++---- .../dart/lib/src/utils/parse_decoder.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/flutter/lib/parse_server_sdk.dart | 13 +++--- 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_function.dart b/packages/dart/lib/src/objects/parse_function.dart index 073e04e7b..68331baca 100644 --- a/packages/dart/lib/src/objects/parse_function.dart +++ b/packages/dart/lib/src/objects/parse_function.dart @@ -28,8 +28,7 @@ class ParseCloudFunction extends ParseObject { /// /// To add the parameters, create an object and call [set](value to set) Future execute( - {Map? parameters, - Map headers = const {}}) async { + {Map? parameters, Map? headers}) async { final String uri = '${ParseCoreData().serverUrl}$_path'; if (parameters != null) { _setObjectData(parameters); @@ -49,8 +48,7 @@ class ParseCloudFunction extends ParseObject { /// /// To add the parameters, create an object and call [set](value to set) Future executeObjectFunction( - {Map? parameters, - Map headers = const {}}) async { + {Map? parameters, Map? headers}) async { final String uri = '${ParseCoreData().serverUrl}$_path'; if (parameters != null) { _setObjectData(parameters); diff --git a/packages/dart/lib/src/objects/parse_relation.dart b/packages/dart/lib/src/objects/parse_relation.dart index 048f78123..d522cab8b 100644 --- a/packages/dart/lib/src/objects/parse_relation.dart +++ b/packages/dart/lib/src/objects/parse_relation.dart @@ -2,39 +2,48 @@ part of flutter_parse_sdk; // ignore_for_file: always_specify_types class ParseRelation { - ParseRelation({ParseObject? parent, String? key}) { + ParseRelation({required ParseObject parent, required String key}) { _parent = parent; _key = key; + _parentObjectId = parent.objectId!; } - String? _targetClass; + ParseRelation.fromJson(Map map) { + _knownObjects = parseDecode(map['objects']); + _targetClass = map['className']; + } + + //The owning object of this ParseRelation ParseObject? _parent; - String? _key; - Set? _objects = Set(); + // The object Id of the parent. + String _parentObjectId = ''; + //The className of the target objects. + String? _targetClass; + //The key of the relation in the parent object. + String _key = ''; + //For offline caching, we keep track of every object we've known to be in the relation. + Set? _knownObjects = Set(); QueryBuilder getQuery() { - return QueryBuilder(ParseObject(_targetClass!)); + return QueryBuilder(ParseObject(_targetClass!)) + ..whereRelatedTo(_key, _parent!.parseClassName, _parentObjectId); } void add(T object) { _targetClass = object.parseClassName; - _objects!.add(object); - _parent?.addRelation(_key!, _objects!.toList()); + _knownObjects!.add(object); + _parent!.addRelation(_key, _knownObjects!.toList()); } void remove(T object) { _targetClass = object.parseClassName; - _objects!.remove(object); - _parent?.removeRelation(_key!, _objects!.toList()); + _knownObjects!.remove(object); + _parent!.removeRelation(_key, _knownObjects!.toList()); } - Map toJson() => { + Map toJson() => { '__type': keyRelation, - 'className': _objects?.first.parseClassName, - 'objects': parseEncode(_objects?.toList()) + 'className': _targetClass, + 'objects': parseEncode(_knownObjects?.toList()) }; - - ParseRelation fromJson(Map map) => ParseRelation() - .._objects = parseDecode(map['objects']) - .._targetClass = map['className']; } diff --git a/packages/dart/lib/src/storage/core_store_sem_impl.dart b/packages/dart/lib/src/storage/core_store_sem_impl.dart index bf2f97212..59b226bd9 100644 --- a/packages/dart/lib/src/storage/core_store_sem_impl.dart +++ b/packages/dart/lib/src/storage/core_store_sem_impl.dart @@ -7,7 +7,7 @@ class CoreStoreSembastImp implements CoreStore { static CoreStoreSembastImp? _instance; static Future getInstance(String dbPath, - {DatabaseFactory? factory, String? password}) async { + {DatabaseFactory? factory, String password = 'flutter_sdk'}) async { if (_instance == null) { factory ??= !parseIsWeb ? databaseFactoryIo : databaseFactoryWeb; assert(() { @@ -30,9 +30,7 @@ class CoreStoreSembastImp implements CoreStore { return true; }()); final Database db = await factory.openDatabase(dbPath, - codec: !parseIsWeb - ? getXXTeaSembastCodec(password: password ?? 'flutter_sdk') - : null); + codec: !parseIsWeb ? getXXTeaSembastCodec(password: password) : null); _instance = CoreStoreSembastImp._internal(db, StoreRef.main()); } @@ -60,31 +58,31 @@ class CoreStoreSembastImp implements CoreStore { @override Future getBool(String key) async { - final bool? storedItem = await (get(key) as FutureOr); + final bool? storedItem = await (get(key)); return storedItem; } @override Future getDouble(String key) async { - final double? storedItem = await (get(key) as FutureOr); + final double? storedItem = await (get(key)); return storedItem; } @override Future getInt(String key) async { - final int? storedItem = await (get(key) as FutureOr); + final int? storedItem = await (get(key)); return storedItem; } @override Future getString(String key) async { - final String? storedItem = await (get(key) as FutureOr); + final String? storedItem = await (get(key)); return storedItem; } @override Future?> getStringList(String key) async { - final List? storedItem = await (get(key) as FutureOr?>); + final List? storedItem = await (get(key)); return storedItem; } diff --git a/packages/dart/lib/src/utils/parse_decoder.dart b/packages/dart/lib/src/utils/parse_decoder.dart index a49c92e1f..b3f14c1a6 100644 --- a/packages/dart/lib/src/utils/parse_decoder.dart +++ b/packages/dart/lib/src/utils/parse_decoder.dart @@ -72,7 +72,7 @@ dynamic parseDecode(dynamic value) { latitude: latitude.toDouble(), longitude: longitude.toDouble()); case 'Relation': // ignore: always_specify_types - return ParseRelation().fromJson(map); + return ParseRelation.fromJson(map); } } diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 9e2fd6aec..e59073c1d 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: xxtea: ^2.1.0 # Utils - uuid: ^3.0.1 + uuid: ^3.0.2 meta: ^1.3.0 path: ^1.8.0 mime_type: ^1.0.0 diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 2f1e5571f..b1cc6d01a 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -151,25 +151,28 @@ Future dbDirectory() async { class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { CoreStoreSembastImp._(); - static sdk.CoreStoreSembastImp? _sembastImp; + static sdk.CoreStore? _sembastImp; static Future getInstance( - {DatabaseFactory? factory, String? password}) async { + {DatabaseFactory? factory, String password = 'flutter_sdk'}) async { _sembastImp ??= await (sdk.CoreStoreSembastImp.getInstance( await dbDirectory(), factory: factory, - password: password) as FutureOr); + password: password)); return CoreStoreSembastImp._(); } @override - Future clear() => _sembastImp!.clear(); + Future clear() async { + await _sembastImp!.clear(); + return Future.value(true); + } @override Future containsKey(String key) => _sembastImp!.containsKey(key); @override - Future get(String key) => _sembastImp!.get(key); + Future get(String key) => _sembastImp!.get(key); @override Future getBool(String key) => _sembastImp!.getBool(key); From c51981ba7a6a38fb308d6b463068b1cf74631787 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Wed, 24 Mar 2021 19:28:44 -0300 Subject: [PATCH 149/195] Nullsafety fixes / Return Types - Nullsafety fixes - Fix return type in CoreStoreSembastImp.getInstance - Fix return type in CoreStoreSharedPrefsImp,getInstance - Fix return type Parse.initialize - Removing unnecessary parentheses --- .../dart/lib/src/objects/parse_installation.dart | 2 +- .../lib/src/storage/core_store_sem_impl.dart | 15 ++++++++------- packages/flutter/lib/parse_server_sdk.dart | 16 ++++++++-------- .../lib/src/storage/core_store_sp_impl.dart | 3 ++- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_installation.dart b/packages/dart/lib/src/objects/parse_installation.dart index a79d0b2b5..b5e73b6e7 100644 --- a/packages/dart/lib/src/objects/parse_installation.dart +++ b/packages/dart/lib/src/objects/parse_installation.dart @@ -61,7 +61,7 @@ class ParseInstallation extends ParseObject { /// Gets the current installation from storage static Future currentInstallation() async { - return (await (_getFromLocalStore() as FutureOr?)) ?? (await _createInstallation()); + return (await _getFromLocalStore()) ?? (await _createInstallation()); } /// Updates the installation with current device data diff --git a/packages/dart/lib/src/storage/core_store_sem_impl.dart b/packages/dart/lib/src/storage/core_store_sem_impl.dart index 59b226bd9..9fc826c8d 100644 --- a/packages/dart/lib/src/storage/core_store_sem_impl.dart +++ b/packages/dart/lib/src/storage/core_store_sem_impl.dart @@ -6,8 +6,9 @@ class CoreStoreSembastImp implements CoreStore { static CoreStoreSembastImp? _instance; - static Future getInstance(String dbPath, - {DatabaseFactory? factory, String password = 'flutter_sdk'}) async { + static Future getInstance(String dbPath, + {DatabaseFactory? factory, String? password}) async { + password ??= 'flutter_sdk'; if (_instance == null) { factory ??= !parseIsWeb ? databaseFactoryIo : databaseFactoryWeb; assert(() { @@ -58,31 +59,31 @@ class CoreStoreSembastImp implements CoreStore { @override Future getBool(String key) async { - final bool? storedItem = await (get(key)); + final bool? storedItem = await get(key); return storedItem; } @override Future getDouble(String key) async { - final double? storedItem = await (get(key)); + final double? storedItem = await get(key); return storedItem; } @override Future getInt(String key) async { - final int? storedItem = await (get(key)); + final int? storedItem = await get(key); return storedItem; } @override Future getString(String key) async { - final String? storedItem = await (get(key)); + final String? storedItem = await get(key); return storedItem; } @override Future?> getStringList(String key) async { - final List? storedItem = await (get(key)); + final List? storedItem = await get(key); return storedItem; } diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index b1cc6d01a..21576799a 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -39,7 +39,7 @@ class Parse extends sdk.Parse /// [appName], [appVersion] and [appPackageName] are automatically set on Android and IOS, if they are not defined. You should provide a value on web. /// [fileDirectory] is not used on web @override - Future initialize( + Future initialize( String appId, String serverUrl, { bool debug = false, @@ -95,7 +95,7 @@ class Parse extends sdk.Parse (!sdk.parseIsWeb ? (await getTemporaryDirectory()).path : null), appResumedStream: appResumedStream ?? _appResumedStreamController.stream, clientCreator: clientCreator, - ); + ) as Parse; } final StreamController _appResumedStreamController = @@ -153,26 +153,26 @@ class CoreStoreSembastImp implements sdk.CoreStoreSembastImp { static sdk.CoreStore? _sembastImp; - static Future getInstance( - {DatabaseFactory? factory, String password = 'flutter_sdk'}) async { - _sembastImp ??= await (sdk.CoreStoreSembastImp.getInstance( + static Future getInstance( + {DatabaseFactory? factory, String? password}) async { + _sembastImp ??= await sdk.CoreStoreSembastImp.getInstance( await dbDirectory(), factory: factory, - password: password)); + password: password); return CoreStoreSembastImp._(); } @override Future clear() async { await _sembastImp!.clear(); - return Future.value(true); + return true; } @override Future containsKey(String key) => _sembastImp!.containsKey(key); @override - Future get(String key) => _sembastImp!.get(key); + Future get(String key) => _sembastImp!.get(key); @override Future getBool(String key) => _sembastImp!.getBool(key); diff --git a/packages/flutter/lib/src/storage/core_store_sp_impl.dart b/packages/flutter/lib/src/storage/core_store_sp_impl.dart index 126ec1228..00958f4ab 100644 --- a/packages/flutter/lib/src/storage/core_store_sp_impl.dart +++ b/packages/flutter/lib/src/storage/core_store_sp_impl.dart @@ -5,7 +5,8 @@ class CoreStoreSharedPrefsImp implements sdk.CoreStore { static CoreStoreSharedPrefsImp? _instance; - static Future getInstance({SharedPreferences? store}) async { + static Future getInstance( + {SharedPreferences? store}) async { if (_instance == null) { store ??= await SharedPreferences.getInstance(); _instance = CoreStoreSharedPrefsImp._internal(store); From de9819ab8db95fec3fd9f63e5ad02d182518105f Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Sun, 4 Apr 2021 22:48:48 -0300 Subject: [PATCH 150/195] Nullsafety fixes / New ParseObject Fetch method - Fix unpin method - New ParseObject Fetch method - Fix username/emailAddress/password null in currentUser method - Updated dependencies version - Fix ParseLiveListWidget --- packages/dart/lib/src/objects/parse_base.dart | 12 +++++----- .../dart/lib/src/objects/parse_object.dart | 16 +++++++++++++ packages/dart/lib/src/objects/parse_user.dart | 24 +++++++++++-------- packages/dart/pubspec.yaml | 6 ++--- packages/flutter/README.md | 7 +++--- .../lib/src/utils/parse_live_list.dart | 6 ++--- packages/flutter/pubspec.yaml | 12 +++++----- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index a9cff1a0c..9b289a5ff 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -235,7 +235,7 @@ abstract class ParseBase { /// /// Replicates Android SDK pin process and saves object to storage Future unpin({String? key}) async { - if (objectId != null) { + if (objectId != null || key != null) { await ParseCoreData().getStore().remove(key ?? objectId!); return true; } @@ -247,12 +247,12 @@ abstract class ParseBase { /// /// Replicates Android SDK pin process and saves object to storage dynamic fromPin(String objectId) async { - final CoreStore coreStore = ParseCoreData().getStore(); - final String? itemFromStore = await coreStore.getString(objectId); + final CoreStore coreStore = ParseCoreData().getStore(); + final String? itemFromStore = await coreStore.getString(objectId); - if (itemFromStore != null) { - return fromJson(json.decode(itemFromStore)); - } + if (itemFromStore != null) { + return fromJson(json.decode(itemFromStore)); + } return null; } diff --git a/packages/dart/lib/src/objects/parse_object.dart b/packages/dart/lib/src/objects/parse_object.dart index 2c0a64ffa..12b4f9985 100644 --- a/packages/dart/lib/src/objects/parse_object.dart +++ b/packages/dart/lib/src/objects/parse_object.dart @@ -448,4 +448,20 @@ class ParseObject extends ParseBase implements ParseCloneable { return handleException(e, ParseApiRQ.delete, _debug, parseClassName); } } + + ///Fetches this object with the data from the server. Call this whenever you want the state of the + ///object to reflect exactly what is on the server. + Future fetch() async { + if (objectId == null || objectId!.isEmpty) { + throw 'can not fetch without a objectId'; + } + + final ParseResponse response = await this.getObject(this.objectId!); + + if (response.success && response.results != null) { + return response.results!.first; + } else { + return this; + } + } } diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 5fba17a8d..6c336128d 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -24,10 +24,10 @@ class ParseUser extends ParseObject implements ParseCloneable { autoSendSessionId: true, debug: debug, ) { - this.username = username; - this.emailAddress = emailAddress; - this.password = password; - this.sessionToken = sessionToken; + if (username != null) this.username = username; + if (emailAddress != null) this.emailAddress = emailAddress; + if (password != null) this.password = password; + if (sessionToken != null) this.sessionToken = sessionToken; } ParseUser.forQuery() : super(keyClassUser); @@ -51,8 +51,7 @@ class ParseUser extends ParseObject implements ParseCloneable { set password(String? password) { if (_password != password) { _password = password; - if (password != null) - _unsavedChanges[keyVarPassword] = password; + if (password != null) _unsavedChanges[keyVarPassword] = password; } } @@ -111,7 +110,8 @@ class ParseUser extends ParseObject implements ParseCloneable { /// /// Uses token to get the latest version of the user. Prefer this to [getCurrentUserFromServer] /// if using custom ParseUser object - Future getUpdatedUser({bool? debug, ParseClient? client}) async { + Future getUpdatedUser( + {bool? debug, ParseClient? client}) async { final bool _debug = isDebugEnabled(objectLevelDebug: debug); final ParseClient _client = client ?? ParseCoreData().clientCreator( @@ -120,7 +120,8 @@ class ParseUser extends ParseObject implements ParseCloneable { // We can't get the current user and session without a sessionId if ((ParseCoreData().sessionId == null) && (sessionToken == null)) { - return null; + ///return null; + throw 'can not get the current user and session without a sessionId'; } final Map headers = {}; @@ -192,7 +193,7 @@ class ParseUser extends ParseObject implements ParseCloneable { options: ParseNetworkOptions(headers: { keyHeaderRevocableSession: '1', if (installationId != null && !doNotSendInstallationID) - keyHeaderInstallationId: installationId, + keyHeaderInstallationId: installationId, }), data: body); @@ -274,7 +275,10 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Set [doNotSendInstallationID] to 'true' in order to prevent the SDK from sending the installationID to the Server. /// This option is especially useful if you are running you application on web and you don't have permission to add 'X-Parse-Installation-Id' as an allowed header on your parse-server. static Future loginWith(String provider, Object authData, - {bool doNotSendInstallationID = false, String? username, String? password, String? email}) async { + {bool doNotSendInstallationID = false, + String? username, + String? password, + String? email}) async { final ParseUser user = ParseUser.createUser(username, password, email); final ParseResponse response = await user._loginWith(provider, authData, doNotSendInstallationID: doNotSendInstallationID); diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index e59073c1d..743cfdda0 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: # Networking - dio: ^4.0.0-prev3 + dio: ^4.0.0 http: ^0.13.1 web_socket_channel: ^2.0.0 @@ -19,12 +19,12 @@ dependencies: xxtea: ^2.1.0 # Utils - uuid: ^3.0.2 + uuid: ^3.0.3 meta: ^1.3.0 path: ^1.8.0 mime_type: ^1.0.0 dev_dependencies: # Testing - mockito: ^5.0.2 + mockito: ^5.0.3 test: ^1.16.8 diff --git a/packages/flutter/README.md b/packages/flutter/README.md index d258591db..3b2032a06 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -744,10 +744,9 @@ class OAuthLogin { GoogleSignInAccount account = await _googleSignIn.signIn(); GoogleSignInAuthentication authentication = await account.authentication; await ParseUser.loginWith( - 'google', - google(_googleSignIn.currentUser.id, - authentication.accessToken, - authentication.idToken)); + 'google', + google(authentication.accessToken!, _googleSignIn.currentUser!.id, + authentication.idToken!)); } } ``` diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 5fae4024d..12277a140 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -50,7 +50,7 @@ class ParseLiveListWidget extends StatefulWidget { @override _ParseLiveListWidgetState createState() => _ParseLiveListWidgetState( query: query, - removedItemBuilder: removedItemBuilder!, + removedItemBuilder: removedItemBuilder, listenOnAllSubItems: listenOnAllSubItems, listeningIncludes: listeningIncludes, lazyLoading: lazyLoading, @@ -145,7 +145,7 @@ class _ParseLiveListWidgetState sdk.ParseLiveList? _liveList; final GlobalKey _animatedListKey = GlobalKey(); - final ChildBuilder removedItemBuilder; + final ChildBuilder? removedItemBuilder; bool noData = true; @override @@ -226,7 +226,7 @@ class ParseLiveListElementWidget } } -class _ParseLiveListElementWidgetState +class _ParseLiveListElementWidgetState extends State> with SingleTickerProviderStateMixin { _ParseLiveListElementWidgetState(sdk.DataGetter? loadedDataGetter, diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index d67af6cb4..6e2da9a1e 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -11,14 +11,14 @@ dependencies: sdk: flutter parse_server_sdk: -# path: ../dart - git: - url: git://github.com/parse-community/Parse-SDK-Flutter.git - ref: nullsafety - path: packages/dart + path: ../dart +# git: +# url: git://github.com/parse-community/Parse-SDK-Flutter.git +# ref: nullsafety +# path: packages/dart # Networking - dio: ^4.0.0-prev3 + dio: ^4.0.0 connectivity: ^3.0.3 # only used in the flutter part #Database From 7c06ff1f13df3f4f8165b816e40a9a34e4bdff05 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Sun, 4 Apr 2021 22:49:39 -0300 Subject: [PATCH 151/195] Update pubspec.yaml --- packages/flutter/pubspec.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 6e2da9a1e..239c62011 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -11,11 +11,11 @@ dependencies: sdk: flutter parse_server_sdk: - path: ../dart -# git: -# url: git://github.com/parse-community/Parse-SDK-Flutter.git -# ref: nullsafety -# path: packages/dart +# path: ../dart + git: + url: git://github.com/parse-community/Parse-SDK-Flutter.git + ref: nullsafety + path: packages/dart # Networking dio: ^4.0.0 From 8b5f36ea97ff964f02b7a12d933de079003559b9 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Mon, 12 Apr 2021 23:29:20 -0300 Subject: [PATCH 152/195] Update pubspec.yaml --- packages/dart/pubspec.yaml | 6 +++--- packages/flutter/pubspec.yaml | 15 ++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 743cfdda0..def9daefe 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -14,17 +14,17 @@ dependencies: web_socket_channel: ^2.0.0 #Database - sembast: ^3.0.0+4 + sembast: ^3.0.1 sembast_web: ^2.0.0+2 xxtea: ^2.1.0 # Utils - uuid: ^3.0.3 + uuid: ^3.0.4 meta: ^1.3.0 path: ^1.8.0 mime_type: ^1.0.0 dev_dependencies: # Testing - mockito: ^5.0.3 + mockito: ^5.0.4 test: ^1.16.8 diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 239c62011..867d552aa 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -10,12 +10,17 @@ dependencies: flutter: sdk: flutter + # Uncomment for Release version + #parse_server_sdk: ^3.0.0 parse_server_sdk: -# path: ../dart - git: - url: git://github.com/parse-community/Parse-SDK-Flutter.git - ref: nullsafety - path: packages/dart +# Uncomment for local testing + path: ../dart + +# Uncomment for test with Github Branch +# git: +# url: git://github.com/parse-community/Parse-SDK-Flutter.git +# ref: nullsafety +# path: packages/dart # Networking dio: ^4.0.0 From 635c43ec84aebb6deda3e0325bdae870986e5be6 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Wed, 14 Apr 2021 01:47:01 -0300 Subject: [PATCH 153/195] Update pubspec.yaml --- packages/flutter/pubspec.yaml | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 867d552aa..2d291ea34 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -10,17 +10,19 @@ dependencies: flutter: sdk: flutter - # Uncomment for Release version - #parse_server_sdk: ^3.0.0 - parse_server_sdk: -# Uncomment for local testing - path: ../dart - -# Uncomment for test with Github Branch -# git: -# url: git://github.com/parse-community/Parse-SDK-Flutter.git -# ref: nullsafety -# path: packages/dart + # Uncomment for Release version + parse_server_sdk: ^3.0.0 + + # Uncomment for local testing + #parse_server_sdk: + # path: ../dart + + # Uncomment for test with Github Branch + #parse_server_sdk: + # git: + # url: git://github.com/parse-community/Parse-SDK-Flutter.git + # ref: nullsafety + # path: packages/dart # Networking dio: ^4.0.0 From d8f485a90f636b9296bb5596cb24a51d77a5d21b Mon Sep 17 00:00:00 2001 From: Gabriel Costa <65033296+gcostaapps@users.noreply.github.com> Date: Fri, 23 Apr 2021 09:49:28 -0300 Subject: [PATCH 154/195] Added UpdateEvent on ParseLiveList (#606) --- packages/dart/lib/src/utils/parse_live_list.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 8cf640e53..cdbd74ca3 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -377,6 +377,8 @@ class ParseLiveList { oldObject: _list[i].object, paths: _includePaths); if (after(_list[i].object, object) == null) { _list[i].object = object.clone(object.toJson(full: true)); + _eventStreamController.sink.add(ParseLiveListUpdateEvent( + i, object.clone(object.toJson(full: true)))); } else { _list.removeAt(i).dispose(); _eventStreamController.sink.add(ParseLiveListDeleteEvent( @@ -742,6 +744,11 @@ class ParseLiveListAddEvent ParseLiveListAddEvent(int index, T object) : super(index, object); } +class ParseLiveListUpdateEvent + extends ParseLiveListEvent { + ParseLiveListUpdateEvent(int index, T object) : super(index, object); +} + class ParseLiveListDeleteEvent extends ParseLiveListEvent { ParseLiveListDeleteEvent(int index, T object) : super(index, object); From 88b42f7f46ecdc436fbccbaa2b49ceab5e31488e Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Fri, 23 Apr 2021 17:30:03 +0200 Subject: [PATCH 155/195] fix dart tests --- .travis.yml | 3 +- packages/dart/pubspec.yaml | 1 + packages/dart/test/parse_query_test.dart | 34 +++++-- .../dart/test/parse_query_test.mocks.dart | 92 +++++++++++++++++++ 4 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 packages/dart/test/parse_query_test.mocks.dart diff --git a/.travis.yml b/.travis.yml index e1599d287..a6b716b50 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,11 @@ install: script: - (cd packages/dart && pub get) + - (cd packages/dart && dart run build_runner build) - (cd packages/dart && pub run test) - (cd packages/flutter && flutter pub get) - (cd packages/flutter && flutter test --no-pub test/) cache: directories: - - "$HOME/.pub-cache" \ No newline at end of file + - "$HOME/.pub-cache" diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index def9daefe..a9baf22d2 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -26,5 +26,6 @@ dependencies: dev_dependencies: # Testing + build_runner: ^2.0.1 mockito: ^5.0.4 test: ^1.16.8 diff --git a/packages/dart/test/parse_query_test.dart b/packages/dart/test/parse_query_test.dart index ca49b3995..ba343ef40 100644 --- a/packages/dart/test/parse_query_test.dart +++ b/packages/dart/test/parse_query_test.dart @@ -1,13 +1,15 @@ +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:parse_server_sdk/parse_server_sdk.dart'; import 'package:test/test.dart'; -class MockClient extends Mock implements ParseClient {} +import 'parse_query_test.mocks.dart'; +@GenerateMocks([ParseClient]) void main() { group('queryBuilder', () { test('whereRelatedTo', () async { - final MockClient client = MockClient(); + final MockParseClient client = MockParseClient(); await Parse().initialize( 'appId', @@ -27,11 +29,31 @@ void main() { QueryBuilder(ParseObject('_User', client: client)); queryBuilder.whereRelatedTo('likes', 'Post', '8TOXdXf3tz'); - when(client.data).thenReturn(ParseCoreData()); - await queryBuilder.query(); + when(client.get( + any, + options: anyNamed("options"), + onReceiveProgress: anyNamed("onReceiveProgress"), + )).thenAnswer((_) async => ParseNetworkResponse( + statusCode: 200, + data: + "{\"results\":[{\"objectId\":\"eT9muOxBTJ\",\"username\":\"test\",\"createdAt\":\"2021-04-23T13:46:06.092Z\",\"updatedAt\":\"2021-04-23T13:46:23.586Z\",\"ACL\":{\"*\":{\"read\":true},\"eT9muOxBTJ\":{\"read\":true,\"write\":true}}}]}")); - final Uri result = - Uri.parse(verify(client.get(captureAny!)).captured.single); + ParseResponse response = await queryBuilder.query(); + + expect(response.results?.first, isA()); + + ParseObject parseObject = response.results?.first; + + expect(parseObject.get(keyVarUsername), "test"); + expect(parseObject.objectId, "eT9muOxBTJ"); + expect(parseObject.createdAt, DateTime.parse("2021-04-23T13:46:06.092Z")); + expect(parseObject.updatedAt, DateTime.parse("2021-04-23T13:46:23.586Z")); + + final Uri result = Uri.parse(verify(client.get( + captureAny, + options: anyNamed("options"), + onReceiveProgress: anyNamed("onReceiveProgress"), + )).captured.single); expect(result.path, '/classes/_User'); diff --git a/packages/dart/test/parse_query_test.mocks.dart b/packages/dart/test/parse_query_test.mocks.dart new file mode 100644 index 000000000..e2d9b8392 --- /dev/null +++ b/packages/dart/test/parse_query_test.mocks.dart @@ -0,0 +1,92 @@ +// Mocks generated by Mockito 5.0.5 from annotations +// in parse_server_sdk/test/parse_query_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i3; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:parse_server_sdk/parse_server_sdk.dart' as _i2; + +// ignore_for_file: comment_references +// ignore_for_file: unnecessary_parenthesis + +class _FakeParseCoreData extends _i1.Fake implements _i2.ParseCoreData {} + +class _FakeParseNetworkResponse extends _i1.Fake + implements _i2.ParseNetworkResponse {} + +class _FakeParseNetworkByteResponse extends _i1.Fake + implements _i2.ParseNetworkByteResponse {} + +/// A class which mocks [ParseClient]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockParseClient extends _i1.Mock implements _i2.ParseClient { + MockParseClient() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.ParseCoreData get data => (super.noSuchMethod(Invocation.getter(#data), + returnValue: _FakeParseCoreData()) as _i2.ParseCoreData); + @override + _i3.Future<_i2.ParseNetworkResponse> get(String? path, + {_i2.ParseNetworkOptions? options, + _i2.ProgressCallback? onReceiveProgress}) => + (super.noSuchMethod( + Invocation.method(#get, [path], + {#options: options, #onReceiveProgress: onReceiveProgress}), + returnValue: Future<_i2.ParseNetworkResponse>.value( + _FakeParseNetworkResponse())) + as _i3.Future<_i2.ParseNetworkResponse>); + @override + _i3.Future<_i2.ParseNetworkResponse> put(String? path, + {String? data, _i2.ParseNetworkOptions? options}) => + (super.noSuchMethod( + Invocation.method(#put, [path], {#data: data, #options: options}), + returnValue: Future<_i2.ParseNetworkResponse>.value( + _FakeParseNetworkResponse())) + as _i3.Future<_i2.ParseNetworkResponse>); + @override + _i3.Future<_i2.ParseNetworkResponse> post(String? path, + {String? data, _i2.ParseNetworkOptions? options}) => + (super.noSuchMethod( + Invocation.method(#post, [path], {#data: data, #options: options}), + returnValue: Future<_i2.ParseNetworkResponse>.value( + _FakeParseNetworkResponse())) as _i3 + .Future<_i2.ParseNetworkResponse>); + @override + _i3.Future<_i2.ParseNetworkResponse> postBytes(String? path, + {_i3.Stream>? data, + _i2.ParseNetworkOptions? options, + _i2.ProgressCallback? onSendProgress}) => + (super.noSuchMethod( + Invocation.method(#postBytes, [ + path + ], { + #data: data, + #options: options, + #onSendProgress: onSendProgress + }), + returnValue: Future<_i2.ParseNetworkResponse>.value( + _FakeParseNetworkResponse())) + as _i3.Future<_i2.ParseNetworkResponse>); + @override + _i3.Future<_i2.ParseNetworkResponse> delete(String? path, + {_i2.ParseNetworkOptions? options}) => + (super.noSuchMethod( + Invocation.method(#delete, [path], {#options: options}), + returnValue: Future<_i2.ParseNetworkResponse>.value( + _FakeParseNetworkResponse())) + as _i3.Future<_i2.ParseNetworkResponse>); + @override + _i3.Future<_i2.ParseNetworkByteResponse> getBytes(String? path, + {_i2.ParseNetworkOptions? options, + _i2.ProgressCallback? onReceiveProgress}) => + (super.noSuchMethod( + Invocation.method(#getBytes, [path], + {#options: options, #onReceiveProgress: onReceiveProgress}), + returnValue: Future<_i2.ParseNetworkByteResponse>.value( + _FakeParseNetworkByteResponse())) + as _i3.Future<_i2.ParseNetworkByteResponse>); +} From f331fb9cce7f56a968429d15cd24e596b92650b9 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Fri, 23 Apr 2021 17:31:53 +0200 Subject: [PATCH 156/195] Delete parse_query_test.dart Already tested in the dart package --- packages/flutter/test/parse_query_test.dart | 47 --------------------- 1 file changed, 47 deletions(-) delete mode 100644 packages/flutter/test/parse_query_test.dart diff --git a/packages/flutter/test/parse_query_test.dart b/packages/flutter/test/parse_query_test.dart deleted file mode 100644 index 9285f04a7..000000000 --- a/packages/flutter/test/parse_query_test.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:parse_server_sdk_flutter/parse_server_sdk.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -class MockClient extends Mock implements ParseClient {} - -void main() { - SharedPreferences.setMockInitialValues(Map()); - - group('queryBuilder', () { - test('whereRelatedTo', () async { - final MockClient client = MockClient(); - - await Parse().initialize( - 'appId', - 'https://test.parse.com', - debug: true, - // to prevent automatic detection - fileDirectory: 'someDirectory', - // to prevent automatic detection - appName: 'appName', - // to prevent automatic detection - appPackageName: 'somePackageName', - // to prevent automatic detection - appVersion: 'someAppVersion', - ); - - final QueryBuilder queryBuilder = - QueryBuilder(ParseObject('_User', client: client)); - queryBuilder.whereRelatedTo('likes', 'Post', '8TOXdXf3tz'); - - when(client.data).thenReturn(ParseCoreData()); - await queryBuilder.query(); - - final Uri result = - Uri.parse(verify(client.get(captureAny!)).captured.single); - - expect(result.path, '/classes/_User'); - - final Uri expectedQuery = Uri( - query: - 'where={"\$relatedTo":{"object":{"__type":"Pointer","className":"Post","objectId":"8TOXdXf3tz"},"key":"likes"}}'); - expect(result.query, expectedQuery.query); - }); - }); -} From 851531afccba8d370e9123f3f5093cbd1c31ee7b Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Fri, 23 Apr 2021 17:40:41 +0200 Subject: [PATCH 157/195] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a6b716b50..8819014fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ install: script: - (cd packages/dart && pub get) - - (cd packages/dart && dart run build_runner build) + - (cd packages/dart && dart run build_runner build --delete-conflicting-outputs) - (cd packages/dart && pub run test) - (cd packages/flutter && flutter pub get) - (cd packages/flutter && flutter test --no-pub test/) From acf12240c7d9ddb68a14bf04090423ab14802e1b Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Thu, 29 Apr 2021 16:31:17 +0200 Subject: [PATCH 158/195] Additional query methods (#611) * add first and find to the QueryBuilder * add documentation for first() and find() --- packages/dart/README.md | 9 ++++++++ .../dart/lib/src/network/parse_query.dart | 21 +++++++++++++++++++ packages/flutter/README.md | 9 ++++++++ 3 files changed, 39 insertions(+) diff --git a/packages/dart/README.md b/packages/dart/README.md index 8d75418dd..8b72b1daf 100644 --- a/packages/dart/README.md +++ b/packages/dart/README.md @@ -248,6 +248,15 @@ if (dietPlan.success) { } ``` +### Alternative query methods + +The standard query method `query()` returns a `ParseResponse` that contains the result or the error. As an alternative, you can also use `Future> find()` for receiving options. +This method returns an `Future` that either resolves in an error (equivalent of the error in the `ParseResponse`) or an `List` containing the queried objects. One difference, you should be aware of, is the fact, that `Future> find()` will return an empty list instead of the 'No results' error you receive in case no object matches you query. + +Choosing between `query()` and `find()` comes down to personal preference. Both methods can be used for querying a `ParseQuery`, just the output method differs. + +Similar to `find()` the `QueryBuilder` also has a function called `Future? first()`. Just like `find()` `first()` is just a convenience method that makes querying the first object satisfying the query simpler. `first()` returns an `Future`, that resoles in an error or the first object matching the query. In case no object satisfies the query, the result will be `null`. + ## Complex queries You can create complex queries to really put your database to the test: diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 4165adac0..627759a35 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -513,4 +513,25 @@ class QueryBuilder { }); return result; } + + /// Find the first object that satisfies the query. + /// Returns null, if no object is found. + Future? first() async { + ParseResponse parseResponse = + await (QueryBuilder.copy(this)..setLimit(1)).query(); + if (parseResponse.success) { + return parseResponse.results?.first; + } + throw parseResponse.error ?? ParseError(); + } + + /// Find the objects that satisfy the query. + /// Returns an empty list if no objects are found. + Future> find() async { + ParseResponse parseResponse = await query(); + if (parseResponse.success) { + return parseResponse.results?.map((e) => e as T).toList() ?? []; + } + throw parseResponse.error ?? ParseError(); + } } diff --git a/packages/flutter/README.md b/packages/flutter/README.md index 3b2032a06..9d91da202 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -265,6 +265,15 @@ if (response.success) { } ``` +### Alternative query methods + +The standard query method `query()` returns a `ParseResponse` that contains the result or the error. As an alternative, you can also use `Future> find()` for receiving options. +This method returns an `Future` that either resolves in an error (equivalent of the error in the `ParseResponse`) or an `List` containing the queried objects. One difference, you should be aware of, is the fact, that `Future> find()` will return an empty list instead of the 'No results' error you receive in case no object matches you query. + +Choosing between `query()` and `find()` comes down to personal preference. Both methods can be used for querying a `ParseQuery`, just the output method differs. + +Similar to `find()` the `QueryBuilder` also has a function called `Future? first()`. Just like `find()` `first()` is just a convenience method that makes querying the first object satisfying the query simpler. `first()` returns an `Future`, that resoles in an error or the first object matching the query. In case no object satisfies the query, the result will be `null`. + ## Complex queries You can create complex queries to really put your database to the test: From ab9a1bcb6702a3abce5e56b057688210e00a24fc Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Thu, 29 Apr 2021 16:33:17 +0200 Subject: [PATCH 159/195] fix livequery (#608) Fix: ParseLiveQueryWidget wont add element to an empty list --- .../lib/src/utils/parse_live_list.dart | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 12277a140..0463c98bd 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -92,24 +92,20 @@ class _ParseLiveListWidgetState listeningIncludes: listeningIncludes, lazyLoading: lazyLoading, preloadedColumns: preloadedColumns, - ).then((sdk.ParseLiveList value) { - if (value.size > 0) { - setState(() { - noData = false; - }); - } else { - setState(() { - noData = true; - }); - } + ).then((sdk.ParseLiveList livelist) { setState(() { - _liveList = value; + _noData = livelist.size == 0; + _liveList = livelist; _liveList!.stream .listen((sdk.ParseLiveListEvent event) { if (event is sdk.ParseLiveListAddEvent) { - if (_animatedListKey.currentState != null) + if (_animatedListKey.currentState != null) { _animatedListKey.currentState! .insertItem(event.index, duration: widget.duration); + } + setState(() { + _noData = livelist.size == 0; + }); } else if (event is sdk.ParseLiveListDeleteEvent) { _animatedListKey.currentState!.removeItem( event.index, @@ -126,15 +122,9 @@ class _ParseLiveListWidgetState preLoadedData: () => event.object as T, ), duration: widget.duration); - if (value.size > 0) { - setState(() { - noData = false; - }); - } else { - setState(() { - noData = true; - }); - } + setState(() { + _noData = livelist.size == 0; + }); } }); }); @@ -146,17 +136,26 @@ class _ParseLiveListWidgetState final GlobalKey _animatedListKey = GlobalKey(); final ChildBuilder? removedItemBuilder; - bool noData = true; + bool _noData = true; @override Widget build(BuildContext context) { if (_liveList == null) { return widget.listLoadingElement ?? Container(); + } else { + return Stack( + children: [ + if (widget.queryEmptyElement != null) + AnimatedOpacity( + opacity: _noData ? 1 : 0, + duration: widget.duration, + child: widget.queryEmptyElement, + ), + //_liveList isn't (checked above) + buildAnimatedList(_liveList!), + ], + ); } - if (noData) { - return widget.queryEmptyElement ?? Container(); - } - return buildAnimatedList(_liveList!); } @override From 13be28ef0672d7b987e1a61939b68127623aa5d4 Mon Sep 17 00:00:00 2001 From: Gabriel Costa <65033296+gcostaapps@users.noreply.github.com> Date: Thu, 29 Apr 2021 21:11:14 -0300 Subject: [PATCH 160/195] Fix error on live query when pointer is null --- .../dart/lib/src/utils/parse_live_list.dart | 80 ++++++++++--------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index cdbd74ca3..2fb58faad 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -265,56 +265,58 @@ class ParseLiveList { for (String key in paths.keys) { if (object.containsKey(key)) { - ParseObject includedObject = object.get(key)!; - //If the object is not fetched - if (!includedObject.containsKey(keyVarUpdatedAt)) { - //See if oldObject contains key - if (oldObject != null && oldObject.containsKey(key)) { - includedObject = oldObject.get(key)!; - //If the object is not fetched || the ids don't match / the pointer changed - if (!includedObject.containsKey(keyVarUpdatedAt) || - includedObject.objectId != - object.get(key)!.objectId) { - includedObject = object.get(key)!; + ParseObject? includedObject = object.get(key); + if(includedObject != null){ + //If the object is not fetched + if (!includedObject.containsKey(keyVarUpdatedAt)) { + //See if oldObject contains key + if (oldObject != null && oldObject.containsKey(key)) { + includedObject = oldObject.get(key)!; + //If the object is not fetched || the ids don't match / the pointer changed + if (!includedObject.containsKey(keyVarUpdatedAt) || + includedObject.objectId != + object.get(key)!.objectId) { + includedObject = object.get(key)!; + //fetch from web including sub objects + //same as down there + final QueryBuilder queryBuilder = QueryBuilder< + ParseObject>(ParseObject(includedObject.parseClassName)) + ..whereEqualTo(keyVarObjectId, includedObject.objectId) + ..includeObject(_toIncludeStringList(paths[key])); + loadingNodes.add(queryBuilder + .query() + .then((ParseResponse parseResponse) { + if (parseResponse.success && + parseResponse.results!.length == 1) { + // ignore: deprecated_member_use_from_same_package + object[key] = parseResponse.results![0]; + } + })); + continue; + } else { + // ignore: deprecated_member_use_from_same_package + object[key] = includedObject; + //recursion + loadingNodes + .add(_loadIncludes(includedObject, paths: paths[key])); + continue; + } + } else { //fetch from web including sub objects - //same as down there + //same as up there final QueryBuilder queryBuilder = QueryBuilder< ParseObject>(ParseObject(includedObject.parseClassName)) ..whereEqualTo(keyVarObjectId, includedObject.objectId) ..includeObject(_toIncludeStringList(paths[key])); - loadingNodes.add(queryBuilder - .query() - .then((ParseResponse parseResponse) { - if (parseResponse.success && - parseResponse.results!.length == 1) { + loadingNodes.add( + queryBuilder.query().then((ParseResponse parseResponse) { + if (parseResponse.success && parseResponse.results!.length == 1) { // ignore: deprecated_member_use_from_same_package object[key] = parseResponse.results![0]; } })); continue; - } else { - // ignore: deprecated_member_use_from_same_package - object[key] = includedObject; - //recursion - loadingNodes - .add(_loadIncludes(includedObject, paths: paths[key])); - continue; } - } else { - //fetch from web including sub objects - //same as up there - final QueryBuilder queryBuilder = QueryBuilder< - ParseObject>(ParseObject(includedObject.parseClassName)) - ..whereEqualTo(keyVarObjectId, includedObject.objectId) - ..includeObject(_toIncludeStringList(paths[key])); - loadingNodes.add( - queryBuilder.query().then((ParseResponse parseResponse) { - if (parseResponse.success && parseResponse.results!.length == 1) { - // ignore: deprecated_member_use_from_same_package - object[key] = parseResponse.results![0]; - } - })); - continue; } } else { //recursion From 8f06fe0517cc3b79223763c8c4074e9f88c1b594 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Fri, 30 Apr 2021 13:31:24 -0300 Subject: [PATCH 161/195] Connectivity switched to connectivity_plus to support windows --- .../.plugin_symlinks/connectivity_plus_linux | 1 + .../.plugin_symlinks/path_provider_linux | 1 + .../.plugin_symlinks/shared_preferences_linux | 1 + .../linux/flutter/generated_plugin_registrant.cc | 9 +++++++++ .../linux/flutter/generated_plugin_registrant.h | 13 +++++++++++++ .../example/linux/flutter/generated_plugins.cmake | 15 +++++++++++++++ .../Flutter/ephemeral/Flutter-Generated.xcconfig | 11 +++++++++++ .../ephemeral/flutter_export_environment.sh | 12 ++++++++++++ packages/flutter/lib/parse_server_sdk.dart | 2 +- packages/flutter/pubspec.yaml | 2 +- 10 files changed, 65 insertions(+), 2 deletions(-) create mode 120000 packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux create mode 120000 packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux create mode 120000 packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux create mode 100644 packages/flutter/example/linux/flutter/generated_plugin_registrant.cc create mode 100644 packages/flutter/example/linux/flutter/generated_plugin_registrant.h create mode 100644 packages/flutter/example/linux/flutter/generated_plugins.cmake create mode 100644 packages/flutter/example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig create mode 100644 packages/flutter/example/macos/Flutter/ephemeral/flutter_export_environment.sh diff --git a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux new file mode 120000 index 000000000..65fa57407 --- /dev/null +++ b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux @@ -0,0 +1 @@ +C:/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.0.1/ \ No newline at end of file diff --git a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux new file mode 120000 index 000000000..4ba2c51d0 --- /dev/null +++ b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux @@ -0,0 +1 @@ +C:/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.0.0/ \ No newline at end of file diff --git a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux new file mode 120000 index 000000000..6490074a9 --- /dev/null +++ b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux @@ -0,0 +1 @@ +C:/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_linux-2.0.0/ \ No newline at end of file diff --git a/packages/flutter/example/linux/flutter/generated_plugin_registrant.cc b/packages/flutter/example/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000..d38195aa0 --- /dev/null +++ b/packages/flutter/example/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,9 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/packages/flutter/example/linux/flutter/generated_plugin_registrant.h b/packages/flutter/example/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000..9bf747894 --- /dev/null +++ b/packages/flutter/example/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/packages/flutter/example/linux/flutter/generated_plugins.cmake b/packages/flutter/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000..51436ae8c --- /dev/null +++ b/packages/flutter/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,15 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) diff --git a/packages/flutter/example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig b/packages/flutter/example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig new file mode 100644 index 000000000..05050e176 --- /dev/null +++ b/packages/flutter/example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig @@ -0,0 +1,11 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=C:\flutter +FLUTTER_APPLICATION_PATH=D:\GithubProjects\parse\Parse-SDK-Flutter\packages\flutter\example +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=1.0.0 +FLUTTER_BUILD_NUMBER=1 +EXCLUDED_ARCHS=arm64 +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=false +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=.packages diff --git a/packages/flutter/example/macos/Flutter/ephemeral/flutter_export_environment.sh b/packages/flutter/example/macos/Flutter/ephemeral/flutter_export_environment.sh new file mode 100644 index 000000000..6f35a01d7 --- /dev/null +++ b/packages/flutter/example/macos/Flutter/ephemeral/flutter_export_environment.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=C:\flutter" +export "FLUTTER_APPLICATION_PATH=D:\GithubProjects\parse\Parse-SDK-Flutter\packages\flutter\example" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "EXCLUDED_ARCHS=arm64" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=false" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.packages" diff --git a/packages/flutter/lib/parse_server_sdk.dart b/packages/flutter/lib/parse_server_sdk.dart index 21576799a..8844aa7f4 100644 --- a/packages/flutter/lib/parse_server_sdk.dart +++ b/packages/flutter/lib/parse_server_sdk.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:ui' as ui; -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:package_info_plus/package_info_plus.dart'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 2d291ea34..a6e36fca8 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -26,7 +26,7 @@ dependencies: # Networking dio: ^4.0.0 - connectivity: ^3.0.3 # only used in the flutter part + connectivity_plus: ^1.0.1 # only used in the flutter part #Database shared_preferences: ^2.0.5 # only used in the flutter part From e6d4f7130b5ef2802ab8964a2f3b58df249a3201 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Fri, 30 Apr 2021 13:40:52 -0300 Subject: [PATCH 162/195] Update pubspec for point to dart package in github --- packages/flutter/pubspec.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index a6e36fca8..449289371 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -11,18 +11,18 @@ dependencies: sdk: flutter # Uncomment for Release version - parse_server_sdk: ^3.0.0 + #parse_server_sdk: ^3.0.0 # Uncomment for local testing #parse_server_sdk: # path: ../dart # Uncomment for test with Github Branch - #parse_server_sdk: - # git: - # url: git://github.com/parse-community/Parse-SDK-Flutter.git - # ref: nullsafety - # path: packages/dart + parse_server_sdk: + git: + url: https://github.com/gcostaapps/Parse-SDK-Flutter.git + ref: nullsafety + path: packages/dart # Networking dio: ^4.0.0 From 4801624d3be5899b115beec6648fe87027437e91 Mon Sep 17 00:00:00 2001 From: Dillon Shaffer Date: Sat, 8 May 2021 21:08:54 -0500 Subject: [PATCH 163/195] Prevent a TypeError from being thrown while parsing an object from a map whose createdAt or updatedAt properties are not Strings --- packages/dart/lib/src/objects/parse_base.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_base.dart b/packages/dart/lib/src/objects/parse_base.dart index 9b289a5ff..6521729d1 100644 --- a/packages/dart/lib/src/objects/parse_base.dart +++ b/packages/dart/lib/src/objects/parse_base.dart @@ -125,16 +125,16 @@ abstract class ParseBase { } else if (key == keyVarObjectId) { _getObjectData()[keyVarObjectId] = value; } else if (key == keyVarCreatedAt) { - if (keyVarCreatedAt is String) { + if (value is String) { _getObjectData()[keyVarCreatedAt] = _parseDateFormat.parse(value); } else { _getObjectData()[keyVarCreatedAt] = value; } } else if (key == keyVarUpdatedAt) { - if (keyVarUpdatedAt is String) { + if (value is String) { _getObjectData()[keyVarUpdatedAt] = _parseDateFormat.parse(value); } else { - _getObjectData()[keyVarUpdatedAt] = _parseDateFormat.parse(value); + _getObjectData()[keyVarUpdatedAt] = value; } } else if (key == keyVarAcl) { _getObjectData()[keyVarAcl] = ParseACL().fromJson(value); From eb1ffcb52bf450a9f9b4be99ed7f6de71f926228 Mon Sep 17 00:00:00 2001 From: Igor Berlenko Date: Fri, 21 May 2021 12:00:45 +0800 Subject: [PATCH 164/195] Update README.md --- packages/flutter/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/README.md b/packages/flutter/README.md index b4ff272bf..3663498a2 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -14,7 +14,7 @@ This is a work in progress and we are consistently updating it. Please let us kn To install, either add to your pubspec.yaml ```yml dependencies: - parse_server_sdk: ^2.1.0 + parse_server_sdk_flutter: ^3.0.0 ``` or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. From a0ede7670522f95c332800c075cd65e7a44dc5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksander=20D=C5=82ugosz?= Date: Fri, 4 Jun 2021 14:51:22 +0200 Subject: [PATCH 165/195] Expose additionalHeaders field using a getter and setter on the parent class with nullsafety --- packages/dart/lib/src/network/parse_http_client.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/dart/lib/src/network/parse_http_client.dart b/packages/dart/lib/src/network/parse_http_client.dart index e2481afe3..3992373d9 100644 --- a/packages/dart/lib/src/network/parse_http_client.dart +++ b/packages/dart/lib/src/network/parse_http_client.dart @@ -16,6 +16,11 @@ class ParseHTTPClient extends ParseClient { late _ParseHTTPClient _client; + Map? get additionalHeaders => _client.additionalHeaders; + + set additionalHeaders(Map? additionalHeaders) => + _client.additionalHeaders = additionalHeaders; + @override Future get( String path, { From 654e1e3e582e0ae51df3c1e6308fe391dd1a10a2 Mon Sep 17 00:00:00 2001 From: bernhardfrenking <58109356+bernhardfrenking@users.noreply.github.com> Date: Sun, 6 Jun 2021 19:06:26 +0200 Subject: [PATCH 166/195] :bug: containsKey on wrong key The containsKey check is on the wrong key (keyVarObjectId) instead of (keyParamSessionToken) - therefore it fails on null safety, if the sessionToken is not provided in responseData (for example in case of signUp) --- packages/dart/lib/src/objects/parse_user.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 234118670..2ef8495a2 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -474,7 +474,7 @@ class ParseUser extends ParseObject implements ParseCloneable { handleResponse(user, response, type, debug, className); final Map responseData = jsonDecode(response.data); - if (responseData.containsKey(keyVarObjectId)) { + if (responseData.containsKey(keyParamSessionToken)) { user.sessionToken = responseData[keyParamSessionToken]; ParseCoreData().setSessionId(user.sessionToken); } From c5e903c6cf86a2f4d28b8b74afd3c72eb40f882c Mon Sep 17 00:00:00 2001 From: bernhardfrenking <58109356+bernhardfrenking@users.noreply.github.com> Date: Mon, 7 Jun 2021 07:50:54 +0200 Subject: [PATCH 167/195] null safety for setSessionId on keyParamSessionToken if sessionToken is not provided in userMap, setSessionId will fail on null. Furthermore the userMap should only be returned if a sessionToken is provided. --- packages/dart/lib/src/objects/parse_user.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/dart/lib/src/objects/parse_user.dart b/packages/dart/lib/src/objects/parse_user.dart index 2ef8495a2..52bb075db 100644 --- a/packages/dart/lib/src/objects/parse_user.dart +++ b/packages/dart/lib/src/objects/parse_user.dart @@ -444,19 +444,20 @@ class ParseUser extends ParseObject implements ParseCloneable { return handleException(e, ParseApiRQ.getAll, _debug, keyClassUser); } } - static Future _getUserFromLocalStore( - {ParseCloneable cloneable}) async { + {ParseCloneable? cloneable}) async { final CoreStore coreStore = ParseCoreData().getStore(); - final String userJson = await coreStore.getString(keyParseStoreUser); + final String? userJson = await coreStore.getString(keyParseStoreUser); if (userJson != null) { final Map userMap = json.decode(userJson); if (cloneable != null) { return cloneable.clone(userMap); } else { - ParseCoreData().setSessionId(userMap[keyParamSessionToken]); - return parseDecode(userMap); + if (userMap.containsKey(keyParamSessionToken)) { + ParseCoreData().setSessionId(userMap[keyParamSessionToken]); + return parseDecode(userMap); + } } } From 9097ccdc3b39a2d753d113e1d5b656f5a6488c97 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Mon, 7 Jun 2021 21:52:49 -0300 Subject: [PATCH 168/195] Update pubspec.yaml Set package path. Retrieve from pub.dev and not git. --- packages/flutter/pubspec.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 449289371..4c310a9bb 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -11,18 +11,18 @@ dependencies: sdk: flutter # Uncomment for Release version - #parse_server_sdk: ^3.0.0 + parse_server_sdk: ^3.0.0 # Uncomment for local testing #parse_server_sdk: # path: ../dart # Uncomment for test with Github Branch - parse_server_sdk: - git: - url: https://github.com/gcostaapps/Parse-SDK-Flutter.git - ref: nullsafety - path: packages/dart + #parse_server_sdk: + # git: + # url: https://github.com/gcostaapps/Parse-SDK-Flutter.git + # ref: nullsafety + # path: packages/dart # Networking dio: ^4.0.0 @@ -41,4 +41,4 @@ dev_dependencies: # Testing flutter_test: sdk: flutter - mockito: ^5.0.2 \ No newline at end of file + mockito: ^5.0.2 From 5fb29a41de60d8ecdd47b2d19592c3d43698366e Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Mon, 7 Jun 2021 21:54:54 -0300 Subject: [PATCH 169/195] Update pubspec.yaml Set package path. Retrieve from pub.dev and not git. --- packages/flutter/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 4c310a9bb..38387bcff 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -20,7 +20,7 @@ dependencies: # Uncomment for test with Github Branch #parse_server_sdk: # git: - # url: https://github.com/gcostaapps/Parse-SDK-Flutter.git + # url: https://github.com/parse-community/Parse-SDK-Flutter.git # ref: nullsafety # path: packages/dart From d5223d13c81639d2b09b39618288ec4ee4f91a94 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:25:15 +0200 Subject: [PATCH 170/195] make object in QueryBuilder not nullable We might have to discuss, wether we consider this to be a breaking change compared to 3.0.0. I have named the new version 3.0.1 for now. I think this should be fine. This change makes sense, as setting object to null (possible with the prior default constructor) would brake the whole QueryBuilder. --- .../lib/src/network/parse_live_query.dart | 2 +- .../dart/lib/src/network/parse_query.dart | 36 ++++++++++--------- .../dart/lib/src/utils/parse_live_list.dart | 4 +-- packages/dart/pubspec.yaml | 3 +- packages/flutter/pubspec.yaml | 4 +-- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 16389586a..1c83c1bb5 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -347,7 +347,7 @@ class LiveQueryClient { 'op': 'subscribe', 'requestId': subscription.requestId, 'query': { - 'className': query.object!.parseClassName, + 'className': query.object.parseClassName, 'where': _whereMap, if (keysToReturn != null && keysToReturn.isNotEmpty) 'fields': keysToReturn diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 627759a35..000bd64fd 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -5,8 +5,9 @@ class QueryBuilder { /// Class to create complex queries QueryBuilder(this.object) : super(); - QueryBuilder.name(String classname) - : this(ParseCoreData.instance.createObject(classname) as T?); + factory QueryBuilder.name(String classname) { + return QueryBuilder(ParseCoreData.instance.createObject(classname) as T); + } QueryBuilder.or(this.object, List> list) { String query = '"\$or":['; @@ -20,20 +21,21 @@ class QueryBuilder { queries.add(MapEntry(_NO_OPERATOR_NEEDED, query)); } - QueryBuilder.copy(QueryBuilder query) { - object = query.object; - queries = query.queries + factory QueryBuilder.copy(QueryBuilder query) { + QueryBuilder copy = QueryBuilder(query.object); + copy.queries = query.queries .map((MapEntry entry) => MapEntry(entry.key, entry.value.toString())) .toList(); query.limiters.forEach((String key, dynamic value) => - limiters.putIfAbsent(key, () => value.toString())); + copy.limiters.putIfAbsent(key, () => value.toString())); + return copy; } static const String _NO_OPERATOR_NEEDED = 'NO_OP'; static const String _SINGLE_QUERY = 'SINGLE_QUERY'; - T? object; + T object; List> queries = >[]; final Map limiters = Map(); @@ -284,18 +286,20 @@ class QueryBuilder { } // Add a constraint to the query that requires a particular key's value match another QueryBuilder - void whereMatchesQuery(String column, QueryBuilder query) { + void whereMatchesQuery( + String column, QueryBuilder query) { final String inQuery = - query._buildQueryRelational(query.object!.parseClassName); + query._buildQueryRelational(query.object.parseClassName); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$inQuery\":$inQuery}')); } //Add a constraint to the query that requires a particular key's value does not match another QueryBuilder - void whereDoesNotMatchQuery(String column, QueryBuilder query) { + void whereDoesNotMatchQuery( + String column, QueryBuilder query) { final String inQuery = - query._buildQueryRelational(query.object!.parseClassName); + query._buildQueryRelational(query.object.parseClassName); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$notInQuery\":$inQuery}')); @@ -315,7 +319,7 @@ class QueryBuilder { } final String inQuery = - query._buildQueryRelationalKey(query.object!.parseClassName, keyInQuery); + query._buildQueryRelationalKey(query.object.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$select\":$inQuery}')); @@ -335,7 +339,7 @@ class QueryBuilder { } final String inQuery = - query._buildQueryRelationalKey(query.object!.parseClassName, keyInQuery); + query._buildQueryRelationalKey(query.object.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$dontSelect\":$inQuery}')); @@ -346,7 +350,7 @@ class QueryBuilder { /// Make sure to call this after defining your queries Future query( {ProgressCallback? progressCallback}) async { - return object!.query( + return object.query( buildQuery(), progressCallback: progressCallback, ); @@ -355,12 +359,12 @@ class QueryBuilder { Future distinct( String className) async { final String queryString = 'distinct=$className'; - return object!.distinct(queryString); + return object.distinct(queryString); } ///Counts the number of objects that match this query Future count() async { - return object!.query(_buildQueryCount()); + return object.query(_buildQueryCount()); } /// Builds the query for Parse diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 2fb58faad..b2ecbb51b 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -165,7 +165,7 @@ class ParseLiveList { LiveQuery() .client .subscribe(QueryBuilder.copy(_query), - copyObject: _query.object!.clone(_query.object!.toJson())) + copyObject: _query.object.clone(_query.object.toJson())) .then((Subscription subscription) { _liveQuerySubscription = subscription; @@ -266,7 +266,7 @@ class ParseLiveList { for (String key in paths.keys) { if (object.containsKey(key)) { ParseObject? includedObject = object.get(key); - if(includedObject != null){ + if (includedObject != null) { //If the object is not fetched if (!includedObject.containsKey(keyVarUpdatedAt)) { //See if oldObject contains key diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index a9baf22d2..efe5c5410 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,13 +1,12 @@ name: parse_server_sdk description: Dart plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 3.0.0 +version: 3.0.1 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: sdk: '>=2.12.0 <3.0.0' dependencies: - # Networking dio: ^4.0.0 http: ^0.13.1 diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 38387bcff..2c6d22b2c 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk_flutter description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 3.0.0 +version: 3.0.1 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: @@ -11,7 +11,7 @@ dependencies: sdk: flutter # Uncomment for Release version - parse_server_sdk: ^3.0.0 + parse_server_sdk: ^3.0.1 # Uncomment for local testing #parse_server_sdk: From 1935c5b004bfbb5e80ffa747624379b7a8904e1a Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:27:50 +0200 Subject: [PATCH 171/195] parse_live_list: fix unmodifiable list --- packages/dart/lib/src/utils/parse_live_list.dart | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index b2ecbb51b..1a2304dbc 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -133,7 +133,7 @@ class ParseLiveList { if (_debug) print('ParseLiveList: lazyLoading is ${_lazyLoading ? 'on' : 'off'}'); if (_lazyLoading) { - final List keys = _preloadedColumns; + final List keys = _preloadedColumns.toList(); if (_lazyLoading && query.limiters.containsKey('order')) keys.addAll( query.limiters['order'].toString().split(',').map((String string) { @@ -480,12 +480,11 @@ class ParseLiveList { } class ParseLiveElement extends ParseLiveListElement { - ParseLiveElement(T object, - {bool loaded = false, List? includeObject}) + ParseLiveElement(T object, {bool loaded = false, List? includeObject}) : super(object, - loaded: loaded, - updatedSubItems: - ParseLiveList._toIncludeMap(includeObject ?? [])) { + loaded: loaded, + updatedSubItems: + ParseLiveList._toIncludeMap(includeObject ?? [])) { _includes = ParseLiveList._toIncludeMap(includeObject ?? []); queryBuilder = QueryBuilder(object.clone({})) ..whereEqualTo(keyVarObjectId, object.objectId); From b294d4b800b6958260e0a100936278ba0f7f124b Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:27:58 +0200 Subject: [PATCH 172/195] auto format --- packages/dart/lib/src/utils/parse_live_list.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 1a2304dbc..337c2a6c5 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -308,9 +308,11 @@ class ParseLiveList { ParseObject>(ParseObject(includedObject.parseClassName)) ..whereEqualTo(keyVarObjectId, includedObject.objectId) ..includeObject(_toIncludeStringList(paths[key])); - loadingNodes.add( - queryBuilder.query().then((ParseResponse parseResponse) { - if (parseResponse.success && parseResponse.results!.length == 1) { + loadingNodes.add(queryBuilder + .query() + .then((ParseResponse parseResponse) { + if (parseResponse.success && + parseResponse.results!.length == 1) { // ignore: deprecated_member_use_from_same_package object[key] = parseResponse.results![0]; } @@ -445,7 +447,7 @@ class ParseLiveList { String getIdentifier(int index) { if (index < _list.length) { return _list[index].object!.get(keyVarObjectId)! + - _list[index].object!.get(keyVarUpdatedAt).toString(); + _list[index].object!.get(keyVarUpdatedAt).toString(); } return 'NotFound'; } From d52cefa49c1a48d539dff4197d9e2525bc326571 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:32:59 +0200 Subject: [PATCH 173/195] fix forced not-null cast in LiveList this should break nothing and instead fix forced not-null casts on null objects --- packages/dart/lib/src/utils/parse_live_list.dart | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 337c2a6c5..0f4f9d792 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -590,11 +590,12 @@ class ParseLiveListElement { void _subscribe() { _subscriptionQueue.whenComplete(() async { - if (_updatedSubItems.isNotEmpty && _object != null) { + T? object = _object; + if (_updatedSubItems.isNotEmpty && object != null) { final List> tasks = >[]; for (PathKey key in _updatedSubItems.keys) { - tasks.add(_subscribeSubItem(_object!, key, - _object!.get(key.key)!, _updatedSubItems[key])); + tasks.add(_subscribeSubItem(object, key, + object.get(key.key), _updatedSubItems[key])); } await Future.wait(tasks); } @@ -612,12 +613,12 @@ class ParseLiveListElement { } Future _subscribeSubItem(ParseObject parentObject, PathKey currentKey, - ParseObject subObject, Map path) async { - if (_liveQuery != null) { + ParseObject? subObject, Map path) async { + if (_liveQuery != null && subObject != null) { final List> tasks = >[]; for (PathKey key in path.keys) { tasks.add(_subscribeSubItem( - subObject, key, subObject.get(key.key)!, path[key])); + subObject, key, subObject.get(key.key), path[key])); } final QueryBuilder queryBuilder = QueryBuilder(subObject) @@ -641,7 +642,7 @@ class ParseLiveListElement { _unsubscribe(path); for (PathKey key in path.keys) { tasks.add(_subscribeSubItem(newObject, key, - newObject.get(key.key)!, path[key])); + newObject.get(key.key), path[key])); } } await Future.wait(tasks); From ac1aaddd851a5a37402dc01a428d77c74256e51c Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:34:42 +0200 Subject: [PATCH 174/195] remove null assertion operator this makes the code easier to maintain --- packages/dart/lib/src/utils/parse_live_list.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 0f4f9d792..11ed23e1f 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -614,7 +614,8 @@ class ParseLiveListElement { Future _subscribeSubItem(ParseObject parentObject, PathKey currentKey, ParseObject? subObject, Map path) async { - if (_liveQuery != null && subObject != null) { + LiveQuery? liveQuery = _liveQuery; + if (liveQuery != null && subObject != null) { final List> tasks = >[]; for (PathKey key in path.keys) { tasks.add(_subscribeSubItem( @@ -624,7 +625,7 @@ class ParseLiveListElement { QueryBuilder(subObject) ..whereEqualTo(keyVarObjectId, subObject.objectId); - tasks.add(_liveQuery!.client + tasks.add(liveQuery.client .subscribe(queryBuilder) .then((Subscription subscription) { currentKey.subscription = subscription; From 44b86113a96925c6584546e473b3d2503c4b85c3 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:37:43 +0200 Subject: [PATCH 175/195] remove null assertion operator this makes the code easier to maintain --- packages/dart/lib/src/utils/parse_live_list.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 11ed23e1f..93a28e04a 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -44,8 +44,7 @@ class ParseLiveList { int get nextID => _nextID++; /// is object1 listed after object2? - /// can return null - bool? after(T? object1, T? object2) { + bool? after(T object1, T object2) { List fields = []; if (_query.limiters.containsKey('order')) { @@ -58,8 +57,8 @@ class ParseLiveList { reverse = true; key = key.substring(1); } - final dynamic val1 = object1!.get(key); - final dynamic val2 = object2!.get(key); + final dynamic val1 = object1.get(key); + final dynamic val2 = object2.get(key); if (val1 == null && val2 == null) { break; @@ -357,7 +356,8 @@ class ParseLiveList { await _loadIncludes(object, paths: _includePaths); } for (int i = 0; i < _list.length; i++) { - if (after(object, _list[i].object) != true) { + T? other = _list[i].object; + if (other != null && after(object, other) != true) { _list.insert( i, ParseLiveListElement(object, From 6568bc208a42331c56bbcd5f8d4d3306f7ac743b Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:45:17 +0200 Subject: [PATCH 176/195] update version --- packages/dart/lib/src/base/parse_constants.dart | 2 +- packages/flutter/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/base/parse_constants.dart b/packages/dart/lib/src/base/parse_constants.dart index d1a5dc428..3794a40db 100644 --- a/packages/dart/lib/src/base/parse_constants.dart +++ b/packages/dart/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '3.0.0'; +const String keySdkVersion = '3.0.1'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points diff --git a/packages/flutter/README.md b/packages/flutter/README.md index bef34efec..8befebe22 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -14,7 +14,7 @@ This is a work in progress and we are consistently updating it. Please let us kn To install, either add to your pubspec.yaml ```yml dependencies: - parse_server_sdk_flutter: ^3.0.0 + parse_server_sdk_flutter: ^3.0.1 ``` or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. From 4b0c310d27c2e222ceb5f52b62e5894da6a2da34 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:53:34 +0200 Subject: [PATCH 177/195] LiveQuery: make _liveQueryURL not null and final --- .../lib/src/network/parse_live_query.dart | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 1c83c1bb5..c0a20fa07 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -126,31 +126,34 @@ class LiveQueryReconnectingController { class LiveQueryClient { factory LiveQueryClient() => _getInstance(); - LiveQueryClient._internal({bool? debug, bool? autoSendSessionId}) { + LiveQueryClient._internal(this._liveQueryURL, + {bool? debug, bool? autoSendSessionId}) { _clientEventStreamController = StreamController(); _clientEventStream = _clientEventStreamController.stream.asBroadcastStream(); _debug = isDebugEnabled(objectLevelDebug: debug); - _sendSessionId = - autoSendSessionId ?? ParseCoreData().autoSendSessionId; - _liveQueryURL = ParseCoreData().liveQueryURL; - assert(_liveQueryURL != null, - 'liveQueryUrl is not set. For how to setup Live Queries, see https://github.com/parse-community/Parse-SDK-Flutter/tree/master/packages/flutter#live-queries.'); - if (_liveQueryURL!.contains('https')) { - _liveQueryURL = _liveQueryURL!.replaceAll('https', 'wss'); - } else if (_liveQueryURL!.contains('http')) { - _liveQueryURL = _liveQueryURL!.replaceAll('http', 'ws'); - } + _sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId; reconnectingController = LiveQueryReconnectingController( () => reconnect(userInitialized: false), getClientEventStream, _debug); } static LiveQueryClient get instance => _getInstance(); static LiveQueryClient? _instance; - static LiveQueryClient _getInstance( - {bool? debug, bool? autoSendSessionId}) { - _instance ??= LiveQueryClient._internal( + static LiveQueryClient _getInstance({bool? debug, bool? autoSendSessionId}) { + String? liveQueryURL = ParseCoreData().liveQueryURL; + if (liveQueryURL == null) { + assert(false, + 'liveQueryUrl is not set. For how to setup Live Queries, see https://github.com/parse-community/Parse-SDK-Flutter/tree/master/packages/flutter#live-queries.'); + liveQueryURL = ""; + } else { + if (liveQueryURL.contains('https')) { + liveQueryURL = liveQueryURL.replaceAll('https', 'wss'); + } else if (liveQueryURL.contains('http')) { + liveQueryURL = liveQueryURL.replaceAll('http', 'ws'); + } + } + _instance ??= LiveQueryClient._internal(liveQueryURL, debug: debug, autoSendSessionId: autoSendSessionId); return _instance!; } @@ -163,7 +166,7 @@ class LiveQueryClient { late bool _debug; late bool _sendSessionId; WebSocketChannel? _channel; - String? _liveQueryURL; + final String _liveQueryURL; bool _connecting = false; late StreamController _clientEventStreamController; late Stream _clientEventStream; @@ -256,7 +259,7 @@ class LiveQueryClient { _connecting = true; try { - _webSocket = await parse_web_socket.WebSocket.connect(_liveQueryURL!); + _webSocket = await parse_web_socket.WebSocket.connect(_liveQueryURL); _connecting = false; if (_webSocket != null && _webSocket!.readyState == parse_web_socket.WebSocket.OPEN) { From 42f82a38054f50b277c7dd6b7b388b0b543f381d Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:53:58 +0200 Subject: [PATCH 178/195] LiveQuery: _currentTimer null-safe --- packages/dart/lib/src/network/parse_live_query.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index c0a20fa07..e0f697b6b 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -61,8 +61,9 @@ class LiveQueryReconnectingController { break; case LiveQueryClientEvent.USER_DISCONNECTED: _userDisconnected = true; - if (_currentTimer != null) { - _currentTimer!.cancel(); + Timer? currentTimer = _currentTimer; + if (currentTimer != null) { + currentTimer.cancel(); _currentTimer = null; } break; From aaeb5229f3f9daa133349200fed9e13a1666ebce Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:55:46 +0200 Subject: [PATCH 179/195] LiveList: fix _objectUpdated --- packages/dart/lib/src/utils/parse_live_list.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 93a28e04a..f81f1ce68 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -375,11 +375,13 @@ class ParseLiveList { Future _objectUpdated(T object) async { for (int i = 0; i < _list.length; i++) { - if (_list[i].object!.get(keyVarObjectId) == - object.get(keyVarObjectId)) { + T? other = _list[i].object; + if (other != null && + other.get(keyVarObjectId) == + object.get(keyVarObjectId)) { await _loadIncludes(object, oldObject: _list[i].object, paths: _includePaths); - if (after(_list[i].object, object) == null) { + if (after(other, object) == null) { _list[i].object = object.clone(object.toJson(full: true)); _eventStreamController.sink.add(ParseLiveListUpdateEvent( i, object.clone(object.toJson(full: true)))); From 0619422c7fcf2a91306a17b70ad725a653cb035d Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 12:58:34 +0200 Subject: [PATCH 180/195] LiveQuery: fix forced not-null cast this should break nothing and instead fix forced not-null casts on null objects --- packages/dart/lib/src/network/parse_live_query.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index e0f697b6b..057c96263 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -154,9 +154,11 @@ class LiveQueryClient { liveQueryURL = liveQueryURL.replaceAll('http', 'ws'); } } - _instance ??= LiveQueryClient._internal(liveQueryURL, - debug: debug, autoSendSessionId: autoSendSessionId); - return _instance!; + LiveQueryClient instance = _instance ?? + LiveQueryClient._internal(liveQueryURL, + debug: debug, autoSendSessionId: autoSendSessionId); + _instance ??= instance; + return instance; } Stream get getClientEventStream { From 481f59e7984afa193e09f7d54230ec0c5a8ee255 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 13:14:02 +0200 Subject: [PATCH 181/195] LiveQuery: remove forced not-null casts this should break nothing and instead remove forced not-null casts on null objects --- .../lib/src/network/parse_live_query.dart | 84 +++++++++++-------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/packages/dart/lib/src/network/parse_live_query.dart b/packages/dart/lib/src/network/parse_live_query.dart index 057c96263..93dbba882 100644 --- a/packages/dart/lib/src/network/parse_live_query.dart +++ b/packages/dart/lib/src/network/parse_live_query.dart @@ -183,26 +183,29 @@ class LiveQueryClient { } int readyState() { - if (_webSocket != null) { - return _webSocket!.readyState; + parse_web_socket.WebSocket? webSocket = _webSocket; + if (webSocket != null) { + return webSocket.readyState; } return parse_web_socket.WebSocket.CONNECTING; } Future disconnect({bool userInitialized = false}) async { - if (_webSocket != null && - _webSocket!.readyState == parse_web_socket.WebSocket.OPEN) { + parse_web_socket.WebSocket? webSocket = _webSocket; + if (webSocket != null && + webSocket.readyState == parse_web_socket.WebSocket.OPEN) { if (_debug) { print('$_printConstLiveQuery: Socket closed'); } - await _webSocket!.close(); + await webSocket.close(); _webSocket = null; } - if (_channel != null && _channel!.sink != null) { + WebSocketChannel? channel = _channel; + if (channel != null) { if (_debug) { print('$_printConstLiveQuery: close'); } - await _channel!.sink.close(); + await channel.sink.close(); _channel = null; } _requestSubscription.values.toList().forEach((Subscription subscription) { @@ -237,11 +240,12 @@ class LiveQueryClient { 'op': 'unsubscribe', 'requestId': subscription.requestId, }; - if (_channel != null && _channel!.sink != null) { + WebSocketChannel? channel = _channel; + if (channel != null) { if (_debug) { print('$_printConstLiveQuery: UnsubscribeMessage: $unsubscribeMessage'); } - _channel!.sink.add(jsonEncode(unsubscribeMessage)); + channel.sink.add(jsonEncode(unsubscribeMessage)); subscription._enabled = false; _requestSubscription.remove(subscription.requestId); } @@ -262,10 +266,11 @@ class LiveQueryClient { _connecting = true; try { - _webSocket = await parse_web_socket.WebSocket.connect(_liveQueryURL); + parse_web_socket.WebSocket webSocket = + await parse_web_socket.WebSocket.connect(_liveQueryURL); + _webSocket = webSocket; _connecting = false; - if (_webSocket != null && - _webSocket!.readyState == parse_web_socket.WebSocket.OPEN) { + if (webSocket.readyState == parse_web_socket.WebSocket.OPEN) { if (_debug) { print('$_printConstLiveQuery: Socket opened'); } @@ -275,8 +280,9 @@ class LiveQueryClient { } return Future.value(null); } - _channel = _webSocket!.createWebSocketChannel(); - _channel!.stream.listen((dynamic message) { + WebSocketChannel channel = webSocket.createWebSocketChannel(); + _channel = channel; + channel.stream.listen((dynamic message) { _handleMessage(message); }, onDone: () { _clientEventStreamController.sink @@ -308,7 +314,8 @@ class LiveQueryClient { } void _connectLiveQuery() { - if (_channel == null || _channel!.sink == null) { + WebSocketChannel? channel = _channel; + if (channel == null) { return; } //The connect message is sent from a client to the LiveQuery server. @@ -318,19 +325,21 @@ class LiveQueryClient { 'applicationId': ParseCoreData().applicationId }; - if (_sendSessionId && ParseCoreData().sessionId != null) { - connectMessage['sessionToken'] = ParseCoreData().sessionId!; + if (_sendSessionId) { + String? sessionId = ParseCoreData().sessionId; + if (sessionId != null) { + connectMessage['sessionToken'] = sessionId; + } } - - if (ParseCoreData().clientKey != null) - connectMessage['clientKey'] = ParseCoreData().clientKey!; - if (ParseCoreData().masterKey != null) - connectMessage['masterKey'] = ParseCoreData().masterKey!; + String? clientKey = ParseCoreData().clientKey; + String? masterKey = ParseCoreData().masterKey; + if (clientKey != null) connectMessage['clientKey'] = clientKey; + if (masterKey != null) connectMessage['masterKey'] = masterKey; if (_debug) { print('$_printConstLiveQuery: ConnectMessage: $connectMessage'); } - _channel!.sink.add(jsonEncode(connectMessage)); + channel.sink.add(jsonEncode(connectMessage)); } void _subscribeLiveQuery(Subscription subscription) { @@ -367,7 +376,7 @@ class LiveQueryClient { print('$_printConstLiveQuery: SubscribeMessage: $subscribeMessage'); } - _channel!.sink.add(jsonEncode(subscribeMessage)); + _channel?.sink.add(jsonEncode(subscribeMessage)); } void _handleMessage(String message) { @@ -394,22 +403,25 @@ class LiveQueryClient { return; } if (subscription.eventCallbacks.containsKey(actionData['op'])) { - if (actionData.containsKey('object')) { - final Map map = actionData['object']; - final String? className = map['className']; - if (className == keyClassUser) { - subscription.eventCallbacks[actionData['op']]!( - (subscription.copyObject ?? + Function? eventCallback = subscription.eventCallbacks[actionData['op']]; + if (eventCallback != null) { + if (actionData.containsKey('object')) { + final Map map = actionData['object']; + final String? className = map['className']; + if (className != null) { + if (className == keyClassUser) { + eventCallback((subscription.copyObject ?? ParseCoreData.instance.createParseUser(null, null, null)) .fromJson(map)); - } else { - subscription.eventCallbacks[actionData['op']]!( - (subscription.copyObject ?? - ParseCoreData.instance.createObject(className!)) + } else { + eventCallback((subscription.copyObject ?? + ParseCoreData.instance.createObject(className)) .fromJson(map)); + } + } + } else { + eventCallback(actionData); } - } else { - subscription.eventCallbacks[actionData['op']]!(actionData); } } } From ad1d966bc85e90312092c4a452d93cfec0c74d82 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 14:36:25 +0200 Subject: [PATCH 182/195] LiveList: remove forced not-null casts this should break nothing and instead remove forced not-null casts on null objects --- .../dart/lib/src/utils/parse_live_list.dart | 211 ++++++++++-------- 1 file changed, 114 insertions(+), 97 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index f81f1ce68..3e3ec8be6 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -205,9 +205,8 @@ class ParseLiveList { //update List for (int i = 0; i < _list.length; i++) { - final ParseObject currentObject = _list[i].object!; - final String currentObjectId = - currentObject.get(keyVarObjectId)!; + final ParseObject currentObject = _list[i].object; + final String? currentObjectId = currentObject.objectId; bool stillInList = false; @@ -223,8 +222,9 @@ class ParseLiveList { tasks.add(queryBuilder .query() .then((ParseResponse result) async { - if (result.success && result.results != null) { - await _objectUpdated(result.results!.first); + List? results = result.results; + if (result.success && results != null) { + await _objectUpdated(results.first); } })); } @@ -263,21 +263,51 @@ class ParseLiveList { final List> loadingNodes = >[]; for (String key in paths.keys) { - if (object.containsKey(key)) { + ParseObject? keyInObject = object.get(key); + if (keyInObject != null) { ParseObject? includedObject = object.get(key); if (includedObject != null) { //If the object is not fetched if (!includedObject.containsKey(keyVarUpdatedAt)) { //See if oldObject contains key - if (oldObject != null && oldObject.containsKey(key)) { - includedObject = oldObject.get(key)!; - //If the object is not fetched || the ids don't match / the pointer changed - if (!includedObject.containsKey(keyVarUpdatedAt) || - includedObject.objectId != - object.get(key)!.objectId) { - includedObject = object.get(key)!; + if (oldObject != null) { + ParseObject? keyInOld = oldObject.get(key); + if (keyInOld != null) { + includedObject = keyInOld; + + //If the object is not fetched || the ids don't match / the pointer changed + if (!includedObject.containsKey(keyVarUpdatedAt) || + includedObject.objectId != keyInObject.objectId) { + includedObject = keyInObject; + //fetch from web including sub objects + //same as down there + final QueryBuilder queryBuilder = QueryBuilder< + ParseObject>(ParseObject(includedObject.parseClassName)) + ..whereEqualTo(keyVarObjectId, includedObject.objectId) + ..includeObject(_toIncludeStringList(paths[key])); + loadingNodes.add(queryBuilder + .query() + .then((ParseResponse parseResponse) { + List? results = parseResponse.results; + if (parseResponse.success && + results != null && + results.length == 1) { + // ignore: deprecated_member_use_from_same_package + object[key] = results[0]; + } + })); + continue; + } else { + // ignore: deprecated_member_use_from_same_package + object[key] = includedObject; + //recursion + loadingNodes + .add(_loadIncludes(includedObject, paths: paths[key])); + continue; + } + } else { //fetch from web including sub objects - //same as down there + //same as up there final QueryBuilder queryBuilder = QueryBuilder< ParseObject>(ParseObject(includedObject.parseClassName)) ..whereEqualTo(keyVarObjectId, includedObject.objectId) @@ -285,38 +315,16 @@ class ParseLiveList { loadingNodes.add(queryBuilder .query() .then((ParseResponse parseResponse) { + List? results = parseResponse.results; if (parseResponse.success && - parseResponse.results!.length == 1) { + results != null && + results.length == 1) { // ignore: deprecated_member_use_from_same_package - object[key] = parseResponse.results![0]; + object[key] = results[0]; } })); continue; - } else { - // ignore: deprecated_member_use_from_same_package - object[key] = includedObject; - //recursion - loadingNodes - .add(_loadIncludes(includedObject, paths: paths[key])); - continue; } - } else { - //fetch from web including sub objects - //same as up there - final QueryBuilder queryBuilder = QueryBuilder< - ParseObject>(ParseObject(includedObject.parseClassName)) - ..whereEqualTo(keyVarObjectId, includedObject.objectId) - ..includeObject(_toIncludeStringList(paths[key])); - loadingNodes.add(queryBuilder - .query() - .then((ParseResponse parseResponse) { - if (parseResponse.success && - parseResponse.results!.length == 1) { - // ignore: deprecated_member_use_from_same_package - object[key] = parseResponse.results![0]; - } - })); - continue; } } } else { @@ -356,8 +364,7 @@ class ParseLiveList { await _loadIncludes(object, paths: _includePaths); } for (int i = 0; i < _list.length; i++) { - T? other = _list[i].object; - if (other != null && after(object, other) != true) { + if (after(object, _list[i].object) != true) { _list.insert( i, ParseLiveListElement(object, @@ -375,13 +382,11 @@ class ParseLiveList { Future _objectUpdated(T object) async { for (int i = 0; i < _list.length; i++) { - T? other = _list[i].object; - if (other != null && - other.get(keyVarObjectId) == - object.get(keyVarObjectId)) { + if (_list[i].object.get(keyVarObjectId) == + object.get(keyVarObjectId)) { await _loadIncludes(object, oldObject: _list[i].object, paths: _includePaths); - if (after(other, object) == null) { + if (after(_list[i].object, object) == null) { _list[i].object = object.clone(object.toJson(full: true)); _eventStreamController.sink.add(ParseLiveListUpdateEvent( i, object.clone(object.toJson(full: true)))); @@ -399,7 +404,7 @@ class ParseLiveList { Future _objectDeleted(T object) async { for (int i = 0; i < _list.length; i++) { - if (_list[i].object!.get(keyVarObjectId) == + if (_list[i].object.get(keyVarObjectId) == object.get(keyVarObjectId)) { await _loadIncludes(object, oldObject: _list[i].object, paths: _includePaths); @@ -416,7 +421,7 @@ class ParseLiveList { if (!_list[index].loaded) { final QueryBuilder queryBuilder = QueryBuilder.copy(_query) ..whereEqualTo( - keyVarObjectId, _list[index].object!.get(keyVarObjectId)) + keyVarObjectId, _list[index].object.get(keyVarObjectId)) ..setLimit(1); final ParseResponse response = await queryBuilder.query(); if (_list.isEmpty) { @@ -427,29 +432,29 @@ class ParseLiveList { if (response.success) { _list[index].object = response.results?.first; } else { - _list[index].object = null; - yield* _createStreamError(response.error!); + ParseError? error = response.error; + if (error != null) yield* _createStreamError(error); return; } } // just for testing // await Future.delayed(const Duration(seconds: 2)); - yield _list[index].object!; + yield _list[index].object; yield* _list[index].stream; } } String idOf(int index) { if (index < _list.length) { - return _list[index].object!.get(keyVarObjectId)!; + return _list[index].object.objectId ?? 'NotFound'; } return 'NotFound'; } String getIdentifier(int index) { if (index < _list.length) { - return _list[index].object!.get(keyVarObjectId)! + - _list[index].object!.get(keyVarUpdatedAt).toString(); + return idOf(index) + + _list[index].object.get(keyVarUpdatedAt).toString(); } return 'NotFound'; } @@ -469,12 +474,15 @@ class ParseLiveList { } void dispose() { - if (_liveQuerySubscription != null) { - LiveQuery().client.unSubscribe(_liveQuerySubscription!); + Subscription? liveQuerySubscription = _liveQuerySubscription; + if (liveQuerySubscription != null) { + LiveQuery().client.unSubscribe(liveQuerySubscription); _liveQuerySubscription = null; } - if (_liveQueryClientEventSubscription != null) { - _liveQueryClientEventSubscription!.cancel(); + StreamSubscription? liveQueryClientEventSubscription = + _liveQueryClientEventSubscription; + if (liveQueryClientEventSubscription != null) { + liveQueryClientEventSubscription.cancel(); _liveQueryClientEventSubscription = null; } while (_list.isNotEmpty) { @@ -511,11 +519,12 @@ class ParseLiveElement extends ParseLiveListElement { } } - _subscription = await LiveQuery().client.subscribe( + Subscription subscription = await LiveQuery().client.subscribe( QueryBuilder.copy(queryBuilder), copyObject: object.clone({})); + _subscription = subscription; - _subscription!.on(LiveQueryEvent.update, (T newObject) async { + subscription.on(LiveQueryEvent.update, (T newObject) async { await ParseLiveList._loadIncludes(newObject, oldObject: super.object, paths: _includes); super.object = newObject; @@ -541,8 +550,9 @@ class ParseLiveElement extends ParseLiveListElement { @override void dispose() { - if (_subscription != null) { - LiveQuery().client.unSubscribe(_subscription!); + final Subscription? subscription = _subscription; + if (subscription != null) { + LiveQuery().client.unSubscribe(subscription); _subscription = null; } super.dispose(); @@ -551,10 +561,8 @@ class ParseLiveElement extends ParseLiveListElement { class ParseLiveListElement { ParseLiveListElement(this._object, - {bool loaded = false, Map? updatedSubItems}) { - if (_object != null) { - _loaded = loaded; - } + {bool loaded = false, Map? updatedSubItems}) + : _loaded = loaded { _updatedSubItems = _toSubscriptionMap(updatedSubItems ?? Map()); if (_updatedSubItems.isNotEmpty) { @@ -564,7 +572,7 @@ class ParseLiveListElement { } final StreamController _streamController = StreamController.broadcast(); - T? _object; + T _object; bool _loaded = false; late Map _updatedSubItems; LiveQuery? _liveQuery; @@ -572,7 +580,7 @@ class ParseLiveListElement { Stream get stream => _streamController.stream; - T? get object => _object?.clone(_object!.toJson(full: true)); + T get object => _object.clone(_object.toJson(full: true)); Map _toSubscriptionMap(Map map) { final Map result = Map(); @@ -592,8 +600,8 @@ class ParseLiveListElement { void _subscribe() { _subscriptionQueue.whenComplete(() async { - T? object = _object; - if (_updatedSubItems.isNotEmpty && object != null) { + final T object = _object; + if (_updatedSubItems.isNotEmpty) { final List> tasks = >[]; for (PathKey key in _updatedSubItems.keys) { tasks.add(_subscribeSubItem(object, key, @@ -606,8 +614,10 @@ class ParseLiveListElement { void _unsubscribe(Map subscriptions) { for (PathKey key in subscriptions.keys) { - if (_liveQuery != null && key.subscription != null) { - _liveQuery!.client.unSubscribe(key.subscription!); + final Subscription? subscription = key.subscription; + LiveQuery? liveQuery = _liveQuery; + if (liveQuery != null && subscription != null) { + liveQuery.client.unSubscribe(subscription); key.subscription = null; } _unsubscribe(subscriptions[key]); @@ -638,8 +648,7 @@ class ParseLiveListElement { // ignore: deprecated_member_use_from_same_package parentObject[currentKey.key] = newObject; if (!_streamController.isClosed) { - _streamController - .add(_object?.clone(_object!.toJson(full: true))); + _streamController.add(object); //Resubscribe subitems // TODO(any): only resubscribe on changed pointers _unsubscribe(path); @@ -656,12 +665,12 @@ class ParseLiveListElement { } } - set object(T? value) { + set object(T value) { _loaded = true; _object = value; _unsubscribe(_updatedSubItems); _subscribe(); - _streamController.add(_object?.clone(_object!.toJson(full: true))); + _streamController.add(object); } bool get loaded => _loaded; @@ -674,7 +683,7 @@ class ParseLiveListElement { Future reconnected() async { if (loaded) { _subscriptionQueue.whenComplete(() async { - await _updateSubItems(_object!, _updatedSubItems); + await _updateSubItems(_object, _updatedSubItems); // _streamController.add(_object?.clone(_object.toJson(full: true))); }); } @@ -694,31 +703,39 @@ class ParseLiveListElement { ParseObject root, Map path) async { final List> tasks = >[]; for (PathKey key in path.keys) { - ParseObject subObject = root.get(key.key)!; - if (subObject.containsKey(keyVarUpdatedAt) == true) { - final QueryBuilder queryBuilder = - QueryBuilder(subObject) - ..keysToReturn([keyVarUpdatedAt]) - ..whereEqualTo(keyVarObjectId, subObject.objectId); - final ParseResponse parseResponse = await queryBuilder.query(); - if (parseResponse.success && - parseResponse.results!.first.updatedAt != subObject.updatedAt) { - queryBuilder.limiters.remove('keys'); - queryBuilder.includeObject(_getIncludeList(path[key])); + ParseObject? subObject = root.get(key.key); + if (subObject != null) { + if (subObject.containsKey(keyVarUpdatedAt) == true) { + final QueryBuilder queryBuilder = + QueryBuilder(subObject) + ..keysToReturn([keyVarUpdatedAt]) + ..whereEqualTo(keyVarObjectId, subObject.objectId); final ParseResponse parseResponse = await queryBuilder.query(); - if (parseResponse.success) { - subObject = parseResponse.result.first; + final List? results = parseResponse.results; + if (parseResponse.success && + results != null && + results.first.updatedAt != subObject.updatedAt) { + queryBuilder.limiters.remove('keys'); + queryBuilder.includeObject(_getIncludeList(path[key])); + final ParseResponse parseResponse = await queryBuilder.query(); + if (parseResponse.success) { + subObject = parseResponse.result.first; // root.getObjectData()[key.key] = subObject; - if (key.subscription?.eventCallbacks.containsKey('update') == - true) { - key.subscription!.eventCallbacks['update']!(subObject); - } + Subscription? subscription = key.subscription; + if (subscription != null && + subscription.eventCallbacks.containsKey('update') == true) { + Function? eventCallback = subscription.eventCallbacks['update']; + if (eventCallback != null) { + eventCallback(subObject); + } + } // key.subscription.eventCallbacks["update"](subObject); - break; + break; + } } } + tasks.add(_updateSubItems(subObject, path[key])); } - tasks.add(_updateSubItems(subObject, path[key])); } await Future.wait(tasks); } From 50fa8125edc75ed671cefb7390b41abfd1f6be7e Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 14:40:47 +0200 Subject: [PATCH 183/195] LiveList: move typedefs to flutter package I think those where missed when splitting the package. --- packages/dart/lib/src/utils/parse_live_list.dart | 3 --- packages/flutter/lib/src/utils/parse_live_list.dart | 13 ++++++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 3e3ec8be6..51d29b933 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -778,9 +778,6 @@ class ParseLiveListDeleteEvent ParseLiveListDeleteEvent(int index, T object) : super(index, object); } -typedef StreamGetter = Stream Function(); -typedef DataGetter = T Function(); - class ParseLiveListElementSnapshot { ParseLiveListElementSnapshot( {this.loadedData, this.error, this.preLoadedData}); diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 0463c98bd..97c41ae33 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -3,6 +3,9 @@ part of flutter_parse_sdk_flutter; typedef ChildBuilder = Widget Function( BuildContext context, sdk.ParseLiveListElementSnapshot snapshot); +typedef StreamGetter = Stream Function(); +typedef DataGetter = T Function(); + class ParseLiveListWidget extends StatefulWidget { const ParseLiveListWidget({ Key? key, @@ -211,9 +214,9 @@ class ParseLiveListElementWidget required this.childBuilder}) : super(key: key); - final sdk.StreamGetter? stream; - final sdk.DataGetter? loadedData; - final sdk.DataGetter? preLoadedData; + final StreamGetter? stream; + final DataGetter? loadedData; + final DataGetter? preLoadedData; final Animation sizeFactor; final Duration duration; final ChildBuilder childBuilder; @@ -228,8 +231,8 @@ class ParseLiveListElementWidget class _ParseLiveListElementWidgetState extends State> with SingleTickerProviderStateMixin { - _ParseLiveListElementWidgetState(sdk.DataGetter? loadedDataGetter, - sdk.DataGetter? preLoadedDataGetter, sdk.StreamGetter? stream) { + _ParseLiveListElementWidgetState(DataGetter? loadedDataGetter, + DataGetter? preLoadedDataGetter, StreamGetter? stream) { _snapshot = sdk.ParseLiveListElementSnapshot( loadedData: loadedDataGetter != null ? loadedDataGetter() : null, preLoadedData: From 769fbf74e5651ae5d8784cbe062083679cc0a24a Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 15:30:24 +0200 Subject: [PATCH 184/195] LiveListWidget: remove forced not-null casts This fixes a bug where a "Null check operator used on a null value"-error --- .../lib/src/utils/parse_live_list.dart | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/packages/flutter/lib/src/utils/parse_live_list.dart b/packages/flutter/lib/src/utils/parse_live_list.dart index 97c41ae33..9cea74101 100644 --- a/packages/flutter/lib/src/utils/parse_live_list.dart +++ b/packages/flutter/lib/src/utils/parse_live_list.dart @@ -4,7 +4,7 @@ typedef ChildBuilder = Widget Function( BuildContext context, sdk.ParseLiveListElementSnapshot snapshot); typedef StreamGetter = Stream Function(); -typedef DataGetter = T Function(); +typedef DataGetter = T? Function(); class ParseLiveListWidget extends StatefulWidget { const ParseLiveListWidget({ @@ -68,7 +68,8 @@ class ParseLiveListWidget extends StatefulWidget { } else if (snapshot.hasData) { child = ListTile( title: Text( - snapshot.loadedData!.get(sdk.keyVarObjectId)!, + snapshot.loadedData?.get(sdk.keyVarObjectId) ?? + 'Missing Data!', ), ); } else { @@ -99,35 +100,37 @@ class _ParseLiveListWidgetState setState(() { _noData = livelist.size == 0; _liveList = livelist; - _liveList!.stream - .listen((sdk.ParseLiveListEvent event) { - if (event is sdk.ParseLiveListAddEvent) { - if (_animatedListKey.currentState != null) { - _animatedListKey.currentState! - .insertItem(event.index, duration: widget.duration); + livelist.stream.listen((sdk.ParseLiveListEvent event) { + final AnimatedListState? animatedListState = + _animatedListKey.currentState; + if (animatedListState != null) { + if (event is sdk.ParseLiveListAddEvent) { + animatedListState.insertItem(event.index, + duration: widget.duration); + + setState(() { + _noData = livelist.size == 0; + }); + } else if (event is sdk.ParseLiveListDeleteEvent) { + animatedListState.removeItem( + event.index, + (BuildContext context, Animation animation) => + ParseLiveListElementWidget( + key: ValueKey( + event.object.get(sdk.keyVarObjectId) ?? + 'removingItem'), + childBuilder: widget.childBuilder ?? + ParseLiveListWidget.defaultChildBuilder, + sizeFactor: animation, + duration: widget.duration, + loadedData: () => event.object as T, + preLoadedData: () => event.object as T, + ), + duration: widget.duration); + setState(() { + _noData = livelist.size == 0; + }); } - setState(() { - _noData = livelist.size == 0; - }); - } else if (event is sdk.ParseLiveListDeleteEvent) { - _animatedListKey.currentState!.removeItem( - event.index, - (BuildContext context, Animation animation) => - ParseLiveListElementWidget( - key: ValueKey(event.object.get( - sdk.keyVarObjectId, - defaultValue: 'removingItem')!), - childBuilder: widget.childBuilder ?? - ParseLiveListWidget.defaultChildBuilder, - sizeFactor: animation, - duration: widget.duration, - loadedData: () => event.object as T, - preLoadedData: () => event.object as T, - ), - duration: widget.duration); - setState(() { - _noData = livelist.size == 0; - }); } }); }); @@ -143,7 +146,8 @@ class _ParseLiveListWidgetState @override Widget build(BuildContext context) { - if (_liveList == null) { + final sdk.ParseLiveList? liveList = _liveList; + if (liveList == null) { return widget.listLoadingElement ?? Container(); } else { return Stack( @@ -154,8 +158,7 @@ class _ParseLiveListWidgetState duration: widget.duration, child: widget.queryEmptyElement, ), - //_liveList isn't (checked above) - buildAnimatedList(_liveList!), + buildAnimatedList(liveList), ], ); } @@ -184,8 +187,8 @@ class _ParseLiveListWidgetState return ParseLiveListElementWidget( key: ValueKey(liveList.getIdentifier(index)), stream: () => liveList.getAt(index), - loadedData: () => liveList.getLoadedAt(index)!, - preLoadedData: () => liveList.getPreLoadedAt(index)!, + loadedData: () => liveList.getLoadedAt(index), + preLoadedData: () => liveList.getPreLoadedAt(index), sizeFactor: animation, duration: widget.duration, childBuilder: From ea7edf47b132f507020c72fbb922f7bb71242789 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 15:46:20 +0200 Subject: [PATCH 185/195] LiveList: fix reusage of unchanged child objects I've broken this part while removing the not-null casts. My second attempt works :-) --- .../dart/lib/src/utils/parse_live_list.dart | 72 +++++++++---------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/packages/dart/lib/src/utils/parse_live_list.dart b/packages/dart/lib/src/utils/parse_live_list.dart index 51d29b933..fb6a74cd5 100644 --- a/packages/dart/lib/src/utils/parse_live_list.dart +++ b/packages/dart/lib/src/utils/parse_live_list.dart @@ -263,51 +263,19 @@ class ParseLiveList { final List> loadingNodes = >[]; for (String key in paths.keys) { - ParseObject? keyInObject = object.get(key); - if (keyInObject != null) { + if (object.containsKey(key)) { ParseObject? includedObject = object.get(key); if (includedObject != null) { //If the object is not fetched if (!includedObject.containsKey(keyVarUpdatedAt)) { //See if oldObject contains key - if (oldObject != null) { - ParseObject? keyInOld = oldObject.get(key); - if (keyInOld != null) { - includedObject = keyInOld; - - //If the object is not fetched || the ids don't match / the pointer changed - if (!includedObject.containsKey(keyVarUpdatedAt) || - includedObject.objectId != keyInObject.objectId) { - includedObject = keyInObject; - //fetch from web including sub objects - //same as down there - final QueryBuilder queryBuilder = QueryBuilder< - ParseObject>(ParseObject(includedObject.parseClassName)) - ..whereEqualTo(keyVarObjectId, includedObject.objectId) - ..includeObject(_toIncludeStringList(paths[key])); - loadingNodes.add(queryBuilder - .query() - .then((ParseResponse parseResponse) { - List? results = parseResponse.results; - if (parseResponse.success && - results != null && - results.length == 1) { - // ignore: deprecated_member_use_from_same_package - object[key] = results[0]; - } - })); - continue; - } else { - // ignore: deprecated_member_use_from_same_package - object[key] = includedObject; - //recursion - loadingNodes - .add(_loadIncludes(includedObject, paths: paths[key])); - continue; - } - } else { + ParseObject? keyInOld = oldObject?.get(key); + if (keyInOld != null) { + //If the object is not fetched || the ids don't match / the pointer changed + if (!keyInOld.containsKey(keyVarUpdatedAt) || + includedObject.objectId != keyInOld.objectId) { //fetch from web including sub objects - //same as up there + //same as down there final QueryBuilder queryBuilder = QueryBuilder< ParseObject>(ParseObject(includedObject.parseClassName)) ..whereEqualTo(keyVarObjectId, includedObject.objectId) @@ -319,12 +287,36 @@ class ParseLiveList { if (parseResponse.success && results != null && results.length == 1) { - // ignore: deprecated_member_use_from_same_package object[key] = results[0]; } })); continue; + } else { + includedObject = keyInOld; + object[key] = includedObject; + //recursion + loadingNodes + .add(_loadIncludes(includedObject, paths: paths[key])); + continue; } + } else { + //fetch from web including sub objects + //same as up there + final QueryBuilder queryBuilder = QueryBuilder< + ParseObject>(ParseObject(includedObject.parseClassName)) + ..whereEqualTo(keyVarObjectId, includedObject.objectId) + ..includeObject(_toIncludeStringList(paths[key])); + loadingNodes.add(queryBuilder + .query() + .then((ParseResponse parseResponse) { + List? results = parseResponse.results; + if (parseResponse.success && + results != null && + results.length == 1) { + object[key] = results[0]; + } + })); + continue; } } } else { From aa80140b719c384fec6838c3dc810261380041d2 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 16:27:45 +0200 Subject: [PATCH 186/195] update version to 3.1.0 --- packages/dart/lib/src/base/parse_constants.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/flutter/README.md | 2 +- packages/flutter/pubspec.yaml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dart/lib/src/base/parse_constants.dart b/packages/dart/lib/src/base/parse_constants.dart index 3794a40db..a1c96cf18 100644 --- a/packages/dart/lib/src/base/parse_constants.dart +++ b/packages/dart/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '3.0.1'; +const String keySdkVersion = '3.1.0'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index efe5c5410..d4cc690e5 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: Dart plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 3.0.1 +version: 3.1.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: diff --git a/packages/flutter/README.md b/packages/flutter/README.md index 8befebe22..8559d98a4 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -14,7 +14,7 @@ This is a work in progress and we are consistently updating it. Please let us kn To install, either add to your pubspec.yaml ```yml dependencies: - parse_server_sdk_flutter: ^3.0.1 + parse_server_sdk_flutter: ^3.1.0 ``` or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 2c6d22b2c..cb366cfa5 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk_flutter description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 3.0.1 +version: 3.1.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: @@ -11,7 +11,7 @@ dependencies: sdk: flutter # Uncomment for Release version - parse_server_sdk: ^3.0.1 + parse_server_sdk: ^3.1.0 # Uncomment for local testing #parse_server_sdk: From a1d95b379bab51d6f83beac498b1fcefb9747826 Mon Sep 17 00:00:00 2001 From: Maximilian Fischer Date: Wed, 9 Jun 2021 16:35:49 +0200 Subject: [PATCH 187/195] Update .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8819014fe..45d165edc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,8 @@ script: - (cd packages/dart && pub get) - (cd packages/dart && dart run build_runner build --delete-conflicting-outputs) - (cd packages/dart && pub run test) + - (cd packages/flutter && flutter pub remove parse_server_sdk) + - (cd packages/flutter && flutter pub add parse_server_sdk --path ../dart) - (cd packages/flutter && flutter pub get) - (cd packages/flutter && flutter test --no-pub test/) From 0608e6fb7f4c13b6901dea45f1808e09c188c249 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Sat, 12 Jun 2021 00:20:37 -0300 Subject: [PATCH 188/195] New method for ParseQuery / Bugfix ParseQuery methods / Bugfix ParseRelation.getQuery - New ParseQuery method: whereWithinPolygon - Bugfix ParseQuery methods: whereContainsWholeWord, whereEndsWith, - Bugfix ParseRelation.getQuery() - ParseGeopoint: value validation - Updated Dependencies version in pubspec.yaml --- .../dart/lib/src/network/parse_query.dart | 48 +++++++++----- .../dart/lib/src/objects/parse_geo_point.dart | 15 ++++- .../dart/lib/src/objects/parse_relation.dart | 3 + packages/dart/pubspec.yaml | 14 ++-- packages/dart/test/parse_relation_test.dart | 66 +++++++++++++++++++ .../.plugin_symlinks/connectivity_plus_linux | 2 +- .../.plugin_symlinks/path_provider_linux | 2 +- .../.plugin_symlinks/shared_preferences_linux | 2 +- packages/flutter/pubspec.yaml | 10 +-- 9 files changed, 131 insertions(+), 31 deletions(-) create mode 100644 packages/dart/test/parse_relation_test.dart diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 627759a35..d1e5bfdb6 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -113,10 +113,10 @@ class QueryBuilder { {bool caseSensitive = false}) { if (caseSensitive) { queries.add(MapEntry( - _SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$query^\"}')); + _SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$query\$\"}')); } else { queries.add(MapEntry(_SINGLE_QUERY, - '\"$column\":{\"\$regex\": \"$query^\", \"\$options\": \"i\"}')); + '\"$column\":{\"\$regex\": \"$query\$\", \"\$options\": \"i\"}')); } } @@ -224,11 +224,14 @@ class QueryBuilder { /// Powerful search for containing whole words. This search is much quicker than regex and can search for whole words including wether they are case sensitive or not. /// This search can also order by the score of the search void whereContainsWholeWord(String column, String query, - {bool caseSensitive = false, bool orderByScore = true}) { + {bool caseSensitive = false, + bool orderByScore = false, + bool diacriticSensitive = false}) { queries.add(MapEntry(_SINGLE_QUERY, - '\"$column\":{\"\$text\":{\"\$search\":{\"\$term\": \"$query\", \"\$caseSensitive\": $caseSensitive }}}')); + '\"$column\":{\"\$text\":{\"\$search\":{\"\$term\": \"$query\", \"\$caseSensitive\": $caseSensitive , \"\$diacriticSensitive\": $diacriticSensitive }}}')); if (orderByScore) { - orderByDescending('score'); + orderByAscending('\$score'); + keysToReturn(['\$score']); } } @@ -283,8 +286,22 @@ class QueryBuilder { '\"$column\":{\"\$within\":{\"\$box\": [{\"__type\": \"GeoPoint\",\"latitude\":$latitudeS,\"longitude\":$longitudeS},{\"__type\": \"GeoPoint\",\"latitude\":$latitudeN,\"longitude\":$longitudeN}]}}')); } - // Add a constraint to the query that requires a particular key's value match another QueryBuilder - void whereMatchesQuery(String column, QueryBuilder query) { + /// Return an object with key coordinates be contained within and on the bounds of a given polygon. + /// Supports closed and open (last point is connected to first) paths + /// Polygon must have at least 3 points + void whereWithinPolygon(String column, List points) { + if (points.length < 3) + throw ArgumentError('Polygon must have at least 3 points'); + Map dictionary = {}; + dictionary['\$polygon'] = points.map((e) => e.toJson()).toList(); + + queries.add(MapEntry(_SINGLE_QUERY, + '\"$column\":{\"\$geoWithin\":${jsonEncode(dictionary)}}')); + } + + /// Add a constraint to the query that requires a particular key's value match another QueryBuilder + void whereMatchesQuery( + String column, QueryBuilder query) { final String inQuery = query._buildQueryRelational(query.object!.parseClassName); @@ -292,8 +309,9 @@ class QueryBuilder { _SINGLE_QUERY, '\"$column\":{\"\$inQuery\":$inQuery}')); } - //Add a constraint to the query that requires a particular key's value does not match another QueryBuilder - void whereDoesNotMatchQuery(String column, QueryBuilder query) { + ///Add a constraint to the query that requires a particular key's value does not match another QueryBuilder + void whereDoesNotMatchQuery( + String column, QueryBuilder query) { final String inQuery = query._buildQueryRelational(query.object!.parseClassName); @@ -301,7 +319,7 @@ class QueryBuilder { _SINGLE_QUERY, '\"$column\":{\"\$notInQuery\":$inQuery}')); } - // Add a constraint to the query that requires a particular key's value matches a value for a key in the results of another ParseQuery. + /// Add a constraint to the query that requires a particular key's value matches a value for a key in the results of another ParseQuery. void whereMatchesKeyInQuery( String column, String keyInQuery, QueryBuilder query) { if (query.queries.isEmpty) { @@ -314,14 +332,14 @@ class QueryBuilder { throw ArgumentError('include is not allowed'); } - final String inQuery = - query._buildQueryRelationalKey(query.object!.parseClassName, keyInQuery); + final String inQuery = query._buildQueryRelationalKey( + query.object!.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$select\":$inQuery}')); } - // Add a constraint to the query that requires a particular key's value does not match any value for a key in the results of another ParseQuery + /// Add a constraint to the query that requires a particular key's value does not match any value for a key in the results of another ParseQuery void whereDoesNotMatchKeyInQuery( String column, String keyInQuery, QueryBuilder query) { if (query.queries.isEmpty) { @@ -334,8 +352,8 @@ class QueryBuilder { throw ArgumentError('include is not allowed'); } - final String inQuery = - query._buildQueryRelationalKey(query.object!.parseClassName, keyInQuery); + final String inQuery = query._buildQueryRelationalKey( + query.object!.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$dontSelect\":$inQuery}')); diff --git a/packages/dart/lib/src/objects/parse_geo_point.dart b/packages/dart/lib/src/objects/parse_geo_point.dart index 318fba95b..f7f60a2e8 100644 --- a/packages/dart/lib/src/objects/parse_geo_point.dart +++ b/packages/dart/lib/src/objects/parse_geo_point.dart @@ -5,7 +5,15 @@ const String keyLongitude = 'longitude'; class ParseGeoPoint { /// Creates a Parse Object of type GeoPoint - ParseGeoPoint({this.latitude = 0.0, this.longitude = 0.0}); + ParseGeoPoint({this.latitude = 0.0, this.longitude = 0.0}) + : assert( + latitude < 90, 'Latitude must be within the range (-90.0, 90.0).'), + assert( + latitude > -90, 'Latitude must be within the range (-90.0, 90.0).'), + assert(latitude < 180, + 'Longitude must be within the range (-180.0, 180.0).'), + assert(latitude > -180, + 'Longitude must be within the range (-180.0, 180.0).'); double latitude, longitude; @@ -15,4 +23,9 @@ class ParseGeoPoint { 'latitude': latitude, 'longitude': longitude }; + + @override + String toString() { + return 'latitude: $latitude, longitude: $longitude'; + } } diff --git a/packages/dart/lib/src/objects/parse_relation.dart b/packages/dart/lib/src/objects/parse_relation.dart index d522cab8b..e73289b8b 100644 --- a/packages/dart/lib/src/objects/parse_relation.dart +++ b/packages/dart/lib/src/objects/parse_relation.dart @@ -3,6 +3,7 @@ part of flutter_parse_sdk; // ignore_for_file: always_specify_types class ParseRelation { ParseRelation({required ParseObject parent, required String key}) { + _targetClass = parent.get(key)!.getTargetClass; _parent = parent; _key = key; _parentObjectId = parent.objectId!; @@ -41,6 +42,8 @@ class ParseRelation { _parent!.removeRelation(_key, _knownObjects!.toList()); } + String get getTargetClass => _targetClass ?? ''; + Map toJson() => { '__type': keyRelation, 'className': _targetClass, diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index a9baf22d2..ce68b48f2 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: Dart plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 3.0.0 +version: 3.1.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: @@ -10,11 +10,11 @@ dependencies: # Networking dio: ^4.0.0 - http: ^0.13.1 - web_socket_channel: ^2.0.0 + http: ^0.13.3 + web_socket_channel: ^2.1.0 #Database - sembast: ^3.0.1 + sembast: ^3.1.0+2 sembast_web: ^2.0.0+2 xxtea: ^2.1.0 @@ -26,6 +26,6 @@ dependencies: dev_dependencies: # Testing - build_runner: ^2.0.1 - mockito: ^5.0.4 - test: ^1.16.8 + build_runner: ^2.0.4 + mockito: ^5.0.10 + test: ^1.17.7 diff --git a/packages/dart/test/parse_relation_test.dart b/packages/dart/test/parse_relation_test.dart new file mode 100644 index 000000000..2dce93605 --- /dev/null +++ b/packages/dart/test/parse_relation_test.dart @@ -0,0 +1,66 @@ +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:parse_server_sdk/parse_server_sdk.dart'; +import 'package:test/test.dart'; + +import 'parse_query_test.mocks.dart'; + +@GenerateMocks([ParseClient]) +void main() { + group('queryBuilder', () { + test('whereRelatedTo', () async { + final MockParseClient client = MockParseClient(); + + await Parse().initialize( + 'appId', + 'https://test.parse.com', + debug: true, + // to prevent automatic detection + fileDirectory: 'someDirectory', + // to prevent automatic detection + appName: 'appName', + // to prevent automatic detection + appPackageName: 'somePackageName', + // to prevent automatic detection + appVersion: 'someAppVersion', + ); + var post = ParseObject('Post', client: client); + post.objectId = '8TOXdXf3tz'; + var relation = post.getRelation("likes"); + final QueryBuilder queryBuilder = relation.getQuery(); + + when(client.get( + any, + options: anyNamed("options"), + onReceiveProgress: anyNamed("onReceiveProgress"), + )).thenAnswer((_) async => ParseNetworkResponse( + statusCode: 200, + data: + "{\"results\":[{\"objectId\":\"eT9muOxBTJ\",\"username\":\"test\",\"createdAt\":\"2021-04-23T13:46:06.092Z\",\"updatedAt\":\"2021-04-23T13:46:23.586Z\",\"ACL\":{\"*\":{\"read\":true},\"eT9muOxBTJ\":{\"read\":true,\"write\":true}}}]}")); + + ParseResponse response = await queryBuilder.query(); + + expect(response.results?.first, isA()); + + ParseObject parseObject = response.results?.first; + + expect(parseObject.get(keyVarUsername), "test"); + expect(parseObject.objectId, "eT9muOxBTJ"); + expect(parseObject.createdAt, DateTime.parse("2021-04-23T13:46:06.092Z")); + expect(parseObject.updatedAt, DateTime.parse("2021-04-23T13:46:23.586Z")); + + final Uri result = Uri.parse(verify(client.get( + captureAny, + options: anyNamed("options"), + onReceiveProgress: anyNamed("onReceiveProgress"), + )).captured.single); + + expect(result.path, '/classes/_User'); + + final Uri expectedQuery = Uri( + query: + 'where={"\$relatedTo":{"object":{"__type":"Pointer","className":"Post","objectId":"8TOXdXf3tz"},"key":"likes"}}'); + expect(result.query, expectedQuery.query); + }); + }); +} diff --git a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux index 65fa57407..6cc4956b2 120000 --- a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux +++ b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus_linux @@ -1 +1 @@ -C:/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.0.1/ \ No newline at end of file +/Users/rodrigo/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.0.2/ \ No newline at end of file diff --git a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux index 4ba2c51d0..a2f4bd65d 120000 --- a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux +++ b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux @@ -1 +1 @@ -C:/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.0.0/ \ No newline at end of file +/Users/rodrigo/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.0.0/ \ No newline at end of file diff --git a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux index 6490074a9..75b80e9f2 120000 --- a/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux +++ b/packages/flutter/example/linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux @@ -1 +1 @@ -C:/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_linux-2.0.0/ \ No newline at end of file +/Users/rodrigo/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_linux-2.0.0/ \ No newline at end of file diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 38387bcff..bac1b7d40 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk_flutter description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 3.0.0 +version: 3.1.0 homepage: https://github.com/phillwiggins/flutter_parse_sdk environment: @@ -11,11 +11,11 @@ dependencies: sdk: flutter # Uncomment for Release version - parse_server_sdk: ^3.0.0 + #parse_server_sdk: ^3.0.0 # Uncomment for local testing - #parse_server_sdk: - # path: ../dart + parse_server_sdk: + path: ../dart # Uncomment for test with Github Branch #parse_server_sdk: @@ -41,4 +41,4 @@ dev_dependencies: # Testing flutter_test: sdk: flutter - mockito: ^5.0.2 + mockito: ^5.0.10 From a20cbd8eef7f43b960a1b3d5e2c10e3282bdec73 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Mon, 14 Jun 2021 08:43:18 -0300 Subject: [PATCH 189/195] Update parse_query.dart --- packages/dart/lib/src/network/parse_query.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index d1e5bfdb6..abd2a87a5 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -225,7 +225,7 @@ class QueryBuilder { /// This search can also order by the score of the search void whereContainsWholeWord(String column, String query, {bool caseSensitive = false, - bool orderByScore = false, + bool orderByScore = true, bool diacriticSensitive = false}) { queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$text\":{\"\$search\":{\"\$term\": \"$query\", \"\$caseSensitive\": $caseSensitive , \"\$diacriticSensitive\": $diacriticSensitive }}}')); From f94a62460bbd8e0734f76ae66253d3d156b000ef Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Tue, 15 Jun 2021 21:41:21 -0300 Subject: [PATCH 190/195] Documentation update: README and CHANGELOG Documentation update: README and CHANGELOG --- packages/dart/CHANGELOG.md | 9 +++++++++ packages/dart/README.md | 9 ++------- packages/flutter/CHANGELOG.md | 8 ++++++++ packages/flutter/README.md | 9 ++------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/dart/CHANGELOG.md b/packages/dart/CHANGELOG.md index 1538e7db7..be6aaf707 100644 --- a/packages/dart/CHANGELOG.md +++ b/packages/dart/CHANGELOG.md @@ -1,3 +1,11 @@ +## 3.1.0 +Bug fixes +General improvements +Updated dependencies + +## 3.0.0 +Stable null safety release. + ## 2.1.0 Option para uses ParseHTTPClient (default) or ParseDioClient (slow on Flutter Web). **BREAKING CHANGE** if use progress callback at the file upload in version 2.0.1 @@ -6,6 +14,7 @@ Changed to the method POST on Login Bug fixes General improvements Updated dependencies + ## 2.0.1 Fixed network exceptions. [#482](https://github.com/parse-community/Parse-SDK-Flutter/pull/482) diff --git a/packages/dart/README.md b/packages/dart/README.md index 8b72b1daf..c229992f5 100644 --- a/packages/dart/README.md +++ b/packages/dart/README.md @@ -17,13 +17,8 @@ This is a Dart package that allows communication with a Parse Server, (https://p This is a work in progress and we are consistently updating it. Please let us know if you think anything needs changing/adding, and more than ever, please do join in on this project. (Even if it is just to improve our documentation) ## Getting Started -To install, either add to your pubspec.yaml -```yml -dependencies: - parse_server_sdk: ^2.1.0 -``` -or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. +To install, either add [dependency in your pubspec.yaml file](https://pub.dev/packages/parse_server_sdk/install). Once you have the library added to your project, upon first call to your app (Similar to what your application class would be) add the following... @@ -66,7 +61,6 @@ When running via express, set [ParseServerOptions](https://parseplatform.org/par Be aware that for web ParseInstallation does include app name, version or package identifier. - ## Objects You can create custom objects by calling: ```dart @@ -312,6 +306,7 @@ The features available are:- * WithinKilometers * WithinRadians * WithinGeoBox + * WithinPolygon * MatchesQuery * DoesNotMatchQuery * MatchesKeyInQuery diff --git a/packages/flutter/CHANGELOG.md b/packages/flutter/CHANGELOG.md index 389bd3857..4db9f515e 100644 --- a/packages/flutter/CHANGELOG.md +++ b/packages/flutter/CHANGELOG.md @@ -1,3 +1,11 @@ +## 3.1.0 +Bug fixes +General improvements +Updated dependencies + +## 3.0.0 +Stable null safety release. + ## 2.1.0 Option para uses ParseHTTPClient (default) or ParseDioClient (slow on Flutter Web). **BREAKING CHANGE** if use progress callback at the file upload in version 2.0.1 diff --git a/packages/flutter/README.md b/packages/flutter/README.md index 8559d98a4..8719e274b 100644 --- a/packages/flutter/README.md +++ b/packages/flutter/README.md @@ -11,13 +11,7 @@ Hi, this is a Flutter plugin that allows communication with a Parse Server, (htt This is a work in progress and we are consistently updating it. Please let us know if you think anything needs changing/adding, and more than ever, please do join in on this project. (Even if it is just to improve our documentation) ## Getting Started -To install, either add to your pubspec.yaml -```yml -dependencies: - parse_server_sdk_flutter: ^3.1.0 -``` -or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. - +To install, either add [dependency in your pubspec.yaml file](https://pub.dev/packages/parse_server_sdk_flutter/install). Once you have the library added to your project, upon first call to your app (Similar to what your application class would be) add the following... @@ -329,6 +323,7 @@ The features available are:- * WithinKilometers * WithinRadians * WithinGeoBox + * WithinPolygon * MatchesQuery * DoesNotMatchQuery * MatchesKeyInQuery From de856215b59e0ad265ec5d072dcea1071ca223ad Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Tue, 15 Jun 2021 21:47:40 -0300 Subject: [PATCH 191/195] Update pubspec.yaml --- packages/flutter/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index d90e0559c..7459d1a53 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -10,8 +10,8 @@ dependencies: flutter: sdk: flutter - # Uncomment for Release version - parse_server_sdk: ^3.1.0 + #Uncomment for Release version + #parse_server_sdk: ^3.1.0 # Uncomment for local testing parse_server_sdk: From f14dbbff881b26814a18b0342714ea421b6f2956 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Tue, 15 Jun 2021 21:54:10 -0300 Subject: [PATCH 192/195] Fix Travis CI build failed --- packages/dart/lib/src/network/parse_query.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/dart/lib/src/network/parse_query.dart b/packages/dart/lib/src/network/parse_query.dart index 2bb1dc6a1..b2932ef06 100644 --- a/packages/dart/lib/src/network/parse_query.dart +++ b/packages/dart/lib/src/network/parse_query.dart @@ -288,7 +288,6 @@ class QueryBuilder { '\"$column\":{\"\$within\":{\"\$box\": [{\"__type\": \"GeoPoint\",\"latitude\":$latitudeS,\"longitude\":$longitudeS},{\"__type\": \"GeoPoint\",\"latitude\":$latitudeN,\"longitude\":$longitudeN}]}}')); } - /// Return an object with key coordinates be contained within and on the bounds of a given polygon. /// Supports closed and open (last point is connected to first) paths /// Polygon must have at least 3 points @@ -335,8 +334,8 @@ class QueryBuilder { throw ArgumentError('include is not allowed'); } - final String inQuery = query._buildQueryRelationalKey( - query.object!.parseClassName, keyInQuery); + final String inQuery = + query._buildQueryRelationalKey(query.object.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$select\":$inQuery}')); @@ -355,8 +354,8 @@ class QueryBuilder { throw ArgumentError('include is not allowed'); } - final String inQuery = query._buildQueryRelationalKey( - query.object!.parseClassName, keyInQuery); + final String inQuery = + query._buildQueryRelationalKey(query.object.parseClassName, keyInQuery); queries.add(MapEntry( _SINGLE_QUERY, '\"$column\":{\"\$dontSelect\":$inQuery}')); From 7cf98c5b41bbff77df55774f7ef087cd6f8c70e0 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Tue, 15 Jun 2021 22:59:37 -0300 Subject: [PATCH 193/195] Delete parse_relation_test.dart --- packages/dart/test/parse_relation_test.dart | 66 --------------------- 1 file changed, 66 deletions(-) delete mode 100644 packages/dart/test/parse_relation_test.dart diff --git a/packages/dart/test/parse_relation_test.dart b/packages/dart/test/parse_relation_test.dart deleted file mode 100644 index 2dce93605..000000000 --- a/packages/dart/test/parse_relation_test.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; -import 'package:parse_server_sdk/parse_server_sdk.dart'; -import 'package:test/test.dart'; - -import 'parse_query_test.mocks.dart'; - -@GenerateMocks([ParseClient]) -void main() { - group('queryBuilder', () { - test('whereRelatedTo', () async { - final MockParseClient client = MockParseClient(); - - await Parse().initialize( - 'appId', - 'https://test.parse.com', - debug: true, - // to prevent automatic detection - fileDirectory: 'someDirectory', - // to prevent automatic detection - appName: 'appName', - // to prevent automatic detection - appPackageName: 'somePackageName', - // to prevent automatic detection - appVersion: 'someAppVersion', - ); - var post = ParseObject('Post', client: client); - post.objectId = '8TOXdXf3tz'; - var relation = post.getRelation("likes"); - final QueryBuilder queryBuilder = relation.getQuery(); - - when(client.get( - any, - options: anyNamed("options"), - onReceiveProgress: anyNamed("onReceiveProgress"), - )).thenAnswer((_) async => ParseNetworkResponse( - statusCode: 200, - data: - "{\"results\":[{\"objectId\":\"eT9muOxBTJ\",\"username\":\"test\",\"createdAt\":\"2021-04-23T13:46:06.092Z\",\"updatedAt\":\"2021-04-23T13:46:23.586Z\",\"ACL\":{\"*\":{\"read\":true},\"eT9muOxBTJ\":{\"read\":true,\"write\":true}}}]}")); - - ParseResponse response = await queryBuilder.query(); - - expect(response.results?.first, isA()); - - ParseObject parseObject = response.results?.first; - - expect(parseObject.get(keyVarUsername), "test"); - expect(parseObject.objectId, "eT9muOxBTJ"); - expect(parseObject.createdAt, DateTime.parse("2021-04-23T13:46:06.092Z")); - expect(parseObject.updatedAt, DateTime.parse("2021-04-23T13:46:23.586Z")); - - final Uri result = Uri.parse(verify(client.get( - captureAny, - options: anyNamed("options"), - onReceiveProgress: anyNamed("onReceiveProgress"), - )).captured.single); - - expect(result.path, '/classes/_User'); - - final Uri expectedQuery = Uri( - query: - 'where={"\$relatedTo":{"object":{"__type":"Pointer","className":"Post","objectId":"8TOXdXf3tz"},"key":"likes"}}'); - expect(result.query, expectedQuery.query); - }); - }); -} From 843258905b4f98a1b0750b8bf774aa9155c2d3ff Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Wed, 16 Jun 2021 00:47:50 -0300 Subject: [PATCH 194/195] Update parse_relation.dart --- packages/dart/lib/src/objects/parse_relation.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/dart/lib/src/objects/parse_relation.dart b/packages/dart/lib/src/objects/parse_relation.dart index e73289b8b..2f3721f8f 100644 --- a/packages/dart/lib/src/objects/parse_relation.dart +++ b/packages/dart/lib/src/objects/parse_relation.dart @@ -3,6 +3,9 @@ part of flutter_parse_sdk; // ignore_for_file: always_specify_types class ParseRelation { ParseRelation({required ParseObject parent, required String key}) { + if (!parent.containsKey(key)) { + throw 'Invalid Relation key name'; + } _targetClass = parent.get(key)!.getTargetClass; _parent = parent; _key = key; From f5c979c8cdbbd9e684b6303247f5b14191f43a27 Mon Sep 17 00:00:00 2001 From: Rodrigo de Souza Marques Date: Mon, 28 Jun 2021 00:51:28 -0300 Subject: [PATCH 195/195] Update dependencies in pubspec.yaml --- packages/dart/pubspec.yaml | 4 ++-- packages/flutter/pubspec.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 83dadb385..24fc1e74f 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -25,6 +25,6 @@ dependencies: dev_dependencies: # Testing - build_runner: ^2.0.4 + build_runner: ^2.0.5 mockito: ^5.0.10 - test: ^1.17.7 + test: ^1.17.9 diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 7459d1a53..086a5bd62 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -11,11 +11,11 @@ dependencies: sdk: flutter #Uncomment for Release version - #parse_server_sdk: ^3.1.0 + parse_server_sdk: ^3.1.0 # Uncomment for local testing - parse_server_sdk: - path: ../dart + #parse_server_sdk: + # path: ../dart # Uncomment for test with Github Branch #parse_server_sdk: