From 3c9c10e5fb905c20c81302bf4a9213640203d8e9 Mon Sep 17 00:00:00 2001 From: Julien Elbaz Date: Fri, 22 Sep 2017 08:18:53 +0200 Subject: [PATCH] :factory: Add headers/content/body methods and better options type. --- README.md | 32 ++++++++++++++++++++++++-- dist/bundle/wretch.js | 2 +- dist/bundle/wretch.js.map | 2 +- dist/index.d.ts | 2 +- dist/index.js.map | 2 +- dist/wretcher.d.ts | 29 ++++++++++++++++++----- dist/wretcher.js | 29 +++++++++++++++++++---- dist/wretcher.js.map | 2 +- src/index.ts | 2 +- src/wretcher.ts | 48 ++++++++++++++++++++++++++------------- test/mock.js | 8 +++++++ test/test.js | 6 +++++ 12 files changed, 130 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 052b03b..b2e836a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Coverage Status

- A tiny (< 1.3Kb g-zipped) wrapper built around fetch with an intuitive syntax. + A tiny (< 1.4Kb g-zipped) wrapper built around fetch with an intuitive syntax.

f[ETCH] [WR]apper @@ -308,7 +308,19 @@ w = w.query({ c: 3, d : [4, 5] }) // url is now http://example.com?c=3&d=4&d=5 ``` -#### accept(what: string) +#### headers(headerValues: { [headerName: string]: any }) + +Set request headers. + +```js +wretch("...") + .headers({ "Content-Type": "text/plain", Accept: "application/json" }) + .body("my text") + .post() + .json() +``` + +#### accept(headerValue: string) Shortcut to set the "Accept" header. @@ -316,10 +328,26 @@ Shortcut to set the "Accept" header. wretch("...").accept("application/json") ``` +#### content(headerValue: string) + +Shortcut to set the "Content-Type" header. + +```js +wretch("...").content("application/json") +``` + ## Body Types *A body type is only needed when performing put/patch/post requests with a body.* +#### body(contents: any) { + +Set the request body with any content. + +```js +wretch("...").body("hello").put() +``` + #### json(jsObject: Object) Sets the content type header, stringifies an object and sets the request body. diff --git a/dist/bundle/wretch.js b/dist/bundle/wretch.js index 6ac4212..bfca7b2 100644 --- a/dist/bundle/wretch.js +++ b/dist/bundle/wretch.js @@ -1,2 +1,2 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):t.wretch=r()}(this,function(){"use strict";const t=Object.assign||function(t){for(var r,n=1;n (opts = {}) => {\n const req = fetch(url, mix(conf.defaults, opts))\n const wrapper: Promise = req.then(response => {\n if (!response.ok) {\n return response[conf.errorType || \"text\"]().then(_ => {\n const err = new Error(_)\n err[conf.errorType] = _\n err[\"status\"] = response.status\n err[\"response\"] = response\n throw err\n })\n }\n return response\n })\n\n type TypeParser = (funName: string | null) => (cb?: (type: Type) => Result) => Promise\n\n const catchers = []\n const doCatch = (promise: Promise): Promise =>\n catchers.reduce((accumulator, catcher) => accumulator.catch(catcher), promise)\n const wrapTypeParser: TypeParser = (funName) => (cb) => funName ?\n doCatch(wrapper.then(_ => _ && _[funName]()).then(_ => _ && cb && cb(_) || _)) :\n doCatch(wrapper.then(_ => _ && cb && cb(_) || _))\n\n const responseTypes: {\n res: (cb?: (type: void) => Result) => Promise,\n json: (cb?: (type: {[key: string]: any}) => Result) => Promise,\n blob: (cb?: (type: Blob) => Result) => Promise,\n formData: (cb?: (type: FormData) => Result) => Promise,\n arrayBuffer: (cb?: (type: ArrayBuffer) => Result) => Promise,\n text: (cb?: (type: string) => Result) => Promise,\n error: (code: number, cb: any) => typeof responseTypes,\n badRequest: (cb: (error: WretcherError) => void) => typeof responseTypes,\n unauthorized: (cb: (error: WretcherError) => void) => typeof responseTypes,\n forbidden: (cb: (error: WretcherError) => void) => typeof responseTypes,\n notFound: (cb: (error: WretcherError) => void) => typeof responseTypes,\n timeout: (cb: (error: WretcherError) => void) => typeof responseTypes,\n internalError: (cb: (error: WretcherError) => void) => typeof responseTypes\n } = {\n /**\n * Retrieves the raw result as a promise.\n */\n res: wrapTypeParser(null),\n /**\n * Retrieves the result as a parsed JSON object.\n */\n json: wrapTypeParser(\"json\"),\n /**\n * Retrieves the result as a Blob object.\n */\n blob: wrapTypeParser(\"blob\"),\n /**\n * Retrieves the result as a FormData object.\n */\n formData: wrapTypeParser(\"formData\"),\n /**\n * Retrieves the result as an ArrayBuffer object.\n */\n arrayBuffer: wrapTypeParser(\"arrayBuffer\"),\n /**\n * Retrieves the result as a string.\n */\n text: wrapTypeParser(\"text\"),\n /**\n * Catches an http response with a specific error code and performs a callback.\n */\n error(code: number, cb) {\n catchers.push(err => {\n if(err.status === code) cb(err)\n else throw err\n })\n return responseTypes\n },\n /**\n * Catches a bad request (http code 400) and performs a callback.\n */\n badRequest: cb => responseTypes.error(400, cb),\n /**\n * Catches an unauthorized request (http code 401) and performs a callback.\n */\n unauthorized: cb => responseTypes.error(401, cb),\n /**\n * Catches a forbidden request (http code 403) and performs a callback.\n */\n forbidden: cb => responseTypes.error(403, cb),\n /**\n * Catches a \"not found\" request (http code 404) and performs a callback.\n */\n notFound: cb => responseTypes.error(404, cb),\n /**\n * Catches a timeout (http code 408) and performs a callback.\n */\n timeout: cb => responseTypes.error(408, cb),\n /**\n * Catches an internal server error (http code 500) and performs a callback.\n */\n internalError: cb => responseTypes.error(500, cb)\n }\n\n return responseTypes\n}\n","import { mix } from \"./mix\"\nimport conf from \"./config\"\nimport { resolver } from \"./resolver\"\n\n/**\n * The Wretcher class used to perform easy fetch requests.\n *\n * Immutability : almost every method of this class return a fresh Wretcher object.\n */\nexport class Wretcher {\n\n constructor(\n private _url: string,\n private _options = {}) {}\n\n /**\n * Sets the default fetch options used for every subsequent fetch call.\n * @param opts New default options\n */\n defaults(opts: object) {\n conf.defaults = opts\n return this\n }\n\n /**\n * Mixins the default fetch options used for every subsequent fetch calls.\n * @param opts Options to mixin with the current default options\n */\n mixdefaults(opts: object) {\n conf.defaults = mix(conf.defaults, opts)\n return this\n }\n\n /**\n * Sets the method (text, json ...) used to parse the data contained in the response body in case of an HTTP error.\n *\n * Persists for every subsequent requests.\n *\n * Default is \"text\".\n */\n errorType(method: \"text\" | \"json\") {\n conf.errorType = method\n return this\n }\n\n /**\n * Returns a new Wretcher object with the url specified and the same options.\n * @param url String url\n */\n url(url: string) {\n return new Wretcher(url, this._options)\n }\n\n /**\n * Returns a wretch factory which, when called, creates a new Wretcher object with the base url as an url prefix.\n * @param baseurl The base url\n */\n baseUrl(baseurl: string) {\n return (url = \"\", opts = {}) => new Wretcher(baseurl + url, opts)\n }\n\n /**\n * Returns a new Wretcher object with the same url and new options.\n * @param options New options\n */\n options(options: object) {\n return new Wretcher(this._url, options)\n }\n\n /**\n * Converts a javascript object to query parameters,\n * then appends this query string to the current url.\n *\n * ```\n * let w = wretch(\"http://example.com\") // url is http://example.com\n * w = w.query({ a: 1, b : 2 }) // url is now http://example.com?a=1&b=2\n * ```\n *\n * @param qp An object which will be converted.\n */\n query(qp: object) {\n return new Wretcher(appendQueryParams(this._url, qp), this._options)\n }\n\n /**\n * Shortcut to set the \"Accept\" header.\n * @param what Header value\n */\n accept(what: string) {\n return new Wretcher(this._url, mix(this._options, { headers: { Accept : what }}))\n }\n\n /**\n * Performs a get request.\n */\n get(opts = {}) {\n return resolver(this._url)(mix(opts, this._options))\n }\n /**\n * Performs a delete request.\n */\n delete(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"DELETE\" })\n }\n /**\n * Performs a put request.\n */\n put(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"PUT\" })\n }\n /**\n * Performs a post request.\n */\n post(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"POST\" })\n }\n /**\n * Performs a patch request.\n */\n patch(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"PATCH\" })\n }\n\n /**\n * Sets the content type header, stringifies an object and sets the request body.\n * @param jsObject An object\n */\n json(jsObject: object) {\n return new Wretcher(this._url, {\n ...this._options,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(jsObject)\n })\n }\n /**\n * Converts the javascript object to a FormData and sets the request body.\n * @param formObject An object\n */\n formData(formObject: object) {\n const formData = new FormData()\n for(const key in formObject) {\n if(formObject[key] instanceof Array) {\n for(const item of formObject[key])\n formData.append(key + \"[]\", item)\n } else {\n formData.append(key, formObject[key])\n }\n }\n\n return new Wretcher(this._url, {\n ...this._options,\n body: formData\n })\n }\n}\n\n// Internal helpers\n\nconst appendQueryParams = (url: string, qp: object) => {\n const usp = new URLSearchParams()\n const index = url.indexOf(\"?\")\n for(const key in qp) {\n if(qp[key] instanceof Array) {\n for(const val of qp[key])\n usp.append(key, val)\n } else {\n usp.append(key, qp[key])\n }\n }\n return ~index ?\n `${url.substring(0, index)}?${usp.toString()}` :\n `${url}?${usp.toString()}`\n}\n","import { Wretcher } from \"./wretcher\"\n\n// URLSearchParams for node.js\ndeclare const global\ndeclare const require\nif(typeof self === \"undefined\") {\n global.URLSearchParams = require(\"url\").URLSearchParams\n}\n\n/**\n * Return a fresh Wretcher instance.\n */\nexport default (url = \"\", opts = {}) => new Wretcher(url, opts)\n"],"names":["mix","one","two","mergeArrays","clone","prop","hasOwnProperty","Array","defaults","errorType","resolver","url","opts","wrapper","fetch","conf","then","response","ok","_","err","Error","status","catchers","doCatch","promise","reduce","accumulator","catcher","catch","wrapTypeParser","funName","cb","responseTypes","res","json","blob","formData","arrayBuffer","text","error","code","push","badRequest","unauthorized","forbidden","notFound","timeout","internalError","_url","_options","this","Wretcher","method","baseurl","options","qp","appendQueryParams","what","headers","Accept","jsObject","Content-Type","body","JSON","stringify","formObject","FormData","key","_a","_i","item","append","usp","URLSearchParams","index","indexOf","val","substring","toString","self","global","require"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"wretch.js","sources":["../../src/mix.ts","../../src/config.ts","../../src/resolver.ts","../../src/wretcher.ts","../../src/index.ts"],"sourcesContent":["export const mix = function(one: object, two: object, mergeArrays: boolean = false) {\n if(!one || !two || typeof one !== \"object\" || typeof two !== \"object\")\n return one\n\n const clone = { ...one, ...two }\n for(const prop in two) {\n if(two.hasOwnProperty(prop)) {\n if(two[prop] instanceof Array && one[prop] instanceof Array) {\n clone[prop] = mergeArrays ? [ ...one[prop], ...two[prop] ] : two[prop]\n } else if(typeof two[prop] === \"object\" && typeof one[prop] === \"object\") {\n clone[prop] = mix(one[prop], two[prop], mergeArrays)\n }\n }\n }\n\n return clone\n}\n","export default {\n // Default options\n defaults: {},\n // Error type\n errorType: null\n}\n","import { mix } from \"./mix\"\nimport conf from \"./config\"\n\nexport type WretcherError = Error & { status: number, response: Response, text?: string, json?: any }\n\nexport const resolver = url => (opts = {}) => {\n const req = fetch(url, mix(conf.defaults, opts))\n const wrapper: Promise = req.then(response => {\n if (!response.ok) {\n return response[conf.errorType || \"text\"]().then(_ => {\n const err = new Error(_)\n err[conf.errorType] = _\n err[\"status\"] = response.status\n err[\"response\"] = response\n throw err\n })\n }\n return response\n })\n\n type TypeParser = (funName: string | null) => (cb?: (type: Type) => Result) => Promise\n\n const catchers = []\n const doCatch = (promise: Promise): Promise =>\n catchers.reduce((accumulator, catcher) => accumulator.catch(catcher), promise)\n const wrapTypeParser: TypeParser = (funName) => (cb) => funName ?\n doCatch(wrapper.then(_ => _ && _[funName]()).then(_ => _ && cb && cb(_) || _)) :\n doCatch(wrapper.then(_ => _ && cb && cb(_) || _))\n\n const responseTypes: {\n res: (cb?: (type: void) => Result) => Promise,\n json: (cb?: (type: {[key: string]: any}) => Result) => Promise,\n blob: (cb?: (type: Blob) => Result) => Promise,\n formData: (cb?: (type: FormData) => Result) => Promise,\n arrayBuffer: (cb?: (type: ArrayBuffer) => Result) => Promise,\n text: (cb?: (type: string) => Result) => Promise,\n error: (code: number, cb: any) => typeof responseTypes,\n badRequest: (cb: (error: WretcherError) => void) => typeof responseTypes,\n unauthorized: (cb: (error: WretcherError) => void) => typeof responseTypes,\n forbidden: (cb: (error: WretcherError) => void) => typeof responseTypes,\n notFound: (cb: (error: WretcherError) => void) => typeof responseTypes,\n timeout: (cb: (error: WretcherError) => void) => typeof responseTypes,\n internalError: (cb: (error: WretcherError) => void) => typeof responseTypes\n } = {\n /**\n * Retrieves the raw result as a promise.\n */\n res: wrapTypeParser(null),\n /**\n * Retrieves the result as a parsed JSON object.\n */\n json: wrapTypeParser(\"json\"),\n /**\n * Retrieves the result as a Blob object.\n */\n blob: wrapTypeParser(\"blob\"),\n /**\n * Retrieves the result as a FormData object.\n */\n formData: wrapTypeParser(\"formData\"),\n /**\n * Retrieves the result as an ArrayBuffer object.\n */\n arrayBuffer: wrapTypeParser(\"arrayBuffer\"),\n /**\n * Retrieves the result as a string.\n */\n text: wrapTypeParser(\"text\"),\n /**\n * Catches an http response with a specific error code and performs a callback.\n */\n error(code: number, cb) {\n catchers.push(err => {\n if(err.status === code) cb(err)\n else throw err\n })\n return responseTypes\n },\n /**\n * Catches a bad request (http code 400) and performs a callback.\n */\n badRequest: cb => responseTypes.error(400, cb),\n /**\n * Catches an unauthorized request (http code 401) and performs a callback.\n */\n unauthorized: cb => responseTypes.error(401, cb),\n /**\n * Catches a forbidden request (http code 403) and performs a callback.\n */\n forbidden: cb => responseTypes.error(403, cb),\n /**\n * Catches a \"not found\" request (http code 404) and performs a callback.\n */\n notFound: cb => responseTypes.error(404, cb),\n /**\n * Catches a timeout (http code 408) and performs a callback.\n */\n timeout: cb => responseTypes.error(408, cb),\n /**\n * Catches an internal server error (http code 500) and performs a callback.\n */\n internalError: cb => responseTypes.error(500, cb)\n }\n\n return responseTypes\n}\n","import { mix } from \"./mix\"\nimport conf from \"./config\"\nimport { resolver } from \"./resolver\"\n\n/**\n * The Wretcher class used to perform easy fetch requests.\n *\n * Immutability : almost every method of this class return a fresh Wretcher object.\n */\nexport class Wretcher {\n\n constructor(\n private _url: string,\n private _options: RequestInit = {}) {}\n\n /**\n * Sets the default fetch options used for every subsequent fetch call.\n * @param opts New default options\n */\n defaults(opts: RequestInit) {\n conf.defaults = opts\n return this\n }\n\n /**\n * Mixins the default fetch options used for every subsequent fetch calls.\n * @param opts Options to mixin with the current default options\n */\n mixdefaults(opts: RequestInit) {\n conf.defaults = mix(conf.defaults, opts)\n return this\n }\n\n /**\n * Sets the method (text, json ...) used to parse the data contained in the response body in case of an HTTP error.\n *\n * Persists for every subsequent requests.\n *\n * Default is \"text\".\n */\n errorType(method: \"text\" | \"json\") {\n conf.errorType = method\n return this\n }\n\n /**\n * Returns a new Wretcher object with the url specified and the same options.\n * @param url String url\n */\n url(url: string) {\n return new Wretcher(url, this._options)\n }\n\n /**\n * Returns a wretch factory which, when called, creates a new Wretcher object with the base url as an url prefix.\n * @param baseurl The base url\n */\n baseUrl(baseurl: string) {\n return (url = \"\", opts: RequestInit = {}) => new Wretcher(baseurl + url, opts)\n }\n\n /**\n * Returns a new Wretcher object with the same url and new options.\n * @param options New options\n */\n options(options: RequestInit) {\n return new Wretcher(this._url, options)\n }\n\n /**\n * Converts a javascript object to query parameters,\n * then appends this query string to the current url.\n *\n * ```\n * let w = wretch(\"http://example.com\") // url is http://example.com\n * w = w.query({ a: 1, b : 2 }) // url is now http://example.com?a=1&b=2\n * ```\n *\n * @param qp An object which will be converted.\n */\n query(qp: object) {\n return new Wretcher(appendQueryParams(this._url, qp), this._options)\n }\n\n /**\n * Set request headers.\n * @param headerValues An object containing header key and values\n */\n headers(headerValues: { [headerName: string]: any }) {\n return new Wretcher(this._url, mix(this._options, { headers: headerValues }))\n }\n\n /**\n * Shortcut to set the \"Accept\" header.\n * @param what Header value\n */\n accept(headerValue: string) {\n return this.headers({ Accept : headerValue })\n }\n\n /**\n * Shortcut to set the \"Content-Type\" header.\n * @param what Header value\n */\n content(headerValue: string) {\n return this.headers({ \"Content-Type\" : headerValue })\n }\n\n /**\n * Performs a get request.\n */\n get(opts = {}) {\n return resolver(this._url)(mix(opts, this._options))\n }\n /**\n * Performs a delete request.\n */\n delete(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"DELETE\" })\n }\n /**\n * Performs a put request.\n */\n put(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"PUT\" })\n }\n /**\n * Performs a post request.\n */\n post(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"POST\" })\n }\n /**\n * Performs a patch request.\n */\n patch(opts = {}) {\n return resolver(this._url)({ ...mix(opts, this._options), method: \"PATCH\" })\n }\n\n /**\n * Sets the request body with any content.\n * @param contents The body contents\n */\n body(contents: any) {\n return new Wretcher(this._url, { ...this._options, body: contents })\n }\n /**\n * Sets the content type header, stringifies an object and sets the request body.\n * @param jsObject An object\n */\n json(jsObject: object) {\n return this.content(\"application/json\").body(JSON.stringify(jsObject))\n }\n /**\n * Converts the javascript object to a FormData and sets the request body.\n * @param formObject An object\n */\n formData(formObject: object) {\n const formData = new FormData()\n for(const key in formObject) {\n if(formObject[key] instanceof Array) {\n for(const item of formObject[key])\n formData.append(key + \"[]\", item)\n } else {\n formData.append(key, formObject[key])\n }\n }\n\n return this.body(formData)\n }\n}\n\n// Internal helpers\n\nconst appendQueryParams = (url: string, qp: object) => {\n const usp = new URLSearchParams()\n const index = url.indexOf(\"?\")\n for(const key in qp) {\n if(qp[key] instanceof Array) {\n for(const val of qp[key])\n usp.append(key, val)\n } else {\n usp.append(key, qp[key])\n }\n }\n return ~index ?\n `${url.substring(0, index)}?${usp.toString()}` :\n `${url}?${usp.toString()}`\n}\n","import { Wretcher } from \"./wretcher\"\n\n// URLSearchParams for node.js\ndeclare const global\ndeclare const require\nif(typeof self === \"undefined\") {\n global.URLSearchParams = require(\"url\").URLSearchParams\n}\n\n/**\n * Return a fresh Wretcher instance.\n */\nexport default (url = \"\", opts: RequestInit = {}) => new Wretcher(url, opts)\n"],"names":["mix","one","two","mergeArrays","clone","prop","hasOwnProperty","Array","defaults","errorType","resolver","url","opts","wrapper","fetch","conf","then","response","ok","_","err","Error","status","catchers","doCatch","promise","reduce","accumulator","catcher","catch","wrapTypeParser","funName","cb","responseTypes","res","json","blob","formData","arrayBuffer","text","error","code","push","badRequest","unauthorized","forbidden","notFound","timeout","internalError","_url","_options","this","Wretcher","method","baseurl","options","qp","appendQueryParams","headerValues","headers","headerValue","Accept","Content-Type","contents","body","jsObject","content","JSON","stringify","formObject","FormData","key","_a","_i","item","append","usp","URLSearchParams","index","indexOf","val","substring","toString","self","global","require"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 46e93d7..1936a01 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,3 +1,3 @@ import { Wretcher } from "./wretcher"; -declare const _default: (url?: string, opts?: {}) => Wretcher; +declare const _default: (url?: string, opts?: RequestInit) => Wretcher; export default _default; diff --git a/dist/index.js.map b/dist/index.js.map index 8e82373..96326a4 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAKrC,EAAE,CAAA,CAAC,OAAO,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,eAAe,CAAA;AAC3D,CAAC;AAED;;GAEG;AACH,eAAe,UAAC,GAAQ,EAAE,IAAS;IAAnB,oBAAA,EAAA,QAAQ;IAAE,qBAAA,EAAA,SAAS;IAAK,OAAA,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;AAAvB,CAAuB,CAAA"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAKrC,EAAE,CAAA,CAAC,OAAO,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,eAAe,CAAA;AAC3D,CAAC;AAED;;GAEG;AACH,eAAe,UAAC,GAAQ,EAAE,IAAsB;IAAhC,oBAAA,EAAA,QAAQ;IAAE,qBAAA,EAAA,SAAsB;IAAK,OAAA,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;AAAvB,CAAuB,CAAA"} \ No newline at end of file diff --git a/dist/wretcher.d.ts b/dist/wretcher.d.ts index bdfedb4..0170739 100644 --- a/dist/wretcher.d.ts +++ b/dist/wretcher.d.ts @@ -6,17 +6,17 @@ export declare class Wretcher { private _url; private _options; - constructor(_url: string, _options?: {}); + constructor(_url: string, _options?: RequestInit); /** * Sets the default fetch options used for every subsequent fetch call. * @param opts New default options */ - defaults(opts: object): this; + defaults(opts: RequestInit): this; /** * Mixins the default fetch options used for every subsequent fetch calls. * @param opts Options to mixin with the current default options */ - mixdefaults(opts: object): this; + mixdefaults(opts: RequestInit): this; /** * Sets the method (text, json ...) used to parse the data contained in the response body in case of an HTTP error. * @@ -34,12 +34,12 @@ export declare class Wretcher { * Returns a wretch factory which, when called, creates a new Wretcher object with the base url as an url prefix. * @param baseurl The base url */ - baseUrl(baseurl: string): (url?: string, opts?: {}) => Wretcher; + baseUrl(baseurl: string): (url?: string, opts?: RequestInit) => Wretcher; /** * Returns a new Wretcher object with the same url and new options. * @param options New options */ - options(options: object): Wretcher; + options(options: RequestInit): Wretcher; /** * Converts a javascript object to query parameters, * then appends this query string to the current url. @@ -52,11 +52,23 @@ export declare class Wretcher { * @param qp An object which will be converted. */ query(qp: object): Wretcher; + /** + * Set request headers. + * @param headerValues An object containing header key and values + */ + headers(headerValues: { + [headerName: string]: any; + }): Wretcher; /** * Shortcut to set the "Accept" header. * @param what Header value */ - accept(what: string): Wretcher; + accept(headerValue: string): Wretcher; + /** + * Shortcut to set the "Content-Type" header. + * @param what Header value + */ + content(headerValue: string): Wretcher; /** * Performs a get request. */ @@ -317,6 +329,11 @@ export declare class Wretcher { json?: any; }) => void) => any; }; + /** + * Sets the request body with any content. + * @param contents The body contents + */ + body(contents: any): Wretcher; /** * Sets the content type header, stringifies an object and sets the request body. * @param jsObject An object diff --git a/dist/wretcher.js b/dist/wretcher.js index b9f965b..0246a24 100644 --- a/dist/wretcher.js +++ b/dist/wretcher.js @@ -86,12 +86,26 @@ var Wretcher = /** @class */ (function () { Wretcher.prototype.query = function (qp) { return new Wretcher(appendQueryParams(this._url, qp), this._options); }; + /** + * Set request headers. + * @param headerValues An object containing header key and values + */ + Wretcher.prototype.headers = function (headerValues) { + return new Wretcher(this._url, mix(this._options, { headers: headerValues })); + }; /** * Shortcut to set the "Accept" header. * @param what Header value */ - Wretcher.prototype.accept = function (what) { - return new Wretcher(this._url, mix(this._options, { headers: { Accept: what } })); + Wretcher.prototype.accept = function (headerValue) { + return this.headers({ Accept: headerValue }); + }; + /** + * Shortcut to set the "Content-Type" header. + * @param what Header value + */ + Wretcher.prototype.content = function (headerValue) { + return this.headers({ "Content-Type": headerValue }); }; /** * Performs a get request. @@ -128,12 +142,19 @@ var Wretcher = /** @class */ (function () { if (opts === void 0) { opts = {}; } return resolver(this._url)(__assign({}, mix(opts, this._options), { method: "PATCH" })); }; + /** + * Sets the request body with any content. + * @param contents The body contents + */ + Wretcher.prototype.body = function (contents) { + return new Wretcher(this._url, __assign({}, this._options, { body: contents })); + }; /** * Sets the content type header, stringifies an object and sets the request body. * @param jsObject An object */ Wretcher.prototype.json = function (jsObject) { - return new Wretcher(this._url, __assign({}, this._options, { headers: { "Content-Type": "application/json" }, body: JSON.stringify(jsObject) })); + return this.content("application/json").body(JSON.stringify(jsObject)); }; /** * Converts the javascript object to a FormData and sets the request body. @@ -152,7 +173,7 @@ var Wretcher = /** @class */ (function () { formData.append(key, formObject[key]); } } - return new Wretcher(this._url, __assign({}, this._options, { body: formData })); + return this.body(formData); }; return Wretcher; }()); diff --git a/dist/wretcher.js.map b/dist/wretcher.js.map index b5ccff7..b6f2fc7 100644 --- a/dist/wretcher.js.map +++ b/dist/wretcher.js.map @@ -1 +1 @@ -{"version":3,"file":"wretcher.js","sourceRoot":"","sources":["../src/wretcher.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"wretcher.js","sourceRoot":"","sources":["../src/wretcher.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 7cc4984..ccac8d3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,4 +10,4 @@ if(typeof self === "undefined") { /** * Return a fresh Wretcher instance. */ -export default (url = "", opts = {}) => new Wretcher(url, opts) +export default (url = "", opts: RequestInit = {}) => new Wretcher(url, opts) diff --git a/src/wretcher.ts b/src/wretcher.ts index 27470e4..cd4d594 100644 --- a/src/wretcher.ts +++ b/src/wretcher.ts @@ -11,13 +11,13 @@ export class Wretcher { constructor( private _url: string, - private _options = {}) {} + private _options: RequestInit = {}) {} /** * Sets the default fetch options used for every subsequent fetch call. * @param opts New default options */ - defaults(opts: object) { + defaults(opts: RequestInit) { conf.defaults = opts return this } @@ -26,7 +26,7 @@ export class Wretcher { * Mixins the default fetch options used for every subsequent fetch calls. * @param opts Options to mixin with the current default options */ - mixdefaults(opts: object) { + mixdefaults(opts: RequestInit) { conf.defaults = mix(conf.defaults, opts) return this } @@ -56,14 +56,14 @@ export class Wretcher { * @param baseurl The base url */ baseUrl(baseurl: string) { - return (url = "", opts = {}) => new Wretcher(baseurl + url, opts) + return (url = "", opts: RequestInit = {}) => new Wretcher(baseurl + url, opts) } /** * Returns a new Wretcher object with the same url and new options. * @param options New options */ - options(options: object) { + options(options: RequestInit) { return new Wretcher(this._url, options) } @@ -82,12 +82,28 @@ export class Wretcher { return new Wretcher(appendQueryParams(this._url, qp), this._options) } + /** + * Set request headers. + * @param headerValues An object containing header key and values + */ + headers(headerValues: { [headerName: string]: any }) { + return new Wretcher(this._url, mix(this._options, { headers: headerValues })) + } + /** * Shortcut to set the "Accept" header. * @param what Header value */ - accept(what: string) { - return new Wretcher(this._url, mix(this._options, { headers: { Accept : what }})) + accept(headerValue: string) { + return this.headers({ Accept : headerValue }) + } + + /** + * Shortcut to set the "Content-Type" header. + * @param what Header value + */ + content(headerValue: string) { + return this.headers({ "Content-Type" : headerValue }) } /** @@ -121,16 +137,19 @@ export class Wretcher { return resolver(this._url)({ ...mix(opts, this._options), method: "PATCH" }) } + /** + * Sets the request body with any content. + * @param contents The body contents + */ + body(contents: any) { + return new Wretcher(this._url, { ...this._options, body: contents }) + } /** * Sets the content type header, stringifies an object and sets the request body. * @param jsObject An object */ json(jsObject: object) { - return new Wretcher(this._url, { - ...this._options, - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(jsObject) - }) + return this.content("application/json").body(JSON.stringify(jsObject)) } /** * Converts the javascript object to a FormData and sets the request body. @@ -147,10 +166,7 @@ export class Wretcher { } } - return new Wretcher(this._url, { - ...this._options, - body: formData - }) + return this.body(formData) } } diff --git a/test/mock.js b/test/mock.js index f550a4d..4eae5aa 100644 --- a/test/mock.js +++ b/test/mock.js @@ -28,6 +28,13 @@ const mockServer = { setupErrors(server) + server.post("/text/roundTrip", (req,res) => { + if(req.header("content-type") === "text/plain") + res.sendRaw(req.body) + else + res.send(400) + }) + server.post("/json/roundTrip", (req, res) => { if(req.header("content-type") === "application/json") res.json(req.body) @@ -53,6 +60,7 @@ const mockServer = { res.json(500, { error: 500, message: "ok" }) }) + server.listen(port) }, stop: () => { diff --git a/test/test.js b/test/test.js index 127ae6b..3471420 100644 --- a/test/test.js +++ b/test/test.js @@ -63,6 +63,12 @@ describe("Wretch", function() { await allRoutes(init, "arrayBuffer", test) }) + it("should perform a plain text round trip", async function() { + const text = "hello, server !" + const roundTrip = await wretch(`${URL}/text/roundTrip`).content("text/plain").body(text).post().text() + expect(roundTrip).to.be.equal(text) + }) + it("should perform a json round trip", async function() { const jsonObject = { a: 1, b: 2, c: 3 } const roundTrip = await wretch(`${URL}/json/roundTrip`).json(jsonObject).post().json()