npm package: @incrediblez/confy-tee
Description: This is a default Runner for confy-tee.
Author: Incrediblez
Latest version: 0.0.2

# What is it?

This is a default Runner for confy-tee.

Used in `npx` calls, like 

```
npx -p @incrediblez/confy-tee.common -p @incrediblez/confy-tee run --env=./somewhere/.env --config=./somewhere/config.json
```

See [GIT Repo](https://bitbucket.org/incrediblez/config-ur-gator) for details

# Using with npx

Cool thing here is that you do not need to install any NPMs, configure any custom code, nothing.

You just run 1 "simple" command, and it gets the whole job done.

`npm@5+` is the only requirement here.

NPX will manage all the NPMs for you, as long as you congigure the call properly.

Semantics of a call:

```bash
npx [-p packagename] run [--env=envfile] [--config=configfile]
```

Where:

* `[-p packagename]` section:
    * Is required.
    * Should always include `-p @incrediblez/confy-tee`, as a **last package**.
    * Can repeat as many times as needed.
    * Should include npm packages for ALL plugins your config relies on.
* `[--env=envfile]` section:
    * Is optional.
    * If provided - points to `.env` formatted file (TODO: Find the name of that format, there's one...)
* `[--config=configfile]` section:
    * Is required.
    * Should point to the Config, created manually or programmatically. See below for instructions on those.

# Creating config manually

Top-level schema:
```
{
  "reads": [
    READ_PLUGINS_CONFIGS_OBJECTS
  ],
  "writes": [
    WRITE_PLUGINS_CONFIGS_OBJECTS
  ]
}
```

Readers schema:

* `name`
    * Unique name of the Setting, that needs to be processed.
    * Writers will lookup setting by that name (try to find the value, that Processor red for that Setting)
* `plugin`
    * String, representing plugin that should be used here.
    * Format: `PLUGIN_FOLDER/PLUGIN_CLASS_NAME`. F.e `Common.HardcodedStringReader`
* `settings`
    * Config, that is defined in your selected Plugin file.
    * Refer to the selected Plugin's `README.md` or `Plugins.ts` for details on which fields there are, and how to fill them in.
    * Can be `Object` or `String`.
* `skip`
    * Nullable field. Set that to `true` if you would like to skip that specific step from processing.

Example:
```
{
  "name": "SOME_SETTING",
  "plugin": "Common.HardcodedStringReader",
  "settings": "CONFIG_VALUE"
}
```

Writers schema:

* `name`
    * Unique name of the Setting, that needs to be processed.
    * Refers to the one of the `name`s in Readers (`reads`).
* `plugin`
    * String, representing plugin that should be used here.
    * Format: `PLUGIN_FOLDER/PLUGIN_CLASS_NAME`. F.e `Common.AppendEnvFileWriter`
* `settings`
    * Config, that is defined in your selected Plugin file.
    * Refer to the selected Plugin's `README.md` or `Plugins.ts` for details on which fields there are, and how to fill them in.
    * Can be `Object` or `String`.
* `write_name`
    * The name, under which this setting will be recorded at the Target system.
    * Nullable field. If not provided - `name` will be used instead.
* `skip`
    * Nullable field. Set that to `true` if you would like to skip that specific step from processing.

Example:
```
{
  "name": "SOME_SETTING",
  "write_name": "SECRETLY_SECRET",
  "plugin": "Common.AppendEnvFileWriter",
  "settings": "./.dev.env"
}
```

# Creating config programmatically

This option allows to get all the fancyness of TypeScript at your service. Like - strong typing, validations, and even JSDocs.

Once configs are created - you can

* Run them in `Processor` yourself. Just take a look at how it's done in `core/runner.ts`, or in the example below.
* Or export them to file (via f.e. `JSON.stringify(MY_STRONGLY_TYPED_CONFIG)`), and then run via `npx` (see above for example)


Small example of how-to do the Config programmatically:

```typescript
import  dotenv from "dotenv"

// Include types and desired Plugins

// Via files (mostly dev)
// import { Config, Processor } from "../config-ur-gator/types/types"
// import {
//   AppendEnvFileWriterConfig,
//   HardcodedStringReaderConfig
// } from "../config-ur-gator/plugins/Common/Plugins"

// Via npm
import { Config, Processor} from '@incrediblez/confy-tee.types'
import {
  AppendEnvFileWriterConfig,
  HardcodedStringReaderConfig
} from '@incrediblez/confy-tee.common'

// Season it with any plugins you would like to use.
// import { MyCustomPlugin } from 'confy-tee.mycustomplugin'

const env = dotenv.config().parsed

// Compose a custom settings by TS
const MY_STRONGLY_TYPED_CONFIG: Config = {
  reads: [],
  writes: []
}

// Reads
const readThingOne: HardcodedStringReaderConfig = {
  plugin: 'Common.HardcodedStringReader',
  name:'SETTING_ONE',
  settings: 'SETTING_{{SOMETHING_SOMETHING}}'
}
MY_STRONGLY_TYPED_CONFIG.reads.push(readThingOne)

// Writes
const writeThingOne: AppendEnvFileWriterConfig = {
  plugin: 'Common.AppendEnvFileWriter',
  name: 'SETTING_ONE',
  settings: './.dev.env',
}
MY_STRONGLY_TYPED_CONFIG.writes.push(writeThingOne)

// process em all!
const processor = new Processor(MY_STRONGLY_TYPED_CONFIG, env)

// Set that if you're using direct files import, not npm. path here is Relative to 'processor.ts' file.
// processor.dangerouslySetCustompathForPLuginsDuringDevelopment('../plugins')

// processor.ValidateConfigs()
// processor.DryRun()
processor.Execute()

```

# Environment, how to use it, and how it works?

Processor can work with plain `env` object (key-value pairs).


In `core/runner.ts` this is supplied via CLI parameter `--env`, and then red using `dotenv` into such object.

Then, when `env` object is available, and supplied to Processor, Processor will try to replace any placeholders it can find, in `config` object.

Placeholder mask is `{{SEARCHTERM}}`.

E.g.

* If in your `env` object you have something like `SETTING=VALUE`
* And in your config, one fo the fields have value `SOMETHING_SOMETHING_{{SETTING}}`
* Then processor will digest that into `SOMETHING_SOMETHING_VALUE` before running anything or usin ghte COnfig anyhow else.

Replacement is recursive, so you can use Terms in subfields on any level. As long as they're strings.


# Where's my Plugins, dude?

Looking for a Plugin? Take a look at `../plugins` in this repo.

# TechBits

```
# Run locally without any installations, and dependencies, using only plugins you need
npm_config_registry=http://localhost:4873 npx -p @incrediblez/confy-tee.common -p @incrediblez/confy-tee run --env=./config-ur-gator/.env --config=./config-ur-gator/config.json

# Local npm repo
docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio

# Connecting to local npm repo
npm adduser --registry http://localhost:4873/

# Installing from local npm repo
npm install @incrediblez/confy-tee.types@latest --registry http://localhost:4873

# Publish to local npm repo
npm run build && npm publish --registry http://localhost:4873/
```