<div align="center">

# africa

[![npm version](https://badge.fury.io/js/africa.svg)](https://www.npmjs.com/package/africa)
[![Build status](https://ci.appveyor.com/api/projects/status/h1wpe3s9gnqk68xe?svg=true)](https://ci.appveyor.com/project/bulbazaur/africa)
<a href="https://gitlab.com/artdeco/africa/-/commits/master">
  <img src="https://gitlab.com/artdeco/africa/badges/master/pipeline.svg" alt="Pipeline Badge">
</a>

</div>

<a href="https://www.npmjs.com/packages/africa">
  <img src="./africa.jpg" alt="Africa" />
</a>

`africa` is a _Node.JS_ package which simplifies reading from and writing to persistent configuration files in user's home directory. If a configuration exists, it will be read, and if not, the user will be presented with questions, after which the answers will be stored in the `.rc` file.

```sh
yarn add africa
```

## Table Of Contents

- [Table Of Contents](#table-of-contents)
- [API](#api)
- [`async africa(packageName, questions=, config=): !Object`](#async-africapackagename-stringquestions-_reloquentquestionsconfig-config-object)
  * [`Config`](#type-config)
- [Groups](#groups)
- [Copyright & License](#copyright--license)

<div align="center"><a href="#table-of-contents">
  <img src="/.documentary/section-breaks/0.svg?sanitize=true">
</a></div>

## API

The package is available by importing its default function:

```js
import africa from 'africa'
```

<div align="center"><a href="#table-of-contents">
  <img src="/.documentary/section-breaks/1.svg?sanitize=true">
</a></div>

## <code>async <ins>africa</ins>(</code><sub><br/>&nbsp;&nbsp;`packageName: string,`<br/>&nbsp;&nbsp;`questions=: !_reloquent.Questions,`<br/>&nbsp;&nbsp;`config=: !Config,`<br/></sub><code>): <i>!Object</i></code>
Read package configuration from the home directory, or ask questions with
readline interface to create a new configuration in `~/.${packageName}rc`.

 - <kbd><strong>packageName*</strong></kbd> <em>`string`</em>: The name of the package.
 - <kbd>questions</kbd> <em>`!_reloquent.Questions`</em> (optional): An object with questions to ask when config wasn't found.
 - <kbd>config</kbd> <em><code><a href="#type-config" title="The configuration object to configure additional functionality.">!Config</a></code></em> (optional): Configuration object.

Call `africa` asynchronously to read or create a new configuration. Questions should adhere to the [`reloquent`][2]'s interface.

__<a name="type-config">`Config`</a>__: The configuration object to configure additional functionality.


|       Name       |                   Type                   |                                                                                                            Description                                                                                                             |    Default     |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| force            | <em>boolean</em>                         | Ask questions and update the configuration file even if it already exists.                                                                                                                                                         | `false`        |
| homedir          | <em>string</em>                          | In which directory to save and search for configuration file.                                                                                                                                                                      | `os.homedir()` |
| questionsTimeout | <em>number</em>                          | How log to wait in ms before timing out. Will wait forever by default.                                                                                                                                                             | -              |
| local            | <em>boolean</em>                         | Whether to read a local config file in the current working directory rather than in the `HOMEDIR`. When initialising, the default values will be taken from the home config if it exists so that it is easy to extend `.rc` files. | `false`        |
| recursive        | <em>boolean</em>                         | **`paid`** Read all configurations up to the root one from the home directory, and merge them together.                                                                                                                            | `false`        |
| skipExisting     | <em>boolean</em>                         | **`paid`** When creating nested configs, skip writing values that are taken from parent RCs.                                                                                                                                       | `true`         |
| rcNameFunction   | <em>(packageName: string) => string</em> | Function used to generate the `.rc` name. Default: packageName =&gt; `.${packageName}rc`.                                                                                                                                          | -              |

```js
import africa from 'africa'
import { userInfo } from 'os'

(async () => {
  try {
    const config = await africa('africa', {
      name: {
        defaultValue: userInfo().username,
        text: 'user',
      },
    }, { force: true })
    console.log(config)
  } catch ({ stack }) {
    console.log(stack)
  }
})()
```

```sh
user: [zavr]
{ name: 'zavr' }
```

<div align="center"><a href="#table-of-contents">
  <img src="/.documentary/section-breaks/2.svg?sanitize=true">
</a></div>

## Groups

It's possible to ask questions in groups, such that answers will be received in a nested object. Only 1 level of nesting is supported at the moment. To group questions, import the _Group_ type and pass questions to it.

```js
import africa, { Group } from 'africa'

africa('test', {
  group: new Group({
    test: {
      text: 'hello',
    },
  }),
  nongroup: {
    text: 'your-name',
  },
}, { force: true, homedir: __dirname })
```

```
your-name: [name-doc] name-doc
hello: [world-doc] world-doc
```

```json
{
  "nongroup": "name-doc",
  "group": {
    "test": "world-doc"
  }
}
```

<div align="center"><a href="#table-of-contents">
  <img src="/.documentary/section-breaks/3.svg?sanitize=true">
</a></div>


## Copyright & License

Photo [Diana Robinson][3], 2017

GNU Affero General Public License v3.0

<table>
  <tr>
    <th>
      <a href="https://www.artd.eco">
        <img width="100" src="https://gitlab.com/uploads/-/system/group/avatar/7454762/artdeco.png"
          alt="Art Deco">
      </a>
    </th>
    <th>© <a href="https://www.artd.eco">Art Deco™</a>   2020</th>
    <th><a href="LICENSE"><img src=".documentary/agpl-3.0.svg" alt="AGPL-3.0"></a></th>
  </tr>
</table>

[2]: https://www.npmjs.com/package/reloquent
[3]: https://www.flickr.com/photos/dianasch/31316774424/in/photolist-PHmDYC-moFj48-Q4Aya5-63Gpiw-mLTkJi-VNKhAn-Rz3Mrh-62BZoA-5q9HuM-6cnt7G-5Jv17M-zn5DFn-5QA73Q-6xjraT-aqGVsL-odrGp-azaw9g-wJQZ9M-4nGawg-4rHcYe-atRxbW-5JYiwy-eki9WF-ahdLm5-aTm2jZ-bp9exn-9xL37X-NBPkZ9-38Exqu-69Wv9G-7yxhvg-8GsnfW-agEC2n-svkzJf-k1ihc6-pPd9Aj-5SuyNP-aAg4Gf-DAMWZ1-DHceLL-oCxZ7U-pQe8E4-y875RB-c21GHN-dNZXJ3-NJ5yVx-e663y6-e6bFDq-jYo6Sm-cem5Xu

<div align="center"><a href="#table-of-contents">
  <img src="/.documentary/section-breaks/-1.svg?sanitize=true">
</a></div>
