Skip to content

Commit a47f2a0

Browse files
authored
fix: ParseXFile uploads file with content-type application/octet-stream if not explicitly set (#1048)
1 parent 4f20640 commit a47f2a0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1854
-624
lines changed

packages/dart/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [8.0.2](https://github.com/parse-community/Parse-SDK-Flutter/compare/dart-8.0.1...dart-8.0.2) (2025-11-28)
2+
3+
### Bug Fixes
4+
5+
* `ParseXFile` uploads file with content-type `application/octet-stream` if not explicitly set ([#1048](https://github.com/parse-community/Parse-SDK-Flutter/pull/1048))
6+
17
## [8.0.1](https://github.com/parse-community/Parse-SDK-Flutter/compare/dart-8.0.0...dart-8.0.1) (2025-11-22)
28

39
### Bug Fixes

packages/dart/example/main.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import 'package:parse_server_sdk/parse_server_sdk.dart';
22

33
Future<void> main() async {
44
// Parse initialize
5-
await Parse().initialize("keyApplicationId", "keyParseServerUrl",
6-
clientKey: "keyParseClientKey",
7-
debug: true,
8-
liveQueryUrl: "keyLiveQueryUrl",
9-
autoSendSessionId: true,
10-
coreStore: CoreStoreMemoryImp());
5+
await Parse().initialize(
6+
"keyApplicationId",
7+
"keyParseServerUrl",
8+
clientKey: "keyParseClientKey",
9+
debug: true,
10+
liveQueryUrl: "keyLiveQueryUrl",
11+
autoSendSessionId: true,
12+
coreStore: CoreStoreMemoryImp(),
13+
);
1114

1215
// Set a ParseObject and save it
1316
var dietPlan = ParseObject('DietPlan')

packages/dart/lib/parse_server_sdk.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,22 +165,27 @@ class Parse {
165165

166166
bool hasParseBeenInitialized() => _hasBeenInitialized;
167167

168-
Future<ParseResponse> healthCheck(
169-
{bool? debug, ParseClient? client, bool? sendSessionIdByDefault}) async {
168+
Future<ParseResponse> healthCheck({
169+
bool? debug,
170+
ParseClient? client,
171+
bool? sendSessionIdByDefault,
172+
}) async {
170173
final bool debugLocal = isDebugEnabled(objectLevelDebug: debug);
171174

172175
final ParseClient clientLocal = client ??
173176
ParseCoreData().clientCreator(
174-
sendSessionId:
175-
sendSessionIdByDefault ?? ParseCoreData().autoSendSessionId,
176-
securityContext: ParseCoreData().securityContext);
177+
sendSessionId:
178+
sendSessionIdByDefault ?? ParseCoreData().autoSendSessionId,
179+
securityContext: ParseCoreData().securityContext,
180+
);
177181

178182
const String className = 'parseBase';
179183
const ParseApiRQ type = ParseApiRQ.healthCheck;
180184

181185
try {
182-
final ParseNetworkResponse response = await clientLocal
183-
.get('${ParseCoreData().serverUrl}$keyEndPointHealth');
186+
final ParseNetworkResponse response = await clientLocal.get(
187+
'${ParseCoreData().serverUrl}$keyEndPointHealth',
188+
);
184189
return handleResponse<Parse>(null, response, type, debugLocal, className);
185190
} on Exception catch (e) {
186191
return handleException(e, type, debugLocal, className);

packages/dart/lib/src/data/parse_core_data.dart

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ class ParseCoreData {
6767
_instance.clientCreator = clientCreator ??
6868
(({required bool sendSessionId, SecurityContext? securityContext}) =>
6969
ParseHTTPClient(
70-
sendSessionId: sendSessionId,
71-
securityContext: securityContext));
70+
sendSessionId: sendSessionId,
71+
securityContext: securityContext,
72+
));
7273
}
7374

7475
String applicationId;
@@ -93,7 +94,9 @@ class ParseCoreData {
9394
late ParseClientCreator clientCreator;
9495

9596
void registerSubClass(
96-
String className, ParseObjectConstructor objectConstructor) {
97+
String className,
98+
ParseObjectConstructor objectConstructor,
99+
) {
97100
_subClassHandler.registerSubClass(className, objectConstructor);
98101
}
99102

@@ -110,10 +113,21 @@ class ParseCoreData {
110113
}
111114

112115
ParseUser createParseUser(
113-
String? username, String? password, String? emailAddress,
114-
{String? sessionToken, bool? debug, ParseClient? client}) {
115-
return _subClassHandler.createParseUser(username, password, emailAddress,
116-
sessionToken: sessionToken, debug: debug, client: client);
116+
String? username,
117+
String? password,
118+
String? emailAddress, {
119+
String? sessionToken,
120+
bool? debug,
121+
ParseClient? client,
122+
}) {
123+
return _subClassHandler.createParseUser(
124+
username,
125+
password,
126+
emailAddress,
127+
sessionToken: sessionToken,
128+
debug: debug,
129+
client: client,
130+
);
117131
}
118132

119133
ParseFileBase createFile({String? url, String? name}) =>

packages/dart/lib/src/data/parse_subclass_handler.dart

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@ part of '../../parse_server_sdk.dart';
22

33
typedef ParseObjectConstructor = ParseObject Function();
44
typedef ParseUserConstructor = ParseUser Function(
5-
String? username, String? password, String? emailAddress,
6-
{String? sessionToken, bool? debug, ParseClient? client});
5+
String? username,
6+
String? password,
7+
String? emailAddress, {
8+
String? sessionToken,
9+
bool? debug,
10+
ParseClient? client,
11+
});
712
typedef ParseFileConstructor = ParseFileBase Function(
813
{String? name, String? url});
914

1015
class ParseSubClassHandler {
11-
ParseSubClassHandler(
12-
{Map<String, ParseObjectConstructor>? registeredSubClassMap,
13-
ParseUserConstructor? parseUserConstructor,
14-
ParseFileConstructor? parseFileConstructor}) {
16+
ParseSubClassHandler({
17+
Map<String, ParseObjectConstructor>? registeredSubClassMap,
18+
ParseUserConstructor? parseUserConstructor,
19+
ParseFileConstructor? parseFileConstructor,
20+
}) {
1521
_subClassMap = registeredSubClassMap ?? <String, ParseObjectConstructor>{};
1622
_parseUserConstructor = parseUserConstructor;
1723
if (parseFileConstructor != null) {
@@ -23,8 +29,10 @@ class ParseSubClassHandler {
2329
ParseUserConstructor? _parseUserConstructor;
2430
ParseFileConstructor _parseFileConstructor = defaultParseFileConstructor;
2531

26-
static ParseFileBase defaultParseFileConstructor(
27-
{String? name, String? url}) {
32+
static ParseFileBase defaultParseFileConstructor({
33+
String? name,
34+
String? url,
35+
}) {
2836
if (parseIsWeb) {
2937
return ParseWebFile(null, name: name!, url: url);
3038
} else {
@@ -33,7 +41,9 @@ class ParseSubClassHandler {
3341
}
3442

3543
void registerSubClass(
36-
String className, ParseObjectConstructor objectConstructor) {
44+
String className,
45+
ParseObjectConstructor objectConstructor,
46+
) {
3747
if (className != keyClassUser &&
3848
className != keyClassInstallation &&
3949
className != keyClassSession &&
@@ -61,13 +71,30 @@ class ParseSubClassHandler {
6171
}
6272

6373
ParseUser createParseUser(
64-
String? username, String? password, String? emailAddress,
65-
{String? sessionToken, bool? debug, ParseClient? client}) {
74+
String? username,
75+
String? password,
76+
String? emailAddress, {
77+
String? sessionToken,
78+
bool? debug,
79+
ParseClient? client,
80+
}) {
6681
return _parseUserConstructor != null
67-
? _parseUserConstructor!(username, password, emailAddress,
68-
sessionToken: sessionToken, debug: debug, client: client)
69-
: ParseUser(username, password, emailAddress,
70-
sessionToken: sessionToken, debug: debug, client: client);
82+
? _parseUserConstructor!(
83+
username,
84+
password,
85+
emailAddress,
86+
sessionToken: sessionToken,
87+
debug: debug,
88+
client: client,
89+
)
90+
: ParseUser(
91+
username,
92+
password,
93+
emailAddress,
94+
sessionToken: sessionToken,
95+
debug: debug,
96+
client: client,
97+
);
7198
}
7299

73100
ParseFileBase createFile({String? name, String? url}) =>

packages/dart/lib/src/enums/parse_enum_api_rq.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ enum ParseApiRQ {
3333
getConfigs,
3434
addConfig,
3535
liveQuery,
36-
batch
36+
batch,
3737
}

packages/dart/lib/src/network/parse_client.dart

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
part of '../../parse_server_sdk.dart';
22

3-
typedef ParseClientCreator = ParseClient Function(
4-
{required bool sendSessionId, SecurityContext? securityContext});
3+
typedef ParseClientCreator = ParseClient Function({
4+
required bool sendSessionId,
5+
SecurityContext? securityContext,
6+
});
57

68
abstract class ParseClient {
79
Future<ParseNetworkResponse> get(
@@ -81,10 +83,7 @@ abstract class ParseClient {
8183
typedef ProgressCallback = void Function(int count, int total);
8284

8385
class ParseNetworkResponse {
84-
ParseNetworkResponse({
85-
required this.data,
86-
this.statusCode = -1,
87-
});
86+
ParseNetworkResponse({required this.data, this.statusCode = -1});
8887

8988
final String data;
9089
final int statusCode;

packages/dart/lib/src/network/parse_connectivity.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ enum ParseConnectivityResult {
99
mobile,
1010

1111
/// None: Device not connected to any network
12-
none
12+
none,
1313
}
1414

1515
abstract class ParseConnectivityProvider {

packages/dart/lib/src/network/parse_dio_client.dart

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ class ParseDioClient extends ParseClient {
5353
cancelToken: cancelToken,
5454
onReceiveProgress: onReceiveProgress,
5555
options: _Options(
56-
headers: options?.headers, responseType: dio.ResponseType.bytes),
56+
headers: options?.headers,
57+
responseType: dio.ResponseType.bytes,
58+
),
5759
);
5860
return ParseNetworkByteResponse(
5961
bytes: dioResponse.data,
@@ -67,14 +69,18 @@ class ParseDioClient extends ParseClient {
6769
);
6870
} else {
6971
return _getOtherCaseErrorForParseNetworkResponse(
70-
error.error.toString());
72+
error.error.toString(),
73+
);
7174
}
7275
}
7376
}
7477

7578
@override
76-
Future<ParseNetworkResponse> put(String path,
77-
{String? data, ParseNetworkOptions? options}) async {
79+
Future<ParseNetworkResponse> put(
80+
String path, {
81+
String? data,
82+
ParseNetworkOptions? options,
83+
}) async {
7884
try {
7985
final dio.Response<String> dioResponse = await _client.put<String>(
8086
path,
@@ -95,8 +101,11 @@ class ParseDioClient extends ParseClient {
95101
}
96102

97103
@override
98-
Future<ParseNetworkResponse> post(String path,
99-
{String? data, ParseNetworkOptions? options}) async {
104+
Future<ParseNetworkResponse> post(
105+
String path, {
106+
String? data,
107+
ParseNetworkOptions? options,
108+
}) async {
100109
try {
101110
final dio.Response<String> dioResponse = await _client.post<String>(
102111
path,
@@ -117,11 +126,13 @@ class ParseDioClient extends ParseClient {
117126
}
118127

119128
@override
120-
Future<ParseNetworkResponse> postBytes(String path,
121-
{Stream<List<int>>? data,
122-
ParseNetworkOptions? options,
123-
ProgressCallback? onSendProgress,
124-
dynamic cancelToken}) async {
129+
Future<ParseNetworkResponse> postBytes(
130+
String path, {
131+
Stream<List<int>>? data,
132+
ParseNetworkOptions? options,
133+
ProgressCallback? onSendProgress,
134+
dynamic cancelToken,
135+
}) async {
125136
try {
126137
final dio.Response<String> dioResponse = await _client.post<String>(
127138
path,
@@ -143,20 +154,24 @@ class ParseDioClient extends ParseClient {
143154
);
144155
} else {
145156
return _getOtherCaseErrorForParseNetworkResponse(
146-
error.error.toString());
157+
error.error.toString(),
158+
);
147159
}
148160
}
149161
}
150162

151163
_getOtherCaseErrorForParseNetworkResponse(String error) {
152164
return ParseNetworkResponse(
153-
data: "{\"code\":${ParseError.otherCause},\"error\":\"$error\"}",
154-
statusCode: ParseError.otherCause);
165+
data: "{\"code\":${ParseError.otherCause},\"error\":\"$error\"}",
166+
statusCode: ParseError.otherCause,
167+
);
155168
}
156169

157170
@override
158-
Future<ParseNetworkResponse> delete(String path,
159-
{ParseNetworkOptions? options}) async {
171+
Future<ParseNetworkResponse> delete(
172+
String path, {
173+
ParseNetworkOptions? options,
174+
}) async {
160175
try {
161176
final dio.Response<String> dioResponse = await _client.delete<String>(
162177
path,
@@ -224,7 +239,8 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio {
224239
/// If developer wants to add custom headers, extend this class and add headers needed.
225240
if (additionalHeaders != null && additionalHeaders!.isNotEmpty) {
226241
additionalHeaders!.forEach(
227-
(String key, String value) => options!.headers![key] = value);
242+
(String key, String value) => options!.headers![key] = value,
243+
);
228244
}
229245

230246
if (parseCoreData.debug) {
@@ -273,11 +289,8 @@ class _ParseDioClient with dio.DioMixin implements dio.Dio {
273289
}
274290

275291
class _Options extends dio.Options {
276-
_Options({
277-
super.headers,
278-
super.responseType,
279-
String? contentType,
280-
}) : super(
292+
_Options({super.headers, super.responseType, String? contentType})
293+
: super(
281294
contentType: contentType ??
282295
(headers ?? <String, dynamic>{})[dio.Headers.contentTypeHeader],
283296
);

0 commit comments

Comments
 (0)