Skip to content

Commit

Permalink
feat(common): add express http verb method name string literal type
Browse files Browse the repository at this point in the history
1. Also ships with a user-defined typescript type-guard so that we can
ensure at runtime that the string literal value is indeed one of the
valid ExpressJS HTTP verb method names.
2. The primary use-case for this is checking at runtime the HTTP verb
name of OpenAPI specifications that are being loaded into the API.

[skip ci]

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Oct 16, 2023
1 parent ed04201 commit e5f62f1
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* A collection of all the HTTP verb method names that Express.js supports.
* Directly taken from the Express.js type definitions file of the @types/express
* package.
*/
export const ALL_EXPRESS_HTTP_VERB_METHOD_NAMES = [
"all",
"get",
"post",
"put",
"delete",
"patch",
"options",
"head",
] as const;

/**
* A type that represents all the HTTP verb method names that Express.js supports.
*/
export type ExpressHttpVerbMethodName =
typeof ALL_EXPRESS_HTTP_VERB_METHOD_NAMES[number];

/**
* Custom (user-defined) typescript type-guard that checks whether the given
* value is an Express.js HTTP verb method name or not.
* Useful for verifying at runtime if we can safely call a method on the Express.js
* application object where the method's name is the value of the given variable.
*
* Example:
*
* ```typescript
* import express from "express";
* import { isExpressHttpVerbMethodName } from "@hyperledger/cactus-core-api-server";
* const app = express();
* const methodName = "get";
* if (isExpressHttpVerbMethodName(methodName)) {
* app[methodName]("/foo", (req, res) => {
* res.send("Hello World!");
* });
* ```
*
* @param x Any value that may or may not be an Express.js HTTP verb method name.
* @returns Whether the given value is an Express.js HTTP verb method name.
*/
export function isExpressHttpVerbMethodName(
x: unknown,
): x is ExpressHttpVerbMethodName {
return (
typeof x === "string" && ALL_EXPRESS_HTTP_VERB_METHOD_NAMES.includes(x as never)
);
}
16 changes: 14 additions & 2 deletions packages/cactus-common/src/main/typescript/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,19 @@ export {
export { isRecord } from "./types/is-record";
export { hasKey } from "./types/has-key";

export { asError, coerceUnknownToError } from "./exception/coerce-unknown-to-error";
export { createRuntimeErrorWithCause, newRex } from "./exception/create-runtime-error-with-cause";
export {
asError,
coerceUnknownToError,
} from "./exception/coerce-unknown-to-error";
export {
createRuntimeErrorWithCause,
newRex,
} from "./exception/create-runtime-error-with-cause";
export { ErrorFromUnknownThrowable } from "./exception/error-from-unknown-throwable";
export { ErrorFromSymbol } from "./exception/error-from-symbol";

export {
ALL_EXPRESS_HTTP_VERB_METHOD_NAMES,
ExpressHttpVerbMethodName,
isExpressHttpVerbMethodName,
} from "./http/express-http-verb-method-name";
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
ALL_EXPRESS_HTTP_VERB_METHOD_NAMES,
ExpressHttpVerbMethodName,
isExpressHttpVerbMethodName,
} from "../../../../main/typescript/public-api";

describe("isExpressHttpVerbMethodName", () => {
it("should return true for valid HTTP verb method names", () => {
ALL_EXPRESS_HTTP_VERB_METHOD_NAMES.forEach((methodName) => {
expect(isExpressHttpVerbMethodName(methodName)).toBe(true);
});
});

it("should return false for invalid values", () => {
const invalidValues = [
123, // Not a string
0, // Falsy Number
"invalid", // Not a valid HTTP verb method name
"gEt", // Case-sensitive
"", // Empty string
null, // Null value
undefined, // Undefined value
{}, // Object
[], // Array
];

invalidValues.forEach((value) => {
expect(isExpressHttpVerbMethodName(value)).toBe(false);
});
});
});

0 comments on commit e5f62f1

Please sign in to comment.