Skip to content

Commit

Permalink
feat: add move method to the file instance
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Aug 28, 2019
1 parent eb44f4f commit 81eacb0
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
1 change: 1 addition & 0 deletions adonis-typings/bodyparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,6 @@ declare module '@ioc:Adonis/Addons/BodyParser' {
extname: string,
validated: boolean,
errors: FileUploadError[],
move (location: string, options?: { name?: string, overwrite?: boolean }): Promise<void>
}
}
19 changes: 19 additions & 0 deletions src/Multipart/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

/// <reference path="../../adonis-typings/bodyparser.ts" />

import { join } from 'path'
import { outputFile } from 'fs-extra'
import { Exception } from '@poppinss/utils'

import {
MultipartFileContract,
FileUploadError,
Expand Down Expand Up @@ -90,4 +94,19 @@ export class File implements MultipartFileContract {
public get status (): 'pending' | 'moved' | 'error' {
return this.errors.length ? 'error' : (this.filePath ? 'moved' : 'pending')
}

/**
* Moves the file to a given location. Multiple calls to the `move` method are allowed,
* incase you want to move a file to multiple locations.
*/
public async move (location: string, options?: { name?: string, overwrite?: boolean }): Promise<void> {
if (!this.tmpPath) {
throw new Exception('tmpPath must be set on the file before moving it', 500, 'E_MISSING_FILE_TMP_PATH')
}

options = Object.assign({ name: this.clientName, overwrite: false }, options)

this.filePath = join(location, options!.name!)
await outputFile(this.filePath, { overwrite: options!.overwrite! })
}
}
70 changes: 69 additions & 1 deletion test/body-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { tmpdir } from 'os'
import * as test from 'japa'
import { merge } from 'lodash'
import { createServer } from 'http'
import { pathExists } from 'fs-extra'
import { pathExists, remove } from 'fs-extra'
import * as supertest from 'supertest'
import { Request } from '@poppinss/request'
import { HttpContext as BaseHttpContext } from '@poppinss/http-server'
Expand Down Expand Up @@ -735,4 +735,72 @@ test.group('BodyParser Middleware | multipart', () => {
assert.isTrue(body.isValid)
assert.deepEqual(body.errors, [])
})

test('move file to a given location', async (assert) => {
const uploadsDir = join(__dirname, 'uploads')

const server = createServer(async (req, res) => {
const ctx = HttpContext.create('/', {}, req, res)
const middleware = new BodyParserMiddleware(bodyParserConfig)

await middleware.handle(ctx, async () => {
const pkgFile = ctx.request.file('package')!

try {
await pkgFile.move(uploadsDir)
assert.equal(pkgFile.status, 'moved')
res.writeHead(200, { 'content-type': 'application/json' })
res.end()
} catch (error) {
res.writeHead(500, { 'content-type': 'application/json' })
res.end(error.message)
}
})
})

await supertest(server)
.post('/')
.attach('package', packageFilePath)
.expect(200)

const hasFile = await pathExists(join(uploadsDir, 'package.json'))
assert.isTrue(hasFile)

await remove(uploadsDir)
})

test('move file with custom name', async (assert) => {
const uploadsDir = join(__dirname, 'uploads')

const server = createServer(async (req, res) => {
const ctx = HttpContext.create('/', {}, req, res)
const middleware = new BodyParserMiddleware(bodyParserConfig)

await middleware.handle(ctx, async () => {
const pkgFile = ctx.request.file('package')!

try {
await pkgFile.move(uploadsDir, {
name: `myapp.${pkgFile.subtype}`,
})
assert.equal(pkgFile.status, 'moved')
res.writeHead(200, { 'content-type': 'application/json' })
res.end()
} catch (error) {
res.writeHead(500, { 'content-type': 'application/json' })
res.end(error.message)
}
})
})

await supertest(server)
.post('/')
.attach('package', packageFilePath)
.expect(200)

const hasFile = await pathExists(join(uploadsDir, 'myapp.json'))
assert.isTrue(hasFile)

await remove(uploadsDir)
})
})

0 comments on commit 81eacb0

Please sign in to comment.