Skip to content

Commit 4a76d24

Browse files
authored
Merge pull request #62 from AthennaIO/develop
feat(config): add new methods and value decorator
2 parents c935918 + 9d8589c commit 4a76d24

File tree

13 files changed

+281
-10
lines changed

13 files changed

+281
-10
lines changed

.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,29 @@ jobs:
6767

6868
- name: Test code compilation
6969
run: sh scripts/build
70+
71+
cov-report:
72+
runs-on: ubuntu-latest
73+
steps:
74+
- uses: actions/checkout@v2
75+
with:
76+
fetch-depth: 0
77+
- name: Use Node.js 18.x
78+
uses: actions/setup-node@v1
79+
with:
80+
node-version: 18.x
81+
82+
- name: Install dependencies
83+
run: npm install
84+
85+
- name: Run tests
86+
run: npm run test:coverage
87+
88+
- name: Generate Code Coverage report
89+
id: code-coverage
90+
uses: barecheck/code-coverage-action@v1
91+
with:
92+
barecheck-github-app-token: ${{ secrets.BARECHECK_GITHUB_APP_TOKEN }}
93+
lcov-file: "./tests/Coverage/lcov.info"
94+
send-summary-comment: true
95+
show-annotations: "warning"

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@athenna/config",
3-
"version": "3.6.0",
3+
"version": "3.7.0",
44
"description": "Cache and handle environment variables and config files of Athenna.",
55
"license": "MIT",
66
"author": "João Lenon <lenon@athenna.io>",
@@ -81,6 +81,7 @@
8181
"exclude": [],
8282
"reporter": [
8383
"text-summary",
84+
"lcovonly",
8485
"html"
8586
],
8687
"report-dir": "./tests/Coverage",

src/Config/Config.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@
77
* file that was distributed with this source code.
88
*/
99

10-
import { sep, parse } from 'node:path'
10+
import {
11+
File,
12+
Json,
13+
Path,
14+
ObjectBuilder,
15+
Exec,
16+
Module,
17+
Is,
18+
} from '@athenna/common'
1119
import { loadFile, writeFile } from 'magicast'
12-
import { File, Json, Path, ObjectBuilder, Exec, Module } from '@athenna/common'
20+
import { sep, parse, extname } from 'node:path'
1321
import { RecursiveConfigException } from '#src/Exceptions/RecursiveConfigException'
1422
import { NotSupportedKeyException } from '#src/Exceptions/NotSupportedKeyException'
23+
import { NotValidArrayConfigException } from '#src/Exceptions/NotValidArrayConfigException'
1524

1625
export class Config {
1726
/**
@@ -111,6 +120,28 @@ export class Config {
111120
return this
112121
}
113122

123+
/**
124+
* Push a value to a configuration key that is a valid array.
125+
* If configuration is not an array, an exception will be thrown.
126+
*/
127+
public static push(key: string, value: any | any[]): typeof Config {
128+
const config = this.configs.get(key, [])
129+
130+
if (!Is.Array(config)) {
131+
throw new NotValidArrayConfigException(key)
132+
}
133+
134+
if (Is.Array(value)) {
135+
config.push(...value)
136+
} else {
137+
config.push(value)
138+
}
139+
140+
this.configs.set(key, config)
141+
142+
return this
143+
}
144+
114145
/**
115146
* Delete the configuration key.
116147
*/
@@ -168,6 +199,12 @@ export class Config {
168199
path = Path.config(),
169200
safe = false,
170201
): Promise<void> {
202+
if (extname(path)) {
203+
safe ? this.safeLoad(path) : this.load(path)
204+
205+
return
206+
}
207+
171208
const files = await Module.getAllJSFilesFrom(path)
172209

173210
this.fatherConfigPath = path

src/Decorators/Value.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* @athenna/config
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import 'reflect-metadata'
11+
12+
import { Is } from '@athenna/common'
13+
import { NotFoundConfigException } from '#src/Exceptions/NotFoundConfigException'
14+
15+
/**
16+
* Set the value of some configuration in your class property.
17+
*/
18+
export function Value(key: string, defaultValue?: any): PropertyDecorator {
19+
return (target: any, propKey: string | symbol) => {
20+
if (Is.Defined(defaultValue) || defaultValue === null) {
21+
Object.defineProperty(target, propKey, {
22+
value: Config.get(key, defaultValue),
23+
})
24+
25+
return
26+
}
27+
28+
if (!Config.exists(key)) {
29+
throw new NotFoundConfigException(key)
30+
}
31+
32+
Object.defineProperty(target, propKey, { value: Config.get(key) })
33+
}
34+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @athenna/config
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Exception } from '@athenna/common'
11+
12+
export class NotFoundConfigException extends Exception {
13+
public constructor(key: string) {
14+
super({
15+
status: 500,
16+
code: 'E_NOT_FOUND_CONFIG',
17+
message: `The configuration ${key} does not exist or the value is a hardcoded undefined.`,
18+
help: `To solve this problem you can set a default value when trying to get your configuration or setting a value to your ${key} configuration.`,
19+
})
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @athenna/config
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Exception } from '@athenna/common'
11+
12+
export class NotValidArrayConfigException extends Exception {
13+
public constructor(key: string) {
14+
super({
15+
status: 500,
16+
code: 'E_NOT_VALID_CONFIG_ARRAY',
17+
message: `The configuration ${key} is not a valid array, and it is not possible to push values to it.`,
18+
help: `Try changing your configuration key when calling push and pushAll methods or transform the value of your configuration ${key} to an array.`,
19+
})
20+
}
21+
}

tests/Stubs/classes/AppService.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Value } from '#src/Decorators/Value'
2+
3+
export class AppService {
4+
@Value('app')
5+
public app: any
6+
7+
@Value('app.name')
8+
public name: any
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Value } from '#src/Decorators/Value'
2+
3+
export class DoesNotThrowNotFound {
4+
@Value('app.notFound', null)
5+
public defined: any
6+
7+
@Value('app.notFoundApp', 'Athenna')
8+
public definedApp: any
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Value } from '#src/Decorators/Value'
2+
3+
export class ThrowNotFound {
4+
@Value('app.notFound')
5+
public app: any
6+
}

0 commit comments

Comments
 (0)