open-index/open-npm huggingface dataset:
npm package: @offirmo/deferred
Description: Implementation of the deferred pattern on top of a Promise
Author: Offirmo
Latest version: 4.0.1


<h1 align="center">
	Deferred promise pattern<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/deferred">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/deferred.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=1-stdlib%2Fdeferred">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=1-stdlib%2Fdeferred">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/deferred">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/deferred.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2022.svg">
</p>


## A simple, TypeScript typed implementation of the deferred pattern

This is seldom used but useful sometimes.

**Be sure to review your options** before using the deferred pattern over a simple promise.

Note: no dependencies!

### Usage
```typescript
import Deferred from '@offirmo/deferred'

const promise = new Deferred<T>()

// it's an unresolved promise, you can attach stuff
promise.then(console.log).catch(...)

// later:
promise.resolve(...)
promise.reject(new Error('Foo!'))
```

## Credits

Iterated from https://github.com/Microsoft/TypeScript/issues/15202#issuecomment-318900991
npm package: @offirmo/globalthis-ponyfill
Description: Ponyfill for globalThis
Author: Offirmo
Latest version: 4.0.0


<h1 align="center">
	globalThis ponyfill<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/public/offirmos_quality_seal.png" alt="Offirmo’s quality seal" width="333">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/globalthis-ponyfill">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/globalthis-ponyfill.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=1-stdlib%2Fglobalthis-ponyfill">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=1-stdlib%2Fglobalthis-ponyfill">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/globalthis-ponyfill">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/globalthis-ponyfill.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2022.svg">
</p>


