Common utilities

BackendTooling

A collection of common utilities, classes, and helpers.

Installation#

yarn add @boost/common

Helpers#

createBlueprint#

createBlueprint<T>(factory: BlueprintFactory<T>): Blueprint<T>

Can be used to generate a blueprint object for use within optimal checks. All supported optimal predicates are passed as an object to the factory.

import { optimal, createBlueprint } from '@boost/common';
const blueprint = createBlueprint(({ string, number }) => ({
name: string().required(),
age: number().gt(0),
}));
const data = optimal({}, blueprint);

deepFreeze#

deepFreeze<T extends object>(obj: T): T

Can be used to recursively freeze plain objects with Object.freeze.

import { deepFreeze } from '@boost/common';
const obj = deepFreeze({ foo: 123 });
// Errors!
obj.foo = 456;

deepMerge#

deepMerge<T extends object | unknown[]>(base: T, other?: T): T

Can be used to recursively merge objects and arrays, where values on the right-hand side will overwrite values on the left-hand based on the key or index respectively. Furthermore, if the 2nd argument is not provided, it will simply clone the base value.

import { deepMerge } from '@boost/common';
const obj = deepMerge({ foo: 123, bar: 'abc' }, { foo: 456, baz: true });
// -> { foo: 456, bar: 'abc', baz: true }

formatMs#

formatMs(time: number, options?: Options): string

Can be used to format a UNIX timestamp in milliseconds into a shorthand human readable format. Wraps the pretty-ms package to handle infinite numbers, zeros, and more.

import { formatMs } from '@boost/common';
formatMs(1337000000); // 15d 11h 23m 20s

instanceOf#

instanceOf(object: unknown, declaration: Constructor, loose?: boolean): boolean

Performs a loose instance check by comparing class names up the prototype chain if instanceof initially fails. To disable this loose check, pass false as the 3rd argument.

import { instanceOf } from '@boost/common';
if (instanceOf(error, Error)) {
console.log(error.stack);
}

Generics can be used to type the object being checked. This will default to the declaration passed to the 2nd argument.

instanceOf<ParseError>(error, Error);

Loose checks can be useful if multiple copies of the same class declaration exists in the module tree. For example, multiple versions of the same package are imported.

isEmpty#

isEmpty(value: unknown): boolean

Returns true if an object has no properties, an array has no items, or the value is falsy, otherwise, it returns false.

import { isEmpty } from '@boost/common';
isEmpty({}); // true
isEmpty({ name: 'Boost' }); // false
isEmpty([]); // true
isEmpty(['Boost']); // false

isFilePath#

isFilePath(path: PortablePath): boolean

Returns true if a string or Path instance looks like a file system path, by checking for absolute or relative path markers, or the existence of path separating slashes. Will return false for values that are only the file or folder name.

import { isFilePath } from '@boost/common';
isFilePath('./path/to/file.ts'); // true
isFilePath(new Path('/path/to/folder')); // true
isFilePath('file.ts'); // false

isModuleName#

isModuleName(name: ModuleName): boolean

Returns true if a string is a valid Node module package name, according to the rules defined in validate-npm-package-name. Will return false for native builtin modules, like fs, and for the old name format.

import { isModuleName } from '@boost/common';
isModuleName('boost'); // true
isModuleName('@boost/common'); // true
isModuleName('fs'); // false

isObject#

isObject<T>(value: unknown): value is T

Returns true if the value is an object.

import { isObject } from '@boost/common';
isObject({}); // true
isObject(new Foo()); // true
isObject([]); // false

Generics can be used to type the return value of the object (when necessary).

interface Person {
name: string;
}
if (isObject<Person>(person)) {
console.log(person.name);
}

isPlainObject#

isPlainObject<T>(value: unknown, loose?: boolean): value is T

Like isObject but only returns true if the value is a plain object (no class instances, built-ins, etc). It achieves this by comparing the value's prototype to the built-in Object types. If you need to run these checks for cross-realm objects, pass true to the loose argument.

import { isPlainObject } from '@boost/common';
isPlainObject({}); // true
isPlainObject(new Foo()); // false
isPlainObject([]); // false

parseFile#

parseFile<T>(path: string): T

Can be used to synchronously parse and return an object for the following file types & extensions: js, ts, tsx, json, json5, yaml, yml. The function requires an absolute file path, and any unsupported file type will throw an error.

import { parseFile } from '@boost/common';
const data: ReturnShape = parseFile('/absolute/file/path');

TypeScript files require the typescript package to be installed.

requireModule#

requireModule<T>(path: string): T

Works in a similar fashion to the native NodeJS require(), but also handles files built with Babel or TypeScript by properly returning the default export if an "ES module", and also allowing the expected type to be defined.

import { requireModule } from '@boost/common';
const result: ReturnShape = requireModule('../../some/module');

There are some caveats to be aware of in regards to default and named exports in the file being required, they are:

  • When only a default export, the exported value is returned directly instead of on an object with a default property.
  • When only named exports, the returned value is an object with all the named exports as properties on the object.
  • When a default export and named exports together, the returned value is an object with a default property, and an additional property for every named export. It's best to stay away from this pattern.

requireTypedModule#

requireTypedModule<T>(path: string): T

Like requireModule but for importing TypeScript files ending in ts or tsx. When imported, will transform the file using the typescript package (must be installed), evaluate the code in the current module context, and apply the same process to all child imports.

import { requireTypedModule } from '@boost/common';
const result: ReturnShape = requireTypedModule('../../some/module.ts');

This helper rarely needs to be used directly as parseFile and requireModule will call it under the hood based on the file extension.

toArray#

toArray<T>(value?: T | T[]): T[]

Converts a non-array to an array. If the provided value is falsy, an empty array is returned. If the provided value is truthy and a non-array, an array of 1 item is returned.

import { toArray } from '@boost/common';
toArray(123); // [123]
toArray('abc'); // ['abc']
toArray(['a', 'b', 'c']); // ['a', 'b', 'c']

Serializers#

JSON#

Powered by the JSON5 package, the json serializer can be used to parse and stringify JSON data.

import { json } from '@boost/common';
json.parse(data);
json.stringify(data);

YAML#

Powered by the YAML package, the yaml serializer can be used to parse and stringify YAML data.

import { yaml } from '@boost/common';
yaml.parse(data);
yaml.stringify(data);