# Omnibelt

![Build Status](https://github.com/Losant/omnibelt/actions/workflows/test.yml/badge.svg?branch=master) [![npm version](https://badge.fury.io/js/omnibelt.svg)](https://badge.fury.io/js/omnibelt)

A utility belt that normalizes and wraps [Ramda](https://ramdajs.com/) and [Lodash/FP](https://github.com/lodash/lodash/wiki/FP-Guide). In addition, some other "adjunct" methods are included that solve common patterns. The order of precedence is: Does it exist in `Ramda`? Does it exist in `Lodash/FP`? Then it must be custom (in `src/omnibelt`). That means that you can deconstruct methods from any of those three from the `omnibelt` exported object.

```js
const {
  merge, converge, toString,   // Ramda
  isNull, throttle, camelCase, // Lodash
  isPopulatedString,           // Omnibelt
} = require('omnibelt');
```

... I've only grouped them for demonstration purposes, please don't do that in your code.

## Test

```bash
yarn run test
```

## Usage

Deconstruction

```js
const { isPopulatedString, toLower } = require('omnibelt');
const foo = 'foo';

if (!isPopulatedString(foo)) {
  throw new Error('DANGER');
} else {
  return toLower(foo);
}
```

Namespaced - Use `O` by convention

```js
const O = require('omnibelt');
const foo = 'foo';

if (!O.isPopulatedString(foo)) {
  throw new Error('DANGER');
} else {
  return O.toLower(foo);
}
```

## Notes

- What is this `method :: Type -> Type` stuff? It's [Hindley-Milner Notation](https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html).
- Since most methods are straight from the source, refer to the [Ramda](http://ramdajs.com/docs/) and [Lodash/FP](https://github.com/lodash/lodash/wiki/FP-Guide) on their respective sites.
- Docs and examples for the `omnibelt` methods are collocated with the method's definition. When contributing a new function, please provide docs (and tests).

## Docs

[JSDoc definitions](https://github.com/jsdoc3/jsdoc) at the top of each of the `omnibelt` module functions should be kept up to date and are meant to describe the usage of each function in detail. From these doc comments, a documentation site is generated using the [Docdash](https://github.com/clenemt/docdash) template.

### Viewing

You can open the docs locally by running the following `npm` script on a mac. In general (and for non-mac machines), you can simply opening `docs/index.html` in a browser.

```bash
yarn run docs
```

You can also see documentation for the latest tag on the GitHub pages for this project.

[https://losant.github.io/omnibelt/](https://losant.github.io/omnibelt/)

#### Building

Docs should be generated when a new version is tagged and pushed. `Ramda` and `Lodash` docs are autogenerated as part of a `pre` build step and you shouldn't have to interface with manually updating which methods are being pulled in. Docs are committed to `docs` and are served as a GitHub page whenever `master` is updated.

```bash
yarn run docs:build
git add -A
git commit -m "Regenerated docs"
```

## Release

```bash
git co develop
git fetch
git pull
# Update `package.json` version
# Update `README` changelog, naming the latest version
yarn run docs:build
git add -A
git commit -m "version bump and doc regeneration"
git push
git checkout master
git merge develop
git release vX.X.X
```

## Changelog

Below should serve as an "upgrade guide" jumping off point as you are migrating projects to newer versions of this package. Ideally, interface changes will be called out specifically and one should not have to go sifting through git diffs to discern what changed.

- `4.1.0`
  - bumped ramda to `0.32.0`
  - bumped various dev dependencies
  - switch from yarn to pnpm
  - fixed issue with maintaining order in mapParallelLimitP
- `4.0.0`
  - moved from travis to github actions
  - bumped ramda to `0.30.1`
  - bumped various dev dependencies
  - drop support for node.js version 14 and 16.
- `3.1.2`
  - Added methods:
    - `debounceLeading`
    - `debounceTrailing`
- `3.1.1`
  - Added methods:
    - `size` (Lodash)
  - removed `@rjhilgefort/export-dir`.
  - updated index.js files to be destructured on import such as `import { size } from 'omnibelt'`.
- `3.1.0`
  - bumped .node-version to `18.16.0`
  - bumped ramda to `0.29.0` (note in this version of ramda they release a function called `isNotNil`, omnibelt has a `isNotNil` function already so that ramda function is not included in this library)
  - bumped various dev dependencies
- `3.0.0`
  - bumped .node-version to `16.17.1`
  - drop support for node versions, 10, 12, 13, and 15
  - bumped ramda version `0.28.0` (note in this version of ramda they release a function called `count`, omnibelt has a `count` function already so that ramda function is not included in this library)
  - bumped @losant/eslint-config-losant to `1.5.0`
  - bumped expect to `29.3.1`
  - bumped fs-extra `10.1.0`
  - bumped husky `8.0.2`
  - bumped jest `29.3.1`
  - bumped jsdoc `4.0.0`
  - bumped lint-staged `13.0.3`
  - added taffdb as a dev dependency for building the documentation
- `2.1.0`
  - `mapP` waits for all promises to complete and then throw the first error if found
  - `mapParallelLimitP` does not continue to run promises once a promise has errored
  - `resolveProps` waits for all promises to complete and then throws the first error if found
- `2.0.2`
  - bumped .node-version to `14.16.1`
  - bumped lodash to `4.17.21`
  - bumped @losant/eslint-config-losant to `1.4.3`
  - bumped handlebars to `4.7.7`
  - bumped husky `6.0.0`
  - bumped jest `26.6.3`
  - bumped lint-staged `11.0.0`
- `2.0.1`
  - Added `mapSerialP`
  - bumped .node-version to `14.15.0`
  - bumped expect to `26.6.2`
  - bumped jest to `26.6.2`
  - bumped lint-staged to `10.5.1`
- `2.0.0`
  - `ramda` bumped to `0.27.1`
  - `lodash` bumped to `4.17.20`
  - `@rjhilgefort/export-dir` bumped to `2.0.0`
  - dropped support for Node.js 8 and 9
  - various development dependencies updated
  - added Node.js 13, 14, and 15 to travis
- `1.3.3`
  - `ramda` bumped to `0.27.0`
  - `@rjhilgefort/export-dir` bumped to `1.1.3`
- `1.3.2`
  - `lodash` bumped to `4.17.15`
  - `string-format` bumped to `2.0.0`
  - various development dependencies updated
  - stack trace improvement for `timeoutP`
- `1.3.1`
  - Added methods:
    - `isPlainObject`
- `1.3.0`
  - Updating linting, fix various spelling and linting errors
  - `lodash` bumped to `4.17.11`
  - Ramda upgraded from 0.25.0 to 0.26.1
    - Removed internal implementation of thunkify, now comes from Ramda
    - Removed `evolveArray`, Ramda evolve now supports arrays with `evolve`
  - `stringify-object` bumped to `3.3.0`
  - Added methods:
    - `allSettledP`
    - `forEachSerialP`
    - `mapParallelLimitP`
  - Removed methods:
    - `evolveArray`
      - 0.26.0 Ramda `evolve` now supports arrays
- `1.2.0`
  - Repo renamed and open sourced!
  - `git remote set-url origin git@github.com:Losant/omnibelt.git`
  - `lodash` bumped to `4.17.10`
  - `string-format` bumped to `1.0.0`
  - Added methods:
    - `mapIndexed`
- `1.1.9`
  - Added methods:
    - `mapP`
  - Method name change:
    - `timeout` -> `timeoutP`
- `1.1.8`
  - Ability to generate a static documentation site that's hosted on GitHub pages.
- `1.1.7`
  - Added methods:
    - `ensureEndsWith`
- `1.1.6`
  - External changes:
    - `testHarness` and the like, no longer assume that `expect` is available in your environment through `jest`. Instead, you must pass `expect` in as a dependency. See [this issue](https://github.com/Losant/omnibelt/issues/40) for more info.
  - Internal changes:
    - linter update to `1.3.2`
    - tests for `equalsAny`
    - tests for `containsAll`
- `1.1.5`
  - Added methods:
    - `testHarness`
    - `testCases`
  - Internal changes:
    - Linter bumped and ran on project.
    - Tests for `evolveArray`.
- `1.1.4`
  - ⬆️ Ramda upgrade to `0.25.0`. Upgrade guide [here](https://github.com/ramda/ramda/issues/2319).
  - `tap` has been omitted from Ramda and implemented in this project to work around new version.
  - Added methods:
    - `toInteger` (Lodash)
  - Remove methods:
    - `testHarness`: Now is not exported as part of this library and is only used internally
  - Internal changes:
    - `test*` methods have been moved to `test/` and are only for internal use.
    - `testHarness` has been updated with a new interface. `testHarnessUnary` is still around for backwards compatibility.
    - `testCases` now exists to eliminate a common pattern when using `testHarness`.
- `1.1.3`
  - All internal Losant utilities now only require the specific function(s) they need from `ramda`/`lodash`.
  - The following methods are now pulled from Lodash instead of Ramda:
    - `forEach`: Note that `forEachObjIndexed` still comes from ramda (behaves as expected)
  - Removed methods:
    - `indexBy` from Ramda has been omitted in favor of `keyBy`
    - `parseInt` from Lodash has been omitted because it conflicts poorly with native
  - Added methods:
    - `dotPath`
    - `dotPathOr`
    - `eqDotPaths`
    - `eqDotPathsShallow`
    - `equalsShallow`
    - `toPlainObject` (Lodash)
    - `toNumber` (Lodash)
    - `mapFilter`
    - `filterMap`
    - `mapRejectNil`
    - `rejectNilMap`
    - `defer`
    - `noopAsync`
    - `resolveProps`
    - `timeout`
- `1.1.2`
  - Added methods:
    - `keyByWith`
- `1.1.1`
  - Added methods:
    - `sleep`
    - `round`
    - `within`
- `1.1.0`
  - All docs now collocated with implementations.
  - Added methods:
    - `clampPositive`
    - `count`
    - `intersectAny`
    - `upperCamelCase`
  - Removed methods:
    - `flattenShallow`
      - This is just `R.unnest` (though `flattenShallow` is a bit more semantic).
- `1.0.12`
  - `ramda` back down to `0.24.1`.
- `1.0.11`
  - Moved git repo from Bitbucket to GitHub, update your remotes!
    - `git remote set-url origin git@github.com:Losant/omnibelt.git`
  - Added methods:
    - `nonePass`
    - `eqPaths`
    - `ensureStartsWith`
    - `throttleLeading`
    - `throttleTrailing`
  - Moved methods:
    - `flip` now comes from `lodash/fp`
    - `throttle` is now "custom" and accepts 3 arguments (still curried)
    - `debounce` is now "custom" and accepts 3 arguments (still curried)
- `1.0.10`
  - Node and Yarn version less restrictive, allows anything newer.
  - Added methods:
    - `containsAny`
    - `isNotNil`
  - The following methods are now pulled from Lodash instead of Ramda:
    - `toString`
    - `toLower`
    - `toUpper`
    - `trim`
    - `split`
- `1.0.9`
  - Added methods:
    - `jsonParseSafe`
    - `thunkify`
    - `tryCatchSafe`
- `1.0.8`
  - `fpThrow` now accepts an `Error` object and will rethrow when passed.
- `1.0.7`
  - Converted to flat structure that exports all of the Lodash, Ramda, and custom methods that we're using.
  - New documentation standard introduced, but not fully converted to.
  - Dependency updates.
  - Added methods:
    - `allEqual`
    - `argsToObj`
    - `containsAll`
    - `defaultToStrict`
    - `ensureArray`
    - `equalsAny`
    - `evolveArray`
    - `flattenShallow`
    - `fpThrow`
    - `isNilOrEmpty`
    - `isNotEmpty`
    - `isNot`
    - `list`
    - `mergeSpec`
    - `propOrStrict`
    - `stringify`
    - `updateKeys`
    - `updateKeysWith`
    - `updateKeyPaths`
- `1.0.6`
  - Added methods:
    - `format`
    - `isPopulatedString`
    - `mergeWithArrays`
    - `replaceAll`
    - `stringToBoolean`
    - `trace`
  - `README.md` documentation can be found at the rood of the repo.
