@orikami/fn-to-json-api
Advanced tools
Comparing version 0.0.2 to 0.1.0
74
index.js
const { json } = require("micro"); | ||
// const getJsonApi = (handler = (req, res) => {}); | ||
const postJsonApi = handler => async (req, res) => { | ||
try { | ||
const data = await json(req); | ||
const result = await handler(data); | ||
return result; | ||
} catch (err) { | ||
let statusCode = 500; | ||
const match = err.message.match(/^([4-5][0-9]{2}): /); | ||
if (match) { | ||
statusCode = parseInt(match[1]); | ||
} | ||
res.statusCode = statusCode; | ||
return { | ||
statusCode, | ||
message: err.message, | ||
// MAGIC!!!! WHat will it do? Run to figure out... | ||
stack: err.stack | ||
.replace(/^\s+at\s+/gm, "") | ||
.split("\n") | ||
.splice(1) | ||
}; | ||
} | ||
}; | ||
module.exports.postJsonApi = postJsonApi; | ||
// const businessFunction = (opts) => { | ||
// return opts.a + opts.b; | ||
// } | ||
// // Native | ||
// const naiveApiFunction = async (req, res) => { | ||
// const opts = await json(req); | ||
// try { | ||
// const result = opts.a + opts.b; | ||
// return result; | ||
// } catch(err) { | ||
// sendError(err); // DRY, created utility function! | ||
// } | ||
// } | ||
// // Wait a minute... still repeating yourself with all the boilerplate! | ||
// // Isn't it possible to automate myself? MORE DRY!!! | ||
// // Better: | ||
// const automateMyselfAndAddStuffAroundMyBusinessFunction = (myBusinessFunction) => { | ||
// const myApiFunction = (req, res) => { | ||
// const data = await json(req); | ||
// try { | ||
// const result = await myBusinessFunction(data); | ||
// } catch(err) { | ||
// sendError(err); | ||
// } | ||
// } | ||
// return myApiFunction; | ||
// } | ||
// // Now use it: | ||
// const myAwesomeApiFunction = automateMyselfAndAddStuffAroundMyBusinessFunction(businessFunction); | ||
const query = require("micro-query"); | ||
module.exports = handler => async (req, res) => { | ||
const postData = req.method === "POST" ? await json(req) : {}; | ||
const queryParams = query(req); | ||
const data = Object.assign(queryParams, postData); | ||
return await handler(data, req, res); | ||
}; |
const request = require("micro-test-request"); | ||
const { postJsonApi } = require("./index"); | ||
const toJsonApi = require("./index"); | ||
const { json } = require("micro"); | ||
test("200 sync function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/", | ||
headers: { | ||
authorization: "Bearer OK" | ||
}, | ||
body: { hello: "world" }, | ||
handler: postJsonApi(handler) | ||
}); | ||
test("200 POST sync function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/?a=query&b=query", | ||
body: { a: "post", c: "post" }, | ||
handler: toJsonApi(echo) | ||
}); | ||
expect(res.statusCode).toBe(200); | ||
expect(res.statusCode).toBe(200); | ||
expect(JSON.parse(res.body)).toEqual({ | ||
a: "post", // POST body overwrites query params | ||
b: "query", | ||
c: "post" | ||
}); | ||
}); | ||
test("200 async function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/", | ||
headers: { | ||
authorization: "Bearer OK" | ||
}, | ||
body: { hello: "world" }, | ||
handler: postJsonApi(handlerAsync) | ||
}); | ||
test("200 POST async function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/?a=query&b=query", | ||
body: { a: "post", c: "post" }, | ||
handler: toJsonApi(echoAsync) | ||
}); | ||
expect(res.statusCode).toBe(200); | ||
expect(res.statusCode).toBe(200); | ||
expect(JSON.parse(res.body)).toEqual({ | ||
a: "post", // POST body overwrites query params | ||
b: "query", | ||
c: "post" | ||
}); | ||
}); | ||
test("500 error function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/", | ||
headers: { | ||
authorization: "Bearer OK" | ||
}, | ||
body: { hello: "world" }, | ||
handler: postJsonApi(handlerError) | ||
}); | ||
test("200 GET async function", async () => { | ||
const res = await request({ | ||
method: "GET", | ||
url: "/?a=query&b=query", | ||
handler: toJsonApi(echoAsync) | ||
}); | ||
expect(res.statusCode).toBe(500); | ||
expect(res.statusCode).toBe(200); | ||
expect(JSON.parse(res.body)).toEqual({ | ||
a: "query", | ||
b: "query" | ||
}); | ||
}); | ||
test("500 error asycn function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/", | ||
headers: { | ||
authorization: "Bearer OK" | ||
}, | ||
body: { hello: "world" }, | ||
handler: postJsonApi(handlerAsyncError) | ||
}); | ||
expect(res.statusCode).toBe(500); | ||
}); | ||
test("401 error function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/", | ||
headers: { | ||
authorization: "Bearer OK" | ||
}, | ||
body: { hello: "world" }, | ||
handler: postJsonApi(handlerError401) | ||
}); | ||
expect(res.statusCode).toBe(401); | ||
}); | ||
test("401 error asycn function", async () => { | ||
const res = await request({ | ||
method: "POST", | ||
url: "/", | ||
headers: { | ||
authorization: "Bearer OK" | ||
}, | ||
body: { hello: "world" }, | ||
handler: postJsonApi(handlerAsyncError401) | ||
}); | ||
expect(res.statusCode).toBe(401); | ||
}); | ||
const waitOneSecond = () => { | ||
return new Promise(resolve => setTimeout(() => resolve(), 1000)); | ||
const echo = data => { | ||
return data; | ||
}; | ||
const handler = data => { | ||
return "Hello world!"; | ||
const echoAsync = async data => { | ||
await new Promise(resolve => setImmediate(resolve)); | ||
return data; | ||
}; | ||
const handlerAsync = async data => { | ||
data = await waitOneSecond(); | ||
return data; | ||
}; | ||
const handlerError = data => { | ||
throw new Error("Goes wrong"); | ||
}; | ||
const handlerAsyncError = async data => { | ||
data = await waitOneSecond(); | ||
throw new Error("Goes wrong"); | ||
}; | ||
const handlerError401 = data => { | ||
throw new Error("401: Goes wrong"); | ||
}; | ||
const handlerAsyncError401 = async data => { | ||
await waitOneSecond(); | ||
throw new Error("401: Goes wrong"); | ||
}; |
{ | ||
"name": "@orikami/fn-to-json-api", | ||
"version": "0.0.2", | ||
"description": "Convert a function to an json rest api. With response and request params.", | ||
"version": "0.1.0", | ||
"description": "Convert (jsonData) => {} to (req, res) => {}", | ||
"main": "index.js", | ||
@@ -12,5 +12,6 @@ "scripts": { | ||
"dependencies": { | ||
"micro": "^8.0.4" | ||
"micro-query": "^0.3.0" | ||
}, | ||
"devDependencies": { | ||
"micro": "^8.0.4", | ||
"jest": "^23.1.0", | ||
@@ -17,0 +18,0 @@ "jsdom": "^11.11.0", |
# fn-to-json-api | ||
Convert a function to an json rest api. With response and request params. | ||
Transform business logic (`data => {}`) to a micro server handler (`(req,res) => {}`) | ||
`data` will be the JSON POST body and GET query parameters. | ||
## Install | ||
@@ -12,12 +14,21 @@ ``` | ||
Given a micro function in `index.js` | ||
Given some business logic in `index.js`: | ||
``` | ||
module.exports = (json) => ({ return json; }) | ||
module.exports = (data, req, res) => { return data; } | ||
``` | ||
Convert it to a lambda function in `handler.js`: | ||
Convert it to a micro server handler in `handler.js`: | ||
``` | ||
var fnToJsonApi = require('fn-to-json-api'); | ||
var index = require('./index'); | ||
module.exports.json = fnToJsonApi(json); | ||
``` | ||
var toJsonAPI = require('fn-to-json-api'); | ||
var fn = require('./index'); | ||
const handler = toJsonAPI(fn); | ||
module.exports = handler; | ||
``` | ||
`data` will contain the POST data and query parameters. POST will override query parameters. | ||
## Changelog | ||
0.1.0 - Refactor | ||
0.0.2 - Initial release |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
33
3002
4
4
57
1
+ Addedmicro-query@^0.3.0
+ Addedmicro-query@0.3.0(transitive)
+ Addedqs@6.5.2(transitive)
- Removedmicro@^8.0.4
- Removedbytes@2.5.0(transitive)
- Removeddepd@1.1.0(transitive)
- Removedhttp-errors@1.6.1(transitive)
- Removediconv-lite@0.4.18(transitive)
- Removedinherits@2.0.3(transitive)
- Removedis-stream@1.1.0(transitive)
- Removedmedia-typer@0.3.0(transitive)
- Removedmicro@8.0.4(transitive)
- Removedmri@1.1.0(transitive)
- Removedraw-body@2.3.0(transitive)
- Removedsetprototypeof@1.0.3(transitive)
- Removedstatuses@1.5.0(transitive)
- Removedunpipe@1.0.0(transitive)