@epistemology-factory/crocks-web
Advanced tools
Comparing version 0.1.8 to 0.2.0
{ | ||
"name": "@epistemology-factory/crocks-web", | ||
"version": "0.1.8", | ||
"version": "0.2.0", | ||
"description": "Functions to help write web applications with crocks", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -42,2 +42,12 @@ "use strict"; | ||
/** | ||
* `mapError` is a function which converts an error to an HTTP response. | ||
* | ||
* `mapError` takes a table of mappings from error type to function of type (Object -> Object). | ||
* When an error object is provided, mapError will look up the mapping function and apply it to | ||
* the error, returning the response. | ||
* | ||
* If an unknown error type, or an value without a type is passed, the result is a HTTP 500 | ||
* response. | ||
*/ | ||
// mapError :: Object -> Object -> Object | ||
@@ -44,0 +54,0 @@ const mapError = curry((mappings) => |
"use strict"; | ||
const objOf = require("crocks/helpers/objOf"); | ||
const pipe = require("crocks/helpers/pipe"); | ||
const setProp = require("crocks/helpers/setProp"); | ||
const ERROR_TYPES = { | ||
INVALID_ENV_VAR: "invalid-env-var", | ||
MISSING_ENV_VAR: "missing-env-var", | ||
VALIDATION_ERROR: "validation-error" | ||
@@ -13,5 +19,20 @@ } | ||
// envVarError :: String -> String -> Object | ||
const envVarError = (type) => | ||
pipe( | ||
objOf("name"), | ||
setProp("type", type) | ||
) | ||
// invalidEnvVar :: String -> Object | ||
const invalidEnvVar = envVarError(ERROR_TYPES.INVALID_ENV_VAR) | ||
// missingEnvVar :: String -> Object | ||
const missingEnvVar = envVarError(ERROR_TYPES.MISSING_ENV_VAR) | ||
module.exports = { | ||
ERROR_TYPES, | ||
invalidEnvVar, | ||
missingEnvVar, | ||
validationError | ||
} |
"use strict"; | ||
const Async = require("crocks/Async"); | ||
const bimap = require("crocks/pointfree/bimap"); | ||
const asyncToPromise = require("crocks/Async/asyncToPromise"); | ||
const coalesce = require("crocks/pointfree/coalesce"); | ||
const compose = require("crocks/helpers/compose"); | ||
const constant = require("crocks/combinators/constant"); | ||
const curry = require("crocks/helpers/curry"); | ||
const either = require("crocks/pointfree/either"); | ||
const identity = require("crocks/combinators/identity"); | ||
const map = require("crocks/pointfree/map"); | ||
const pipe = require("crocks/helpers/pipe"); | ||
const { LOG_LEVELS } = require("../../logging/logger"); | ||
/** | ||
* In order to return our response to the caller we have to convert any | ||
* error response into an Async.Resolved so that the Promise resolves. | ||
* `handler` is the interfacing function between the Lambda world, and the Crocks world. | ||
* | ||
* Else the Promise will reject and AWS error handling will kick in. | ||
* `handler` takes a function, which when given an object, returns an Async resolved with an | ||
* object representing the HTTP "success" response, or rejected with an object representing the | ||
* HTTP "failure" response. The Async is converted to a Promise which is returned to Lambda. | ||
* | ||
* Because Lambda expects the Promise to resolve to an object representing the HTTP response, | ||
* `handler` will coalesce the Async into a resolved Promise. If the Promise rejects, AWS | ||
* error handling will kick in, and the caller will receive a HTTP 500 with the default | ||
* API Gateway error message. | ||
* | ||
* Lambdas will need to perform some initialisation logic to assemble the handler. | ||
* For example, environment variables will need to be processed to configure the lambda, and | ||
* if the initialisation fails, the lambda should be configured to return an internal server | ||
* error to caller to indicate that the lambda instance is unusable (rather than crashing, | ||
* and having the default AWS Gateway error response being returned). `assembler` can be used | ||
* to take some initial environment and assemble the "request handler" to process incoming | ||
* events. | ||
* | ||
* Consequently, the provided function to `handler` should not directly encapsulate the flow | ||
* to process the request. `requestHandler` should orchestrate the processing of the request | ||
* to a response. | ||
*/ | ||
// returnResponse :: Async Object -> Async Object | ||
const returnResponse = coalesce(identity, identity) | ||
/** | ||
* A lambda handler that returns an object describing an HTTP response | ||
*/ | ||
// handler :: (Object -> Async Object) -> Object -> Promise Object | ||
@@ -25,3 +46,3 @@ const handler = curry((fn) => | ||
fn, | ||
returnResponse, | ||
coalesce(identity, identity), | ||
asyncToPromise | ||
@@ -31,4 +52,58 @@ ) | ||
/** | ||
* `requestHandler` encapsulates the flow of processing an HTTP request to an HTTP response. | ||
* `requestHandler` can be used by a handler factory to produce a request handler that can use | ||
* items from a config, that is created during the lambda assembly. | ||
* | ||
* `requestHandler` takes a logger, and error mapper, a success mapper and a function that can | ||
* process the HTTP request to an Async of an HTTP response. If the Async is Rejected, the | ||
* result is considered a failure and passed to the error mapper, else success is assumed. | ||
* | ||
* After mapping to an HTTP response, the Async is coalesced to a Resolved instance so that | ||
* the final Promise doesn't reject. | ||
* | ||
* Request/responses are logged at debug level to aid in debugging. | ||
*/ | ||
// requestHandler :: (Integer -> String -> a -> a) -> (Object -> Object) -> (Object -> Object) -> (Object -> Async Object) -> Object -> Async Object | ||
const requestHandler = curry((logger, errorMapper, successMapper, fn) => | ||
pipe( | ||
logger(LOG_LEVELS.DEBUG, "request=%j"), | ||
fn, | ||
bimap(logger(LOG_LEVELS.ERROR, "Error processing request error=%j"), identity), | ||
bimap(errorMapper, successMapper), | ||
coalesce(identity, identity), | ||
map(logger(LOG_LEVELS.DEBUG, "response=%j")) | ||
) | ||
) | ||
// mapAssemblerError :: (Object -> Object) -> Object -> (Object -> Async Object) | ||
const mapAssemblerError = (errorMapper) => compose(constant, Async.Rejected, errorMapper) | ||
/** | ||
* `assembler` is a helper for assembling request handlers, which are the functions that process | ||
* HTTP requests to responses. | ||
* | ||
* `assembler` takes a logger, an error mapper, a request handler factory function, and some | ||
* initial environment. The factory is applied to the environment. If an error is returned, the | ||
* error mapper is used to convert the error to a HTTP failure response. | ||
* | ||
* The result of assembling the request handler is a function suitable to be used with `handler` | ||
* | ||
* The `logger` is only used to report assemble errors, and is not used during the processing of | ||
* an HTTP request. | ||
*/ | ||
// assembler :: (Integer -> String -> a -> a) -> (Object -> Object) -> (Object -> Result Object (Object -> Async Object)) -> Object -> Object -> Promise Object | ||
const assembler = curry((logger, errorMapper, factory) => | ||
pipe( | ||
factory, | ||
bimap(logger(LOG_LEVELS.ERROR, "Can't assemble handler error=%j"), identity), | ||
either(mapAssemblerError(errorMapper), identity), | ||
handler | ||
) | ||
) | ||
module.exports = { | ||
handler | ||
assembler, | ||
handler, | ||
requestHandler | ||
} |
@@ -55,3 +55,3 @@ "use strict"; | ||
/* | ||
/** | ||
* `getHeader` looks for a header in an object, but will check for the presence of the key | ||
@@ -58,0 +58,0 @@ * taking into account variations in how headers are capitalised. |
@@ -27,3 +27,3 @@ "use strict"; | ||
/** | ||
* Creates a response object suitable to result from a lambda to API Gateway. | ||
* Creates a response object suitable to result from a Lambda to API Gateway. | ||
* | ||
@@ -30,0 +30,0 @@ * Will always return a JSON body, otherwise API Gateway doesn't like the response. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23956
21
652