@1matrix/config-loader 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 +352 -0
- package/dist/config-loader.d.ts +26 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +174 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/fetcher/file-cache-fetcher.d.ts +9 -0
- package/dist/fetcher/file-cache-fetcher.d.ts.map +1 -0
- package/dist/fetcher/file-cache-fetcher.js +80 -0
- package/dist/fetcher/file-cache-fetcher.js.map +1 -0
- package/dist/fetcher/github-fetcher.d.ts +14 -0
- package/dist/fetcher/github-fetcher.d.ts.map +1 -0
- package/dist/fetcher/github-fetcher.js +123 -0
- package/dist/fetcher/github-fetcher.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/poller/config-poller.d.ts +13 -0
- package/dist/poller/config-poller.d.ts.map +1 -0
- package/dist/poller/config-poller.js +48 -0
- package/dist/poller/config-poller.js.map +1 -0
- package/dist/types/index.d.ts +32 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/deep-get.d.ts +2 -0
- package/dist/utils/deep-get.d.ts.map +1 -0
- package/dist/utils/deep-get.js +18 -0
- package/dist/utils/deep-get.js.map +1 -0
- package/dist/utils/env-mapper.d.ts +7 -0
- package/dist/utils/env-mapper.d.ts.map +1 -0
- package/dist/utils/env-mapper.js +15 -0
- package/dist/utils/env-mapper.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +24 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/validator/default-schemas.d.ts +2 -0
- package/dist/validator/default-schemas.d.ts.map +1 -0
- package/dist/validator/default-schemas.js +46 -0
- package/dist/validator/default-schemas.js.map +1 -0
- package/dist/validator/schema-validator.d.ts +13 -0
- package/dist/validator/schema-validator.d.ts.map +1 -0
- package/dist/validator/schema-validator.js +52 -0
- package/dist/validator/schema-validator.js.map +1 -0
- package/dist/webhook/signature-validator.d.ts +6 -0
- package/dist/webhook/signature-validator.d.ts.map +1 -0
- package/dist/webhook/signature-validator.js +64 -0
- package/dist/webhook/signature-validator.js.map +1 -0
- package/dist/webhook/webhook-handler.d.ts +11 -0
- package/dist/webhook/webhook-handler.d.ts.map +1 -0
- package/dist/webhook/webhook-handler.js +60 -0
- package/dist/webhook/webhook-handler.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# @onematrix/config-loader
|
|
2
|
+
|
|
3
|
+
Hot-reloadable public configuration management for Web3 applications with GitHub webhook integration.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Hot Reloading**: Automatically update configurations without restarting your application
|
|
8
|
+
- ✅ **GitHub Integration**: Fetch configurations from a dedicated GitHub repository
|
|
9
|
+
- ✅ **Webhook Support**: Real-time updates via GitHub webhooks
|
|
10
|
+
- ✅ **Polling Backup**: Periodic polling as a fallback mechanism
|
|
11
|
+
- ✅ **Schema Validation**: JSON Schema validation for all configurations
|
|
12
|
+
- ✅ **Environment Support**: Map NODE_ENV to different configuration directories
|
|
13
|
+
- ✅ **Fail-safe Caching**: Local cache fallback when GitHub is unavailable
|
|
14
|
+
- ✅ **TypeScript**: Full TypeScript support with type definitions
|
|
15
|
+
- ✅ **Event-Driven**: Listen to configuration changes with EventEmitter
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @onematrix/config-loader
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Initialize ConfigLoader
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { ConfigLoader } from '@onematrix/config-loader';
|
|
29
|
+
|
|
30
|
+
const config = new ConfigLoader({
|
|
31
|
+
repository: 'OneMatrixL1/public-configs',
|
|
32
|
+
branch: 'main',
|
|
33
|
+
githubToken: process.env.GITHUB_TOKEN,
|
|
34
|
+
webhookSecret: process.env.GITHUB_WEBHOOK_SECRET,
|
|
35
|
+
cacheFile: './config-cache.json',
|
|
36
|
+
pollingInterval: 5 * 60 * 1000 // 5 minutes
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
await config.initialize();
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Access Configuration
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// Get specific value
|
|
46
|
+
const apiKeyName = config.get('api-keys.a129f786...');
|
|
47
|
+
|
|
48
|
+
// Get with type inference
|
|
49
|
+
const handlers = config.get<string[]>('intent-handlers', []);
|
|
50
|
+
|
|
51
|
+
// Check if exists
|
|
52
|
+
if (config.has('api-keys.some-hash')) {
|
|
53
|
+
// ...
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Get all configs
|
|
57
|
+
const allConfigs = config.getAll();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Listen to Updates
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// Listen to all updates
|
|
64
|
+
config.on('update', (newConfigs, changedKeys) => {
|
|
65
|
+
console.log('Updated configs:', changedKeys);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Listen to specific config updates
|
|
69
|
+
config.on('update:api-keys', (newApiKeys) => {
|
|
70
|
+
console.log('API keys changed');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Listen to validation errors
|
|
74
|
+
config.on('validation-error', (configName, errors) => {
|
|
75
|
+
console.error('Validation failed:', configName, errors);
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 4. Set Up Webhook (Express)
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import express from 'express';
|
|
83
|
+
|
|
84
|
+
const app = express();
|
|
85
|
+
|
|
86
|
+
app.post(
|
|
87
|
+
'/webhook/config-update',
|
|
88
|
+
express.json(),
|
|
89
|
+
config.createWebhookHandler({
|
|
90
|
+
onUpdate: (configs) => console.log('Updated via webhook'),
|
|
91
|
+
onError: (err) => console.error(err)
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Configuration Repository Structure
|
|
97
|
+
|
|
98
|
+
Your GitHub configuration repository should follow this structure:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
public-configs/
|
|
102
|
+
├── schemas/
|
|
103
|
+
│ ├── api-keys.schema.json
|
|
104
|
+
│ ├── roles.schema.json
|
|
105
|
+
│ └── intent-handlers.schema.json
|
|
106
|
+
├── dev/
|
|
107
|
+
│ ├── api-keys.json
|
|
108
|
+
│ ├── roles.json
|
|
109
|
+
│ └── intent-handlers.json
|
|
110
|
+
├── staging/
|
|
111
|
+
│ └── ...
|
|
112
|
+
└── prod/
|
|
113
|
+
└── ...
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Example Configurations
|
|
117
|
+
|
|
118
|
+
**`dev/api-keys.json`**
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"a129f7860d47c0630e6d06c153fe36711f25a31bfb4304dc6d2a79e609da0e96": "VNIDC",
|
|
122
|
+
"b234c8971e58d1741f7e17d264gf47822g36b42cgc5415ed7e3b8a710eb1fa07": "SERVICE_2"
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**`dev/roles.json`**
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"explorer.viewer": [
|
|
130
|
+
"0xE61383556642AF1Bd7c5756b13f19A63Dc8601df",
|
|
131
|
+
"0x7d5538fEe2CE89dA936ec29cC48386b6E7548FaB"
|
|
132
|
+
],
|
|
133
|
+
"admin": [
|
|
134
|
+
"0x194f5b1755562966302Ef0BbF4349c842c60FC42"
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**`dev/intent-handlers.json`**
|
|
140
|
+
```json
|
|
141
|
+
[
|
|
142
|
+
"0x84f915BcbD5C1134BCb93a0f50D9D36E6D3b508c",
|
|
143
|
+
"0x626b1E2458A9307E73A570c291bCd467216cc1D7"
|
|
144
|
+
]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Example Schemas
|
|
148
|
+
|
|
149
|
+
**`schemas/api-keys.schema.json`**
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
153
|
+
"type": "object",
|
|
154
|
+
"patternProperties": {
|
|
155
|
+
"^[a-f0-9]{64}$": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"minLength": 1
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"additionalProperties": false
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API Reference
|
|
165
|
+
|
|
166
|
+
### ConfigLoader Options
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
interface ConfigLoaderOptions {
|
|
170
|
+
repository: string; // GitHub repository (owner/repo)
|
|
171
|
+
branch: string; // Branch to fetch from
|
|
172
|
+
githubToken?: string; // GitHub personal access token
|
|
173
|
+
webhookSecret?: string; // GitHub webhook secret
|
|
174
|
+
envMappings?: Record<string, string>; // NODE_ENV to directory mappings
|
|
175
|
+
defaultEnv?: string; // Default environment (default: 'dev')
|
|
176
|
+
pollingInterval?: number; // Polling interval in ms (default: 300000)
|
|
177
|
+
cacheFile?: string; // Cache file path (default: './config-cache.json')
|
|
178
|
+
usePackageSchemas?: boolean; // Use built-in schemas (default: true)
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Methods
|
|
183
|
+
|
|
184
|
+
#### `async initialize(): Promise<void>`
|
|
185
|
+
Initialize the config loader. Attempts to load from GitHub, falls back to cache if unavailable.
|
|
186
|
+
|
|
187
|
+
#### `async refresh(): Promise<void>`
|
|
188
|
+
Manually refresh configurations from GitHub.
|
|
189
|
+
|
|
190
|
+
#### `get<T>(path: string, defaultValue?: T): T | undefined`
|
|
191
|
+
Get a configuration value by dot-notation path.
|
|
192
|
+
|
|
193
|
+
#### `has(path: string): boolean`
|
|
194
|
+
Check if a configuration path exists.
|
|
195
|
+
|
|
196
|
+
#### `getAll(): Record<string, any>`
|
|
197
|
+
Get all configurations.
|
|
198
|
+
|
|
199
|
+
#### `getCurrentEnvironment(): string`
|
|
200
|
+
Get the current environment name.
|
|
201
|
+
|
|
202
|
+
#### `getConfigNames(): string[]`
|
|
203
|
+
Get names of all loaded configurations.
|
|
204
|
+
|
|
205
|
+
#### `createWebhookHandler(options?: WebhookHandlerOptions): ExpressMiddleware`
|
|
206
|
+
Create an Express middleware for handling GitHub webhooks.
|
|
207
|
+
|
|
208
|
+
#### `destroy(): void`
|
|
209
|
+
Clean up resources (stop polling, remove listeners).
|
|
210
|
+
|
|
211
|
+
### Events
|
|
212
|
+
|
|
213
|
+
#### `'update'`
|
|
214
|
+
Emitted when configurations are updated.
|
|
215
|
+
```typescript
|
|
216
|
+
config.on('update', (newConfigs: Record<string, any>, changedKeys: string[]) => {
|
|
217
|
+
// Handle update
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### `'update:${configName}'`
|
|
222
|
+
Emitted when a specific configuration is updated.
|
|
223
|
+
```typescript
|
|
224
|
+
config.on('update:api-keys', (newApiKeys: any) => {
|
|
225
|
+
// Handle API keys update
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### `'validation-error'`
|
|
230
|
+
Emitted when configuration validation fails.
|
|
231
|
+
```typescript
|
|
232
|
+
config.on('validation-error', (configName: string, errors: any[]) => {
|
|
233
|
+
// Handle validation error
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### `'error'`
|
|
238
|
+
Emitted when an error occurs.
|
|
239
|
+
```typescript
|
|
240
|
+
config.on('error', (error: Error) => {
|
|
241
|
+
// Handle error
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## GitHub Webhook Setup
|
|
246
|
+
|
|
247
|
+
### 1. Create Webhook in GitHub Repository
|
|
248
|
+
|
|
249
|
+
1. Go to your config repository → Settings → Webhooks → Add webhook
|
|
250
|
+
2. Payload URL: `https://your-app.com/webhook/config-update`
|
|
251
|
+
3. Content type: `application/json`
|
|
252
|
+
4. Secret: Generate a strong random secret
|
|
253
|
+
5. Events: Select "Just the push event"
|
|
254
|
+
6. Active: ✅
|
|
255
|
+
|
|
256
|
+
### 2. Configure Branch Protection
|
|
257
|
+
|
|
258
|
+
Ensure only authorized users can update configs:
|
|
259
|
+
|
|
260
|
+
1. Go to Settings → Branches → Add rule
|
|
261
|
+
2. Branch name pattern: `main`
|
|
262
|
+
3. Enable:
|
|
263
|
+
- Require pull request reviews (at least 1 approval)
|
|
264
|
+
- Require status checks before merging
|
|
265
|
+
- Restrict push access to admins
|
|
266
|
+
|
|
267
|
+
### 3. Set Environment Variables
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
GITHUB_TOKEN=ghp_your_personal_access_token
|
|
271
|
+
GITHUB_WEBHOOK_SECRET=your_webhook_secret
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Environment Mapping
|
|
275
|
+
|
|
276
|
+
Map `NODE_ENV` values to configuration directories:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
const config = new ConfigLoader({
|
|
280
|
+
// ...
|
|
281
|
+
envMappings: {
|
|
282
|
+
'dev': 'dev',
|
|
283
|
+
'development': 'dev',
|
|
284
|
+
'develop': 'develop',
|
|
285
|
+
'stg': 'stg',
|
|
286
|
+
'staging': 'staging',
|
|
287
|
+
'prod': 'prod',
|
|
288
|
+
'production': 'production'
|
|
289
|
+
},
|
|
290
|
+
defaultEnv: 'dev'
|
|
291
|
+
});
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Security Best Practices
|
|
295
|
+
|
|
296
|
+
### ✅ DO
|
|
297
|
+
|
|
298
|
+
- Store only hashed/public data in configurations (e.g., Keccak256 hashes)
|
|
299
|
+
- Use environment variables for webhook secrets and GitHub tokens
|
|
300
|
+
- Enable branch protection on configuration repository
|
|
301
|
+
- Monitor `validation-error` events for malicious payloads
|
|
302
|
+
- Set up alerts for repeated webhook validation failures
|
|
303
|
+
|
|
304
|
+
### ❌ DON'T
|
|
305
|
+
|
|
306
|
+
- Store raw API keys or passwords in configuration files
|
|
307
|
+
- Expose webhook endpoints without signature validation
|
|
308
|
+
- Allow direct pushes to main branch (require PRs)
|
|
309
|
+
- Disable schema validation
|
|
310
|
+
- Use weak webhook secrets
|
|
311
|
+
|
|
312
|
+
## Testing
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
# Run tests
|
|
316
|
+
pnpm test
|
|
317
|
+
|
|
318
|
+
# Run tests in watch mode
|
|
319
|
+
pnpm test:watch
|
|
320
|
+
|
|
321
|
+
# Run tests with coverage
|
|
322
|
+
pnpm test:coverage
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Building
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# Build TypeScript to JavaScript
|
|
329
|
+
pnpm build
|
|
330
|
+
|
|
331
|
+
# Build and watch for changes
|
|
332
|
+
pnpm build:watch
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Examples
|
|
336
|
+
|
|
337
|
+
See the `examples/` directory for complete examples:
|
|
338
|
+
|
|
339
|
+
- `basic-usage.ts`: Simple configuration loading
|
|
340
|
+
- `express-integration.ts`: Full Express.js integration with webhooks
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
MIT
|
|
345
|
+
|
|
346
|
+
## Contributing
|
|
347
|
+
|
|
348
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
349
|
+
|
|
350
|
+
## Support
|
|
351
|
+
|
|
352
|
+
For issues and questions, please open an issue on GitHub.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { ConfigLoaderOptions, WebhookHandlerOptions, ExpressMiddleware } from './types';
|
|
3
|
+
export declare class ConfigLoader extends EventEmitter {
|
|
4
|
+
readonly options: ConfigLoaderOptions;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private readonly githubFetcher;
|
|
7
|
+
private readonly cacheFetcher;
|
|
8
|
+
private readonly validator;
|
|
9
|
+
private readonly envMapper;
|
|
10
|
+
private configs;
|
|
11
|
+
private poller;
|
|
12
|
+
lastUpdateTimestamp: number | null;
|
|
13
|
+
constructor(options: ConfigLoaderOptions);
|
|
14
|
+
initialize(): Promise<void>;
|
|
15
|
+
refresh(): Promise<void>;
|
|
16
|
+
get<T = any>(path: string, defaultValue?: T): T | undefined;
|
|
17
|
+
has(path: string): boolean;
|
|
18
|
+
getAll(): Record<string, any>;
|
|
19
|
+
getCurrentEnvironment(): string;
|
|
20
|
+
getConfigNames(): string[];
|
|
21
|
+
createWebhookHandler(options?: WebhookHandlerOptions): ExpressMiddleware;
|
|
22
|
+
reload(): Promise<void>;
|
|
23
|
+
private detectChanges;
|
|
24
|
+
destroy(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AAUzC,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAMxF,qBAAa,YAAa,SAAQ,YAAY;IAC5C,SAAgB,OAAO,EAAE,mBAAmB,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,MAAM,CAAsB;IAC7B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;gBAK9B,OAAO,EAAE,mBAAmB;IAoDlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyE9B,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAS3D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQ1B,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAQ7B,qBAAqB,IAAI,MAAM;IAQ/B,cAAc,IAAI,MAAM,EAAE;IAS1B,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,iBAAiB;IAQtE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAU7B,OAAO,CAAC,aAAa;IA0BrB,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConfigLoader = void 0;
|
|
7
|
+
const eventemitter3_1 = __importDefault(require("eventemitter3"));
|
|
8
|
+
const github_fetcher_1 = require("./fetcher/github-fetcher");
|
|
9
|
+
const file_cache_fetcher_1 = require("./fetcher/file-cache-fetcher");
|
|
10
|
+
const schema_validator_1 = require("./validator/schema-validator");
|
|
11
|
+
const webhook_handler_1 = require("./webhook/webhook-handler");
|
|
12
|
+
const config_poller_1 = require("./poller/config-poller");
|
|
13
|
+
const env_mapper_1 = require("./utils/env-mapper");
|
|
14
|
+
const deep_get_1 = require("./utils/deep-get");
|
|
15
|
+
const default_schemas_1 = require("./validator/default-schemas");
|
|
16
|
+
const logger_1 = require("./utils/logger");
|
|
17
|
+
class ConfigLoader extends eventemitter3_1.default {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
super();
|
|
20
|
+
if (!options.repository) {
|
|
21
|
+
throw new Error('repository option is required');
|
|
22
|
+
}
|
|
23
|
+
if (!options.branch) {
|
|
24
|
+
throw new Error('branch option is required');
|
|
25
|
+
}
|
|
26
|
+
this.options = {
|
|
27
|
+
pollingInterval: 5 * 60 * 1000,
|
|
28
|
+
defaultEnv: 'dev',
|
|
29
|
+
envMappings: {},
|
|
30
|
+
usePackageSchemas: true,
|
|
31
|
+
cacheFile: './config-cache.json',
|
|
32
|
+
...options
|
|
33
|
+
};
|
|
34
|
+
this.logger = new logger_1.Logger('ConfigLoader');
|
|
35
|
+
const [owner, repo] = this.options.repository.split('/');
|
|
36
|
+
if (!owner || !repo) {
|
|
37
|
+
throw new Error('repository must be in format "owner/repo"');
|
|
38
|
+
}
|
|
39
|
+
this.githubFetcher = new github_fetcher_1.GitHubFetcher({
|
|
40
|
+
owner,
|
|
41
|
+
repo,
|
|
42
|
+
branch: this.options.branch,
|
|
43
|
+
token: this.options.githubToken
|
|
44
|
+
});
|
|
45
|
+
this.cacheFetcher = new file_cache_fetcher_1.FileCacheFetcher(this.options.cacheFile);
|
|
46
|
+
this.validator = new schema_validator_1.SchemaValidator();
|
|
47
|
+
this.envMapper = new env_mapper_1.EnvMapper(this.options.envMappings, this.options.defaultEnv);
|
|
48
|
+
this.configs = {};
|
|
49
|
+
this.poller = null;
|
|
50
|
+
this.lastUpdateTimestamp = null;
|
|
51
|
+
}
|
|
52
|
+
async initialize() {
|
|
53
|
+
try {
|
|
54
|
+
this.logger.info('Initializing ConfigLoader...');
|
|
55
|
+
await this.refresh();
|
|
56
|
+
this.logger.info('Successfully initialized from GitHub');
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const err = error;
|
|
60
|
+
this.logger.warn('Failed to load from GitHub, attempting cache fallback:', err.message);
|
|
61
|
+
this.emit('error', err);
|
|
62
|
+
const cached = await this.cacheFetcher.read();
|
|
63
|
+
if (cached) {
|
|
64
|
+
this.configs = cached;
|
|
65
|
+
this.lastUpdateTimestamp = Date.now();
|
|
66
|
+
this.emit('update', this.configs, Object.keys(this.configs));
|
|
67
|
+
this.logger.info('Loaded configurations from cache');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
throw new Error('Failed to initialize: no GitHub access and no cache available');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (this.options.pollingInterval && this.options.pollingInterval > 0) {
|
|
74
|
+
this.poller = new config_poller_1.ConfigPoller(this, this.options.pollingInterval);
|
|
75
|
+
this.poller.start();
|
|
76
|
+
this.logger.info(`Started polling with interval: ${this.options.pollingInterval}ms`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async refresh() {
|
|
80
|
+
const env = this.envMapper.resolve();
|
|
81
|
+
this.logger.debug(`Refreshing configs for environment: ${env}`);
|
|
82
|
+
const schemas = this.options.usePackageSchemas ? { ...default_schemas_1.defaultSchemas } : {};
|
|
83
|
+
try {
|
|
84
|
+
const repoSchemas = await this.githubFetcher.fetchAllSchemas();
|
|
85
|
+
Object.assign(schemas, repoSchemas);
|
|
86
|
+
this.logger.debug(`Loaded ${Object.keys(schemas).length} schemas`);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const err = error;
|
|
90
|
+
this.logger.warn('Failed to fetch repo schemas, using defaults:', err.message);
|
|
91
|
+
}
|
|
92
|
+
this.validator.loadSchemas(schemas);
|
|
93
|
+
const newConfigs = await this.githubFetcher.fetchAllConfigs(env);
|
|
94
|
+
this.logger.debug(`Fetched ${Object.keys(newConfigs).length} config files`);
|
|
95
|
+
const validatedConfigs = {};
|
|
96
|
+
for (const [name, data] of Object.entries(newConfigs)) {
|
|
97
|
+
const result = this.validator.validate(name, data);
|
|
98
|
+
if (!result.valid) {
|
|
99
|
+
this.logger.error(`Validation failed for ${name}:`, result.errors);
|
|
100
|
+
this.emit('validation-error', name, result.errors);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
validatedConfigs[name] = data;
|
|
104
|
+
}
|
|
105
|
+
const changedKeys = this.detectChanges(validatedConfigs);
|
|
106
|
+
this.configs = validatedConfigs;
|
|
107
|
+
this.lastUpdateTimestamp = Date.now();
|
|
108
|
+
try {
|
|
109
|
+
await this.cacheFetcher.write(validatedConfigs);
|
|
110
|
+
this.logger.debug('Updated cache file');
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const err = error;
|
|
114
|
+
this.logger.warn('Failed to update cache:', err.message);
|
|
115
|
+
}
|
|
116
|
+
if (changedKeys.length > 0) {
|
|
117
|
+
this.logger.info(`Configs updated: ${changedKeys.join(', ')}`);
|
|
118
|
+
this.emit('update', validatedConfigs, changedKeys);
|
|
119
|
+
for (const key of changedKeys) {
|
|
120
|
+
this.emit(`update:${key}`, validatedConfigs[key]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.logger.debug('No config changes detected');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
get(path, defaultValue) {
|
|
128
|
+
return (0, deep_get_1.deepGet)(this.configs, path, defaultValue);
|
|
129
|
+
}
|
|
130
|
+
has(path) {
|
|
131
|
+
return (0, deep_get_1.deepGet)(this.configs, path) !== undefined;
|
|
132
|
+
}
|
|
133
|
+
getAll() {
|
|
134
|
+
return { ...this.configs };
|
|
135
|
+
}
|
|
136
|
+
getCurrentEnvironment() {
|
|
137
|
+
return this.envMapper.resolve();
|
|
138
|
+
}
|
|
139
|
+
getConfigNames() {
|
|
140
|
+
return Object.keys(this.configs);
|
|
141
|
+
}
|
|
142
|
+
createWebhookHandler(options = {}) {
|
|
143
|
+
const handler = new webhook_handler_1.WebhookHandler(this, options);
|
|
144
|
+
return handler.createMiddleware();
|
|
145
|
+
}
|
|
146
|
+
async reload() {
|
|
147
|
+
await this.refresh();
|
|
148
|
+
}
|
|
149
|
+
detectChanges(newConfigs) {
|
|
150
|
+
const changed = [];
|
|
151
|
+
for (const key of Object.keys(newConfigs)) {
|
|
152
|
+
const oldValue = JSON.stringify(this.configs[key]);
|
|
153
|
+
const newValue = JSON.stringify(newConfigs[key]);
|
|
154
|
+
if (oldValue !== newValue) {
|
|
155
|
+
changed.push(key);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
for (const key of Object.keys(this.configs)) {
|
|
159
|
+
if (!(key in newConfigs)) {
|
|
160
|
+
changed.push(key);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return changed;
|
|
164
|
+
}
|
|
165
|
+
destroy() {
|
|
166
|
+
if (this.poller) {
|
|
167
|
+
this.poller.stop();
|
|
168
|
+
}
|
|
169
|
+
this.removeAllListeners();
|
|
170
|
+
this.logger.info('ConfigLoader destroyed');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.ConfigLoader = ConfigLoader;
|
|
174
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class FileCacheFetcher {
|
|
2
|
+
private readonly cacheFile;
|
|
3
|
+
constructor(cacheFilePath: string);
|
|
4
|
+
read(): Promise<Record<string, any> | null>;
|
|
5
|
+
write(configs: Record<string, any>): Promise<void>;
|
|
6
|
+
exists(): boolean;
|
|
7
|
+
clear(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=file-cache-fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache-fetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher/file-cache-fetcher.ts"],"names":[],"mappings":"AAMA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAKvB,aAAa,EAAE,MAAM;IAQ3B,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAkB3C,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxD,MAAM,IAAI,OAAO;IAOX,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FileCacheFetcher = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class FileCacheFetcher {
|
|
40
|
+
constructor(cacheFilePath) {
|
|
41
|
+
this.cacheFile = cacheFilePath;
|
|
42
|
+
}
|
|
43
|
+
async read() {
|
|
44
|
+
try {
|
|
45
|
+
if (!fs.existsSync(this.cacheFile)) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const content = await fs.promises.readFile(this.cacheFile, 'utf8');
|
|
49
|
+
return JSON.parse(content);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const err = error;
|
|
53
|
+
throw new Error(`Failed to read cache file: ${err.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async write(configs) {
|
|
57
|
+
try {
|
|
58
|
+
const dir = path.dirname(this.cacheFile);
|
|
59
|
+
if (!fs.existsSync(dir)) {
|
|
60
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
const data = JSON.stringify(configs, null, 2);
|
|
63
|
+
await fs.promises.writeFile(this.cacheFile, data, 'utf8');
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const err = error;
|
|
67
|
+
throw new Error(`Failed to write cache file: ${err.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exists() {
|
|
71
|
+
return fs.existsSync(this.cacheFile);
|
|
72
|
+
}
|
|
73
|
+
async clear() {
|
|
74
|
+
if (this.exists()) {
|
|
75
|
+
await fs.promises.unlink(this.cacheFile);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.FileCacheFetcher = FileCacheFetcher;
|
|
80
|
+
//# sourceMappingURL=file-cache-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache-fetcher.js","sourceRoot":"","sources":["../../src/fetcher/file-cache-fetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAK7B,MAAa,gBAAgB;IAM3B,YAAY,aAAqB;QAC/B,IAAI,CAAC,SAAS,GAAG,aAAa,CAAC;IACjC,CAAC;IAMD,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAc,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAMD,KAAK,CAAC,KAAK,CAAC,OAA4B;QACtC,IAAI,CAAC;YAEH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9C,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAc,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAMD,MAAM;QACJ,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAKD,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;CACF;AAhED,4CAgEC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GitHubFetcherOptions } from '../types';
|
|
2
|
+
export declare class GitHubFetcher {
|
|
3
|
+
private readonly owner;
|
|
4
|
+
private readonly repo;
|
|
5
|
+
private readonly branch;
|
|
6
|
+
private readonly octokit;
|
|
7
|
+
constructor(options: GitHubFetcherOptions);
|
|
8
|
+
fetchConfig(env: string, configName: string): Promise<any>;
|
|
9
|
+
private getConfigPath;
|
|
10
|
+
fetchSchema(schemaName: string): Promise<any | null>;
|
|
11
|
+
fetchAllConfigs(env: string): Promise<Record<string, any>>;
|
|
12
|
+
fetchAllSchemas(): Promise<Record<string, any>>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=github-fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-fetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher/github-fetcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAKhD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAKtB,OAAO,EAAE,oBAAoB;IAgBnC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAsChE,OAAO,CAAC,aAAa;IAef,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAkCpD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IA0B1D,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAmCtD"}
|