dotenvi
Advanced tools
Comparing version 0.0.0-development to 0.0.1
{ | ||
"name": "dotenvi", | ||
"version": "0.0.0-development", | ||
"author": "Ben Ross <bcr@alum.mit.edu>", | ||
"version": "0.0.1", | ||
"author": "Ben Ross", | ||
"license": "MIT", | ||
"homepage": "https://github.com/b3ross/dotenvi#readme", | ||
"bugs": { | ||
"url": "https://github.com/b3ross/dotenvi/issues" | ||
}, | ||
"scripts": { | ||
"release": "semantic-release pre && npm publish && semantic-release post" | ||
"precommit": "lint-staged", | ||
"release": "semantic-release" | ||
}, | ||
"bin": { | ||
"dotenvi": "dist/index.js" | ||
}, | ||
"dependencies": { | ||
@@ -20,2 +28,4 @@ "@types/argparse": "^1.0.33", | ||
"devDependencies": { | ||
"lint-staged": "^7.0.4", | ||
"prettier": "^1.12.0", | ||
"semantic-release": "^15.1.7", | ||
@@ -28,3 +38,19 @@ "semantic-release-cli": "^3.6.6", | ||
"url": "https://github.com/b3ross/dotenvi.git" | ||
}, | ||
"keywords": [ | ||
"dotenv", | ||
"yaml", | ||
"config", | ||
"environment" | ||
], | ||
"lint-staged": { | ||
"*.{ts,json}": [ | ||
"prettier --write", | ||
"git add" | ||
] | ||
}, | ||
"prettier": { | ||
"printWidth": 120, | ||
"singleQuote": true | ||
} | ||
} |
# dotenvi | ||
A simple library for generating dotenv files | ||
A library for generating dotenv files | ||
## Motivation | ||
The library `dotenv` is a simple, convenient mechanism to add configuration to your node application. With simplicity, however, comes drawbacks. Dotenvi (pronounced "dotenvee") attempts to address those drawbacks. | ||
Dotenvi defines all configuration at the root of your package in a yaml file called `env.yml`. | ||
Use dotenvi to generate a .env file that plays nicely with dotenv without having to hack on top of dotenv to get it to support your needs. | ||
## Installation | ||
``` | ||
yarn add --dev dotenvi | ||
``` | ||
## Usage | ||
Define your configuration in a yaml file at the root of your application: | ||
```yaml | ||
default_env: &default_env | ||
SERVICE_URL: ${cft:my-stack.ServiceURL} ## Reference to an AWS CFT stack output | ||
SOME_ENV_VARIABLE: ${env:SOME_ENV_VARIABLE} ## Reference to an external environment variable | ||
SOME_CONSTANT: SOME_CONSTANT | ||
development: | ||
<<: *default_env | ||
staging: | ||
<<: *default_env | ||
production: | ||
SOME_CONSTANT: OVERRIDE_FOR_PRODUCTION | ||
<<: *default_env | ||
``` | ||
Then, run `yarn dotenvi -s <stage>` to generate a `.env` file for the stage desired (e.g., development, staging, production, etc...). Use the generated `.env` file in your normal processes using [dotenv](https://github.com/motdotla/dotenv). | ||
Note that stages are not required in your yaml file - you can also define it without stages, in which case you should not specify a stage with the `-s` option when you run `dotenvi`. | ||
## Discussion | ||
The main design goals of dotenvi are as follows: | ||
1. Document ALL configuration for a project in a consistent and easy to find way. | ||
2. Allow for environment variable generation from outside sources (such as AWS CFT outputs or other environment variables). | ||
3. Allow for different "environments" or "stages". | ||
## Additional Notes | ||
I don't prescribe to the 12-factor application strategy that dotenv is based around, so please understand that this library may not completely follow that strategy. | ||
The reference syntax used in `env.yml` is inspired by [serverless](https://github.com/serverless/serverless). | ||
## Possible Future Work | ||
1. Support for user-defined resolvers (e.g., other than `cft` and `env`). | ||
2. Allow for `dotenvi` to replace `dotenv`, if desired, by skipping the `.env`-generation step. | ||
3. Support for references embedded within a configuration value (e.g., `foo-${env:BAR}` --> `foo-bar` if BAR=bar) | ||
4. Support recursive reference calls (e.g., `${env:${env:FOO}}`) |
@@ -0,1 +1,2 @@ | ||
#! /usr/bin/env node | ||
@@ -23,3 +24,5 @@ import * as yaml from 'js-yaml'; | ||
} catch (e) { | ||
throw new Error(`Could not get info for stack with name ${parsedArgument[0]} when parsing cft reference ${argument}: ${e}`); | ||
throw new Error( | ||
`Could not get info for stack with name ${parsedArgument[0]} when parsing cft reference ${argument}: ${e}` | ||
); | ||
} | ||
@@ -39,3 +42,3 @@ for (const output of stack.Stacks[0].Outputs) { | ||
} | ||
} | ||
}; | ||
@@ -47,5 +50,2 @@ const parser = new ArgumentParser(); | ||
}); | ||
parser.addArgument(['file'], { | ||
help: 'env.yml file' | ||
}); | ||
const args = parser.parseArgs(); | ||
@@ -62,9 +62,8 @@ | ||
try { | ||
// TODO Load external resolvers | ||
let document = yaml.safeLoad(fs.readFileSync(args.file, 'utf8')); | ||
let document = yaml.safeLoad(fs.readFileSync('./env.yml', 'utf8')); | ||
if (args.stage) { | ||
document = document[args.stage]; | ||
document = (document as any)[args.stage]; | ||
if (!document) { | ||
@@ -71,0 +70,0 @@ throw new Error(`Could not locate stage ${args.stage} in file ${args.file}`); |
@@ -11,3 +11,3 @@ import { ResolverMap } from './types'; | ||
const value = document[variable]; | ||
result[variable] = await this.parseValue(value); | ||
(result as any)[variable] = await this.parseValue(value); | ||
} | ||
@@ -14,0 +14,0 @@ return result; |
@@ -1,1 +0,1 @@ | ||
export type ResolverMap = { [name: string]: (arg: string) => Promise<string> }; | ||
export type ResolverMap = { [name: string]: (arg: string) => Promise<string> }; |
@@ -8,2 +8,3 @@ { | ||
"sourceMap": true, | ||
"outDir": "dist", | ||
"experimentalDecorators": true, | ||
@@ -10,0 +11,0 @@ "emitDecoratorMetadata": true, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
216010
12
120
63
5