This is a trivial TypeScript-compatible [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) [ponyfill](https://ponyfill.com/).
* very small minzipped size
* NO dependencies
* doesn't alter the environment ([ponyfill](https://ponyfill.com/))
* compatible with node & browser


## Usage
```js
import { getGlobalThis } from '@offirmo/globalthis-ponyfill'

// typed access
declare global {
	var foo: number
}
const globalThis = getGlobalThis()
globalThis.foo = 42

// untyped access
const globalThis = getGlobalThis<any>()
globalThis.bar = 42
```


## Rationale

* `globalThis` is a [TC-39 proposal](https://github.com/tc39/proposal-global)
 which is [already supported by Firefox and Chrome](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis).
* There are existing ponyfills/polyfills [out there](https://github.com/ljharb/globalThis), but they didn't work for me:
  * mine is much simpler: a single TS file of 6 meaningful lines
  * I needed TypeScript
  * a [ponyfill](https://ponyfill.com/) is better than a polyfill, it doesn't patch the environment.




## Credits

**YES** I had a look at [ljharb/globalThis](https://github.com/ljharb/globalThis) 's [implementation](https://github.com/ljharb/globalThis/blob/master/implementation.js) (MIT)
and started my implementation from it! Thanks a lot and all credits due!

About the proposed implementation here: https://mathiasbynens.be/notes/globalthis we can't use it: it creates a polyfill, not a ponyfill.
However I took a line from the "naive implementation".
npm package: @offirmo/practical-logger-core
Description: Common internal code for Offirmo’s practical logger
Author: Offirmo
Latest version: 3.1.0


<h1 align="center">
	Offirmo’s practical logger - Core (internal, reusable)<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/practical-logger-core">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/practical-logger-core.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=2-foundation%2Fpractical-logger-core">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=2-foundation%2Fpractical-logger-core">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/practical-logger-core">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/practical-logger-core.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2021.svg">
</p>

This is an **internal / technical** component of [Offirmo’s practical logger](https://practical-logger-js.netlify.app/).
* isomorphic code for node and browser
* TODO explain the interface pattern


## Usage

**This is most likely not what you are looking for!**

See the final implementations using this module:
* minimal no-op: [@offirmo/practical-logger-minimal-noop](https://www.npmjs.com/package/@offirmo/practical-logger-minimal-noop)
* browser: [@offirmo/practical-logger-browser](https://www.npmjs.com/package/@offirmo/practical-logger-browser)
* node: [@offirmo/practical-logger-node](https://www.npmjs.com/package/@offirmo/practical-loggernode)

**if you know what you are doing:**

While this module was made to be a component in a final logger sink,
it is a perfectly working logger
which will output JSON lines to stdout, corresponding to log lines,
in the same way [bunyan](https://github.com/trentm/node-bunyan) does.

```javascript
import { createLogger } from '@offirmo/practical-logger-core'

const logger = createLogger({ /* ... */ })

logger.verbose('foo', { bar: 42, baz: 33 })
```

Advanced usage:
```typescript
import { createLogger, LogPayload } from '@offirmo/practical-logger-core'

function sink(payload: LogPayload) {
    const {
        level,
        name,
        msg,
        time,
        err,
        details
    } = payload
    /* ... */
}

const logger = createLogger({ /* ... */ }, sink)

logger.verbose('foo', { bar: 42, baz: 33 })
```
npm package: @offirmo/practical-logger-interface
Description: TypeScript types for Offirmo’s practical logger (no code)
Author: Offirmo
Latest version: 1.1.1
Deprecated: WARNING: this has been renamed to @offirmo/practical-logger-types for clarity


<h1 align="center">
	Offirmo’s practical logger - TypeScript interfaces<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/practical-logger-interface">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/practical-logger-interface.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=1-foundation%2Fpractical-logger-interface">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=1-foundation%2Fpractical-logger-interface">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/practical-logger-interface">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/practical-logger-interface.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2019.svg">
</p>

This is an **internal** component of [Offirmo’s practical logger](https://github.com/Offirmo/offirmo-monorepo/wiki/Offirmo%E2%80%99s-Practical-Logger). 
* declares only TypeScript types/interfaces
* **No code, 0 bytes** = will do nothing to your bundle size.
* TODO explain the interface pattern


## Usage

**This is most likely not what you are looking for!**

See the actual implementations of those interfaces:
* minimal no-op: [@offirmo/practical-logger-minimal-noop](https://www.npmjs.com/package/@offirmo/practical-logger-minimal-noop)
* browser: [@offirmo/practical-logger-browser](https://www.npmjs.com/package/@offirmo/practical-logger-browser)
* node: TODO publish to npm

### Interface
A logger will have the following interface:
* `setLevel(level: LogLevel): void`
* `getLevel(): LogLevel`
* `addCommonDetails(hash: Readonly<{ [k: string]: any }>): void`
* Log primitives: (mirroring the log levels)
  * `fatal(message?: string, details?: Readonly<{ [k: string]: any }>): void`
  * `emerg(…) idem`
  * `alert(…) idem`
  * `crit(…) idem`
  * `error(…) idem`
  * `warning(…), warn(…) idem`
  * `notice(…) idem`
  * `info(…) idem`
  * `verbose(…) idem`
  * `log(…) idem`
  * `debug(…) idem`
  * `trace(…) idem`
  * `silly(…) idem`
* those functions may not do anything:
  * `group(groupTitle?: string): void` 
  * `groupCollapsed(groupTitle?: string): void`
  * `groupEnd(): void`


## Concept
Other loggers:
* http://getpino.io/#/docs/benchmarks
npm package: @offirmo/practical-logger-minimal-noop
Description: Implementation of Offirmo’s practical logger doing nothing at all
Author: Offirmo
Latest version: 3.0.1


<h1 align="center">
	Offirmo’s practical logger - <a href="https://en.wikipedia.org/wiki/NOP_(code)">no op</a> implementation<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/practical-logger-minimal-noop">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/practical-logger-minimal-noop.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=2-foundation%2Fpractical-logger-minimal-noop">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=2-foundation%2Fpractical-logger-minimal-noop">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/practical-logger-minimal-noop">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/practical-logger-minimal-noop.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2021.svg">
</p>

**This is a minimal, no-operation implementation of [Offirmo’s practical logger](https://practical-logger-js.netlify.app/).**

Use this lib if you want to provide a default implementation,
for example as a default value in a dependency injection mechanism,
ready to be replaced by an actual version if the caller wants it,
but not hurting the bundle size if the user opts out.

### API
Exact same API as `@offirmo/practical-logger-browser` and `@offirmo/practical-logger-node`:
```javascript
import { createLogger } from '@offirmo/practical-logger-minimal-noop'

const logger = createLogger()
logger.log('hello from logger!') // absolutely nothing happens, no-op
```
npm package: @offirmo/practical-logger-node
Description: node-specific practical logger
Author: Offirmo
Latest version: 0.3.0


<h1 align="center">
	Offirmo’s practical logger - node implementation<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/practical-logger-node">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/practical-logger-node.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=2-foundation%2Fpractical-logger-node">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=2-foundation%2Fpractical-logger-node">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/practical-logger-node">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/practical-logger-node.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2020.svg">
</p>

**This is a node implementation of [Offirmo’s practical logger](https://github.com/Offirmo/offirmo-monorepo/wiki/Offirmo%E2%80%99s-Practical-Logger).**

## Demo

![dark terminal demo](./doc/screen-term-dark-alt.png)


## Usage

```javascript
import { createLogger } from '@offirmo/practical-logger-node'

const logger = createLogger()
logger.log('hello from logger!')

const fooLogger = createLogger({
	name: 'Foo',
	suggestedLevel: 'silly',
})
fooLogger.log('hello from fooLogger!', { bar: 42, baz: 33 })
```

TODO explanation

TODO https://www.stefanjudis.com/today-i-learned/node-js-has-a-built-in-debug-method/
npm package: @offirmo/practical-logger-types
Description: TypeScript types for Offirmo’s practical logger (no code)
Author: Offirmo
Latest version: 3.0.1


<h1 align="center">
	Offirmo’s practical logger - TypeScript interfaces<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/practical-logger-types">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/practical-logger-types.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=2-foundation%2Fpractical-logger-types">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=2-foundation%2Fpractical-logger-types">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/practical-logger-types">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/practical-logger-types.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2021.svg">
</p>

This is an **internal** module of [Offirmo’s practical logger](https://practical-logger-js.netlify.app/).
* declares only TypeScript types
* **No code, 0 bytes** = will do nothing to your bundle size
* no dependencies


## Usage

**This is most likely not what you are looking for!**

See the actual implementations of those interfaces:
* minimal no-op: [@offirmo/practical-logger-minimal-noop](https://www.npmjs.com/package/@offirmo/practical-logger-minimal-noop)
* browser: [@offirmo/practical-logger-browser](https://www.npmjs.com/package/@offirmo/practical-logger-browser)
* node: [@offirmo/practical-logger-node](https://www.npmjs.com/package/@offirmo/practical-logger-node)

### Interface
A logger will have the following interface:
* `setLevel(level: LogLevel): void`
* `getLevel(): LogLevel`
* `addCommonDetails(hash: Readonly<{ [k: string]: any }>): void`
* Log primitives: (mirroring the log levels)
  * `fatal(message?: string, details?: Readonly<{ [k: string]: any }>): void`
  * `emerg(…) idem`
  * `alert(…) idem`
  * `crit(…) idem`
  * `error(…) idem`
  * `warning(…), warn(…) idem`
  * `notice(…) idem`
  * `info(…) idem`
  * `verbose(…) idem`
  * `log(…) idem`
  * `debug(…) idem`
  * `trace(…) idem`
  * `silly(…) idem`
* those functions are present for convenience but may not do anything (platform-dependent):
  * `group(groupTitle?: string): void`
  * `groupCollapsed(groupTitle?: string): void`
  * `groupEnd(): void`


## Concept
Other loggers:
* http://getpino.io/#/docs/benchmarks
* discovered later:  https://github.com/ianstormtaylor/browser-logger

## Credits
I had a look at bunyan's interface.
npm package: @offirmo/tiny-singleton
Description: Typescript simple singleton
Author: Offirmo
Latest version: 1.0.0


<h1 align="center">
	Tiny singleton<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/public/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/tiny-singleton">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/tiny-singleton.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=1-stdlib%2Ftiny-singleton">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=1-stdlib%2Ftiny-singleton">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/tiny-singleton">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/tiny-singleton.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2022.svg">
</p>


This is a trivial, isomorphic, straightforward, TypeScript-compatible [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) implementation:
* NO dependencies
* lazily created on first use, as expected

Typical usage is when one wants to share a common object, for ex. a connection to a database, yet is able to create it if not already existing.

This lib is NOT a memoization lib in the sense that in this lib, subsequent calls with different parameters (if any) will still yield the first invocation result.


**Be sure to review your options** before using the singleton pattern!
While there are legitimate uses, it can also be a code smell
close to a global variable!

**See also:**
* [memoize-one](https://github.com/alexreardon/memoize-one) if you simply want a single call


### Usage


```typescript
// "@offirmo/tiny-singleton": "^1",

import tiny_singleton from '@offirmo/tiny-singleton'

// underlying function: exemple of a DB client is a correct case where the singleton pattern can be useful
function create_db_client(ip: string, logger: Console = console): DBClient {
	return ...
}

// example 1: best semantic
const get_db_client = tiny_singleton(() => create_db_client('127.0.0.1'))
get_db_client().read(1234).then(...)

// example 2: with params (not recommended as the params will only affect the 1st call, but sometimes convenient)
const get_db_client = tiny_singleton(create_db_client)

// alternative (not better, just an alternative example)
const get_db_client = tiny_singleton((options?: CreationOptions) => create_db_client(options.ip || '127.0.0.1'))

// usage
get_db_client('127.0.0.1')
get_db_client('1.2.3.4') // XXX This will return the same as above!! No new instance creation.
get_db_client().write('hello').then(...)
```
npm package: @offirmo/unit-test-toolbox
Description: An aggregation of quality npm modules to be used for writing unit tests.
Author: Offirmo
Latest version: 9.0.0

# unit-test-toolbox
A convenient aggregation of quality npm modules to be used for writing unit tests.
Just install this module and you get everything needed at once!

This modules bundles:
* `mocha`
* `chai`
* `sinon`
* `sinon-chai`
* `chai-as-promised`
* `chai-subset`
* `chai-moment`
* (optional) `chai-fetch-mock`
* `eslint-plugin-mocha` and `eslint-plugin-chai-expect`
* all corresponding TypeScript types
* `@offirmo/universal-debug-api-node`

It also exposes:
- a pre-made plumbing for:
  - activating the `chai.expect` interface
  - activating correctly the chai plugins: `sinon-chai`, `chai-as-promised`, `chai-subset`, `chai-moment`, [`chai-fetch-mock` if present]
- a pre-made mocha options file


## Introduction - the problem
Writing unit tests in JavaScript with mocha/chai requires assembling a bunch of modules and repeating the same operations:

**:-1: WITHOUT @offirmo/unit-test-toolbox :-1: :hurtrealbad:**:
1. remembering all the libs needed
1. installing them: `npm install mocha chai sinon sinon-chai chai-as-promised chai-subset chai-moment`
1. if using typescript: `npm install @types/mocha @types/chai @types/sinon @types/sinon-chai @types/chai-as-promised`
1. write an init file for activating `chai.expect` (what else ?), `sinon-chai` and `chai-as-promised`
1. write the npm task `"test": "mocha --config mocharc.json path/to/init.js '<glob_to_my_tests/**/*spec.js>'"`
1. keep all those dependencies up-to-date

The proposed solution:

**:+1: WITH @offirmo/unit-test-toolbox :+1: :sunglasses:**:
1. install only one module `npm i -D @offirmo/unit-test-toolbox`
1. write this npm task `"test": "mocha --config node_modules/@offirmo/unit-test-toolbox/mocharc.json node_modules/@offirmo/unit-test-toolbox/mocha-chai-init-node.cjs '<glob_to_my_tests/**/*spec.js>'"`
1. keep just @offirmo/unit-test-toolbox up-to-date


## Installation & usage

### recent npm
Targeting npm >= 3 (for we abuse the flat deps)

```shell
npm i --save-dev @offirmo/unit-test-toolbox
```

If you want to use the pre-written init file, reference it in your `test` task:
```json
  "scripts": {
    "test": "mocha --opts node_modules/@offirmo/unit-test-toolbox/mocha.opts node_modules/@offirmo/unit-test-toolbox/mocha-chai-init.js 'test/unit/src/**/*spec.js'"
  },
```


## See also
* mocha
* chai
* sinon
* sinon-chai
* chai-as-promised
* chai-subset
* chai-moment https://www.npmjs.com/package/chai-moment


## Contributing
Suggestions welcome.
npm package: @offirmo/universal-debug-api-browser
Description: An implementation of the universal debug API for browsers
Author: Offirmo
Latest version: 1.0.1


<h1 align="center">
	Offirmo’s Universal Debug API - browser implementation<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/universal-debug-api-browser">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/universal-debug-api-browser.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=3-advanced--multi%2Funiversal-debug-api-browser">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=3-advanced--multi%2Funiversal-debug-api-browser">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/universal-debug-api-browser">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/universal-debug-api-browser.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2021.svg">
</p>

**This is the browser implementation of [Offirmo’s Universal Debug API](https://universal-debug-api-js.netlify.app/).**

## Usage

The Universal Debug API is exposed as expected:

```javascript
import {
	getLogger,
	overrideHook,
} from '@offirmo/universal-debug-api-browser'

const logger = getLogger({ name: 'foo', suggestedLevel: 'info' })
logger.silly('Hello')
logger.verbose('Hello')
logger.fatal('Hello')

const SERVER_URL = overrideHook('server-url', 'https://prod.dev')
logger.info('Server URL=', {SERVER_URL})
```

Specific to the browser version, overrides are set through local storage:

```
localStorage.setItem('🛠UDA.override.logger.foo.logLevel', '"verbose"')
localStorage.setItem('🛠UDA.override.server-url', '"https://prod.dev"')
// loglevel || ll => log level
// cohort || co => experiment cohort
// is has should was will => boolean
```

Don't forget that overrides accept only JSON!

Debug:
```
localStorage.setItem('🛠UDA.override.logger._UDA_internal.logLevel', '"silly"')
```

## Notes

> Why would I use a mechanism such as `overrideHook()` when I can simply read local storage?

Sure you can if your code is browser only.
The point of the Universal Debug API is to be isomorphic,
for shared code.

For ex. the same code running on node will get its overrides from ENV vars.
npm package: @offirmo/universal-debug-api-minimal-noop
Description: Implementation of Offirmo’s Universal Debug Api doing nothing at all
Author: Offirmo
Latest version: 0.1.1
Deprecated: renamed to @offirmo/universal-debug-api-placeholder


<h1 align="center">
	Offirmo’s Universal Debug API - no op implementation<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/universal-debug-api-minimal-noop">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/universal-debug-api-minimal-noop.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=2-advanced%2Funiversal-debug-api-minimal-noop">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=2-advanced%2Funiversal-debug-api-minimal-noop">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/universal-debug-api-minimal-noop">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/universal-debug-api-minimal-noop.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2019.svg">
</p>

**This is a minimal, no-operation implementation of [Offirmo’s Universal Debug API](https://github.com/Offirmo/offirmo-monorepo/wiki/Offirmo%E2%80%99s-Universal-Debug-Api).**

Isomorphic, for node and browser.

**In Chrome and Firefox, this no-op code can be magically hot-swapped with the companion [webextension](TODO)!**

See overall explanation: [Offirmo’s Universal Debug API](https://github.com/Offirmo/offirmo-monorepo/wiki/Offirmo%E2%80%99s-Universal-Debug-Api).


## Usage

Use this lib **to not bloat your webapp/npx bundle**. This no-op implementation will do nothing: display nothing, compute nothing.


```javascript
import { } from '@offirmo/universal-debug-api-minimal-noop'

TODO
```

Note: no bundled version provided, for this lib is targeted at lib authors, not end users.
npm package: @offirmo/universal-debug-api-node
Description: Implementation of Offirmo’s Universal Debug Api for node
Author: Offirmo
Latest version: 0.2.0


<h1 align="center">
	Offirmo’s Universal Debug API - node implementation<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/universal-debug-api-node">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/universal-debug-api-node.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=3-advanced--multi%2Funiversal-debug-api-node">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=3-advanced--multi%2Funiversal-debug-api-node">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/universal-debug-api-node">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/universal-debug-api-node.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2021.svg">
</p>

**This is the node implementation of [Offirmo’s Universal Debug API](https://universal-debug-api-js.netlify.app/).**

## Usage

The Universal Debug API is exposed as expected:

```javascript
import {
	getLogger,
	overrideHook,
} from '@offirmo/universal-debug-api-node'

const logger = getLogger({ name: 'foo', suggestedLevel: 'info' })
logger.silly('Hello')
logger.verbose('Hello')
logger.fatal('Hello')

const DB_URL = overrideHook('db-url', 'https://prod.dev')
logger.info('DB URL=', {DB_URL})
```

Specific to the node version, overrides are set through ENV vars:

```bash
UDA_OVERRIDE__LOGGER_FOO_LOGLEVEL=verbose \
UDA_OVERRIDE__DB_URL=localhost:1234 \
node ./doc/demo.js
```

Because ENV vars format is restricted, keys are automatically normalized:
1. to upper case
1. separators chars `-.⋄∙ꘌꓺː` are converted to '_'

Though overrides values accept JSON (correctly escaped),
as a convenience because escaping is hard in shell and text files,
numbers are auto-converted and non-JSON values are defaulted to strings:

```bash
UDA_OVERRIDE__LOGGER_FOO_LOGLEVEL=\"verbose\" \
## is equivalent to
UDA_OVERRIDE__LOGGER_FOO_LOGLEVEL=verbose \
```

## Notes

> Why would I use a mechanism such as `overrideHook()` when I can simply read ENV vars?

Sure you can if your code is node only.
The point of the Universal Debug API is to be isomorphic,
for shared code.

For ex. the same code running on a browser could get its overrides from local storage.
npm package: @offirmo/universal-debug-api-placeholder
Description: Implementation of Offirmo’s Universal Debug Api doing nothing at all, yielding to any other effective implementation
Author: Offirmo
Latest version: 1.0.1


<h1 align="center">
	Offirmo’s Universal Debug API - no op placeholder<br>
	<a href="https://www.offirmo.net/offirmo-monorepo/0-doc/modules-directory/index.html">
		<img src="https://www.offirmo.net/offirmo-monorepo/0-doc/quality-seal/offirmos_quality_seal.svg" alt="Offirmo’s quality seal">
	</a>
</h1>

<p align="center">
	<a alt="npm package page"
	  href="https://www.npmjs.com/package/@offirmo/universal-debug-api-placeholder">
		<img alt="npm badge"
		  src="https://img.shields.io/npm/v/@offirmo/universal-debug-api-placeholder.svg">
	</a>
	<a alt="dependencies analysis"
	  href="https://david-dm.org/offirmo/offirmo-monorepo?path=3-advanced--multi%2Funiversal-debug-api-placeholder">
		<img alt="dependencies badge"
		  src="https://img.shields.io/david/offirmo/offirmo-monorepo.svg?path=3-advanced--multi%2Funiversal-debug-api-placeholder">
	</a>
	<a alt="bundle size evaluation"
	  href="https://bundlephobia.com/result?p=@offirmo/universal-debug-api-placeholder">
		<img alt="bundle size badge"
		  src="https://img.shields.io/bundlephobia/minzip/@offirmo/universal-debug-api-placeholder.svg">
	</a>
	<a alt="license"
	  href="https://unlicense.org/">
		<img alt="license badge"
		  src="https://img.shields.io/badge/license-public_domain-brightgreen.svg">
	</a>
	<img alt="maintenance status badge"
	  src="https://img.shields.io/maintenance/yes/2021.svg">
</p>

**This is a minimal, no-operation implementation of [Offirmo’s Universal Debug API](https://universal-debug-api-js.netlify.app/).**

Isomorphic, for node and browser.

Does nothing, minimal code footprint. BUT will transparently yield to any other previously required/imported effective version such as [node](../universal-debug-api-node/README.md) or [browser](../universal-debug-api-browser/README.md).
**Pro tip: for browser, hot-swap this placeholder at run time with the [companion webextension](../../4-tools/universal-debug-api-companion-webextension/README.md)!**

See overall explanation: [Offirmo’s Universal Debug API](https://universal-debug-api-js.netlify.app/).


## Usage

Use this lib **to not bloat your module or webapp/lambda/npx bundle**.
This no-op implementation will do nothing = display nothing = compute nothing.

However, when an effective implementation is used (see above),
this module will silently and automatically forward the effective implementation
instead of its own no-op mock.

```javascript
import {
	getLogger,
	exposeInternal,
	overrideHook,
	addDebugCommand,
	globalThis, // exposed from sub-dependency for convenience
} from '@offirmo/universal-debug-api-placeholder'
```