New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

http4js

Package Overview
Dependencies
Maintainers
1
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http4js - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

dist/main/core/Body.d.ts

51

index.ts
import {Request} from "./src/main/core/Request";
import {Method, Http4jsRequest} from "./src/main/core/HttpMessage";
import {HttpHandler} from "./src/main/core/HttpMessage";
import {routes} from "./src/main/core/RoutingHttpHandler";
import {Response} from "./src/main/core/Response";
import {httpClient} from "./src/main/core/Client";
import {HttpClient} from "./src/main/core/Client";
import {Body} from "./src/main/core/Body";
import {Uri} from "./src/main/core/Uri";
let req: Http4jsRequest = new Request(Method.GET, "/path");
let handler = (req: Request) => {
return new Response(new Body(Buffer.from(`${req.method} to ${req.uri} with headers ${req.headers}`)))
let bodyString = `<h1>${req.method} to ${req.uri.href} with headers ${Object.keys(req.headers)}</h1>`;
return new Response(200, new Body(Buffer.from(bodyString)))
};
routes("/path", handler).asServer(3000).start();
let options = {
host: 'localhost',
port: 3000,
method: 'post',
path: '/path',
headers: {tom: ["pwns", "rocks", "smells"]}
let headerFilter = (handler: HttpHandler) => {
return (req: Request) => {
return handler(req.setHeader("filter", "1"));
}
};
httpClient().get(options).then(succ => console.log(succ));
let moreRoutes = routes("/bob/{id}", "POST", (req) => { return new Response(201, new Body("created a " + req.path))});
routes("/path", "GET", handler)
.withHandler("/tom", "GET", handler)
.withRoutes(moreRoutes)
.withFilter(headerFilter)
.asServer(3000).start();
let getRequest = new Request("GET", Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules");
let postRequest = new Request("GET", Uri.of("http://localhost:3000/path/tom")).setHeader("tom", "rules");
let client = HttpClient;
client(getRequest).then(succ => {
console.log("body string");
console.log(succ.body.bodyString());
console.log("headers");
console.log(succ.headers);
});
client(postRequest).then(succ => {
console.log("body string");
console.log(succ.body.bodyString());
console.log("headers");
console.log(succ.headers);
});
{
"name": "http4js",
"version": "1.0.0",
"version": "1.0.1",
"description": "",
"main": "index.js",
"main": "dist/index.js",
"types" : "dist/index.d.ts",
"scripts": {
"test": "mocha src/test/**",
"build": "tsc",
"app": "tsc; node index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tomshacham/http4js.git"
},
"author": "",

@@ -11,0 +17,0 @@ "license": "ISC",

## Http4js
A port of http4k: a lightweight _toolkit_ to allow in memory functional testing and to simplify working with HTTP.
A port of [http4k](https://github.com/http4k/http4k): a lightweight _toolkit_ to allow in memory functional testing and to simplify working with HTTP.
#### To run:
`tsc; node index.js`
`tsc index.ts --target es5; node index.js`

@@ -16,3 +16,3 @@ #### To test:

**In order to run test in idea/webstorm**, you may need to:
**In order to run tests in idea/webstorm**, you may need to:

@@ -27,4 +27,7 @@ ```

- client catching errors and supporting all methods
- chaining and nesting filters
- uri has path and host and protocol and scheme and authority
- code:
- extract form data
- ordering of filters
- other client verbs
- write docs
- publish as library to npm
import * as http from 'http';
import {Response} from "./Response";
import {Body} from "./Body";
import {Method} from "./HttpMessage";
export function httpClient() {
return new HttpClient();
export function HttpClient(request) {
if (request.method == "GET") {
return get(request)
} else {
return post(request)
}
}
export function HttpClient() {
this.get = (request) => {
let options = {};
options["hostname"] = "localhost";
options["port"] = 3000;
options["path"] = "/";
options["headers"] = request.headers;
options["method"] = Method[request.method];
function get(request): Promise<Response> {
let options = request.uri.asRequest;
options.headers = request.headers;
return new Promise(succ => {
http.request(options, (res) => {
let chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
let body = new Body(Buffer.concat(chunks));
let response = new Response(body).setHeaders(res.headers);
succ(response);
});
}).end();
});
};
return new Promise(succ => {
http.request(options, (res) => {
let chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
let body = new Body(Buffer.concat(chunks));
let response = new Response(res.statusCode, body).setHeaders(res.headers);
return succ(response);
});
}).end();
});
};
this.post = (request) => {
let options = {};
options["hostname"] = "localhost";
options["port"] = 3000;
options["path"] = "/";
options["headers"] = request.headers;
options["method"] = Method[request.method];
function post(request): Promise<Response> {
let options = request.uri.asRequest;
options.headers = request.headers;
options.method = request.method;
return new Promise(succ => {
let clientRequest = http.request(options, (res) => {
let chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
let body = new Body(Buffer.concat(chunks));
let response = new Response(body).setHeaders(res.headers);
succ(response);
});
return new Promise(succ => {
let clientRequest = http.request(options, (res) => {
let chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
clientRequest.write(request.body.bodyString());
clientRequest.end();
res.on('end', () => {
let body = new Body(Buffer.concat(chunks));
let response = new Response(res.statusCode, body).setHeaders(res.headers);
return succ(response);
});
});
}
clientRequest.write(request.body.bodyString());
clientRequest.end();
});
}

@@ -27,7 +27,2 @@ import {Body} from "./Body";

export enum Method {
GET,
POST
}
export interface Http4jsRequest extends HttpMessage {

@@ -34,0 +29,0 @@ method: string

@@ -1,5 +0,5 @@

import {Http4jsRequest, Method} from "./HttpMessage";
import {Headers} from "./Headers";
import {Http4jsRequest} from "./HttpMessage";
import {Body} from "./Body";
import {Uri} from "./Uri";
import {isNullOrUndefined} from "util";

@@ -12,6 +12,6 @@ export class Request implements Http4jsRequest {

body: Body;
private queries = {};
queries = {};
constructor(
method: Method,
method: string,
uri: Uri | string,

@@ -21,3 +21,3 @@ body: Body = new Body(new Buffer("")),

) {
this.method = method.toString();
this.method = method;
if (typeof uri == "string") {

@@ -30,5 +30,16 @@ this.uri = Uri.of(uri);

this.headers = headers ? headers : {};
this.queries = this.getQueryParams();
return this;
}
private getQueryParams(): object {
if (isNullOrUndefined(this.uri.query)) return {};
let pairs = this.uri.query.split("&");
pairs.map(pair => {
let split = pair.split("=");
this.queries[split[0]] = split[1]
});
return this.queries;
}
setUri(uri: Uri | string): Request {

@@ -81,12 +92,11 @@ if (typeof uri == "string") {

query(name: string, value: string): Request {
let queries = Object.keys(this.queries);
if (queries.length > 0) {
this.uri.uriString += `&${name}=${value}`;
} else {
this.uri.uriString += `?${name}=${value}`;
}
this.queries[name] = value;
this.uri = this.uri.withQuery(name, value);
return this;
}
getQuery(name: string) : string {
return this.queries[name];
}
}
import {HttpMessage} from "./HttpMessage";
import {Headers} from "./Headers";
import {Body} from "./Body";
import {Uri} from "./Uri";
interface Http4jsResponse extends HttpMessage {
}
export interface Http4jsResponse extends HttpMessage {}

@@ -13,9 +11,12 @@ export class Response implements Http4jsResponse {

body: Body;
status: number;
pathParams: object;
constructor(body: Body = new Body("")) {
constructor(status: number = 200, body: Body = new Body("")) {
this.body = body;
this.status = status;
}
getHeader(name: string): string {
return this.headers[name];
return this.headers[name.toLowerCase()];
}

@@ -39,3 +40,3 @@

allHeaders(headers: Headers): Response {
allHeaders(headers: object): Response {
return undefined;

@@ -42,0 +43,0 @@ }

@@ -1,2 +0,1 @@

import * as http from "http";
import {Response} from "./Response";

@@ -6,43 +5,21 @@ import {Http4jsRequest, HttpHandler} from "./HttpMessage";

import {Body} from "./Body";
import {Http4jsServer, Server} from "./Server";
import {Uri} from "./Uri";
interface Router {
match(request: Http4jsRequest): Response
}
interface RoutingHttpHandler extends Router {
export interface RoutingHttpHandler {
withFilter(filter: (HttpHandler) => HttpHandler): RoutingHttpHandler
// withBasePath(path: String): RoutingHttpHandler
asServer(port: number): Http4jsServer
match(request: Http4jsRequest): Response
}
interface Http4jsServer {
server;
port: number;
start(): void
stop(): void
export function routes(path: string, method: string, handler: HttpHandler): ResourceRoutingHttpHandler {
return new ResourceRoutingHttpHandler(path, method, handler);
}
class BasicServer implements Http4jsServer {
server;
port: number;
constructor(port: number) {
this.port = port;
this.server = http.createServer();
return this;
}
start(): void {
this.server.listen(this.port)
}
stop(): void {
this.server.close()
}
export function getTo(path: string, handler: HttpHandler): ResourceRoutingHttpHandler {
return new ResourceRoutingHttpHandler(path, "GET", handler);
}
export function routes(path: string, handler: HttpHandler): ResourceRoutingHttpHandler {
return new ResourceRoutingHttpHandler(path, handler);
export function postTo(path: string, handler: HttpHandler): ResourceRoutingHttpHandler {
return new ResourceRoutingHttpHandler(path, "POST", handler);
}

@@ -54,16 +31,38 @@

private path: string;
private handler: HttpHandler;
private handler: object;
private handlers: object = {};
private filters: Array<any> = [];
constructor(path: string, handler: HttpHandler) {
constructor(path: string,
method: string,
handler: HttpHandler) {
this.path = path;
this.handler = handler;
let verbToHandler = {verb: method, handler: handler};
this.handler = verbToHandler;
this.handlers[path] = verbToHandler;
}
withFilter(filter: (HttpHandler) => HttpHandler): RoutingHttpHandler {
return new ResourceRoutingHttpHandler(this.path, filter(this.handler));
withRoutes(routes: ResourceRoutingHttpHandler): ResourceRoutingHttpHandler {
for (let path of Object.keys(routes.handlers)) {
let existingPath = this.path != "/" ? this.path : "";
let nestedPath = existingPath + path;
this.handlers[nestedPath] = routes.handlers[path]
}
return this;
}
withFilter(filter: (HttpHandler) => HttpHandler): ResourceRoutingHttpHandler {
this.filters.push(filter);
return this;
}
withHandler(path: string, method: string, handler: HttpHandler): ResourceRoutingHttpHandler {
let existingPath = this.path != "/" ? this.path : "";
let nestedPath = existingPath + path;
this.handlers[nestedPath] = {verb: method, handler: handler};
return this;
}
asServer(port: number): Http4jsServer {
this.server = new BasicServer(port);
this.server = new Server(port);
this.server.server.on("request", (req, res) => {

@@ -77,7 +76,5 @@ const {headers, method, url} = req;

}).on('end', () => {
let body = new Body(Buffer.concat(chunks));
let inMemoryRequest = new Request(method, url, body, headers);
let response = this.match(inMemoryRequest);
res.writeHead(200, response.headers);
res.end(response.bodyString());
let response = this.createInMemResponse(chunks, method, url, headers);
res.writeHead(response.status, response.headers);
res.end(response.body.bytes);
})

@@ -89,14 +86,30 @@ });

match(request: Http4jsRequest): Response {
let handler = this.handler;
let path = this.path;
if (request.uri.match(path)) {
return handler(request);
let paths = Object.keys(this.handlers);
let exactMatch = paths.find(handlerPath => {
return request.uri.match(handlerPath) && this.handlers[handlerPath].verb == request.method
});
let fuzzyMatch = paths.find(handlerPath => {
return Uri.of(handlerPath).match(request.uri.path) && this.handlers[handlerPath].verb == request.method
});
let match = exactMatch || fuzzyMatch;
if (match) {
let handler = this.handlers[match].handler;
let filtered = this.filters.reduce((acc, next) => { return next(acc) }, handler);
let response = filtered(request);
if (match.includes("{")) response.pathParams = Uri.of(match).extract(request.uri.path).matches;
return response;
} else {
let body = new Body(Buffer.from(`${request.method} to ${request.uri.uriString} did not match route ${path}`));
return new Response(body);
let notFoundBody = `${request.method} to ${request.uri.template} did not match routes ${paths.join(" // ")}`;
let body = new Body(notFoundBody);
return new Response(404, body);
}
}
private createInMemResponse(chunks: Array<any>, method: any, url: any, headers: any): Response {
let body = new Body(Buffer.concat(chunks));
let inMemRequest = new Request(method, url, body, headers);
return this.match(inMemRequest);
}
}

@@ -0,26 +1,34 @@

let URI = require('url');
export class Uri {
template: string;
uriString: string;
path: string;
scheme: string;
authority: string;
protocol: string;
auth: string;
query: string;
fragment: string;
private matches: object = {};
private pathParamMatchingRegex: RegExp = new RegExp(/\{(\w+)\}/);
hostname: string;
port: string;
href: string;
template: string;
asRequest: object;
matches: object = {};
private pathParamMatchingRegex: RegExp = new RegExp(/\{(\w+)\}/g);
private pathParamCaptureTemplate: string = "([\\w\\s]+)";
constructor(uri: string) {
this.template = uri;
this.uriString = encodeURI(uri);
let rfc3986 = new RegExp(/^(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?/);
let [wtfIsThis, scheme,authority,path,query,fragment] = uri.split(rfc3986);
this.scheme = scheme;
this.authority = authority;
this.path = path;
this.query = query;
this.fragment = fragment;
constructor(template: string) {
let uri = URI.parse(template);
this.asRequest = uri;
this.template = uri.pathname;
this.protocol = uri.protocol;
this.auth = uri.auth;
this.hostname = uri.hostname;
this.path = uri.path;
this.port = uri.port;
this.query = uri.query;
this.href = uri.href;
}
static of (uri: string): Uri {
static of(uri: string): Uri {
return new Uri(uri)

@@ -34,6 +42,10 @@ }

extract (uri: string): Uri {
let decoded = decodeURI(uri);
let pathParamName = this.pathParamMatchingRegex.exec(this.template)[1];
this.matches[pathParamName] = this.uriTemplateToPathParamCapturingRegex().exec(decoded)[1];
extract(uri: string): Uri {
let decodedUri = decodeURI(uri);
let pathParamNames = this.template.match(this.pathParamMatchingRegex)
.map(it => it.replace("{", "").replace("}", ""));
let pathParams = this.uriTemplateToPathParamCapturingRegex().exec(decodedUri);
pathParamNames.map( (name, i) => {
this.matches[name] = pathParams[i+1]
});
return this;

@@ -46,2 +58,10 @@ }

withQuery(name: string, value: string): Uri {
if (this.query && this.query.length > 0){
return Uri.of(this.href + `&${name}=${value}`)
} else {
return Uri.of(this.href + `?${name}=${value}`)
}
}
private uriTemplateToPathParamCapturingRegex (): RegExp {

@@ -48,0 +68,0 @@ return new RegExp(this.template.replace(

import * as assert from "assert";
import {equal} from "assert";
import {Request} from "../../main/core/Request";
import {Method} from "../../main/core/HttpMessage";
import {Body} from "../../main/core/Body";

@@ -11,6 +10,6 @@

equal(
new Request(Method.GET, "/")
new Request("GET", "/")
.setUri("/tom")
.uri
.uriString,
.template,
"/tom")

@@ -21,3 +20,3 @@ });

equal(
new Request(Method.GET, "/")
new Request("GET", "/")
.setBody(new Body("body boy"))

@@ -30,3 +29,3 @@ .bodyString(),

equal(
new Request(Method.GET, "/")
new Request("GET", "/")
.setBodystring("tommy boy")

@@ -39,8 +38,8 @@ .bodyString(),

equal(
new Request(Method.GET, "/tom")
new Request("GET", "/tom")
.query("tom", "tosh")
.query("ben", "bosh")
.uri
.uriString,
"/tom?tom=tosh&ben=bosh")
.query,
"tom=tosh&ben=bosh")
});

@@ -50,3 +49,3 @@

equal(
new Request(Method.GET, "some/url")
new Request("GET", "some/url")
.setHeader("tom", "smells")

@@ -59,3 +58,3 @@ .getHeader("tom"),

assert.deepEqual(
new Request(Method.GET, "some/url")
new Request("GET", "some/url")
.setHeader("tom", "smells")

@@ -70,3 +69,3 @@ .setHeader("tom", "smells more")

equal(
new Request(Method.GET, "some/url")
new Request("GET", "some/url")
.setHeader("tom", "smells")

@@ -80,3 +79,3 @@ .replaceHeader("tom", "is nice")

equal(
new Request(Method.GET, "some/url")
new Request("GET", "some/url")
.setHeader("tom", "smells")

@@ -83,0 +82,0 @@ .removeHeader("tom")

import * as assert from "assert";
import {equal, deepEqual} from "assert";
import {Request} from "../../main/core/Request";
import {Method} from "../../main/core/HttpMessage";
import {httpClient} from "../../main/core/Client";
import {routes} from "../../main/core/RoutingHttpHandler";
import {equal} from "assert";
import {Response} from "../../main/core/Response";

@@ -62,4 +58,4 @@ import {Body} from "../../main/core/Body";

undefined);
})
});
});

@@ -8,3 +8,3 @@ import {equal} from "assert";

equal(
Uri.of("/tom/is the sugar/goodness").uriString,
Uri.of("/tom/is the sugar/goodness").template,
"/tom/is%20the%20sugar/goodness");

@@ -38,15 +38,9 @@ });

Uri.of("http://localhost:3000/tom/is the hot sauce/guy").path,
"/tom/is the hot sauce/guy");
"/tom/is%20the%20hot%20sauce/guy");
});
it("parses out the authority from uri string", () => {
equal(
Uri.of("http://localhost:3000/").authority,
"localhost:3000");
});
it("parses out the scheme from uri string", () => {
equal(
Uri.of("http://localhost:3000/").scheme,
"http");
Uri.of("http://localhost:3000/").protocol,
"http:");
});

@@ -57,5 +51,5 @@

Uri.of("http://localhost:3000/?tom=foo&ben=bar").query,
"?tom=foo&ben=bar");
"tom=foo&ben=bar");
});
});
{
"compilerOptions": {
"target": "es5",
"lib": ["es2015"]
"lib": ["es2015"],
"declaration": true,
"outDir": "./dist"
},

@@ -6,0 +8,0 @@ "include": [

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