feat: add @discordjs/util (#8591)

* feat: add @discordjs/util

* fix: builders test

* refactor: make rest use lazy for ESM import

* chore: make requested changes

* Apply suggestions from code review

Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
Co-authored-by: A. Román <kyradiscord@gmail.com>

* chore: make requested changes and add tests

* chore: regen lockfile

* test: add type tests

* chore: push missing files

* chore: make requested changes

* chore: update CI stuff

* chore: fix lockfile

* chore: make requested changes

Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
Co-authored-by: A. Román <kyradiscord@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Suneet Tipirneni
2022-10-02 14:00:31 -04:00
committed by GitHub
parent 3f8656115b
commit b2ec865765
56 changed files with 1311 additions and 1326 deletions

View File

@@ -0,0 +1,21 @@
/**
* Represents a structure that can be checked against another
* given structure for equality
*
* @typeParam T - The type of object to compare the current object to
*/
export interface Equatable<T> {
/**
* Whether or not this is equal to another structure
*/
equals(other: T): boolean;
}
/**
* Indicates if an object is equatable or not.
*
* @param maybeEquatable - The object to check against
*/
export function isEquatable(maybeEquatable: unknown): maybeEquatable is Equatable<unknown> {
return maybeEquatable !== null && typeof maybeEquatable === 'object' && 'equals' in maybeEquatable;
}

View File

@@ -0,0 +1,20 @@
/**
* Represents an object capable of representing itself as a JSON object
*
* @typeParam T - The JSON type corresponding to {@link JSONEncodable.toJSON} outputs.
*/
export interface JSONEncodable<T> {
/**
* Transforms this object to its JSON format
*/
toJSON(): T;
}
/**
* Indicates if an object is encodable or not.
*
* @param maybeEncodable - The object to check against
*/
export function isJSONEncodable(maybeEncodable: unknown): maybeEncodable is JSONEncodable<unknown> {
return maybeEncodable !== null && typeof maybeEncodable === 'object' && 'toJSON' in maybeEncodable;
}

View File

@@ -0,0 +1,2 @@
export * from './lazy.js';
export * from './range.js';

View File

@@ -0,0 +1,18 @@
/**
* Lazy is a wrapper around a value that is computed lazily. It is useful for
* cases where the value is expensive to compute and the computation may not
* be needed at all.
*
* @param cb - The callback to lazily evaluate
* @typeParam T - The type of the value
* @example
* ```ts
* const value = lazy(() => computeExpensiveValue());
* ```
*/
// eslint-disable-next-line promise/prefer-await-to-callbacks
export function lazy<T>(cb: () => T): () => T {
let defaultValue: T;
// eslint-disable-next-line promise/prefer-await-to-callbacks
return () => (defaultValue ??= cb());
}

View File

@@ -0,0 +1,20 @@
/**
* Yields the numbers in the given range as an array
*
* @param start - The start of the range
* @param end - The end of the range (inclusive)
* @param step - The amount to increment between each number
* @example
* Basic range
* ```ts
* range(3, 5); // [3, 4, 5]
* ```
* @example
* Range with a step
* ```ts
* range(3, 10, 2); // [3, 5, 7, 9]
* ```
*/
export function range(start: number, end: number, step = 1): number[] {
return Array.from({ length: (end - start) / step + 1 }, (_, index) => start + index * step);
}

View File

@@ -0,0 +1,4 @@
export * from './types.js';
export * from './functions/index.js';
export * from './JSONEncodable.js';
export * from './Equatable.js';

View File

@@ -0,0 +1,4 @@
/**
* Represents a type that may or may not be a promise
*/
export type Awaitable<T> = PromiseLike<T> | T;