npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@noravel/supporter

v2.4.20

Published

This is a support library for my personal projects.

Readme

Noravel supporter

This is a support library for Nam's projects.

Content

Object

const { _obj } = require('@noravel/supporter');

// OR

import { _obj } from '@noravel/supporter';

_obj.combine

Create a new object with each key associated with each corresponding value.

const keys = ['id', 'name'];
const values = [1, 'Trinh Tran Phuong Nam'];

console.log(_obj.combine(keys, values));
/*
{
  id: 1,
  name: 'Trinh Tran Phuong Nam'
}
*/

In case the key length is greater than the value length.

const keys = ['id', 'name', 'email'];
const values = [1, 'Trinh Tran Phuong Nam'];

console.log(_obj.combine(keys, values));
/*
{
  id: 1,
  name: 'Trinh Tran Phuong Nam',
  email: null
}
*/

In case the value length is greater than the key length.

const keys = ['id', 'name'];
const values = [1, 'Trinh Tran Phuong Nam', '[email protected]', 'bla bla'];

console.log(_obj.combine(keys, values));
/*
{
  id: 1,
  name: 'Trinh Tran Phuong Nam',
  key_0: '[email protected]',
  key_1: 'bla bla'
}
*/

_obj.get

Get an item from an array using "dot" notation.

const data = {
  user: {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
  },
};

console.log(_obj.get(data, 'user.name')); // 'Trinh Tran Phuong Nam'
console.log(_obj.get(data, 'user.email')); // null
console.log(_obj.get(data, 'user.email', '[email protected]')); // '[email protected]'
console.log(_obj.get(data, 'user.email', () => 'We can pass the callback here.')); // 'We can pass the callback here.'

_obj.set

Set an object item to a given value using "dot" notation.

const data = {
  user: {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
  },
};

console.log(_obj.get(data, 'user.email')); // null

_obj.set(data, 'user.email', '[email protected]');

console.log(_obj.get(data, 'user.email')); // '[email protected]'

_obj.only

Get a subset of the items from the given object.

const user = {
  id: 1,
  name: 'Trinh Tran Phuong Nam',
  email: '[email protected]',
  address: 'Everywhere',
};

console.log(_obj.only(user, 'id')); // { id: 1 }
console.log(_obj.only(user, ['id', 'name'])); // { id: 1, name: 'Trinh Tran Phuong Nam' }

_obj.except

Get all of the given object except for a specified object of keys.

const user = {
  id: 1,
  name: 'Trinh Tran Phuong Nam',
  email: '[email protected]',
};

console.log(_obj.except(user, 'email')); // { id: 1, name: 'Trinh Tran Phuong Nam' }
console.log(_obj.except(user, ['name', 'email'])); // { id: 1 }

_obj.has

Deeply check whether the properties exist or not.

const user = {
  id: 1,
  address: {
    city: 'Sample city',
  },
};

console.log(_obj.has(user, 'address.city')); // true
console.log(_obj.has(user, 'address.district')); // false

_obj.map

Run a map over each of the properties in the object.

const routes = {
  home: {
    controller: 'HomeController',
    url: '/',
  },
  about: {
    controller: 'HomeController',
    url: '/about',
  },
};

const links = _obj.map(routes, item => `https://domain.example${item.url}`);
const actions = _obj.map(routes, (item, key) => `${item.controller}@${key}`);

console.log(links); // ['https://domain.example/', 'https://domain.example/about']
console.log(actions); // ['HomeController@home', 'HomeController@about']

_obj.toQueryString

Convert an object to a query string with each property.

const filters = { search: { name: 'Nam' }, sort_field: 'id', sort_direction: 'desc' };

console.log(_obj.toQueryString(filters)); // '?search[name]=Nam&sort_field=id&sort_direction=desc'

_obj.replicate

Clone the object into a new, non-existing instance.

const user = new User();
const clone = _obj.replicate(user);

JSON.stringify(user) === JSON.stringify(clone); // true

Array

const { _arr } = require('@noravel/supporter');

// OR

import { _arr } from '@noravel/supporter';

_arr().chunk

Chunk the array into chunks of the given size.

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(_arr(data).chunk(2)); // [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

_arr().collapse

Collapse the array into a single array.

const data = [[1, 2, 3], [4, 5, 6, 7], [8, 9], [10]];

console.log(_arr(data).collapse()); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

