Socket
Socket
Sign inDemoInstall

fp-ts-http

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fp-ts-http - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

es6/index.d.ts

37

lib/index.d.ts

@@ -7,7 +7,8 @@ /// <reference types="node" />

import * as t from "io-ts";
export declare const withoutRequestBody: (method: "GET" | "DELETE" | "OPTIONS") => <TPath extends object, TResponseBody>(matcher: Match<TPath>, handler: (req: Readonly<{
export declare type THttpMethod = "GET" | "DELETE" | "OPTIONS" | "POST" | "PUT" | "PATCH";
export declare const get: <TPath extends object, TRequestQuery, TResponseBody>(matcher: Match<TPath>, queryType: t.Decoder<object, TRequestQuery>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
path: TPath & TRequestQuery;
body: any;

@@ -20,7 +21,7 @@ stream: import("http").IncomingMessage;

}>>) => readonly composeMiddleware.Middleware<Koa.ParameterizedContext<any, {}>>[];
export declare const get: <TPath extends object, TResponseBody>(matcher: Match<TPath>, handler: (req: Readonly<{
export declare const options: <TPath extends object, TRequestQuery, TResponseBody>(matcher: Match<TPath>, queryType: t.Decoder<object, TRequestQuery>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
path: TPath & TRequestQuery;
body: any;

@@ -33,7 +34,7 @@ stream: import("http").IncomingMessage;

}>>) => readonly composeMiddleware.Middleware<Koa.ParameterizedContext<any, {}>>[];
export declare const options: <TPath extends object, TResponseBody>(matcher: Match<TPath>, handler: (req: Readonly<{
export declare const del: <TPath extends object, TRequestQuery, TResponseBody>(matcher: Match<TPath>, queryType: t.Decoder<object, TRequestQuery>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
path: TPath & TRequestQuery;
body: any;

@@ -46,19 +47,7 @@ stream: import("http").IncomingMessage;

}>>) => readonly composeMiddleware.Middleware<Koa.ParameterizedContext<any, {}>>[];
export declare const del: <TPath extends object, TResponseBody>(matcher: Match<TPath>, handler: (req: Readonly<{
export declare const post: <TPath extends object, TRequestQuery, TRequestBody, TResponseBody>(matcher: Match<TPath>, queryType: t.Decoder<object, TRequestQuery>, bodyParser: t.Type<TRequestBody, TRequestBody, unknown>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
body: any;
stream: import("http").IncomingMessage;
}>) => Promise<Readonly<{
status: number;
headers: import("fp-ts/lib/Option").Option<Record<string, string>>;
body: TResponseBody;
}>>) => readonly composeMiddleware.Middleware<Koa.ParameterizedContext<any, {}>>[];
export declare const post: <TPath extends object, TRequestBody, TResponseBody>(matcher: Match<TPath>, bodyParser: t.Type<TRequestBody, TRequestBody, unknown>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
path: TPath & TRequestQuery;
body: TRequestBody;

@@ -71,7 +60,7 @@ stream: import("http").IncomingMessage;

}>>) => readonly composeMiddleware.Middleware<Koa.ParameterizedContext<any, {}>>[];
export declare const put: <TPath extends object, TRequestBody, TResponseBody>(matcher: Match<TPath>, bodyParser: t.Type<TRequestBody, TRequestBody, unknown>, handler: (req: Readonly<{
export declare const put: <TPath extends object, TRequestQuery, TRequestBody, TResponseBody>(matcher: Match<TPath>, queryType: t.Decoder<object, TRequestQuery>, bodyParser: t.Type<TRequestBody, TRequestBody, unknown>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
path: TPath & TRequestQuery;
body: TRequestBody;

@@ -84,7 +73,7 @@ stream: import("http").IncomingMessage;

}>>) => readonly composeMiddleware.Middleware<Koa.ParameterizedContext<any, {}>>[];
export declare const patch: <TPath extends object, TRequestBody, TResponseBody>(matcher: Match<TPath>, bodyParser: t.Type<TRequestBody, TRequestBody, unknown>, handler: (req: Readonly<{
export declare const patch: <TPath extends object, TRequestQuery, TRequestBody, TResponseBody>(matcher: Match<TPath>, queryType: t.Decoder<object, TRequestQuery>, bodyParser: t.Type<TRequestBody, TRequestBody, unknown>, handler: (req: Readonly<{
status: number;
headers: Record<string, string>;
url: string;
path: TPath;
path: TPath & TRequestQuery;
body: TRequestBody;

@@ -91,0 +80,0 @@ stream: import("http").IncomingMessage;

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -51,6 +62,7 @@ return new (P || (P = Promise))(function (resolve, reject) {

var Middleware_1 = require("./Middleware");
exports.withoutRequestBody = function (method) {
return function (matcher, handler) {
var io_ts_reporters_1 = require("io-ts-reporters");
var withoutRequestBody = function (method) {
return function (matcher, queryType, handler) {
return Middleware_1.from(function (ctx, next) { return __awaiter(_this, void 0, void 0, function () {
var pathParser, match, request, response;
var pathParser, pathRoute, matchPath, query, request, response;
return __generator(this, function (_a) {

@@ -62,6 +74,12 @@ switch (_a.label) {

pathParser = matcher.parser.map(function_1.identity);
match = fp_ts_routing_1.parse(pathParser, fp_ts_routing_1.Route.parse(ctx.request.url), null);
if (util_1.isNull(match))
pathRoute = fp_ts_routing_1.Route.parse(ctx.request.path);
matchPath = fp_ts_routing_1.parse(pathParser, pathRoute, null);
if (util_1.isNull(matchPath))
return [2 /*return*/, next()];
request = Request_1.koaContextToRequest(ctx, match);
query = queryType.decode(ctx.query);
if (query.isLeft())
return [2 /*return*/, ctx.throw(400, JSON.stringify({
errors: io_ts_reporters_1.reporter(query)
}))];
request = Request_1.fromKoaContext(ctx, __assign({}, matchPath, query.value));
return [4 /*yield*/, handler(request)];

@@ -77,9 +95,9 @@ case 1:

};
exports.get = exports.withoutRequestBody("GET");
exports.options = exports.withoutRequestBody("OPTIONS");
exports.del = exports.withoutRequestBody("DELETE");
exports.get = withoutRequestBody("GET");
exports.options = withoutRequestBody("OPTIONS");
exports.del = withoutRequestBody("DELETE");
var withRequestBody = function (method) {
return function (matcher, bodyParser, handler) {
return function (matcher, queryType, bodyParser, handler) {
return Middleware_1.from(function (ctx, next) { return __awaiter(_this, void 0, void 0, function () {
var pathParser, match, decodedBody, request, response;
var pathParser, pathRoute, matchPath, query, decodedBody, request, response;
return __generator(this, function (_a) {

@@ -91,9 +109,15 @@ switch (_a.label) {

pathParser = matcher.parser.map(function_1.identity);
match = fp_ts_routing_1.parse(pathParser, fp_ts_routing_1.Route.parse(ctx.request.url), null);
if (util_1.isNull(match))
pathRoute = fp_ts_routing_1.Route.parse(ctx.request.path);
matchPath = fp_ts_routing_1.parse(pathParser, pathRoute, null);
if (util_1.isNull(matchPath))
return [2 /*return*/, next()];
query = queryType.decode(ctx.query);
if (query.isLeft())
return [2 /*return*/, ctx.throw(400, JSON.stringify({
errors: io_ts_reporters_1.reporter(query)
}))];
decodedBody = bodyParser.decode(ctx.request.body);
if (decodedBody.isLeft())
return [2 /*return*/, ctx.throw(400)];
request = Request_1.koaContextToRequest(ctx, match, decodedBody.value);
return [2 /*return*/, ctx.throw(400, "request body invalid")];
request = Request_1.fromKoaContext(ctx, __assign({}, matchPath, query.value), decodedBody.value);
return [4 /*yield*/, handler(request)];

@@ -125,3 +149,11 @@ case 1:

var koa = new koa_1.default();
var middleware = koa_compose_1.default([koa_body_1.default()].concat(stack));
var middleware = koa_compose_1.default([
function (ctx, next) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
ctx.set('content-type', 'application/json');
return [2 /*return*/, next()];
});
}); },
koa_body_1.default()
].concat(stack));
koa.use(middleware);

@@ -128,0 +160,0 @@ return new Promise(function (resolve) { return koa.listen(port, resolve); });

@@ -12,3 +12,3 @@ /// <reference types="node" />

}>;
export declare const koaContextToRequest: <PT, BT>(ctx: Koa.Context, path: PT, body?: BT | undefined) => Readonly<{
export declare const fromKoaContext: <PT, BT = any>(ctx: Koa.Context, path: PT, body?: BT | undefined) => Readonly<{
status: number;

@@ -18,4 +18,4 @@ headers: Record<string, string>;

path: PT;
body: any;
body: BT;
stream: IncomingMessage;
}>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.koaContextToRequest = function (ctx, path, body) {
exports.fromKoaContext = function (ctx, path, body) {
return Object.freeze({

@@ -10,4 +10,4 @@ url: ctx.url,

path: path,
stream: ctx.req
stream: ctx.req,
});
};
{
"name": "fp-ts-http",
"version": "0.0.1",
"version": "0.0.2",
"description": "Opinionated Typesafe http middleware library using fp-ts-routing and io-ts",
"keywords": ["functional", "typesafe", "http", "rest", "routing", "fp-ts", "fp-ts-routing", "io-ts"],
"keywords": [
"functional",
"typesafe",
"http",
"rest",
"routing",
"fp-ts",
"fp-ts-routing",
"io-ts"
],
"files": [
"lib",
"es6"
],
"typings": "lib/index.d.ts",
"main": "lib/index.js",
"scripts": {
"dev": "nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.test.ts' --exec 'ts-node' test.ts -- --experimental-modules",
"build": "npm run clean && npm run build:lib && npm run build:es6",
"dev": "nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.test.ts' --exec 'ts-node' src/test.ts -- --experimental-modules",
"build:watch": "concurrently 'npm run build:lib:watch' 'npm run build:es6:watch'",
"build": "npm run clean && concurrently 'npm run build:lib' 'npm run build:es6'",
"build:lib": "tsc",
"build:es6": "tsc -p tsconfig.es6.json",
"build:lib:watch": "tsc --watch",
"build:es6:watch": "tsc --watch -p tsconfig.es6.json",
"clean": "rimraf lib/* es6/*"

@@ -27,2 +43,3 @@ },

"@types/node": "^12.0.10",
"concurrently": "^4.1.1",
"nodemon": "^1.19.1",

@@ -43,2 +60,3 @@ "renamer": "^1.1.2",

"io-ts": "^1.10.2",
"io-ts-reporters": "0.0.21",
"koa": "^2.7.0",

@@ -45,0 +63,0 @@ "koa-body": "^4.1.0",

# fp-ts-http
### Install
Includes `fp-ts` `fp-ts-routing` and `io-ts`
```bash
npm i fp-ts-http
```
## Example
```typescript
import { end, lit, int } from 'fp-ts-routing'
import * as t from "io-ts"
import { get, post, driver } from "fp-ts-routing"
import { TMiddlewareStack } from 'fp-ts-routing/lib/Middleware';
import * as io from "io-ts"
import { get, post, driver } from "fp-ts-http"
import { TMiddlewareStack } from 'fp-ts-http/lib/Middleware';
import { none } from 'fp-ts/lib/Option';

@@ -19,3 +28,3 @@

headers: none,
body: "get success: " + req.path.userid
body: `fetched user ${req.path.userid}`
}

@@ -25,3 +34,3 @@ })]

const userMessages = userById.then(lit("messages"))
const userMessageDto = t.type({ message: t.string })
const userMessageDto = io.type({ message: io.string })

@@ -39,3 +48,76 @@ const stack3 = [...stack2, ...post<{userid: number}, {message: string}, string>(userMessages.then(end), userMessageDto, async(req) => {

.then(() => console.log("server running"))
```
```
## Advanced query parsing example
```typescript
import { end, lit, query, str } from 'fp-ts-routing'
import * as io from "io-ts"
import { get, post, driver } from "."
import { TMiddlewareStack } from './Middleware';
import { none } from 'fp-ts/lib/Option';
import { NumberFromString, BooleanFromString, ArrayFromString } from './Query';
const stack: TMiddlewareStack = []
type TUsersPath = {
type: string;
}
const usersQuery = io.strict({
filter: io.union([ io.undefined, io.string ]),
validStatusCodes: io.union([ io.undefined, ArrayFromString<number>(NumberFromString) ]),
sortBy: io.union([ io.undefined, io.string]),
sortDirection: io.union([ io.undefined, BooleanFromString])
})
type TUsersQuery = io.TypeOf<typeof usersQuery>
type TUsersResponseBody = string
const users = lit("users").then(str("type"))
const stack2 = [...stack, ...get<TUsersPath, TUsersQuery, TUsersResponseBody>(users.then(end), usersQuery, async(req) => {
return {
status: 200,
headers: none,
body: await UserRepository.find({
type: req.path.type,
sortBy: req.path.sortBy,
sortDirection: req.path.sortDirection
})
}
})]
type TUserMessageDto = {
message: string
}
const userMessages = users.then(lit("messages"))
const userMessageDto = io.type({ message: io.string })
type TUserMessagesResponseBody = string
const stack3 = [...stack2, ...post<TUsersPath, TUsersQuery, TUserMessageDto, TUserMessagesResponseBody>(userMessages.then(end), usersQuery, userMessageDto, async(req) => {
const users = await UserRepository.find({
type: req.path.type,
sortBy: req.path.sortBy,
sortDirection: req.path.sortDirection
})
await Promise.all(users.map(async user => sendMessageToUser(user, req.body)))
return {
status: 200,
headers: none,
body: JSON.stringify(req.path)
}
})]
driver(stack3, 3000).run()
.then(() => console.log("server running"))
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc