From 0a26c4bbe73904e69627dccecef177e78f2a8058 Mon Sep 17 00:00:00 2001 From: Phill Date: Wed, 13 Mar 2019 17:58:03 +0000 Subject: [PATCH 1/8] Merge branches 'develop' and 'master' of https://github.com/phillwiggins/flutter_parse_sdk # Conflicts: # .idea/libraries/Dart_Packages.xml # lib/src/objects/parse_file.dart # lib/src/objects/parse_user.dart # pubspec.yaml --- CHANGELOG.md | 5 ++++ README.md | 2 +- lib/src/base/parse_constants.dart | 2 +- lib/src/objects/parse_object.dart | 42 +++++++++++++++++++++++++------ lib/src/objects/parse_user.dart | 28 ++++++++++++++++++--- pubspec.yaml | 2 +- 6 files changed, 66 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c333a7593..04efbf907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.16 +Bug fixes +Fixed object delete +Added port support + ## 1.0.15 Fixed 'full' bool issue diff --git a/README.md b/README.md index 31bdf4f99..afb139412 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Want to get involved? Join our Slack channel and help out! (http://flutter-parse To install, either add to your pubspec.yaml ``` dependencies: - parse_server_sdk: ^1.0.15 + parse_server_sdk: ^1.0.16 ``` 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/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index f591f1416..dd15ca2b7 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '1.0.15'; +const String keySdkVersion = '1.0.16'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index 61c13c918..31191d5f8 100644 --- a/lib/src/objects/parse_object.dart +++ b/lib/src/objects/parse_object.dart @@ -84,13 +84,21 @@ class ParseObject extends ParseBase implements ParseCloneable { return create(); } else { try { - var uri = "${ParseCoreData().serverUrl}$_path/$objectId"; + + Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + + Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + port: tempUri.port, + path: "${tempUri.path}$_path/$objectId"); + var body = json.encode(toJson(forApiRQ: true)); if (_debug) { logRequest(ParseCoreData().appName, className, - ParseApiRQ.save.toString(), uri, body); + ParseApiRQ.save.toString(), url.toString(), body); } - var result = await _client.put(uri, body: body); + var result = await _client.put(url, body: body); return handleResponse(this, result, ParseApiRQ.save, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.save, _debug, className); @@ -178,10 +186,18 @@ class ParseObject extends ParseBase implements ParseCloneable { String key, List values) async { try { if (objectId != null) { - var uri = "${ParseCoreData().serverUrl}$_path/$objectId"; + + Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + + Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + port: tempUri.port, + path: "${tempUri.path}$_path/$objectId"); + var body = "{\"$key\":{\"__op\":\"$arrayAction\",\"objects\":${json.encode(parseEncode(values))}}}"; - var result = await _client.put(uri, body: body); + var result = await _client.put(url, body: body); return handleResponse(this, result, apiRQType, _debug, className); } else { return null; @@ -234,9 +250,17 @@ class ParseObject extends ParseBase implements ParseCloneable { ParseApiRQ apiRQType, String countAction, String key, num amount) async { try { if (objectId != null) { - var uri = "${ParseCoreData().serverUrl}$_path/$objectId"; + + Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + + Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + port: tempUri.port, + path: "${tempUri.path}$_path/$objectId"); + var body = "{\"$key\":{\"__op\":\"$countAction\",\"amount\":$amount}}"; - var result = await _client.put(uri, body: body); + var result = await _client.put(url, body: body); return handleResponse(this, result, apiRQType, _debug, className); } else { return null; @@ -254,6 +278,7 @@ class ParseObject extends ParseBase implements ParseCloneable { Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$_path", query: query); @@ -265,9 +290,10 @@ class ParseObject extends ParseBase implements ParseCloneable { } /// Deletes the current object locally and online - Future delete(String objectId, {String path}) async { + Future delete({String objectId, String path}) async { try { path ??= _path; + objectId ??= objectId; var uri = "${ParseCoreData().serverUrl}$path/$objectId"; if (_debug) { logRequest(ParseCoreData().appName, className, diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index f50770c35..db8c7a6e2 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -95,6 +95,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Uri uri = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$keyEndPointUserName"); final response = await _client.get(uri, headers: headers); @@ -133,6 +134,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$path"); final response = await _client.post(url, @@ -159,6 +161,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$keyEndPointLogin", queryParameters: { keyVarUsername: username, @@ -184,6 +187,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$keyEndPointUsers", ); @@ -224,6 +228,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$keyEndPointUsers", ); @@ -262,6 +267,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, + port: tempUri.port, path: "${tempUri.path}$keyEndPointLogout"); final response = @@ -311,10 +317,17 @@ class ParseUser extends ParseObject implements ParseCloneable { return signUp(); } else { try { - var uri = _client.data.serverUrl + "$path/$objectId"; + Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + + Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + port: tempUri.port, + path: "${tempUri.path}$_path/$objectId"); + var body = json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); - final response = await _client.put(uri, body: body); + final response = await _client.put(url, body: body); return _handleResponse( this, response, ParseApiRQ.save, _debug, className); } on Exception catch (e) { @@ -327,8 +340,15 @@ class ParseUser extends ParseObject implements ParseCloneable { Future destroy() async { if (objectId != null) { try { - final response = - await _client.delete(_client.data.serverUrl + "$path/$objectId"); + Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + + Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + port: tempUri.port, + path: "${tempUri.path}$_path/$objectId"); + + final response = await _client.delete(url); return _handleResponse( this, response, ParseApiRQ.destroy, _debug, className); } on Exception catch (e) { diff --git a/pubspec.yaml b/pubspec.yaml index 53fbb7f49..9199d48fa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 1.0.15 +version: 1.0.16 homepage: https://github.com/phillwiggins/flutter_parse_sdk author: PhillWiggins From 57ca63e91b43ec71860379bfbecdc9188b5e80ec Mon Sep 17 00:00:00 2001 From: Phill Date: Wed, 13 Mar 2019 20:34:38 +0000 Subject: [PATCH 2/8] Correct null pointer from success response with empty body --- lib/src/objects/parse_base.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index bbb90c2a8..bcb784c78 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -52,7 +52,7 @@ abstract class ParseBase { map.remove(keyVarAcl); map.remove(keyParamSessionToken); } - + return map; } @@ -61,6 +61,10 @@ abstract class ParseBase { @protected fromJson(Map objectData) { + if (objectData == null) { + return this; + } + objectData.forEach((key, value) { if (key == className || key == '__type') { // NO OP From 0612fd296cb765369332267c44cc3de26e3d5d8e Mon Sep 17 00:00:00 2001 From: Phill Date: Sat, 16 Mar 2019 16:15:31 +0000 Subject: [PATCH 3/8] Code tidy --- analysis_options.yaml | 179 + example/lib/diet_plan.dart | 2 +- example/lib/main.dart | 198 +- lib/parse_server_sdk.dart | 50 +- lib/src/base/parse_constants.dart | 26 +- lib/src/data/parse_core_data.dart | 50 +- lib/src/network/parse_http_client.dart | 19 +- lib/src/network/parse_live_query.dart | 50 +- lib/src/network/parse_query.dart | 225 +- lib/src/objects/parse_base.dart | 47 +- lib/src/objects/parse_cloneable.dart | 2 +- lib/src/objects/parse_config.dart | 16 +- lib/src/objects/parse_error.dart | 34 +- lib/src/objects/parse_file.dart | 80 +- lib/src/objects/parse_function.dart | 32 +- lib/src/objects/parse_geo_point.dart | 17 +- lib/src/objects/parse_installation.dart | 131 +- lib/src/objects/parse_object.dart | 156 +- lib/src/objects/parse_response.dart | 160 +- lib/src/objects/parse_session.dart | 66 +- lib/src/objects/parse_user.dart | 292 +- .../response/parse_error_response.dart | 14 + .../response/parse_exception_response.dart | 9 + .../response/parse_response_builder.dart | 144 + .../response/parse_success_no_results.dart | 9 + lib/src/utils/parse_decoder.dart | 47 +- lib/src/utils/parse_encoder.dart | 8 +- lib/src/utils/parse_file_extensions.dart | 10886 ++++++++-------- lib/src/utils/parse_logger.dart | 47 +- lib/src/utils/parse_utils.dart | 4 +- 30 files changed, 6626 insertions(+), 6374 deletions(-) create mode 100644 analysis_options.yaml create mode 100644 lib/src/objects/response/parse_error_response.dart create mode 100644 lib/src/objects/response/parse_exception_response.dart create mode 100644 lib/src/objects/response/parse_response_builder.dart create mode 100644 lib/src/objects/response/parse_success_no_results.dart diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 000000000..bb1a51614 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,179 @@ +# Specify analysis options. +# +# Until there are meta linter rules, each desired lint must be explicitly enabled. +# See: https://github.com/dart-lang/linter/issues/288 +# +# For a list of lints, see: http://dart-lang.github.io/linter/lints/ +# See the configuration guide for more +# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# +# There are other similar analysis options files in the flutter repos, +# which should be kept in sync with this file: +# +# - analysis_options.yaml (this file) +# - packages/flutter/lib/analysis_options_user.yaml +# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml +# - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# +# This file contains the analysis options used by Flutter tools, such as IntelliJ, +# Android Studio, and the `flutter analyze` command. + +analyzer: + strong-mode: + implicit-dynamic: false + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # allow having TODOs in the code + todo: ignore + # Ignore analyzer hints for updating pubspecs when using Future or + # Stream and not importing dart:async + # Please see https://github.com/flutter/flutter/pull/24528 for details. + sdk_version_async_exported_from_core: ignore + exclude: + - 'bin/cache/**' + # the following two are relative to the stocks example and the flutter package respectively + # see https://github.com/dart-lang/sdk/issues/28463 + - 'lib/i18n/stock_messages_*.dart' + - 'lib/src/http/**' + +linter: + rules: + # these rules are documented on and in the same order as + # the Dart Lint rules page to make maintenance easier + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + - always_put_control_body_on_new_line + # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 + - always_require_non_null_named_parameters + - always_specify_types + - annotate_overrides + # - avoid_annotating_with_dynamic # conflicts with always_specify_types + - avoid_as + # - avoid_bool_literals_in_conditional_expressions # not yet tested + # - avoid_catches_without_on_clauses # we do this commonly + # - avoid_catching_errors # we do this commonly + - avoid_classes_with_only_static_members + # - avoid_double_and_int_checks # only useful when targeting JS runtime + - avoid_empty_else + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + # - avoid_implementing_value_types # not yet tested + - avoid_init_to_null + # - avoid_js_rounded_ints # only useful when targeting JS runtime + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters # not yet tested + # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + # - avoid_returning_null # there are plenty of valid reasons to return null + # - avoid_returning_null_for_future # not yet tested + - avoid_returning_null_for_void + # - avoid_returning_this # there are plenty of valid reasons to return this + # - avoid_setters_without_getters # not yet tested + # - avoid_shadowing_type_parameters # not yet tested + # - avoid_single_cascade_in_expression_statements # not yet tested + - avoid_slow_async_io + - avoid_types_as_parameter_names + # - avoid_types_on_closure_parameters # conflicts with always_specify_types + - avoid_unused_constructor_parameters + - avoid_void_async + - await_only_futures + - camel_case_types + - cancel_subscriptions + # - cascade_invocations # not yet tested + # - close_sinks # not reliable enough + # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 + # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 + - control_flow_in_finally + # - curly_braces_in_flow_control_structures # not yet tested + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + # - file_names # not yet tested + - flutter_style_todos + - hash_and_equals + - implementation_imports + # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + - iterable_contains_unrelated_type + # - join_return_with_assignment # not yet tested + - library_names + - library_prefixes + # - lines_longer_than_80_chars # not yet tested + - list_remove_unrelated_type + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 + - no_adjacent_strings_in_list + - no_duplicate_case_values + - non_constant_identifier_names + # - null_closures # not yet tested + # - omit_local_variable_types # opposite of always_specify_types + # - one_member_abstracts # too many false positives + # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + # - parameter_assignments # we do this commonly + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + # - prefer_collection_literals # temporary until all platforms support set literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + # - prefer_constructors_over_static_methods # not yet tested + - prefer_contains + - prefer_equal_for_default_values + # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods + - prefer_final_fields + - prefer_final_locals + - prefer_foreach + # - prefer_function_declarations_over_variables # not yet tested + - prefer_generic_function_type_aliases + - prefer_initializing_formals + # - prefer_int_literals # not yet tested + # - prefer_interpolation_to_compose_strings # not yet tested + - prefer_is_empty + - prefer_is_not_empty + - prefer_iterable_whereType + # - prefer_mixin # https://github.com/dart-lang/language/issues/32 + - prefer_single_quotes + - prefer_typing_uninitialized_variables + - prefer_void_to_null + # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml + - recursive_getters + - slash_for_doc_comments + - sort_constructors_first + - sort_pub_dependencies + - sort_unnamed_constructors_first + # - super_goes_last # no longer needed w/ Dart 2 + - test_types_in_equals + - throw_in_finally + # - type_annotate_public_apis # subset of always_specify_types + - type_init_formals + # - unawaited_futures # too many false positives + # - unnecessary_await_in_return # not yet tested + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_getters_setters + # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_in_if_null_operators + - unnecessary_overrides + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_this + - unrelated_type_equality_checks + # - use_function_type_syntax_for_parameters # not yet tested + - use_rethrow_when_possible + # - use_setters_to_change_properties # not yet tested + # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - valid_regexps + # - void_checks # not yet tested \ No newline at end of file diff --git a/example/lib/diet_plan.dart b/example/lib/diet_plan.dart index 2a064a3b7..b9046d3f5 100644 --- a/example/lib/diet_plan.dart +++ b/example/lib/diet_plan.dart @@ -9,7 +9,7 @@ class DietPlan extends ParseObject implements ParseCloneable { /// Looks strangely hacky but due to Flutter not using reflection, we have to /// mimic a clone @override - clone(Map map) => DietPlan.clone()..fromJson(map); + DietPlan clone(Map map) => DietPlan.clone()..fromJson(map); static const String _keyTableName = 'Diet_Plans'; static const String keyName = 'Name'; diff --git a/example/lib/main.dart b/example/lib/main.dart index 06dbf8527..dcb19eae5 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -6,12 +6,12 @@ import 'package:parse_server_sdk/parse_server_sdk.dart'; void main() { Stetho.initialize(); - runApp(new MyApp()); + runApp(MyApp()); } class MyApp extends StatefulWidget { @override - _MyAppState createState() => new _MyAppState(); + _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { @@ -23,36 +23,35 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { - return new MaterialApp( - home: new Scaffold( - appBar: new AppBar( + return MaterialApp( + home: Scaffold( + appBar: AppBar( title: const Text('Plugin example app'), ), - body: new Center( - child: new Text('Running Parse init'), + body: Center( + child: const Text('Running Parse init'), ), - floatingActionButton: - new FloatingActionButton(onPressed: runTestQueries), + floatingActionButton: FloatingActionButton(onPressed: runTestQueries), ), ); } - initParse() async { + Future initParse() async { // Initialize parse Parse().initialize(ApplicationConstants.keyParseApplicationId, ApplicationConstants.keyParseServerUrl, masterKey: ApplicationConstants.keyParseMasterKey, debug: true); // Check server is healthy and live - Debug is on in this instance so check logs for result - var response = await Parse().healthCheck(); + final ParseResponse response = await Parse().healthCheck(); if (response.success) { runTestQueries(); } else { - print("Server health check failed"); + print('Server health check failed'); } } - runTestQueries() { + void runTestQueries() { createItem(); getAllItems(); getAllItemsByName(); @@ -64,153 +63,198 @@ class _MyAppState extends State { functionWithParameters(); } - void createItem() async { - var newObject = ParseObject('TestObjectForApi'); + Future createItem() async { + final ParseObject newObject = ParseObject('TestObjectForApi'); newObject.set('name', 'testItem'); newObject.set('age', 26); - var apiResponse = await newObject.create(); + final ParseResponse apiResponse = await newObject.create(); if (apiResponse.success && apiResponse.result != null) { print(ApplicationConstants.keyAppName + - ": " + + ': ' + apiResponse.result.toString()); } } - void getAllItemsByName() async { - var apiResponse = await ParseObject('TestObjectForApi').getAll(); + Future getAllItemsByName() async { + final ParseResponse apiResponse = + await ParseObject('TestObjectForApi').getAll(); if (apiResponse.success && apiResponse.result != null) { - for (var testObject in apiResponse.result) { - print(ApplicationConstants.keyAppName + ": " + testObject.toString()); + for (final ParseObject testObject in apiResponse.result) { + print(ApplicationConstants.keyAppName + ': ' + testObject.toString()); } } } - void getAllItems() async { - var apiResponse = await DietPlan().getAll(); + Future getAllItems() async { + final ParseResponse apiResponse = await DietPlan().getAll(); if (apiResponse.success && apiResponse.result != null) { - for (var plan in apiResponse.result) { - print(ApplicationConstants.keyAppName + ": " + (plan as DietPlan).name); + for (final DietPlan plan in apiResponse.result) { + print(ApplicationConstants.keyAppName + ': ' + plan.name); } } else { - print(ApplicationConstants.keyAppName + ": " + apiResponse.error.message); + print(ApplicationConstants.keyAppName + ': ' + apiResponse.error.message); } } - void getSingleItem() async { - var apiResponse = await DietPlan().getObject('R5EonpUDWy'); + Future getSingleItem() async { + final ParseResponse apiResponse = await DietPlan().getObject('R5EonpUDWy'); if (apiResponse.success && apiResponse.result != null) { - var dietPlan = (apiResponse.result as DietPlan); + final DietPlan dietPlan = apiResponse.result; // Shows example of storing values in their proper type and retrieving them dietPlan.set('RandomInt', 8); - var randomInt = dietPlan.get('RandomInt'); + final int randomInt = dietPlan.get('RandomInt'); - if (randomInt is int) print('Saving generic value worked!'); + if (randomInt is int) { + print('Saving generic value worked!'); + } // Shows example of pinning an item await dietPlan.pin(); // shows example of retrieving a pin - var newDietPlanFromPin = await DietPlan().fromPin('R5EonpUDWy'); - if (newDietPlanFromPin != null) print('Retreiving from pin worked!'); + final DietPlan newDietPlanFromPin = + await DietPlan().fromPin('R5EonpUDWy'); + if (newDietPlanFromPin != null) { + print('Retreiving from pin worked!'); + } } else { - print(ApplicationConstants.keyAppName + ": " + apiResponse.error.message); + print(ApplicationConstants.keyAppName + ': ' + apiResponse.error.message); } } - void query() async { - var queryBuilder = + Future query() async { + final QueryBuilder queryBuilder = QueryBuilder(ParseObject('TestObjectForApi')) ..whereEqualTo('age', 26) - ..includeObject(['Day']); + ..includeObject(['Day']); - var apiResponse = await queryBuilder.query(); + final ParseResponse apiResponse = await queryBuilder.query(); if (apiResponse.success && apiResponse.result != null) { - print( - "Result: ${((apiResponse.result as List).first as ParseObject).toString()}"); + final List listFromApi = apiResponse.result; + final ParseObject parseObject = listFromApi?.first; + print('Result: ${parseObject.toString()}'); } else { - print("Result: ${apiResponse.error.message}"); + print('Result: ${apiResponse.error.message}'); } } - initUser() async { + Future initUser() async { // All return type ParseUser except all - var user = - ParseUser("TestFlutter", "TestPassword123", "phill.wiggins@gmail.com"); - var response = await user.signUp(); - if (response.success) user = response.result; + ParseUser user = + ParseUser('TestFlutter', 'TestPassword123', 'test.flutter@gmail.com'); + + /// Sign-up + ParseResponse response = await user.signUp(); + if (response.success) { + user = response.result; + } + /// Login response = await user.login(); - if (response.success) user = response.result; + if (response.success) { + user = response.result; + } + /// Reset password response = await user.requestPasswordReset(); - if (response.success) user = response.result; + if (response.success) { + user = response.result; + } + /// Verify email response = await user.verificationEmailRequest(); - // Best practice for starting the app. This will check for a valid user + if (response.success) { + user = response.result; + } + + // Best practice for starting the app. This will check for a valid user from a previous session from a local storage user = await ParseUser.currentUser(); - await user.logout(); + + /// Update current user from server - Best done to verify user is still a valid user + response = await ParseUser.getCurrentUserFromServer( + token: user?.get(keyHeaderSessionToken)); + if (response.success) { + user = response.result; + } + + /// log user out + response = await user.logout(); + if (response.success) { + user = response.result; + } user = - ParseUser("TestFlutter", "TestPassword123", "phill.wiggins@gmail.com"); + ParseUser('TestFlutter', 'TestPassword123', 'phill.wiggins@gmail.com'); response = await user.login(); - if (response.success) user = response.result; - - response = await ParseUser.getCurrentUserFromServer( - token: user.get(keyHeaderSessionToken)); - if (response.success) user = response.result; + if (response.success) { + user = response.result; + } response = await user.save(); - if (response.success) user = response.result; + if (response.success) { + user = response.result; + } - var destroyResponse = await user.destroy(); - if (destroyResponse.success) print('object has been destroyed!'); + /// Remove a user and delete + final ParseResponse destroyResponse = await user.destroy(); + if (destroyResponse.success) { + print('object has been destroyed!'); + } // Returns type ParseResponse as its a query, not a single result response = await ParseUser.all(); - if (response.success) user = response.result; + if (response.success) { + // We have a list of all users (LIMIT SET VIA SDK) + } - var queryBuilder = QueryBuilder(ParseUser.forQuery()) - ..whereStartsWith(ParseUser.keyUsername, 'phillw'); + final QueryBuilder queryBuilder = + QueryBuilder(ParseUser.forQuery()) + ..whereStartsWith(ParseUser.keyUsername, 'phillw'); - var apiResponse = await queryBuilder.query(); - if (apiResponse.success) user = response.result; + final ParseResponse apiResponse = await queryBuilder.query(); + if (apiResponse.success) { + user = response.result; + } } - function() async { - var function = ParseCloudFunction('hello'); - var result = await function.executeObjectFunction(); + Future function() async { + final ParseCloudFunction function = ParseCloudFunction('hello'); + final ParseResponse result = + await function.executeObjectFunction(); if (result.success) { if (result.result is ParseObject) { - print((result.result as ParseObject).className); + final ParseObject parseObject = result.result; + print(parseObject.className); } } } - functionWithParameters() async { - var function = ParseCloudFunction('hello'); - var params = {'plan': 'paid'}; + Future functionWithParameters() async { + final ParseCloudFunction function = ParseCloudFunction('hello'); + final Map params = {'plan': 'paid'}; function.execute(parameters: params); } - Future getConfigs() async { - var config = ParseConfig(); - var addResponse = await config.addConfig('TestConfig', 'testing'); + Future getConfigs() async { + final ParseConfig config = ParseConfig(); + final ParseResponse addResponse = + await config.addConfig('TestConfig', 'testing'); if (addResponse.success) { - print("Added a config"); + print('Added a config'); } - var getResponse = await config.getConfigs(); + final ParseResponse getResponse = await config.getConfigs(); if (getResponse.success) { - print("We have our configs."); + print('We have our configs.'); } } } diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index 3df9b6aaa..9a302e9e4 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -5,16 +5,24 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:devicelocale/devicelocale.dart'; import 'package:http/http.dart'; import 'package:http/io_client.dart'; import 'package:meta/meta.dart'; +import 'package:package_info/package_info.dart'; import 'package:path/path.dart' as path; +import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:web_socket_channel/io.dart'; import 'package:uuid/uuid.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:devicelocale/devicelocale.dart'; -import 'package:package_info/package_info.dart'; +import 'package:web_socket_channel/io.dart'; + +part 'package:parse_server_sdk/src/objects/response/parse_error_response.dart'; + +part 'package:parse_server_sdk/src/objects/response/parse_exception_response.dart'; + +part 'package:parse_server_sdk/src/objects/response/parse_response_builder.dart'; + +part 'package:parse_server_sdk/src/objects/response/parse_success_no_results.dart'; part 'src/base/parse_constants.dart'; @@ -42,15 +50,15 @@ part 'src/objects/parse_function.dart'; part 'src/objects/parse_geo_point.dart'; +part 'src/objects/parse_installation.dart'; + part 'src/objects/parse_object.dart'; part 'src/objects/parse_response.dart'; -part 'src/objects/parse_user.dart'; - part 'src/objects/parse_session.dart'; -part 'src/objects/parse_installation.dart'; +part 'src/objects/parse_user.dart'; part 'src/utils/parse_decoder.dart'; @@ -79,8 +87,8 @@ class Parse { // liveQuery: true); // ``` Parse initialize(String appId, String serverUrl, - {bool debug: false, - String appName: "", + {bool debug = false, + String appName = '', String liveQueryUrl, String clientKey, String masterKey, @@ -108,25 +116,23 @@ class Parse { {bool debug, ParseHTTPClient client, bool autoSendSessionId}) async { ParseResponse parseResponse; - bool _debug = isDebugEnabled(objectLevelDebug: debug); - ParseHTTPClient _client = client ?? + final bool _debug = isDebugEnabled(objectLevelDebug: debug); + final ParseHTTPClient _client = client ?? ParseHTTPClient( - autoSendSessionId: + sendSessionId: autoSendSessionId ?? ParseCoreData().autoSendSessionId, securityContext: ParseCoreData().securityContext); + const String className = 'parseBase'; + const ParseApiRQ type = ParseApiRQ.healthCheck; + try { - var response = - await _client.get("${ParseCoreData().serverUrl}$keyEndPointHealth"); - parseResponse = - ParseResponse.handleResponse(this, response, returnAsResult: true); - } on Exception catch (e) { - parseResponse = ParseResponse.handleException(e); - } + final Response response = + await _client.get('${ParseCoreData().serverUrl}$keyEndPointHealth'); - if (_debug) { - logger(ParseCoreData().appName, keyClassMain, - ParseApiRQ.healthCheck.toString(), parseResponse); + parseResponse = handleResponse(null, response, type, _debug, className); + } on Exception catch (e) { + parseResponse = handleException(e, type, _debug, className); } return parseResponse; diff --git a/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index dd15ca2b7..cc3021fc2 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -50,5 +50,27 @@ const String keyParamSessionToken = 'sessionToken'; // Storage const String keyParseStoreBase = 'flutter_parse_sdk_'; -const String keyParseStoreUser = "${keyParseStoreBase}user"; -const String keyParseStoreInstallation = "${keyParseStoreBase}installation"; +const String keyParseStoreUser = '${keyParseStoreBase}user'; +const String keyParseStoreInstallation = '${keyParseStoreBase}installation'; + +// Installation +const String keyTimeZone = 'timeZone'; +const String keyLocaleIdentifier = 'localeIdentifier'; +const String keyDeviceToken = 'deviceToken'; +const String keyDeviceType = 'deviceType'; +const String keyInstallationId = 'installationId'; +const String keyAppName = 'appName'; +const String keyAppVersion = 'appVersion'; +const String keyAppIdentifier = 'appIdentifier'; +const String keyParseVersion = 'parseVersion'; + +// Parse Session +const String keyVarUser = 'user'; +const String keyVarCreatedWith = 'createdWith'; +const String keyVarRestricted = 'restricted'; +const String keyVarExpiresAt = 'expiresAt'; +const String keyVarInstallationId = 'installationId'; + +// Error +const String keyError = 'error'; +const String keyCode = 'code'; diff --git a/lib/src/data/parse_core_data.dart b/lib/src/data/parse_core_data.dart index b5b0bccee..7a9429216 100644 --- a/lib/src/data/parse_core_data.dart +++ b/lib/src/data/parse_core_data.dart @@ -2,6 +2,11 @@ part of flutter_parse_sdk; /// Singleton class that defines all user keys and data class ParseCoreData { + + factory ParseCoreData() => _instance; + + ParseCoreData._init(this.applicationId, this.serverUrl); + static ParseCoreData _instance; static ParseCoreData get instance => _instance; @@ -10,26 +15,33 @@ class ParseCoreData { /// /// This class should not be user unless switching servers during the app, /// which is odd. Should only be user by Parse.init - static void init(appId, serverUrl, - {debug, - appName, - liveQueryUrl, - masterKey, - clientKey, - sessionId, - autoSendSessionId, - securityContext}) { + static void init(String appId, String serverUrl, + {bool debug, + String appName, + String liveQueryUrl, + String masterKey, + String clientKey, + String sessionId, + bool autoSendSessionId, + SecurityContext securityContext}) { _instance = ParseCoreData._init(appId, serverUrl); - if (debug != null) _instance.debug = debug; - if (appName != null) _instance.appName = appName; - 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 (debug != null) + _instance.debug = debug; + if (appName != null) + _instance.appName = appName; + 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 (securityContext != null) + _instance.securityContext = securityContext; } String appName; @@ -44,10 +56,6 @@ class ParseCoreData { bool debug; SharedPreferences storage; - ParseCoreData._init(this.applicationId, this.serverUrl); - - factory ParseCoreData() => _instance; - /// Sets the current sessionId. /// /// This is generated when a users logs in, or calls currentUser to update @@ -61,5 +69,5 @@ class ParseCoreData { } @override - String toString() => "$applicationId $masterKey"; + String toString() => '$applicationId $masterKey'; } diff --git a/lib/src/network/parse_http_client.dart b/lib/src/network/parse_http_client.dart index a31da62da..6659abb15 100644 --- a/lib/src/network/parse_http_client.dart +++ b/lib/src/network/parse_http_client.dart @@ -2,25 +2,26 @@ part of flutter_parse_sdk; /// Creates a custom version of HTTP Client that has Parse Data Preset class ParseHTTPClient extends BaseClient { - final Client _client; - final bool _autoSendSessionId; - final String _userAgent = "$keyLibraryName $keySdkVersion"; - ParseCoreData data = ParseCoreData(); - Map additionalHeaders; ParseHTTPClient( - {bool autoSendSessionId = false, SecurityContext securityContext}) - : _autoSendSessionId = autoSendSessionId, + {bool sendSessionId = false, SecurityContext securityContext}) + : _sendSessionId = sendSessionId, _client = securityContext != null ? IOClient(HttpClient(context: securityContext)) : IOClient(); + final Client _client; + final bool _sendSessionId; + final String _userAgent = '$keyLibraryName $keySdkVersion'; + ParseCoreData data = ParseCoreData(); + Map additionalHeaders; + /// Overrides the call method for HTTP Client and adds custom headers @override Future send(BaseRequest request) { request.headers[keyHeaderUserAgent] = _userAgent; request.headers[keyHeaderApplicationId] = data.applicationId; - if ((_autoSendSessionId == true) && + if ((_sendSessionId == true) && (data.sessionId != null) && (request.headers[keyHeaderSessionToken] == null)) request.headers[keyHeaderSessionToken] = data.sessionId; @@ -31,7 +32,7 @@ class ParseHTTPClient extends BaseClient { request.headers[keyHeaderMasterKey] = data.masterKey; /// If developer wants to add custom headers, extend this class and add headers needed. - if (additionalHeaders != null && additionalHeaders.length > 0) { + if (additionalHeaders != null && additionalHeaders.isNotEmpty) { additionalHeaders.forEach((k, v) => request.headers[k] = v); } diff --git a/lib/src/network/parse_live_query.dart b/lib/src/network/parse_live_query.dart index 31bd4382e..4126d9345 100644 --- a/lib/src/network/parse_live_query.dart +++ b/lib/src/network/parse_live_query.dart @@ -2,37 +2,41 @@ part of flutter_parse_sdk; /// Still under development class LiveQuery { - final ParseHTTPClient client; - var channel; - Map connectMessage; - Map subscribeMessage; - Map eventCallbacks = {}; LiveQuery(ParseHTTPClient client) : client = client { connectMessage = { - "op": "connect", - "applicationId": client.data.applicationId, + 'op': 'connect', + 'applicationId': client.data.applicationId, }; + final Map whereMap = Map(); + subscribeMessage = { - "op": "subscribe", - "requestId": 1, - "query": { - "className": null, - "where": {}, + 'op': 'subscribe', + 'requestId': 1, + 'query': { + 'className': null, + 'where': whereMap, } }; } - subscribe(String className) async { - // ignore: close_sinks - var webSocket = await WebSocket.connect(client.data.liveQueryURL); - channel = new IOWebSocketChannel(webSocket); - channel.sink.add(JsonEncoder().convert(connectMessage)); - subscribeMessage['query']['className'] = className; - channel.sink.add(JsonEncoder().convert(subscribeMessage)); - channel.stream.listen((message) { - Map actionData = JsonDecoder().convert(message); + final ParseHTTPClient client; + IOWebSocketChannel channel; + Map connectMessage; + Map subscribeMessage; + Map eventCallbacks = {}; + + Future subscribe(String className) async { + final WebSocket webSocket = await WebSocket.connect(client.data.liveQueryURL); + channel = IOWebSocketChannel(webSocket); + channel.sink.add(jsonEncode(connectMessage)); + Map classNameMap = subscribeMessage['query']; + classNameMap['className'] = className; + channel.sink.add(jsonEncode(subscribeMessage)); + + channel.stream.listen((dynamic message) { + final Map actionData = jsonDecode(message); if (eventCallbacks.containsKey(actionData['op'])) eventCallbacks[actionData['op']](actionData); }); @@ -42,7 +46,7 @@ class LiveQuery { eventCallbacks[op] = callback; } - void close() { - channel.close(); + Future close() async { + await channel.sink.close(); } } diff --git a/lib/src/network/parse_query.dart b/lib/src/network/parse_query.dart index 8cdd67623..fac28485e 100644 --- a/lib/src/network/parse_query.dart +++ b/lib/src/network/parse_query.dart @@ -2,24 +2,24 @@ part of flutter_parse_sdk; /// Class to create complex queries class QueryBuilder { - static const String _NO_OPERATOR_NEEDED = "NO_OP"; - static const String _SINGLE_QUERY = "SINGLE_QUERY"; - - T object; - var queries = List(); - var limiters = Map(); - /// Class to create complex queries QueryBuilder(this.object) : super(); + static const String _NO_OPERATOR_NEEDED = 'NO_OP'; + static const String _SINGLE_QUERY = 'SINGLE_QUERY'; + + T object; + List> queries = >[]; + final Map limiters = Map(); + /// Adds a limit to amount of results return from Parse void setLimit(int limit) { - limiters["limit"] = limit; + limiters['limit'] = limit; } /// Useful for pagination, skips [int] amount of results void setAmountToSkip(int skip) { - limiters["skip"] = skip; + limiters['skip'] = skip; } /// Creates a query based on where @@ -32,7 +32,7 @@ class QueryBuilder { /// [String] order will be the column of the table that the results are /// ordered by void orderByAscending(String order) { - limiters["order"] = order; + limiters['order'] = order; } /// Sorts the results descending order. @@ -40,7 +40,7 @@ class QueryBuilder { /// [String] order will be the column of the table that the results are /// ordered by void orderByDescending(String order) { - limiters["order"] = "-$order"; + limiters['order'] = '-$order'; } /// Define which keys in an object to return. @@ -48,33 +48,34 @@ class QueryBuilder { /// [String] keys will only return the columns of a result you want the data for, /// this is useful for large objects void keysToReturn(List keys) { - limiters["keys"] = concatenateArray(keys); + limiters['keys'] = concatenateArray(keys); } /// Includes other ParseObjects stored as a Pointer void includeObject(List objectTypes) { - limiters["include"] = concatenateArray(objectTypes); + limiters['include'] = concatenateArray(objectTypes); } /// Returns an object where the [String] column starts with [value] void whereStartsWith(String column, String query, - {bool caseSensitive: false}) { + {bool caseSensitive = false}) { if (caseSensitive) { - queries.add( - MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$regex\": \"^$query\"}')); + queries.add(MapEntry( + _SINGLE_QUERY, '\"$column\":{\"\$regex\": \"^$query\"}')); } else { - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$regex\": \"^$query\", \"\$options\": \"i\"}')); } } /// Returns an object where the [String] column ends with [value] - void whereEndsWith(String column, String query, {bool caseSensitive: false}) { + void whereEndsWith(String column, String query, + {bool caseSensitive = false}) { if (caseSensitive) { - queries.add( - MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$query^\"}')); + queries.add(MapEntry( + _SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$query^\"}')); } else { - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$query^\", \"\$options\": \"i\"}')); } } @@ -82,93 +83,94 @@ class QueryBuilder { /// Returns an object where the [String] column equals [value] void whereEqualTo(String column, dynamic value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), _NO_OPERATOR_NEEDED)); + MapEntry(column, value), _NO_OPERATOR_NEEDED)); } /// Returns an object where the [String] column contains a value less than /// value void whereLessThan(String column, dynamic value) { - queries.add( - _buildQueryWithColumnValueAndOperator(MapEntry(column, value), "\$lt")); + queries.add(_buildQueryWithColumnValueAndOperator( + MapEntry(column, value), '\$lt')); } /// Returns an object where the [String] column contains a value less or equal /// to than value void whereLessThanOrEqualTo(String column, dynamic value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$lte")); + MapEntry(column, value), '\$lte')); } /// Returns an object where the [String] column contains a value greater /// than value void whereGreaterThan(String column, dynamic value) { - queries.add( - _buildQueryWithColumnValueAndOperator(MapEntry(column, value), "\$gt")); + queries.add(_buildQueryWithColumnValueAndOperator( + MapEntry(column, value), '\$gt')); } /// Returns an object where the [String] column contains a value greater /// than equal to value void whereGreaterThanOrEqualsTo(String column, dynamic value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$gte")); + MapEntry(column, value), '\$gte')); } /// Returns an object where the [String] column is not equal to value void whereNotEqualTo(String column, dynamic value) { - queries.add( - _buildQueryWithColumnValueAndOperator(MapEntry(column, value), "\$ne")); + queries.add(_buildQueryWithColumnValueAndOperator( + MapEntry(column, value), '\$ne')); } /// Returns an object where the [String] column is containedIn - void whereContainedIn(String column, List value) { - queries.add( - _buildQueryWithColumnValueAndOperator(MapEntry(column, value), "\$in")); + void whereContainedIn(String column, List value) { + queries.add(_buildQueryWithColumnValueAndOperator( + MapEntry(column, value), '\$in')); } /// Returns an object where the [String] column is notContainedIn - void whereNotContainedIn(String column, List value) { + void whereNotContainedIn(String column, List value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$nin")); + MapEntry(column, value), '\$nin')); } /// Returns an object where the [String] column for the object has data correctly entered/saved void whereValueExists(String column, bool value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$exists")); + MapEntry(column, value), '\$exists')); } /// Returns an object where the [String] column contains select void selectKeys(String column, dynamic value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$select")); + MapEntry(column, value), '\$select')); } /// Returns an object where the [String] column doesn't select void dontSelectKeys(String column, dynamic value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$dontSelect")); + MapEntry(column, value), '\$dontSelect')); } /// Returns an object where the [String] column contains all - void whereArrayContainsAll(String column, List value) { + void whereArrayContainsAll(String column, List value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value.toString()), "\$all")); + MapEntry(column, value.toString()), '\$all')); } /// Returns an object where the [String] column has a regEx performed on, /// this can include ^StringsWith, or ^EndsWith. This can be manipulated to the users desire void regEx(String column, String value) { queries.add(_buildQueryWithColumnValueAndOperator( - MapEntry(column, value), "\$regex")); + MapEntry(column, value), '\$regex')); } /// Performs a search to see if [String] contains other string - void whereContains(String column, String value, {bool caseSensitive: false}) { + void whereContains(String column, String value, + {bool caseSensitive = false}) { if (caseSensitive) { - queries.add( - MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$value\"}')); + queries.add(MapEntry( + _SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$value\"}')); } else { - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$regex\": \"$value\", \"\$options\": \"i\"}')); } } @@ -176,60 +178,62 @@ 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}) { - queries.add(MapEntry(_SINGLE_QUERY, + {bool caseSensitive = false, bool orderByScore = true}) { + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$text\":{\"\$search\":{\"\$term\": \"$query\", \"\$caseSensitive\": $caseSensitive }}}')); - if (orderByScore) orderByDescending('score'); + if (orderByScore) { + orderByDescending('score'); + } } - /// Returns an objects with key point values near the point given + /// Returns an objects with key point values near the point given void whereNear(String column, ParseGeoPoint point) { - var latitude = point.latitude; - var longitude = point.longitude; - queries.add(MapEntry(_SINGLE_QUERY, + final double latitude = point.latitude; + final double longitude = point.longitude; + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$nearSphere\":{\"__type\":\"GeoPoint\",\"latitude\":$latitude,\"longitude\":$longitude}}')); } /// Returns an object with key point values near the point given and within the maximum distance given. void whereWithinMiles( String column, ParseGeoPoint point, double maxDistance) { - var latitude = point.latitude; - var longitude = point.longitude; + final double latitude = point.latitude; + final double longitude = point.longitude; - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$nearSphere\":{\"__type\":\"GeoPoint\",\"latitude\":$latitude,\"longitude\":$longitude},\"\$maxDistanceInMiles\":$maxDistance}')); } /// Returns an object with key point values near the point given and within the maximum distance given. void whereWithinKilometers( String column, ParseGeoPoint point, double maxDistance) { - var latitude = point.latitude; - var longitude = point.longitude; + final double latitude = point.latitude; + final double longitude = point.longitude; - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$nearSphere\":{\"__type\":\"GeoPoint\",\"latitude\":$latitude,\"longitude\":$longitude},\"\$maxDistanceInKilometers\":$maxDistance}')); } /// Returns an object with key point values near the point given and within the maximum distance given. void whereWithinRadians( String column, ParseGeoPoint point, double maxDistance) { - var latitude = point.latitude; - var longitude = point.longitude; + final double latitude = point.latitude; + final double longitude = point.longitude; - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$nearSphere\":{\"__type\":\"GeoPoint\",\"latitude\":$latitude,\"longitude\":$longitude},\"\$maxDistanceInRadians\":$maxDistance}')); } /// Returns an object with key point values contained within a given rectangular geographic bounding box. void whereWithinGeoBox( String column, ParseGeoPoint southwest, ParseGeoPoint northeast) { - var latitudeS = southwest.latitude; - var longitudeS = southwest.longitude; + final double latitudeS = southwest.latitude; + final double longitudeS = southwest.longitude; - var latitudeN = northeast.latitude; - var longitudeN = northeast.longitude; + final double latitudeN = northeast.latitude; + final double longitudeN = northeast.longitude; - queries.add(MapEntry(_SINGLE_QUERY, + queries.add(MapEntry(_SINGLE_QUERY, '\"$column\":{\"\$within\":{\"\$box\": [{\"__type\": \"GeoPoint\",\"latitude\":$latitudeS,\"longitude\":$longitudeS},{\"__type\": \"GeoPoint\",\"latitude\":$latitudeN,\"longitude\":$longitudeN}]}}')); } @@ -243,19 +247,18 @@ class QueryBuilder { /// Builds the query for Parse String _buildQuery() { queries = _checkForMultipleColumnInstances(queries); - var query = "where={${buildQueries(queries)}}${getLimiters(limiters)}"; - return "$query"; + return 'where={${buildQueries(queries)}}${getLimiters(limiters)}'; } /// Runs through all queries and adds them to a query string - String buildQueries(List queries) { - String queryBuilder = ""; + String buildQueries(List> queries) { + String queryBuilder = ''; - for (var item in queries) { + for (final MapEntry item in queries) { if (item == queries.first) { queryBuilder += item.value; } else { - queryBuilder += ",${item.value}"; + queryBuilder += ',${item.value}'; } } @@ -263,12 +266,13 @@ class QueryBuilder { } String concatenateArray(List queries) { - String queryBuilder = ""; + String queryBuilder = ''; - for (var item in queries) { + for (final String item in queries) { if (item == queries.first) { queryBuilder += item; } else { + // ignore: prefer_single_quotes queryBuilder += ",$item"; } } @@ -278,39 +282,44 @@ class QueryBuilder { /// Creates a query param using the column, the value and the queryOperator /// that the column and value are being queried against - MapEntry _buildQueryWithColumnValueAndOperator( - MapEntry columnAndValue, String queryOperator) { - var key = columnAndValue.key; + MapEntry _buildQueryWithColumnValueAndOperator( + MapEntry columnAndValue, String queryOperator) { + final String key = columnAndValue.key; - var value = convertValueToCorrectType(columnAndValue.value); + final dynamic value = convertValueToCorrectType(columnAndValue.value); if (queryOperator == _NO_OPERATOR_NEEDED) { - return MapEntry(_NO_OPERATOR_NEEDED, "\"${columnAndValue.key}\": $value"); + return MapEntry( + _NO_OPERATOR_NEEDED, '\"${columnAndValue.key}\": $value"'); } else { - var queryString = "\"$key\":"; + String queryString = '\"$key\":'; - var queryOperatorAndValueMap = Map(); + final Map queryOperatorAndValueMap = + Map(); queryOperatorAndValueMap[queryOperator] = columnAndValue.value; - var formattedQueryOperatorAndValue = - JsonEncoder().convert(queryOperatorAndValueMap); - queryString += "$formattedQueryOperatorAndValue"; + final String formattedQueryOperatorAndValue = + jsonEncode(queryOperatorAndValueMap); + queryString += '$formattedQueryOperatorAndValue'; - return MapEntry(key, queryString); + return MapEntry(key, queryString); } } /// This joins queries that should be joined together... e.g. age > 10 && /// age < 20, this would be similar to age > 10 < 20 - List _checkForMultipleColumnInstances(List queries) { - List sanitizedQueries = List(); - List keysAlreadyCompacted = List(); + List> _checkForMultipleColumnInstances( + List> queries) { + final List> sanitizedQueries = + List>(); + final List keysAlreadyCompacted = List(); // Run through each query - for (var query in queries) { + for (final MapEntry query in queries) { // Add queries that don't need sanitizing if (query.key == _NO_OPERATOR_NEEDED || query.key == _SINGLE_QUERY) { - sanitizedQueries.add(MapEntry(_NO_OPERATOR_NEEDED, query.value)); + sanitizedQueries + .add(MapEntry(_NO_OPERATOR_NEEDED, query.value)); } // Check if query with same column name has been sanitized @@ -321,27 +330,29 @@ class QueryBuilder { keysAlreadyCompacted.add(query.key); // Build a list of all queries with the same column name - var listOfQueriesCompact = - queries.where((i) => query.key == i.key).toList(); + final List> listOfQueriesCompact = queries + .where((MapEntry entry) => query.key == entry.key) + .toList(); // Build first part of query - var queryStart = "\"${query.key}\":"; - var queryEnd = ""; + String queryStart = '\"${query.key}\":'; + String queryEnd = ''; // Compact all the queries in the correct format - for (var queryToCompact in listOfQueriesCompact) { - var queryToCompactValue = queryToCompact.value.toString(); - queryToCompactValue = queryToCompactValue.replaceFirst("{", ""); - queryToCompactValue = queryToCompactValue.replaceAll("}", ""); + for (MapEntry queryToCompact in listOfQueriesCompact) { + String queryToCompactValue = queryToCompact.value.toString(); + queryToCompactValue = queryToCompactValue.replaceFirst('{', ''); + queryToCompactValue = queryToCompactValue.replaceAll('}', ''); if (listOfQueriesCompact.first == queryToCompact) { - queryEnd += (queryToCompactValue.replaceAll(queryStart, " ")); + queryEnd += queryToCompactValue.replaceAll(queryStart, ' '); } else { - queryEnd += (queryToCompactValue.replaceAll(queryStart, ", ")); + queryEnd += queryToCompactValue.replaceAll(queryStart, ', '); } } - sanitizedQueries.add(MapEntry(query.key, queryStart += "{$queryEnd}")); + sanitizedQueries.add( + MapEntry(query.key, queryStart += '{$queryEnd}')); } } @@ -349,10 +360,14 @@ class QueryBuilder { } /// Adds the limiters to the query, i.e. skip=10, limit=10 - String getLimiters(Map map) { - String result = ""; - map.forEach((key, value) { - result = (result != null) ? result + "&$key=$value" : "&$key=$value"; + String getLimiters(Map map) { + String result = ''; + map.forEach((String key, dynamic value) { + if (result != null) { + result = result + '&$key=$value'; + } else { + result = '&$key=$value'; + } }); return result; } diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index bcb784c78..3f55dc993 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -4,12 +4,12 @@ abstract class ParseBase { String className; Type type; - setClassName(String className) => this.className = className; + String setClassName(String className) => this.className = className; String getClassName() => className; /// Stores all the values of a class - Map _objectData = Map(); + Map _objectData = Map(); /// Returns [String] objectId String get objectId => get(keyVarObjectId); @@ -24,8 +24,8 @@ abstract class ParseBase { /// Converts object to [String] in JSON format @protected - toJson({bool full, bool forApiRQ: false}) { - final map = { + Map toJson({bool full, bool forApiRQ = false}) { + final Map map = { keyVarClassName: className, }; @@ -41,8 +41,10 @@ abstract class ParseBase { map[keyVarUpdatedAt] = updatedAt.toIso8601String(); } - getObjectData().forEach((key, value) { - if (!map.containsKey(key)) map[key] = parseEncode(value, full: full); + getObjectData().forEach((String key, dynamic value) { + if (!map.containsKey(key)) { + map[key] = parseEncode(value, full: full); + } }); if (forApiRQ) { @@ -60,12 +62,12 @@ abstract class ParseBase { String toString() => json.encode(toJson()); @protected - fromJson(Map objectData) { + dynamic fromJson(Map objectData) { if (objectData == null) { return this; } - objectData.forEach((key, value) { + objectData.forEach((String key, dynamic value) { if (key == className || key == '__type') { // NO OP } else if (key == keyVarObjectId) { @@ -84,19 +86,19 @@ abstract class ParseBase { /// Creates a copy of this class @protected - copy() => fromJson(json.decode(toJson())); + dynamic copy() => fromJson(toJson()); /// Sets all the objects variables @protected - void setObjectData(Map objectData) => _objectData = objectData; + void setObjectData(Map objectData) => _objectData = objectData; /// Returns the objects variables @protected - Map getObjectData() => _objectData ?? Map(); + Map getObjectData() => _objectData ?? Map(); /// Saves in storage @protected - void saveInStorage(String key) async { + Future saveInStorage(String key) async { await ParseCoreData().getStore() ..setString(key, toString()); } @@ -106,10 +108,12 @@ 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 (value != null) { if (getObjectData().containsKey(key)) { - if (forceUpdate) getObjectData()[key] = value; + if (forceUpdate) { + getObjectData()[key] = value; + } } else { getObjectData()[key] = value; } @@ -121,10 +125,11 @@ 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 - get(String key, {T defaultValue}) { + dynamic get(String key, {T defaultValue}) { if (getObjectData().containsKey(key)) { if (T != null && getObjectData()[key] is T) { - return getObjectData()[key] as T; + final T data = getObjectData()[key]; + return data; } else { return getObjectData()[key]; } @@ -141,7 +146,7 @@ abstract class ParseBase { await unpin(); final Map objectMap = parseEncode(this, full: true); final String json = jsonEncode(objectMap); - var store = await ParseCoreData().getStore(); + final SharedPreferences store = await ParseCoreData().getStore(); store.setString(objectId, json); return true; } else { @@ -165,12 +170,14 @@ abstract class ParseBase { /// Saves item to simple key pair value storage /// /// Replicates Android SDK pin process and saves object to storage - fromPin(String objectId) async { + dynamic fromPin(String objectId) async { if (objectId != null) { - var itemFromStore = + final String itemFromStore = (await ParseCoreData().getStore()).getString(objectId); - if (itemFromStore != null) return fromJson(json.decode(itemFromStore)); + if (itemFromStore != null) { + return fromJson(json.decode(itemFromStore)); + } } return null; } diff --git a/lib/src/objects/parse_cloneable.dart b/lib/src/objects/parse_cloneable.dart index f668dad10..589b60149 100644 --- a/lib/src/objects/parse_cloneable.dart +++ b/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 { - clone(Map map); + dynamic clone(Map map); } diff --git a/lib/src/objects/parse_config.dart b/lib/src/objects/parse_config.dart index 14e7b025e..25c579ec9 100644 --- a/lib/src/objects/parse_config.dart +++ b/lib/src/objects/parse_config.dart @@ -7,7 +7,7 @@ class ParseConfig extends ParseObject { _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient( - autoSendSessionId: + sendSessionId: autoSendSessionId ?? ParseCoreData().autoSendSessionId, securityContext: ParseCoreData().securityContext); } @@ -15,9 +15,9 @@ class ParseConfig extends ParseObject { /// Gets all configs from the server Future getConfigs() async { try { - var uri = "${ParseCoreData().serverUrl}/config"; - var result = await _client.get(uri); - return handleResponse( + final String uri = '${ParseCoreData().serverUrl}/config'; + final result = await _client.get(uri); + return handleResponse( this, result, ParseApiRQ.getConfigs, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.getConfigs, _debug, className); @@ -27,10 +27,10 @@ class ParseConfig extends ParseObject { /// Adds a new config Future addConfig(String key, dynamic value) async { try { - var uri = "${ParseCoreData().serverUrl}/config"; - var body = "{\"params\":{\"$key\": \"${parseEncode(value)}\"}}"; - var result = await _client.put(uri, body: body); - return handleResponse( + final String uri = '${ParseCoreData().serverUrl}/config'; + final String body = '{\"params\":{\"$key\": \"${parseEncode(value)}\"}}'; + final Response result = await _client.put(uri, body: body); + return handleResponse( this, result, ParseApiRQ.addConfig, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.addConfig, _debug, className); diff --git a/lib/src/objects/parse_error.dart b/lib/src/objects/parse_error.dart index e2d059206..eda1e30b9 100644 --- a/lib/src/objects/parse_error.dart +++ b/lib/src/objects/parse_error.dart @@ -2,6 +2,19 @@ part of flutter_parse_sdk; /// ParseException is used in [ParseResult] to inform the user of the exception class ParseError { + + ParseError( + {this.code = -1, + this.message = 'Unknown error', + this.isTypeOfException = false, + bool debug = false}) { + type = exceptions[code]; + if (debug) { + print(toString()); + } + } + + // ignore: always_specify_types Map exceptions = { -1: 'UnknownError', @@ -61,23 +74,14 @@ class ParseError { final bool isTypeOfException; String type; - ParseError( - {this.code = -1, - this.message = "Unknown error", - this.isTypeOfException = false, - bool debug: false}) { - type = exceptions[code]; - if (debug) print(toString()); - } - @override String toString() { - var exceptionString = ' \n'; - exceptionString += "----"; - exceptionString += "\nParseException (Type: $type) :"; - exceptionString += "\nCode: $code"; - exceptionString += "\nMessage: $message"; - exceptionString += "----"; + String exceptionString = ' \n'; + exceptionString += '----'; + exceptionString += '\nParseException (Type: $type) :'; + exceptionString += '\nCode: $code'; + exceptionString += '\nMessage: $message'; + exceptionString += '----'; return exceptionString; } } diff --git a/lib/src/objects/parse_file.dart b/lib/src/objects/parse_file.dart index a9b3c87dd..9bc4f0a16 100644 --- a/lib/src/objects/parse_file.dart +++ b/lib/src/objects/parse_file.dart @@ -1,22 +1,6 @@ part of flutter_parse_sdk; class ParseFile extends ParseObject { - File file; - String name; - String url; - - @override - String _path; - - bool get saved => url != null; - - @override - toJson({bool full: false, bool forApiRQ: false}) => - {'__type': keyFile, 'name': name, 'url': url}; - - @override - String toString() => json.encode(toString()); - /// Creates a new file /// /// {https://docs.parseplatform.org/rest/guide/#files/} @@ -30,29 +14,47 @@ class ParseFile extends ParseObject { _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient( - autoSendSessionId: + sendSessionId: autoSendSessionId ?? ParseCoreData().autoSendSessionId, securityContext: ParseCoreData().securityContext); if (file != null) { - this.name = path.basename(file.path); - this._path = '/files/$name'; + name = path.basename(file.path); + _path = '/files/$name'; } else { - this.name = name; - this.url = url; + name = name; + url = url; } } + File file; + String name; + String url; + + @override + // ignore: overridden_fields + String _path; + + bool get saved => url != null; + + @override + Map toJson({bool full = false, bool forApiRQ = false}) => + {'__type': keyFile, 'name': name, 'url': url}; + + @override + String toString() => json.encode(toString()); + Future loadStorage() async { - Directory tempPath = await getTemporaryDirectory(); + final Directory tempPath = await getTemporaryDirectory(); if (name == null) { file = null; return this; } - File possibleFile = new File("${tempPath.path}/$name"); - bool exists = await possibleFile.exists(); + final File possibleFile = File('${tempPath.path}/$name'); + // ignore: avoid_slow_async_io + final bool exists = await possibleFile.exists(); if (exists) { file = possibleFile; @@ -68,11 +70,11 @@ class ParseFile extends ParseObject { return this; } - Directory tempPath = await getTemporaryDirectory(); - this.file = new File("${tempPath.path}/$name"); + final Directory tempPath = await getTemporaryDirectory(); + file = File('${tempPath.path}/$name'); await file.create(); - var response = await _client.get(url); + final Response response = await _client.get(url); file.writeAsBytes(response.bodyBytes); return this; @@ -88,25 +90,27 @@ class ParseFile extends ParseObject { Future upload() async { if (saved) { //Creates a Fake Response to return the correct result - final response = {"url": this.url, "name": this.name}; - return handleResponse(this, Response(json.encode(response), 201), + // ignore: always_specify_types + final Map response = {'url': url, 'name': name}; + return handleResponse(this, Response(json.encode(response), 201), ParseApiRQ.upload, _debug, className); } - final ext = path.extension(file.path).replaceAll('.', ''); - final headers = { + final String ext = path.extension(file.path).replaceAll('.', ''); + final Map headers = { HttpHeaders.contentTypeHeader: getContentType(ext) }; try { - var uri = _client.data.serverUrl + "$_path"; - final body = await file.readAsBytes(); - final response = await _client.post(uri, headers: headers, body: body); + final String uri = _client.data.serverUrl + '$_path'; + final List body = await file.readAsBytes(); + final Response response = + await _client.post(uri, headers: headers, body: body); if (response.statusCode == 201) { - final map = json.decode(response.body); - this.url = map["url"].toString(); - this.name = map["name"].toString(); + final Map map = json.decode(response.body); + url = map['url'].toString(); + name = map['name'].toString(); } - return handleResponse( + return handleResponse( this, response, ParseApiRQ.upload, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.upload, _debug, className); diff --git a/lib/src/objects/parse_function.dart b/lib/src/objects/parse_function.dart index 7b23368f7..2a739284f 100644 --- a/lib/src/objects/parse_function.dart +++ b/lib/src/objects/parse_function.dart @@ -1,45 +1,49 @@ part of flutter_parse_sdk; class ParseCloudFunction extends ParseObject { - final String functionName; - - @override - String _path; - /// Creates a new cloud function object /// /// {https://docs.parseplatform.org/cloudcode/guide/} ParseCloudFunction(this.functionName, {bool debug, ParseHTTPClient client, bool autoSendSessionId}) : super(functionName) { - _path = "/functions/$functionName"; + _path = '/functions/$functionName'; _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient( - autoSendSessionId: + sendSessionId: autoSendSessionId ?? ParseCoreData().autoSendSessionId, securityContext: ParseCoreData().securityContext); } + final String functionName; + + @override + // ignore: overridden_fields + String _path; + /// Executes a cloud function /// /// To add the parameters, create an object and call [set](value to set) - execute({Map parameters, Map headers}) async { - var uri = _client.data.serverUrl + "$_path"; + Future execute( + {Map parameters, Map headers}) async { + final String uri = '${_client.data.serverUrl}$_path'; if (parameters != null) setObjectData(parameters); - var result = await _client.post(uri, body: json.encode(getObjectData())); - return handleResponse(this, result, ParseApiRQ.execute, _debug, className); + final Response result = + await _client.post(uri, body: json.encode(getObjectData())); + return handleResponse(this, result, ParseApiRQ.execute, _debug, className); } /// Executes a cloud function that returns a ParseObject type /// /// To add the parameters, create an object and call [set](value to set) Future executeObjectFunction( - {Map parameters, Map headers}) async { - var uri = _client.data.serverUrl + "$_path"; + {Map parameters, Map headers}) async { + final String uri = '${_client.data.serverUrl}$_path'; if (parameters != null) setObjectData(parameters); - var result = await _client.post(uri, body: json.encode(getObjectData())); + final Response result = + await _client.post(uri, body: json.encode(getObjectData())); return handleResponse( this, result, ParseApiRQ.executeObjectionFunction, _debug, className); } diff --git a/lib/src/objects/parse_geo_point.dart b/lib/src/objects/parse_geo_point.dart index 076691529..3d4bffd19 100644 --- a/lib/src/objects/parse_geo_point.dart +++ b/lib/src/objects/parse_geo_point.dart @@ -1,8 +1,6 @@ part of flutter_parse_sdk; class ParseGeoPoint extends ParseObject { - double _latitude; - double _longitude; /// Creates a Parse Object of type GeoPoint ParseGeoPoint( @@ -18,29 +16,30 @@ class ParseGeoPoint extends ParseObject { _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient( - autoSendSessionId: + sendSessionId: autoSendSessionId ?? ParseCoreData().autoSendSessionId, securityContext: ParseCoreData().securityContext); } + double _latitude; + double _longitude; + double get latitude => _latitude; double get longitude => _longitude; set latitude(double value) { - assert(value >= -90.0 || value <= 90.0); _latitude = value; } set longitude(double value) { - assert(value >= -180.0 || value <= 180.0); _longitude = value; } @override - toJson({bool full: false, bool forApiRQ: false}) => { - "__type": "GeoPoint", - "latitude": _latitude, - "longitude": _longitude + Map toJson({bool full = false, bool forApiRQ = false}) => { + '__type': 'GeoPoint', + 'latitude': _latitude, + 'longitude': _longitude }; } diff --git a/lib/src/objects/parse_installation.dart b/lib/src/objects/parse_installation.dart index 7e16f1664..a1b7e9115 100644 --- a/lib/src/objects/parse_installation.dart +++ b/lib/src/objects/parse_installation.dart @@ -1,17 +1,23 @@ part of flutter_parse_sdk; class ParseInstallation extends ParseObject { - static final String keyTimeZone = 'timeZone'; - static final String keyLocaleIdentifier = 'localeIdentifier'; - static final String keyDeviceToken = 'deviceToken'; - static final String keyDeviceType = 'deviceType'; - static final String keyInstallationId = 'installationId'; - static final String keyAppName = 'appName'; - static final String keyAppVersion = 'appVersion'; - static final String keyAppIdentifier = 'appIdentifier'; - static final String keyParseVersion = 'parseVersion'; - static final List readOnlyKeys = [ - //TODO + + /// Creates an instance of ParseInstallation + ParseInstallation( + {bool debug, ParseHTTPClient client, bool autoSendSessionId}) + : super(keyClassInstallation) { + _debug = isDebugEnabled(objectLevelDebug: debug); + _client = client ?? + ParseHTTPClient( + sendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); + } + + ParseInstallation.forQuery() : super(keyClassUser); + + static final List readOnlyKeys = [ + // TODO keyDeviceToken, keyDeviceType, keyInstallationId, keyAppName, keyAppVersion, keyAppIdentifier, keyParseVersion ]; @@ -19,9 +25,9 @@ class ParseInstallation extends ParseObject { //Getters/setters - Map get acl => super.get(keyVarAcl); + Map get acl => super.get>(keyVarAcl); - set acl(Map acl) => set(keyVarAcl, acl); + set acl(Map acl) => set>(keyVarAcl, acl); String get deviceToken => super.get(keyDeviceToken); @@ -43,49 +49,31 @@ class ParseInstallation extends ParseObject { String get parseVersion => super.get(keyParseVersion); - /// Creates an instance of ParseInstallation - ParseInstallation( - {bool debug, ParseHTTPClient client, bool autoSendSessionId}) - : super(keyClassInstallation) { - _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? - ParseHTTPClient( - autoSendSessionId: - autoSendSessionId ?? ParseCoreData().autoSendSessionId, - securityContext: ParseCoreData().securityContext); - } - - ParseInstallation.forQuery() : super(keyClassUser); - static Future isCurrent(ParseInstallation installation) async { - if (_currentInstallationId == null) { - _currentInstallationId = (await _getFromLocalStore()).installationId; - } + _currentInstallationId ??= (await _getFromLocalStore()).installationId; return _currentInstallationId != null && installation.installationId == _currentInstallationId; } /// Gets the current installation from storage static Future currentInstallation() async { - var installation = await _getFromLocalStore(); - if (installation == null) { - installation = await _createInstallation(); - } + ParseInstallation installation = await _getFromLocalStore(); + installation ??= await _createInstallation(); return installation; } /// Updates the installation with current device data - _updateInstallation() async { + Future _updateInstallation() async { //Device type if (Platform.isAndroid) - set(keyDeviceType, "android"); + set(keyDeviceType, 'android'); else if (Platform.isIOS) - set(keyDeviceType, "ios"); + set(keyDeviceType, 'ios'); else - throw Exception("Unsupported platform/operating system"); + throw Exception('Unsupported platform/operating system'); //Locale - String locale = await Devicelocale.currentLocale; + final String locale = await Devicelocale.currentLocale; if (locale != null && locale.isNotEmpty) { set(keyLocaleIdentifier, locale); } @@ -94,18 +82,20 @@ class ParseInstallation extends ParseObject { //TODO set(keyTimeZone, ); //App info - PackageInfo packageInfo = await PackageInfo.fromPlatform(); + final PackageInfo packageInfo = await PackageInfo.fromPlatform(); set(keyAppName, packageInfo.appName); set(keyAppVersion, packageInfo.version); set(keyAppIdentifier, packageInfo.packageName); set(keyParseVersion, keySdkVersion); } + @override Future create() async { - var isCurrent = await ParseInstallation.isCurrent(this); - if (isCurrent) await _updateInstallation(); + final bool isCurrent = await ParseInstallation.isCurrent(this); + if (isCurrent) + await _updateInstallation(); //ParseResponse parseResponse = await super.create(); - ParseResponse parseResponse = await _create(); + final ParseResponse parseResponse = await _create(); if (parseResponse.success && isCurrent) { saveInStorage(keyParseStoreInstallation); } @@ -113,6 +103,7 @@ class ParseInstallation extends ParseObject { } /// Saves the current installation + @override Future save() async { var isCurrent = await ParseInstallation.isCurrent(this); if (isCurrent) await _updateInstallation(); @@ -126,14 +117,14 @@ class ParseInstallation extends ParseObject { /// Gets the locally stored installation static Future _getFromLocalStore() async { - var installationJson = + final String installationJson = (await ParseCoreData().getStore()).getString(keyParseStoreInstallation); if (installationJson != null) { - var installationMap = parseDecode(json.decode(installationJson)); + final dynamic installationMap = parseDecode(json.decode(installationJson)); if (installationMap != null) { - return new ParseInstallation()..fromJson(installationMap); + return ParseInstallation()..fromJson(installationMap); } } @@ -144,10 +135,8 @@ 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 { - if (_currentInstallationId == null) { - _currentInstallationId = Uuid().v4(); - } - var installation = new ParseInstallation(); + _currentInstallationId ??= Uuid().v4(); + final ParseInstallation installation = ParseInstallation(); installation._installationId = _currentInstallationId; await installation._updateInstallation(); return installation; @@ -156,22 +145,22 @@ class ParseInstallation extends ParseObject { /// Creates a new object and saves it online Future _create() async { try { - var uri = _client.data.serverUrl + "$keyEndPointInstallations"; - var body = json.encode(toJson(forApiRQ: true)); + final String uri = '${_client.data.serverUrl}$keyEndPointInstallations'; + final String body = json.encode(toJson(forApiRQ: true)); if (_debug) { logRequest(ParseCoreData().appName, className, ParseApiRQ.create.toString(), uri, body); } - var result = await _client.post(uri, body: body); + final Response result = await _client.post(uri, body: body); //Set the objectId on the object after it is created. //This allows you to perform operations on the object after creation if (result.statusCode == 201) { - final map = json.decode(result.body); - this.objectId = map["objectId"].toString(); + final Map map = json.decode(result.body); + objectId = map['objectId'].toString(); } - return handleResponse(this, result, ParseApiRQ.create, _debug, className); + return handleResponse(this, result, ParseApiRQ.create, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.create, _debug, className); } @@ -183,15 +172,15 @@ class ParseInstallation extends ParseObject { return create(); } else { try { - var uri = - "${ParseCoreData().serverUrl}$keyEndPointInstallations/$objectId"; - var body = json.encode(toJson(forApiRQ: true)); + final String uri = + '${ParseCoreData().serverUrl}$keyEndPointInstallations/$objectId'; + final String body = json.encode(toJson(forApiRQ: true)); if (_debug) { logRequest(ParseCoreData().appName, className, ParseApiRQ.save.toString(), uri, body); } - var result = await _client.put(uri, body: body); - return handleResponse(this, result, ParseApiRQ.save, _debug, className); + final Response result = await _client.put(uri, body: body); + return handleResponse(this, result, ParseApiRQ.save, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.save, _debug, className); } @@ -200,26 +189,26 @@ class ParseInstallation extends ParseObject { ///Subscribes the device to a channel of push notifications. void subscribeToChannel(String value) { - final List channel = [value]; - this.addUnique("channels", channel); + final List channel = [value]; + addUnique('channels', channel); } ///Unsubscribes the device to a channel of push notifications. void unsubscribeFromChannel(String value) { - final List channel = [value]; - this.removeAll("channels", channel); + final List channel = [value]; + removeAll('channels', channel); } ///Returns an > containing all the channel names this device is subscribed to. Future> getSubscribedChannels() async { - print("getSubscribedChannels"); - final apiResponse = - await ParseObject(keyClassInstallation).getObject(this.objectId); + print('getSubscribedChannels'); + final ParseResponse apiResponse = + await ParseObject(keyClassInstallation).getObject(objectId); if (apiResponse.success) { - var installation = apiResponse.result as ParseObject; - print("achou installation"); - return Future.value(installation.get>("channels")); + final ParseObject installation = apiResponse.result; + print('achou installation'); + return Future.value(installation.get>('channels')); } else { return null; } diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index 31191d5f8..5f54fc779 100644 --- a/lib/src/objects/parse_object.dart +++ b/lib/src/objects/parse_object.dart @@ -1,44 +1,47 @@ part of flutter_parse_sdk; class ParseObject extends ParseBase implements ParseCloneable { - ParseObject.clone(String className) : this(className); - - @override - clone(Map map) => ParseObject.clone(className)..fromJson(map); - - String _path; - bool _debug; - ParseHTTPClient _client; - /// Creates a new Parse Object /// /// [String] className refers to the Table Name in your Parse Server, /// [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: false, ParseHTTPClient client, bool autoSendSessionId}) + {bool debug = false, ParseHTTPClient client, bool autoSendSessionId}) : super() { setClassName(className); - _path = "$keyEndPointClasses$className"; + _path = '$keyEndPointClasses$className'; _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient( - autoSendSessionId: + sendSessionId: autoSendSessionId ?? ParseCoreData().autoSendSessionId, securityContext: ParseCoreData().securityContext); } + ParseObject.clone(String className) : this(className); + + @override + dynamic clone(Map map) => + ParseObject.clone(className)..fromJson(map); + + String _path; + bool _debug; + ParseHTTPClient _client; + /// Converts the object to a Pointer to be used ONLY in queries using Pointers dynamic toPointer() => json.encode(parseEncode(this)); /// Gets an object from the server using it's [String] objectId Future getObject(String objectId) async { try { - var uri = "${ParseCoreData().serverUrl}$_path"; - if (objectId != null) uri += "/$objectId"; - var result = await _client.get(uri); - return handleResponse(this, result, ParseApiRQ.get, _debug, className); + String uri = '${ParseCoreData().serverUrl}$_path'; + if (objectId != null) { + uri += '/$objectId'; + } + final Response result = await _client.get(uri); + return handleResponse(this, result, ParseApiRQ.get, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.get, _debug, className); } @@ -47,8 +50,9 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Gets all objects from this table - Limited response at the moment Future getAll() async { try { - var result = await _client.get("${ParseCoreData().serverUrl}$_path"); - return handleResponse(this, result, ParseApiRQ.getAll, _debug, className); + final Response result = + await _client.get('${ParseCoreData().serverUrl}$_path'); + return handleResponse(this, result, ParseApiRQ.getAll, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.getAll, _debug, className); } @@ -57,22 +61,18 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Creates a new object and saves it online Future create() async { try { - var uri = _client.data.serverUrl + "$_path"; - var body = json.encode(toJson(forApiRQ: true)); - if (_debug) { - logRequest(ParseCoreData().appName, className, - ParseApiRQ.create.toString(), uri, body); - } - var result = await _client.post(uri, body: body); + final String uri = '${_client.data.serverUrl}$_path'; + final String body = json.encode(toJson(forApiRQ: true)); + final Response result = await _client.post(uri, body: body); //Set the objectId on the object after it is created. //This allows you to perform operations on the object after creation if (result.statusCode == 201) { - final map = json.decode(result.body); - this.objectId = map["objectId"].toString(); + final Map map = json.decode(result.body); + objectId = map['objectId'].toString(); } - return handleResponse(this, result, ParseApiRQ.create, _debug, className); + return handleResponse(this, result, ParseApiRQ.create, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.create, _debug, className); } @@ -84,22 +84,17 @@ class ParseObject extends ParseBase implements ParseCloneable { return create(); } else { try { + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$_path/$objectId"); - - var body = json.encode(toJson(forApiRQ: true)); - if (_debug) { - logRequest(ParseCoreData().appName, className, - ParseApiRQ.save.toString(), url.toString(), body); - } - var result = await _client.put(url, body: body); - return handleResponse(this, result, ParseApiRQ.save, _debug, className); + path: '${tempUri.path}$_path/$objectId'); + + final String body = json.encode(toJson(forApiRQ: true)); + final Response result = await _client.put(url, body: body); + return handleResponse(this, result, ParseApiRQ.save, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.save, _debug, className); } @@ -110,7 +105,7 @@ class ParseObject extends ParseBase implements ParseCloneable { @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); + return await _sortArrays(ParseApiRQ.remove, 'Remove', key, values); } else { return null; } @@ -118,14 +113,14 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Removes an element from an Array void setRemove(String key, dynamic values) { - _arrayOperation("Remove", key, values); + _arrayOperation('Remove', key, values); } /// 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); + return await _sortArrays(ParseApiRQ.removeAll, 'Remove', key, values); } else { return null; } @@ -133,14 +128,14 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Remove multiple elements from an array of an object void setRemoveAll(String key, List values) { - _arrayOperation("Remove", key, 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); + return await _sortArrays(ParseApiRQ.addAll, 'Add', key, values); } else { return null; } @@ -148,14 +143,14 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Add a multiple elements to an array of an object void setAddAll(String key, List values) { - _arrayOperation("Add", key, 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); + return await _sortArrays(ParseApiRQ.addUnique, 'AddUnique', key, values); } else { return null; } @@ -163,14 +158,14 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Add a multiple elements to an array of an object void setAddUnique(String key, List values) { - _arrayOperation("AddUnique", key, values); + _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); + return await _sortArrays(ParseApiRQ.add, 'Add', key, values); } else { return null; } @@ -178,7 +173,7 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Add a single element to an array of an object void setAdd(String key, dynamic values) { - _arrayOperation("Add", key, values); + _arrayOperation('Add', key, values); } /// Can be used to add arrays to a given type @@ -186,19 +181,18 @@ class ParseObject extends ParseBase implements ParseCloneable { String key, List values) async { try { if (objectId != null) { + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$_path/$objectId"); + path: '${tempUri.path}$_path/$objectId'); - var body = - "{\"$key\":{\"__op\":\"$arrayAction\",\"objects\":${json.encode(parseEncode(values))}}}"; - var result = await _client.put(url, body: body); - return handleResponse(this, result, apiRQType, _debug, className); + final String body = + '{\"$key\":{\"__op\":\"$arrayAction\",\"objects\":${json.encode(parseEncode(values))}}}'; + final Response result = await _client.put(url, body: body); + return handleResponse(this, result, apiRQType, _debug, className); } else { return null; } @@ -209,15 +203,14 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Used in array Operations in save() method void _arrayOperation(String arrayAction, String key, List values) { - this.set>( - key, {'__op': arrayAction, 'objects': values}); + set>(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); + return await _increment(ParseApiRQ.increment, 'Increment', key, amount); } else { return null; } @@ -225,15 +218,15 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Increases a num of an object by x amount void setIncrement(String key, num amount) { - this.set>( - key, {'__op': 'Increment', 'amount': 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); + return await _increment(ParseApiRQ.decrement, 'Increment', key, -amount); } else { return null; } @@ -241,8 +234,8 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Decreases a num of an object by x amount void setDecrement(String key, num amount) { - this.set>( - key, {'__op': 'Increment', 'amount': -amount}); + set>( + key, {'__op': 'Increment', 'amount': -amount}); } /// Can be used to add arrays to a given type @@ -250,18 +243,17 @@ class ParseObject extends ParseBase implements ParseCloneable { ParseApiRQ apiRQType, String countAction, String key, num amount) async { try { if (objectId != null) { + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$_path/$objectId"); + path: '${tempUri.path}$_path/$objectId'); - var body = "{\"$key\":{\"__op\":\"$countAction\",\"amount\":$amount}}"; - var result = await _client.put(url, body: body); - return handleResponse(this, result, apiRQType, _debug, className); + final String body = '{\"$key\":{\"__op\":\"$countAction\",\"amount\":$amount}}'; + final Response result = await _client.put(url, body: body); + return handleResponse(this, result, apiRQType, _debug, className); } else { return null; } @@ -273,17 +265,17 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Can be used to create custom queries Future query(String query) async { try { - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$_path", + path: '${tempUri.path}$_path', query: query); - var result = await _client.get(url); - return handleResponse(this, result, ParseApiRQ.query, _debug, className); + final Response result = await _client.get(url); + return handleResponse(this, result, ParseApiRQ.query, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.query, _debug, className); } @@ -294,13 +286,13 @@ class ParseObject extends ParseBase implements ParseCloneable { try { path ??= _path; objectId ??= objectId; - var uri = "${ParseCoreData().serverUrl}$path/$objectId"; + final String uri = '${ParseCoreData().serverUrl}$path/$objectId'; if (_debug) { logRequest(ParseCoreData().appName, className, - ParseApiRQ.delete.toString(), uri, ""); + ParseApiRQ.delete.toString(), uri, ''); } - var result = await _client.delete(uri); - return handleResponse(this, result, ParseApiRQ.delete, _debug, className); + final Response result = await _client.delete(uri); + return handleResponse(this, result, ParseApiRQ.delete, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.delete, _debug, className); } diff --git a/lib/src/objects/parse_response.dart b/lib/src/objects/parse_response.dart index 80dfc4ad7..b736ee51e 100644 --- a/lib/src/objects/parse_response.dart +++ b/lib/src/objects/parse_response.dart @@ -5,162 +5,4 @@ class ParseResponse { int statusCode = -1; dynamic result; ParseError error; - - /// Handles all the ParseObject responses - /// - /// There are 4 probable outcomes from a Parse API call, - /// 1. Fail - [ParseResponse()] will be returned with further details - /// 2. Success but no results. [ParseResponse()] is returned. - /// 3. Success with simple OK. - /// 4. Success with results. Again [ParseResponse()] is returned - static handleResponse( - dynamic object, Response apiResponse, - {bool returnAsResult: false}) { - var parseResponse = ParseResponse(); - - if (apiResponse != null) { - parseResponse.statusCode = apiResponse.statusCode; - - if (apiResponse.statusCode != 200 && apiResponse.statusCode != 201) { - return _handleError(parseResponse, apiResponse); - } else if (apiResponse.body == "{\"results\":[]}") { - return _handleSuccessWithNoResults( - parseResponse, 1, "Successful request, but no results found"); - } else if (returnAsResult) { - return _handleSuccessWithoutParseObject( - parseResponse, object, apiResponse.body); - } else { - return _handleSuccess(parseResponse, object, apiResponse.body); - } - } else { - parseResponse.error = ParseError( - message: "Error reaching server, or server response was null"); - return apiResponse; - } - } - - /// Handles exception instead of throwing an exception - static ParseResponse handleException(Exception exception) { - var response = ParseResponse(); - response.error = - ParseError(message: exception.toString(), isTypeOfException: true); - return response; - } - - /// Handles any errors returned in response - static ParseResponse _handleError( - ParseResponse response, Response apiResponse) { - Map responseData = json.decode(apiResponse.body); - response.error = ParseError( - code: responseData['code'], message: responseData['error'].toString()); - response.statusCode = responseData['code']; - return response; - } - - /// Handles successful responses with no results - static ParseResponse _handleSuccessWithNoResults( - ParseResponse response, int code, String value) { - response.success = true; - response.statusCode = 200; - response.error = ParseError(code: code, message: value); - return response; - } - - /// Handles successful response without creating a ParseObject - static ParseResponse _handleSuccessWithoutParseObject( - ParseResponse response, dynamic object, String responseBody) { - response.success = true; - - if (responseBody == "OK") { - response.result = responseBody; - } else if (json.decode(responseBody).containsKey('params')) { - response.result = json.decode(responseBody)['params']; - } else { - response.result = json.decode(responseBody); - } - - return response; - } - - /// Handles successful response with results - static ParseResponse _handleSuccess( - ParseResponse response, dynamic object, String responseBody) { - response.success = true; - - var map = json.decode(responseBody) as Map; - - if (map != null && map.length == 1 && map.containsKey('results')) { - response.result = - _handleMultipleResults(object, map.entries.first.value); - } else { - response.result = _handleSingleResult(object, map); - } - - return response; - } - - /// Handles a response with a multiple result object - static List _handleMultipleResults( - dynamic object, dynamic map) { - var resultsList = List(); - - for (var value in map) { - resultsList.add(_handleSingleResult(object, value)); - } - - return resultsList; - } - - /// Handles a response with a single result object - static T _handleSingleResult(dynamic object, map) { - if (object is Parse) return map; - if (object is ParseCloneable) return object.clone(map); - return null; - } -} - -/// Handles an API response and logs data if [bool] debug is enabled -@protected -ParseResponse handleResponse(ParseCloneable object, - Response response, ParseApiRQ type, bool debug, String className) { - ParseResponse parseResponse = ParseResponse.handleResponse( - object, response, - returnAsResult: shouldReturnAsABaseResult(type)); - - if (debug) { - logger(ParseCoreData().appName, className, type.toString(), parseResponse); - } - - return parseResponse; -} - -/// Handles an API response and logs data if [bool] debug is enabled -@protected -ParseResponse handleException( - Exception exception, ParseApiRQ type, bool debug, String className) { - ParseResponse parseResponse = ParseResponse.handleException(exception); - - if (debug) { - logger(ParseCoreData().appName, className, type.toString(), parseResponse); - } - - return parseResponse; -} - -bool shouldReturnAsABaseResult(ParseApiRQ type) { - if (type == ParseApiRQ.healthCheck || - type == ParseApiRQ.execute || - type == ParseApiRQ.add || - type == ParseApiRQ.addAll || - type == ParseApiRQ.addUnique || - type == ParseApiRQ.remove || - type == ParseApiRQ.removeAll || - type == ParseApiRQ.increment || - type == ParseApiRQ.decrement || - type == ParseApiRQ.getConfigs || - type == ParseApiRQ.addConfig) { - return true; - } else { - return false; - } -} +} \ No newline at end of file diff --git a/lib/src/objects/parse_session.dart b/lib/src/objects/parse_session.dart index 1bd2fd88b..61f20ba2f 100644 --- a/lib/src/objects/parse_session.dart +++ b/lib/src/objects/parse_session.dart @@ -1,16 +1,18 @@ part of flutter_parse_sdk; class ParseSession extends ParseObject implements ParseCloneable { - @override - clone(Map map) { - return this.fromJson(map); + ParseSession({bool debug, ParseHTTPClient client}) : super(keyClassSession) { + _debug = isDebugEnabled(objectLevelDebug: debug); + _client = client ?? + ParseHTTPClient( + sendSessionId: true, + securityContext: ParseCoreData().securityContext); } - static final String keyVarUser = 'user'; - static final String keyVarCreatedWith = 'createdWith'; - static final String keyVarRestricted = 'restricted'; - static final String keyVarExpiresAt = 'expiresAt'; - static final String keyVarInstallationId = 'installationId'; + @override + ParseSession clone(Map map) { + return fromJson(map); + } String get sessionToken => super.get(keyVarSessionToken); @@ -25,57 +27,21 @@ class ParseSession extends ParseObject implements ParseCloneable { String get installationId => super.get(keyVarInstallationId); - ParseSession({String sessionToken, bool debug, ParseHTTPClient client}) - : super(keyClassSession) { - _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? - ParseHTTPClient( - autoSendSessionId: true, - securityContext: ParseCoreData().securityContext); - } - Future getCurrentSessionFromServer() async { try { - Uri tempUri = Uri.parse(_client.data.serverUrl); + final Uri tempUri = Uri.parse(_client.data.serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, - path: "${tempUri.path}$keyEndPointSessions/me"); + path: '${tempUri.path}$keyEndPointSessions/me'); - final response = await _client.get(url); + final Response response = await _client.get(url); - return _handleResponse( + return handleResponse( this, response, ParseApiRQ.logout, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.logout, _debug, className); - } - } - - /// Handles an API response and logs data if [bool] debug is enabled - static ParseResponse _handleException( - Exception exception, ParseApiRQ type, bool debug, String className) { - ParseResponse parseResponse = ParseResponse.handleException(exception); - - if (debug) { - logger( - ParseCoreData().appName, className, type.toString(), parseResponse); + return handleException(e, ParseApiRQ.logout, _debug, className); } - - return parseResponse; - } - - /// Handles all the response data for this class - static ParseResponse _handleResponse(ParseSession session, Response response, - ParseApiRQ type, bool debug, String className) { - ParseResponse parseResponse = - ParseResponse.handleResponse(session, response); - - if (debug) { - logger( - ParseCoreData().appName, className, type.toString(), parseResponse); - } - - return parseResponse; } } diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index db8c7a6e2..4e6f244b7 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -1,40 +1,6 @@ part of flutter_parse_sdk; class ParseUser extends ParseObject implements ParseCloneable { - ParseUser.clone(Map map) - : this(map[keyVarUsername], map[keyVarPassword], map[keyVarEmail]); - - @override - clone(Map map) { - return this.fromJson(map); - } - - static final String keyUsername = 'username'; - static final String keyEmailAddress = 'email'; - static final String path = "$keyEndPointClasses$keyClassUser"; - - Map get acl => super.get(keyVarAcl); - - set acl(Map acl) => set(keyVarAcl, acl); - - String get username => super.get(keyVarUsername); - - set username(String username) => set(keyVarUsername, username); - - String get password => super.get(keyVarPassword); - - set password(String password) => set(keyVarPassword, password); - - String get emailAddress => super.get(keyVarEmail); - - set emailAddress(String emailAddress) => - set(keyVarEmail, emailAddress); - - String get sessionToken => super.get(keyVarSessionToken); - - set sessionToken(String sessionToken) => - set(keyVarSessionToken, sessionToken); - /// Creates an instance of ParseUser /// /// Users can set whether debug should be set on this class with a [bool], @@ -51,7 +17,7 @@ class ParseUser extends ParseObject implements ParseCloneable { _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient( - autoSendSessionId: true, + sendSessionId: true, securityContext: ParseCoreData().securityContext); this.username = username; @@ -60,9 +26,45 @@ class ParseUser extends ParseObject implements ParseCloneable { this.sessionToken = sessionToken; } + ParseUser.clone(Map map) + : this(map[keyVarUsername], map[keyVarPassword], map[keyVarEmail]); + ParseUser.forQuery() : super(keyClassUser); - static createUser([String username, String password, String emailAddress]) { + @override + dynamic clone(Map map) { + return fromJson(map); + } + + static const String keyUsername = 'username'; + static const String keyEmailAddress = 'email'; + static const String path = '$keyEndPointClasses$keyClassUser'; + + Map get acl => super.get>(keyVarAcl); + + set acl(Map acl) => + set>(keyVarAcl, acl); + + String get username => super.get(keyVarUsername); + + set username(String username) => set(keyVarUsername, username); + + String get password => super.get(keyVarPassword); + + set password(String password) => set(keyVarPassword, password); + + String get emailAddress => super.get(keyVarEmail); + + set emailAddress(String emailAddress) => + set(keyVarEmail, emailAddress); + + String get sessionToken => super.get(keyVarSessionToken); + + set sessionToken(String sessionToken) => + set(keyVarSessionToken, sessionToken); + + static ParseUser createUser( + [String username, String password, String emailAddress]) { return ParseUser(username, password, emailAddress); } @@ -73,10 +75,10 @@ class ParseUser extends ParseObject implements ParseCloneable { /// returned static Future getCurrentUserFromServer( {String token, bool debug, ParseHTTPClient client}) async { - bool _debug = isDebugEnabled(objectLevelDebug: debug); - ParseHTTPClient _client = client ?? + final bool _debug = isDebugEnabled(objectLevelDebug: debug); + final ParseHTTPClient _client = client ?? ParseHTTPClient( - autoSendSessionId: true, + sendSessionId: true, securityContext: ParseCoreData().securityContext); // We can't get the current user and session without a sessionId @@ -84,25 +86,25 @@ class ParseUser extends ParseObject implements ParseCloneable { return null; } - final Map headers = {}; + final Map headers = {}; if (token != null) { headers[keyHeaderSessionToken] = token; } try { - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri uri = Uri( + final Uri uri = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$keyEndPointUserName"); + path: '${tempUri.path}$keyEndPointUserName'); - final response = await _client.get(uri, headers: headers); + final Response response = await _client.get(uri, headers: headers); return _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, _debug, _getEmptyUser().className); } on Exception catch (e) { - return _handleException( + return handleException( e, ParseApiRQ.currentUser, _debug, _getEmptyUser().className); } } @@ -122,31 +124,33 @@ class ParseUser extends ParseObject implements ParseCloneable { /// that user on Parse Future signUp() async { try { - if (emailAddress == null) return null; + if (emailAddress == null) { + return null; + } - Map bodyData = {}; + final Map bodyData = {}; bodyData[keyVarEmail] = emailAddress; bodyData[keyVarPassword] = password; bodyData[keyVarUsername] = username; - Uri tempUri = Uri.parse(_client.data.serverUrl); + final Uri tempUri = Uri.parse(_client.data.serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$path"); + path: '${tempUri.path}$path'); - final response = await _client.post(url, - headers: { - keyHeaderRevocableSession: "1", + final Response response = await _client.post(url, + headers: { + keyHeaderRevocableSession: '1', }, body: json.encode(bodyData)); return _handleResponse( this, response, ParseApiRQ.signUp, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.signUp, _debug, className); + return handleException(e, ParseApiRQ.signUp, _debug, className); } } @@ -156,64 +160,65 @@ class ParseUser extends ParseObject implements ParseCloneable { /// provided, call this method to login. Future login() async { try { - Uri tempUri = Uri.parse(_client.data.serverUrl); + final Uri tempUri = Uri.parse(_client.data.serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$keyEndPointLogin", - queryParameters: { + path: '${tempUri.path}$keyEndPointLogin', + queryParameters: { keyVarUsername: username, keyVarPassword: password }); - final response = await _client.get(url, headers: { - keyHeaderRevocableSession: "1", + final Response response = + await _client.get(url, headers: { + keyHeaderRevocableSession: '1', }); return _handleResponse( this, response, ParseApiRQ.login, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.login, _debug, className); + return handleException(e, ParseApiRQ.login, _debug, className); } } // Logs in a user anonymously Future loginAnonymous() async { try { - Uri tempUri = Uri.parse(_client.data.serverUrl); + final Uri tempUri = Uri.parse(_client.data.serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$keyEndPointUsers", + path: '${tempUri.path}$keyEndPointUsers', ); - var uuid = new Uuid(); + final Uuid uuid = Uuid(); - final response = await _client.post(url, - headers: { - keyHeaderRevocableSession: "1", + final Response response = await _client.post(url, + headers: { + keyHeaderRevocableSession: '1', }, - body: jsonEncode({ - "authData": { - "anonymous": {"id": uuid.v4()} + body: jsonEncode({ + 'authData': { + 'anonymous': {'id': uuid.v4()} } })); return _handleResponse( this, response, ParseApiRQ.loginAnonymous, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.loginAnonymous, _debug, className); + return handleException(e, ParseApiRQ.loginAnonymous, _debug, className); } } // Logs in a user using a service static Future loginWith(String provider, Object authData) async { - ParseUser user = ParseUser.createUser(); - var response = await user._loginWith(provider, authData); + final ParseUser user = ParseUser.createUser(); + final ParseResponse response = await user._loginWith(provider, authData); if (response.success) { return user; } else { @@ -223,27 +228,27 @@ class ParseUser extends ParseObject implements ParseCloneable { Future _loginWith(String provider, Object authData) async { try { - Uri tempUri = Uri.parse(_client.data.serverUrl); + final Uri tempUri = Uri.parse(_client.data.serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$keyEndPointUsers", + path: '${tempUri.path}$keyEndPointUsers', ); - final response = await _client.post(url, + final Response response = await _client.post(url, headers: { - keyHeaderRevocableSession: "1", + keyHeaderRevocableSession: '1', }, - body: jsonEncode({ - "authData": {provider: authData} + body: jsonEncode({ + 'authData': {provider: authData} })); return _handleResponse( this, response, ParseApiRQ.loginWith, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.loginWith, _debug, className); + return handleException(e, ParseApiRQ.loginWith, _debug, className); } } @@ -262,34 +267,34 @@ class ParseUser extends ParseObject implements ParseCloneable { } try { - Uri tempUri = Uri.parse(_client.data.serverUrl); + final Uri tempUri = Uri.parse(_client.data.serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$keyEndPointLogout"); + path: '${tempUri.path}$keyEndPointLogout'); - final response = - await _client.post(url, headers: {keyHeaderSessionToken: sessionId}); + final Response response = await _client.post(url, + headers: {keyHeaderSessionToken: sessionId}); return _handleResponse( this, response, ParseApiRQ.logout, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.logout, _debug, className); + return handleException(e, ParseApiRQ.logout, _debug, className); } } /// Sends a verification email to the users email address Future verificationEmailRequest() async { try { - final response = await _client.post( - "${_client.data.serverUrl}$keyEndPointVerificationEmail", - body: json.encode({keyVarEmail: emailAddress})); + final Response response = await _client.post( + '${_client.data.serverUrl}$keyEndPointVerificationEmail', + body: json.encode({keyVarEmail: emailAddress})); return _handleResponse(this, response, ParseApiRQ.verificationEmailRequest, _debug, className); } on Exception catch (e) { - return _handleException( + return handleException( e, ParseApiRQ.verificationEmailRequest, _debug, className); } } @@ -297,13 +302,13 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Sends a password reset email to the users email address Future requestPasswordReset() async { try { - final response = await _client.post( - "${_client.data.serverUrl}$keyEndPointRequestPasswordReset", - body: json.encode({keyVarEmail: emailAddress})); + final Response response = await _client.post( + '${_client.data.serverUrl}$keyEndPointRequestPasswordReset', + body: json.encode({keyVarEmail: emailAddress})); return _handleResponse( this, response, ParseApiRQ.requestPasswordReset, _debug, className); } on Exception catch (e) { - return _handleException( + return handleException( e, ParseApiRQ.requestPasswordReset, _debug, className); } } @@ -312,26 +317,27 @@ class ParseUser extends ParseObject implements ParseCloneable { /// /// If changes are made to the current user, call save to sync them with /// Parse Server + @override Future save() async { if (objectId == null) { return signUp(); } else { try { - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$_path/$objectId"); + path: '${tempUri.path}$_path/$objectId'); - var body = + final String body = json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); - final response = await _client.put(url, body: body); + final Response response = await _client.put(url, body: body); return _handleResponse( this, response, ParseApiRQ.save, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.save, _debug, className); + return handleException(e, ParseApiRQ.save, _debug, className); } } } @@ -340,19 +346,19 @@ class ParseUser extends ParseObject implements ParseCloneable { Future destroy() async { if (objectId != null) { try { - Uri tempUri = Uri.parse(ParseCoreData().serverUrl); + final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - Uri url = Uri( + final Uri url = Uri( scheme: tempUri.scheme, host: tempUri.host, port: tempUri.port, - path: "${tempUri.path}$_path/$objectId"); + path: '${tempUri.path}$_path/$objectId'); - final response = await _client.delete(url); + final Response response = await _client.delete(url); return _handleResponse( this, response, ParseApiRQ.destroy, _debug, className); } on Exception catch (e) { - return _handleException(e, ParseApiRQ.destroy, _debug, className); + return handleException(e, ParseApiRQ.destroy, _debug, className); } } @@ -361,82 +367,63 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Gets a list of all users (limited return) static Future all({bool debug, ParseHTTPClient client}) async { - var emptyUser = ParseUser(null, null, null); + final ParseUser emptyUser = ParseUser(null, null, null); - bool _debug = isDebugEnabled(objectLevelDebug: debug); - ParseHTTPClient _client = client ?? + final bool _debug = isDebugEnabled(objectLevelDebug: debug); + final ParseHTTPClient _client = client ?? ParseHTTPClient( - autoSendSessionId: true, + sendSessionId: true, securityContext: ParseCoreData().securityContext); try { - final response = await _client.get("${ParseCoreData().serverUrl}/$path"); - - ParseResponse parseResponse = - ParseResponse.handleResponse(emptyUser, response); - - if (_debug) { - logger(ParseCoreData().appName, keyClassUser, - ParseApiRQ.getAll.toString(), parseResponse); - } - + final Response response = + await _client.get('${ParseCoreData().serverUrl}/$path'); + final ParseResponse parseResponse = handleResponse( + emptyUser, response, ParseApiRQ.getAll, debug, keyClassUser); return parseResponse; } on Exception catch (e) { - return ParseResponse.handleException(e); + return handleException(e, ParseApiRQ.getAll, _debug, keyClassUser); } } static Future _getUserFromLocalStore() async { - var userJson = + final String userJson = (await ParseCoreData().getStore()).getString(keyParseStoreUser); if (userJson != null) { - var userMap = parseDecode(json.decode(userJson)); - + final Map userMap = json.decode(userJson); if (userMap != null) { ParseCoreData().setSessionId(userMap[keyParamSessionToken]); - return _getEmptyUser()..fromJson(userMap); + return parseDecode(userMap); } } return null; } - /// Handles an API response and logs data if [bool] debug is enabled - static ParseResponse _handleException( - Exception exception, ParseApiRQ type, bool debug, String className) { - ParseResponse parseResponse = ParseResponse.handleException(exception); - - if (debug) { - logger( - ParseCoreData().appName, className, type.toString(), parseResponse); - } - - return parseResponse; - } - /// Handles all the response data for this class static ParseResponse _handleResponse(ParseUser user, Response response, ParseApiRQ type, bool debug, String className) { - ParseResponse parseResponse = - ParseResponse.handleResponse(user, response); - - if (debug) { - logger( - ParseCoreData().appName, className, type.toString(), parseResponse); - } + final ParseResponse parseResponse = + handleResponse(user, response, type, debug, className); - Map responseData = JsonDecoder().convert(response.body); + final Map responseData = jsonDecode(response.body); if (responseData.containsKey(keyVarObjectId)) { parseResponse.result.fromJson(responseData); user.sessionToken = responseData[keyParamSessionToken]; ParseCoreData().setSessionId(user.sessionToken); } - if (type == ParseApiRQ.getAll || type == ParseApiRQ.destroy) { + if (parseResponse.statusCode != 200 || + parseResponse.statusCode != 201 || + type == ParseApiRQ.getAll || + type == ParseApiRQ.destroy || + type == ParseApiRQ.requestPasswordReset || + type == ParseApiRQ.verificationEmailRequest) { return parseResponse; } else { - parseResponse.result?.saveInStorage(keyParseStoreUser); + final ParseUser user = parseResponse.result; + user?.saveInStorage(keyParseStoreUser); return parseResponse; } } @@ -444,9 +431,10 @@ class ParseUser extends ParseObject implements ParseCloneable { static ParseUser _getEmptyUser() => ParseUser(null, null, null); @override - toJson({bool full: false, bool forApiRQ: false}) => { - "__type": "Pointer", + Map toJson({bool full = false, bool forApiRQ = false}) => + { + '__type': 'Pointer', keyVarClassName: keyClassUser, - keyVarObjectId: this.objectId + keyVarObjectId: objectId }; } diff --git a/lib/src/objects/response/parse_error_response.dart b/lib/src/objects/response/parse_error_response.dart new file mode 100644 index 000000000..b90196166 --- /dev/null +++ b/lib/src/objects/response/parse_error_response.dart @@ -0,0 +1,14 @@ +part of flutter_parse_sdk; + +/// Handles any errors returned in response +ParseResponse buildErrorResponse(ParseResponse response, Response apiResponse) { + + if (apiResponse.body == null) { + return null; + } + + final Map responseData = json.decode(apiResponse.body); + response.error = ParseError(code: responseData[keyCode], message: responseData[keyError].toString()); + response.statusCode = responseData[keyCode]; + return response; +} diff --git a/lib/src/objects/response/parse_exception_response.dart b/lib/src/objects/response/parse_exception_response.dart new file mode 100644 index 000000000..9a798c8b0 --- /dev/null +++ b/lib/src/objects/response/parse_exception_response.dart @@ -0,0 +1,9 @@ +part of flutter_parse_sdk; + +/// Handles exception instead of throwing an exception +ParseResponse buildParseResponseWithException(Exception exception) { + final ParseResponse response = ParseResponse(); + response.error = + ParseError(message: exception.toString(), isTypeOfException: true); + return response; +} diff --git a/lib/src/objects/response/parse_response_builder.dart b/lib/src/objects/response/parse_response_builder.dart new file mode 100644 index 000000000..bbbc0f7a6 --- /dev/null +++ b/lib/src/objects/response/parse_response_builder.dart @@ -0,0 +1,144 @@ +part of flutter_parse_sdk; + +/// Handles all the ParseObject responses +/// +/// There are 4 probable outcomes from a Parse API call, +/// 1. Fail - [ParseResponse()] will be returned with further details +/// 2. Success but no results. [ParseResponse()] is returned. +/// 3. Success with simple OK. +/// 4. Success with results. Again [ParseResponse()] is returned +class _ParseResponseBuilder { + ParseResponse handleResponse(dynamic object, Response apiResponse, + {bool returnAsResult = false}) { + final ParseResponse parseResponse = ParseResponse(); + + if (apiResponse != null) { + parseResponse.statusCode = apiResponse.statusCode; + + if (apiResponse.statusCode != 200 && apiResponse.statusCode != 201) { + return buildErrorResponse(parseResponse, apiResponse); + } else if (apiResponse.body == '{\"results\":[]}') { + return buildSuccessResponseWithNoResults( + parseResponse, 1, 'Successful request, but no results found'); + } else if (returnAsResult) { + return _handleSuccessWithoutParseObject( + parseResponse, object, apiResponse.body); + } else { + return _handleSuccess(parseResponse, object, apiResponse.body); + } + } else { + parseResponse.error = ParseError( + message: 'Error reaching server, or server response was null'); + return parseResponse; + } + } + + /// Handles successful response without creating a ParseObject + ParseResponse _handleSuccessWithoutParseObject( + ParseResponse response, dynamic object, String responseBody) { + response.success = true; + + if (responseBody == 'OK') { + response.result = responseBody; + return response; + } + + final Map decodedJson = json.decode(responseBody); + + if (decodedJson.containsKey('params')) { + response.result = decodedJson['params']; + } else if (decodedJson.containsKey('result')) { + response.result = decodedJson['result']; + } else { + response.result = decodedJson; + } + + return response; + } + + /// Handles successful response with results + ParseResponse _handleSuccess( + ParseResponse response, dynamic object, String responseBody) { + response.success = true; + + final Map map = json.decode(responseBody); + + if (object is Parse) { + response.result = map; + } else if (map != null && map.length == 1 && map.containsKey('results')) { + final List results = map['results']; + response.result = _handleMultipleResults(object, results); + } else { + response.result = _handleSingleResult(object, map); + } + + return response; + } + + /// Handles a response with a multiple result object + List _handleMultipleResults(dynamic object, List data) { + final List resultsList = List(); + + for (dynamic value in data) { + resultsList.add(_handleSingleResult(object, value)); + } + + return resultsList; + } + + /// Handles a response with a single result object + T _handleSingleResult(T object, Map map) { + if (object is ParseCloneable) { + return object.clone(map); + } else { + return null; + } + } +} + +/// Handles an API response and logs data if [bool] debug is enabled +@protected +ParseResponse handleResponse(ParseCloneable object, Response response, + ParseApiRQ type, bool debug, String className) { + final ParseResponse parseResponse = _ParseResponseBuilder().handleResponse( + object, response, + returnAsResult: shouldReturnAsABaseResult(type)); + + if (debug) { + logger(ParseCoreData().appName, className, type.toString(), parseResponse); + } + + return parseResponse; +} + +/// Handles an API response and logs data if [bool] debug is enabled +@protected +ParseResponse handleException( + Exception exception, ParseApiRQ type, bool debug, String className) { + final ParseResponse parseResponse = + buildParseResponseWithException(exception); + + if (debug) { + logger(ParseCoreData().appName, className, type.toString(), parseResponse); + } + + return parseResponse; +} + +bool shouldReturnAsABaseResult(ParseApiRQ type) { + if (type == ParseApiRQ.healthCheck || + type == ParseApiRQ.execute || + type == ParseApiRQ.add || + type == ParseApiRQ.addAll || + type == ParseApiRQ.addUnique || + type == ParseApiRQ.remove || + type == ParseApiRQ.removeAll || + type == ParseApiRQ.increment || + type == ParseApiRQ.decrement || + type == ParseApiRQ.getConfigs || + type == ParseApiRQ.addConfig) { + return true; + } else { + return false; + } +} diff --git a/lib/src/objects/response/parse_success_no_results.dart b/lib/src/objects/response/parse_success_no_results.dart new file mode 100644 index 000000000..053dbadb4 --- /dev/null +++ b/lib/src/objects/response/parse_success_no_results.dart @@ -0,0 +1,9 @@ +part of flutter_parse_sdk; + +/// Handles successful responses with no results +ParseResponse buildSuccessResponseWithNoResults(ParseResponse response, int code, String value) { + response.success = true; + response.statusCode = 200; + response.error = ParseError(code: code, message: value); + return response; +} diff --git a/lib/src/utils/parse_decoder.dart b/lib/src/utils/parse_decoder.dart index b0022bfde..e11062619 100644 --- a/lib/src/utils/parse_decoder.dart +++ b/lib/src/utils/parse_decoder.dart @@ -1,16 +1,16 @@ part of flutter_parse_sdk; List _convertJSONArrayToList(List array) { - List list = new List(); - array.forEach((value) { - list.add(parseDecode(value)); - }); + final List list = []; + for (final dynamic item in array){ + list.add(parseDecode(item)); + } return list; } Map _convertJSONObjectToMap(Map object) { - Map map = new Map(); - object.forEach((key, value) { + final Map map = Map(); + object.forEach((String key, dynamic value) { map.putIfAbsent(key, () => parseDecode(value)); }); return map; @@ -42,33 +42,34 @@ dynamic parseDecode(dynamic value) { return value; } - Map map = value; - if (!map.containsKey("__type")) { + final Map map = value; + + if (!map.containsKey('__type')) { return _convertJSONObjectToMap(map); } - switch (map["__type"]) { - case "Date": - String iso = map["iso"]; + switch (map['__type']) { + case 'Date': + final String iso = map['iso']; return DateTime.parse(iso); - case "Bytes": - String val = map["base64"]; + case 'Bytes': + final String val = map['base64']; return base64.decode(val); - case "Pointer": - String className = map["className"]; + case 'Pointer': + final String className = map['className']; return ParseObject(className).fromJson(map); - case "Object": - String className = map["className"]; + case 'Object': + final String className = map['className']; if (className == '_User') { return ParseUser(null, null, null).fromJson(map); } return ParseObject(className).fromJson(map); - case "File": - return new ParseFile(null, url: map["url"], name: map["name"]).fromJson(map); - case "GeoPoint": - num latitude = map["latitude"] ?? 0.0; - num longitude = map["longitude"] ?? 0.0; - return new ParseGeoPoint( + case 'File': + return ParseFile(null, url: map['url'], name: map['name']).fromJson(map); + case 'GeoPoint': + final num latitude = map['latitude'] ?? 0.0; + final num longitude = map['longitude'] ?? 0.0; + return ParseGeoPoint( latitude: latitude.toDouble(), longitude: longitude.toDouble()); } diff --git a/lib/src/utils/parse_encoder.dart b/lib/src/utils/parse_encoder.dart index 8e4c11766..7c31f44f2 100644 --- a/lib/src/utils/parse_encoder.dart +++ b/lib/src/utils/parse_encoder.dart @@ -44,17 +44,17 @@ dynamic parseEncode(dynamic value, {bool full}) { } Map _encodeUint8List(Uint8List value) { - return {"__type": "Bytes", "base64": base64.encode(value)}; + return {'__type': 'Bytes', 'base64': base64.encode(value)}; } Map _encodeObject(ParseObject object) { - return { - "__type": "Pointer", + return { + '__type': 'Pointer', keyVarClassName: object.className, keyVarObjectId: object.objectId }; } Map _encodeDate(DateTime date) { - return {"__type": "Date", "iso": date.toIso8601String()}; + return {'__type': 'Date', 'iso': date.toIso8601String()}; } diff --git a/lib/src/utils/parse_file_extensions.dart b/lib/src/utils/parse_file_extensions.dart index 23fa1f147..7dc4a829a 100644 --- a/lib/src/utils/parse_file_extensions.dart +++ b/lib/src/utils/parse_file_extensions.dart @@ -11,27 +11,25 @@ String getExtension(String contentType) { /// Get the content type based on String getContentType(String extension) { - Map extensions = _queryExtensions(); + final Map extensions = _queryExtensions(); if (extension.lastIndexOf('.') >= 0) { extension = extension.substring(extension.lastIndexOf('.') + 1); } String contentType = extensions[extension.toLowerCase()]; - if (contentType == null) { - contentType = 'application/octet-stream'; - } + contentType ??= 'application/octet-stream'; return contentType; } /// Add content types based on extension to a map -Map _queryExtensions() { - Map extensions = Map(); +Map _queryExtensions() { + Map extensions = Map(); if (extensions == null) { - extensions = {}; - _extensions.forEach((type, typeInfo) { + extensions = {}; + _extensions.forEach((dynamic type, dynamic typeInfo) { if (typeInfo.containsKey('extensions')) { for (String ext in typeInfo['extensions']) { _extensions[ext] = type; @@ -43,5444 +41,5444 @@ Map _queryExtensions() { return extensions; } -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" +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/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} + '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} }; diff --git a/lib/src/utils/parse_logger.dart b/lib/src/utils/parse_logger.dart index 7ce7eb7ef..8d62d0ea6 100644 --- a/lib/src/utils/parse_logger.dart +++ b/lib/src/utils/parse_logger.dart @@ -2,43 +2,46 @@ part of flutter_parse_sdk; void logger(String appName, String className, String type, ParseResponse parseResponse) { - var responseString = ' \n'; - var name = appName; - if (name.length > 0) name = "$appName "; + String responseString = ' \n'; + String name = appName; + if (name.isNotEmpty) { + name = '$appName '; + } - responseString += "----\n${name}API Response ($className : $type) :"; + responseString += '----\n${name}API Response ($className : $type) :'; if (parseResponse.success) { - responseString += "\nStatus Code: ${parseResponse.statusCode}"; + responseString += '\nStatus Code: ${parseResponse.statusCode}'; if (parseResponse.result != null) { - responseString += "\nPayload: ${parseResponse.result.toString()}"; + responseString += '\nPayload: ${parseResponse.result.toString()}'; } else { - responseString += "\nReponse: OK"; + 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}'; - String errorOrException = - parseResponse.error.isTypeOfException ? "Exception" : "Error"; + final String errorOrException = + parseResponse.error.isTypeOfException ? 'Exception' : 'Error'; - responseString += "\n$errorOrException: ${parseResponse.error.message}"; + responseString += '\n$errorOrException: ${parseResponse.error.message}'; } - responseString += "\n----\n"; + responseString += '\n----\n'; print(responseString); } void logRequest( String appName, String className, String type, String uri, String body) { - var requestString = ' \n'; - var name = appName; - if (name.length > 0) name = "$appName "; - - requestString += "----\n${name}API Request ($className : $type) :"; - requestString += "\nUri: ${uri}"; - requestString += "\nBody: ${body}"; + String requestString = ' \n'; + String name = appName; + if (name.isNotEmpty) { + name = '$appName '; + } + requestString += '----\n${name}API Request ($className : $type) :'; + requestString += '\nUri: $uri'; + requestString += '\nBody: $body'; - requestString += "\n----\n"; - print(requestString); + requestString += '\n----\n'; + print(requestString); } diff --git a/lib/src/utils/parse_utils.dart b/lib/src/utils/parse_utils.dart index 422e011e3..daa9f5e1b 100644 --- a/lib/src/utils/parse_utils.dart +++ b/lib/src/utils/parse_utils.dart @@ -11,9 +11,9 @@ bool isDebugEnabled({bool objectLevelDebug}) { /// Converts the object to the correct value for JSON, /// /// Strings are wrapped with "" but integers and others are not -convertValueToCorrectType(dynamic value) { +dynamic convertValueToCorrectType(dynamic value) { if (value is String && !value.contains('__type')) { - return "\"$value\""; + return '\"$value\"'; } else { return value; } From ea0bef7afb103e64549e5f0dd73b0a947c68cd48 Mon Sep 17 00:00:00 2001 From: Phill Date: Sun, 17 Mar 2019 16:54:24 +0000 Subject: [PATCH 4/8] Added url port support Added lint rules Added object population on update and save --- example/lib/diet_plan.dart | 2 +- lib/parse_server_sdk.dart | 2 + lib/src/network/parse_http_client.dart | 2 +- lib/src/network/parse_live_query.dart | 4 +- lib/src/objects/parse_base.dart | 48 +++++++-- lib/src/objects/parse_config.dart | 2 +- lib/src/objects/parse_file.dart | 3 +- lib/src/objects/parse_function.dart | 13 ++- lib/src/objects/parse_geo_point.dart | 25 ++--- lib/src/objects/parse_installation.dart | 8 +- lib/src/objects/parse_object.dart | 46 ++------- lib/src/objects/parse_user.dart | 98 ++++--------------- .../response/parse_response_builder.dart | 65 +++--------- lib/src/objects/response/response_utils.dart | 53 ++++++++++ lib/src/utils/parse_decoder.dart | 72 +++++++++----- lib/src/utils/parse_encoder.dart | 16 +-- lib/src/utils/parse_utils.dart | 13 +++ test/parse_client_configuration_test.dart | 28 +++--- 18 files changed, 234 insertions(+), 266 deletions(-) create mode 100644 lib/src/objects/response/response_utils.dart diff --git a/example/lib/diet_plan.dart b/example/lib/diet_plan.dart index b9046d3f5..94f16496f 100644 --- a/example/lib/diet_plan.dart +++ b/example/lib/diet_plan.dart @@ -9,7 +9,7 @@ class DietPlan extends ParseObject implements ParseCloneable { /// Looks strangely hacky but due to Flutter not using reflection, we have to /// mimic a clone @override - DietPlan clone(Map map) => DietPlan.clone()..fromJson(map); + DietPlan clone(Map map) => DietPlan.clone()..fromJson(map); static const String _keyTableName = 'Diet_Plans'; static const String keyName = 'Name'; diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index 9a302e9e4..ab8a14fa3 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -16,6 +16,8 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:uuid/uuid.dart'; import 'package:web_socket_channel/io.dart'; +part 'package:parse_server_sdk/src/objects/response/response_utils.dart'; + part 'package:parse_server_sdk/src/objects/response/parse_error_response.dart'; part 'package:parse_server_sdk/src/objects/response/parse_exception_response.dart'; diff --git a/lib/src/network/parse_http_client.dart b/lib/src/network/parse_http_client.dart index 6659abb15..b88fe9183 100644 --- a/lib/src/network/parse_http_client.dart +++ b/lib/src/network/parse_http_client.dart @@ -33,7 +33,7 @@ class ParseHTTPClient extends BaseClient { /// If developer wants to add custom headers, extend this class and add headers needed. if (additionalHeaders != null && additionalHeaders.isNotEmpty) { - additionalHeaders.forEach((k, v) => request.headers[k] = v); + additionalHeaders.forEach((String key, String value) => request.headers[key] = value); } return _client.send(request); diff --git a/lib/src/network/parse_live_query.dart b/lib/src/network/parse_live_query.dart index 4126d9345..d04988682 100644 --- a/lib/src/network/parse_live_query.dart +++ b/lib/src/network/parse_live_query.dart @@ -4,7 +4,7 @@ part of flutter_parse_sdk; class LiveQuery { LiveQuery(ParseHTTPClient client) : client = client { - connectMessage = { + connectMessage = { 'op': 'connect', 'applicationId': client.data.applicationId, }; @@ -31,7 +31,7 @@ class LiveQuery { final WebSocket webSocket = await WebSocket.connect(client.data.liveQueryURL); channel = IOWebSocketChannel(webSocket); channel.sink.add(jsonEncode(connectMessage)); - Map classNameMap = subscribeMessage['query']; + final Map classNameMap = subscribeMessage['query']; classNameMap['className'] = className; channel.sink.add(jsonEncode(subscribeMessage)); diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 3f55dc993..de56a30c6 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -17,10 +17,24 @@ abstract class ParseBase { set objectId(String objectId) => set(keyVarObjectId, objectId); /// Returns [DateTime] createdAt - DateTime get createdAt => get(keyVarCreatedAt); + DateTime get createdAt { + if (get(keyVarCreatedAt) is String) { + final String dateAsString = get(keyVarCreatedAt); + return DateTime.parse(dateAsString); + } else { + return get(keyVarCreatedAt); + } + } /// Returns [DateTime] updatedAt - DateTime get updatedAt => get(keyVarUpdatedAt); + DateTime get updatedAt { + if (get(keyVarUpdatedAt) is String) { + final String dateAsString = get(keyVarUpdatedAt); + return DateTime.parse(dateAsString); + } else { + return get(keyVarUpdatedAt); + } + } /// Converts object to [String] in JSON format @protected @@ -42,9 +56,9 @@ abstract class ParseBase { } getObjectData().forEach((String key, dynamic value) { - if (!map.containsKey(key)) { - map[key] = parseEncode(value, full: full); - } + if (!map.containsKey(key)) { + map[key] = parseEncode(value, full: full); + } }); if (forApiRQ) { @@ -73,9 +87,17 @@ abstract class ParseBase { } else if (key == keyVarObjectId) { objectId = value; } else if (key == keyVarCreatedAt) { - set(keyVarCreatedAt, DateTime.parse(value)); + if (keyVarCreatedAt is String) { + set(keyVarCreatedAt, DateTime.parse(value)); + } else { + set(keyVarCreatedAt, value); + } } else if (key == keyVarUpdatedAt) { - set(keyVarUpdatedAt, DateTime.parse(value)); + if (keyVarUpdatedAt is String) { + set(keyVarUpdatedAt, DateTime.parse(value)); + } else { + set(keyVarUpdatedAt, value); + } } else { getObjectData()[key] = parseDecode(value); } @@ -90,7 +112,8 @@ abstract class ParseBase { /// Sets all the objects variables @protected - void setObjectData(Map objectData) => _objectData = objectData; + void setObjectData(Map objectData) => + _objectData = objectData; /// Returns the objects variables @protected @@ -99,8 +122,9 @@ abstract class ParseBase { /// Saves in storage @protected Future saveInStorage(String key) async { + final String objectJson = json.encode(toJson(full: true)); await ParseCoreData().getStore() - ..setString(key, toString()); + ..setString(key, objectJson); } /// Sets type [T] from objectData @@ -181,4 +205,10 @@ abstract class ParseBase { } return null; } + + Map toPointer() => { + '__type': 'Pointer', + keyVarClassName: className, + keyVarObjectId: objectId + }; } diff --git a/lib/src/objects/parse_config.dart b/lib/src/objects/parse_config.dart index 25c579ec9..86e3e3292 100644 --- a/lib/src/objects/parse_config.dart +++ b/lib/src/objects/parse_config.dart @@ -16,7 +16,7 @@ class ParseConfig extends ParseObject { Future getConfigs() async { try { final String uri = '${ParseCoreData().serverUrl}/config'; - final result = await _client.get(uri); + final Response result = await _client.get(uri); return handleResponse( this, result, ParseApiRQ.getConfigs, _debug, className); } on Exception catch (e) { diff --git a/lib/src/objects/parse_file.dart b/lib/src/objects/parse_file.dart index 9bc4f0a16..372d0e2b4 100644 --- a/lib/src/objects/parse_file.dart +++ b/lib/src/objects/parse_file.dart @@ -90,8 +90,7 @@ class ParseFile extends ParseObject { Future upload() async { if (saved) { //Creates a Fake Response to return the correct result - // ignore: always_specify_types - final Map response = {'url': url, 'name': name}; + final Map response = {'url': url, 'name': name}; return handleResponse(this, Response(json.encode(response), 201), ParseApiRQ.upload, _debug, className); } diff --git a/lib/src/objects/parse_function.dart b/lib/src/objects/parse_function.dart index 2a739284f..16bcf12e6 100644 --- a/lib/src/objects/parse_function.dart +++ b/lib/src/objects/parse_function.dart @@ -29,10 +29,13 @@ class ParseCloudFunction extends ParseObject { Future execute( {Map parameters, Map headers}) async { final String uri = '${_client.data.serverUrl}$_path'; - if (parameters != null) setObjectData(parameters); + if (parameters != null) { + setObjectData(parameters); + } + final Response result = - await _client.post(uri, body: json.encode(getObjectData())); - return handleResponse(this, result, ParseApiRQ.execute, _debug, className); + await _client.post(uri, body: json.encode(getObjectData())); + return handleResponse(this, result, ParseApiRQ.execute, _debug, className); } /// Executes a cloud function that returns a ParseObject type @@ -41,7 +44,9 @@ class ParseCloudFunction extends ParseObject { Future executeObjectFunction( {Map parameters, Map headers}) async { final String uri = '${_client.data.serverUrl}$_path'; - if (parameters != null) setObjectData(parameters); + if (parameters != null) { + setObjectData(parameters); + } final Response result = await _client.post(uri, body: json.encode(getObjectData())); return handleResponse( diff --git a/lib/src/objects/parse_geo_point.dart b/lib/src/objects/parse_geo_point.dart index 3d4bffd19..3ffff43e6 100644 --- a/lib/src/objects/parse_geo_point.dart +++ b/lib/src/objects/parse_geo_point.dart @@ -10,8 +10,9 @@ class ParseGeoPoint extends ParseObject { ParseHTTPClient client, bool autoSendSessionId}) : super(keyGeoPoint) { - _latitude = latitude; - _longitude = longitude; + + latitude = latitude; + longitude = longitude; _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? @@ -21,25 +22,13 @@ class ParseGeoPoint extends ParseObject { securityContext: ParseCoreData().securityContext); } - double _latitude; - double _longitude; - - double get latitude => _latitude; - - double get longitude => _longitude; - - set latitude(double value) { - _latitude = value; - } - - set longitude(double value) { - _longitude = value; - } + double latitude; + double longitude; @override Map toJson({bool full = false, bool forApiRQ = false}) => { '__type': 'GeoPoint', - 'latitude': _latitude, - 'longitude': _longitude + 'latitude': latitude, + 'longitude': longitude }; } diff --git a/lib/src/objects/parse_installation.dart b/lib/src/objects/parse_installation.dart index a1b7e9115..26296162d 100644 --- a/lib/src/objects/parse_installation.dart +++ b/lib/src/objects/parse_installation.dart @@ -105,10 +105,12 @@ class ParseInstallation extends ParseObject { /// Saves the current installation @override Future save() async { - var isCurrent = await ParseInstallation.isCurrent(this); - if (isCurrent) await _updateInstallation(); + final bool isCurrent = await ParseInstallation.isCurrent(this); + if (isCurrent) { + await _updateInstallation(); + } //ParseResponse parseResponse = await super.save(); - ParseResponse parseResponse = await _save(); + final ParseResponse parseResponse = await _save(); if (parseResponse.success && isCurrent) { saveInStorage(keyParseStoreInstallation); } diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index 5f54fc779..e007814f3 100644 --- a/lib/src/objects/parse_object.dart +++ b/lib/src/objects/parse_object.dart @@ -30,9 +30,6 @@ class ParseObject extends ParseBase implements ParseCloneable { bool _debug; ParseHTTPClient _client; - /// Converts the object to a Pointer to be used ONLY in queries using Pointers - dynamic toPointer() => json.encode(parseEncode(this)); - /// Gets an object from the server using it's [String] objectId Future getObject(String objectId) async { try { @@ -50,8 +47,8 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Gets all objects from this table - Limited response at the moment Future getAll() async { try { - final Response result = - await _client.get('${ParseCoreData().serverUrl}$_path'); + final Uri url = getSanitisedUri(_client, '$_path'); + final Response result = await _client.get(url); return handleResponse(this, result, ParseApiRQ.getAll, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.getAll, _debug, className); @@ -61,9 +58,9 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Creates a new object and saves it online Future create() async { try { - final String uri = '${_client.data.serverUrl}$_path'; + final Uri url = getSanitisedUri(_client, '$_path'); final String body = json.encode(toJson(forApiRQ: true)); - final Response result = await _client.post(uri, body: body); + final Response result = await _client.post(url, body: body); //Set the objectId on the object after it is created. //This allows you to perform operations on the object after creation @@ -84,14 +81,7 @@ class ParseObject extends ParseBase implements ParseCloneable { return create(); } else { try { - final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$_path/$objectId'); - + final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final String body = json.encode(toJson(forApiRQ: true)); final Response result = await _client.put(url, body: body); return handleResponse(this, result, ParseApiRQ.save, _debug, className); @@ -181,14 +171,7 @@ class ParseObject extends ParseBase implements ParseCloneable { String key, List values) async { try { if (objectId != null) { - final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$_path/$objectId'); - + final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final String body = '{\"$key\":{\"__op\":\"$arrayAction\",\"objects\":${json.encode(parseEncode(values))}}}'; final Response result = await _client.put(url, body: body); @@ -243,14 +226,7 @@ class ParseObject extends ParseBase implements ParseCloneable { ParseApiRQ apiRQType, String countAction, String key, num amount) async { try { if (objectId != null) { - final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$_path/$objectId'); - + final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final String body = '{\"$key\":{\"__op\":\"$countAction\",\"amount\":$amount}}'; final Response result = await _client.put(url, body: body); return handleResponse(this, result, apiRQType, _debug, className); @@ -286,12 +262,8 @@ class ParseObject extends ParseBase implements ParseCloneable { try { path ??= _path; objectId ??= objectId; - final String uri = '${ParseCoreData().serverUrl}$path/$objectId'; - if (_debug) { - logRequest(ParseCoreData().appName, className, - ParseApiRQ.delete.toString(), uri, ''); - } - final Response result = await _client.delete(uri); + final Uri url = getSanitisedUri(_client, '$_path/$objectId'); + final Response result = await _client.delete(url); return handleResponse(this, result, ParseApiRQ.delete, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.delete, _debug, className); diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 4e6f244b7..6a875c3cd 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -92,15 +92,8 @@ class ParseUser extends ParseObject implements ParseCloneable { } try { - final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - final Uri uri = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$keyEndPointUserName'); - - final Response response = await _client.get(uri, headers: headers); + final Uri url = getSanitisedUri(_client, '$keyEndPointUserName'); + final Response response = await _client.get(url, headers: headers); return _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, _debug, _getEmptyUser().className); } on Exception catch (e) { @@ -132,15 +125,7 @@ class ParseUser extends ParseObject implements ParseCloneable { bodyData[keyVarEmail] = emailAddress; bodyData[keyVarPassword] = password; bodyData[keyVarUsername] = username; - - final Uri tempUri = Uri.parse(_client.data.serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$path'); - + final Uri url = getSanitisedUri(_client, '$path'); final Response response = await _client.post(url, headers: { keyHeaderRevocableSession: '1', @@ -187,15 +172,7 @@ class ParseUser extends ParseObject implements ParseCloneable { // Logs in a user anonymously Future loginAnonymous() async { try { - final Uri tempUri = Uri.parse(_client.data.serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$keyEndPointUsers', - ); - + final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); final Uuid uuid = Uuid(); final Response response = await _client.post(url, @@ -216,29 +193,18 @@ class ParseUser extends ParseObject implements ParseCloneable { } // Logs in a user using a service - static Future loginWith(String provider, Object authData) async { + static Future loginWith(String provider, Object authData) async { final ParseUser user = ParseUser.createUser(); final ParseResponse response = await user._loginWith(provider, authData); - if (response.success) { - return user; - } else { - return Future.error(response); - } + return response; } Future _loginWith(String provider, Object authData) async { try { - final Uri tempUri = Uri.parse(_client.data.serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$keyEndPointUsers', - ); + final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); final Response response = await _client.post(url, - headers: { + headers: { keyHeaderRevocableSession: '1', }, body: jsonEncode({ @@ -267,14 +233,7 @@ class ParseUser extends ParseObject implements ParseCloneable { } try { - final Uri tempUri = Uri.parse(_client.data.serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$keyEndPointLogout'); - + final Uri url = getSanitisedUri(_client, '$keyEndPointLogout'); final Response response = await _client.post(url, headers: {keyHeaderSessionToken: sessionId}); @@ -323,19 +282,10 @@ class ParseUser extends ParseObject implements ParseCloneable { return signUp(); } else { try { - final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$_path/$objectId'); - - final String body = - json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); + final Uri url = getSanitisedUri(_client, '$_path/$objectId'); + final String body = json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); final Response response = await _client.put(url, body: body); - return _handleResponse( - this, response, ParseApiRQ.save, _debug, className); + return _handleResponse(this, response, ParseApiRQ.save, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.save, _debug, className); } @@ -346,14 +296,7 @@ class ParseUser extends ParseObject implements ParseCloneable { Future destroy() async { if (objectId != null) { try { - final Uri tempUri = Uri.parse(ParseCoreData().serverUrl); - - final Uri url = Uri( - scheme: tempUri.scheme, - host: tempUri.host, - port: tempUri.port, - path: '${tempUri.path}$_path/$objectId'); - + final Uri url = getSanitisedUri(_client, '$_path/$objectId'); final Response response = await _client.delete(url); return _handleResponse( this, response, ParseApiRQ.destroy, _debug, className); @@ -394,7 +337,8 @@ class ParseUser extends ParseObject implements ParseCloneable { final Map userMap = json.decode(userJson); if (userMap != null) { ParseCoreData().setSessionId(userMap[keyParamSessionToken]); - return parseDecode(userMap); + final ParseUser user = parseDecode(userMap); + return user; } } @@ -414,8 +358,8 @@ class ParseUser extends ParseObject implements ParseCloneable { ParseCoreData().setSessionId(user.sessionToken); } - if (parseResponse.statusCode != 200 || - parseResponse.statusCode != 201 || + if ((parseResponse.statusCode != 200 && + parseResponse.statusCode != 201) || type == ParseApiRQ.getAll || type == ParseApiRQ.destroy || type == ParseApiRQ.requestPasswordReset || @@ -429,12 +373,4 @@ class ParseUser extends ParseObject implements ParseCloneable { } static ParseUser _getEmptyUser() => ParseUser(null, null, null); - - @override - Map toJson({bool full = false, bool forApiRQ = false}) => - { - '__type': 'Pointer', - keyVarClassName: keyClassUser, - keyVarObjectId: objectId - }; } diff --git a/lib/src/objects/response/parse_response_builder.dart b/lib/src/objects/response/parse_response_builder.dart index bbbc0f7a6..714a86e51 100644 --- a/lib/src/objects/response/parse_response_builder.dart +++ b/lib/src/objects/response/parse_response_builder.dart @@ -8,16 +8,18 @@ part of flutter_parse_sdk; /// 3. Success with simple OK. /// 4. Success with results. Again [ParseResponse()] is returned class _ParseResponseBuilder { - ParseResponse handleResponse(dynamic object, Response apiResponse, + ParseResponse handleResponse( + dynamic object, + Response apiResponse, {bool returnAsResult = false}) { final ParseResponse parseResponse = ParseResponse(); if (apiResponse != null) { parseResponse.statusCode = apiResponse.statusCode; - if (apiResponse.statusCode != 200 && apiResponse.statusCode != 201) { + if (isUnsuccessfulResponse(apiResponse)) { return buildErrorResponse(parseResponse, apiResponse); - } else if (apiResponse.body == '{\"results\":[]}') { + } else if (isSuccessButNoResults(apiResponse)) { return buildSuccessResponseWithNoResults( parseResponse, 1, 'Successful request, but no results found'); } else if (returnAsResult) { @@ -69,7 +71,7 @@ class _ParseResponseBuilder { final List results = map['results']; response.result = _handleMultipleResults(object, results); } else { - response.result = _handleSingleResult(object, map); + response.result = _handleSingleResult(object, map, false); } return response; @@ -80,65 +82,20 @@ class _ParseResponseBuilder { final List resultsList = List(); for (dynamic value in data) { - resultsList.add(_handleSingleResult(object, value)); + resultsList.add(_handleSingleResult(object, value, true)); } return resultsList; } /// Handles a response with a single result object - T _handleSingleResult(T object, Map map) { - if (object is ParseCloneable) { + T _handleSingleResult(T object, Map map, bool createNewObject) { + if (createNewObject && object is ParseCloneable) { return object.clone(map); + } else if (object is ParseObject) { + return object..fromJson(map); } else { return null; } } } - -/// Handles an API response and logs data if [bool] debug is enabled -@protected -ParseResponse handleResponse(ParseCloneable object, Response response, - ParseApiRQ type, bool debug, String className) { - final ParseResponse parseResponse = _ParseResponseBuilder().handleResponse( - object, response, - returnAsResult: shouldReturnAsABaseResult(type)); - - if (debug) { - logger(ParseCoreData().appName, className, type.toString(), parseResponse); - } - - return parseResponse; -} - -/// Handles an API response and logs data if [bool] debug is enabled -@protected -ParseResponse handleException( - Exception exception, ParseApiRQ type, bool debug, String className) { - final ParseResponse parseResponse = - buildParseResponseWithException(exception); - - if (debug) { - logger(ParseCoreData().appName, className, type.toString(), parseResponse); - } - - return parseResponse; -} - -bool shouldReturnAsABaseResult(ParseApiRQ type) { - if (type == ParseApiRQ.healthCheck || - type == ParseApiRQ.execute || - type == ParseApiRQ.add || - type == ParseApiRQ.addAll || - type == ParseApiRQ.addUnique || - type == ParseApiRQ.remove || - type == ParseApiRQ.removeAll || - type == ParseApiRQ.increment || - type == ParseApiRQ.decrement || - type == ParseApiRQ.getConfigs || - type == ParseApiRQ.addConfig) { - return true; - } else { - return false; - } -} diff --git a/lib/src/objects/response/response_utils.dart b/lib/src/objects/response/response_utils.dart new file mode 100644 index 000000000..17fc181b2 --- /dev/null +++ b/lib/src/objects/response/response_utils.dart @@ -0,0 +1,53 @@ +part of flutter_parse_sdk; + +/// Handles an API response and logs data if [bool] debug is enabled +@protected +ParseResponse handleResponse(ParseCloneable object, Response response, + ParseApiRQ type, bool debug, String className) { + final ParseResponse parseResponse = _ParseResponseBuilder().handleResponse( + object, response, + returnAsResult: shouldReturnAsABaseResult(type)); + + if (debug) { + logger(ParseCoreData().appName, className, type.toString(), parseResponse); + } + + return parseResponse; +} + +/// Handles an API response and logs data if [bool] debug is enabled +@protected +ParseResponse handleException( + Exception exception, ParseApiRQ type, bool debug, String className) { + final ParseResponse parseResponse = + buildParseResponseWithException(exception); + + if (debug) { + logger(ParseCoreData().appName, className, type.toString(), parseResponse); + } + + return parseResponse; +} + +bool shouldReturnAsABaseResult(ParseApiRQ type) { + if (type == ParseApiRQ.healthCheck || + type == ParseApiRQ.execute || + type == ParseApiRQ.add || + type == ParseApiRQ.addAll || + type == ParseApiRQ.addUnique || + type == ParseApiRQ.remove || + type == ParseApiRQ.removeAll || + type == ParseApiRQ.increment || + type == ParseApiRQ.decrement || + type == ParseApiRQ.getConfigs || + type == ParseApiRQ.addConfig) { + return true; + } else { + return false; + } +} + +bool isUnsuccessfulResponse(Response apiResponse) => apiResponse.statusCode != 200 && apiResponse.statusCode != 201; + +bool isSuccessButNoResults(Response apiResponse) => apiResponse.body == '{\"results\":[]}'; + diff --git a/lib/src/utils/parse_decoder.dart b/lib/src/utils/parse_decoder.dart index e11062619..dc348cf45 100644 --- a/lib/src/utils/parse_decoder.dart +++ b/lib/src/utils/parse_decoder.dart @@ -2,7 +2,7 @@ part of flutter_parse_sdk; List _convertJSONArrayToList(List array) { final List list = []; - for (final dynamic item in array){ + for (final dynamic item in array) { list.add(parseDecode(item)); } return list; @@ -44,33 +44,55 @@ dynamic parseDecode(dynamic value) { final Map map = value; - if (!map.containsKey('__type')) { + if (!map.containsKey('__type') && !map.containsKey('className')) { return _convertJSONObjectToMap(map); } - switch (map['__type']) { - case 'Date': - final String iso = map['iso']; - return DateTime.parse(iso); - case 'Bytes': - final String val = map['base64']; - return base64.decode(val); - case 'Pointer': - final String className = map['className']; - return ParseObject(className).fromJson(map); - case 'Object': - final String className = map['className']; - if (className == '_User') { - return ParseUser(null, null, null).fromJson(map); - } - return ParseObject(className).fromJson(map); - case 'File': - return ParseFile(null, url: map['url'], name: map['name']).fromJson(map); - case 'GeoPoint': - final num latitude = map['latitude'] ?? 0.0; - final num longitude = map['longitude'] ?? 0.0; - return ParseGeoPoint( - latitude: latitude.toDouble(), longitude: longitude.toDouble()); + /// Decoding from Api Response + if (map.containsKey('__type')) { + switch (map['__type']) { + case 'Date': + final String iso = map['iso']; + return DateTime.parse(iso); + case 'Bytes': + final String val = map['base64']; + return base64.decode(val); + case 'Pointer': + final String className = map['className']; + if (className == '_User') { + return ParseUser._getEmptyUser().fromJson(map); + } + return ParseObject(className).fromJson(map); + case 'Object': + final String className = map['className']; + if (className == '_User') { + return ParseUser._getEmptyUser().fromJson(map); + } + return ParseObject(className).fromJson(map); + case 'File': + return ParseFile(null, url: map['url'], name: map['name']) + .fromJson(map); + case 'GeoPoint': + final num latitude = map['latitude'] ?? 0.0; + final num longitude = map['longitude'] ?? 0.0; + return ParseGeoPoint( + latitude: latitude.toDouble(), longitude: longitude.toDouble()); + } + } + + /// Decoding from locally cached JSON + if (map.containsKey('className')) { + switch (map['className']) { + case '_User': + return ParseUser._getEmptyUser().fromJson(map); + case 'GeoPoint': + final num latitude = map['latitude'] ?? 0.0; + final num longitude = map['longitude'] ?? 0.0; + return ParseGeoPoint( + latitude: latitude.toDouble(), longitude: longitude.toDouble()); + default: + return ParseObject(map['className']).fromJson(map); + } } return null; diff --git a/lib/src/utils/parse_encoder.dart b/lib/src/utils/parse_encoder.dart index 7c31f44f2..2fe2abe4a 100644 --- a/lib/src/utils/parse_encoder.dart +++ b/lib/src/utils/parse_encoder.dart @@ -28,15 +28,11 @@ dynamic parseEncode(dynamic value, {bool full}) { return value; } - if (value is ParseUser) { - return value; - } - - if (value is ParseObject) { + if (value is ParseObject || value is ParseUser) { if (full) { return value.toJson(full: full); } else { - return _encodeObject(value); + return value.toPointer(); } } @@ -47,14 +43,6 @@ Map _encodeUint8List(Uint8List value) { return {'__type': 'Bytes', 'base64': base64.encode(value)}; } -Map _encodeObject(ParseObject object) { - return { - '__type': 'Pointer', - keyVarClassName: object.className, - keyVarObjectId: object.objectId - }; -} - Map _encodeDate(DateTime date) { return {'__type': 'Date', 'iso': date.toIso8601String()}; } diff --git a/lib/src/utils/parse_utils.dart b/lib/src/utils/parse_utils.dart index daa9f5e1b..4b00a2a3c 100644 --- a/lib/src/utils/parse_utils.dart +++ b/lib/src/utils/parse_utils.dart @@ -18,3 +18,16 @@ dynamic convertValueToCorrectType(dynamic value) { return value; } } + +/// Sanitises a url +Uri getSanitisedUri(ParseHTTPClient client, String pathToAppend) { + final Uri tempUri = Uri.parse(client.data.serverUrl); + + final Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + port: tempUri.port, + path: '${tempUri.path}$pathToAppend'); + + return url; +} diff --git a/test/parse_client_configuration_test.dart b/test/parse_client_configuration_test.dart index e017fb36f..0d90dc20b 100644 --- a/test/parse_client_configuration_test.dart +++ b/test/parse_client_configuration_test.dart @@ -2,22 +2,22 @@ import 'package:parse_server_sdk/parse_server_sdk.dart'; import 'package:test/test.dart'; void main() { - test("testBuilder", () { - Parse().initialize("appId", "serverUrl", - clientKey: "clientKey", - liveQueryUrl: "liveQueryUrl", - appName: "appName", - masterKey: "masterKey", - sessionId: "sessionId", + test('testBuilder', () { + Parse().initialize('appId', 'serverUrl', + clientKey: 'clientKey', + liveQueryUrl: 'liveQueryUrl', + appName: 'appName', + masterKey: 'masterKey', + sessionId: 'sessionId', debug: true); - expect(ParseCoreData().applicationId, "appId"); - expect(ParseCoreData().serverUrl, "serverUrl"); - expect(ParseCoreData().clientKey, "clientKey"); - expect(ParseCoreData().liveQueryURL, "liveQueryUrl"); - expect(ParseCoreData().appName, "appName"); - expect(ParseCoreData().masterKey, "masterKey"); - expect(ParseCoreData().sessionId, "sessionId"); + expect(ParseCoreData().applicationId, 'appId'); + expect(ParseCoreData().serverUrl, 'serverUrl'); + expect(ParseCoreData().clientKey, 'clientKey'); + expect(ParseCoreData().liveQueryURL, 'liveQueryUrl'); + expect(ParseCoreData().appName, 'appName'); + expect(ParseCoreData().masterKey, 'masterKey'); + expect(ParseCoreData().sessionId, 'sessionId'); expect(ParseCoreData().debug, true); }); } From f411bbf81119ed8c612609782f3bb19e90ebf44f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bj=C3=B8rnbakk?= Date: Sun, 17 Mar 2019 18:44:47 +0100 Subject: [PATCH 5/8] Updated dependency uuid (#120) --- pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 9199d48fa..b23ea471a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # Utils shared_preferences: ^0.5.0 path_provider: ^0.4.1 - uuid: ^1.0.3 + uuid: ^2.0.0 package_info: ^0.4.0 devicelocale: ^0.1.1 @@ -26,4 +26,4 @@ dev_dependencies: # Testing test: ^1.5.1 flutter_test: - sdk: flutter \ No newline at end of file + sdk: flutter From 45b251eb7af4ecb7e820f5711fff05f00613e003 Mon Sep 17 00:00:00 2001 From: Phill Date: Sun, 17 Mar 2019 18:01:43 +0000 Subject: [PATCH 6/8] Fixed date query - Needs testing --- example/lib/main.dart | 9 ++++++--- lib/src/network/parse_query.dart | 16 ++++++++++++---- lib/src/objects/parse_user.dart | 21 +++++++++++---------- lib/src/utils/parse_encoder.dart | 8 ++++---- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index dcb19eae5..b96310655 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -131,8 +131,8 @@ class _MyAppState extends State { Future query() async { final QueryBuilder queryBuilder = QueryBuilder(ParseObject('TestObjectForApi')) - ..whereEqualTo('age', 26) - ..includeObject(['Day']); + ..whereGreaterThan( + keyVarCreatedAt, DateTime.now().subtract(Duration(hours: 1))); final ParseResponse apiResponse = await queryBuilder.query(); @@ -220,7 +220,10 @@ class _MyAppState extends State { final ParseResponse apiResponse = await queryBuilder.query(); if (apiResponse.success) { - user = response.result; + final List users = response.result; + for (final ParseUser user in users) { + print(ApplicationConstants.keyAppName + ': ' + user.toString()); + } } } diff --git a/lib/src/network/parse_query.dart b/lib/src/network/parse_query.dart index fac28485e..9c8b14092 100644 --- a/lib/src/network/parse_query.dart +++ b/lib/src/network/parse_query.dart @@ -285,8 +285,8 @@ class QueryBuilder { MapEntry _buildQueryWithColumnValueAndOperator( MapEntry columnAndValue, String queryOperator) { final String key = columnAndValue.key; - - final dynamic value = convertValueToCorrectType(columnAndValue.value); + final dynamic value = + convertValueToCorrectType(parseEncode(columnAndValue.value)); if (queryOperator == _NO_OPERATOR_NEEDED) { return MapEntry( @@ -296,8 +296,8 @@ class QueryBuilder { final Map queryOperatorAndValueMap = Map(); - queryOperatorAndValueMap[queryOperator] = columnAndValue.value; - + queryOperatorAndValueMap[queryOperator] = + parseEncode(columnAndValue.value); final String formattedQueryOperatorAndValue = jsonEncode(queryOperatorAndValueMap); queryString += '$formattedQueryOperatorAndValue'; @@ -371,4 +371,12 @@ class QueryBuilder { }); return result; } + + String convertToQueryableFormats(dynamic value) { + if (value is DateTime) { + return value.toIso8601String(); + } + + return value; + } } diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 6a875c3cd..a5bf6e68f 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -193,7 +193,8 @@ class ParseUser extends ParseObject implements ParseCloneable { } // Logs in a user using a service - static Future loginWith(String provider, Object authData) async { + static Future loginWith( + String provider, Object authData) async { final ParseUser user = ParseUser.createUser(); final ParseResponse response = await user._loginWith(provider, authData); return response; @@ -201,7 +202,6 @@ class ParseUser extends ParseObject implements ParseCloneable { Future _loginWith(String provider, Object authData) async { try { - final Uri url = getSanitisedUri(_client, '$keyEndPointUsers'); final Response response = await _client.post(url, headers: { @@ -283,9 +283,11 @@ class ParseUser extends ParseObject implements ParseCloneable { } else { try { final Uri url = getSanitisedUri(_client, '$_path/$objectId'); - final String body = json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); + final String body = + json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); final Response response = await _client.put(url, body: body); - return _handleResponse(this, response, ParseApiRQ.save, _debug, className); + return _handleResponse( + this, response, ParseApiRQ.save, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.save, _debug, className); } @@ -310,7 +312,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Gets a list of all users (limited return) static Future all({bool debug, ParseHTTPClient client}) async { - final ParseUser emptyUser = ParseUser(null, null, null); + final ParseUser emptyUser = _getEmptyUser(); final bool _debug = isDebugEnabled(objectLevelDebug: debug); final ParseHTTPClient _client = client ?? @@ -319,10 +321,10 @@ class ParseUser extends ParseObject implements ParseCloneable { securityContext: ParseCoreData().securityContext); try { - final Response response = - await _client.get('${ParseCoreData().serverUrl}/$path'); + final Uri url = getSanitisedUri(_client, '$path'); + final Response response = await _client.get(url); final ParseResponse parseResponse = handleResponse( - emptyUser, response, ParseApiRQ.getAll, debug, keyClassUser); + emptyUser, response, ParseApiRQ.getAll, _debug, keyClassUser); return parseResponse; } on Exception catch (e) { return handleException(e, ParseApiRQ.getAll, _debug, keyClassUser); @@ -358,8 +360,7 @@ class ParseUser extends ParseObject implements ParseCloneable { ParseCoreData().setSessionId(user.sessionToken); } - if ((parseResponse.statusCode != 200 && - parseResponse.statusCode != 201) || + if ((parseResponse.statusCode != 200 && parseResponse.statusCode != 201) || type == ParseApiRQ.getAll || type == ParseApiRQ.destroy || type == ParseApiRQ.requestPasswordReset || diff --git a/lib/src/utils/parse_encoder.dart b/lib/src/utils/parse_encoder.dart index 2fe2abe4a..600410924 100644 --- a/lib/src/utils/parse_encoder.dart +++ b/lib/src/utils/parse_encoder.dart @@ -12,14 +12,14 @@ dynamic dateTimeEncoder(dynamic item) { dynamic parseEncode(dynamic value, {bool full}) { full ??= false; - if (value is DateTime) { - return _encodeDate(value); - } - if (value is Uint8List) { return _encodeUint8List(value); } + if (value is DateTime) { + return _encodeDate(value); + } + if (value is ParseGeoPoint) { return value; } From 26693889988aa776a26cf181d9ce74dfa6db6950 Mon Sep 17 00:00:00 2001 From: Phill Date: Sun, 17 Mar 2019 22:24:45 +0000 Subject: [PATCH 7/8] Added date formatting Added cURL logging --- example/lib/diet_plan.dart | 2 +- example/lib/main.dart | 3 +- lib/parse_server_sdk.dart | 4 +- lib/src/network/parse_http_client.dart | 34 ++++++++-- lib/src/network/parse_query.dart | 8 --- lib/src/objects/parse_base.dart | 12 ++-- lib/src/objects/parse_object.dart | 10 ++- ...e_utils.dart => parse_response_utils.dart} | 0 lib/src/utils/parse_date_format.dart | 66 +++++++++++++++++++ lib/src/utils/parse_decoder.dart | 2 +- lib/src/utils/parse_encoder.dart | 4 +- lib/src/utils/parse_utils.dart | 2 +- 12 files changed, 118 insertions(+), 29 deletions(-) rename lib/src/objects/response/{response_utils.dart => parse_response_utils.dart} (100%) create mode 100644 lib/src/utils/parse_date_format.dart diff --git a/example/lib/diet_plan.dart b/example/lib/diet_plan.dart index 94f16496f..747bc65bc 100644 --- a/example/lib/diet_plan.dart +++ b/example/lib/diet_plan.dart @@ -3,7 +3,7 @@ import 'dart:core'; import 'package:parse_server_sdk/parse_server_sdk.dart'; class DietPlan extends ParseObject implements ParseCloneable { - DietPlan() : super(_keyTableName); + DietPlan() : super(_keyTableName, debug: true); DietPlan.clone() : this(); /// Looks strangely hacky but due to Flutter not using reflection, we have to diff --git a/example/lib/main.dart b/example/lib/main.dart index b96310655..946941e82 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -131,8 +131,7 @@ class _MyAppState extends State { Future query() async { final QueryBuilder queryBuilder = QueryBuilder(ParseObject('TestObjectForApi')) - ..whereGreaterThan( - keyVarCreatedAt, DateTime.now().subtract(Duration(hours: 1))); + ..whereLessThan(keyVarCreatedAt, DateTime.now()); final ParseResponse apiResponse = await queryBuilder.query(); diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index ab8a14fa3..b0fcda35c 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -16,7 +16,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:uuid/uuid.dart'; import 'package:web_socket_channel/io.dart'; -part 'package:parse_server_sdk/src/objects/response/response_utils.dart'; +part 'package:parse_server_sdk/src/objects/response/parse_response_utils.dart'; part 'package:parse_server_sdk/src/objects/response/parse_error_response.dart'; @@ -72,6 +72,8 @@ part 'src/utils/parse_logger.dart'; part 'src/utils/parse_utils.dart'; +part 'src/utils/parse_date_format.dart'; + class Parse { ParseCoreData data; bool _hasBeenInitialized = false; diff --git a/lib/src/network/parse_http_client.dart b/lib/src/network/parse_http_client.dart index b88fe9183..4604f58e6 100644 --- a/lib/src/network/parse_http_client.dart +++ b/lib/src/network/parse_http_client.dart @@ -2,9 +2,7 @@ part of flutter_parse_sdk; /// Creates a custom version of HTTP Client that has Parse Data Preset class ParseHTTPClient extends BaseClient { - - ParseHTTPClient( - {bool sendSessionId = false, SecurityContext securityContext}) + ParseHTTPClient({bool sendSessionId = false, SecurityContext securityContext}) : _sendSessionId = sendSessionId, _client = securityContext != null ? IOClient(HttpClient(context: securityContext)) @@ -33,9 +31,37 @@ class ParseHTTPClient extends BaseClient { /// 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) => request.headers[key] = value); + additionalHeaders + .forEach((String key, String value) => request.headers[key] = value); + } + + if (data.debug) { + _logging(request); } return _client.send(request); } + + void _logging(BaseRequest request) { + String curlCmd = 'curl'; + curlCmd += ' -X ' + request.method; + bool compressed = false; + request.headers.forEach((String name, String value) { + if (name?.toLowerCase() == 'accept-encoding' && + value?.toLowerCase() == 'gzip') { + compressed = true; + } + curlCmd += ' -H \'$name: $value\''; + }); + if (request.method == 'POST' || request.method == 'PUT') { + if (request is Request) { + final String body = latin1.decode(request.bodyBytes); + curlCmd += ' -d \'$body\''; + } + } + curlCmd += (compressed ? ' --compressed ' : ' ') + request.url.toString(); + print('╭-- cURL'); + print(curlCmd); + print('╰-- (copy and paste the above line to a terminal)'); + } } diff --git a/lib/src/network/parse_query.dart b/lib/src/network/parse_query.dart index 9c8b14092..1d83d3150 100644 --- a/lib/src/network/parse_query.dart +++ b/lib/src/network/parse_query.dart @@ -371,12 +371,4 @@ class QueryBuilder { }); return result; } - - String convertToQueryableFormats(dynamic value) { - if (value is DateTime) { - return value.toIso8601String(); - } - - return value; - } } diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index de56a30c6..55d116aae 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -20,7 +20,7 @@ abstract class ParseBase { DateTime get createdAt { if (get(keyVarCreatedAt) is String) { final String dateAsString = get(keyVarCreatedAt); - return DateTime.parse(dateAsString); + return _parseDateFormat.parse(dateAsString); } else { return get(keyVarCreatedAt); } @@ -30,7 +30,7 @@ abstract class ParseBase { DateTime get updatedAt { if (get(keyVarUpdatedAt) is String) { final String dateAsString = get(keyVarUpdatedAt); - return DateTime.parse(dateAsString); + return _parseDateFormat.parse(dateAsString); } else { return get(keyVarUpdatedAt); } @@ -48,11 +48,11 @@ abstract class ParseBase { } if (createdAt != null) { - map[keyVarCreatedAt] = createdAt.toIso8601String(); + map[keyVarCreatedAt] = _parseDateFormat.format(createdAt); } if (updatedAt != null) { - map[keyVarUpdatedAt] = updatedAt.toIso8601String(); + map[keyVarUpdatedAt] = _parseDateFormat.format(updatedAt); } getObjectData().forEach((String key, dynamic value) { @@ -88,13 +88,13 @@ abstract class ParseBase { objectId = value; } else if (key == keyVarCreatedAt) { if (keyVarCreatedAt is String) { - set(keyVarCreatedAt, DateTime.parse(value)); + set(keyVarCreatedAt, _parseDateFormat.parse(value)); } else { set(keyVarCreatedAt, value); } } else if (key == keyVarUpdatedAt) { if (keyVarUpdatedAt is String) { - set(keyVarUpdatedAt, DateTime.parse(value)); + set(keyVarUpdatedAt, _parseDateFormat.parse(value)); } else { set(keyVarUpdatedAt, value); } diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index e007814f3..a7412e73c 100644 --- a/lib/src/objects/parse_object.dart +++ b/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 = false, ParseHTTPClient client, bool autoSendSessionId}) + {bool debug, ParseHTTPClient client, bool autoSendSessionId}) : super() { setClassName(className); _path = '$keyEndPointClasses$className'; @@ -33,11 +33,15 @@ class ParseObject extends ParseBase implements ParseCloneable { /// Gets an object from the server using it's [String] objectId Future getObject(String objectId) async { try { - String uri = '${ParseCoreData().serverUrl}$_path'; + String uri =_path; + if (objectId != null) { uri += '/$objectId'; } - final Response result = await _client.get(uri); + + final Uri url = getSanitisedUri(_client, '$uri'); + + final Response result = await _client.get(url); return handleResponse(this, result, ParseApiRQ.get, _debug, className); } on Exception catch (e) { return handleException(e, ParseApiRQ.get, _debug, className); diff --git a/lib/src/objects/response/response_utils.dart b/lib/src/objects/response/parse_response_utils.dart similarity index 100% rename from lib/src/objects/response/response_utils.dart rename to lib/src/objects/response/parse_response_utils.dart diff --git a/lib/src/utils/parse_date_format.dart b/lib/src/utils/parse_date_format.dart new file mode 100644 index 000000000..fc394d734 --- /dev/null +++ b/lib/src/utils/parse_date_format.dart @@ -0,0 +1,66 @@ +part of flutter_parse_sdk; + +final _ParseDateFormat _parseDateFormat = _ParseDateFormat._internal(); + +/// This is the currently used date format. It is precise to the millisecond. +class _ParseDateFormat { + _ParseDateFormat._internal(); + + /// Deserialize an ISO-8601 full-precision extended format representation of date string into [DateTime]. + DateTime parse(String strDate) { + try { + return DateTime.parse(strDate); + } on FormatException { + return null; + } + } + + /// Serialize [DateTime] into an ISO-8601 full-precision extended format representation. + String format(DateTime datetime) { + if (!datetime.isUtc) { + datetime = datetime.toUtc(); + } + + final String y = _fourDigits(datetime.year); + final String m = _twoDigits(datetime.month); + final String d = _twoDigits(datetime.day); + final String h = _twoDigits(datetime.hour); + final String min = _twoDigits(datetime.minute); + final String sec = _twoDigits(datetime.second); + final String ms = _threeDigits(datetime.millisecond); + + return '$y-$m-${d}T$h:$min:$sec.${ms}Z'; + } + + static String _fourDigits(int n) { + final int absN = n.abs(); + final String sign = n < 0 ? '-' : ''; + if (absN >= 1000) { + return '$n'; + } + if (absN >= 100) { + return '${sign}0$absN'; + } + if (absN >= 10) { + return '${sign}00$absN'; + } + return '${sign}000$absN'; + } + + static String _threeDigits(int n) { + if (n >= 100) { + return '$n'; + } + if (n >= 10) { + return '0$n'; + } + return '00$n'; + } + + static String _twoDigits(int n) { + if (n >= 10) { + return '$n'; + } + return '0$n'; + } +} \ No newline at end of file diff --git a/lib/src/utils/parse_decoder.dart b/lib/src/utils/parse_decoder.dart index dc348cf45..cff6fcb87 100644 --- a/lib/src/utils/parse_decoder.dart +++ b/lib/src/utils/parse_decoder.dart @@ -53,7 +53,7 @@ dynamic parseDecode(dynamic value) { switch (map['__type']) { case 'Date': final String iso = map['iso']; - return DateTime.parse(iso); + return _parseDateFormat.parse(iso); case 'Bytes': final String val = map['base64']; return base64.decode(val); diff --git a/lib/src/utils/parse_encoder.dart b/lib/src/utils/parse_encoder.dart index 600410924..65b499392 100644 --- a/lib/src/utils/parse_encoder.dart +++ b/lib/src/utils/parse_encoder.dart @@ -3,7 +3,7 @@ part of flutter_parse_sdk; /// Custom encoder for DateTime dynamic dateTimeEncoder(dynamic item) { if (item is DateTime) { - return item.toIso8601String(); + return _parseDateFormat.format(item); } return item; } @@ -44,5 +44,5 @@ Map _encodeUint8List(Uint8List value) { } Map _encodeDate(DateTime date) { - return {'__type': 'Date', 'iso': date.toIso8601String()}; + return {'__type': 'Date', 'iso': _parseDateFormat.format(date)}; } diff --git a/lib/src/utils/parse_utils.dart b/lib/src/utils/parse_utils.dart index 4b00a2a3c..43e80d686 100644 --- a/lib/src/utils/parse_utils.dart +++ b/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 ?? false; + return objectLevelDebug ??= ParseCoreData().debug; } /// Converts the object to the correct value for JSON, From a1017cb49369b8301a62556eb48b38e2b1964f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bj=C3=B8rnbakk?= Date: Mon, 18 Mar 2019 07:37:42 +0100 Subject: [PATCH 8/8] updating path_provider dependency (#121) --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index b23ea471a..af7d53b12 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: # Utils shared_preferences: ^0.5.0 - path_provider: ^0.4.1 + path_provider: ^0.5.0+1 uuid: ^2.0.0 package_info: ^0.4.0 devicelocale: ^0.1.1