|
1 | | -import {Inject, Injectable} from '@nestjs/common'; |
| 1 | +import { Inject, Injectable } from '@nestjs/common'; |
2 | 2 | import * as path from 'path'; |
3 | | -import {COMMANDER_PROGRAM, LOGGER} from '../constants'; |
4 | | -import {set, get, has, merge} from 'lodash'; |
| 3 | +import { COMMANDER_PROGRAM, LOGGER } from '../constants'; |
5 | 4 | import * as fs from 'fs-extra'; |
6 | 5 | import { Command } from 'commander'; |
7 | 6 |
|
@@ -45,29 +44,106 @@ export class ConfigService { |
45 | 44 | } |
46 | 45 |
|
47 | 46 | get<T = unknown>(path: string, defaultValue?: T): T { |
48 | | - return get(this.read(), path, defaultValue) |
| 47 | + const getPath = ( |
| 48 | + obj: Record<string, unknown> | unknown, |
| 49 | + keys: string[], |
| 50 | + ): unknown => { |
| 51 | + if (!obj || keys.length === 0) return obj; |
| 52 | + |
| 53 | + const [head, ...tail] = keys; |
| 54 | + |
| 55 | + if (tail.length === 0) { |
| 56 | + return obj[head]; |
| 57 | + } |
| 58 | + |
| 59 | + return getPath(obj[head], tail); |
| 60 | + }; |
| 61 | + |
| 62 | + const result = getPath(this.read(), path.split('.')) as T; |
| 63 | + return result !== undefined ? result : defaultValue; |
49 | 64 | } |
50 | 65 |
|
51 | | - has(path) { |
52 | | - return has(this.read(), path) |
| 66 | + has(path: string) { |
| 67 | + const hasPath = ( |
| 68 | + obj: Record<string, unknown> | unknown, |
| 69 | + keys: string[], |
| 70 | + ): boolean => { |
| 71 | + if (!obj || keys.length === 0) return false; |
| 72 | + |
| 73 | + const [head, ...tail] = keys; |
| 74 | + |
| 75 | + if (tail.length === 0) { |
| 76 | + return Object.prototype.hasOwnProperty.call(obj, head); |
| 77 | + } |
| 78 | + |
| 79 | + return hasPath(obj[head] as Record<string, unknown>, tail); |
| 80 | + }; |
| 81 | + |
| 82 | + return hasPath(this.read(), path.split('.')); |
53 | 83 | } |
54 | 84 |
|
55 | 85 | set(path: string, value: unknown) { |
56 | | - this.write(set(this.read(), path, value)) |
57 | | - return this |
| 86 | + const setPath = ( |
| 87 | + obj: object, |
| 88 | + keys: string[], |
| 89 | + val: unknown, |
| 90 | + ): object => { |
| 91 | + const [head, ...tail] = keys; |
| 92 | + |
| 93 | + if (tail.length === 0) { |
| 94 | + obj[head] = val; |
| 95 | + return obj; |
| 96 | + } |
| 97 | + |
| 98 | + if (!obj[head] || typeof obj[head] !== 'object') { |
| 99 | + obj[head] = {}; |
| 100 | + } |
| 101 | + |
| 102 | + setPath(obj[head] as Record<string, unknown>, tail, val); |
| 103 | + return obj; |
| 104 | + }; |
| 105 | + |
| 106 | + const config = this.read(); |
| 107 | + this.write(setPath(config, path.split('.'), value)); |
| 108 | + return this; |
58 | 109 | } |
59 | 110 |
|
60 | 111 | private read() { |
61 | | - fs.ensureFileSync(this.configFile) |
62 | | - |
63 | | - return merge( |
| 112 | + const deepMerge = ( |
| 113 | + target: object, |
| 114 | + source: object, |
| 115 | + ): object => { |
| 116 | + if (!source || typeof source !== 'object') return target; |
| 117 | + |
| 118 | + const result = { ...target }; |
| 119 | + |
| 120 | + for (const key in source) { |
| 121 | + if (Object.prototype.hasOwnProperty.call(source, key)) { |
| 122 | + if ( |
| 123 | + source[key] && |
| 124 | + typeof source[key] === 'object' && |
| 125 | + !Array.isArray(source[key]) |
| 126 | + ) { |
| 127 | + const value = (result[key] || {}); |
| 128 | + result[key] = deepMerge(value, source[key]); |
| 129 | + } else { |
| 130 | + result[key] = source[key]; |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | + |
| 135 | + return result; |
| 136 | + }; |
| 137 | + |
| 138 | + fs.ensureFileSync(this.configFile); |
| 139 | + |
| 140 | + return deepMerge( |
64 | 141 | this.defaultConfig, |
65 | | - fs.readJSONSync(this.configFile, {throws: false, encoding: 'utf8'}), |
66 | | - ) |
| 142 | + fs.readJSONSync(this.configFile, { throws: false, encoding: 'utf8' }), |
| 143 | + ); |
67 | 144 | } |
68 | 145 |
|
69 | 146 | private write(config) { |
70 | 147 | fs.writeJSONSync(this.configFile, config, {encoding: 'utf8', spaces: config.spaces || 2}) |
71 | 148 | } |
72 | | - |
73 | 149 | } |
0 commit comments