Skip to content

Commit

Permalink
Merge pull request #35 from shinspiegel/json-body
Browse files Browse the repository at this point in the history
feat: add new method on Request class
  • Loading branch information
ije authored Nov 24, 2020
2 parents 52ed72c + e24ca71 commit 9596ac9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
48 changes: 47 additions & 1 deletion api.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { compress as brotli } from 'https://deno.land/x/[email protected]/mod.ts'
import { FormDataReader } from 'https://deno.land/x/[email protected]/multipart.ts'
import { gzipEncode } from 'https://deno.land/x/[email protected]/mod.ts'
import log from './log.ts'
import { ServerRequest } from './std.ts'
import type { APIRequest } from './types.ts'
import type { APIRequest, FormDataBody } from './types.ts'

export class Request extends ServerRequest implements APIRequest {
#pathname: string
Expand Down Expand Up @@ -84,6 +85,51 @@ export class Request extends ServerRequest implements APIRequest {
await this.send(JSON.stringify(data, replacer, space), 'application/json; charset=utf-8')
}

async decodeBody(type: "text"): Promise<string>
async decodeBody(type: "json"): Promise<any>
async decodeBody(type: "form-data"): Promise<FormDataBody>
async decodeBody(type: string): Promise<any> {
if (type === "text") {
try {
const buff: Uint8Array = await Deno.readAll(this.body);
const encoded = new TextDecoder("utf-8").decode(buff);
return encoded;
} catch (err) {
console.error("Failed to parse the request body.", err);
}
}

if (type === "json") {
try {
const buff: Uint8Array = await Deno.readAll(this.body);
const encoded = new TextDecoder("utf-8").decode(buff);
const json = JSON.parse(encoded);
return json;
} catch (err) {
console.error("Failed to parse the request body.", err);
}
}

if (type === "form-data") {
try {
const boundary = this.headers.get("content-type");

if (!boundary) throw new Error("Failed to get the content-type")

const reader = new FormDataReader(boundary, this.body);
const { fields, files } = await reader.read({ maxSize: 1024 * 1024 * 10 });

return {
get: (key: string) => fields[key],
getFile: (key: string) => files?.find(i => i.name === key)
}

} catch (err) {
console.error("Failed to parse the request form-data", err)
}
}
}

async send(data: string | Uint8Array | ArrayBuffer, contentType?: string): Promise<void> {
if (this.#resp.done) {
log.warn('ServerRequest: repeat respond calls')
Expand Down
23 changes: 23 additions & 0 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export interface APIRequest extends ServerRequest {
send(data: string | Uint8Array | ArrayBuffer, contentType?: string): Promise<void>
/** `json` replies to the request with a json content */
json(data: any): Promise<void>
/** `decodeBody` will return a string, a form-data or any json object */
decodeBody(type: "text"): Promise<string>
decodeBody(type: "json"): Promise<any>
decodeBody(type: "form-data"): Promise<FormDataBody>
}

/**
Expand All @@ -105,3 +109,22 @@ export interface RouterURL {
readonly params: Record<string, string>
readonly query: URLSearchParams
}

/**
* The form data body
*/
export interface FormDataBody {
get(key: string): string
getFile(key: string): FormFile
}

/**
* The form file data
*/
export interface FormFile {
name: string
content: Uint8Array
contentType: string
filename: string
originalName: string
}

0 comments on commit 9596ac9

Please sign in to comment.