diff --git a/.gitignore b/.gitignore index 08a5e7b..a0553cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .dccache -testf.txt # Logs logs diff --git a/TODOs.md b/TODOs.md index 95df7fe..fbbbf96 100644 --- a/TODOs.md +++ b/TODOs.md @@ -1,5 +1,4 @@ - [ ] Tests -- [ ] Test Coverage - [X] GET - [X] HEAD - [X] OPTIONS @@ -7,9 +6,8 @@ - [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 \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 610ab7b..223d0db 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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' @@ -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) diff --git a/test/endpoints.js b/test/endpoints.js index 3e9943e..677e28b 100644 --- a/test/endpoints.js +++ b/test/endpoints.js @@ -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) diff --git a/test/test.html b/test/test.html index 1bc9076..a5e6e97 100644 --- a/test/test.html +++ b/test/test.html @@ -20,6 +20,10 @@

+
+ +
+ diff --git a/test/test.js b/test/test.js index 3035e4b..8fb8bcf 100644 --- a/test/test.js +++ b/test/test.js @@ -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:')) diff --git a/testf.txt b/testf.txt new file mode 100644 index 0000000..4a94e07 --- /dev/null +++ b/testf.txt @@ -0,0 +1 @@ +!TRUE!TEST! \ No newline at end of file