Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@extollo/util

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@extollo/util - npm Package Compare versions

Comparing version
0.1.0
to
0.2.0
+28
lib/cache/Cache.d.ts
/**
* Abstract interface class for an application cache object.
*/
export declare abstract class Cache {
/**
* Fetch a value from the cache by its key.
* @param {string} key
* @return Promise<any|undefined>
*/
abstract fetch(key: string): Promise<any>;
/**
* Store the given value in the cache by key.
* @param {string} key
* @param {string} value
*/
abstract put(key: string, value: string): Promise<void>;
/**
* Check if the cache has the given key.
* @param {string} key
* @return Promise<boolean>
*/
abstract has(key: string): Promise<boolean>;
/**
* Drop the given key from the cache.
* @param {string} key
*/
abstract drop(key: string): Promise<void>;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cache = void 0;
/**
* Abstract interface class for an application cache object.
*/
class Cache {
}
exports.Cache = Cache;
import { Cache } from './Cache';
import { Collection } from '../collection/Collection';
/**
* Base interface for an item stored in a memory cache.
*/
export interface InMemCacheItem {
key: string;
item: string;
}
/**
* A cache implementation stored in memory.
* @extends Cache
*/
export declare class InMemCache extends Cache {
/**
* The stored cache items.
* @type Collection<InMemCacheItem>
*/
protected items: Collection<InMemCacheItem>;
fetch(key: string): Promise<string | undefined>;
put(key: string, item: string): Promise<void>;
has(key: string): Promise<boolean>;
drop(key: string): Promise<void>;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InMemCache = void 0;
const Cache_1 = require("./Cache");
const Collection_1 = require("../collection/Collection");
/**
* A cache implementation stored in memory.
* @extends Cache
*/
class InMemCache extends Cache_1.Cache {
constructor() {
super(...arguments);
/**
* The stored cache items.
* @type Collection<InMemCacheItem>
*/
this.items = new Collection_1.Collection();
}
fetch(key) {
return __awaiter(this, void 0, void 0, function* () {
const item = this.items.firstWhere('key', '=', key);
if (item)
return item.item;
});
}
put(key, item) {
return __awaiter(this, void 0, void 0, function* () {
const existing = this.items.firstWhere('key', '=', key);
if (existing)
existing.item = item;
else
this.items.push({ key, item });
});
}
has(key) {
return __awaiter(this, void 0, void 0, function* () {
return this.items.where('key', '=', key).length > 0;
});
}
drop(key) {
return __awaiter(this, void 0, void 0, function* () {
this.items = this.items.whereNot('key', '=', key);
});
}
}
exports.InMemCache = InMemCache;
import { Iterable } from './Iterable';
/**
* A basic Iterable implementation that uses an array as a backend.
* @extends Iterable
*/
export declare class ArrayIterable<T> extends Iterable<T> {
/**
* Items to use for this iterable.
*/
protected items: T[];
constructor(
/**
* Items to use for this iterable.
*/
items: T[]);
at_index(i: number): Promise<T>;
from_range(start: number, end: number): Promise<import("./Collection").Collection<T>>;
count(): Promise<number>;
clone(): ArrayIterable<T>;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayIterable = void 0;
const Iterable_1 = require("./Iterable");
const Collection_1 = require("./Collection");
/**
* A basic Iterable implementation that uses an array as a backend.
* @extends Iterable
*/
class ArrayIterable extends Iterable_1.Iterable {
constructor(
/**
* Items to use for this iterable.
*/
items) {
super();
this.items = items;
}
at_index(i) {
return __awaiter(this, void 0, void 0, function* () {
return this.items[i];
});
}
from_range(start, end) {
return __awaiter(this, void 0, void 0, function* () {
return Collection_1.collect(this.items.slice(start, end + 1));
});
}
count() {
return __awaiter(this, void 0, void 0, function* () {
return this.items.length;
});
}
clone() {
return new ArrayIterable([...this.items]);
}
}
exports.ArrayIterable = ArrayIterable;
import { Collection, CollectionIndex, CollectionItem, ComparisonFunction, DeterminesEquality, KeyFunction, KeyOperator, KeyReducerFunction, MaybeCollectionIndex, MaybeCollectionItem } from './Collection';
import { Iterable } from './Iterable';
import { WhereOperator } from './where';
declare type AsyncCollectionComparable<T> = CollectionItem<T>[] | Collection<T> | AsyncCollection<T>;
declare type AsyncKeyFunction<T, T2> = (item: CollectionItem<T>, index: number) => CollectionItem<T2> | Promise<CollectionItem<T2>>;
declare type AsyncCollectionFunction<T, T2> = (items: AsyncCollection<T>) => T2;
/**
* Like a collection, but asynchronous.
*/
export declare class AsyncCollection<T> {
/**
* Iterable of items to base this collction on.
* @type Iterable
*/
private _items;
/**
* Size to use when chunking results for memory-optimization.
* @type number
*/
private _chunk_size;
constructor(
/**
* Iterable of items to base this collction on.
* @type Iterable
*/
_items: Iterable<T>,
/**
* Size to use when chunking results for memory-optimization.
* @type number
*/
_chunk_size?: number);
private _chunk;
private _chunk_all;
private _chunk_all_numbers;
private _chunk_all_associate;
/**
* Get all items in this collection as an array.
* @return Promise<array>
*/
all(): Promise<CollectionItem<T>[]>;
/**
* Get all items in this collection as a synchronous Collection
* @return Promise<Collection>
*/
collect(): Promise<Collection<T>>;
/**
* Get the average value of the collection or one of its keys.
* @param {KeyOperator} key
* @return Promise<number>
*/
average<T2>(key?: KeyOperator<T, T2>): Promise<number>;
/**
* Get the median value of the collection or one of its keys.
* @param {KeyOperator} key
* @return Promise<number>
*/
median<T2>(key?: KeyOperator<T, T2>): Promise<number>;
/**
* Get the mode value of the collection or one of its keys.
* @param {KeyOperator} key
* @return Promise<number>
*/
mode<T2>(key?: KeyOperator<T, T2>): Promise<number>;
/**
* If this collection contains nested collections, collapse them to a single level.
* @return Promise<Collection>
*/
collapse(): Promise<Collection<any>>;
/**
* Returns true if the collection contains an item satisfying the given collection.
* @example
* collection.contains('id', '>', 4)
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<boolean>
*/
contains<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Promise<boolean>;
/**
* Returns a clean instance of this collection pointing to the same result set of the iterable.
* @return Promise<AsyncCollection>
*/
clone(): Promise<AsyncCollection<T>>;
/**
* Returns the elements that are different between the two collections.
* @param {AsyncCollectionComparable} items
* @return Promise<Collection>
*/
diff(items: AsyncCollectionComparable<T>): Promise<Collection<T>>;
/**
* Returns the elements that are different between the two collections, using the given function
* as a comparator for the elements.
* @param {AsyncCollectionComparable} items
* @param {DeterminesEquality} compare
* @return Promise<Collection>
*/
diffUsing(items: AsyncCollectionComparable<T>, compare: DeterminesEquality<T>): Promise<Collection<T>>;
/**
* Returns true if the given item is present in the collection.
* @param item
* @return Promise<boolean>
*/
includes(item: CollectionItem<T>): Promise<boolean>;
/**
* Returns true if there is an item in the collection for which the given operator returns true.
* @param {function} operator - item => boolean
* @return Promise<boolean>
*/
some(operator: (item: T) => boolean): Promise<boolean>;
/**
* Applies a callback to each item in the collection.
* @param {AsyncKeyFunction} func
* @return Promise<void>
*/
each<T2>(func: AsyncKeyFunction<T, T2>): Promise<void>;
/**
* Applies a callback to each item in the collection and returns the results as a collection.
* @param {AsyncKeyFunction} func
* @return Promise<Collection>
*/
map<T2>(func: AsyncKeyFunction<T, T2>): Promise<Collection<T2>>;
/**
* Returns true if the given operator returns true for every item in the collection.
* @param {AsyncKeyFunction} func
* @return Promise<boolean>
*/
every<T2>(func: AsyncKeyFunction<T, T2>): Promise<boolean>;
/**
* Returns true if every item in the collection satisfies the given where clause.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
*/
everyWhere<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Promise<boolean>;
/**
* Applies a filter to every item in the collection and returns the results that pass the filter.
* @param {KeyFunction} func
* @return Promise<Collection>
*/
filter<T2>(func: KeyFunction<T, T2>): Promise<Collection<T>>;
/**
* Calls the passed in function if the boolean condition is true. Allows for functional syntax.
* @param {boolean} bool
* @param {AsyncCollectionFunction} then
* @return AsyncCollection
*/
when<T2>(bool: boolean, then: AsyncCollectionFunction<T, T2>): AsyncCollection<T>;
/**
* Calls the passed in function if the boolean condition is false. Allows for functional syntax.
* @param {boolean} bool
* @param {AsyncCollectionFunction} then
* @return AsyncCollection
*/
unless<T2>(bool: boolean, then: AsyncCollectionFunction<T, T2>): AsyncCollection<T>;
/**
* Applies the given where condition to the collection and returns a new collection of the results.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<Collection>
*/
where<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Promise<Collection<T>>;
/**
* Applies the given where condition to the collection and returns a new collection of the items
* that did not satisfy the condition.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<Collection>
*/
whereNot<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Promise<Collection<T>>;
/**
* Applies a WHERE ... IN ... condition to the collection an returns a new collection of the results.
* @param {KeyOperator} key
* @param {AsyncCollectionComparable} items
* @return Promise<Collection>
*/
whereIn<T2>(key: KeyOperator<T, T2>, items: AsyncCollectionComparable<T2>): Promise<Collection<T>>;
/**
* Applies a WHERE ... IN ... condition to the collection and returns a new collection of the items
* that did not satisfy the condition.
* @param {KeyOperator} key
* @param {AsyncCollectionComparable} items
* @return Promise<Collection>
*/
whereNotIn<T2>(key: KeyOperator<T, T2>, items: AsyncCollectionComparable<T2>): Promise<Collection<T>>;
/**
* Returns the first item in the collection, if one exists.
* @return Promise<MaybeCollectionItem>
*/
first(): Promise<MaybeCollectionItem<T>>;
/**
* Return the first item in the collection that satisfies the given where condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} [operator = '=']
* @param [operand = true]
* @return Promise<MaybeCollectionItem>
*/
firstWhere<T2>(key: KeyOperator<T, T2>, operator?: WhereOperator, operand?: any): Promise<MaybeCollectionItem<T>>;
/**
* Return the first item in the collection that does not satisfy the given where condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} [operator = '=']
* @param [operand = true]
*/
firstWhereNot<T2>(key: KeyOperator<T, T2>, operator?: WhereOperator, operand?: any): Promise<MaybeCollectionItem<T>>;
/**
* Returns the number of elements in this collection.
* @return Promise<number>
*/
count(): Promise<number>;
/**
* Returns the number of elements in this collection.
* @return Promise<number>
*/
length(): Promise<number>;
/**
* Get the item at the given index of this collection, if one exists.
* If none exists and a fallback value is provided, that value will be returned.
* @param {number} index
* @param [fallback]
* @return Promise<any>
*/
get(index: number, fallback?: any): Promise<any>;
/**
* Get the item at the given index of this collection, if one exists.
* @param {number} index
*/
at(index: number): Promise<MaybeCollectionItem<T>>;
/**
* Return an object which maps key values to arrays of items in the collection that satisfy that value.
* @param {KeyOperator} key
* @return Promise<object>
*/
groupBy<T2>(key: KeyOperator<T, T2>): Promise<any>;
/**
* Return an object mapping the given key value to items in this collection.
* @param {KeyOperator} key
* @return Promise<object>
*/
associate<T2>(key: KeyOperator<T, T2>): Promise<any>;
/**
* Join the items in this collection with the given delimiter.
* @example
* await collection.join(',') // => '1,2,3,4'
* @param {string} delimiter
* @return Promise<string>
*/
join(delimiter: string): Promise<string>;
/**
* Join the items in this collection with the given delimiter.
* @example
* await collection.implode(',') // => '1,2,3,4'
* @param {string} delimiter
* @return Promise<string>
*/
implode(delimiter: string): Promise<string>;
/**
* Returns true if there are no items in this collection.
* @return Promise<boolean>
*/
isEmpty(): Promise<boolean>;
/**
* Returns true if there is at least one item in this collection.
* @return Promise<boolean>
*/
isNotEmpty(): Promise<boolean>;
/**
* Return the last item in this collection, if one exists.
* @return Promise<MaybeCollectionItem>
*/
last(): Promise<MaybeCollectionItem<T>>;
/**
* Return the last item in this collection which satisfies the given where condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<MaybeCollectionItem>
*/
lastWhere<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Promise<MaybeCollectionItem<T>>;
/**
* Return the last item in this collection which does not satisfy the given condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<MaybeCollectionItem>
*/
lastWhereNot<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Promise<MaybeCollectionItem<T>>;
/**
* Builds a collection of the values of a given key for each item in this collection.
* @example
* // collection has { a: 1 }, { a: 2 }, { a: 3 }
* await collection.pluck('a') // => [1, 2, 3]
* @param {KeyOperator} key
* @return Promise<Collection>
*/
pluck<T2>(key: KeyOperator<T, T2>): Promise<Collection<T2>>;
/**
* Return the max value of the given key.
* @param {KeyOperator} key
* @return Promise<number>
*/
max<T2>(key: KeyOperator<T, T2>): Promise<number>;
/**
* Return a collection of items that have the max value of the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
whereMax<T2>(key: KeyOperator<T, T2>): Promise<Collection<T>>;
/**
* Return the min value of the given key.
* @param {KeyOperator} key
* @return Promise<number>
*/
min<T2>(key: KeyOperator<T, T2>): Promise<number>;
/**
* Return a collection of items that have the min value of the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
whereMin<T2>(key: KeyOperator<T, T2>): Promise<Collection<T>>;
/**
* Merge the two collections.
* @param {AsyncCollectionComparable} merge_with
* @return Promise<Collection>
*/
merge<T2>(merge_with: AsyncCollectionComparable<T2>): Promise<Collection<T | T2>>;
/**
* Return a collection of every nth item in this collection.
* @param {number} n
* @return Promise<Collection>
*/
nth(n: number): Promise<Collection<T>>;
/**
* Return a collection containing the items that would be on the given page, with the given number of items per page.
* @param {number} page
* @param {number} per_page
*/
forPage(page: number, per_page: number): Promise<Collection<T>>;
/**
* Return the value of the function, passing this collection to it.
* @param {AsyncCollectionFunction} func
*/
pipe<T2>(func: AsyncCollectionFunction<T, T2>): any;
/**
* Get n random items from this collection.
* @todo add safety check for it loop exceeds max number of items
* @param {number} n
* @return Promise<Collection>
*/
random(n: number): Promise<Collection<T>>;
/**
* Collapse the collection into a single value using a reducer function.
* @param {KeyReducerFunction} reducer
* @param [initial_value]
* @return Promise<any>
*/
reduce<T2>(reducer: KeyReducerFunction<T, T2>, initial_value?: T2): Promise<T2 | undefined>;
/**
* Returns a collection of items that fail the truth test.
* @param {AsyncKeyFunction} truth_test
* @return Promise<Collection>
*/
reject<T2>(truth_test: AsyncKeyFunction<T, T2>): Promise<Collection<T>>;
/**
* Get a reversed collection of this collection's items.
* @return Promise<Collection>
*/
reverse(): Promise<Collection<T>>;
/**
* Search the collection and return the index of that item, if one exists.
* @param {CollectionItem} item
* @return Promise<MaybeCollectionIndex>
*/
search(item: CollectionItem<T>): Promise<MaybeCollectionIndex>;
/**
* Get the next item in the collection and remove it.
* @return Promise<MaybeCollectionItem>
*/
shift(): Promise<MaybeCollectionItem<T>>;
/**
* Shuffle the items in the collection to a random order.
* @return Promise<Collection>
*/
shuffle(): Promise<Collection<T>>;
/**
* Return a slice of this collection.
* @param {number} start - the starting index
* @param {number} end - the ending index
* @return Promise<Collection>
*/
slice(start: number, end: number): Promise<Collection<T>>;
/**
* Sort the collection, optionally with the given comparison function.
* @param {ComparisonFunction} compare_func
* @return Promise<Collection>
*/
sort(compare_func?: ComparisonFunction<T>): Promise<Collection<T>>;
/**
* Sort the collection by the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
sortBy<T2>(key?: KeyOperator<T, T2>): Promise<Collection<T>>;
/**
* Reverse sort the collection, optionally with the given comparison function.
* @param {ComparisonFunction} compare_func
* @return Promise<Collection>
*/
sortDesc(compare_func?: ComparisonFunction<T>): Promise<Collection<T>>;
/**
* Reverse sort the collection by the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
sortByDesc<T2>(key?: KeyOperator<T, T2>): Promise<Collection<T>>;
/**
* Splice the collection at the given index. Optionally, removing the given number of items.
* @param {CollectionIndex} start
* @param {number} [deleteCount]
* @return Promise<Collection>
*/
splice(start: CollectionIndex, deleteCount?: number): Promise<Collection<T>>;
/**
* Sum the items in the collection, or the values of the given key.
* @param {KeyOperator} key
* @return Promise<number>
*/
sum<T2>(key?: KeyOperator<T, T2>): Promise<number>;
/**
* Take the first n items from the front or back of the collection.
* @param {number} limit
* @return Promise<Collection>
*/
take(limit: number): Promise<Collection<T>>;
/**
* Call the given function, passing in this collection. Allows functional syntax.
* @param {AsyncCollectionFunction} func
* @return Promise<AsyncCollection>
*/
tap<T2>(func: AsyncCollectionFunction<T, T2>): Promise<AsyncCollection<T>>;
/**
* Return all the unique values in the collection, or the unique values of the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
unique<T2>(key?: KeyOperator<T, T2>): Promise<Collection<T | T2>>;
/**
* Cast this collection to an array.
* @return Promise<array>
*/
toArray(): Promise<any[]>;
/**
* Cast this collection to a JSON string.
* @param [replacer] - the replacer to use
* @param {number} [space = 4] number of indentation spaces to use
*/
toJSON(replacer?: undefined, space?: number): Promise<string>;
/**
* Get a clone of the underlying iterator of this collection.
* @return Iterable
*/
iterator(): Iterable<T>;
}
export {};
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncCollection = void 0;
const Collection_1 = require("./Collection");
const Iterable_1 = require("./Iterable");
const where_1 = require("./where");
/**
* Like a collection, but asynchronous.
*/
class AsyncCollection {
constructor(
/**
* Iterable of items to base this collction on.
* @type Iterable
*/
_items,
/**
* Size to use when chunking results for memory-optimization.
* @type number
*/
_chunk_size = 1000) {
this._items = _items;
this._chunk_size = _chunk_size;
}
_chunk(callback) {
return __awaiter(this, void 0, void 0, function* () {
yield this._items.chunk(this._chunk_size, (items) => __awaiter(this, void 0, void 0, function* () {
yield callback(items);
}));
yield this._items.reset();
});
}
_chunk_all(key, callback) {
return __awaiter(this, void 0, void 0, function* () {
yield this._items.chunk(this._chunk_size, (items) => __awaiter(this, void 0, void 0, function* () {
yield callback(items.pluck(key));
}));
yield this._items.reset();
});
}
_chunk_all_numbers(key, callback) {
return __awaiter(this, void 0, void 0, function* () {
yield this._items.chunk(this._chunk_size, (items) => __awaiter(this, void 0, void 0, function* () {
yield callback(items.pluck(key).map(x => Number(x)).all());
}));
yield this._items.reset();
});
}
_chunk_all_associate(key, callback) {
return __awaiter(this, void 0, void 0, function* () {
yield this._items.chunk(this._chunk_size, (items) => __awaiter(this, void 0, void 0, function* () {
const assoc_items = [];
if (typeof key === 'function') {
items.map((item, index) => {
const key_item = key(item, index);
assoc_items.push({ key: key_item, item });
});
}
else {
items.map((item, index) => {
assoc_items.push({ key: item[key], item });
});
}
yield callback(assoc_items);
}));
yield this._items.reset();
});
}
/**
* Get all items in this collection as an array.
* @return Promise<array>
*/
all() {
return __awaiter(this, void 0, void 0, function* () {
return (yield this._items.from_range(0, yield this._items.count())).all();
});
}
/**
* Get all items in this collection as a synchronous Collection
* @return Promise<Collection>
*/
collect() {
return __awaiter(this, void 0, void 0, function* () {
return this._items.from_range(0, yield this._items.count());
});
}
/**
* Get the average value of the collection or one of its keys.
* @param {KeyOperator} key
* @return Promise<number>
*/
average(key) {
return __awaiter(this, void 0, void 0, function* () {
let running_total = 0;
let running_items = 0;
const chunk_helper = (items) => {
running_items += items.length;
running_total += items.reduce((prev, curr) => prev + curr);
};
if (key)
yield this._chunk_all_numbers(key, chunk_helper);
else
yield this._chunk((items) => {
chunk_helper(items.map(x => Number(x)).all());
});
return running_total / running_items;
});
}
/**
* Get the median value of the collection or one of its keys.
* @param {KeyOperator} key
* @return Promise<number>
*/
median(key) {
return __awaiter(this, void 0, void 0, function* () {
let items = [];
const chunk_helper = (next_items) => {
items = items.concat(next_items);
};
if (key)
yield this._chunk_all_numbers(key, chunk_helper);
else
yield this._chunk(items => {
chunk_helper(items.map(x => Number(x)).all());
});
items = items.sort((a, b) => a - b);
const middle = Math.floor((items.length - 1) / 2);
if (items.length % 2)
return items[middle];
else
return (items[middle] + items[middle + 1]) / 2;
});
}
/**
* Get the mode value of the collection or one of its keys.
* @param {KeyOperator} key
* @return Promise<number>
*/
mode(key) {
return __awaiter(this, void 0, void 0, function* () {
let counts = {};
const chunk_helper = (items) => {
for (const item of items) {
if (!counts[item])
counts[item] = 1;
else
counts[item] += 1;
}
};
if (key)
yield this._chunk_all_numbers(key, chunk_helper);
else
yield this._chunk(items => {
chunk_helper(items.map(x => Number(x)).all());
});
return Number(Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b)[0]);
});
}
/**
* If this collection contains nested collections, collapse them to a single level.
* @return Promise<Collection>
*/
collapse() {
return __awaiter(this, void 0, void 0, function* () {
const items = yield this.collect();
return items.collapse();
});
}
/**
* Returns true if the collection contains an item satisfying the given collection.
* @example
* collection.contains('id', '>', 4)
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<boolean>
*/
contains(key, operator, operand) {
return __awaiter(this, void 0, void 0, function* () {
let contains = false;
yield this._chunk_all_associate(key, (items) => {
const matches = where_1.applyWhere(items, operator, operand);
if (matches.length > 0) {
contains = true;
throw new Iterable_1.StopIteration();
}
});
return contains;
});
}
/**
* Returns a clean instance of this collection pointing to the same result set of the iterable.
* @return Promise<AsyncCollection>
*/
clone() {
return __awaiter(this, void 0, void 0, function* () {
return new AsyncCollection(yield this._items.clone());
});
}
/**
* Returns the elements that are different between the two collections.
* @param {AsyncCollectionComparable} items
* @return Promise<Collection>
*/
diff(items) {
return __awaiter(this, void 0, void 0, function* () {
const matches = [];
yield this._chunk((chunk) => __awaiter(this, void 0, void 0, function* () {
for (const item of chunk.all()) {
if (!(yield items.includes(item))) {
matches.push(item);
}
}
}));
return new Collection_1.Collection(matches);
});
}
/**
* Returns the elements that are different between the two collections, using the given function
* as a comparator for the elements.
* @param {AsyncCollectionComparable} items
* @param {DeterminesEquality} compare
* @return Promise<Collection>
*/
diffUsing(items, compare) {
return __awaiter(this, void 0, void 0, function* () {
const matches = [];
yield this._chunk((chunk) => __awaiter(this, void 0, void 0, function* () {
for (const item of chunk.all()) {
if (!(yield items.some(exc => compare(item, exc))))
matches.push(item);
}
}));
return new Collection_1.Collection(matches);
});
}
/**
* Returns true if the given item is present in the collection.
* @param item
* @return Promise<boolean>
*/
includes(item) {
return __awaiter(this, void 0, void 0, function* () {
let contains = false;
yield this._chunk(items => {
if (items.includes(item)) {
contains = true;
throw new Iterable_1.StopIteration();
}
});
return contains;
});
}
/**
* Returns true if there is an item in the collection for which the given operator returns true.
* @param {function} operator - item => boolean
* @return Promise<boolean>
*/
some(operator) {
return __awaiter(this, void 0, void 0, function* () {
let contains = false;
yield this._chunk(items => {
for (const item of items.all()) {
if (operator(item)) {
contains = true;
throw new Iterable_1.StopIteration();
}
}
});
return contains;
});
}
/**
* Applies a callback to each item in the collection.
* @param {AsyncKeyFunction} func
* @return Promise<void>
*/
each(func) {
return __awaiter(this, void 0, void 0, function* () {
let index = 0;
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
for (const item of items.all()) {
yield func(item, index);
index += 1;
}
}));
});
}
/**
* Applies a callback to each item in the collection and returns the results as a collection.
* @param {AsyncKeyFunction} func
* @return Promise<Collection>
*/
map(func) {
return __awaiter(this, void 0, void 0, function* () {
const new_items = [];
yield this.each((item, index) => __awaiter(this, void 0, void 0, function* () {
new_items.push(yield func(item, index));
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Returns true if the given operator returns true for every item in the collection.
* @param {AsyncKeyFunction} func
* @return Promise<boolean>
*/
every(func) {
return __awaiter(this, void 0, void 0, function* () {
let pass = true;
let index = 0;
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
for (const item of items.all()) {
if (!(yield func(item, index))) {
pass = false;
throw new Iterable_1.StopIteration();
}
index += 1;
}
}));
return pass;
});
}
/**
* Returns true if every item in the collection satisfies the given where clause.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
*/
everyWhere(key, operator, operand) {
return __awaiter(this, void 0, void 0, function* () {
let pass = true;
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
pass = pass && items.everyWhere(key, operator, operand);
if (!pass) {
throw new Iterable_1.StopIteration();
}
}));
return pass;
});
}
/**
* Applies a filter to every item in the collection and returns the results that pass the filter.
* @param {KeyFunction} func
* @return Promise<Collection>
*/
filter(func) {
return __awaiter(this, void 0, void 0, function* () {
let new_items = [];
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
new_items = new_items.concat(items.filter(func).all());
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Calls the passed in function if the boolean condition is true. Allows for functional syntax.
* @param {boolean} bool
* @param {AsyncCollectionFunction} then
* @return AsyncCollection
*/
when(bool, then) {
if (bool)
then(this);
return this;
}
/**
* Calls the passed in function if the boolean condition is false. Allows for functional syntax.
* @param {boolean} bool
* @param {AsyncCollectionFunction} then
* @return AsyncCollection
*/
unless(bool, then) {
if (!bool)
then(this);
return this;
}
/**
* Applies the given where condition to the collection and returns a new collection of the results.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<Collection>
*/
where(key, operator, operand) {
return __awaiter(this, void 0, void 0, function* () {
let new_items = [];
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
new_items = new_items.concat(items.where(key, operator, operand).all());
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Applies the given where condition to the collection and returns a new collection of the items
* that did not satisfy the condition.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<Collection>
*/
whereNot(key, operator, operand) {
return __awaiter(this, void 0, void 0, function* () {
let new_items = [];
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
new_items = new_items.concat(items.whereNot(key, operator, operand).all());
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Applies a WHERE ... IN ... condition to the collection an returns a new collection of the results.
* @param {KeyOperator} key
* @param {AsyncCollectionComparable} items
* @return Promise<Collection>
*/
whereIn(key, items) {
return __awaiter(this, void 0, void 0, function* () {
let new_items = [];
yield this._chunk_all_associate(key, (chunk) => __awaiter(this, void 0, void 0, function* () {
for (const item of chunk) {
if (yield items.includes(item.key)) {
new_items.push(item.item);
}
}
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Applies a WHERE ... IN ... condition to the collection and returns a new collection of the items
* that did not satisfy the condition.
* @param {KeyOperator} key
* @param {AsyncCollectionComparable} items
* @return Promise<Collection>
*/
whereNotIn(key, items) {
return __awaiter(this, void 0, void 0, function* () {
let new_items = [];
yield this._chunk_all_associate(key, (chunk) => __awaiter(this, void 0, void 0, function* () {
for (const item of chunk) {
if (!(yield items.includes(item.key))) {
new_items.push(item.item);
}
}
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Returns the first item in the collection, if one exists.
* @return Promise<MaybeCollectionItem>
*/
first() {
return __awaiter(this, void 0, void 0, function* () {
if ((yield this._items.count()) > 0) {
return this._items.at_index(0);
}
});
}
/**
* Return the first item in the collection that satisfies the given where condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} [operator = '=']
* @param [operand = true]
* @return Promise<MaybeCollectionItem>
*/
firstWhere(key, operator = '=', operand = true) {
return __awaiter(this, void 0, void 0, function* () {
let item = undefined;
yield this._chunk_all_associate(key, (items) => __awaiter(this, void 0, void 0, function* () {
const matches = where_1.applyWhere(items, operator, operand);
if (matches.length > 0) {
item = matches[0];
throw new Iterable_1.StopIteration();
}
}));
return item;
});
}
/**
* Return the first item in the collection that does not satisfy the given where condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} [operator = '=']
* @param [operand = true]
*/
firstWhereNot(key, operator = '=', operand = true) {
return __awaiter(this, void 0, void 0, function* () {
let item = undefined;
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
const matches = items.whereNot(key, operator, operand);
if (matches.length > 0) {
item = matches.first();
throw new Iterable_1.StopIteration();
}
}));
return item;
});
}
/**
* Returns the number of elements in this collection.
* @return Promise<number>
*/
count() {
return __awaiter(this, void 0, void 0, function* () {
return this._items.count();
});
}
/**
* Returns the number of elements in this collection.
* @return Promise<number>
*/
length() {
return __awaiter(this, void 0, void 0, function* () {
return this._items.count();
});
}
/**
* Get the item at the given index of this collection, if one exists.
* If none exists and a fallback value is provided, that value will be returned.
* @param {number} index
* @param [fallback]
* @return Promise<any>
*/
get(index, fallback) {
return __awaiter(this, void 0, void 0, function* () {
if ((yield this.count()) > index)
return this._items.at_index(index);
else
return fallback;
});
}
/**
* Get the item at the given index of this collection, if one exists.
* @param {number} index
*/
at(index) {
return __awaiter(this, void 0, void 0, function* () {
return this.get(index);
});
}
/**
* Return an object which maps key values to arrays of items in the collection that satisfy that value.
* @param {KeyOperator} key
* @return Promise<object>
*/
groupBy(key) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).groupBy(key);
});
}
/**
* Return an object mapping the given key value to items in this collection.
* @param {KeyOperator} key
* @return Promise<object>
*/
associate(key) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).associate(key);
});
}
/**
* Join the items in this collection with the given delimiter.
* @example
* await collection.join(',') // => '1,2,3,4'
* @param {string} delimiter
* @return Promise<string>
*/
join(delimiter) {
return __awaiter(this, void 0, void 0, function* () {
let running_strings = [];
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
running_strings.push(items.join(delimiter));
}));
return running_strings.join(delimiter);
});
}
/**
* Join the items in this collection with the given delimiter.
* @example
* await collection.implode(',') // => '1,2,3,4'
* @param {string} delimiter
* @return Promise<string>
*/
implode(delimiter) {
return __awaiter(this, void 0, void 0, function* () {
return this.join(delimiter);
});
}
// TODO intersect
/**
* Returns true if there are no items in this collection.
* @return Promise<boolean>
*/
isEmpty() {
return __awaiter(this, void 0, void 0, function* () {
return (yield this._items.count()) < 1;
});
}
/**
* Returns true if there is at least one item in this collection.
* @return Promise<boolean>
*/
isNotEmpty() {
return __awaiter(this, void 0, void 0, function* () {
return (yield this._items.count()) > 0;
});
}
/**
* Return the last item in this collection, if one exists.
* @return Promise<MaybeCollectionItem>
*/
last() {
return __awaiter(this, void 0, void 0, function* () {
const length = yield this._items.count();
if (length > 0)
return this._items.at_index(length - 1);
});
}
/**
* Return the last item in this collection which satisfies the given where condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<MaybeCollectionItem>
*/
lastWhere(key, operator, operand) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.where(key, operator, operand)).last();
});
}
/**
* Return the last item in this collection which does not satisfy the given condition, if one exists.
* @param {KeyOperator} key
* @param {WhereOperator} operator
* @param [operand]
* @return Promise<MaybeCollectionItem>
*/
lastWhereNot(key, operator, operand) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.whereNot(key, operator, operand)).last();
});
}
/**
* Builds a collection of the values of a given key for each item in this collection.
* @example
* // collection has { a: 1 }, { a: 2 }, { a: 3 }
* await collection.pluck('a') // => [1, 2, 3]
* @param {KeyOperator} key
* @return Promise<Collection>
*/
pluck(key) {
return __awaiter(this, void 0, void 0, function* () {
let new_items = [];
yield this._chunk_all(key, (items) => __awaiter(this, void 0, void 0, function* () {
new_items = new_items.concat(items.all());
}));
return new Collection_1.Collection(new_items);
});
}
/**
* Return the max value of the given key.
* @param {KeyOperator} key
* @return Promise<number>
*/
max(key) {
return __awaiter(this, void 0, void 0, function* () {
let running_max;
yield this._chunk_all_numbers(key, (items) => __awaiter(this, void 0, void 0, function* () {
const local_max = Math.max(...items);
if (typeof running_max === 'undefined')
running_max = local_max;
else
running_max = Math.max(running_max, local_max);
}));
// @ts-ignore
return running_max;
});
}
/**
* Return a collection of items that have the max value of the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
whereMax(key) {
return __awaiter(this, void 0, void 0, function* () {
return this.where(key, '=', yield this.max(key));
});
}
/**
* Return the min value of the given key.
* @param {KeyOperator} key
* @return Promise<number>
*/
min(key) {
return __awaiter(this, void 0, void 0, function* () {
let running_min;
yield this._chunk_all_numbers(key, (items) => __awaiter(this, void 0, void 0, function* () {
const local_min = Math.min(...items);
if (typeof running_min === 'undefined')
running_min = local_min;
else
running_min = Math.min(running_min, local_min);
}));
// @ts-ignore
return running_min;
});
}
/**
* Return a collection of items that have the min value of the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
whereMin(key) {
return __awaiter(this, void 0, void 0, function* () {
return this.where(key, '=', yield this.min(key));
});
}
/**
* Merge the two collections.
* @param {AsyncCollectionComparable} merge_with
* @return Promise<Collection>
*/
merge(merge_with) {
return __awaiter(this, void 0, void 0, function* () {
let items;
if (merge_with instanceof Collection_1.Collection)
items = yield merge_with.all();
else if (merge_with instanceof AsyncCollection)
items = yield merge_with.all();
else if (Array.isArray(merge_with))
items = merge_with;
// @ts-ignore
return new Collection_1.Collection([...items, ...yield this.all()]);
});
}
/**
* Return a collection of every nth item in this collection.
* @param {number} n
* @return Promise<Collection>
*/
nth(n) {
return __awaiter(this, void 0, void 0, function* () {
const matches = [];
let current = 1;
yield this._chunk((chunk) => __awaiter(this, void 0, void 0, function* () {
for (const item of chunk.all()) {
if (current === 1)
matches.push(item);
current += 1;
if (current > n)
current = 1;
}
}));
return new Collection_1.Collection(matches);
});
}
/**
* Return a collection containing the items that would be on the given page, with the given number of items per page.
* @param {number} page
* @param {number} per_page
*/
forPage(page, per_page) {
return __awaiter(this, void 0, void 0, function* () {
const start = page * per_page - per_page;
const end = page * per_page - 1;
return this._items.from_range(start, end);
});
}
/**
* Return the value of the function, passing this collection to it.
* @param {AsyncCollectionFunction} func
*/
pipe(func) {
return func(this);
}
/*async pop(): Promise<MaybeCollectionItem<T>> {
const next_item = await this._items.next()
if ( !next_item.done ) {
return next_item.value
}
}*/ // TODO Fix this
/**
* Get n random items from this collection.
* @todo add safety check for it loop exceeds max number of items
* @param {number} n
* @return Promise<Collection>
*/
random(n) {
return __awaiter(this, void 0, void 0, function* () {
const random_items = [];
const fetched_indices = [];
const max_n = yield this._items.count();
if (n > max_n)
n = max_n;
while (random_items.length < n) {
const index = Math.floor(Math.random() * max_n);
if (!fetched_indices.includes(index)) {
fetched_indices.push(index);
const item = yield this._items.at_index(index);
if (typeof item !== 'undefined')
random_items.push(item);
}
}
return new Collection_1.Collection(random_items);
});
}
/**
* Collapse the collection into a single value using a reducer function.
* @param {KeyReducerFunction} reducer
* @param [initial_value]
* @return Promise<any>
*/
reduce(reducer, initial_value) {
return __awaiter(this, void 0, void 0, function* () {
let current_value = initial_value;
let index = 0;
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
for (const item of items.all()) {
current_value = reducer(current_value, item, index);
index += 1;
}
}));
return current_value;
});
}
/**
* Returns a collection of items that fail the truth test.
* @param {AsyncKeyFunction} truth_test
* @return Promise<Collection>
*/
reject(truth_test) {
return __awaiter(this, void 0, void 0, function* () {
let rejected = [];
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
rejected = rejected.concat(items.all().filter((item, index) => {
return !truth_test(item, index);
}));
}));
return new Collection_1.Collection(rejected);
});
}
/**
* Get a reversed collection of this collection's items.
* @return Promise<Collection>
*/
reverse() {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).reverse();
});
}
/**
* Search the collection and return the index of that item, if one exists.
* @param {CollectionItem} item
* @return Promise<MaybeCollectionIndex>
*/
search(item) {
return __awaiter(this, void 0, void 0, function* () {
let found_index;
let index = 0;
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
items.some(possible_item => {
if (possible_item === item) {
found_index = index;
throw new Iterable_1.StopIteration();
}
index += 1;
return false;
});
}));
return found_index;
});
}
/**
* Get the next item in the collection and remove it.
* @return Promise<MaybeCollectionItem>
*/
shift() {
return __awaiter(this, void 0, void 0, function* () {
const next_item = yield this._items.next();
if (!next_item.done) {
return next_item.value;
}
});
}
/**
* Shuffle the items in the collection to a random order.
* @return Promise<Collection>
*/
shuffle() {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).shuffle();
});
}
/**
* Return a slice of this collection.
* @param {number} start - the starting index
* @param {number} end - the ending index
* @return Promise<Collection>
*/
slice(start, end) {
return __awaiter(this, void 0, void 0, function* () {
return this._items.from_range(start, end - 1);
});
}
/**
* Sort the collection, optionally with the given comparison function.
* @param {ComparisonFunction} compare_func
* @return Promise<Collection>
*/
sort(compare_func) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).sort(compare_func);
});
}
/**
* Sort the collection by the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
sortBy(key) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).sortBy(key);
});
}
/**
* Reverse sort the collection, optionally with the given comparison function.
* @param {ComparisonFunction} compare_func
* @return Promise<Collection>
*/
sortDesc(compare_func) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).sortDesc(compare_func);
});
}
/**
* Reverse sort the collection by the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
sortByDesc(key) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).sortByDesc(key);
});
}
/**
* Splice the collection at the given index. Optionally, removing the given number of items.
* @param {CollectionIndex} start
* @param {number} [deleteCount]
* @return Promise<Collection>
*/
splice(start, deleteCount) {
return __awaiter(this, void 0, void 0, function* () {
return (yield this.collect()).splice(start, deleteCount);
});
}
/**
* Sum the items in the collection, or the values of the given key.
* @param {KeyOperator} key
* @return Promise<number>
*/
sum(key) {
return __awaiter(this, void 0, void 0, function* () {
let running_sum = 0;
const chunk_handler = (items) => {
for (const item of items) {
running_sum += item;
}
};
if (key)
yield this._chunk_all_numbers(key, chunk_handler);
else
yield this._chunk((chunk) => __awaiter(this, void 0, void 0, function* () {
chunk_handler(chunk.map(x => Number(x)).all());
}));
return running_sum;
});
}
/**
* Take the first n items from the front or back of the collection.
* @param {number} limit
* @return Promise<Collection>
*/
take(limit) {
return __awaiter(this, void 0, void 0, function* () {
if (limit === 0)
return new Collection_1.Collection();
else if (limit > 0) {
return this.slice(0, limit);
}
else {
const cnt = yield this._items.count();
return this._items.from_range(cnt - (-1 * limit), cnt - 1);
}
});
}
/**
* Call the given function, passing in this collection. Allows functional syntax.
* @param {AsyncCollectionFunction} func
* @return Promise<AsyncCollection>
*/
tap(func) {
return __awaiter(this, void 0, void 0, function* () {
yield func(this);
return this;
});
}
/**
* Return all the unique values in the collection, or the unique values of the given key.
* @param {KeyOperator} key
* @return Promise<Collection>
*/
unique(key) {
return __awaiter(this, void 0, void 0, function* () {
const has = [];
if (!key) {
yield this._chunk((items) => __awaiter(this, void 0, void 0, function* () {
for (const item of items.all()) {
if (!has.includes(item))
has.push(item);
}
}));
}
else {
yield this._chunk_all(key, (items) => __awaiter(this, void 0, void 0, function* () {
for (const item of items.all()) {
if (!has.includes(item))
has.push(item);
}
}));
}
return new Collection_1.Collection(has);
});
}
/**
* Cast this collection to an array.
* @return Promise<array>
*/
toArray() {
return __awaiter(this, void 0, void 0, function* () {
const returns = [];
for (const item of (yield this.all())) {
if (item instanceof Collection_1.Collection)
returns.push(item.toArray());
else if (item instanceof AsyncCollection)
returns.push(yield item.toArray());
else
returns.push(item);
}
return returns;
});
}
/**
* Cast this collection to a JSON string.
* @param [replacer] - the replacer to use
* @param {number} [space = 4] number of indentation spaces to use
*/
toJSON(replacer = undefined, space = 4) {
return __awaiter(this, void 0, void 0, function* () {
return JSON.stringify(this.toArray(), replacer, space);
});
}
/**
* Get a clone of the underlying iterator of this collection.
* @return Iterable
*/
iterator() {
return this._items.clone();
}
}
exports.AsyncCollection = AsyncCollection;
declare type CollectionItem<T> = T;
declare type MaybeCollectionItem<T> = CollectionItem<T> | undefined;
declare type KeyFunction<T, T2> = (item: CollectionItem<T>, index: number) => CollectionItem<T2>;
declare type KeyReducerFunction<T, T2> = (current: any, item: CollectionItem<T>, index: number) => T2;
declare type CollectionFunction<T, T2> = (items: Collection<T>) => T2;
declare type KeyOperator<T, T2> = string | KeyFunction<T, T2>;
declare type AssociatedCollectionItem<T2, T> = {
key: T2;
item: CollectionItem<T>;
};
declare type CollectionComparable<T> = CollectionItem<T>[] | Collection<T>;
declare type DeterminesEquality<T> = (item: CollectionItem<T>, other: any) => boolean;
declare type CollectionIndex = number;
declare type MaybeCollectionIndex = CollectionIndex | undefined;
declare type ComparisonFunction<T> = (item: CollectionItem<T>, other_item: CollectionItem<T>) => number;
import { WhereOperator } from "./where";
declare const collect: <T>(items: T[]) => Collection<T>;
export { collect, Collection, CollectionItem, MaybeCollectionItem, KeyFunction, KeyReducerFunction, CollectionFunction, KeyOperator, AssociatedCollectionItem, CollectionComparable, DeterminesEquality, CollectionIndex, MaybeCollectionIndex, ComparisonFunction, };
declare class Collection<T> {
private _items;
static collect<T>(items: CollectionItem<T>[]): Collection<T>;
static size(size: number): Collection<undefined>;
static fill<T>(size: number, item: T): Collection<T>;
constructor(items?: CollectionItem<T>[]);
private _all;
private _all_numbers;
private _all_associate;
all(): CollectionItem<T>[];
average<T2>(key?: KeyOperator<T, T2>): number;
median<T2>(key?: KeyOperator<T, T2>): number;
mode<T2>(key?: KeyOperator<T, T2>): number;
collapse(): Collection<any>;
contains<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): boolean;
clone(): Collection<T>;
diff<T2>(items: CollectionComparable<T | T2>): Collection<T>;
diffUsing<T2>(items: CollectionComparable<T | T2>, compare: DeterminesEquality<T>): Collection<T>;
some(func: (item: T) => boolean): boolean;
each<T2>(func: KeyFunction<T, T2>): void;
map<T2>(func: KeyFunction<T, T2>): Collection<T2>;
every<T2>(func: KeyFunction<T, T2>): boolean;
everyWhere<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): boolean;
filter<T2>(func: KeyFunction<T, T2>): Collection<T>;
find<T2>(func: KeyFunction<T, T2>): number | undefined;
when<T2>(bool: boolean, then: CollectionFunction<T, T2>): Collection<T>;
unless<T2>(bool: boolean, then: CollectionFunction<T, T2>): Collection<T>;
where<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Collection<T>;
whereNot<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): Collection<T>;
whereIn<T2>(key: KeyOperator<T, T2>, items: CollectionComparable<T2>): Collection<T>;
whereNotIn<T2>(key: KeyOperator<T, T2>, items: CollectionComparable<T2>): Collection<T>;
first(): MaybeCollectionItem<T>;
firstWhere<T2>(key: KeyOperator<T, T2>, operator?: WhereOperator, operand?: any): MaybeCollectionItem<T>;
firstWhereNot<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): MaybeCollectionItem<T>;
get length(): number;
count(): number;
get(index: number, fallback?: any): any;
at(index: number): MaybeCollectionItem<T>;
groupBy<T2>(key: KeyOperator<T, T2>): any;
associate<T2>(key: KeyOperator<T, T2>): any;
join(delimiter: string): string;
implode(delimiter: string): string;
intersect(items: CollectionComparable<T>, key?: KeyOperator<T, T>): Collection<T>;
isEmpty(): boolean;
isNotEmpty(): boolean;
last(): MaybeCollectionItem<T>;
lastWhere<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): MaybeCollectionItem<T>;
lastWhereNot<T2>(key: KeyOperator<T, T2>, operator: WhereOperator, operand?: any): MaybeCollectionItem<T>;
pluck<T2>(key: KeyOperator<T, T2>): Collection<T2>;
max<T2>(key: KeyOperator<T, T2>): number;
whereMax<T2>(key: KeyOperator<T, T2>): Collection<T>;
min<T2>(key: KeyOperator<T, T2>): number;
whereMin<T2>(key: KeyOperator<T, T2>): Collection<T>;
merge<T2>(items: CollectionComparable<T2>): Collection<T | T2>;
nth(n: number): Collection<T>;
forPage(page: number, perPage: number): Collection<T>;
pipe<T2>(func: CollectionFunction<T, T2>): any;
pop(): MaybeCollectionItem<T>;
prepend(item: CollectionItem<T>): Collection<T>;
push(item: CollectionItem<T>): Collection<T>;
concat(items: CollectionComparable<T>): Collection<T>;
put(index: number, item: CollectionItem<T>): Collection<T>;
random(n: number): Collection<T>;
reduce<T2>(reducer: KeyReducerFunction<T, T2>, initial_value?: T2): T2 | undefined;
reject<T2>(truth_test: KeyFunction<T, T2>): Collection<T>;
reverse(): Collection<T>;
search(item: CollectionItem<T>): MaybeCollectionIndex;
shift(): MaybeCollectionItem<T>;
shuffle(): Collection<T>;
slice(start: number, end: number): Collection<T>;
sort(compare_func?: ComparisonFunction<T>): Collection<T>;
sortBy<T2>(key?: KeyOperator<T, T2>): Collection<T>;
sortDesc(compare_func?: ComparisonFunction<T>): Collection<T>;
sortByDesc<T2>(key?: KeyOperator<T, T2>): Collection<T>;
splice(start: CollectionIndex, deleteCount?: number): Collection<T>;
sum<T2>(key?: KeyOperator<T, T2>): number;
take(limit: number): Collection<T>;
tap<T2>(func: CollectionFunction<T, T2>): Collection<T>;
unique<T2>(key?: KeyOperator<T, T2>): Collection<T | T2>;
includes(item: CollectionItem<T>): boolean;
pad(length: number, value: CollectionItem<T>): Collection<T>;
toArray(): any[];
toJSON(replacer?: undefined, space?: number): string;
[Symbol.iterator](): {
current_index: number;
next(): {
done: boolean;
value?: undefined;
} | {
done: boolean;
value: T;
};
};
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Collection = exports.collect = void 0;
const where_1 = require("./where");
const collect = (items) => Collection.collect(items);
exports.collect = collect;
class Collection {
constructor(items) {
this._items = [];
if (items)
this._items = items;
}
static collect(items) {
return new Collection(items);
}
static size(size) {
const arr = Array(size).fill(undefined);
return new Collection(arr);
}
static fill(size, item) {
const arr = Array(size).fill(item);
return new Collection(arr);
}
_all(key) {
let items = [];
if (typeof key === 'function') {
items = this._items.map(key);
}
else {
items = this._items.map((item) => item[key]);
}
return items;
}
_all_numbers(key) {
return this._all(key).map(value => Number(value));
}
_all_associate(key) {
const assoc_items = [];
let items = [...this._items];
if (typeof key === 'function') {
items.map((item, index) => {
const key_item = key(item, index);
assoc_items.push({ key: key_item, item });
});
}
else {
items.map((item, index) => {
assoc_items.push({ key: item[key], item });
});
}
return assoc_items;
}
all() {
return [...this._items];
}
average(key) {
let items;
if (key)
items = this._all_numbers(key);
else
items = this._items.map(x => Number(x));
if (items.length === 0)
return 0;
let sum = items.reduce((prev, curr) => prev + curr);
return sum / items.length;
}
median(key) {
let items;
if (key)
items = this._all_numbers(key).sort((a, b) => a - b);
else
items = this._items.map(x => Number(x)).sort((a, b) => a - b);
const middle = Math.floor((items.length - 1) / 2);
if (items.length % 2)
return items[middle];
else
return (items[middle] + items[middle + 1]) / 2;
}
mode(key) {
var _a;
let items;
if (key)
items = this._all_numbers(key).sort((a, b) => a - b);
else
items = this._items.map(x => Number(x)).sort((a, b) => a - b);
let counts = {};
for (const item of items) {
counts[item] = ((_a = counts[item]) !== null && _a !== void 0 ? _a : -1) + 1;
}
return Number(Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b)[0]);
}
collapse() {
const new_items = [];
const items = [...this._items];
const get_layer = (current) => {
if (typeof current[Symbol.iterator] === 'function') {
// @ts-ignore
// TODO fix this
for (const item of current) {
if (Array.isArray(item)) {
get_layer(item);
}
else {
new_items.push(item);
}
}
}
};
get_layer(items);
return new Collection(new_items);
}
contains(key, operator, operand) {
const associate = this._all_associate(key);
const matches = where_1.applyWhere(associate, operator, operand);
return matches.length > 0;
}
// TODO crossJoin
clone() {
return new Collection(this._items);
}
diff(items) {
const exclude = items instanceof Collection ? items.all() : items;
const matches = [];
for (const item of [...this._items]) {
if (!exclude.includes(item))
matches.push(item);
}
return new Collection(matches);
}
diffUsing(items, compare) {
const exclude = items instanceof Collection ? items.all() : items;
const matches = [];
for (const item of [...this._items]) {
if (!exclude.some(exc => compare(item, exc)))
matches.push(item);
}
return new Collection(matches);
}
some(func) {
return this._items.some(func);
}
each(func) {
this._items.map(func);
}
map(func) {
const new_items = [];
this.each(((item, index) => {
new_items.push(func(item, index));
}));
return new Collection(new_items);
}
every(func) {
return this._items.every(func);
}
everyWhere(key, operator, operand) {
const items = this._all_associate(key);
return items.every(item => where_1.whereMatch(item, operator, operand));
}
filter(func) {
return new Collection(this._items.filter(func));
}
find(func) {
let found_index = undefined;
this._items.some((item, index) => {
if (func(item, index)) {
found_index = index;
return true;
}
});
return found_index;
}
when(bool, then) {
if (bool)
then(this);
return this;
}
unless(bool, then) {
if (!bool)
then(this);
return this;
}
where(key, operator, operand) {
const items = this._all_associate(key);
return new Collection(where_1.applyWhere(items, operator, operand));
}
whereNot(key, operator, operand) {
return this.diff(this.where(key, operator, operand));
}
whereIn(key, items) {
const allowed = items instanceof Collection ? items.all() : items;
const matches = [];
for (const { key: search, item } of this._all_associate(key)) {
if (allowed.includes(search))
matches.push(item);
}
return new Collection(matches);
}
whereNotIn(key, items) {
return this.diff(this.whereIn(key, items));
}
first() {
if (this.length > 0)
return this._items[0];
}
firstWhere(key, operator = '=', operand = true) {
const items = this.where(key, operator, operand).all();
if (items.length > 0)
return items[0];
}
firstWhereNot(key, operator, operand) {
const items = this.whereNot(key, operator, operand).all();
if (items.length > 0)
return items[0];
}
get length() {
return this._items.length;
}
count() {
return this._items.length;
}
// TODO flatten - depth
get(index, fallback) {
if (this.length > index)
return this._items[index];
else
return fallback;
}
at(index) {
return this.get(index);
}
groupBy(key) {
const items = this._all_associate(key);
const groups = {};
for (const item of items) {
const key = String(item.key);
if (!groups[key])
groups[key] = [];
groups[key].push(item.item);
}
return groups;
}
associate(key) {
const items = this._all_associate(key);
const values = {};
for (const item of items) {
values[String(item.key)] = item.item;
}
return values;
}
join(delimiter) {
return this._items.join(delimiter);
}
implode(delimiter) {
return this.join(delimiter);
}
intersect(items, key) {
const compare = items instanceof Collection ? items.all() : items;
const intersect = [];
let all_items;
if (key)
all_items = this._all_associate(key);
else
all_items = this._items.map(item => {
return { key: item, item };
});
for (const item of all_items) {
if (compare.includes(item.key))
intersect.push(item.item);
}
return new Collection(intersect);
}
isEmpty() {
return this.length < 1;
}
isNotEmpty() {
return this.length > 0;
}
last() {
if (this.length > 0)
return this._items.reverse()[0];
}
lastWhere(key, operator, operand) {
const items = this.where(key, operator, operand).all();
if (items.length > 0)
return items.reverse()[0];
}
lastWhereNot(key, operator, operand) {
const items = this.whereNot(key, operator, operand).all();
if (items.length > 0)
return items.reverse()[0];
}
pluck(key) {
return new Collection(this._all(key));
}
max(key) {
const values = this._all_numbers(key);
return Math.max(...values);
}
whereMax(key) {
return this.where(key, '=', this.max(key));
}
min(key) {
const values = this._all_numbers(key);
return Math.min(...values);
}
whereMin(key) {
return this.where(key, '=', this.min(key));
}
merge(items) {
const merge = items instanceof Collection ? items.all() : items;
return new Collection([...this._items, ...merge]);
}
nth(n) {
const matches = [];
let current = 1;
this._items.forEach((item, index) => {
if (current === 1)
matches.push(item);
current += 1;
if (current > n)
current = 1;
});
return new Collection(matches);
}
forPage(page, perPage) {
const start = page * perPage - perPage;
const end = page * perPage;
return new Collection(this._items.slice(start, end));
}
pipe(func) {
return func(this);
}
pop() {
if (this.length > 0) {
return this._items.pop();
}
}
prepend(item) {
this._items = [item, ...this._items];
return this;
}
push(item) {
this._items.push(item);
return this;
}
concat(items) {
const concats = items instanceof Collection ? items.all() : items;
for (const item of concats) {
this._items.push(item);
}
return this;
}
put(index, item) {
const new_items = [];
let inserted = false;
this._items.forEach((existing, existing_index) => {
if (existing_index === index) {
new_items.push(item);
inserted = true;
}
new_items.push(existing);
});
if (!inserted)
new_items.push(item);
return new Collection(new_items);
}
random(n) {
const random_items = [];
const all = this._items;
if (n > this.length)
n = this.length;
while (random_items.length < n) {
const item = all[Math.floor(Math.random() * all.length)];
if (!random_items.includes(item))
random_items.push(item);
}
return new Collection(random_items);
}
reduce(reducer, initial_value) {
let current_value = initial_value;
this._items.forEach((item, index) => {
current_value = reducer(current_value, item, index);
});
return current_value;
}
reject(truth_test) {
const rejected = this._items.filter((item, index) => {
return !truth_test(item, index);
});
return new Collection(rejected);
}
reverse() {
return new Collection([...this._items.reverse()]);
}
search(item) {
let found_index;
this._items.some((possible_item, index) => {
if (possible_item === item) {
found_index = index;
return true;
}
});
return found_index;
}
shift() {
if (this.length > 0) {
return this._items.shift();
}
}
shuffle() {
const items = [...this._items];
for (let i = items.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[items[i], items[j]] = [items[j], items[i]];
}
return new Collection(items);
}
slice(start, end) {
return new Collection(this._items.slice(start, end));
}
// TODO split
// TODO chunk
sort(compare_func) {
const items = this._items;
if (compare_func)
items.sort(compare_func);
else
items.sort();
return new Collection(items);
}
sortBy(key) {
let items;
if (key)
items = this._all_associate(key);
else
items = this._items.map(item => {
return { key: item, item };
});
items.sort((a, b) => {
if (a.key > b.key)
return 1;
else if (a.key < b.key)
return -1;
else
return 0;
});
return new Collection(items.map((item) => item.item));
}
sortDesc(compare_func) {
return this.sort(compare_func).reverse();
}
sortByDesc(key) {
return this.sortBy(key).reverse();
}
splice(start, deleteCount) {
return new Collection([...this._items].splice(start, deleteCount));
}
sum(key) {
let items;
if (key)
items = this._all_numbers(key);
else
items = this._items.map(x => Number(x));
return items.reduce((prev, curr) => prev + curr);
}
take(limit) {
if (limit === 0)
return new Collection();
else if (limit > 0) {
return new Collection(this._items.slice(0, limit));
}
else {
return new Collection(this._items.reverse().slice(0, -1 * limit).reverse());
}
}
tap(func) {
func(this);
return this;
}
unique(key) {
const has = [];
let items;
if (key)
items = this._all(key);
else
items = [...this._items];
for (const item of items) {
if (!has.includes(item))
has.push(item);
}
return new Collection(has);
}
includes(item) {
return this._items.includes(item);
}
pad(length, value) {
const items = [...this._items];
while (items.length < length)
items.push(value);
return new Collection(items);
}
toArray() {
const returns = [];
for (const item of this._items) {
if (item instanceof Collection)
returns.push(item.toArray());
else
returns.push(item);
}
return returns;
}
toJSON(replacer = undefined, space = 4) {
return JSON.stringify(this.toArray(), replacer, space);
}
// TODO getIterator
// TODO getCachingIterator
[Symbol.iterator]() {
const items = this._items;
return {
current_index: 0,
next() {
if (items.length < 1 || this.current_index + 1 > items.length) {
return { done: true };
}
const item = items[this.current_index];
this.current_index += 1;
return { done: false, value: item };
},
};
}
}
exports.Collection = Collection;
import { Collection } from './Collection';
export declare type MaybeIterationItem<T> = {
done: boolean;
value?: T;
};
export declare type ChunkCallback<T> = (items: Collection<T>) => any;
export declare class StopIteration extends Error {
}
/**
* Abstract class representing an iterable, lazy-loaded dataset.
* @abstract
*/
export declare abstract class Iterable<T> {
/**
* The current index of the iterable.
* @type number
*/
protected index: number;
/**
* Get the item of this iterable at the given index, if one exists.
* @param {number} i
* @return Promise<any|undefined>
*/
abstract at_index(i: number): Promise<T | undefined>;
/**
* Get the collection of items in the given range of this iterable.
* @param {number} start
* @param {number} end
* @return Promise<Collection>
*/
abstract from_range(start: number, end: number): Promise<Collection<T>>;
/**
* Count the number of items in this collection.
* @return Promise<number>
*/
abstract count(): Promise<number>;
/**
* Get a copy of this iterable.
* @return Iterable
*/
abstract clone(): Iterable<T>;
/**
* Advance to the next value of this iterable.
* @return Promise<MaybeIterationItem>
*/
next(): Promise<MaybeIterationItem<T>>;
/**
* Chunk the iterable into the given size and call the callback passing the chunk along.
* @param {number} size
* @param {ChunkCallback} callback
* @return Promise<void>
*/
chunk(size: number, callback: ChunkCallback<T>): Promise<void>;
/**
* Advance the iterable to the given index.
* @param {number} index
* @return Promise<void>
*/
seek(index: number): Promise<void>;
/**
* Peek at the next value of the iterable, without advancing.
* @return Promise<any|undefined>
*/
peek(): Promise<T | undefined>;
/**
* Reset the iterable to the first index.
* @return Promise<any>
*/
reset(): Promise<void>;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Iterable = exports.StopIteration = void 0;
class StopIteration extends Error {
}
exports.StopIteration = StopIteration;
/**
* Abstract class representing an iterable, lazy-loaded dataset.
* @abstract
*/
class Iterable {
constructor() {
/**
* The current index of the iterable.
* @type number
*/
this.index = 0;
}
/**
* Advance to the next value of this iterable.
* @return Promise<MaybeIterationItem>
*/
next() {
return __awaiter(this, void 0, void 0, function* () {
const i = this.index;
if (i >= (yield this.count())) {
return { done: true };
}
this.index = i + 1;
return { done: false, value: yield this.at_index(i) };
});
}
/**
* Chunk the iterable into the given size and call the callback passing the chunk along.
* @param {number} size
* @param {ChunkCallback} callback
* @return Promise<void>
*/
chunk(size, callback) {
return __awaiter(this, void 0, void 0, function* () {
const total = yield this.count();
while (this.index < total) {
const items = yield this.from_range(this.index, this.index + size - 1);
try {
yield callback(items);
}
catch (error) {
if (error instanceof StopIteration)
break;
else
throw error;
}
this.index += size;
}
});
}
/**
* Advance the iterable to the given index.
* @param {number} index
* @return Promise<void>
*/
seek(index) {
return __awaiter(this, void 0, void 0, function* () {
if (index < 0)
throw new TypeError('Cannot seek to negative index.');
else if (index >= (yield this.count()))
throw new TypeError('Cannot seek past last item.');
this.index = index;
});
}
/**
* Peek at the next value of the iterable, without advancing.
* @return Promise<any|undefined>
*/
peek() {
return __awaiter(this, void 0, void 0, function* () {
if (this.index + 1 >= (yield this.count()))
return undefined;
else
return this.at_index(this.index + 1);
});
}
/**
* Reset the iterable to the first index.
* @return Promise<any>
*/
reset() {
return __awaiter(this, void 0, void 0, function* () {
this.index = 0;
});
}
}
exports.Iterable = Iterable;
/**
* Type representing a valid where operator.
*/
declare type WhereOperator = '&' | '>' | '>=' | '<' | '<=' | '!=' | '<=>' | '%' | '|' | '!' | '~' | '=' | '^';
/**
* Type associating search items with a key.
*/
declare type AssociatedSearchItem = {
key: any;
item: any;
};
/**
* Type representing the result of a where.
*/
declare type WhereResult = any[];
/**
* Returns true if the given item satisfies the given where clause.
* @param {AssociatedSearchItem} item
* @param {WhereOperator} operator
* @param [operand]
* @return boolean
*/
declare const whereMatch: (item: AssociatedSearchItem, operator: WhereOperator, operand?: any) => boolean;
/**
* Apply the given where clause to the items and return those that match.
* @param {Array<AssociatedSearchItem>} items
* @param {WhereOperator} operator
* @param [operand]
*/
declare const applyWhere: (items: AssociatedSearchItem[], operator: WhereOperator, operand?: any) => WhereResult;
export { WhereOperator, WhereResult, AssociatedSearchItem, applyWhere, whereMatch };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.whereMatch = exports.applyWhere = void 0;
/**
* Returns true if the given item satisfies the given where clause.
* @param {AssociatedSearchItem} item
* @param {WhereOperator} operator
* @param [operand]
* @return boolean
*/
const whereMatch = (item, operator, operand) => {
switch (operator) {
case '&':
if (item.key & operand)
return true;
break;
case '>':
if (item.key > operand)
return true;
break;
case '>=':
if (item.key >= operand)
return true;
break;
case '<':
if (item.key < operand)
return true;
break;
case '<=':
if (item.key <= operand)
return true;
break;
case '!=':
if (item.key !== operand)
return true;
break;
case '<=>':
if (item.key === operand && typeof item.key !== 'undefined' && item.key !== null)
return true;
break;
case '%':
if (item.key % operand)
return true;
break;
case '|':
if (item.key | operand)
return true;
break;
case '!':
if (!item.key)
return true;
break;
case '~':
if (~item.key)
return true;
break;
case '=':
if (item.key === operand)
return true;
break;
case '^':
if (item.key ^ operand)
return true;
break;
}
return false;
};
exports.whereMatch = whereMatch;
/**
* Apply the given where clause to the items and return those that match.
* @param {Array<AssociatedSearchItem>} items
* @param {WhereOperator} operator
* @param [operand]
*/
const applyWhere = (items, operator, operand) => {
const matches = [];
for (const item of items) {
if (whereMatch(item, operator, operand))
matches.push(item.item);
}
return matches;
};
exports.applyWhere = applyWhere;
/**
* Enum of HTTP statuses.
* @example
* HTTPStatus.http200 // => 200
*
* @example
* HTTPStatus.REQUEST_TIMEOUT // => 408
*/
export declare enum HTTPStatus {
http100 = 100,
http101 = 101,
http102 = 102,
http200 = 200,
http201 = 201,
http202 = 202,
http203 = 203,
http204 = 204,
http205 = 205,
http206 = 206,
http207 = 207,
http300 = 300,
http301 = 301,
http302 = 302,
http303 = 303,
http304 = 304,
http305 = 305,
http307 = 307,
http308 = 308,
http400 = 400,
http401 = 401,
http402 = 402,
http403 = 403,
http404 = 404,
http405 = 405,
http406 = 406,
http407 = 407,
http408 = 408,
http409 = 409,
http410 = 410,
http411 = 411,
http412 = 412,
http413 = 413,
http414 = 414,
http415 = 415,
http416 = 416,
http417 = 417,
http418 = 418,
http419 = 419,
http420 = 420,
http422 = 422,
http423 = 423,
http424 = 424,
http428 = 428,
http429 = 429,
http431 = 431,
http500 = 500,
http501 = 501,
http502 = 502,
http503 = 503,
http504 = 504,
http505 = 505,
http507 = 507,
http511 = 511,
CONTINUE = 100,
SWITCHING_PROTOCOLS = 101,
PROCESSING = 102,
OK = 200,
CREATED = 201,
ACCEPTED = 202,
NON_AUTHORITATIVE_INFORMATION = 203,
NO_CONTENT = 204,
RESET_CONTENT = 205,
PARTIAL_CONTENT = 206,
MULTI_STATUS = 207,
MULTIPLE_CHOICES = 300,
MOVED_PERMANENTLY = 301,
MOVED_TEMPORARILY = 302,
SEE_OTHER = 303,
NOT_MODIFIED = 304,
USE_PROXY = 305,
TEMPORARY_REDIRECT = 307,
PERMANENT_REDIRECT = 308,
BAD_REQUEST = 400,
UNAUTHORIZED = 401,
PAYMENT_REQUIRED = 402,
FORBIDDEN = 403,
NOT_FOUND = 404,
METHOD_NOT_ALLOWED = 405,
NOT_ACCEPTABLE = 406,
PROXY_AUTHENTICATION_REQUIRED = 407,
REQUEST_TIMEOUT = 408,
CONFLICT = 409,
GONE = 410,
LENGTH_REQUIRED = 411,
PRECONDITION_FAILED = 412,
REQUEST_TOO_LONG = 413,
REQUEST_URI_TOO_LONG = 414,
UNSUPPORTED_MEDIA_TYPE = 415,
REQUESTED_RANGE_NOT_SATISFIABLE = 416,
EXPECTATION_FAILED = 417,
IM_A_TEAPOT = 418,
INSUFFICIENT_SPACE_ON_RESOURCE = 419,
METHOD_FAILURE = 420,
UNPROCESSABLE_ENTITY = 422,
LOCKED = 423,
FAILED_DEPENDENCY = 424,
PRECONDITION_REQUIRED = 428,
TOO_MANY_REQUESTS = 429,
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
INTERNAL_SERVER_ERROR = 500,
NOT_IMPLEMENTED = 501,
BAD_GATEWAY = 502,
SERVICE_UNAVAILABLE = 503,
GATEWAY_TIMEOUT = 504,
HTTP_VERSION_NOT_SUPPORTED = 505,
INSUFFICIENT_STORAGE = 507,
NETWORK_AUTHENTICATION_REQUIRED = 511
}
/**
* Maps HTTP status code to default status message.
*/
export declare const HTTPMessage: {
100: string;
101: string;
102: string;
200: string;
201: string;
202: string;
203: string;
204: string;
205: string;
206: string;
207: string;
300: string;
301: string;
302: string;
303: string;
304: string;
305: string;
307: string;
308: string;
400: string;
401: string;
402: string;
403: string;
404: string;
405: string;
406: string;
407: string;
408: string;
409: string;
410: string;
411: string;
412: string;
413: string;
414: string;
415: string;
416: string;
417: string;
418: string;
419: string;
420: string;
422: string;
423: string;
424: string;
428: string;
429: string;
431: string;
500: string;
501: string;
502: string;
503: string;
504: string;
505: string;
507: string;
511: string;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HTTPMessage = exports.HTTPStatus = void 0;
/**
* Enum of HTTP statuses.
* @example
* HTTPStatus.http200 // => 200
*
* @example
* HTTPStatus.REQUEST_TIMEOUT // => 408
*/
var HTTPStatus;
(function (HTTPStatus) {
HTTPStatus[HTTPStatus["http100"] = 100] = "http100";
HTTPStatus[HTTPStatus["http101"] = 101] = "http101";
HTTPStatus[HTTPStatus["http102"] = 102] = "http102";
HTTPStatus[HTTPStatus["http200"] = 200] = "http200";
HTTPStatus[HTTPStatus["http201"] = 201] = "http201";
HTTPStatus[HTTPStatus["http202"] = 202] = "http202";
HTTPStatus[HTTPStatus["http203"] = 203] = "http203";
HTTPStatus[HTTPStatus["http204"] = 204] = "http204";
HTTPStatus[HTTPStatus["http205"] = 205] = "http205";
HTTPStatus[HTTPStatus["http206"] = 206] = "http206";
HTTPStatus[HTTPStatus["http207"] = 207] = "http207";
HTTPStatus[HTTPStatus["http300"] = 300] = "http300";
HTTPStatus[HTTPStatus["http301"] = 301] = "http301";
HTTPStatus[HTTPStatus["http302"] = 302] = "http302";
HTTPStatus[HTTPStatus["http303"] = 303] = "http303";
HTTPStatus[HTTPStatus["http304"] = 304] = "http304";
HTTPStatus[HTTPStatus["http305"] = 305] = "http305";
HTTPStatus[HTTPStatus["http307"] = 307] = "http307";
HTTPStatus[HTTPStatus["http308"] = 308] = "http308";
HTTPStatus[HTTPStatus["http400"] = 400] = "http400";
HTTPStatus[HTTPStatus["http401"] = 401] = "http401";
HTTPStatus[HTTPStatus["http402"] = 402] = "http402";
HTTPStatus[HTTPStatus["http403"] = 403] = "http403";
HTTPStatus[HTTPStatus["http404"] = 404] = "http404";
HTTPStatus[HTTPStatus["http405"] = 405] = "http405";
HTTPStatus[HTTPStatus["http406"] = 406] = "http406";
HTTPStatus[HTTPStatus["http407"] = 407] = "http407";
HTTPStatus[HTTPStatus["http408"] = 408] = "http408";
HTTPStatus[HTTPStatus["http409"] = 409] = "http409";
HTTPStatus[HTTPStatus["http410"] = 410] = "http410";
HTTPStatus[HTTPStatus["http411"] = 411] = "http411";
HTTPStatus[HTTPStatus["http412"] = 412] = "http412";
HTTPStatus[HTTPStatus["http413"] = 413] = "http413";
HTTPStatus[HTTPStatus["http414"] = 414] = "http414";
HTTPStatus[HTTPStatus["http415"] = 415] = "http415";
HTTPStatus[HTTPStatus["http416"] = 416] = "http416";
HTTPStatus[HTTPStatus["http417"] = 417] = "http417";
HTTPStatus[HTTPStatus["http418"] = 418] = "http418";
HTTPStatus[HTTPStatus["http419"] = 419] = "http419";
HTTPStatus[HTTPStatus["http420"] = 420] = "http420";
HTTPStatus[HTTPStatus["http422"] = 422] = "http422";
HTTPStatus[HTTPStatus["http423"] = 423] = "http423";
HTTPStatus[HTTPStatus["http424"] = 424] = "http424";
HTTPStatus[HTTPStatus["http428"] = 428] = "http428";
HTTPStatus[HTTPStatus["http429"] = 429] = "http429";
HTTPStatus[HTTPStatus["http431"] = 431] = "http431";
HTTPStatus[HTTPStatus["http500"] = 500] = "http500";
HTTPStatus[HTTPStatus["http501"] = 501] = "http501";
HTTPStatus[HTTPStatus["http502"] = 502] = "http502";
HTTPStatus[HTTPStatus["http503"] = 503] = "http503";
HTTPStatus[HTTPStatus["http504"] = 504] = "http504";
HTTPStatus[HTTPStatus["http505"] = 505] = "http505";
HTTPStatus[HTTPStatus["http507"] = 507] = "http507";
HTTPStatus[HTTPStatus["http511"] = 511] = "http511";
HTTPStatus[HTTPStatus["CONTINUE"] = 100] = "CONTINUE";
HTTPStatus[HTTPStatus["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
HTTPStatus[HTTPStatus["PROCESSING"] = 102] = "PROCESSING";
HTTPStatus[HTTPStatus["OK"] = 200] = "OK";
HTTPStatus[HTTPStatus["CREATED"] = 201] = "CREATED";
HTTPStatus[HTTPStatus["ACCEPTED"] = 202] = "ACCEPTED";
HTTPStatus[HTTPStatus["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
HTTPStatus[HTTPStatus["NO_CONTENT"] = 204] = "NO_CONTENT";
HTTPStatus[HTTPStatus["RESET_CONTENT"] = 205] = "RESET_CONTENT";
HTTPStatus[HTTPStatus["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
HTTPStatus[HTTPStatus["MULTI_STATUS"] = 207] = "MULTI_STATUS";
HTTPStatus[HTTPStatus["MULTIPLE_CHOICES"] = 300] = "MULTIPLE_CHOICES";
HTTPStatus[HTTPStatus["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
HTTPStatus[HTTPStatus["MOVED_TEMPORARILY"] = 302] = "MOVED_TEMPORARILY";
HTTPStatus[HTTPStatus["SEE_OTHER"] = 303] = "SEE_OTHER";
HTTPStatus[HTTPStatus["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
HTTPStatus[HTTPStatus["USE_PROXY"] = 305] = "USE_PROXY";
HTTPStatus[HTTPStatus["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
HTTPStatus[HTTPStatus["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
HTTPStatus[HTTPStatus["BAD_REQUEST"] = 400] = "BAD_REQUEST";
HTTPStatus[HTTPStatus["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
HTTPStatus[HTTPStatus["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
HTTPStatus[HTTPStatus["FORBIDDEN"] = 403] = "FORBIDDEN";
HTTPStatus[HTTPStatus["NOT_FOUND"] = 404] = "NOT_FOUND";
HTTPStatus[HTTPStatus["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
HTTPStatus[HTTPStatus["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
HTTPStatus[HTTPStatus["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
HTTPStatus[HTTPStatus["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
HTTPStatus[HTTPStatus["CONFLICT"] = 409] = "CONFLICT";
HTTPStatus[HTTPStatus["GONE"] = 410] = "GONE";
HTTPStatus[HTTPStatus["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
HTTPStatus[HTTPStatus["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
HTTPStatus[HTTPStatus["REQUEST_TOO_LONG"] = 413] = "REQUEST_TOO_LONG";
HTTPStatus[HTTPStatus["REQUEST_URI_TOO_LONG"] = 414] = "REQUEST_URI_TOO_LONG";
HTTPStatus[HTTPStatus["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
HTTPStatus[HTTPStatus["REQUESTED_RANGE_NOT_SATISFIABLE"] = 416] = "REQUESTED_RANGE_NOT_SATISFIABLE";
HTTPStatus[HTTPStatus["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
HTTPStatus[HTTPStatus["IM_A_TEAPOT"] = 418] = "IM_A_TEAPOT";
HTTPStatus[HTTPStatus["INSUFFICIENT_SPACE_ON_RESOURCE"] = 419] = "INSUFFICIENT_SPACE_ON_RESOURCE";
HTTPStatus[HTTPStatus["METHOD_FAILURE"] = 420] = "METHOD_FAILURE";
HTTPStatus[HTTPStatus["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
HTTPStatus[HTTPStatus["LOCKED"] = 423] = "LOCKED";
HTTPStatus[HTTPStatus["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
HTTPStatus[HTTPStatus["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
HTTPStatus[HTTPStatus["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
HTTPStatus[HTTPStatus["REQUEST_HEADER_FIELDS_TOO_LARGE"] = 431] = "REQUEST_HEADER_FIELDS_TOO_LARGE";
HTTPStatus[HTTPStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
HTTPStatus[HTTPStatus["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
HTTPStatus[HTTPStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
HTTPStatus[HTTPStatus["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
HTTPStatus[HTTPStatus["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
HTTPStatus[HTTPStatus["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
HTTPStatus[HTTPStatus["INSUFFICIENT_STORAGE"] = 507] = "INSUFFICIENT_STORAGE";
HTTPStatus[HTTPStatus["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
})(HTTPStatus = exports.HTTPStatus || (exports.HTTPStatus = {}));
/**
* Maps HTTP status code to default status message.
*/
exports.HTTPMessage = {
100: 'Continue',
101: 'Switching Protocols',
102: 'Processing',
200: 'OK',
201: 'Created',
202: 'Accepted',
203: 'Non Authoritative Information',
204: 'No Content',
205: 'Reset Content',
206: 'Partial Content',
207: 'Multi-Status',
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Moved Temporarily',
303: 'See Other',
304: 'Not Modified',
305: 'Use Proxy',
307: 'Temporary Redirect',
308: 'Permanent Redirect',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
403: 'Forbidden',
404: 'Not Found',
405: 'Method Not Allowed',
406: 'Not Acceptable',
407: 'Proxy Authentication Required',
408: 'Request Timeout',
409: 'Conflict',
410: 'Gone',
411: 'Length Required',
412: 'Precondition Failed',
413: 'Request Entity Too Large',
414: 'Request-URI Too Long',
415: 'Unsupported Media Type',
416: 'Request Range Not Satisfiable',
417: 'Expectation Failed',
418: 'I\'m a teapot',
419: 'Insufficient Space on Resource',
420: 'Method Failure',
422: 'Unprocessable Entity',
423: 'Locked',
424: 'Failed Dependency',
428: 'Precondition Required',
429: 'Too Many Requests',
431: 'Request Header Fields Too Large',
500: 'Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
507: 'Insufficient Storage',
511: 'Network Authentication Required',
};
export declare class ErrorWithContext extends Error {
readonly context: string[];
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorWithContext = void 0;
class ErrorWithContext extends Error {
constructor() {
super(...arguments);
this.context = [];
}
}
exports.ErrorWithContext = ErrorWithContext;
export declare class RunLevelErrorHandler {
/**
* Get the error handler function.
* @type (e: Error) => void
*/
get handle(): (e: Error) => void;
/**
* Log the error to the logger.
* @param {Error} e
*/
display(e: Error): void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RunLevelErrorHandler = void 0;
const color = require("colors/safe");
class RunLevelErrorHandler {
/**
* Get the error handler function.
* @type (e: Error) => void
*/
get handle() {
return (e) => {
this.display(e);
process.exit(1);
};
}
/**
* Log the error to the logger.
* @param {Error} e
*/
display(e) {
try {
const error_string = `RunLevelErrorHandler invoked:
${color.bgRed(' ')}
${color.bgRed(' UNCAUGHT TOP-LEVEL ERROR ')}
${color.bgRed(' ')}
${e.constructor ? e.constructor.name : e.name}
${color.red(`---------------------------------------------------`)}
${e.stack}
`;
// this.logger.error(error_string, true)
console.error(error_string); // FIXME: handle with injected logging service
}
catch (display_e) {
// The error display encountered an error...
// just throw the original so it makes it out
console.error('RunLevelErrorHandler encountered an error:', display_e.message);
throw e;
}
}
}
exports.RunLevelErrorHandler = RunLevelErrorHandler;
import { LoggingLevel, LogMessage } from './types';
/**
* Base class for an application logger.
*/
export declare abstract class Logger {
/**
* Write the given message to the log destination.
* @param {LogMessage} message
* @return Promise<void>
*/
abstract write(message: LogMessage): Promise<void> | void;
/**
* Format the date object to the string output format.
* @param {Date} date
* @return string
*/
protected formatDate(date: Date): string;
/**
* Given a logging level, get the display string of that level.
* @param {LoggingLevel} level
* @return string
*/
protected levelDisplay(level: LoggingLevel): string;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
const types_1 = require("./types");
const color = require("colors/safe");
/**
* Base class for an application logger.
*/
class Logger {
/**
* Format the date object to the string output format.
* @param {Date} date
* @return string
*/
formatDate(date) {
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${hours > 9 ? hours : '0' + hours}:${minutes > 9 ? minutes : '0' + minutes}:${seconds > 9 ? seconds : '0' + seconds}`;
}
/**
* Given a logging level, get the display string of that level.
* @param {LoggingLevel} level
* @return string
*/
levelDisplay(level) {
switch (level) {
case types_1.LoggingLevel.Success:
return color.green('success');
case types_1.LoggingLevel.Error:
return color.red(' error');
case types_1.LoggingLevel.Warning:
return color.yellow('warning');
case types_1.LoggingLevel.Info:
return color.blue(' info');
case types_1.LoggingLevel.Debug:
return color.cyan(' debug');
case types_1.LoggingLevel.Verbose:
return color.gray('verbose');
case types_1.LoggingLevel.Silent:
return color.gray(' silent');
}
}
}
exports.Logger = Logger;
import { Logger } from "./Logger";
import { LogMessage } from "./types";
export declare class StandardLogger extends Logger {
write(message: LogMessage): void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StandardLogger = void 0;
const Logger_1 = require("./Logger");
const color = require("colors/safe");
class StandardLogger extends Logger_1.Logger {
write(message) {
const prefix = this.levelDisplay(message.level);
const text = `${prefix} ${color.gray(this.formatDate(message.date))} (${color.cyan(message.callerName || 'Unknown')})`;
console.log(text, message.output);
}
}
exports.StandardLogger = StandardLogger;
/**
* Base type for logging levels.
*/
declare enum LoggingLevel {
Silent = 0,
Success = 1,
Error = 2,
Warning = 3,
Info = 4,
Debug = 5,
Verbose = 6
}
/**
* Returns true if the given element is a logging level.
* @param something
* @return boolean
*/
declare const isLoggingLevel: (something: any) => something is LoggingLevel;
/**
* Base type for a message written to the log.
*/
interface LogMessage {
level: LoggingLevel;
date: Date;
output: any;
callerName: string;
}
/**
* Returns true if the given object is a log message.
* @param something
* @return boolean
*/
declare const isLogMessage: (something: any) => something is LogMessage;
export { LoggingLevel, LogMessage, isLoggingLevel, isLogMessage };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isLogMessage = exports.isLoggingLevel = exports.LoggingLevel = void 0;
/**
* Base type for logging levels.
*/
var LoggingLevel;
(function (LoggingLevel) {
LoggingLevel[LoggingLevel["Silent"] = 0] = "Silent";
LoggingLevel[LoggingLevel["Success"] = 1] = "Success";
LoggingLevel[LoggingLevel["Error"] = 2] = "Error";
LoggingLevel[LoggingLevel["Warning"] = 3] = "Warning";
LoggingLevel[LoggingLevel["Info"] = 4] = "Info";
LoggingLevel[LoggingLevel["Debug"] = 5] = "Debug";
LoggingLevel[LoggingLevel["Verbose"] = 6] = "Verbose";
})(LoggingLevel || (LoggingLevel = {}));
exports.LoggingLevel = LoggingLevel;
/**
* Returns true if the given element is a logging level.
* @param something
* @return boolean
*/
const isLoggingLevel = (something) => {
return [
LoggingLevel.Silent,
LoggingLevel.Success,
LoggingLevel.Error,
LoggingLevel.Warning,
LoggingLevel.Info,
LoggingLevel.Debug,
LoggingLevel.Verbose
].includes(something);
};
exports.isLoggingLevel = isLoggingLevel;
/**
* Returns true if the given object is a log message.
* @param something
* @return boolean
*/
const isLogMessage = (something) => {
return isLoggingLevel(something === null || something === void 0 ? void 0 : something.level) && (something === null || something === void 0 ? void 0 : something.date) instanceof Date;
};
exports.isLogMessage = isLogMessage;
/**
* Base type for an API response format.
*/
export interface APIResponse {
success: boolean;
message?: string;
data?: any;
error?: {
name: string;
message: string;
stack?: string[];
};
}
/**
* Formats a message as a successful API response.
* @param {string} message
* @return APIResponse
*/
export declare function message(message: string): APIResponse;
/**
* Formats a single record as a successful API response.
* @param record
* @return APIResponse
*/
export declare function one(record: any): APIResponse;
/**
* Formats an array of records as a successful API response.
* @param {array} records
* @return APIResponse
*/
export declare function many(records: any[]): APIResponse;
/**
* Formats an error message or Error instance as an API response.
* @param {string|Error} error
* @return APIResponse
*/
export declare function error(error: string | Error): APIResponse;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.error = exports.many = exports.one = exports.message = void 0;
/**
* Formats a message as a successful API response.
* @param {string} message
* @return APIResponse
*/
function message(message) {
return {
success: true,
message,
};
}
exports.message = message;
/**
* Formats a single record as a successful API response.
* @param record
* @return APIResponse
*/
function one(record) {
return {
success: true,
data: record,
};
}
exports.one = one;
/**
* Formats an array of records as a successful API response.
* @param {array} records
* @return APIResponse
*/
function many(records) {
return {
success: true,
data: {
records,
total: records.length,
},
};
}
exports.many = many;
/**
* Formats an error message or Error instance as an API response.
* @param {string|Error} error
* @return APIResponse
*/
function error(error) {
if (typeof error === 'string') {
return {
success: false,
message: error,
};
}
else {
return {
success: false,
message: error.message,
error: {
name: error.name,
message: error.message,
stack: error.stack ? error.stack.split(/\s+at\s+/).slice(1) : [],
},
};
}
}
exports.error = error;
/**
* Base error used to trigger an unsubscribe action from a subscriber.
* @extends Error
*/
export declare class UnsubscribeError extends Error {
}
/**
* Thrown when a closed observable is pushed to.
* @extends Error
*/
export declare class CompletedObservableError extends Error {
constructor();
}
/**
* Type of a basic subscriber function.
*/
export declare type SubscriberFunction<T> = (val: T) => any;
/**
* Type of a basic subscriber function that handles errors.
*/
export declare type SubscriberErrorFunction = (error: Error) => any;
/**
* Type of a basic subscriber function that handles completed events.
*/
export declare type SubscriberCompleteFunction<T> = (val?: T) => any;
/**
* Subscribers that define multiple handler methods.
*/
export declare type ComplexSubscriber<T> = {
next?: SubscriberFunction<T>;
error?: SubscriberErrorFunction;
complete?: SubscriberCompleteFunction<T>;
};
/**
* Subscription to a behavior subject.
*/
export declare type Subscription<T> = SubscriberFunction<T> | ComplexSubscriber<T>;
/**
* Object providing helpers for unsubscribing from a subscription.
*/
export declare type Unsubscribe = {
unsubscribe: () => void;
};
/**
* A stream-based state class.
*/
export declare class BehaviorSubject<T> {
/**
* Subscribers to this subject.
* @type Array<ComplexSubscriber>
*/
protected subscribers: ComplexSubscriber<T>[];
/**
* True if this subject has been marked complete.
* @type boolean
*/
protected _isComplete: boolean;
/**
* The current value of this subject.
*/
protected _value?: T;
/**
* True if any value has been pushed to this subject.
* @type boolean
*/
protected _hasPush: boolean;
/**
* Register a new subscription to this subject.
* @param {Subscription} subscriber
* @return Unsubscribe
*/
subscribe(subscriber: Subscription<T>): Unsubscribe;
/**
* Cast this subject to a promise, which resolves on the output of the next value.
* @return Promise
*/
toPromise(): Promise<T>;
/**
* Push a new value to this subject. The promise resolves when all subscribers have been pushed to.
* @param val
* @return Promise<void>
*/
next(val: T): Promise<void>;
/**
* Push the given array of values to this subject in order.
* The promise resolves when all subscribers have been pushed to for all values.
* @param {Array} vals
* @return Promise<void>
*/
push(vals: T[]): Promise<void>;
/**
* Mark this subject as complete.
* The promise resolves when all subscribers have been pushed to.
* @param [final_val] - optionally, a final value to set
* @return Promise<void>
*/
complete(final_val?: T): Promise<void>;
/**
* Get the current value of this subject.
*/
value(): T | undefined;
/**
* True if this subject is marked as complete.
* @return boolean
*/
isComplete(): boolean;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorSubject = exports.CompletedObservableError = exports.UnsubscribeError = void 0;
/**
* Base error used to trigger an unsubscribe action from a subscriber.
* @extends Error
*/
class UnsubscribeError extends Error {
}
exports.UnsubscribeError = UnsubscribeError;
/**
* Thrown when a closed observable is pushed to.
* @extends Error
*/
class CompletedObservableError extends Error {
constructor() {
super('This observable can no longer be pushed to, as it has been completed.');
}
}
exports.CompletedObservableError = CompletedObservableError;
/**
* A stream-based state class.
*/
class BehaviorSubject {
constructor() {
/**
* Subscribers to this subject.
* @type Array<ComplexSubscriber>
*/
this.subscribers = [];
/**
* True if this subject has been marked complete.
* @type boolean
*/
this._isComplete = false;
/**
* True if any value has been pushed to this subject.
* @type boolean
*/
this._hasPush = false;
}
/**
* Register a new subscription to this subject.
* @param {Subscription} subscriber
* @return Unsubscribe
*/
subscribe(subscriber) {
if (typeof subscriber === 'function') {
this.subscribers.push({ next: subscriber });
}
else {
this.subscribers.push(subscriber);
}
return {
unsubscribe: () => {
this.subscribers = this.subscribers.filter(x => x !== subscriber);
}
};
}
/**
* Cast this subject to a promise, which resolves on the output of the next value.
* @return Promise
*/
toPromise() {
return new Promise((resolve, reject) => {
const { unsubscribe } = this.subscribe({
next: (val) => {
resolve(val);
unsubscribe();
},
error: (error) => {
reject(error);
unsubscribe();
},
complete: (val) => {
if (typeof val !== 'undefined')
resolve(val);
unsubscribe();
}
});
});
}
/**
* Push a new value to this subject. The promise resolves when all subscribers have been pushed to.
* @param val
* @return Promise<void>
*/
next(val) {
return __awaiter(this, void 0, void 0, function* () {
if (this._isComplete)
throw new CompletedObservableError();
this._value = val;
this._hasPush = true;
for (const subscriber of this.subscribers) {
if (subscriber.next) {
try {
yield subscriber.next(val);
}
catch (e) {
if (e instanceof UnsubscribeError) {
this.subscribers = this.subscribers.filter(x => x !== subscriber);
}
else if (subscriber.error) {
yield subscriber.error(e);
}
else {
throw e;
}
}
}
}
});
}
/**
* Push the given array of values to this subject in order.
* The promise resolves when all subscribers have been pushed to for all values.
* @param {Array} vals
* @return Promise<void>
*/
push(vals) {
return __awaiter(this, void 0, void 0, function* () {
if (this._isComplete)
throw new CompletedObservableError();
yield Promise.all(vals.map(val => this.next(val)));
});
}
/**
* Mark this subject as complete.
* The promise resolves when all subscribers have been pushed to.
* @param [final_val] - optionally, a final value to set
* @return Promise<void>
*/
complete(final_val) {
return __awaiter(this, void 0, void 0, function* () {
if (this._isComplete)
throw new CompletedObservableError();
if (typeof final_val === 'undefined')
final_val = this.value();
else
this._value = final_val;
for (const subscriber of this.subscribers) {
if (subscriber.complete) {
try {
yield subscriber.complete(final_val);
}
catch (e) {
if (subscriber.error) {
yield subscriber.error(e);
}
else {
throw e;
}
}
}
}
this._isComplete = true;
});
}
/**
* Get the current value of this subject.
*/
value() {
return this._value;
}
/**
* True if this subject is marked as complete.
* @return boolean
*/
isComplete() {
return this._isComplete;
}
}
exports.BehaviorSubject = BehaviorSubject;
/**
* Make a deep copy of an object.
* @param target
*/
export declare function deepCopy<T>(target: T): T;
/**
* Given a string of a value, try to infer the JavaScript type.
* @param {string} val
*/
export declare function infer(val: string): any;
/**
* Returns true if the given value is valid JSON.
* @param {string} val
*/
export declare function isJSON(val: string): boolean;
/**
* Get a universally-unique ID string.
* @return string
*/
export declare function uuid_v4(): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.uuid_v4 = exports.isJSON = exports.infer = exports.deepCopy = void 0;
const node_uuid = require("uuid");
/**
* Make a deep copy of an object.
* @param target
*/
function deepCopy(target) {
if (target === null)
return target;
if (target instanceof Date)
return new Date(target.getTime());
if (target instanceof Array) {
const copy = [];
target.forEach(item => { copy.push(item); });
return copy.map((item) => deepCopy(item));
}
if (typeof target === 'object' && target !== {}) {
const copy = Object.assign({}, target);
Object.keys(copy).forEach(key => {
copy[key] = deepCopy(copy[key]);
});
}
return target;
}
exports.deepCopy = deepCopy;
/**
* Given a string of a value, try to infer the JavaScript type.
* @param {string} val
*/
function infer(val) {
if (!val)
return undefined;
else if (val.toLowerCase() === 'true')
return true;
else if (val.toLowerCase() === 'false')
return false;
else if (!isNaN(Number(val)))
return Number(val);
else if (isJSON(val))
return JSON.parse(val);
else if (val.toLowerCase() === 'null')
return null;
else if (val.toLowerCase() === 'undefined')
return undefined;
else
return val;
}
exports.infer = infer;
/**
* Returns true if the given value is valid JSON.
* @param {string} val
*/
function isJSON(val) {
try {
JSON.parse(val);
return true;
}
catch (e) {
return false;
}
}
exports.isJSON = isJSON;
/**
* Get a universally-unique ID string.
* @return string
*/
function uuid_v4() {
return node_uuid.v4();
}
exports.uuid_v4 = uuid_v4;
/**
* Apply the given mixin classes to the given constructor.
* @param derivedCtor
* @param {array} baseCtors
*/
export declare function applyMixins(derivedCtor: any, baseCtors: any[]): void;
/**
* Base type for a constructor function.
*/
export declare type Constructor<T = {}> = new (...args: any[]) => T;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyMixins = void 0;
/**
* Apply the given mixin classes to the given constructor.
* @param derivedCtor
* @param {array} baseCtors
*/
function applyMixins(derivedCtor, baseCtors) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
const desc = Object.getOwnPropertyDescriptor(baseCtor.prototype, name);
if (typeof desc !== 'undefined')
Object.defineProperty(derivedCtor.prototype, name, desc);
});
});
}
exports.applyMixins = applyMixins;
export declare enum UniversalPathPrefix {
HTTP = "http://",
HTTPS = "https://",
Local = "file://"
}
export declare type PathLike = string | UniversalPath;
export declare function universalPath(...parts: PathLike[]): UniversalPath;
export declare class UniversalPath {
protected readonly initial: string;
protected _prefix: UniversalPathPrefix;
protected _local: string;
constructor(initial: string);
protected setPrefix(): void;
protected setLocal(): void;
get prefix(): UniversalPathPrefix;
get isLocal(): boolean;
get isRemote(): boolean;
get unqualified(): string;
get toLocal(): string;
get toRemote(): string;
concat(...paths: PathLike[]): UniversalPath;
append(path: PathLike): this;
toString(): string;
get ext(): string;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UniversalPath = exports.universalPath = exports.UniversalPathPrefix = void 0;
const node_path = require("path");
var UniversalPathPrefix;
(function (UniversalPathPrefix) {
UniversalPathPrefix["HTTP"] = "http://";
UniversalPathPrefix["HTTPS"] = "https://";
UniversalPathPrefix["Local"] = "file://";
})(UniversalPathPrefix = exports.UniversalPathPrefix || (exports.UniversalPathPrefix = {}));
function universalPath(...parts) {
let [main, ...concats] = parts;
if (!(main instanceof UniversalPath))
main = new UniversalPath(main);
return main.concat(...concats);
}
exports.universalPath = universalPath;
class UniversalPath {
constructor(initial) {
this.initial = initial;
this.setPrefix();
this.setLocal();
}
setPrefix() {
if (this.initial.toLowerCase().startsWith('http://')) {
this._prefix = UniversalPathPrefix.HTTP;
}
else if (this.initial.toLowerCase().startsWith('https://')) {
this._prefix = UniversalPathPrefix.HTTPS;
}
else {
this._prefix = UniversalPathPrefix.Local;
}
}
setLocal() {
this._local = this.initial;
if (this.initial.toLowerCase().startsWith(this._prefix)) {
this._local = this._local.slice(this._prefix.length);
}
if (this._prefix === UniversalPathPrefix.Local && !this._local.startsWith('/')) {
this._local = node_path.resolve(this._local);
}
}
get prefix() {
return this._prefix;
}
get isLocal() {
return this._prefix === UniversalPathPrefix.Local;
}
get isRemote() {
return this._prefix !== UniversalPathPrefix.Local;
}
get unqualified() {
return this._local;
}
get toLocal() {
if (this.isLocal) {
return this._local;
}
else {
return `${this.prefix}${this._local}`;
}
}
get toRemote() {
return `${this.prefix}${this._local}`;
}
concat(...paths) {
const resolved = node_path.join(this.unqualified, ...(paths.map(p => typeof p === 'string' ? p : p.unqualified)));
return new UniversalPath(`${this.prefix}${resolved}`);
}
append(path) {
this._local += String(path);
return this;
}
toString() {
return `${this.prefix}${this._local}`;
}
get ext() {
return node_path.extname(this._local);
}
}
exports.UniversalPath = UniversalPath;
/**
* Type representing a JSON serializable object.
*/
export declare type JSONState = {
[key: string]: string | boolean | number | undefined | JSONState | Array<string | boolean | number | undefined | JSONState>;
};
/**
* Returns true if the given object can be JSON serialized.
* @param what
* @return boolean
*/
export declare function isJSONState(what: any): what is JSONState;
/**
* Base interface for a class that can be rehydrated and restored.
*/
export interface Rehydratable {
/**
* Dehydrate this class' state and get it.
* @return Promise<JSONState>
*/
dehydrate(): Promise<JSONState>;
/**
* Rehydrate a state into this class.
* @param {JSONState} state
* @return void|Promise<void>
*/
rehydrate(state: JSONState): void | Promise<void>;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isJSONState = void 0;
/**
* Returns true if the given object can be JSON serialized.
* @param what
* @return boolean
*/
function isJSONState(what) {
try {
JSON.stringify(what);
return true;
}
catch (e) {
return false;
}
}
exports.isJSONState = isJSONState;
/**
* Base interface representing a timeout subscriber.
*/
export interface TimeoutSubscriber<T> {
onTime: (handler: (arg: T) => any) => TimeoutSubscriber<T>;
late: (handler: (arg: T) => any) => TimeoutSubscriber<T>;
timeout: (handler: () => any) => TimeoutSubscriber<T>;
run: () => Promise<T>;
}
/**
* Subscribe to a promise with a timeout.
* @param {number} timeout - timeout in milliseconds
* @param {Promise} promise - the promise to subscribe to
*/
export declare function withTimeout<T>(timeout: number, promise: Promise<T>): TimeoutSubscriber<T>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withTimeout = void 0;
/**
* Subscribe to a promise with a timeout.
* @param {number} timeout - timeout in milliseconds
* @param {Promise} promise - the promise to subscribe to
*/
function withTimeout(timeout, promise) {
let onTimeHandler = (arg) => { };
let lateHandler = (arg) => { };
let timeoutHandler = () => { };
const sub = {
onTime: handler => {
onTimeHandler = handler;
return sub;
},
late: handler => {
lateHandler = handler;
return sub;
},
timeout: handler => {
timeoutHandler = handler;
return sub;
},
run: () => __awaiter(this, void 0, void 0, function* () {
let expired = false;
let resolved = false;
setTimeout(() => {
expired = true;
if (!resolved)
timeoutHandler();
}, timeout);
const result = yield promise;
resolved = true;
if (!expired) {
yield onTimeHandler(result);
}
else {
yield lateHandler(result);
}
return result;
})
};
return sub;
}
exports.withTimeout = withTimeout;
+31
-0
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./cache/Cache"), exports);
__exportStar(require("./cache/InMemCache"), exports);
__exportStar(require("./collection/ArrayIterable"), exports);
__exportStar(require("./collection/AsyncCollection"), exports);
__exportStar(require("./collection/Collection"), exports);
__exportStar(require("./collection/Iterable"), exports);
__exportStar(require("./collection/where"), exports);
__exportStar(require("./const/http"), exports);
__exportStar(require("./error/ErrorWithContext"), exports);
__exportStar(require("./error/RunLevelErrorHandler"), exports);
__exportStar(require("./logging/Logger"), exports);
__exportStar(require("./logging/StandardLogger"), exports);
__exportStar(require("./logging/types"), exports);
__exportStar(require("./support/api"), exports);
__exportStar(require("./support/BehaviorSubject"), exports);
__exportStar(require("./support/data"), exports);
__exportStar(require("./support/mixin"), exports);
__exportStar(require("./support/path"), exports);
__exportStar(require("./support/Rehydratable"), exports);
__exportStar(require("./support/timeout"), exports);
+6
-2
{
"name": "@extollo/util",
"version": "0.1.0",
"version": "0.2.0",
"description": "Utilities that lift up your code.",

@@ -11,3 +11,7 @@ "main": "lib/index.js",

"dependencies": {
"typescript": "^4.1.3"
"@types/node": "^14.14.20",
"@types/uuid": "^8.3.0",
"colors": "^1.4.0",
"typescript": "^4.1.3",
"uuid": "^8.3.2"
},

@@ -14,0 +18,0 @@ "devDependencies": {},