Skip to content

This middleware automatically organizes uploads to avoid file system problems and create dirs if not exists, perform validations and optimizes ram usage when uploading big files using Deno standard libraries!

License

Notifications You must be signed in to change notification settings

GuilhermeVendramini/Upload-middleware-for-Oak-Deno-framework

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Upload middleware for Oak Deno framework

This middleware automatically organizes uploads to avoid file system problems and create dirs if not exists, perform validations and optimizes ram usage when uploading large files using Deno standard libraries!

Usage:

Ex:

.post("/upload", upload('uploads'), async (context: any, next: any) => { ...
.post("/upload", upload('uploads', { extensions: ['jpg', 'png'], maxSizeBytes: 20000000, maxFileSizeBytes: 10000000, saveFile: true, readFile: false, useCurrentDir: true, useDateTimeSubDir: true }), async (context: any, next: any) => { ...
.post("/upload", upload('uploads', { extensions: ['jpg', 'png'], useDateTimeSubDir: false }), async (context: any, next: any) => { ...

Uploads will be in context.uploadedFiles;

upload(

path,

extensions: optional ex: ['jpg', 'png'], default allow all - [].

maxSizeBytes: optional, max total size in bytes for all files in form, default unlimited - Number.MAX_SAFE_INTEGER.

maxFileSizeBytes: optional, max size in bytes for each file in form, default unlimited - Number.MAX_SAFE_INTEGER.

saveFile: optional, if false the file will not be saved in the file system, and a temporary file generated by Deno std will returned in 'tempfile' field, default true.

readFile: optional, if true the file will be fully loaded on the ram and a Uint8Array will be returned in the 'data' field, default false.

useCurrentDir: optional, if true the path is relative to current Deno working directory, default true.

useDateTimeSubDir: optional, if true the file path will be prefixed with /year/month/day/hour/minute/second/uuid/filename e.g. /2020/4/4/20/0/28/1350065e-7053-429b-869b-08008a098b23/test.jpg, default true.

), next middlewares ...

Request must contains a body with form type "multipart/form-data", and inputs with type="file".

Ex:

.post("/pre_upload", preUploadValidate(["jpg", "png"], 20000000, 10000000), async (context: any, next: any) => { ...

preUploadValidate(

extensions: optional ex: ['jpg', 'png'], default allow all - [],

maxSizeBytes: optional, max total size in bytes for all files in form, default unlimited - Number.MAX_SAFE_INTEGER,

maxFileSizeBytes: optional, max size in bytes for each file in form, default unlimited - Number.MAX_SAFE_INTEGER

), next middlewares ...

This middleware does a pre-validation before sending the form, for optimizations. To use it, send a JSON containing the objects "file". Use a different route than the upload route. Returns a validation message with all errors and status 422 (if there are errors).

Examples:

Below an example to work with AJAX, also accepting type="file" multiple:

var files = document.querySelector('#yourFormId input[type=file]').files
var name = document.querySelector('#yourFormId input[type=file]').getAttribute('name');

var form = new FormData();
for(var i=0;i<files.length;i++){
	form.append(`${name}_${i}`, files[i]);	
}
var res = await fetch('/upload', { //Fetch API automatically puts the form in the format "multipart/form-data".
	method: 'POST',
	body: form,
}).then(response=>response.json())
console.log(res)

//VALIDATIONS --------------

var validationData = {}
for(var i=0;i<files.length;i++){
	var newObj = { //newObj is needed, JSON.stringify(files[i]) not work
	   'name'             : files[i].name,
	   'size'             : files[i].size
	}; 
	validationData[`${name}_${i}`] = newObj;
}
var validations = await fetch('/pre_upload', {
	method: 'POST',
	headers: {'Content-Type': 'application/json'},
	body: JSON.stringify(validationData),
}).then(response=>response.json())
console.log(validations)

In Deno:

import { upload, preUploadValidate} from "https://deno.land/x/upload_middleware_for_oak_framework/mod.ts";

  .post("/upload", upload('uploads', { extensions: ['jpg', 'png'], maxSizeBytes: 20000000, maxFileSizeBytes: 10000000 }),
    async (context: any, next: any) => {
      context.response.body = context.uploadedFiles;
    },
  )
  .post("/pre_upload", preUploadValidate(["jpg", "png"], 20000000, 10000000),
    async (context: any, next: any) => {
      context.response.body = { msg: "Pass upload validations." };
    },
  )
  .get("/", async (context: any, next: any) => {
    context.response.body = `
            <form id="yourFormId" enctype="multipart/form-data" action="/upload" method="post">
              <input type="file" name="file1" multiple><br>
              <input type="submit" value="Submit">
            </form>
    `;
  })
  //This will return something like:
{
	"file1_0":{
		"filename":"test.jpg",
		"type":"image/jpeg",
		"size":16980,
		"id":"2020/4/4/20/0/28/1350065e-7053-429b-869b-08008a098b23",
		"url":"uploads/2020/4/4/20/0/28/1350065e-7053-429b-869b-08008a098b23/test.jpg",
		"uri":"C:\\Users\\Engenharia\\Documents\\base\\uploads\\2020\\4\\4\\20\\0\\28\\1350065e-7053-429b-869b-08008a098b23\\test.jpg"
	},
	"file1_1":{
		"filename":"download.png",
		"type":"image/png",
		"size":2623,
		"id":"2020/4/4/20/0/28/46698b10-d319-4bbb-af64-fc8b2b991b54",
		"url":"uploads/2020/4/4/20/0/28/46698b10-d319-4bbb-af64-fc8b2b991b54/download.png",
		"uri":"C:\\Users\\Engenharia\\Documents\\base\\uploads\\2020\\4\\4\\20\\0\\28\\46698b10-d319-4bbb-af64-fc8b2b991b54\\download.png"
	}
}

If you want, you can delete a file sent using:

await Deno.remove(context.uploadedFiles['file2']['uri']);

Or (if not save file):

await Deno.remove(context.uploadedFiles['file2']['tempfile']);

Remember that you need permissions:

deno run --allow-net --allow-read --allow-write ./server.ts

About

This middleware automatically organizes uploads to avoid file system problems and create dirs if not exists, perform validations and optimizes ram usage when uploading big files using Deno standard libraries!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 100.0%