Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion content/body.xqm
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,13 @@ function body:get-form-data-value ($name as xs:string, $format as xs:string?) as

declare %private
function body:additional-property ($name as xs:string) as map(*) {
map { $name : request:get-parameter($name, ()) }
(: a repeating field is wrapped in an array - a sequence of more than one
: item cannot be serialized with the JSON output method (err:SERE0023)
: and multi-value parameters are arrays in $request?parameters as well :)
let $values := request:get-parameter($name, ())
return map {
$name : if (count($values) > 1) then array { $values } else $values
}
};

declare %private
Expand All @@ -189,6 +195,10 @@ function body:validate-value ($schema as map(*)) as function(*) {
then error($errors:BAD_REQUEST, 'Property "' || $name || '" is required!')
else if (count($value) > 1 and not($is-array))
then error($errors:BAD_REQUEST, 'Property "' || $name || '" only allows one item. Got ' || count($value), $value)
(: properties declared as type "array" are wrapped like
: parameters:cast-array does for multi-value parameters :)
else if ($is-array and exists($value))
then map:entry($name, array { $value })
else map:entry($name, $value)
}
};
Expand Down
4 changes: 2 additions & 2 deletions doc/file-upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ In order to allow batch uploads only very few modifications to the above example
}
```
2. `<input type="file" multiple="true" />`
3. iterate over all files in the body `for $file in $request?body?file`
3. iterate over all files in the body `for $file in $request?body?file?*` (properties declared as type "array" are array values)
4. return array of uploaded resources in response

```html
Expand Down Expand Up @@ -178,7 +178,7 @@ In order to allow batch uploads only very few modifications to the above example
declare function upload:batch ($request as map(*)) {
let $stored :=
array{
for $file in $request?body?file
for $file in $request?body?file?*
return xmldb:store(
"/db/apps/roasted/uploads", $file?name, $file?data)
}
Expand Down
2 changes: 1 addition & 1 deletion test/app/modules/upload.xqm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ declare function upload:single ($request as map(*)) {
declare function upload:batch ($request as map(*)) {
try {
let $download-links as xs:string+ :=
for $file in $request?body?file
for $file in $request?body?file?*
let $stored := xmldb:store($upload:collection, $file?name, $file?data)
return $upload:download-path || $file?name

Expand Down
36 changes: 36 additions & 0 deletions test/mediatype.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,42 @@ test.
})


describe("with one file posted to the batch route", function () {
let uploadResponse
const data = new FormData()

const fileName = 'only-file.txt'
const fileContent = 'the only text'
data.append('file', fileContent, {
knownLength: fileContent.length,
filename: fileName,
contentType: 'text/plain'
})
const headers = data.getHeaders();

before(function () {
return util.axios.post(
'upload/batch',
data,
{ headers }
)
.then(r => uploadResponse = r)
.catch(e => uploadResponse = e.response )
})
// a property declared as type "array" is an array even for a single value
it("was uploaded", function () {
expect(uploadResponse.status).to.equal(201)
expect(uploadResponse.data.uploaded).to.deep.equal([
downloadApiEndpoint + fileName
])
})
it('can be retrieved', async function () {
const res = await util.axios.get(uploadResponse.data.uploaded[0], { responseType: 'arraybuffer' })
expect(res.status).to.equal(200)
expect(res.data.toString()).to.eql(fileContent, 'File content differs')
})
})

describe("with two files", function () {
let uploadResponse
const data = new FormData()
Expand Down