_arr().first

Returns the first element of the array.

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(_arr(data).first()); // 1

_arr().mapToGroups

Run a grouping map over the items. The callback should return an array with a single key/value pair.

const users = [
  {
    name: 'John Doe',
    department: 'Sales',
  },
  {
    name: 'Jane Doe',
    department: 'Sales',
  },
  {
    name: 'Johnny Doe',
    department: 'Marketing',
  },
];

console.log(_arr(users).mapToGroups(user => [user.department, user.name]));
/*
{
  Sales: ['John Doe', 'Jane Doe'],
  Marketing: ['Johnny Doe'],
}
*/

_arr().pluck

Pluck an array of values from an array.

const users = [
  {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
  },
  {
    id: 2,
    name: 'John Doe',
  },
];

console.log(_arr(users).pluck('id')); // [1, 2]

_arr().range

Creates an array of numbers processing from "start" up to "end" (including "end").

console.log(_arr().range(10)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(_arr().range(-10)); // [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]
console.log(_arr().range(0, 10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(_arr().range(1, 10, 2)); // [1, 3, 5, 7, 9]
console.log(_arr().range(10, 1)); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
console.log(_arr().range(10, 1, 2)); // [10, 8, 6, 4, 2]

_arr().supplement

Add elements to ensure the length of the array.

const data = ['a', 'b', 'c'];

console.log(_arr(data).supplement(5)); // ['a', 'b', 'c', null, null]
console.log(_arr(data).supplement(5, 'additional item')); // ['a', 'b', 'c', 'additional item', 'additional item']

_arr().unique

Filter out duplicate elements to ensure that array elements are unique.

const data = ['a', 'b', 1, 2, 'a', '1'];
console.log(_arr(data).unique()); // ['a', 'b', 1, 2, '1']

Check for a unique value for an array element that is an object by key.

const users = [
  {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
  },
  {
    id: 2,
    name: 'John Doe',
  },
  {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
  },
];

console.log(_arr(users).unique('id'));
/*
[
  {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
  },
  {
    id: 2,
    name: 'John Doe',
  },
]
*/

_arr().toSelectOptions

The first parameter is an array with 2 elements, the first element is the name of the key that will be taken as the value of the option and the second element is the name of the key that will be taken as the label.

The second parameter is an array with 2 elements, the first element is the name of the key that stores the value of the element retrieved by the key in the first parameter and the second element is the name of the key that stores the value of the element is obtained by the second key in the first parameter.

const users = [
  {
    id: 1,
    name: 'Trinh Tran Phuong Nam',
    email: '[email protected]',
  },
  {
    id: 2,
    name: 'John Doe',
    email: '[email protected]',
  }
];

const options = _arr(users).toSelectOptions(['id', 'name'], ['value', 'label']);
console.log(options);
/*
[
  {
    value: 1,
    label: 'Trinh Tran Phuong Nam',
  },
  {
    value: 2,
    label: 'John Doe',
  },
]
*/

// Example for react component
<select>
  {options.map(option => (
      <option value={option.value} key={option.value}>
        {option.label}
      </option>
    )
  )}
</select>

<Select options={options} />

In case the array elements are not an object. The element's index will be the value of the option, the element's value will be the label.

const status = ['new', 'in process', 'done'];
console.log(_arr(status).toSelectOptions());
/*
[
  {
    value: 0,
    label: 'new',
  },
  {
    value: 1,
    label: 'in process',
  },
  {
    value: 2,
    label: 'done',
  },
]
*/

_arr().isEmpty

Check for empty array.

console.log(_arr([]).isEmpty()); // true
console.log(_arr([]).supplement(10).isEmpty()); // false

String

const { _str } = require('@noravel/supporter');

// OR

import { _str } from '@noravel/supporter';

_str().get

Get the raw string value.

console.log(_str('Lorem ipsum').get()); // 'Lorem ipsum'

// OR

console.log(_str('Lorem ipsum').toString()); // 'Lorem ipsum'

You can also get a substring from the start position to the end position.

console.log(_str('Lorem ipsum').get(6, 11)); // 'ipsum'

_str().length

Get the length of the string.

console.log(_str('Nam').length()); // 3

_str().after

Return the remainder of a string after the first occurrence of a given value.

console.log(_str('This is my name').after(' ').get()); // 'is my name'

_str().afterLast

Return the remainder of a string after the last occurrence of a given value.

console.log(_str('/path/to/filename.extension').afterLast('/').get()); // 'filename.extension'

_str().before

Get the portion of a string before the first occurrence of a given value.

console.log(_str('This is my name').before(' ').get()); // 'This'

_str().beforeLast

Get the portion of a string before the last occurrence of a given value.

console.log(_str('This is my name').beforeLast(' ').get()); // 'This is my'

_str().between

Get the portion of a string between two given values.

console.log(_str('This is my name').between('This', 'name').get()); // ' is my '

_str().betweenFirst

Get the smallest possible portion of a string between two given values.

console.log(_str('[a] bc [d]').betweenFirst('[', ']').get()); // 'a'
console.log(_str('[a] bc [d]').between('[', ']').get()); // 'a] bc [d'

_str().bind

Binds the values ​​to the given string.

const user = { user_id: 1, name: 'John Doe' };
const url = '/api/users/{user_id}/edit';

console.log(_str(url).bind(user).get()); // '/api/users/1/edit'
const user = { user_id: 1, name: 'John Doe' };
const url = '/api/users/{0}/edit';

console.log(_str(url).bind(user.user_id).get()); // '/api/users/1/edit'
const user = { user_id: 1, name: 'John Doe' };
const post = { post_id: 1812, title: 'Title', content: 'Content' };
const url = '/api/users/{0}/post/{1}/edit';

console.log(_str(url).bind(user.user_id, post.post_id).get()); // '/api/users/1/post/1812/edit'
console.log(_str(url).bind([user.user_id, post.post_id]).get()); // '/api/users/1/post/1812/edit'

_str().append

Append the given values to the string.

console.log(_str('This is').append(' my name').get()); // 'This is my name'

_str().prepend

Prepend the given values to the string.

console.log(_str('/api/users').prepend('https://domain.example').get()); // 'https://domain.example/api/users'

_str().title

Convert the given string to proper case.

console.log(_str('trinh tran phuong nam').title().get()); // 'Trinh Tran Phuong Nam'

_str().studly

Convert a value to studly caps case.

console.log(_str('phuong_nam').studly().get()); // 'PhuongNam'

_str().camel

Convert a value to camel case.

console.log(_str('phuong_nam').camel().get()); // 'phuongNam'

_str().lower

Convert the given string to lower-case.

console.log(_str('NAM').lower().get()); // 'nam'

_str().upper

Convert the given string to upper-case.

console.log(_str('nam').upper().get()); // 'NAM'

_str().nonUnicode

Remove Vietnamese unicode characters from the string.

console.log(_str('Trịnh Trần Phương Nam').nonUnicode().get()); // 'Trinh Tran Phuong Nam'

_str().snake

Convert a string to snake case.

console.log(_str('trinhTranPhuongNam').snake().get()); // 'trinh_tran_phuong_nam'

console.log(_str('trinhTranPhuongNam').snake('-').get()); // 'trinh-tran-phuong-nam'

_str().kebab

Convert a string to kebab case.

console.log(_str('trinhTranPhuongNam').kebab().get()); // 'trinh-tran-phuong-nam'

_str().escapeHtml

Escape HTML character.

console.log(_str('<p>Hello world</p>').escapeHtml().get()); // '&lt;p&gt;Hello world&lt;/p&gt;'

_str().limit

Limit the number of characters in a string.

console.log(_str('The quick brown fox jumps over the lazy dog').limit(20).get()); // 'The quick brown fox...'

_str().random

Generate a more truly "random" string. The includeSymbols option includes the following characters:

!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
console.log(_str().random(20)); // 'kvyufaqbosqlcojacnqo'
console.log(_str().random(20, { uppercase: true })); // 'KJqGfjKjccCjHnmmxyeM'
console.log(_str().random(20, { numbers: true })); // 'h372ysnmr71klxekb4fs'
console.log(_str().random(20, { symbols: true })); // '[-\\jb'p*w_i}@(;|t"zh'

// full options
const options = {
  uppercase: true,
  numbers: true,
  symbols: true,
};
const password = _str().random(20, options);

console.log(password); // '6!?iR(2)iQW}>UY})owi'

_str().shuffle

Randomly shuffles a string.

console.log(_str('abcdefghijklmnopqrstuvwxyz').shuffle().get()); // 'zjmpnleuqfcsakigwhoxrdytbv'

_str().replace

Replace the given value in the given string.

console.log(
  _str('Hello everyone')
    .replace(/^Hello/, 'Hi')
    .get(),
); // 'Hi everyone'

_str().replaceAt

Replace the given value in the given string from a specific position.

console.log(_str('Hello everyone').replaceAt(2, '!!').get()); // 'He!!o everyone'

_str().splice

Split a string from a specific position and then insert the splice into the slice.

console.log(_str('Hello everyone!!!').splice(6, 8, '**everyone**').get()); // 'Hello **everyone**!!!'

_str().slice

Extracts a section of this string and returns it as a new string. The start value is the position taken from and the end value is the position taken to. Start = 0 is equivalent to the first character of the string. The ending value includes the character at that position.

const str = 'The quick brown fox jumps over the lazy dog.';

console.log(_str(str).slice(31).get()); // 'the lazy dog.'
console.log(_str(str).slice(4, 19).get()); // 'quick brown fox'
console.log(_str(str).slice(-4).get()); // 'dog.'
console.log(_str(str).slice(-9, -5).get()); // 'lazy'
console.log(_str(str).slice(-9).upper().slice(0, 8).get()); // 'LAZY DOG'

_str().padStart

Pads a given value in front of a given string until the given length is reached.

console.log(_str('1').padStart(2, '0').get()); // '01'

const email = '[email protected]';
const marked = _str(email)
  .before('@')
  .slice(-3)
  .padStart(_str(email).before('@').length(), '*')
  .append(_str(email).after('@').prepend('@').get())
  .get();
console.log(marked); // '***[email protected]'

_str().padEnd

Pads a given value behind a given string until the given length is reached.

console.log(_str('200').padEnd(10, '-').get()); // '200-------'
console.log(_str('200').padEnd(5).get()); // '200     '

_str().ltrim

Remove whitespace from the left side of a string.

console.log(_str('  Hello world  ').ltrim().get()); // 'Hello world  '

_str().rtrim

Remove whitespace from the right side of a string.

console.log(_str('  Hello world  ').rtrim().get()); // '  Hello world'

_str().trim

Remove whitespace from both sides of a string.

console.log(_str('  Hello world  ').trim().get()); // 'Hello world'

_str().dump

You can log the results of each processing segment for easy debugging.

_str('/storage/files/logs/log.log')
  .beforeLast('/')
  .dump()
  .after('/storage/')
  .dump()
  .toString();

// /storage/files/logs
// files/logs

Collection

Create a collection instance from an array or object.

const { _col, Collection } = require('@noravel/supporter');

// OR

import { _col, Collection } from '@noravel/supporter';

...

console.log(_col([1, 2, 3]).all()); // [1, 2, 3]

// OR

console.log(new Collection([1, 2, 3]).all()); // [1, 2, 3]

You can create a new instance of the collection by passing a parameter that is not an array.

console.log(_col('Hello world').all()); // ['Hello world']
console.log(_col(123).all()); // [123]
console.log(_col({ name: 'John', age: 30 }).all()); // [{ name: 'John', age: 30 }]

_col().all

Get all items in the collection as an array.

console.log(_col().all()); // []
console.log(_col([1, 2, 3, 4, 5]).all()); // [1, 2, 3, 4, 5]

_col().chunk

Split an array into chunks of the specified size.

console.log(_col([1, 2, 3, 4, 5]).chunk(2).all()); // [[1, 2], [3, 4], [5]]

_col().collapse

Collapse an array of arrays into a single array.

console.log(_col([[1, 2], [3, 4], [5]]).collapse().all()); // [1, 2, 3, 4, 5]

_col().collect

Get a shallow copy of this collection.

console.log(_col([1, 2, 3, 4, 5]).collect().all()); // [1, 2, 3, 4, 5]

_col().concat

The concat method concatenates the underlying array with the given array or collection and return a new collection.

console.log(_col([1, 2, 3]).concat([3, 4, 5]).all()); // [1, 2, 3, 3, 4, 5]

_col().contains

Check if a value is present in the collection.

console.log(_col([1, 2, 3]).contains(2)); // true

// OR

console.log(_col([1, 2, 3]).contains(value => value === 3)); // true

_col().count

Get the number of items in the collection.

console.log(_col([1, 2, 3]).count()); // 3

_col().crossJoin

Cross join the given arrays.

console.log(_col([1, 2]).crossJoin(['a', 'b']).all()); // [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
console.log(_col([1, 2]).crossJoin(['a', 'b'], ['I', 'II']).all());
/*
[
  [1, 'a', 'I'],
  [1, 'a', 'II'],
  [1, 'b', 'I'],
  [1, 'b', 'II'],
  [2, 'a', 'I'],
  [2, 'a', 'II'],
  [2, 'b', 'I'],
  [2, 'b', 'II']
]
*/

_col().diff

The diff method compares the collection against another collection or a plain array based on its values. This method will return the values in the original collection that are not present in the given collection or array.

const collection = _col([1, 2, 3, 4, 5]);
const diff = collection.diff([2, 4, 6, 8]);
console.log(diff.all()); // [1, 3, 5]

_col().each

This will iterate over the items in the collection and pass each item to the given callback.

_col([1, 2, 3]).each(value => console.log(value)); // 1 2 3

If you would like to stop iterating through the items, you may return false from your callback.

_col([1, 2, 3, 4, 5]).each(value => {
  if (value > 3) {
    return false
  };

  console.log(value);
}); // 1 2 3

_col().every

The every method may be used to verify that all elements of a collection pass a given truth test.

console.log(_col([1, 2, 3, 4, 5]).every(value => value < 4)); // false

If the collection is empty, the every method will return true.

console.log(_col().every(value => value < 4)); // true

_col().filter

The filter method filters the collection using the given callback, keeping only those items that pass a given truth test.

const collection = _col([1, 2, 3, 4, 5]);
const filtered = collection.filter(value => value < 4);
console.log(filtered.all()); // [1, 2, 3]

If no callback is supplied, all entries of the collection that are equivalent to false will be returned.

const collection = _col([0, 1, 2, 3, null, false, '', undefined, [], {}, { isEmpty: () => true }, { count: () => 0 }]);
const filtered = collection.filter();
console.log(filtered.all()); // [1, 2, 3]

_col().first

The first method returns the first element in the collection that passes a given truth test.

console.log(_col([1, 2, 3, 4, 5]).first(value => value > 3)); // 4

You may also call the first method with no arguments to get the first element in the collection. If the collection is empty, it will return undefined.

console.log(_col([1, 2, 3, 4, 5]).first()); // 1

_col().forPage

The forPage method returns a new collection containing the items that would be present on a given page number. The method accepts the page number as its first argument and the number of items to show per page as its second argument. By default, the number of items per page is 10.

const collection = _col([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const page = collection.forPage(2, 3);
console.log(page.all()); // [4, 5, 6]

_col().groupBy

The groupBy method groups the collection's items by a given key.

const collection = _col([
  { name: 'John Doe', department: 'IT' },
  { name: 'Jane Doe', department: 'IT' },
  { name: 'Jame Doe', department: 'Sales' },
]);
const grouped = collection.groupBy('department');
console.log(grouped.all());
/*
{
  IT: [
    { name: 'John Doe', department: 'IT' },
    { name: 'Jane Doe', department: 'IT' },
  ],
  Sales: [
    { name: 'Jame Doe', department: 'Sales' },
  ],
}
*/

_col().intersect

The intersect method removes any values from the original collection that are not present in the given collection or array.

const collection = _col([1, 2, 3, 4, 5]);
const intersected = collection.intersect([1, 2, 4]);
console.log(intersected.all()); // [1, 2, 4]

_col().isEmpty

The isEmpty method returns true if the collection is empty, false otherwise.

const collection = _col([]);
console.log(collection.isEmpty()); // true

const collection2 = _col([1, 2, 3]);
console.log(collection2.isEmpty()); // false

_col().isNotEmpty

The isNotEmpty method returns true if the collection is not empty, false otherwise.

const collection = _col([1, 2, 3]);
console.log(collection.isNotEmpty()); // true

const collection2 = _col([]);
console.log(collection2.isNotEmpty()); // false

_col().last

The last method returns the last element of the collection that passes a given truth test.

const collection = _col([1, 2, 3]);
console.log(collection.last(value => value < 3)); // 2

You may also call the last method with no arguments to get the last element in the collection. If the collection is empty, it will return undefined.

const collection = _col([1, 2, 3]);
console.log(collection.last()); // 3

_col().map

The map method iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items.

const collection = _col([1, 2, 3]);
const multiplied = collection.map(value => value * 2);
console.log(multiplied.all()); // [2, 4, 6]

_col().mapToGroups

The mapToGroups method groups the collection's items by the given closure. The closure should return an array with two elements, the first being the group key and the second being the item. If closure returns an array with number of elements different from 2, it will throw an error.

const collection = _col([
  { name: 'John', department: 'IT' },
  { name: 'Jane', department: 'Marketing' },
  { name: 'Bob', department: 'IT' }
]);
const grouped = collection.mapToGroups(item => [item.department, item.name]);
console.log(grouped);
/*
{
  IT: ['John', 'Bob'],
  Marketing: ['Jane'],
}
*/

_col().merge

The merge method merges the given array or collection with the original collection. Unlike the concat method, this method only merges non-existent elements in the origin collection and modifies the original collection.

const collection1 = _col([1, 2, 3]);
const collection2 = _col([3, 4, 5]);
collection1.merge(collection2);
console.log(collection1.all()); // [1, 2, 3, 4, 5]

const users1 = _col([
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 3, name: 'Jame' },
]);
const users2 = _col([
  { id: 1, name: 'John' },
  { id: 4, name: 'Bob' },
]);
users1.merge(users2);
console.log(users1.all());
/* 
[
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 3, name: 'Jame' },
  { id: 4, name: 'Bob' },
]
*/

_col().pad

The pad method will fill the array with the given value until the array reaches the specified size. To pad to the left, you should specify a negative size. No padding with take place if the absolute value of the size is less than or equal to the array length.

const collection = _col([1, 2, 3]);
let filtered = collection.pad(5, 0);
console.log(filtered.all()); // [1, 2, 3, 0, 0]

filtered = collection.pad(-5, 0);
console.log(filtered.all()); // [0, 0, 1, 2, 3]

_col().pluck

The pluck method retrieves all of the values for a given key.

const collection = _col([
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 3, name: 'Jame' },
]);

const names = collection.pluck('name');
console.log(names); // ['John', 'Jane', 'Jame']

The pluck method also supports retrieving nested values using dot notation.

const collection = _col([
  { id: 1, department: { name: 'IT' } },
  { id: 2, department: { name: 'Sales' } },
  { id: 3, department: { name: 'Marketing' } },
]);

const names = collection.pluck('department.name');
console.log(names); // ['IT', 'Sales', 'Marketing']

_col().pop

The pop method removes and returns the last item from the collection.

const collection = _col([1, 2, 3, 4, 5]);
const popped = collection.pop();
console.log(popped); // 5
console.log(collection.all()); // [1, 2, 3, 4]

You may pass an integer to the pop method to remove and return multiple items from the end of a collection.

const collection = _col([1, 2, 3, 4, 5]);
const popped = collection.pop(2);
console.log(popped); // [5, 4]
console.log(collection.all()); // [1, 2, 3]

_col().prepend

The prepend method will add the given value(s) to the beginning of the collection.

const collection = _col([1, 2, 3]);
collection.prepend(-1, 0);
console.log(collection.all()); // [-1, 0, 1, 2, 3]

_col().push

The push method will add the given item to the end of the collection.

const collection = _col([1, 2, 3]);
collection.push(4);
console.log(collection.all()); // [1, 2, 3, 4]

_col().random

The random method will return a random item from the collection.

const collection = _col([1, 2, 3, 4, 5]);
const random = collection.random();
console.log(random); // 3 - (retrieved randomly)

_col().range

The range method returns a collection containing integers between the specified range. If the first argument is greater than the second, it will return a collection decreasing in value.

const collection = _col.range(3, 5);
console.log(collection.all()); // [3, 4, 5]

const decreased = _col.range(5, 3);
console.log(decreased.all()); // [5, 4, 3]

You may also pass a third argument to specify the step value.

const collection = _col.range(1, 10, 2);
console.log(collection.all()); // [1, 3, 5, 7, 9]

If the first argument is equal to the second, it will return a collection with 1 element.

const collection = _col.range(3, 3);
console.log(collection.all()); // [3]

_col().reverse

The reverse method returns a new collection with the items in reverse order.

const collection = _col([1, 2, 3, 4, 5]);
const reversed = collection.reverse();
console.log(reversed.all()); // [5, 4, 3, 2, 1]

_col().shift

The shift method removes and returns the first element of the collection.

const collection = _col([1, 2, 3, 4, 5]);
const shifted = collection.shift();
console.log(shifted); // 1
console.log(collection.all()); // [2, 3, 4, 5]

_col().shuffle

The shuffle method returns a new collection with the items in random order.

const collection = _col([1, 2, 3, 4, 5]);
const shuffled = collection.shuffle();
console.log(shuffled.all()); // [3, 5, 2, 4, 1] - (retrieved randomly)

_col().slice

The slice method returns a new collection containing a slice of the items in the original collection.

const collection = _col([1, 2, 3, 4, 5]);
const sliced = collection.slice(1, 4);
console.log(sliced.all()); // [2, 3, 4]

_col().sort

The sort method returns a new collection with the items in sorted order.

const collection = _col([3, 5, 2, 4, 1]);
const sorted = collection.sort();
console.log(sorted.all()); // [1, 2, 3, 4, 5]

You may also pass a closure to specify the sorting criteria.

const collection = _col([
  { id: 3, name: 'Jame Doe' },
  { id: 1, name: 'John Doe' },
  { id: 2, name: 'Jane Doe' },
  { id: 4, name: 'John Smith' },
]);
const sorted = collection.sort((a, b) => a.id - b.id);
console.log(sorted.all());
/*
[
  { id: 1, name: 'John Doe' },
  { id: 2, name: 'Jane Doe' },
  { id: 3, name: 'Jame Doe' },
  { id: 4, name: 'John Smith' },
]
*/

_col().splice

The splice method removes and gets the spliced items in the collection.

const collection1 = _col([1, 2, 3, 4, 5, 6]);
collection1.splice(1);
console.log(collection1.all()); // [1]

const collection2 = _col([1, 2, 3, 4, 5, 6]);
collection2.splice(1, 2);
console.log(collection2.all()); // [1, 4, 5, 6]

const collection3 = _col(['Jan', 'Apr', 'May', 'Jun']);
collection3.splice(1, 0, 'Feb', 'Mar');
console.log(collection3.all()); // ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']

_col().split

The split method breaks a collection into the given number of groups, filling non-terminal groups completely before allocating the remainder to the final group.

const collection = _col([1, 2, 3, 4, 5]);
const groups = collection.split();
console.log(groups.all()); // [[1, 2], [3, 4], [5]]

_col().sum

The sum method returns the sum of the items in the collection.

const collection = _col([1, 2, 3, 4, 5]);
const sum = collection.sum();
console.log(sum); // 15

If the item of the collection is an array, the sum of the length of the array is returned.

const collection = _col([[1, 2], [3, 4], [5]]);
const sum = collection.sum();
console.log(sum); // 5

If the item of the collection is an object, you should pass a key to the sum method to calculate the sum of the values of that key.

const collection = _col([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);
const sum = collection.sum('id');
console.log(sum); // 3

_col().tap

The tap method passes the collection to the given callback, allowing you to tap into the collection at a specific point and do something with the items while not affecting the collection itself. The collection is then returned bt the tap method.

const shifted = _col([2, 4, 3, 1, 5])
  .sort()
  .tap(function (collection) {
    collection.dump(); // [1, 2, 3, 4, 5]
  })
  .shift();
console.log(shifted); // 1

_col().toArray

The toArray method returns all items in the collection as a plain array. If the item of the collection is an instance of the object has a toArray method, the toArray method will be called recursively.

const collection = _col([
  _col().range(1, 5),
  _col().range(6, 10),
]);
const toArray = collection.toArray();
const all = collection.all();
console.log(toArray); // [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
console.log(all);
/*
[
  Collection { items: [ 1, 2, 3, 4, 5 ] },
  Collection { items: [ 6, 7, 8, 9, 10 ] }
]
*/

_col().toJson

The toJson method returns all items in the collection as a JSON string.

const collection = _col([1, 2, 3, 4, 5]);
const json = collection.toJson();
console.log(json); // "[1,2,3,4,5]"

_col().toString

The toString method is similar to the toJson method, except that for a sequential map collection, it returns a string containing the collection values ​​separated by commas.

const string = _col([1, 2, 3, 4, 5]).toString();
console.log(string); // "1,2,3,4,5"

Equivalent

const string = _col([1, 2, 3, 4, 5]).all().join(',');
console.log(string); // "1,2,3,4,5"

In the case where the collection items are objects, it will prioritize checking the toJson method first. If there is no toJson method, it will convert the object to a JSON string.

const users = [
  {
    id: 1,
    name: 'User 1',
  },
  {
    id: 2,
    name: 'User 2',
  },
];
const collection = _col(users).map(user => ({
  ...user,
  toJson: () => JSON.stringify(this),
})).toString();
// {"id":1,"name":"User 1"},{"id":2,"name":"User 2"}

_col().unique

The unique method returns all of the unique items in the collection.

const collection = _col([1, 2, 3, 4, 5, 1, 2]);
const unique = collection.unique();
console.log(unique); // [1, 2, 3, 4, 5]

If the item of the collection is an object, you should specify the key to be checked.

const collection = _col([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 1, name: 'John' }]);
const unique = collection.unique('id');
console.log(unique); // [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]

_col().when

The when method method will execute the given callback when the first argument given to the method evaluates to true. The collection instance and the first argument given to the when method will be provided to the callback.

const collection = _col([1, 2, 3, 4, 5]);
collection.when(true, (collection, value) => {
  return collection.push(6);
});
console.log(collection.all()); // [2, 4, 6, 8, 10]

Helper

const { Helper } = require('@noravel/supporter');

// OR

import { Helper } from '@noravel/supporter';

Helper.isset();
Helper.empty();
Helper.typeOf();
Helper.isJSON();
Helper.queryStringToObject();

isset

Determine if a variable is declared and is different than null. Except for undefined and null, everything will return true;

console.log(Helper.isset(undefined)); // false
console.log(Helper.isset(null)); // false

empty

Determine whether a variable is empty.

console.log(Helper.empty(undefined)); // true
console.log(Helper.empty(null)); // true
console.log(Helper.empty('')); // true
console.log(Helper.empty(false)); // true
console.log(Helper.empty(0)); // true
console.log(Helper.empty([])); // true
console.log(Helper.empty({})); // true
console.log(
  Helper.empty({
    items: [],
    count() {
      return this.items.length;
    },
  }),
); // true
console.log(
  Helper.empty({
    isEmpty() {
      return true;
    },
  }),
); // true

Some shared functions will be exported separately, you can call them directly to use them without going through Helper.

getArray

const { Collection, getArray } = require('@noravel/supporter');

console.log(getArray('Nam')); // ['Nam']
console.log(getArray(1)); // [1]
console.log(getArray(new Collection([1, 2 ,3]))); // [1, 2, 3]
console.log(getArray([1, 2 ,3])); // [1, 2, 3]
console.log(getArray({ toArray: () => [1, 2, 3] })); // [1, 2, 3]
console.log(getArray('[1,2,3]')); // [1, 2, 3]

typeOf

If you want to check the exact data type then typeOf will help you.

const { typeOf } = require('@noravel/supporter');

// OR

import { typeOf } from '@noravel/supporter';

What makes this function different from typeof is:

console.log(typeof []); // object
console.log(typeOf([])); // array

console.log(typeof null); // object
console.log(typeOf(null)); // null

function* inf() {
  let i = 1;
  while (true) {
    yield i;
    i++;
  }
}
console.log(typeof inf); // function
console.log(typeOf(inf)); // generatorfunction

isConstructor

const { isConstructor } = require('@noravel/supporter');

// OR

import { isConstructor } from '@noravel/supporter';
class Alien {
  sayHello() {
    return 'Hello';
  }
}
const Human = {
  sayHi() {
    return 'Hi';
  },
};

console.log(isConstructor(Alien)); // true
console.log(isConstructor(function () {})); // true
console.log(isConstructor(() => {})); // false
console.log(isConstructor(Human)); // false

isJSON

Check if a string value is json.

const { isJSON } = require('@noravel/supporter');

// OR

import { isJSON } from '@noravel/supporter';
console.log(isJSON('{}')); // true
console.log(isJSON('[]')); // true
console.log(isJSON('nam')); // false

queryStringToObject

Convert a query string to an object.

const { queryStringToObject } = require('@noravel/supporter');

// OR

import { queryStringToObject } from '@noravel/supporter';
console.log(queryStringToObject('?search[name]=Nam&sort_field=id&sort_direction=desc'));

// { search: { name: 'Nam' }, sort_field: 'id', sort_direction: 'desc' }