Commits
William Welling authored bc999d0b5f1
4 4 | |
5 5 | import { AppConfig } from './app-config.interface'; |
6 6 | import { Config } from './config.interface'; |
7 7 | import { DefaultAppConfig } from './default-app-config'; |
8 8 | import { ServerConfig } from './server-config.interface'; |
9 9 | import { mergeConfig } from './config.util'; |
10 10 | import { isNotEmpty } from '../app/shared/empty.util'; |
11 11 | |
12 12 | const CONFIG_PATH = join(process.cwd(), 'config'); |
13 13 | |
14 - | const APP_CONFIG_PATH = join(CONFIG_PATH, 'appConfig.json'); |
15 - | |
16 14 | type Environment = 'production' | 'development' | 'test'; |
17 15 | |
18 16 | const getBooleanFromString = (variable: string): boolean => { |
19 17 | return variable === 'true' || variable === '1'; |
20 18 | }; |
21 19 | |
22 20 | const getNumberFromString = (variable: string): number => { |
23 21 | return Number(variable); |
24 22 | }; |
25 23 | |
40 38 | default: |
41 39 | console.warn(`Unknown NODE_ENV ${process.env.NODE_ENV}. Defaulting to development`); |
42 40 | } |
43 41 | } |
44 42 | |
45 43 | return environment; |
46 44 | }; |
47 45 | |
48 46 | const getLocalConfigPath = (env: Environment) => { |
49 47 | // default to config/appConfig.json |
50 - | let localConfigPath = APP_CONFIG_PATH; |
48 + | let localConfigPath = join(CONFIG_PATH, 'appConfig.json'); |
51 49 | |
52 50 | // determine app config filename variations |
53 51 | let envVariations; |
54 52 | switch (env) { |
55 53 | case 'production': |
56 54 | envVariations = ['prod', 'production']; |
57 55 | break; |
58 56 | case 'test': |
59 57 | envVariations = ['test']; |
60 58 | break; |
61 59 | case 'development': |
62 60 | default: |
63 61 | envVariations = ['dev', 'development'] |
64 62 | } |
65 63 | |
66 64 | // check if any environment variations of app config exist |
67 65 | for (const envVariation of envVariations) { |
68 - | const altDistConfigPath = join(CONFIG_PATH, `appConfig.${envVariation}.json`); |
69 - | if (fs.existsSync(altDistConfigPath)) { |
70 - | localConfigPath = altDistConfigPath; |
66 + | const envLocalConfigPath = join(CONFIG_PATH, `appConfig.${envVariation}.json`); |
67 + | if (fs.existsSync(envLocalConfigPath)) { |
68 + | localConfigPath = envLocalConfigPath; |
71 69 | } |
72 70 | } |
73 71 | |
74 72 | return localConfigPath; |
75 73 | }; |
76 74 | |
77 75 | const overrideWithConfig = (config: Config, pathToConfig: string) => { |
78 76 | try { |
79 77 | console.log(`Overriding app config with ${pathToConfig}`); |
80 78 | const externalConfig = fs.readFileSync(pathToConfig, 'utf8'); |
99 97 | config[property] = getNumberFromString(process.env[variable]); |
100 98 | break; |
101 99 | case 'boolean': |
102 100 | config[property] = getBooleanFromString(process.env[variable]); |
103 101 | break; |
104 102 | case 'string': |
105 103 | config[property] = process.env[variable]; |
106 104 | default: |
107 105 | console.warn(`Unsupported environment variable type ${typeof innerConfig} ${variable}`); |
108 106 | } |
109 - | |
110 107 | } |
111 108 | } |
112 109 | } |
113 110 | } |
114 111 | }; |
115 112 | |
116 113 | const buildBaseUrl = (config: ServerConfig): void => { |
117 114 | config.baseUrl = [ |
118 115 | config.ssl ? 'https://' : 'http://', |
119 116 | config.host, |
120 117 | config.port && config.port !== 80 && config.port !== 443 ? `:${config.port}` : '', |
121 118 | config.nameSpace && config.nameSpace.startsWith('/') ? config.nameSpace : `/${config.nameSpace}` |
122 119 | ].join(''); |
123 120 | }; |
124 121 | |
122 + | /** |
123 + | * Build app config with the following chain of override. |
124 + | * |
125 + | * local config -> environment local config -> external config -> environment variable |
126 + | * |
127 + | * Optionally save to file. |
128 + | * |
129 + | * @param destConfigPath optional path to save config file |
130 + | * @returns app config |
131 + | */ |
125 132 | export const buildAppConfig = (destConfigPath?: string): AppConfig => { |
126 133 | // start with default app config |
127 134 | const appConfig: AppConfig = new DefaultAppConfig(); |
128 135 | |
129 136 | // determine which dist app config by environment |
130 137 | const env = getEnvironment(); |
131 138 | |
132 139 | switch (env) { |
133 140 | case 'production': |
134 141 | console.log(`Building ${colors.red.bold(`production`)} app config`); |
135 142 | break; |
136 143 | case 'test': |
137 144 | console.log(`Building ${colors.blue.bold(`test`)} app config`); |
138 145 | break; |
139 146 | default: |
140 147 | console.log(`Building ${colors.green.bold(`development`)} app config`); |
141 148 | } |
142 149 | |
143 150 | // override with dist config |
144 - | const distConfigPath = getLocalConfigPath(env); |
145 - | if (fs.existsSync(distConfigPath)) { |
146 - | overrideWithConfig(appConfig, distConfigPath); |
151 + | const localConfigPath = getLocalConfigPath(env); |
152 + | if (fs.existsSync(localConfigPath)) { |
153 + | overrideWithConfig(appConfig, localConfigPath); |
147 154 | } else { |
148 - | console.warn(`Unable to find dist config file at ${distConfigPath}`); |
155 + | console.warn(`Unable to find dist config file at ${localConfigPath}`); |
149 156 | } |
150 157 | |
151 158 | // override with external config if specified by environment variable `APP_CONFIG_PATH` |
152 159 | const externalConfigPath = process.env.APP_CONFIG_PATH; |
153 160 | if (isNotEmpty(externalConfigPath)) { |
154 161 | if (fs.existsSync(externalConfigPath)) { |
155 162 | overrideWithConfig(appConfig, externalConfigPath); |
156 163 | } else { |
157 164 | console.warn(`Unable to find external config file at ${externalConfigPath}`); |
158 165 | } |