Skip to content

Commit

Permalink
fix for some requests to endpoints implementing upload where field na…
Browse files Browse the repository at this point in the history
…mes contain brackets
  • Loading branch information
pleary committed Nov 22, 2024
1 parent bdc06b9 commit 5095203
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 9 deletions.
18 changes: 14 additions & 4 deletions build/inaturalistjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,23 @@ var iNaturalistAPI = /*#__PURE__*/function () {
key: "multipartBodyForResuest",
value: function multipartBodyForResuest(parameters) {
var body = new LocalFormData();
var bodyContainsObjects = false;
var bodyNeedsMultipart = false;
// Before params get "flattened" extract the fields and encode them as a
// single JSON string, which the server can handle
var fields = parameters.fields;
if (fields) {
body.append("fields", _typeof(fields) === "object" ? JSON.stringify(fields) : fields);
}
// if any of the incoming parameters have brackets, these are requests that
// are expecting an older behavior of inaturalistjs which is to use multipart/form-data
// for all requests that might contain a file. This behavior has since been changed to use
// application/json where possible. For now, have these requests use the previous behavior,
// thus they will need to use a multipart request
Object.keys(parameters).forEach(function (k) {
if (k.match(/\[/)) {
bodyNeedsMultipart = true;
}
});
// multipart requests reference all nested parameter names as strings
// so flatten arrays into "arr[0]" and objects into "obj[prop]"
var params = iNaturalistAPI.flattenMultipartParams(parameters);
Expand All @@ -291,17 +301,17 @@ var iNaturalistAPI = /*#__PURE__*/function () {
// FormData params can include options like file upload sizes
if (params[k] && params[k].type === "custom" && params[k].value) {
body.append(k, params[k].value, params[k].options);
bodyContainsObjects = true;
bodyNeedsMultipart = true;
} else {
if (params[k] !== null && _typeof(params[k]) === "object") {
bodyContainsObjects = true;
bodyNeedsMultipart = true;
}
body.append(k, typeof params[k] === "boolean" ? params[k].toString() : params[k]);
}
});
// there are no parameters with type object, so there are no files in this
// request. Return null as this request does not need to be multipart
if (!bodyContainsObjects) {
if (!bodyNeedsMultipart) {
return null;
}
return body;
Expand Down
18 changes: 14 additions & 4 deletions lib/inaturalist_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,23 @@ const iNaturalistAPI = class iNaturalistAPI {

static multipartBodyForResuest( parameters ) {
const body = new LocalFormData( );
let bodyContainsObjects = false;
let bodyNeedsMultipart = false;
// Before params get "flattened" extract the fields and encode them as a
// single JSON string, which the server can handle
const { fields } = parameters;
if ( fields ) {
body.append( "fields", typeof ( fields ) === "object" ? JSON.stringify( fields ) : fields );
}
// if any of the incoming parameters have brackets, these are requests that
// are expecting an older behavior of inaturalistjs which is to use multipart/form-data
// for all requests that might contain a file. This behavior has since been changed to use
// application/json where possible. For now, have these requests use the previous behavior,
// thus they will need to use a multipart request
Object.keys( parameters ).forEach( k => {
if ( k.match( /\[/ ) ) {
bodyNeedsMultipart = true;
}
} );
// multipart requests reference all nested parameter names as strings
// so flatten arrays into "arr[0]" and objects into "obj[prop]"
const params = iNaturalistAPI.flattenMultipartParams( parameters );
Expand All @@ -210,17 +220,17 @@ const iNaturalistAPI = class iNaturalistAPI {
// FormData params can include options like file upload sizes
if ( params[k] && params[k].type === "custom" && params[k].value ) {
body.append( k, params[k].value, params[k].options );
bodyContainsObjects = true;
bodyNeedsMultipart = true;
} else {
if ( params[k] !== null && typeof ( params[k] ) === "object" ) {
bodyContainsObjects = true;
bodyNeedsMultipart = true;
}
body.append( k, ( typeof params[k] === "boolean" ) ? params[k].toString( ) : params[k] );
}
} );
// there are no parameters with type object, so there are no files in this
// request. Return null as this request does not need to be multipart
if ( !bodyContainsObjects ) {
if ( !bodyNeedsMultipart ) {
return null;
}
return body;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "inaturalistjs",
"version": "2.14.0",
"version": "2.15.0",
"description": "inaturalistjs",
"author": "iNaturalist",
"license": "MIT",
Expand Down
8 changes: 8 additions & 0 deletions test/inaturalist_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ describe( "iNaturalistAPI", ( ) => {
expect( body.constructor.name ).to.eq( "FormData" );
} );

it( "returns FormData if any field names contain brackets", ( ) => {
const requestParameters = {
"field_with[brackets]": true
};
const body = iNaturalistAPI.multipartBodyForResuest( requestParameters );
expect( body.constructor.name ).to.eq( "FormData" );
} );

it( "returns fields as a JSON string", ( ) => {
const fields = {
field1: true,
Expand Down

0 comments on commit 5095203

Please sign in to comment.