@aws-lambda-powertools/commons
Version:
A shared utility package for Powertools for AWS Lambda (TypeScript) libraries
325 lines (324 loc) • 8.07 kB
JavaScript
/**
* Check if a value is a record.
*
* @example
* ```typescript
* import { isRecord } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = { key: 'value' };
* if (isRecord(value)) {
* // value is a record
* }
* ```
*
* @param value - The value to check
*/
const isRecord = (value) => {
return (Object.prototype.toString.call(value) === '[object Object]' &&
!Object.is(value, null));
};
/**
* Check if a value is a string.
*
* @example
* ```typescript
* import { isString } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = 'foo';
* if (isString(value)) {
* // value is a string
* }
* ```
*
* @param value - The value to check
*/
const isString = (value) => {
return typeof value === 'string';
};
/**
* Check if a value is a number.
*
* @example
* ```typescript
* import { isNumber } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = 42;
* if (isNumber(value)) {
* // value is a number
* }
* ```
*
* @param value - The value to check
*/
const isNumber = (value) => {
return typeof value === 'number';
};
/**
* Check if a value is an integer number.
*
* @example
* ```typescript
* import { isIntegerNumber } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = 42;
* if (isIntegerNumber(value)) {
* // value is an integer number
* }
* ```
*
* @param value - The value to check
*/
const isIntegerNumber = (value) => {
return isNumber(value) && Number.isInteger(value);
};
/**
* Check if a value is truthy.
*
* @example
* ```typescript
* import { isTruthy } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = 'yes';
* if (isTruthy(value)) {
* // value is truthy
* }
* ```
*
* @see https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/types-grammar/ch4.md#toboolean
*
* @param value - The value to check
*/
const isTruthy = (value) => {
if (isString(value)) {
return value !== '';
}
if (isNumber(value)) {
return value !== 0;
}
if (typeof value === 'boolean') {
return value;
}
if (Array.isArray(value)) {
return value.length > 0;
}
if (isRecord(value)) {
return Object.keys(value).length > 0;
}
return false;
};
/**
* Check if a value is `null`.
*
* @example
* ```typescript
* import { isNull } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = null;
* if (isNull(value)) {
* // value is null
* }
* ```
*
* @param value - The value to check
*/
const isNull = (value) => {
return Object.is(value, null);
};
/**
* Check if a value is `null` or `undefined`.
*
* @example
* ```typescript
* import { isNullOrUndefined } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = null;
* if (isNullOrUndefined(value)) {
* // value is null or undefined
* }
* ```
*
* @param value - The value to check
*/
const isNullOrUndefined = (value) => {
return isNull(value) || Object.is(value, undefined);
};
/**
* Check if string is undefined, null, empty.
*
* @example
* ```typescript
* import { isStringUndefinedNullEmpty } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = 'foo';
* if (isStringUndefinedNullEmpty(value)) {
* // value is either undefined, null, or an empty string
* }
* ```
*
* @param value - The value to check
*/
const isStringUndefinedNullEmpty = (value) => {
if (isNullOrUndefined(value))
return true;
if (!isString(value))
return true;
if (value.trim().length === 0)
return true;
return false;
};
/**
* Check if a Regular Expression
*
* @example
* ```typescript
* import { isRegExp } from '@aws-lambda-powertools/commons/typeUtils';
*
* const value = /^foo.+$/;
* if (isRegExp(value)) {
* // value is a Regular Expression
* }
* ```
*
* @param value - The value to check
*/
const isRegExp = (value) => {
return value instanceof RegExp;
};
/**
* Get the type of a value as a string.
*
* @example
* ```typescript
* import { getType } from '@aws-lambda-powertools/commons/typeUtils';
*
* const type = getType('foo'); // 'string'
* const otherType = getType(42); // 'number'
* const anotherType = getType({ key: 'value' }); // 'object'
* const unknownType = getType(Symbol('foo')); // 'unknown'
* ```
*
* @param value - The value to check
*/
const getType = (value) => {
if (Array.isArray(value)) {
return 'array';
}
if (isRecord(value)) {
return 'object';
}
if (isString(value)) {
return 'string';
}
if (isNumber(value)) {
return 'number';
}
if (typeof value === 'boolean') {
return 'boolean';
}
if (isNull(value)) {
return 'null';
}
return 'unknown';
};
/**
* Compare two arrays for strict equality.
*
* This function compares each element in the arrays, regardless of order.
*
* @example
* ```typescript
* import { areArraysEqual } from '@aws-lambda-powertools/commons/typeUtils';
*
* const left = [1, 2, 3];
* const right = [3, 2, 1];
* const equal = areArraysEqual(left, right); // true
*
* const otherLeft = [1, 2, 3];
* const otherRight = [1, 2, 4];
* const otherEqual = areArraysEqual(otherLeft, otherRight); // false
* ```
*
* @param left - The left array to compare
* @param right - The right array to compare
*/
const areArraysEqual = (left, right) => {
if (left.length !== right.length) {
return false;
}
return left.every((value, i) => isStrictEqual(value, right[i]));
};
/**
* Compare two records for strict equality.
*
* @example
* ```typescript
* import { areRecordsEqual } from '@aws-lambda-powertools/commons/typeUtils';
*
* const left = { key: 'value' };
* const right = { key: 'value' };
* const equal = areRecordsEqual(left, right); // true
*
* const otherLeft = { key: 'value' };
* const otherRight = { key: 'other value' };
* const otherEqual = areRecordsEqual(otherLeft, otherRight); // false
* ```
*
* @param left - The left record to compare
* @param right - The right record to compare
*/
const areRecordsEqual = (left, right) => {
const leftKeys = Object.keys(left);
const rightKeys = Object.keys(right);
if (leftKeys.length !== rightKeys.length) {
return false;
}
return leftKeys.every((key) => isStrictEqual(left[key], right[key]));
};
/**
* Check if two unknown values are strictly equal.
*
* If the values are arrays, then each element is compared, regardless of
* order. If the values are objects, then each key and value from left
* is compared to the corresponding key and value from right. If the
* values are primitives, then they are compared using strict equality.
*
* @example
* ```typescript
* import { isStrictEqual } from '@aws-lambda-powertools/commons/typeUtils';
*
* const left = { key: 'value' };
* const right = { key: 'value' };
* const equal = isStrictEqual(left, right); // true
*
* const otherLeft = [1, 2, 3];
* const otherRight = [3, 2, 1];
* const otherEqual = isStrictEqual(otherLeft, otherRight); // true
*
* const anotherLeft = 'foo';
* const anotherRight = 'bar';
* const anotherEqual = isStrictEqual(anotherLeft, anotherRight); // false
*
* const yetAnotherLeft = 42;
* const yetAnotherRight = 42;
* const yetAnotherEqual = isStrictEqual(yetAnotherLeft, yetAnotherRight); // true
* ```
*
* @param left - Left side of strict equality comparison
* @param right - Right side of strict equality comparison
*/
const isStrictEqual = (left, right) => {
if (left === right) {
return true;
}
if (typeof left !== typeof right) {
return false;
}
if (Array.isArray(left) && Array.isArray(right)) {
return areArraysEqual(left, right);
}
if (isRecord(left) && isRecord(right)) {
return areRecordsEqual(left, right);
}
return false;
};
export { isRecord, isString, isNumber, isIntegerNumber, isTruthy, isNull, isNullOrUndefined, isStringUndefinedNullEmpty, isRegExp, getType, isStrictEqual, };