From c65baf88749166ba8d0c970760c8aab172a83a1a Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Fri, 4 Sep 2020 20:12:06 -0700 Subject: [PATCH] feat(common): Checks and CodedError classes Utilities for easier one-liners that can verify arguments or execution state in a much more concise way compared to if conditions throwing manually. Makes the code less verbose and requires less typing as well. Also: added a bools utlity class for checking strict boolean typing of a value and a new string utility method as well. Fixes #266 Signed-off-by: Peter Somogyvari --- .../src/main/typescript/bools.ts | 15 +++++++++++++ .../src/main/typescript/checks.ts | 21 +++++++++++++++++++ .../src/main/typescript/coded-error.ts | 14 +++++++++++++ .../src/main/typescript/public-api.ts | 5 +++++ .../src/main/typescript/strings.ts | 12 +++++++++++ 5 files changed, 67 insertions(+) create mode 100644 packages/cactus-common/src/main/typescript/bools.ts create mode 100644 packages/cactus-common/src/main/typescript/checks.ts create mode 100644 packages/cactus-common/src/main/typescript/coded-error.ts diff --git a/packages/cactus-common/src/main/typescript/bools.ts b/packages/cactus-common/src/main/typescript/bools.ts new file mode 100644 index 0000000000..a14d88354f --- /dev/null +++ b/packages/cactus-common/src/main/typescript/bools.ts @@ -0,0 +1,15 @@ +export class Bools { + /** + * Determines if a value is strictly a boolean `true` or `false`. Anything else + * will result in the method returning `false`. + * + * Useful in cases where you have an optional boolean parameter that you need + * to assign a default value to by determining if it had been set or not. + * + * @param val The value to be decided on whether it's strictly boolean `true` + * or `false`. + */ + public static isBooleanStrict(val: unknown): boolean { + return val === true || val === false; + } +} diff --git a/packages/cactus-common/src/main/typescript/checks.ts b/packages/cactus-common/src/main/typescript/checks.ts new file mode 100644 index 0000000000..9c3c66e93b --- /dev/null +++ b/packages/cactus-common/src/main/typescript/checks.ts @@ -0,0 +1,21 @@ +import { CodedError } from "./coded-error"; + +export class Checks { + /** + * Verifies that a boolean condition is met or throws an Error if it is not. + * + * @param checkResult Determines the outcome of the check via it's truthyness. + * @param subjectOfCheck The error message if `checkResult` is falsy. + * @param code The code of the error if `checkResult is falsy. + */ + public static truthy( + checkResult: any, + subjectOfCheck: string = "variable", + code: string = "-1" + ): void { + if (!checkResult) { + const message = `"${subjectOfCheck}" is falsy, need a truthy value.`; + throw new CodedError(message, code); + } + } +} diff --git a/packages/cactus-common/src/main/typescript/coded-error.ts b/packages/cactus-common/src/main/typescript/coded-error.ts new file mode 100644 index 0000000000..239fe0c4bb --- /dev/null +++ b/packages/cactus-common/src/main/typescript/coded-error.ts @@ -0,0 +1,14 @@ +/** + * Utility class for better exception handling by way of having a code property + * which is designated to uniquely identify the type of exception that was + * thrown, essentially acting as a discriminator property. + */ +export class CodedError extends Error { + constructor(public readonly message: string, public readonly code: string) { + super(message); + } + + sameCode(codedError: CodedError): boolean { + return this.code === codedError?.code; + } +} diff --git a/packages/cactus-common/src/main/typescript/public-api.ts b/packages/cactus-common/src/main/typescript/public-api.ts index 74970bf805..bf15824aff 100755 --- a/packages/cactus-common/src/main/typescript/public-api.ts +++ b/packages/cactus-common/src/main/typescript/public-api.ts @@ -3,6 +3,10 @@ export { Logger, ILoggerOptions } from "./logging/logger"; export { LogLevelDesc } from "loglevel"; export { Objects } from "./objects"; export { Strings } from "./strings"; +export { Bools } from "./bools"; +export { Checks } from "./checks"; +export { CodedError } from "./coded-error"; + export { JsObjectSigner, IJsObjectSignerOptions, @@ -10,5 +14,6 @@ export { VerifySignatureFunction, HashFunction, } from "./js-object-signer"; + export { ISignerKeyPair } from "./signer-key-pair"; export { Secp256k1Keys } from "./secp256k1-keys"; diff --git a/packages/cactus-common/src/main/typescript/strings.ts b/packages/cactus-common/src/main/typescript/strings.ts index 54cd57b5a3..47e62f75b0 100644 --- a/packages/cactus-common/src/main/typescript/strings.ts +++ b/packages/cactus-common/src/main/typescript/strings.ts @@ -1,3 +1,5 @@ +import { Checks } from "./checks"; + export class Strings { public static replaceAll( source: string, @@ -6,4 +8,14 @@ export class Strings { ): string { return source.replace(new RegExp(searchValue, "gm"), replaceValue); } + + public static isString(val: any): boolean { + return typeof val === "string" || val instanceof String; + } + + public static dropNonPrintable(val: string): string { + const fnTag = "Strings#dropNonPrintable()"; + Checks.truthy(Strings.isString(val), `${fnTag} Strings.isString(val)`); + return val.replace(/[^ -~]+/g, ""); + } }