Skip to content

Commit

Permalink
Initial v2 alpha release (#48)
Browse files Browse the repository at this point in the history
* v2 initial commit

* Add an example that uses TSyringe for dependency injection (#45)

* Add an example that uses tsyringe

* Update minimum node version to 18

* Remove lint step from ci workflow

* Update build command in ci workflow

* Prepare initial v2 alpha release (#47)

* Update for publishing
  • Loading branch information
iansu authored Dec 29, 2023
1 parent 743ce79 commit aa17307
Show file tree
Hide file tree
Showing 103 changed files with 4,184 additions and 13,524 deletions.
2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

3 changes: 0 additions & 3 deletions .eslintrc

This file was deleted.

25 changes: 6 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,18 @@ jobs:
timeout-minutes: 20
strategy:
matrix:
node: [10, 12, 14, 16]
node: [18, 20]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- name: Install
run: npm ci
run: |
npm i -g npm
npm ci --prefer-offline --omit=optional
- name: Format Check
run: npm run format:check
- name: Lint
run: npm run lint
- name: Build
run: npm run build
- name: Test
run: npm run test -- --coverage
- name: Codecov
uses: codecov/codecov-action@v1
with:
token: ${{secrets.CODECOV_TOKEN}}
- name: Coverage
uses: neofinancial/coverage-upload-action@v1
with:
coverageEndpoint: ${{secrets.COVERAGE_ENDPOINT}}
coverageToken: ${{secrets.COVERAGE_TOKEN}}
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
62 changes: 12 additions & 50 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
name: 'CodeQL'

on:
push:
branches: [ master ]
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
branches: [master]
schedule:
- cron: '40 2 * * 3'

Expand All @@ -32,40 +20,14 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
language: ['javascript']

steps:
- name: Checkout repository
uses: actions/checkout@v2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
- name: Checkout repository
uses: actions/checkout@v2
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12
18
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
build
coverage

package-lock.json
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"printWidth": 100,
"printWidth": 120,
"singleQuote": true
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Neo Financial Technologies Inc.
Copyright (c) 2019-2023 Neo Financial Technologies Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
165 changes: 14 additions & 151 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,162 +1,25 @@
# Config Dug

[![Build status](https://github.com/neofinancial/config-dug/workflows/CI/badge.svg)](https://github.com/neofinancial/config-dug/actions)
[![coverage](https://coverage.neotools.ca/api/badge/master/4C8hhW7NzS4PKdA9C3NqNM)](https://coverage.neotools.ca/coverage/neofinancial/config-dug)
[![codecov](https://codecov.io/gh/neofinancial/config-dug/branch/master/graph/badge.svg)](https://codecov.io/gh/neofinancial/config-dug)
![TypeScript 3.7.2](https://img.shields.io/badge/TypeScript-3.7.2-brightgreen.svg)
Config management library for Node.js with support for multiple environments, config files, environment variables and plugins

![Config Dug](https://github.com/neofinancial/config-dug/blob/master/config-dug.png)
![Config Dug logo](./config-dug.png)

Config loader with support for AWS Secrets Manager.
## Packages

## Usage
- [config-dug](./packages/config-dug): Config Dug core library

### Installation
### Plugins

| yarn | npm |
| --------------------- | ------------------------ |
| `yarn add config-dug` | `npm install config-dug` |
- [@config-dug/plugin-aws-secrets-manager](./packages/plugin-aws-secrets-manager): [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) plugin

### Create your config files
## Examples

`config-dug` looks in several places for your config, including config files in your project, environment variables and [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/). `config-dug` allows you to write your config files in either TypeScript or JavaScript. You are expected to export a default object from your config file:
- [@config-dug/script-cjs](./examples/script-cjs): CJS test script
- [@config-dug/script-cjs-ts](./examples/script-cjs-ts): TypeScript CJS test script
- [@config-dug/script-esm](./examples/script-esm): ESM test script
- [@config-dug/script-esm-ts](./examples/script-esm-ts): TypeScript ESM test script
- [@config-dug/service-esm-ts](./examples/service-esm-ts): TypeScript ESM test service

```ts
// config.default.ts
export default {
API_ENDPOINT: 'https://api.example.com/',
};
```
## License

```js
// config.default.js
module.exports = {
API_ENDPOINT: 'https://api.example.com/',
};
```

Environment specific config files are loaded based on the value of the `APP_ENV` or `NODE_ENV` environment variables. If `APP_ENV` is present it will take precedence over `NODE_ENV`.

Settings from these different sources are merged together into a single config object in the following order:

1. `config.default.{ts|js}`
1. `config.${APP_ENV|NODE_ENV}.{ts|js}`
1. `config.${APP_ENV|NODE_ENV}.local.{ts|js}`
1. `config.local.{ts|js}`
1. AWS Secrets Manager
1. Environment variables

By default your config files need to be placed in the root directory of your project. If you want to keep config files in a different directory see [Customizing Config Loading](#customizing-config-loading).

### Import config

Import `config-dug` anywhere in your code where you want to access your config. All of your settings are available on the imported object:

```ts
// app.ts
import config from 'config-dug';

console.log(config.API_ENDPOINT);
```

```js
// app.js
const config = require('config-dug').default;

console.log(config.API_ENDPOINT);
// https://api.example.com/
```

> :warning: You must use `require('config-dug').default` in JavaScript files. If you exclude `.default` Config Dug will not work.
### Environment Variables

`config-dug` will add all your environment variables to the `config` object. This can have unintended consequences if one of your config keys has the same name as an existing, unrelated environment variable.

> :warning: `config-dug` is only intended to be used on the server. Your server already has access to your full environment in `process.env`. If you use `config-dug` in server rendered client applications you risk exposing your server's environment to the client.
### Using AWS Secrets Manager

In order to use AWS Secrets Manager you have to add a `AWS_SECRETS_MANAGER_NAME` or `awsSecretsManagerName` setting to your config that specifies the names of the secrets to look up:

```ts
// config.default.ts
export default {
AWS_SECRETS_MANAGER_NAME: 'production/myapp/config',
API_ENDPOINT: 'https://api.example.com/',
};
```

If you need to read from multiple secret buckets, `AWS_SECRETS_MANAGER_NAMES` takes a comma separated list to allow connection to multiple secrets in AWS Secrets Manager. Each secret from the list is evaluated in order mean that if a specific key appears in two secrets the value will be overwritten by the last secret in the list.

```ts
// config.default.ts
export default {
AWS_SECRETS_MANAGER_NAMES: 'production/myapp/config,production/myapp/another-config',
API_ENDPOINT: 'https://api.example.com/',
};
```

In addition to specifying the secret name you can also provide a region using the `AWS_SECRETS_MANAGER_REGION` or `awsSecretsManagerRegion` setting. The connection timeout in milliseconds can also be specified using the `AWS_SECRETS_MANAGER_TIMEOUT` or `awsSecretsManagerTimeout` setting:

```ts

// config.default.ts
export default {
AWS_SECRETS_MANAGER_NAME: 'production/myapp/config',
AWS_SECRETS_MANAGER_REGION: 'us-west-2',
AWS_SECRETS_MANAGER_TIMEOUT: 2000
API_ENDPOINT: 'https://api.example.com'
};
```

The default region is `us-east-1` and the default connection timeout is `5000`ms.

Config Dug will warn if it detects invalid config values. Invalid values include:

- undefined
- null
- the string 'undefined'
- an empty string

This package uses the [aws-sdk](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/) internally. Refer to their documentation for information about [authentication](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html), configuring a default [region](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-region.html) and configuring [access control for AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access.html).

## Advanced

### Customizing Config Loading

If you want to load config files from a directory other than the project root you can import the `loadConfig` function and use it directly.

```ts
import { loadConfig } from 'config-dug';

loadConfig('config');
```

This will import your config files from the `config` directory. The path you specify must be relative to your project root.

### Debugging

`config-dug` uses the [debug](https://github.com/visionmedia/debug) library. To print debug messages for `config-dug` set `DEBUG=config-dug`.

## Contributing

### Running Tests

1. Fork this repo
1. Clone the forked repo
1. Install dependencies: `npm install` OR `npm i`
1. Run tests: `npm run test`

## Publishing

1. Update the version in `package.json`
1. Add a `CHANGELOG` entry
1. Commit your changes
1. Run `npm pack` to see what will be published then delete the `.tgz` file that was created
1. Run `npm publish`
1. Create a release on GitHub. Use the version as the tag and release name. For example for version `1.0.0` the tag and release name would be `v1.0.0`.

## Credits

This project was inspired by [config3](https://github.com/focusaurus/config3) and [config4](https://github.com/autolotto/config4).
MIT
9 changes: 9 additions & 0 deletions examples/script-cjs-ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# script-cjs-ts

TypeScript CJS test script for Config Dug

## Usage

- `npm start`: loads `config.development.js` which is a CJS file without issue
- `npm run start:staging`: loads `config.staging.mjs` and logs a warning since this is a CJS project
- `npm run start:production`: loads `config.production.cjs` without issue
3 changes: 3 additions & 0 deletions examples/script-cjs-ts/config.development.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
logLevel: 'debug',
};
3 changes: 3 additions & 0 deletions examples/script-cjs-ts/config.production.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
logLevel: 'debug',
};
3 changes: 3 additions & 0 deletions examples/script-cjs-ts/config.staging.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
logLevel: 'debug',
};
11 changes: 11 additions & 0 deletions examples/script-cjs-ts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ConfigDug, z } from 'config-dug';

const schema = {
logLevel: z.string().default('info'),
};

(async () => {
const config = await ConfigDug.getConfig(schema);

console.log('logLevel', config.logLevel);
})();
25 changes: 25 additions & 0 deletions examples/script-cjs-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@config-dug/script-cjs-ts",
"version": "1.0.0",
"description": "TypeScript CJS test script for Config Dug",
"author": "Ian Sutherland",
"license": "UNLICENSED",
"private": true,
"engines": {
"node": ">=18.0.0"
},
"scripts": {
"start": "DEBUG=config-dug* APP_ENV=development ts-node index.ts",
"start:staging": "DEBUG=config-dug* APP_ENV=staging ts-node index.ts",
"start:production": "DEBUG=config-dug* APP_ENV=production ts-node index.ts"
},
"dependencies": {
"config-dug": "^2.0.0-alpha.0"
},
"devDependencies": {
"@tsconfig/node18": "^1.0.3",
"@types/node": "^18.11.18",
"ts-node": "^10.9.1",
"typescript": "^4.9.4"
}
}
4 changes: 4 additions & 0 deletions examples/script-cjs-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "@tsconfig/node18",
"include": ["./**/*"]
}
9 changes: 9 additions & 0 deletions examples/script-cjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# script-cjs

CJS test script for Config Dug

## Usage

- `npm start`: loads `config.development.js` which is a CJS file without issue
- `npm run start:staging`: loads `config.staging.mjs` and logs a warning since this is a CJS project
- `npm run start:production`: loads `config.production.cjs` without issue
Loading

0 comments on commit aa17307

Please sign in to comment.