Skip to content

Commit a73338d

Browse files
committed
fix: rebased to latest main
1 parent 903e443 commit a73338d

File tree

8 files changed

+272
-271
lines changed

8 files changed

+272
-271
lines changed

index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import yargs from 'yargs';
44
import { hideBin } from 'yargs/helpers';
55
import * as fs from 'fs';
66
import { configFile, setConfigFile, validate } from './src/config/file';
7-
import proxy from './src/proxy';
7+
import * as proxy from './src/proxy';
88
import service from './src/service';
99

1010
const argv = yargs(hideBin(process.argv))
@@ -28,7 +28,7 @@ const argv = yargs(hideBin(process.argv))
2828
.strict()
2929
.parseSync();
3030

31-
setConfigFile(argv.c as string || "");
31+
setConfigFile((argv.c as string) || '');
3232

3333
if (argv.v) {
3434
if (!fs.existsSync(configFile)) {

src/config/ConfigLoader.js

Lines changed: 102 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,29 @@ class ConfigLoader extends EventEmitter {
6565
if (!fs.existsSync(this.cacheDir)) {
6666
try {
6767
fs.mkdirSync(this.cacheDir, { recursive: true });
68+
console.log(`Created cache directory at ${this.cacheDir}`);
6869
return true;
6970
} catch (err) {
7071
console.error('Failed to create cache directory:', err);
7172
return false;
7273
}
7374
}
75+
console.log(`Using cache directory at ${this.cacheDir}`);
7476
return true;
7577
}
7678

7779
async start() {
7880
const { configurationSources } = this.config;
7981
if (!configurationSources?.enabled) {
82+
console.log('Configuration sources are disabled');
8083
return;
8184
}
8285

86+
console.log('Configuration sources are enabled');
87+
console.log(
88+
`Sources: ${JSON.stringify(configurationSources.sources.filter((s) => s.enabled).map((s) => s.type))}`,
89+
);
90+
8391
// Clear any existing interval before starting a new one
8492
if (this.reloadTimer) {
8593
clearInterval(this.reloadTimer);
@@ -88,6 +96,9 @@ class ConfigLoader extends EventEmitter {
8896

8997
// Start periodic reload if interval is set
9098
if (configurationSources.reloadIntervalSeconds > 0) {
99+
console.log(
100+
`Setting reload interval to ${configurationSources.reloadIntervalSeconds} seconds`,
101+
);
91102
this.reloadTimer = setInterval(
92103
() => this.reloadConfiguration(),
93104
configurationSources.reloadIntervalSeconds * 1000,
@@ -106,34 +117,63 @@ class ConfigLoader extends EventEmitter {
106117
}
107118

108119
async reloadConfiguration() {
109-
if (this.isReloading) return;
120+
if (this.isReloading) {
121+
console.log('Configuration reload already in progress, skipping');
122+
return;
123+
}
110124
this.isReloading = true;
125+
console.log('Starting configuration reload');
111126

112127
try {
113128
const { configurationSources } = this.config;
114-
if (!configurationSources?.enabled) return;
129+
if (!configurationSources?.enabled) {
130+
console.log('Configuration sources are disabled, skipping reload');
131+
return;
132+
}
133+
134+
const enabledSources = configurationSources.sources.filter((source) => source.enabled);
135+
console.log(`Found ${enabledSources.length} enabled configuration sources`);
115136

116137
const configs = await Promise.all(
117-
configurationSources.sources
118-
.filter((source) => source.enabled)
119-
.map((source) => this.loadFromSource(source)),
138+
enabledSources.map(async (source) => {
139+
try {
140+
console.log(`Loading configuration from ${source.type} source`);
141+
return await this.loadFromSource(source);
142+
} catch (error) {
143+
console.error(`Error loading from ${source.type} source:`, error.message);
144+
return null;
145+
}
146+
}),
120147
);
121148

149+
// Filter out null results from failed loads
150+
const validConfigs = configs.filter((config) => config !== null);
151+
152+
if (validConfigs.length === 0) {
153+
console.log('No valid configurations loaded from any source');
154+
return;
155+
}
156+
122157
// Use merge strategy based on configuration
123158
const shouldMerge = configurationSources.merge ?? true; // Default to true for backward compatibility
159+
console.log(`Using ${shouldMerge ? 'merge' : 'override'} strategy for configuration`);
160+
124161
const newConfig = shouldMerge
125-
? configs.reduce(
162+
? validConfigs.reduce(
126163
(acc, curr) => {
127164
return this.deepMerge(acc, curr);
128165
},
129166
{ ...this.config },
130167
)
131-
: { ...this.config, ...configs[configs.length - 1] }; // Use last config for override
168+
: { ...this.config, ...validConfigs[validConfigs.length - 1] }; // Use last config for override
132169

133170
// Emit change event if config changed
134171
if (JSON.stringify(newConfig) !== JSON.stringify(this.config)) {
172+
console.log('Configuration has changed, updating and emitting change event');
135173
this.config = newConfig;
136174
this.emit('configurationChanged', this.config);
175+
} else {
176+
console.log('Configuration has not changed, no update needed');
137177
}
138178
} catch (error) {
139179
console.error('Error reloading configuration:', error);
@@ -161,11 +201,13 @@ class ConfigLoader extends EventEmitter {
161201
if (!isValidPath(configPath)) {
162202
throw new Error('Invalid configuration file path');
163203
}
204+
console.log(`Loading configuration from file: ${configPath}`);
164205
const content = await fs.promises.readFile(configPath, 'utf8');
165206
return JSON.parse(content);
166207
}
167208

168209
async loadFromHttp(source) {
210+
console.log(`Loading configuration from HTTP: ${source.url}`);
169211
const headers = {
170212
...source.headers,
171213
...(source.auth?.type === 'bearer' ? { Authorization: `Bearer ${source.auth.token}` } : {}),
@@ -176,6 +218,8 @@ class ConfigLoader extends EventEmitter {
176218
}
177219

178220
async loadFromGit(source) {
221+
console.log(`Loading configuration from Git: ${source.repository}`);
222+
179223
// Validate inputs
180224
if (!source.repository || !isValidGitUrl(source.repository)) {
181225
throw new Error('Invalid repository URL format');
@@ -191,15 +235,25 @@ class ConfigLoader extends EventEmitter {
191235
if (!isValidPath(tempDir)) {
192236
throw new Error('Invalid temporary directory path');
193237
}
238+
239+
console.log(`Creating git cache directory at ${tempDir}`);
194240
await fs.promises.mkdir(tempDir, { recursive: true });
195241

196-
const repoDir = path.join(tempDir, Buffer.from(source.repository).toString('base64'));
242+
// Create a safe directory name from the repository URL
243+
const repoDirName = Buffer.from(source.repository)
244+
.toString('base64')
245+
.replace(/[^a-zA-Z0-9]/g, '_');
246+
const repoDir = path.join(tempDir, repoDirName);
247+
197248
if (!isValidPath(repoDir)) {
198249
throw new Error('Invalid repository directory path');
199250
}
200251

252+
console.log(`Using repository directory: ${repoDir}`);
253+
201254
// Clone or pull repository
202255
if (!fs.existsSync(repoDir)) {
256+
console.log(`Cloning repository ${source.repository} to ${repoDir}`);
203257
const execOptions = {
204258
cwd: process.cwd(),
205259
env: {
@@ -211,23 +265,57 @@ class ConfigLoader extends EventEmitter {
211265
: {}),
212266
},
213267
};
214-
await execFileAsync('git', ['clone', source.repository, repoDir], execOptions);
268+
269+
try {
270+
await execFileAsync('git', ['clone', source.repository, repoDir], execOptions);
271+
console.log('Repository cloned successfully');
272+
} catch (error) {
273+
console.error('Failed to clone repository:', error.message);
274+
throw new Error(`Failed to clone repository: ${error.message}`);
275+
}
215276
} else {
216-
await execFileAsync('git', ['pull'], { cwd: repoDir });
277+
console.log(`Pulling latest changes from ${source.repository}`);
278+
try {
279+
await execFileAsync('git', ['pull'], { cwd: repoDir });
280+
console.log('Repository pulled successfully');
281+
} catch (error) {
282+
console.error('Failed to pull repository:', error.message);
283+
throw new Error(`Failed to pull repository: ${error.message}`);
284+
}
217285
}
218286

219287
// Checkout specific branch if specified
220288
if (source.branch) {
221-
await execFileAsync('git', ['checkout', source.branch], { cwd: repoDir });
289+
console.log(`Checking out branch: ${source.branch}`);
290+
try {
291+
await execFileAsync('git', ['checkout', source.branch], { cwd: repoDir });
292+
console.log(`Branch ${source.branch} checked out successfully`);
293+
} catch (error) {
294+
console.error(`Failed to checkout branch ${source.branch}:`, error.message);
295+
throw new Error(`Failed to checkout branch ${source.branch}: ${error.message}`);
296+
}
222297
}
223298

224299
// Read and parse config file
225300
const configPath = path.join(repoDir, source.path);
226301
if (!isValidPath(configPath)) {
227302
throw new Error('Invalid configuration file path in repository');
228303
}
229-
const content = await fs.promises.readFile(configPath, 'utf8');
230-
return JSON.parse(content);
304+
305+
console.log(`Reading configuration file: ${configPath}`);
306+
if (!fs.existsSync(configPath)) {
307+
throw new Error(`Configuration file not found at ${configPath}`);
308+
}
309+
310+
try {
311+
const content = await fs.promises.readFile(configPath, 'utf8');
312+
const config = JSON.parse(content);
313+
console.log('Configuration loaded successfully from Git');
314+
return config;
315+
} catch (error) {
316+
console.error('Failed to read or parse configuration file:', error.message);
317+
throw new Error(`Failed to read or parse configuration file: ${error.message}`);
318+
}
231319
}
232320

233321
deepMerge(target, source) {
@@ -249,6 +337,7 @@ class ConfigLoader extends EventEmitter {
249337
}
250338
}
251339

340+
// Helper function to check if a value is an object
252341
function isObject(item) {
253342
return item && typeof item === 'object' && !Array.isArray(item);
254343
}

0 commit comments

Comments
 (0)