diff --git a/.eslintrc.yml b/.eslintrc.yml index 0733e51..080b4b7 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -5,10 +5,10 @@ env: plugins: - jest ignorePatterns: - - "**/*.test.js" + - "**/*.d.ts" extends: - eslint:recommended - prettier parserOptions: - ecmaVersion: 2021 + ecmaVersion: 2022 sourceType: module diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 456dfaf..99e91d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,8 +4,10 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install modules run: yarn - name: Run lint run: yarn lint + - name: Run lint + run: yarn test diff --git a/.gitignore b/.gitignore index 682446c..3ca6a9c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # Don't edit this part .yarn/cache/*.zip -coverage_cjs # Created by https://www.toptal.com/developers/gitignore/api/node,intellij+all,yarn # Edit at https://www.toptal.com/developers/gitignore?templates=node,intellij+all,yarn diff --git a/.husky/pre-commit b/.husky/pre-commit index e136717..8a31f84 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -3,4 +3,4 @@ yarn lint yarn test -git add index.esm.js index.cjs index.esm.d.ts +git add index.js index.d.ts diff --git a/.nvmrc b/.nvmrc index d939939..02c8b48 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.13.0 +18.18.0 diff --git a/README.md b/README.md index 539f1e9..be04dc5 100644 --- a/README.md +++ b/README.md @@ -1 +1,106 @@ +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +![Static Badge](https://img.shields.io/badge/coverage-100-brightgreen) +![Static Badge](https://img.shields.io/badge/release-3.0.1-blue) +[![test](https://github.com/mathrobin/lambda-returns/actions/workflows/test.yml/badge.svg)](https://github.com/mathrobin/lambda-returns/actions/workflows/test.yml) + # lambda-returns + +Provides shorthand to manage AWS lambda result. And provides test helper methods too! + +ESM only since v3. Typings included. + +## Usage + +Deadly simple + +```javascript +import { ok, internalServerError } from "lambda-returns"; + +export default async () => { + try { + + return ok({ + status: "success" + }); + } catch (err) { + + return internalServerError({ + status: "error", + error: err + }); + } +} +``` + +instead of that non-funny code: + +```javascript +export default async () => { + try { + + return { + statusCode: 200, + body: JSON.stringify({ + status: "success" + }), + }; + } catch (err) { + + return { + statusCode: 500, + body: JSON.stringify({ + status: "error", + error: err + }), + }; + } +} +``` + +### Test helpers methods + +Not enough for you? For me too. This package provides a simple way to test your return result from your AWS lambda +handler method. + +```javascript +import { isOk, isBadRequest } from "lambda-returns"; + +expect(isOk(result)).toBeTruthy(); +expect(isBadRequest(result)).toBeTruthy(); +``` + +## Pros + +- No prod dependency +- Typings provided +- lower than 45kB unpacked + +### Stop remember codes + +You don't have to remember status code values. Just the name which is more "menaningful". Who really knows the code of: + +- insufficientStorage +- partialContent +- imATeapot + . You ? Me no. And don't want/need to. + +### Stop polluting your business logic + +Moreover, into vanilla AWS lambda way, you need to return a string as body. But just stringify your result is dangerous, +if you have a dynamic result, maybe is null, maybe is undefined, maybe you already have a string. + +F*ck! I don't want to care of it in my business logic! `lambda-returns` manages it for you. + +## Cons + +There is only one known pitfall. We can't technically export "continue" status due to it's a reserved word in +JavaScript. + +```javascript +export const continue += {}; // or whatever; +``` + +This is just forbidden. If you knwon any way to go over this problem, tell me. + +Despite to this problem, test helper method `isContinue` is available. diff --git a/build.js b/build.js index 2969e8d..d5445fa 100644 --- a/build.js +++ b/build.js @@ -1,70 +1,9 @@ import fs from 'fs'; -const codes = { - continue: 100, - switchingProtocols: 101, - processing: 102, - ok: 200, - created: 201, - accepted: 202, - nonAuthoritativeInformation: 203, - noContent: 204, - resetContent: 205, - partialContent: 206, - multiStatus: 207, - multipleChoices: 300, - movedPermanently: 301, - movedTemporarily: 302, - seeOther: 303, - notModified: 304, - useProxy: 305, - temporaryRedirect: 307, - badRequest: 400, - unauthorized: 401, - paymentRequired: 402, - forbidden: 403, - notFound: 404, - methodNotAllowed: 405, - notAcceptable: 406, - proxyAuthenticationRequired: 407, - requestTimeOut: 408, - conflict: 409, - gone: 410, - lengthRequired: 411, - preconditionFailed: 412, - requestEntityTooLarge: 413, - requestUriTooLarge: 414, - unsupportedMediaType: 415, - requestedRangeNotSatisfiable: 416, - expectationFailed: 417, - imATeapot: 418, - unprocessableEntity: 422, - locked: 423, - failedDependency: 424, - unorderedCollection: 425, - upgradeRequired: 426, - preconditionRequired: 428, - tooManyRequests: 429, - requestHeaderFieldsTooLarge: 431, - internalServerError: 500, - notImplemented: 501, - badGateway: 502, - serviceUnavailable: 503, - gatewayTimeOut: 504, - httpVersionNotSupported: 505, - variantAlsoNegotiates: 506, - insufficientStorage: 507, - bandwidthLimitExceeded: 509, - notExtended: 510, - networkAuthenticationRequired: 511, -}; +import capitalizeFirstLetter from './src/capitalize_first/index.js'; +import codes from './codes.js'; const exportsEsm = []; -const exportsCjs = []; - -function capitalizeFirstLetter(string) { - return string[0].toUpperCase() + string.slice(1); -} Object.entries(codes) .filter(([message]) => { @@ -77,12 +16,6 @@ Object.entries(codes) headers, body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, });`); - - exportsCjs.push(`module.exports.${message} = (result, headers = {}) => ({ - statusCode: ${code}, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -});`); }); Object.entries(codes).forEach(([message, code]) => { @@ -91,17 +24,8 @@ Object.entries(codes).forEach(([message, code]) => { )} = (response) => { return response.statusCode === ${code}; };`); - - exportsCjs.push(`module.exports.is${capitalizeFirstLetter( - message - )} = (response) => { - return response.statusCode === ${code}; -};`); }); -fs.writeFile('./index.esm.js', exportsEsm.join('\n\n'), () => { - console.log('Version ES Module generated'); -}); -fs.writeFile('./index.cjs', exportsCjs.join('\n\n'), () => { - console.log('Version CommonJs generated'); +fs.writeFile('./index.js', exportsEsm.join('\n\n'), () => { + console.log('Module generated'); }); diff --git a/codes.js b/codes.js new file mode 100644 index 0000000..2dc4509 --- /dev/null +++ b/codes.js @@ -0,0 +1,58 @@ +export default { + continue: 100, + switchingProtocols: 101, + processing: 102, + ok: 200, + created: 201, + accepted: 202, + nonAuthoritativeInformation: 203, + noContent: 204, + resetContent: 205, + partialContent: 206, + multiStatus: 207, + multipleChoices: 300, + movedPermanently: 301, + movedTemporarily: 302, + seeOther: 303, + notModified: 304, + useProxy: 305, + temporaryRedirect: 307, + badRequest: 400, + unauthorized: 401, + paymentRequired: 402, + forbidden: 403, + notFound: 404, + methodNotAllowed: 405, + notAcceptable: 406, + proxyAuthenticationRequired: 407, + requestTimeOut: 408, + conflict: 409, + gone: 410, + lengthRequired: 411, + preconditionFailed: 412, + requestEntityTooLarge: 413, + requestUriTooLarge: 414, + unsupportedMediaType: 415, + requestedRangeNotSatisfiable: 416, + expectationFailed: 417, + imATeapot: 418, + unprocessableEntity: 422, + locked: 423, + failedDependency: 424, + unorderedCollection: 425, + upgradeRequired: 426, + preconditionRequired: 428, + tooManyRequests: 429, + requestHeaderFieldsTooLarge: 431, + internalServerError: 500, + notImplemented: 501, + badGateway: 502, + serviceUnavailable: 503, + gatewayTimeOut: 504, + httpVersionNotSupported: 505, + variantAlsoNegotiates: 506, + insufficientStorage: 507, + bandwidthLimitExceeded: 509, + notExtended: 510, + networkAuthenticationRequired: 511, +}; diff --git a/index.cjs b/index.cjs deleted file mode 100644 index 7ddb698..0000000 --- a/index.cjs +++ /dev/null @@ -1,553 +0,0 @@ -module.exports.switchingProtocols = (result, headers = {}) => ({ - statusCode: 101, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.processing = (result, headers = {}) => ({ - statusCode: 102, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.ok = (result, headers = {}) => ({ - statusCode: 200, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.created = (result, headers = {}) => ({ - statusCode: 201, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.accepted = (result, headers = {}) => ({ - statusCode: 202, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.nonAuthoritativeInformation = (result, headers = {}) => ({ - statusCode: 203, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.noContent = (result, headers = {}) => ({ - statusCode: 204, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.resetContent = (result, headers = {}) => ({ - statusCode: 205, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.partialContent = (result, headers = {}) => ({ - statusCode: 206, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.multiStatus = (result, headers = {}) => ({ - statusCode: 207, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.multipleChoices = (result, headers = {}) => ({ - statusCode: 300, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.movedPermanently = (result, headers = {}) => ({ - statusCode: 301, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.movedTemporarily = (result, headers = {}) => ({ - statusCode: 302, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.seeOther = (result, headers = {}) => ({ - statusCode: 303, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.notModified = (result, headers = {}) => ({ - statusCode: 304, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.useProxy = (result, headers = {}) => ({ - statusCode: 305, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.temporaryRedirect = (result, headers = {}) => ({ - statusCode: 307, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.badRequest = (result, headers = {}) => ({ - statusCode: 400, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.unauthorized = (result, headers = {}) => ({ - statusCode: 401, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.paymentRequired = (result, headers = {}) => ({ - statusCode: 402, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.forbidden = (result, headers = {}) => ({ - statusCode: 403, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.notFound = (result, headers = {}) => ({ - statusCode: 404, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.methodNotAllowed = (result, headers = {}) => ({ - statusCode: 405, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.notAcceptable = (result, headers = {}) => ({ - statusCode: 406, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.proxyAuthenticationRequired = (result, headers = {}) => ({ - statusCode: 407, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.requestTimeOut = (result, headers = {}) => ({ - statusCode: 408, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.conflict = (result, headers = {}) => ({ - statusCode: 409, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.gone = (result, headers = {}) => ({ - statusCode: 410, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.lengthRequired = (result, headers = {}) => ({ - statusCode: 411, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.preconditionFailed = (result, headers = {}) => ({ - statusCode: 412, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.requestEntityTooLarge = (result, headers = {}) => ({ - statusCode: 413, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.requestUriTooLarge = (result, headers = {}) => ({ - statusCode: 414, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.unsupportedMediaType = (result, headers = {}) => ({ - statusCode: 415, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.requestedRangeNotSatisfiable = (result, headers = {}) => ({ - statusCode: 416, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.expectationFailed = (result, headers = {}) => ({ - statusCode: 417, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.imATeapot = (result, headers = {}) => ({ - statusCode: 418, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.unprocessableEntity = (result, headers = {}) => ({ - statusCode: 422, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.locked = (result, headers = {}) => ({ - statusCode: 423, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.failedDependency = (result, headers = {}) => ({ - statusCode: 424, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.unorderedCollection = (result, headers = {}) => ({ - statusCode: 425, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.upgradeRequired = (result, headers = {}) => ({ - statusCode: 426, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.preconditionRequired = (result, headers = {}) => ({ - statusCode: 428, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.tooManyRequests = (result, headers = {}) => ({ - statusCode: 429, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.requestHeaderFieldsTooLarge = (result, headers = {}) => ({ - statusCode: 431, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.internalServerError = (result, headers = {}) => ({ - statusCode: 500, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.notImplemented = (result, headers = {}) => ({ - statusCode: 501, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.badGateway = (result, headers = {}) => ({ - statusCode: 502, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.serviceUnavailable = (result, headers = {}) => ({ - statusCode: 503, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.gatewayTimeOut = (result, headers = {}) => ({ - statusCode: 504, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.httpVersionNotSupported = (result, headers = {}) => ({ - statusCode: 505, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.variantAlsoNegotiates = (result, headers = {}) => ({ - statusCode: 506, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.insufficientStorage = (result, headers = {}) => ({ - statusCode: 507, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.bandwidthLimitExceeded = (result, headers = {}) => ({ - statusCode: 509, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.notExtended = (result, headers = {}) => ({ - statusCode: 510, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.networkAuthenticationRequired = (result, headers = {}) => ({ - statusCode: 511, - headers, - body: result ? typeof result === 'string' ? result : JSON.stringify(result) : null, -}); - -module.exports.isContinue = (response) => { - return response.statusCode === 100; -}; - -module.exports.isSwitchingProtocols = (response) => { - return response.statusCode === 101; -}; - -module.exports.isProcessing = (response) => { - return response.statusCode === 102; -}; - -module.exports.isOk = (response) => { - return response.statusCode === 200; -}; - -module.exports.isCreated = (response) => { - return response.statusCode === 201; -}; - -module.exports.isAccepted = (response) => { - return response.statusCode === 202; -}; - -module.exports.isNonAuthoritativeInformation = (response) => { - return response.statusCode === 203; -}; - -module.exports.isNoContent = (response) => { - return response.statusCode === 204; -}; - -module.exports.isResetContent = (response) => { - return response.statusCode === 205; -}; - -module.exports.isPartialContent = (response) => { - return response.statusCode === 206; -}; - -module.exports.isMultiStatus = (response) => { - return response.statusCode === 207; -}; - -module.exports.isMultipleChoices = (response) => { - return response.statusCode === 300; -}; - -module.exports.isMovedPermanently = (response) => { - return response.statusCode === 301; -}; - -module.exports.isMovedTemporarily = (response) => { - return response.statusCode === 302; -}; - -module.exports.isSeeOther = (response) => { - return response.statusCode === 303; -}; - -module.exports.isNotModified = (response) => { - return response.statusCode === 304; -}; - -module.exports.isUseProxy = (response) => { - return response.statusCode === 305; -}; - -module.exports.isTemporaryRedirect = (response) => { - return response.statusCode === 307; -}; - -module.exports.isBadRequest = (response) => { - return response.statusCode === 400; -}; - -module.exports.isUnauthorized = (response) => { - return response.statusCode === 401; -}; - -module.exports.isPaymentRequired = (response) => { - return response.statusCode === 402; -}; - -module.exports.isForbidden = (response) => { - return response.statusCode === 403; -}; - -module.exports.isNotFound = (response) => { - return response.statusCode === 404; -}; - -module.exports.isMethodNotAllowed = (response) => { - return response.statusCode === 405; -}; - -module.exports.isNotAcceptable = (response) => { - return response.statusCode === 406; -}; - -module.exports.isProxyAuthenticationRequired = (response) => { - return response.statusCode === 407; -}; - -module.exports.isRequestTimeOut = (response) => { - return response.statusCode === 408; -}; - -module.exports.isConflict = (response) => { - return response.statusCode === 409; -}; - -module.exports.isGone = (response) => { - return response.statusCode === 410; -}; - -module.exports.isLengthRequired = (response) => { - return response.statusCode === 411; -}; - -module.exports.isPreconditionFailed = (response) => { - return response.statusCode === 412; -}; - -module.exports.isRequestEntityTooLarge = (response) => { - return response.statusCode === 413; -}; - -module.exports.isRequestUriTooLarge = (response) => { - return response.statusCode === 414; -}; - -module.exports.isUnsupportedMediaType = (response) => { - return response.statusCode === 415; -}; - -module.exports.isRequestedRangeNotSatisfiable = (response) => { - return response.statusCode === 416; -}; - -module.exports.isExpectationFailed = (response) => { - return response.statusCode === 417; -}; - -module.exports.isImATeapot = (response) => { - return response.statusCode === 418; -}; - -module.exports.isUnprocessableEntity = (response) => { - return response.statusCode === 422; -}; - -module.exports.isLocked = (response) => { - return response.statusCode === 423; -}; - -module.exports.isFailedDependency = (response) => { - return response.statusCode === 424; -}; - -module.exports.isUnorderedCollection = (response) => { - return response.statusCode === 425; -}; - -module.exports.isUpgradeRequired = (response) => { - return response.statusCode === 426; -}; - -module.exports.isPreconditionRequired = (response) => { - return response.statusCode === 428; -}; - -module.exports.isTooManyRequests = (response) => { - return response.statusCode === 429; -}; - -module.exports.isRequestHeaderFieldsTooLarge = (response) => { - return response.statusCode === 431; -}; - -module.exports.isInternalServerError = (response) => { - return response.statusCode === 500; -}; - -module.exports.isNotImplemented = (response) => { - return response.statusCode === 501; -}; - -module.exports.isBadGateway = (response) => { - return response.statusCode === 502; -}; - -module.exports.isServiceUnavailable = (response) => { - return response.statusCode === 503; -}; - -module.exports.isGatewayTimeOut = (response) => { - return response.statusCode === 504; -}; - -module.exports.isHttpVersionNotSupported = (response) => { - return response.statusCode === 505; -}; - -module.exports.isVariantAlsoNegotiates = (response) => { - return response.statusCode === 506; -}; - -module.exports.isInsufficientStorage = (response) => { - return response.statusCode === 507; -}; - -module.exports.isBandwidthLimitExceeded = (response) => { - return response.statusCode === 509; -}; - -module.exports.isNotExtended = (response) => { - return response.statusCode === 510; -}; - -module.exports.isNetworkAuthenticationRequired = (response) => { - return response.statusCode === 511; -}; \ No newline at end of file diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..de6b633 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,441 @@ +export function switchingProtocols(result: unknown, headers?: T): { + statusCode: 101; + headers: T | {}; + body: string; +}; + +export function processing(result: unknown, headers?: T): { + statusCode: 102; + headers: T | {}; + body: string; +}; + +export function ok(result: unknown, headers?: T): { + statusCode: 200; + headers: T | {}; + body: string; +}; + +export function created(result: unknown, headers?: T): { + statusCode: 201; + headers: T | {}; + body: string; +}; + +export function accepted(result: unknown, headers?: T): { + statusCode: 202; + headers: T | {}; + body: string; +}; + +export function nonAuthoritativeInformation(result: unknown, headers?: T): { + statusCode: 203; + headers: T | {}; + body: string; +}; + +export function noContent(result: unknown, headers?: T): { + statusCode: 204; + headers: T | {}; + body: string; +}; + +export function resetContent(result: unknown, headers?: T): { + statusCode: 205; + headers: T | {}; + body: string; +}; + +export function partialContent(result: unknown, headers?: T): { + statusCode: 206; + headers: T | {}; + body: string; +}; + +export function multiStatus(result: unknown, headers?: T): { + statusCode: 207; + headers: T | {}; + body: string; +}; + +export function multipleChoices(result: unknown, headers?: T): { + statusCode: 300; + headers: T | {}; + body: string; +}; + +export function movedPermanently(result: unknown, headers?: T): { + statusCode: 301; + headers: T | {}; + body: string; +}; + +export function movedTemporarily(result: unknown, headers?: T): { + statusCode: 302; + headers: T | {}; + body: string; +}; + +export function seeOther(result: unknown, headers?: T): { + statusCode: 303; + headers: T | {}; + body: string; +}; + +export function notModified(result: unknown, headers?: T): { + statusCode: 304; + headers: T | {}; + body: string; +}; + +export function useProxy(result: unknown, headers?: T): { + statusCode: 305; + headers: T | {}; + body: string; +}; + +export function temporaryRedirect(result: unknown, headers?: T): { + statusCode: 307; + headers: T | {}; + body: string; +}; + +export function badRequest(result: unknown, headers?: T): { + statusCode: 400; + headers: T | {}; + body: string; +}; + +export function unauthorized(result: unknown, headers?: T): { + statusCode: 401; + headers: T | {}; + body: string; +}; + +export function paymentRequired(result: unknown, headers?: T): { + statusCode: 402; + headers: T | {}; + body: string; +}; + +export function forbidden(result: unknown, headers?: T): { + statusCode: 403; + headers: T | {}; + body: string; +}; + +export function notFound(result: unknown, headers?: T): { + statusCode: 404; + headers: T | {}; + body: string; +}; + +export function methodNotAllowed(result: unknown, headers?: T): { + statusCode: 405; + headers: T | {}; + body: string; +}; + +export function notAcceptable(result: unknown, headers?: T): { + statusCode: 406; + headers: T | {}; + body: string; +}; + +export function proxyAuthenticationRequired(result: unknown, headers?: T): { + statusCode: 407; + headers: T | {}; + body: string; +}; + +export function requestTimeOut(result: unknown, headers?: T): { + statusCode: 408; + headers: T | {}; + body: string; +}; + +export function conflict(result: unknown, headers?: T): { + statusCode: 409; + headers: T | {}; + body: string; +}; + +export function gone(result: unknown, headers?: T): { + statusCode: 410; + headers: T | {}; + body: string; +}; + +export function lengthRequired(result: unknown, headers?: T): { + statusCode: 411; + headers: T | {}; + body: string; +}; + +export function preconditionFailed(result: unknown, headers?: T): { + statusCode: 412; + headers: T | {}; + body: string; +}; + +export function requestEntityTooLarge(result: unknown, headers?: T): { + statusCode: 413; + headers: T | {}; + body: string; +}; + +export function requestUriTooLarge(result: unknown, headers?: T): { + statusCode: 414; + headers: T | {}; + body: string; +}; + +export function unsupportedMediaType(result: unknown, headers?: T): { + statusCode: 415; + headers: T | {}; + body: string; +}; + +export function requestedRangeNotSatisfiable(result: unknown, headers?: T): { + statusCode: 416; + headers: T | {}; + body: string; +}; + +export function expectationFailed(result: unknown, headers?: T): { + statusCode: 417; + headers: T | {}; + body: string; +}; + +export function imATeapot(result: unknown, headers?: T): { + statusCode: 418; + headers: T | {}; + body: string; +}; + +export function unprocessableEntity(result: unknown, headers?: T): { + statusCode: 422; + headers: T | {}; + body: string; +}; + +export function locked(result: unknown, headers?: T): { + statusCode: 423; + headers: T | {}; + body: string; +}; + +export function failedDependency(result: unknown, headers?: T): { + statusCode: 424; + headers: T | {}; + body: string; +}; + +export function unorderedCollection(result: unknown, headers?: T): { + statusCode: 425; + headers: T | {}; + body: string; +}; + +export function upgradeRequired(result: unknown, headers?: T): { + statusCode: 426; + headers: T | {}; + body: string; +}; + +export function preconditionRequired(result: unknown, headers?: T): { + statusCode: 428; + headers: T | {}; + body: string; +}; + +export function tooManyRequests(result: unknown, headers?: T): { + statusCode: 429; + headers: T | {}; + body: string; +}; + +export function requestHeaderFieldsTooLarge(result: unknown, headers?: T): { + statusCode: 431; + headers: T | {}; + body: string; +}; + +export function internalServerError(result: unknown, headers?: T): { + statusCode: 500; + headers: T | {}; + body: string; +}; + +export function notImplemented(result: unknown, headers?: T): { + statusCode: 501; + headers: T | {}; + body: string; +}; + +export function badGateway(result: unknown, headers?: T): { + statusCode: 502; + headers: T | {}; + body: string; +}; + +export function serviceUnavailable(result: unknown, headers?: T): { + statusCode: 503; + headers: T | {}; + body: string; +}; + +export function gatewayTimeOut(result: unknown, headers?: T): { + statusCode: 504; + headers: T | {}; + body: string; +}; + +export function httpVersionNotSupported(result: unknown, headers?: T): { + statusCode: 505; + headers: T | {}; + body: string; +}; + +export function variantAlsoNegotiates(result: unknown, headers?: T): { + statusCode: 506; + headers: T | {}; + body: string; +}; + +export function insufficientStorage(result: unknown, headers?: T): { + statusCode: 507; + headers: T | {}; + body: string; +}; + +export function bandwidthLimitExceeded(result: unknown, headers?: T): { + statusCode: 509; + headers: T | {}; + body: string; +}; + +export function notExtended(result: unknown, headers?: T): { + statusCode: 510; + headers: T | {}; + body: string; +}; + +export function networkAuthenticationRequired(result: unknown, headers?: T): { + statusCode: 511; + headers: T | {}; + body: string; +}; + +export function isContinue (response: unknown): boolean; + +export function isSwitchingProtocols (response: unknown): boolean; + +export function isProcessing (response: unknown): boolean; + +export function isOk (response: unknown): boolean; + +export function isCreated (response: unknown): boolean; + +export function isAccepted (response: unknown): boolean; + +export function isNonAuthoritativeInformation (response: unknown): boolean; + +export function isNoContent (response: unknown): boolean; + +export function isResetContent (response: unknown): boolean; + +export function isPartialContent (response: unknown): boolean; + +export function isMultiStatus (response: unknown): boolean; + +export function isMultipleChoices (response: unknown): boolean; + +export function isMovedPermanently (response: unknown): boolean; + +export function isMovedTemporarily (response: unknown): boolean; + +export function isSeeOther (response: unknown): boolean; + +export function isNotModified (response: unknown): boolean; + +export function isUseProxy (response: unknown): boolean; + +export function isTemporaryRedirect (response: unknown): boolean; + +export function isBadRequest (response: unknown): boolean; + +export function isUnauthorized (response: unknown): boolean; + +export function isPaymentRequired (response: unknown): boolean; + +export function isForbidden (response: unknown): boolean; + +export function isNotFound (response: unknown): boolean; + +export function isMethodNotAllowed (response: unknown): boolean; + +export function isNotAcceptable (response: unknown): boolean; + +export function isProxyAuthenticationRequired (response: unknown): boolean; + +export function isRequestTimeOut (response: unknown): boolean; + +export function isConflict (response: unknown): boolean; + +export function isGone (response: unknown): boolean; + +export function isLengthRequired (response: unknown): boolean; + +export function isPreconditionFailed (response: unknown): boolean; + +export function isRequestEntityTooLarge (response: unknown): boolean; + +export function isRequestUriTooLarge (response: unknown): boolean; + +export function isUnsupportedMediaType (response: unknown): boolean; + +export function isRequestedRangeNotSatisfiable (response: unknown): boolean; + +export function isExpectationFailed (response: unknown): boolean; + +export function isImATeapot (response: unknown): boolean; + +export function isUnprocessableEntity (response: unknown): boolean; + +export function isLocked (response: unknown): boolean; + +export function isFailedDependency (response: unknown): boolean; + +export function isUnorderedCollection (response: unknown): boolean; + +export function isUpgradeRequired (response: unknown): boolean; + +export function isPreconditionRequired (response: unknown): boolean; + +export function isTooManyRequests (response: unknown): boolean; + +export function isRequestHeaderFieldsTooLarge (response: unknown): boolean; + +export function isInternalServerError (response: unknown): boolean; + +export function isNotImplemented (response: unknown): boolean; + +export function isBadGateway (response: unknown): boolean; + +export function isServiceUnavailable (response: unknown): boolean; + +export function isGatewayTimeOut (response: unknown): boolean; + +export function isHttpVersionNotSupported (response: unknown): boolean; + +export function isVariantAlsoNegotiates (response: unknown): boolean; + +export function isInsufficientStorage (response: unknown): boolean; + +export function isBandwidthLimitExceeded (response: unknown): boolean; + +export function isNotExtended (response: unknown): boolean; + +export function isNetworkAuthenticationRequired (response: unknown): boolean; \ No newline at end of file diff --git a/index.esm.d.ts b/index.esm.d.ts deleted file mode 100644 index 8a7a1fb..0000000 --- a/index.esm.d.ts +++ /dev/null @@ -1,331 +0,0 @@ -export function switchingProtocols(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function processing(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function ok(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function created(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function accepted(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function nonAuthoritativeInformation(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function noContent(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function resetContent(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function partialContent(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function multiStatus(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function multipleChoices(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function movedPermanently(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function movedTemporarily(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function seeOther(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function notModified(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function useProxy(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function temporaryRedirect(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function badRequest(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function unauthorized(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function paymentRequired(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function forbidden(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function notFound(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function methodNotAllowed(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function notAcceptable(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function proxyAuthenticationRequired(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function requestTimeOut(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function conflict(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function gone(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function lengthRequired(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function preconditionFailed(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function requestEntityTooLarge(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function requestUriTooLarge(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function unsupportedMediaType(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function requestedRangeNotSatisfiable(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function expectationFailed(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function imATeapot(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function unprocessableEntity(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function locked(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function failedDependency(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function unorderedCollection(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function upgradeRequired(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function preconditionRequired(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function tooManyRequests(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function requestHeaderFieldsTooLarge(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function internalServerError(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function notImplemented(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function badGateway(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function serviceUnavailable(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function gatewayTimeOut(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function httpVersionNotSupported(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function variantAlsoNegotiates(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function insufficientStorage(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function bandwidthLimitExceeded(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function notExtended(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function networkAuthenticationRequired(result: any, headers?: {}): { - statusCode: number; - headers: {}; - body: string; -}; -export function isContinue(response: any): boolean; -export function isSwitchingProtocols(response: any): boolean; -export function isProcessing(response: any): boolean; -export function isOk(response: any): boolean; -export function isCreated(response: any): boolean; -export function isAccepted(response: any): boolean; -export function isNonAuthoritativeInformation(response: any): boolean; -export function isNoContent(response: any): boolean; -export function isResetContent(response: any): boolean; -export function isPartialContent(response: any): boolean; -export function isMultiStatus(response: any): boolean; -export function isMultipleChoices(response: any): boolean; -export function isMovedPermanently(response: any): boolean; -export function isMovedTemporarily(response: any): boolean; -export function isSeeOther(response: any): boolean; -export function isNotModified(response: any): boolean; -export function isUseProxy(response: any): boolean; -export function isTemporaryRedirect(response: any): boolean; -export function isBadRequest(response: any): boolean; -export function isUnauthorized(response: any): boolean; -export function isPaymentRequired(response: any): boolean; -export function isForbidden(response: any): boolean; -export function isNotFound(response: any): boolean; -export function isMethodNotAllowed(response: any): boolean; -export function isNotAcceptable(response: any): boolean; -export function isProxyAuthenticationRequired(response: any): boolean; -export function isRequestTimeOut(response: any): boolean; -export function isConflict(response: any): boolean; -export function isGone(response: any): boolean; -export function isLengthRequired(response: any): boolean; -export function isPreconditionFailed(response: any): boolean; -export function isRequestEntityTooLarge(response: any): boolean; -export function isRequestUriTooLarge(response: any): boolean; -export function isUnsupportedMediaType(response: any): boolean; -export function isRequestedRangeNotSatisfiable(response: any): boolean; -export function isExpectationFailed(response: any): boolean; -export function isImATeapot(response: any): boolean; -export function isUnprocessableEntity(response: any): boolean; -export function isLocked(response: any): boolean; -export function isFailedDependency(response: any): boolean; -export function isUnorderedCollection(response: any): boolean; -export function isUpgradeRequired(response: any): boolean; -export function isPreconditionRequired(response: any): boolean; -export function isTooManyRequests(response: any): boolean; -export function isRequestHeaderFieldsTooLarge(response: any): boolean; -export function isInternalServerError(response: any): boolean; -export function isNotImplemented(response: any): boolean; -export function isBadGateway(response: any): boolean; -export function isServiceUnavailable(response: any): boolean; -export function isGatewayTimeOut(response: any): boolean; -export function isHttpVersionNotSupported(response: any): boolean; -export function isVariantAlsoNegotiates(response: any): boolean; -export function isInsufficientStorage(response: any): boolean; -export function isBandwidthLimitExceeded(response: any): boolean; -export function isNotExtended(response: any): boolean; -export function isNetworkAuthenticationRequired(response: any): boolean; diff --git a/index.esm.js b/index.js similarity index 100% rename from index.esm.js rename to index.js diff --git a/index.test.cjs b/index.test.cjs deleted file mode 100644 index 3352657..0000000 --- a/index.test.cjs +++ /dev/null @@ -1,49 +0,0 @@ -describe('lambda-returns', () => { - let module; - - beforeEach(() => { - module = require('./index'); - }); - - test('length check', () => { - expect(Object.keys(module).length).toBe(111); - }); - - describe('some methods', () => { - test('ok', () => { - expect(module.ok({ status: 'success' })).toEqual({ - statusCode: 200, - headers: {}, - body: JSON.stringify({ status: 'success' }), - }); - }); - - test('ok with headers', () => { - expect(module.ok({ status: 'success' }, { Content: 'json' })).toEqual({ - statusCode: 200, - headers: { - Content: 'json', - }, - body: JSON.stringify({ status: 'success' }), - }); - }); - - test('noContent', () => { - expect(module.noContent()).toEqual({ - statusCode: 204, - headers: {}, - body: null, - }); - }); - - test('badRequest', () => { - expect( - module.badRequest({ error: 'argument foo was not provided' }) - ).toEqual({ - statusCode: 400, - headers: {}, - body: JSON.stringify({ error: 'argument foo was not provided' }), - }); - }); - }); -}); diff --git a/index.test.esm.js b/index.test.esm.js deleted file mode 100644 index d92ca16..0000000 --- a/index.test.esm.js +++ /dev/null @@ -1,39 +0,0 @@ -import { ok, noContent, badRequest } from './index.esm.js'; - -describe('lambda-returns', () => { - describe('some methods', () => { - test('ok', () => { - expect(ok({ status: 'success' })).toEqual({ - statusCode: 200, - headers: {}, - body: JSON.stringify({ status: 'success' }), - }); - }); - - test('ok with headers', () => { - expect(ok({ status: 'success' }, { Content: 'json' })).toEqual({ - statusCode: 200, - headers: { - Content: 'json', - }, - body: JSON.stringify({ status: 'success' }), - }); - }); - - test('noContent', () => { - expect(noContent()).toEqual({ - statusCode: 204, - headers: {}, - body: null, - }); - }); - - test('badRequest', () => { - expect(badRequest({ error: 'argument foo was not provided' })).toEqual({ - statusCode: 400, - headers: {}, - body: JSON.stringify({ error: 'argument foo was not provided' }), - }); - }); - }); -}); diff --git a/index.test.js b/index.test.js new file mode 100644 index 0000000..96a22eb --- /dev/null +++ b/index.test.js @@ -0,0 +1,259 @@ +import * as lambdaReturns from './index.js'; +import codes from './codes.js'; +import capitalizeFirstLetter from './src/capitalize_first/index.js'; +import randomInteger from './src/random_integer/index.js'; + +describe('lambda-returns', () => { + const codesEntries = Object.entries(codes); + + describe('basic methods', () => { + // can't test continue status word because it's forbidden to export it in JS + // look at README + const cases = codesEntries + .filter(([status]) => status !== 'continue') + .map(([status, code]) => [status, code]); + + test.each(cases)('%s should return %s when empty args', (status, code) => { + expect(lambdaReturns[status]()).toEqual({ + statusCode: code, + headers: {}, + body: null, + }); + }); + + test.each(cases)( + '%s should return %s when empty body but headers filled', + (status, code) => { + expect( + lambdaReturns[status](undefined, { ContentType: 'application/json' }) + ).toEqual({ + statusCode: code, + headers: { ContentType: 'application/json' }, + body: null, + }); + } + ); + + test.each(cases)( + '%s should return %s when has obect body, no headers', + (status, code) => { + expect(lambdaReturns[status]({ status: 'success' })).toEqual({ + statusCode: code, + headers: {}, + body: '{"status":"success"}', + }); + } + ); + + test.each(cases)( + '%s should return %s when has string body, no headers', + (status, code) => { + expect(lambdaReturns[status]('{"everything":"is good"}')).toEqual({ + statusCode: code, + headers: {}, + body: '{"everything":"is good"}', + }); + } + ); + + test.each(cases)( + '%s should return %s when has obect body, with headers', + (status, code) => { + expect( + lambdaReturns[status]( + { status: 'success' }, + { + 'Accept-Encoding': 'gzip, deflate, br', + } + ) + ).toEqual({ + statusCode: code, + headers: { + 'Accept-Encoding': 'gzip, deflate, br', + }, + body: '{"status":"success"}', + }); + } + ); + + test.each(cases)( + '%s should return %s when has string body, with headers', + (status, code) => { + expect( + lambdaReturns[status]('{"everything":"is good"}', { + 'Cache-Control': 'no-cache', + }) + ).toEqual({ + statusCode: code, + headers: { + 'Cache-Control': 'no-cache', + }, + body: '{"everything":"is good"}', + }); + } + ); + }); + + describe('test helper methods', () => { + const cases = codesEntries.map(([status, code]) => [ + `is${capitalizeFirstLetter(status)}`, + code, + ]); + + test.each(cases)( + '%s should return %s when empty body, empty headers', + (statusTest, code) => { + expect( + lambdaReturns[statusTest]({ + statusCode: code, + headers: {}, + body: null, + }) + ).toBe(true); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: null, + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: null, + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: null, + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: null, + }) + ).toBe(false); + } + ); + + test.each(cases)( + '%s should return %s when has body', + (statusTest, code) => { + expect( + lambdaReturns[statusTest]({ + statusCode: code, + headers: {}, + body: '{"status":"success"}', + }) + ).toBe(true); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: '{"status":"success"}', + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: '{"status":"success"}', + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: {}, + body: '{"status":"success"}', + }) + ).toBe(false); + } + ); + + test.each(cases)( + '%s should return %s when has body and headers', + (statusTest, code) => { + expect( + lambdaReturns[statusTest]({ + statusCode: code, + headers: { ContentType: 'application/json' }, + body: '{"status":"success"}', + }) + ).toBe(true); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: { ContentType: 'application/json' }, + body: '{"status":"success"}', + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: { ContentType: 'application/json' }, + body: '{"status":"success"}', + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: { ContentType: 'application/json' }, + body: '{"status":"success"}', + }) + ).toBe(false); + } + ); + + test.each(cases)( + '%s should return %s when has headers and no body', + (statusTest, code) => { + expect( + lambdaReturns[statusTest]({ + statusCode: code, + headers: { ContentType: 'application/json' }, + body: null, + }) + ).toBe(true); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: { ContentType: 'application/json' }, + body: null, + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: { ContentType: 'application/json' }, + body: null, + }) + ).toBe(false); + + expect( + lambdaReturns[statusTest]({ + statusCode: randomInteger(code), + headers: { ContentType: 'application/json' }, + body: null, + }) + ).toBe(false); + } + ); + }); +}); diff --git a/jest.config.cjs b/jest.config.cjs deleted file mode 100644 index 4becb1f..0000000 --- a/jest.config.cjs +++ /dev/null @@ -1,14 +0,0 @@ -/* - * For a detailed explanation regarding each configuration property, visit: - * https://jestjs.io/docs/configuration - */ - -module.exports = { - clearMocks: true, - collectCoverage: true, - coverageDirectory: "coverage", - coverageProvider: "v8", - testMatch: [ - "**/index.test.cjs" - ] -}; diff --git a/jest.config.esm.js b/jest.config.js similarity index 60% rename from jest.config.esm.js rename to jest.config.js index 7811f37..ad5e51e 100644 --- a/jest.config.esm.js +++ b/jest.config.js @@ -4,11 +4,11 @@ */ export default { + bail: true, + transform: {}, clearMocks: true, collectCoverage: true, - coverageDirectory: "coverage", - coverageProvider: "v8", - testMatch: [ - "**/index.test.esm.js" - ] + coverageDirectory: 'coverage', + coverageProvider: 'v8', + testMatch: ['**/index.test.js'], }; diff --git a/package.json b/package.json index 0b8644a..6ffa328 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "lambda-returns", - "version": "2.2.1", + "version": "3.0.1", "main": "index.cjs", - "module": "index.esm.js", - "types": "./index.esm.d.ts", + "module": "index.js", + "types": "./index.d.ts", "repository": "git@github.com:MathRobin/lambda-returns.git", "author": "MathRobin ", "license": "MIT", @@ -11,13 +11,13 @@ "packageManager": "yarn@3.6.4", "type": "module", "scripts": { - "build": "node build.js; npx -p typescript tsc ./index.esm.js --declaration --allowJs --emitDeclarationOnly --outDir .", + "build": "yarn build:source && yarn build:typings", + "build:source": "node build.js", + "build:typings": "node typings.js", "lint": "eslint .", - "testCjs": "jest --coverage -c jest.config.cjs --coverageDirectory coverage_cjs", - "testEsm": "NODE_OPTIONS=--experimental-vm-modules npx jest --coverage -c jest.config.esm.js", "pretest": "yarn build", "publish": "yarn build && yarn npm publish && git add package.json yarn.lock", - "test": "yarn testCjs; yarn testEsm", + "test": "NODE_OPTIONS=--experimental-vm-modules npx jest --coverage -c jest.config.js", "prepare": "husky install" }, "devDependencies": { @@ -27,7 +27,6 @@ "eslint-plugin-jest": "27.4.2", "husky": "8.0.3", "jest": "29.7.0", - "prettier": "3.0.3", - "typescript": "5.2.2" + "prettier": "3.0.3" } } diff --git a/src/capitalize_first/index.js b/src/capitalize_first/index.js new file mode 100644 index 0000000..0437931 --- /dev/null +++ b/src/capitalize_first/index.js @@ -0,0 +1,3 @@ +export default function capitalizeFirstLetter(string) { + return string[0].toUpperCase() + string.slice(1); +} diff --git a/src/random_integer/index.js b/src/random_integer/index.js new file mode 100644 index 0000000..4a03464 --- /dev/null +++ b/src/random_integer/index.js @@ -0,0 +1,9 @@ +export default function randomInteger(codeExcluded, min = 100, max = 511) { + let result; + + do { + result = Math.floor(Math.random() * (max - min + 1)) + min; + } while (result === codeExcluded); + + return result; +} diff --git a/src/random_integer/index.test.js b/src/random_integer/index.test.js new file mode 100644 index 0000000..688cefd --- /dev/null +++ b/src/random_integer/index.test.js @@ -0,0 +1,25 @@ +import randomInteger from './index.js'; + +describe('randomInteger', () => { + const cases = [ + [randomInteger(2, 1, 2), 1, 2, 2], + [randomInteger(2, 1, 2), 1, 2, 2], + [randomInteger(2, 1, 2), 1, 2, 2], + [randomInteger(2, 1, 2), 1, 2, 2], + [randomInteger(2, 1, 2), 1, 2, 2], + [randomInteger(2, 1, 2), 1, 2, 2], + [randomInteger(200), 100, 511, 200], + [randomInteger(200, 100), 100, 511, 200], + [randomInteger(200, 100, 511), 100, 511, 200], + [randomInteger(200, undefined, 511), 100, 511, 200], + ]; + + test.each(cases)( + '%s is between %s and %s (both included)', + (codeExcluded, min, max, codeAsked) => { + expect(codeExcluded).toBeGreaterThanOrEqual(min); + expect(codeExcluded).toBeLessThanOrEqual(max); + expect(codeExcluded).not.toBe(codeAsked); + } + ); +}); diff --git a/typings.js b/typings.js new file mode 100644 index 0000000..1e507f1 --- /dev/null +++ b/typings.js @@ -0,0 +1,34 @@ +import fs from 'fs'; + +import codes from './codes.js'; + +const exportsEsm = []; + +function capitalizeFirstLetter(string) { + return string[0].toUpperCase() + string.slice(1); +} + +Object.entries(codes) + .filter(([message]) => { + // can't be exported as it uses a reserved word + return message !== 'continue'; + }) + .forEach(([message, code]) => { + exportsEsm.push(`export function ${message}(result: unknown, headers?: T): { + statusCode: ${code}; + headers: T | {}; + body: string; +};`); + }); + +Object.entries(codes).forEach(([message]) => { + exportsEsm.push( + `export function is${capitalizeFirstLetter( + message + )} (response: unknown): boolean;` + ); +}); + +fs.writeFile('./index.d.ts', exportsEsm.join('\n\n'), () => { + console.log('Module typings generated'); +}); diff --git a/yarn.lock b/yarn.lock index 0f553b2..a95d022 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3181,7 +3181,6 @@ __metadata: husky: 8.0.3 jest: 29.7.0 prettier: 3.0.3 - typescript: 5.2.2 languageName: unknown linkType: soft @@ -4304,26 +4303,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.2.2": - version: 5.2.2 - resolution: "typescript@npm:5.2.2" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c - languageName: node - linkType: hard - -"typescript@patch:typescript@5.2.2#~builtin": - version: 5.2.2 - resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=f3b441" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 0f4da2f15e6f1245e49db15801dbee52f2bbfb267e1c39225afdab5afee1a72839cd86000e65ee9d7e4dfaff12239d28beaf5ee431357fcced15fb08583d72ca - languageName: node - linkType: hard - "unique-filename@npm:^3.0.0": version: 3.0.0 resolution: "unique-filename@npm:3.0.0"