Skip to content

Commit

Permalink
Upload API
Browse files Browse the repository at this point in the history
  • Loading branch information
cabraviva committed Apr 24, 2023
1 parent f5aa205 commit 9d4328f
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 20 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.dccache
testf.txt

# Logs
logs
Expand Down
8 changes: 3 additions & 5 deletions TODOs.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
- [ ] Tests
- [ ] Test Coverage
- [X] GET
- [X] HEAD
- [X] OPTIONS
- [X] PUT
- [X] POST
- [X] DELETE
- [X] PATCH
- [ ] optional errors
- [ ] upload api (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestUpload)
- [ ] FormData (https://developer.mozilla.org/en-US/docs/Web/API/FormData)
- [X] upload api (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestUpload)
- [X] FormData (https://developer.mozilla.org/en-US/docs/Web/API/FormData)
- [ ] Fetch support
- [ ] Data (req.body)
- [X] Data (req.body)
- [ ] options.easyMode -> doesn't pretend to be a primitive
51 changes: 51 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,29 @@ interface RequestOptions {
username?: string | null,
password?: string | null
},

/**
* Here you can optionally provide event handlers fo file uploads
*/
upload?: {
/**
* An event handler function which is called at the beginning of a file upload
* @param total Total file size in bytes
*/
start?(total: number): void,
/**
* An event handler function which is called everytime upload progress was made
* @param percentage A number between 0 and 1 indicating how much progress was already made
* @param loaded Already uploaded bytes
* @param total Total file size in bytes
*/
progress?(percentage: number, loaded: number, total: number): void,
/**
* An event handler function which is called at the end of a file upload
* @param success Indicates whether the upload was sucessful or not
*/
end?(success: boolean): void
}
}

type HTTPMethod = 'GET' | 'POST' | 'HEAD' | 'OPTIONS' | 'PUT' | 'DELETE' | 'PATCH' | 'CONNECT' | 'TRACE'
Expand Down Expand Up @@ -370,6 +393,34 @@ type HTTPMethod = 'GET' | 'POST' | 'HEAD' | 'OPTIONS' | 'PUT' | 'DELETE' | 'PATC
resolve(response)
})

// Upload API
if (typeof options.upload === 'object') {
if (typeof options.upload.start === 'function') {
xhr.upload.addEventListener('loadstart', (ev) => {
if (ev.lengthComputable) {
// @ts-expect-error: No it's not
options.upload.start(ev.total)
}
})
}

if (typeof options.upload.progress === 'function') {
xhr.upload.addEventListener('progress', (ev) => {
if (ev.lengthComputable) {
// @ts-expect-error: No it's not
options.upload.progress(ev.loaded / ev.total, ev.loaded, ev.total)
}
})
}

if (typeof options.upload.end === 'function') {
xhr.upload.addEventListener('loadend', (ev) => {
// @ts-expect-error: No it's not
options.upload.end(ev.loaded !== 0)
})
}
}

// Open request
xhr.open(method, url, true)

Expand Down
9 changes: 6 additions & 3 deletions test/endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,16 @@ export default function applyRoutes(app, fn = () => {}) {

fstream.on('close', () => {
console.log('Uploaded file')
const fcontent = fs.readFileSync(path.join(__dirname, 'file.txt'), {
encoding: 'utf8'
})
fs.rmSync(path.join(__dirname, 'file.txt'))
res.json(fcontent.includes('TRUE'))
})
})

req.busboy.on('finish', () => {
const fcontent = fs.readFileSync(path.join(__dirname, 'file.txt')).toString('utf8')
fs.rmSync(path.join(__dirname, 'file.txt'))
res.json(fcontent.includes('TRUE'))

})

req.pipe(req.busboy)
Expand Down
45 changes: 34 additions & 11 deletions test/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ <h2 id="teststat"></h2>

<script src="./test-engine.js"></script>

<form>
<input type="file" name="file" id="file">
</form>

<script type="module">
import * as knorryObj from './knorry.js'
import { get, defineKnorryOptions, post, useFetch, put, head, del, options, patch } from './knorry.js'
Expand Down Expand Up @@ -252,20 +256,39 @@ <h2 id="teststat"></h2>
})).worked === 'true'
}).as('.post() with implicit FormData()')
// TODO: Test file upload using formData
/*
Like this i guess?!
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
setTimeout(async () => {
expect(async () => {
const formData = new FormData()
formData.append('file', document.querySelector('input[name="file"]').files[0])
const result = (await post('/upload-file', formData)).$plain()

expect(async () => {
const formData = new FormData()
formData.append('file', document.querySelector('input[name="file"]').files[0])
let sfc = false
let pfc = false
let efc = false

await page.goto('http://example.com');
const req = await post('/upload-file', formData, {
upload: {
start: (totalFileSize) => {
sfc = !!totalFileSize
},
progress: (percentage, loaded, total) => {
pfc = percentage > 0.1
},
end: (success) => {
efc = success
}
}
})

const fileInput = await page.$('input[type="file"]');
await fileInput.uploadFile('/path/to/testf.txt');
return req.$plain() && sfc && pfc && efc
}).as('FormData File upload with Upload Features')

await browser.close();
})();
*/
return result
}).as('FormData File upload')
}, 1000)
}, 3000)
</script>
</body>
Expand Down
2 changes: 2 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ app.listen(4560, async () => {
})
const page = await browser.newPage()
await page.goto(`http://localhost:4560`)
const fileInput = await page.$('input[type="file"]')
await fileInput.uploadFile(path.join(__dirname, '..', 'testf.txt'))

global.printFullLogs = async () => {
console.log(chalk.cyan('Full log:'))
Expand Down
1 change: 1 addition & 0 deletions testf.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!TRUE!TEST!

0 comments on commit 9d4328f

Please sign in to comment.