@x-fiber-sys/be-config 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # `be-config`
2
+
3
+ > TODO: description
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ const beConfig = require('be-config');
9
+
10
+ // TODO: DEMONSTRATE API
11
+ ```
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@x-fiber-sys/be-config",
3
+ "version": "0.1.0",
4
+ "description": "Service env configurations processing library",
5
+ "author": "pestsov-v <pestsov.js@gmail.com>",
6
+ "homepage": "https://github.com/pestsov-v/c-argo-back-mono#readme",
7
+ "license": "ISC",
8
+ "main": "src/index.ts",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/pestsov-v/c-argo-back-mono.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/pestsov-v/c-argo-back-mono/issues"
18
+ },
19
+ "dependencies": {
20
+ "dotenv": "^17.2.1",
21
+ "envalid": "^8.1.0"
22
+ }
23
+ }
package/src/config.ts ADDED
@@ -0,0 +1,149 @@
1
+ import 'dotenv/config'
2
+ import { num, str, bool, cleanEnv } from 'envalid'
3
+
4
+ import type { OptionalValidatorSpec, Spec } from 'envalid'
5
+
6
+ export type ConfigType = 'string' | 'boolean' | 'number'
7
+
8
+ export type ConfigEnvs = Record<string, ConfigType>
9
+ export type ConfigVal<T = ConfigType> = { type: T; specs?: Spec<unknown> }
10
+ export type ConfigObj<C extends ConfigEnvs> = { [K in keyof C]: ConfigVal<C[K]> }
11
+
12
+ export class Config<C extends Record<string, ConfigType> = Record<string, ConfigType>> {
13
+ private _config: Record<string, string | number | boolean>
14
+ private readonly _hotConfig: Record<string, string | number | boolean>
15
+
16
+ constructor() {
17
+ this._config = {}
18
+ this._hotConfig = {}
19
+ }
20
+
21
+ public async init(config: ConfigObj<C>): Promise<void> {
22
+ const specs: Record<string, Spec<unknown>> = {}
23
+
24
+ for (const key in config) {
25
+ const env = config[key]
26
+
27
+ switch (env.type) {
28
+ case 'string':
29
+ specs[key] = env.specs ? str(env.specs) : str()
30
+ break
31
+ case 'number':
32
+ specs[key] = env.specs ? num(env.specs) : num()
33
+ break
34
+ case 'boolean':
35
+ specs[key] = env.specs ? bool(env.specs as OptionalValidatorSpec<boolean>) : bool()
36
+ break
37
+ }
38
+ }
39
+
40
+ this._config = cleanEnv(process.env, specs)
41
+ }
42
+
43
+ public get hotConfig() {
44
+ return this._hotConfig
45
+ }
46
+
47
+ public get serviceVersion() {
48
+ return process.env.npm_package_version as string
49
+ }
50
+
51
+ public get nodeVersion() {
52
+ return process.env.NODE_VERSION as string
53
+ }
54
+
55
+ public get isDevelopment(): boolean {
56
+ return this._config.isDevelopment as boolean
57
+ }
58
+
59
+ public get isTest(): boolean {
60
+ return process.env.NODE_ENV === 'test'
61
+ }
62
+
63
+ public getString<V extends string, K extends keyof C = keyof C>(
64
+ key: K,
65
+ isRequired?: true,
66
+ devVal?: V,
67
+ ): V
68
+ public getString<V extends string, K extends keyof C = keyof C>(
69
+ key: K,
70
+ isRequired: boolean = true,
71
+ devVal?: string,
72
+ ): V | null {
73
+ const val = this._config[key as string]
74
+
75
+ if (!val) {
76
+ if (isRequired) {
77
+ throw new Error(`Key '${String(key)}' is required, but was not found.`)
78
+ }
79
+
80
+ return (devVal as V) || null
81
+ }
82
+
83
+ if (typeof val !== 'string') {
84
+ throw new Error(`Key '${String(key)}' is required, but was not found.`)
85
+ }
86
+
87
+ return val as V
88
+ }
89
+
90
+ public getBoolean<K extends keyof C = keyof C>(
91
+ key: K,
92
+ isRequired?: true,
93
+ devVal?: boolean,
94
+ ): boolean
95
+ public getBoolean<K extends keyof C = keyof C>(
96
+ key: K,
97
+ isRequired: boolean = true,
98
+ devVal?: boolean,
99
+ ): boolean | null {
100
+ const val = this._config[key as string]
101
+
102
+ if (val === undefined || val === null) {
103
+ if (isRequired) {
104
+ throw new Error(`Key '${String(key)}' is required, but was not found.`)
105
+ }
106
+
107
+ return devVal ?? null
108
+ }
109
+
110
+ if (typeof val !== 'boolean') {
111
+ throw new Error(`Key '${String(key)}' must be a boolean, but got '${typeof val}'.`)
112
+ }
113
+
114
+ return val
115
+ }
116
+
117
+ public getNumber<K extends keyof C>(
118
+ key: C[K] extends 'number' ? K : never,
119
+ isRequired?: true,
120
+ devVal?: number,
121
+ ): number
122
+ public getNumber<K extends keyof C>(
123
+ key: C[K] extends 'number' ? K : never,
124
+ isRequired: boolean = true,
125
+ devVal?: number,
126
+ ): number | null {
127
+ const val = this._config[key as string]
128
+
129
+ if (!val) {
130
+ if (isRequired) {
131
+ throw new Error(`Key '${String(key)}' is required, but was not found.`)
132
+ }
133
+
134
+ return devVal || null
135
+ }
136
+
137
+ if (typeof val !== 'number') {
138
+ throw new Error(`Key '${String(key)}' is required, but was not found.`)
139
+ }
140
+
141
+ return val
142
+ }
143
+
144
+ public async destroy() {
145
+ new Config()
146
+
147
+ this._config = {}
148
+ }
149
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './config'