diff --git a/.gitignore b/.gitignore index 030f151..e306283 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ +/.* +!/.gitignore +!/.jscsrc +!/.jshintrc +!/.travis.yml /bower_components/ /node_modules/ /output/ -/.psci* -/src/.webpack.js diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000..2561ce9 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,17 @@ +{ + "preset": "grunt", + "disallowSpacesInFunctionExpression": null, + "requireSpacesInFunctionExpression": { + "beforeOpeningRoundBrace": true, + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInAnonymousFunctionExpression": null, + "requireSpacesInAnonymousFunctionExpression": { + "beforeOpeningRoundBrace": true, + "beforeOpeningCurlyBrace": true + }, + "disallowSpacesInsideObjectBrackets": null, + "requireSpacesInsideObjectBrackets": "all", + "validateQuoteMarks": "\"", + "requireCurlyBraces": null +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..e73b39a --- /dev/null +++ b/.jshintrc @@ -0,0 +1,19 @@ +{ + "bitwise": true, + "eqeqeq": true, + "forin": true, + "freeze": true, + "funcscope": true, + "futurehostile": true, + "strict": "global", + "latedef": true, + "noarg": true, + "nocomma": true, + "nonew": true, + "notypeof": true, + "singleGroups": true, + "undef": true, + "unused": true, + "eqnull": true, + "predef": ["exports", "require", "process"] +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..969f56d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +language: node_js +dist: trusty +sudo: required +node_js: 6 +install: + - npm install -g bower + - npm install +script: + - bower install --production + - npm run -s build + - bower install + - npm test +after_success: +- >- + test $TRAVIS_TAG && + echo $GITHUB_TOKEN | pulp login && + echo y | pulp publish --no-push diff --git a/README.md b/README.md index 0a3b992..cdef816 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,16 @@ # purescript-node-http -A wrapper for Node's HTTP APIs +[![Latest release](http://img.shields.io/github/release/purescript-node/purescript-node-http.svg)](https://github.com/purescript/purescript-node-http/releases) +[![Build Status](https://travis-ci.org/purescript-node/purescript-node-http.svg?branch=master)](https://travis-ci.org/purescript-node/purescript-node-http) -- [Module Documentation](docs/Node) -- [Example](test/Main.purs) +A wrapper for Node's HTTP APIs. + +## Installation + +``` +bower install purescript-node-http +``` + +## Documentation + +Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-node-http). diff --git a/bower.json b/bower.json index 55f549d..58ccb2d 100644 --- a/bower.json +++ b/bower.json @@ -12,13 +12,13 @@ "url": "git://github.com/purescript-node/purescript-node-http.git" }, "devDependencies": { - "purescript-console": "^1.0.0" + "purescript-console": "^2.0.0" }, "dependencies": { - "purescript-maps": "^1.0.0", - "purescript-node-streams": "^1.0.0", - "purescript-node-url": "^1.0.0", - "purescript-options": "^1.0.0", - "purescript-unsafe-coerce": "^1.0.0" + "purescript-maps": "^2.0.0", + "purescript-node-streams": "^2.0.0", + "purescript-node-url": "^2.0.0", + "purescript-options": "^2.0.0", + "purescript-unsafe-coerce": "^2.0.0" } } diff --git a/docs/Node/HTTP.md b/docs/Node/HTTP.md deleted file mode 100644 index f088893..0000000 --- a/docs/Node/HTTP.md +++ /dev/null @@ -1,133 +0,0 @@ -## Module Node.HTTP - -This module defines low-level bindings to the Node HTTP module. - -#### `Server` - -``` purescript -data Server :: * -``` - -The type of a HTTP server object - -#### `Request` - -``` purescript -data Request :: * -``` - -A HTTP request object - -#### `Response` - -``` purescript -data Response :: * -``` - -A HTTP response object - -#### `HTTP` - -``` purescript -data HTTP :: ! -``` - -The effect associated with using the HTTP module. - -#### `createServer` - -``` purescript -createServer :: forall eff. (Request -> Response -> Eff (http :: HTTP | eff) Unit) -> Eff (http :: HTTP | eff) Server -``` - -Create a HTTP server, given a function to be executed when a request is received. - -#### `listen` - -``` purescript -listen :: forall eff. Server -> Int -> Eff (http :: HTTP | eff) Unit -> Eff (http :: HTTP | eff) Unit -``` - -Listen on the specified port. The specified callback will be run when setup is complete. - -#### `httpVersion` - -``` purescript -httpVersion :: Request -> String -``` - -Get the request HTTP version - -#### `requestHeaders` - -``` purescript -requestHeaders :: Request -> StrMap String -``` - -Get the request headers as a hash - -#### `requestMethod` - -``` purescript -requestMethod :: Request -> String -``` - -Get the request method (GET, POST, etc.) - -#### `requestURL` - -``` purescript -requestURL :: Request -> String -``` - -Get the request URL - -#### `requestAsStream` - -``` purescript -requestAsStream :: forall eff. Request -> Readable () (http :: HTTP | eff) -``` - -Coerce the request object into a readable stream. - -#### `setHeader` - -``` purescript -setHeader :: forall eff. Response -> String -> String -> Eff (http :: HTTP | eff) Unit -``` - -Set a header with a single value. - -#### `setHeaders` - -``` purescript -setHeaders :: forall eff. Response -> String -> Array String -> Eff (http :: HTTP | eff) Unit -``` - -Set a header with multiple values. - -#### `setStatusCode` - -``` purescript -setStatusCode :: forall eff. Response -> Int -> Eff (http :: HTTP | eff) Unit -``` - -Set the status code. - -#### `setStatusMessage` - -``` purescript -setStatusMessage :: forall eff. Response -> String -> Eff (http :: HTTP | eff) Unit -``` - -Set the status message. - -#### `responseAsStream` - -``` purescript -responseAsStream :: forall eff. Response -> Writable () (http :: HTTP | eff) -``` - -Coerce the response object into a writable stream. - - diff --git a/docs/Node/HTTP/Client.md b/docs/Node/HTTP/Client.md deleted file mode 100644 index 4b2314a..0000000 --- a/docs/Node/HTTP/Client.md +++ /dev/null @@ -1,192 +0,0 @@ -## Module Node.HTTP.Client - -This module defines low-level bindings to the Node HTTP client. - -#### `Request` - -``` purescript -data Request :: * -``` - -A HTTP request object - -#### `Response` - -``` purescript -data Response :: * -``` - -A HTTP response object - -#### `RequestHeaders` - -``` purescript -newtype RequestHeaders - = RequestHeaders (StrMap String) -``` - -A HTTP request object - -#### `RequestOptions` - -``` purescript -data RequestOptions -``` - -The type of HTTP request options - -#### `RequestFamily` - -``` purescript -data RequestFamily - = IPV4 - | IPV6 -``` - -Values for the `family` request option - -#### `protocol` - -``` purescript -protocol :: Option RequestOptions String -``` - -The protocol to use - -#### `hostname` - -``` purescript -hostname :: Option RequestOptions String -``` - -Domain name or IP - -#### `port` - -``` purescript -port :: Option RequestOptions Int -``` - -Port of remote server - -#### `method` - -``` purescript -method :: Option RequestOptions String -``` - -The HTTP request method: GET, POST, etc. - -#### `path` - -``` purescript -path :: Option RequestOptions String -``` - -The request path, including query string if appropriate. - -#### `headers` - -``` purescript -headers :: Option RequestOptions RequestHeaders -``` - -#### `auth` - -``` purescript -auth :: Option RequestOptions String -``` - -Basic authentication - -#### `family` - -``` purescript -family :: Option RequestOptions RequestFamily -``` - -IP address family to use when resolving `hostname`. -Valid values are `IPV6` and `IPV4` - -#### `request` - -``` purescript -request :: forall eff. Options RequestOptions -> (Response -> Eff (http :: HTTP | eff) Unit) -> Eff (http :: HTTP | eff) Request -``` - -Make a HTTP request using the specified options and response callback. - -#### `requestFromURI` - -``` purescript -requestFromURI :: forall eff. String -> (Response -> Eff (http :: HTTP | eff) Unit) -> Eff (http :: HTTP | eff) Request -``` - -Make a HTTP request from a URI string and response callback. - -#### `requestAsStream` - -``` purescript -requestAsStream :: forall eff r. Request -> Writable r (http :: HTTP | eff) -``` - -Create a writable stream from a request object. - -#### `responseAsStream` - -``` purescript -responseAsStream :: forall eff w. Response -> Readable w (http :: HTTP | eff) -``` - -Create a readable stream from a response object. - -#### `setTimeout` - -``` purescript -setTimeout :: forall eff. Request -> Int -> Eff (http :: HTTP | eff) Unit -> Eff (http :: HTTP | eff) Unit -``` - -Set the socket timeout for a `Request` - -#### `httpVersion` - -``` purescript -httpVersion :: Response -> String -``` - -Get the request HTTP version - -#### `responseHeaders` - -``` purescript -responseHeaders :: Response -> StrMap String -``` - -Get the response headers as a hash -Cookies are not included and could be retrieved with responseCookies - -#### `responseCookies` - -``` purescript -responseCookies :: Response -> Maybe (Array String) -``` - -Get the response cookies as Just (Array String) or Nothing if no cookies - -#### `statusCode` - -``` purescript -statusCode :: Response -> Int -``` - -Get the response status code - -#### `statusMessage` - -``` purescript -statusMessage :: Response -> String -``` - -Get the response status message - - diff --git a/package.json b/package.json new file mode 100644 index 0000000..3e013cf --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "private": true, + "scripts": { + "clean": "rimraf output && rimraf .pulp-cache", + "build": "jshint src && jscs src && pulp build --censor-lib --strict", + "test": "pulp build -I test" + }, + "devDependencies": { + "jscs": "^3.0.7", + "jshint": "^2.9.4", + "pulp": "^9.0.1", + "purescript-psa": "^0.3.9", + "purescript": "^0.10.1", + "rimraf": "^2.5.4" + } +} diff --git a/src/Node/HTTP.js b/src/Node/HTTP.js index 4c8f410..d9c6687 100644 --- a/src/Node/HTTP.js +++ b/src/Node/HTTP.js @@ -1,20 +1,20 @@ "use strict"; -var http = require('http'); +var http = require("http"); -exports.createServer = function(handleRequest) { - return function() { - return http.createServer(function(req, res) { +exports.createServer = function (handleRequest) { + return function () { + return http.createServer(function (req, res) { handleRequest(req)(res)(); }); }; }; -exports.listen = function(server) { - return function(port) { - return function(done) { - return function() { - server.listen(port, function() { +exports.listen = function (server) { + return function (port) { + return function (done) { + return function () { + server.listen(port, function () { done(); }); }; @@ -22,37 +22,37 @@ exports.listen = function(server) { }; }; -exports.setHeader = function(res) { - return function(key) { - return function(value) { - return function() { +exports.setHeader = function (res) { + return function (key) { + return function (value) { + return function () { res.setHeader(key, value); }; }; }; }; -exports.setHeaders = function(res) { - return function(key) { - return function(values) { - return function() { +exports.setHeaders = function (res) { + return function (key) { + return function (values) { + return function () { res.setHeader(key, values); }; }; }; }; -exports.setStatusCode = function(res) { - return function(code) { - return function() { +exports.setStatusCode = function (res) { + return function (code) { + return function () { res.statusCode = code; }; }; }; -exports.setStatusMessage = function(res) { - return function(message) { - return function() { +exports.setStatusMessage = function (res) { + return function (message) { + return function () { res.statusMessage = message; }; }; diff --git a/src/Node/HTTP.purs b/src/Node/HTTP.purs index 40e60ba..d368e2c 100644 --- a/src/Node/HTTP.purs +++ b/src/Node/HTTP.purs @@ -5,8 +5,11 @@ module Node.HTTP where import Prelude import Control.Monad.Eff (Eff) + import Data.StrMap (StrMap) + import Node.Stream (Writable, Readable) + import Unsafe.Coerce (unsafeCoerce) -- | The type of a HTTP server object diff --git a/src/Node/HTTP/Client.js b/src/Node/HTTP/Client.js index fcc8f12..59bddd5 100644 --- a/src/Node/HTTP/Client.js +++ b/src/Node/HTTP/Client.js @@ -1,23 +1,23 @@ "use strict"; -var http = require('http'); -var https = require('https'); +var http = require("http"); +var https = require("https"); -exports.requestImpl = function(opts) { - return function(k) { - return function() { - var lib = opts.protocol === 'https:' ? https : http; - return lib.request(opts, function(res) { +exports.requestImpl = function (opts) { + return function (k) { + return function () { + var lib = opts.protocol === "https:" ? https : http; + return lib.request(opts, function (res) { k(res)(); }); }; }; }; -exports.setTimeout = function(r) { - return function(ms) { - return function(k) { - return function() { +exports.setTimeout = function (r) { + return function (ms) { + return function (k) { + return function () { r.setTimeout(ms, k); }; }; diff --git a/src/Node/HTTP/Client.purs b/src/Node/HTTP/Client.purs index 81aca67..6a92c18 100644 --- a/src/Node/HTTP/Client.purs +++ b/src/Node/HTTP/Client.purs @@ -1,10 +1,10 @@ -- | This module defines low-level bindings to the Node HTTP client. module Node.HTTP.Client - ( Request() - , Response() + ( Request + , Response , RequestHeaders(..) - , RequestOptions() + , RequestOptions , RequestFamily(..) , protocol , hostname @@ -29,17 +29,20 @@ module Node.HTTP.Client , statusMessage ) where -import Prelude (Unit, (<<<), ($)) +import Prelude import Control.Monad.Eff (Eff) -import Data.Maybe (Maybe) + import Data.Foreign (Foreign, toForeign) -import Data.Options (Options, Option, options, opt) -import Data.StrMap (StrMap(), delete, lookup) import Data.Functor.Contravariant ((>$<)) -import Node.HTTP (HTTP()) +import Data.Maybe (Maybe) +import Data.Options (Options, Option, options, opt) +import Data.StrMap (StrMap, delete, lookup) + +import Node.HTTP (HTTP) import Node.Stream (Readable, Writable) import Node.URL as URL + import Unsafe.Coerce (unsafeCoerce) -- | A HTTP request object diff --git a/test/Main.purs b/test/Main.purs index 3c4eae2..19bfae8 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -2,13 +2,16 @@ module Test.Main where import Prelude -import Node.Encoding (Encoding(..)) -import Node.HTTP (HTTP, listen, createServer, setHeader, requestMethod, requestURL, responseAsStream, requestAsStream, setStatusCode) -import Node.Stream (Writable, end, pipe, writeString) -import Node.HTTP.Client as Client import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, log, logShow) + import Data.Foldable (foldMap) + +import Node.Encoding (Encoding(..)) +import Node.HTTP (HTTP, listen, createServer, setHeader, requestMethod, requestURL, responseAsStream, requestAsStream, setStatusCode) +import Node.HTTP.Client as Client +import Node.Stream (Writable, end, pipe, writeString) + import Partial.Unsafe (unsafeCrashWith) foreign import stdout :: forall eff r. Writable r eff @@ -50,8 +53,8 @@ testHttps = simpleReq "https://pursuit.purescript.org/packages/purescript-node-http/badge" testCookies :: forall eff. Eff (console :: CONSOLE, http :: HTTP | eff) Unit -testCookies = - simpleReq +testCookies = + simpleReq "https://httpbin.org/cookies/set?cookie1=firstcookie&cookie2=secondcookie" simpleReq :: forall eff. String -> Eff (console :: CONSOLE, http :: HTTP | eff) Unit