io-ts-serverless-handler
Advanced tools
Comparing version 1.0.4 to 2.0.0
@@ -6,2 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Either_1 = require("fp-ts/lib/Either"); | ||
const jest_each_1 = __importDefault(require("jest-each")); | ||
@@ -20,15 +21,21 @@ const codecs_1 = require("../codecs"); | ||
['{ "hello": 4 '] | ||
]).test("fails when decoding [%p]", input => { | ||
]).test("fails when decoding [%p]", (input) => { | ||
expect.assertions(2); | ||
const result = codecs_1.jsonFromStringCodec.decode(input); | ||
expect(result.isLeft()).toBe(true); | ||
expect(result.value).toMatchSnapshot(); | ||
expect(Either_1.isLeft(result)).toBe(true); | ||
if (Either_1.isLeft(result)) { | ||
expect(result.left).toMatchSnapshot(); | ||
} | ||
}); | ||
}); | ||
describe("when decoding a valid input", () => { | ||
jest_each_1.default([["null"], ["8"], ["false"], ['{ "hello": 4 }']]).test("succeeds when decoding [%p]", input => { | ||
jest_each_1.default([["null"], ["8"], ["false"], ['{ "hello": 4 }']]).test("succeeds when decoding [%p]", (input) => { | ||
expect.assertions(2); | ||
const result = codecs_1.jsonFromStringCodec.decode(input); | ||
expect(result.isRight()).toBe(true); | ||
expect(result.value).toMatchSnapshot(); | ||
expect(Either_1.isRight(result)).toBe(true); | ||
if (Either_1.isRight(result)) { | ||
expect(result.right).toMatchSnapshot(); | ||
} | ||
}); | ||
}); | ||
}); |
@@ -10,2 +10,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Either_1 = require("fp-ts/lib/Either"); | ||
const t = __importStar(require("io-ts")); | ||
@@ -19,5 +20,5 @@ const default_handlers_1 = require("../default-handlers"); | ||
expect.assertions(2); | ||
expect(validationError.isLeft()).toBe(true); | ||
if (validationError.isLeft()) { | ||
expect(default_handlers_1.defaultValidationErrorHandler(validationError.value)).toMatchSnapshot(); | ||
expect(Either_1.isLeft(validationError)).toBe(true); | ||
if (Either_1.isLeft(validationError)) { | ||
expect(default_handlers_1.defaultValidationErrorHandler(validationError.left)).toMatchSnapshot(); | ||
} | ||
@@ -24,0 +25,0 @@ }); |
@@ -11,2 +11,3 @@ "use strict"; | ||
const t = __importStar(require("io-ts")); | ||
const NumberFromString_1 = require("io-ts-types/lib/NumberFromString"); | ||
const __1 = require(".."); | ||
@@ -19,3 +20,3 @@ // tslint:disable: no-duplicate-string no-identical-functions | ||
queryStringParameters: t.type({ | ||
pageSize: t.number | ||
pageSize: NumberFromString_1.NumberFromString | ||
}), | ||
@@ -34,3 +35,3 @@ body: t.type({ | ||
queryStringParameters: { | ||
pageSize: 4 | ||
pageSize: "4" | ||
}, | ||
@@ -51,3 +52,3 @@ body: JSON.stringify({ | ||
queryStringParameters: { | ||
pageSize: 4 | ||
pageSize: "4" | ||
}, | ||
@@ -63,3 +64,3 @@ body: 5 | ||
queryStringParameters: { | ||
pageSize: "string" | ||
pageSize: "not-a-number" | ||
}, | ||
@@ -76,3 +77,3 @@ body: false | ||
queryStringParameters: t.type({ | ||
pageNumber: t.number | ||
pageNumber: NumberFromString_1.NumberFromString | ||
}) | ||
@@ -85,3 +86,3 @@ }, | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
} | ||
@@ -98,7 +99,7 @@ }; | ||
queryStringParameters: t.type({ | ||
pageNumber: t.number, | ||
pageSize: t.union([t.undefined, t.number]) | ||
pageNumber: NumberFromString_1.NumberFromString, | ||
pageSize: t.union([t.undefined, NumberFromString_1.NumberFromString]) | ||
}), | ||
headers: t.partial({ | ||
someHeader: t.number | ||
someHeader: NumberFromString_1.NumberFromString | ||
}) | ||
@@ -116,3 +117,3 @@ }, async ({ queryStringParameters: { pageNumber, pageSize }, headers: { someHeader } }) => ({ | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
} | ||
@@ -129,3 +130,3 @@ }; | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
}, | ||
@@ -143,3 +144,3 @@ headers: {} | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
}, | ||
@@ -157,7 +158,7 @@ headers: null | ||
queryStringParameters: { | ||
pageNumber: 4, | ||
pageSize: 9 | ||
pageNumber: "4", | ||
pageSize: "9" | ||
}, | ||
headers: { | ||
someHeader: 6 | ||
someHeader: "6" | ||
} | ||
@@ -175,3 +176,3 @@ }; | ||
queryStringParameters: t.type({ | ||
pageNumber: t.number | ||
pageNumber: NumberFromString_1.NumberFromString | ||
}) | ||
@@ -181,7 +182,7 @@ }, async (params) => params); | ||
queryStringParameters: { | ||
pageNumber: 4, | ||
pageNumber: "4", | ||
extraParameter: "hello" | ||
}, | ||
pathParameters: { | ||
something: true | ||
something: "true" | ||
} | ||
@@ -202,3 +203,3 @@ }; | ||
queryStringParameters: t.type({ | ||
pageNumber: t.number | ||
pageNumber: NumberFromString_1.NumberFromString | ||
}) | ||
@@ -209,3 +210,3 @@ }, async (params) => params); | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
} | ||
@@ -222,7 +223,7 @@ }; | ||
queryStringParameters: { | ||
pageNumber: 4, | ||
pageNumber: "4", | ||
extraParameter: "hello" | ||
}, | ||
pathParameters: { | ||
something: true | ||
something: "true" | ||
} | ||
@@ -263,3 +264,3 @@ }; | ||
queryStringParameters: t.type({ | ||
pageNumber: t.number | ||
pageNumber: NumberFromString_1.NumberFromString | ||
}) | ||
@@ -276,3 +277,3 @@ }, async ({ queryStringParameters: { pageNumber } }) => ({ | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
}, | ||
@@ -292,3 +293,3 @@ body: JSON.stringify({ | ||
queryStringParameters: { | ||
pageSize: 4 | ||
pageSize: "4" | ||
}, | ||
@@ -314,3 +315,3 @@ body: 5 | ||
queryStringParameters: t.type({ | ||
pageNumber: t.number | ||
pageNumber: NumberFromString_1.NumberFromString | ||
}) | ||
@@ -323,3 +324,3 @@ }, | ||
queryStringParameters: { | ||
pageNumber: 4 | ||
pageNumber: "4" | ||
} | ||
@@ -326,0 +327,0 @@ }; |
import * as t from "io-ts"; | ||
import { JSONValue } from "./types"; | ||
import { JsonValue } from "type-fest"; | ||
/** | ||
@@ -9,2 +9,2 @@ * A codec that takes a JSON string and does two things: | ||
*/ | ||
export declare const jsonFromStringCodec: t.Type<JSONValue, string, unknown>; | ||
export declare const jsonFromStringCodec: t.Type<JsonValue, string, unknown>; |
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda"; | ||
import * as t from "io-ts"; | ||
import { HandlerConfig, HandlerFunction } from "./types"; | ||
export * from "./types"; | ||
/** | ||
@@ -17,2 +18,1 @@ * Takes an optional config object and returns a function that wraps | ||
}>, ReturnType_1>(codecMaps: EventMap, handlerFn: HandlerFunction<EventMap, ReturnType_1>) => (event: APIGatewayProxyEvent) => Promise<APIGatewayProxyResult>; | ||
export * from "./types"; |
@@ -10,2 +10,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Either_1 = require("fp-ts/lib/Either"); | ||
const t = __importStar(require("io-ts")); | ||
@@ -68,9 +69,9 @@ const codecs_1 = require("./codecs"); | ||
}); | ||
if (decoded.isLeft()) { | ||
if (Either_1.isLeft(decoded)) { | ||
// There was an error validating the event | ||
// This would probably be returned with a 400 status code | ||
return validationErrorHandler(decoded.value); | ||
return validationErrorHandler(decoded.left); | ||
} | ||
try { | ||
const result = await handlerFn(decoded.value); | ||
const result = await handlerFn(decoded.right); | ||
// Everything went OK and the handler function returned a value | ||
@@ -77,0 +78,0 @@ // This would probably be returned with a 200 status code |
@@ -45,17 +45,2 @@ import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda"; | ||
/** | ||
* Represents a generic JSON object that is part of a JSONValue | ||
*/ | ||
export declare type JSONObject = { | ||
readonly [key: string]: JSONValue; | ||
}; | ||
/** | ||
* Represents a generic JSON array which is part of a JSONValue | ||
*/ | ||
export interface JSONArray extends Array<JSONValue> { | ||
} | ||
/** | ||
* Represents a generic JSON value that is parsed from a JSON string | ||
*/ | ||
export declare type JSONValue = null | string | number | boolean | JSONArray | JSONObject; | ||
/** | ||
* Represents the set of config that is required to set up the handler wrapper | ||
@@ -62,0 +47,0 @@ */ |
{ | ||
"name": "io-ts-serverless-handler", | ||
"version": "1.0.4", | ||
"version": "2.0.0", | ||
"description": "A simple wrapper for Serverless Framework HTTP handlers to remove the boilerplate of using io-ts codecs to validate and extract request parameters", | ||
@@ -26,5 +26,8 @@ "main": "dist/index.js", | ||
"format": "prettier --write '{src,test}/**/*.{ts,tsx}'", | ||
"commit": "git-cz" | ||
"commit": "git-cz", | ||
"quality-check": "yon test && yon lint && yon format-check && yon type-coverage" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^8.3.5", | ||
"@commitlint/config-conventional": "^8.3.4", | ||
"@types/aws-lambda": "^8.10.39", | ||
@@ -34,6 +37,10 @@ "@types/jest": "^24.0.25", | ||
"cz-conventional-changelog": "3.0.2", | ||
"fp-ts": "^1.19.5", | ||
"io-ts": "^1.10.4", | ||
"fp-ts": "^2.4.1", | ||
"husky": "^4.2.3", | ||
"io-ts": "^2.0.5", | ||
"io-ts-types": "^0.5.6", | ||
"jest": "^24.9.0", | ||
"jest-each": "^24.9.0", | ||
"monocle-ts": "^2.1.0", | ||
"newtype-ts": "^0.3.4", | ||
"prettier": "^1.19.1", | ||
@@ -48,3 +55,4 @@ "prettier-check": "^2.0.0", | ||
"type-coverage": "^2.4.0", | ||
"typescript": "^3.7.4" | ||
"typescript": "^3.7.4", | ||
"yarn-or-npm": "^3.0.1" | ||
}, | ||
@@ -55,3 +63,15 @@ "config": { | ||
} | ||
}, | ||
"dependencies": { | ||
"type-fest": "^0.11.0" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "yon quality-check", | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
} | ||
}, | ||
"typeCoverage": { | ||
"atLeast": 100 | ||
} | ||
} |
# io-ts-serverless-handler | ||
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) | ||
A simple wrapper for [Serverless Framework](https://github.com/serverless/serverless) HTTP handlers | ||
@@ -31,2 +33,3 @@ to remove the boilerplate of using [io-ts](https://github.com/gcanti/io-ts) codecs to validate and extract request parameters. | ||
import { codecHandler } from "./codec-handler.ts"; | ||
import { NumberFromString } from "io-ts-types/lib/NumberFromString"; | ||
@@ -36,7 +39,7 @@ export const getUsers = codecHandler( | ||
queryParameters: t.partial({ | ||
pageSize: t.number, | ||
pageNumber: t.number | ||
pageSize: NumberFromString, | ||
pageNumber: NumberFromString | ||
}), | ||
pathParameters: t.type({ | ||
userId: t.string | ||
userId: NumberFromString | ||
}) | ||
@@ -55,7 +58,19 @@ }, | ||
The request body will parsed as JSON and then passed to | ||
your codec. | ||
All the other parameters from API Gateway will come through | ||
as strings so if you want to decode a non-string type you will | ||
have to use a codec that accepts a string, converts it to the type | ||
you want and than validates that. | ||
There are a lot of types in the | ||
[io-ts-types](https://github.com/gcanti/io-ts-types) | ||
library that can do this for you such as `NumberFromString` | ||
or `BooleanFromString`. | ||
## Roadmap | ||
1. Better documentation | ||
2. Support io-ts/fp-ts 2.x | ||
3. CI/CD | ||
4. Support for serverless handlers for providers other than AWS | ||
2. CI/CD | ||
3. Support for serverless handlers for providers other than AWS |
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
31083
26
74
3
25
734
+ Addedtype-fest@^0.11.0
+ Addedtype-fest@0.11.0(transitive)