@nexe/config-manager 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/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/config-manager.d.ts +34 -0
- package/dist/config-manager.d.ts.map +1 -0
- package/dist/config-manager.js +138 -0
- package/dist/config-manager.js.map +1 -0
- package/dist/debug/consul-debug.d.ts +6 -0
- package/dist/debug/consul-debug.d.ts.map +1 -0
- package/dist/debug/consul-debug.js +53 -0
- package/dist/debug/consul-debug.js.map +1 -0
- package/dist/decorators.d.ts +12 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +29 -0
- package/dist/decorators.js.map +1 -0
- package/dist/examples/annotation-example.d.ts +1 -0
- package/dist/examples/annotation-example.d.ts.map +1 -0
- package/dist/examples/annotation-example.js +273 -0
- package/dist/examples/annotation-example.js.map +1 -0
- package/dist/examples/config-example.d.ts +1 -0
- package/dist/examples/config-example.d.ts.map +1 -0
- package/dist/examples/config-example.js +83 -0
- package/dist/examples/config-example.js.map +1 -0
- package/dist/examples/consul-config-example.v2.d.ts +1 -0
- package/dist/examples/consul-config-example.v2.d.ts.map +1 -0
- package/dist/examples/consul-config-example.v2.js +145 -0
- package/dist/examples/consul-config-example.v2.js.map +1 -0
- package/dist/examples/database-config.d.ts +1 -0
- package/dist/examples/database-config.d.ts.map +1 -0
- package/dist/examples/database-config.js +23 -0
- package/dist/examples/database-config.js.map +1 -0
- package/dist/examples/hot-reload-test.d.ts +1 -0
- package/dist/examples/hot-reload-test.d.ts.map +1 -0
- package/dist/examples/hot-reload-test.js +65 -0
- package/dist/examples/hot-reload-test.js.map +1 -0
- package/dist/factory.d.ts +45 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +46 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +100 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +6 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/sources/consul-config-source.d.ts +79 -0
- package/dist/sources/consul-config-source.d.ts.map +1 -0
- package/dist/sources/consul-config-source.js +332 -0
- package/dist/sources/consul-config-source.js.map +1 -0
- package/dist/sources/environment-config-source.d.ts +34 -0
- package/dist/sources/environment-config-source.d.ts.map +1 -0
- package/dist/sources/environment-config-source.js +77 -0
- package/dist/sources/environment-config-source.js.map +1 -0
- package/dist/sources/index.d.ts +6 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +6 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/json-config-source.d.ts +57 -0
- package/dist/sources/json-config-source.d.ts.map +1 -0
- package/dist/sources/json-config-source.js +153 -0
- package/dist/sources/json-config-source.js.map +1 -0
- package/dist/sources/remote-api-config-source.d.ts +62 -0
- package/dist/sources/remote-api-config-source.d.ts.map +1 -0
- package/dist/sources/remote-api-config-source.js +169 -0
- package/dist/sources/remote-api-config-source.js.map +1 -0
- package/dist/sources/yaml-config-source.d.ts +57 -0
- package/dist/sources/yaml-config-source.d.ts.map +1 -0
- package/dist/sources/yaml-config-source.js +163 -0
- package/dist/sources/yaml-config-source.js.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 aqz236
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
# @nexe/config-manager
|
2
|
+
|
3
|
+
A flexible configuration management solution with multiple sources and hot reload support.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- 🔧 **Multiple Configuration Sources**: Support for environment variables, JSON, YAML, TOML, Consul, and custom sources
|
8
|
+
- 🔄 **Hot Reload**: Automatic configuration updates with change notifications
|
9
|
+
- 📊 **Priority-based Configuration**: Layer configurations with different priorities
|
10
|
+
- 🎯 **Type Safety**: Strong typing with TypeScript decorators
|
11
|
+
- 🔌 **Dependency Injection**: Seamless integration with tsyringe
|
12
|
+
- 📝 **Validation**: Built-in configuration validation support
|
13
|
+
- 🚀 **Easy to Use**: Simple API with minimal setup
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
```bash
|
18
|
+
# Using bun
|
19
|
+
bun add @nexe/config-manager
|
20
|
+
|
21
|
+
# Using npm
|
22
|
+
npm install @nexe/config-manager
|
23
|
+
|
24
|
+
# Using yarn
|
25
|
+
yarn add @nexe/config-manager
|
26
|
+
```
|
27
|
+
|
28
|
+
## Quick Start
|
29
|
+
|
30
|
+
### 1. Define Configuration Class
|
31
|
+
|
32
|
+
```typescript
|
33
|
+
import { ConfigProperty, ConfigSection } from '@nexe/config-manager';
|
34
|
+
|
35
|
+
@ConfigSection('database')
|
36
|
+
export class DatabaseConfig {
|
37
|
+
@ConfigProperty('host')
|
38
|
+
host = 'localhost';
|
39
|
+
|
40
|
+
@ConfigProperty('port')
|
41
|
+
port = 5432;
|
42
|
+
|
43
|
+
@ConfigProperty('username')
|
44
|
+
username = '';
|
45
|
+
|
46
|
+
@ConfigProperty('password')
|
47
|
+
password = '';
|
48
|
+
|
49
|
+
@ConfigProperty('database')
|
50
|
+
database = 'myapp';
|
51
|
+
}
|
52
|
+
```
|
53
|
+
|
54
|
+
### 2. Setup Configuration Manager
|
55
|
+
|
56
|
+
```typescript
|
57
|
+
import 'reflect-metadata';
|
58
|
+
import { container } from 'tsyringe';
|
59
|
+
import {
|
60
|
+
ConfigManager,
|
61
|
+
EnvironmentConfigSource,
|
62
|
+
JsonConfigSource
|
63
|
+
} from '@nexe/config-manager';
|
64
|
+
|
65
|
+
// Register config manager
|
66
|
+
container.registerSingleton('IConfigManager', ConfigManager);
|
67
|
+
|
68
|
+
// Get config manager instance
|
69
|
+
const configManager = container.resolve<ConfigManager>('IConfigManager');
|
70
|
+
|
71
|
+
// Add configuration sources (higher priority first)
|
72
|
+
configManager.addSource(new EnvironmentConfigSource(), 100);
|
73
|
+
configManager.addSource(new JsonConfigSource('./config.json'), 50);
|
74
|
+
```
|
75
|
+
|
76
|
+
### 3. Use Configuration
|
77
|
+
|
78
|
+
```typescript
|
79
|
+
// Get typed configuration
|
80
|
+
const dbConfig = await configManager.getConfig(DatabaseConfig);
|
81
|
+
console.log(`Connecting to ${dbConfig.host}:${dbConfig.port}`);
|
82
|
+
|
83
|
+
// Get individual values
|
84
|
+
const host = await configManager.get<string>('database.host', 'localhost');
|
85
|
+
```
|
86
|
+
|
87
|
+
## Configuration Sources
|
88
|
+
|
89
|
+
### Environment Variables
|
90
|
+
|
91
|
+
```typescript
|
92
|
+
import { EnvironmentConfigSource } from '@nexe/config-manager';
|
93
|
+
|
94
|
+
configManager.addSource(new EnvironmentConfigSource(), 100);
|
95
|
+
```
|
96
|
+
|
97
|
+
### JSON File
|
98
|
+
|
99
|
+
```typescript
|
100
|
+
import { JsonConfigSource } from '@nexe/config-manager';
|
101
|
+
|
102
|
+
configManager.addSource(new JsonConfigSource('./config.json'), 50);
|
103
|
+
```
|
104
|
+
|
105
|
+
### YAML File
|
106
|
+
|
107
|
+
```typescript
|
108
|
+
import { YamlConfigSource } from '@nexe/config-manager';
|
109
|
+
|
110
|
+
configManager.addSource(new YamlConfigSource('./config.yaml'), 50);
|
111
|
+
```
|
112
|
+
|
113
|
+
### Consul
|
114
|
+
|
115
|
+
```typescript
|
116
|
+
import { ConsulConfigSource } from '@nexe/config-manager';
|
117
|
+
|
118
|
+
const consulSource = new ConsulConfigSource({
|
119
|
+
host: 'localhost',
|
120
|
+
port: 8500,
|
121
|
+
basePath: 'config/myapp'
|
122
|
+
});
|
123
|
+
|
124
|
+
configManager.addSource(consulSource, 75);
|
125
|
+
```
|
126
|
+
|
127
|
+
## Hot Reload
|
128
|
+
|
129
|
+
Subscribe to configuration changes:
|
130
|
+
|
131
|
+
```typescript
|
132
|
+
// Subscribe to specific key changes
|
133
|
+
configManager.subscribe<string>('database.host', (newHost) => {
|
134
|
+
console.log(`Database host changed to: ${newHost}`);
|
135
|
+
});
|
136
|
+
|
137
|
+
// Subscribe with path prefix
|
138
|
+
configManager.subscribe<number>('port', (newPort) => {
|
139
|
+
console.log(`Port changed to: ${newPort}`);
|
140
|
+
}, { pathPrefix: 'database' });
|
141
|
+
```
|
142
|
+
|
143
|
+
## Advanced Usage
|
144
|
+
|
145
|
+
### Custom Configuration Source
|
146
|
+
|
147
|
+
```typescript
|
148
|
+
import { IConfigSource } from '@nexe/config-manager';
|
149
|
+
|
150
|
+
export class CustomConfigSource implements IConfigSource {
|
151
|
+
async load(key?: string): Promise<unknown> {
|
152
|
+
// Your custom loading logic
|
153
|
+
return value;
|
154
|
+
}
|
155
|
+
|
156
|
+
getName(): string {
|
157
|
+
return 'custom-source';
|
158
|
+
}
|
159
|
+
|
160
|
+
supportsHotReload(): boolean {
|
161
|
+
return false;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
configManager.addSource(new CustomConfigSource(), 25);
|
166
|
+
```
|
167
|
+
|
168
|
+
### Configuration Factory
|
169
|
+
|
170
|
+
```typescript
|
171
|
+
import { ConfigFactory } from '@nexe/config-manager';
|
172
|
+
|
173
|
+
// Use factory for convenient setup
|
174
|
+
const factory = new ConfigFactory();
|
175
|
+
factory
|
176
|
+
.addEnvironmentSource(100)
|
177
|
+
.addJsonSource('./config.json', 50)
|
178
|
+
.addYamlSource('./config.yaml', 25);
|
179
|
+
|
180
|
+
const configManager = factory.build();
|
181
|
+
```
|
182
|
+
|
183
|
+
## API Reference
|
184
|
+
|
185
|
+
### ConfigManager
|
186
|
+
|
187
|
+
- `addSource(source: IConfigSource, priority?: number)`: Add a configuration source
|
188
|
+
- `get<T>(key: string, defaultValue?: T, options?: ConfigOptions)`: Get a configuration value
|
189
|
+
- `getConfig<T>(configClass: new () => T, options?: ConfigOptions)`: Get a typed configuration object
|
190
|
+
- `subscribe<T>(key: string, callback: (value: T) => void, options?: ConfigOptions)`: Subscribe to configuration changes
|
191
|
+
- `unsubscribe(key: string, options?: ConfigOptions)`: Unsubscribe from configuration changes
|
192
|
+
|
193
|
+
### Decorators
|
194
|
+
|
195
|
+
- `@ConfigSection(section: string)`: Mark a class as a configuration section
|
196
|
+
- `@ConfigProperty(key: string)`: Mark a property as a configuration property
|
197
|
+
|
198
|
+
## License
|
199
|
+
|
200
|
+
MIT © [aqz236](https://github.com/aqz236)
|
201
|
+
|
202
|
+
## Contributing
|
203
|
+
|
204
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
205
|
+
|
206
|
+
## Support
|
207
|
+
|
208
|
+
If you have any questions or issues, please open an issue on [GitHub](https://github.com/aqz236/nexe/issues).
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import 'reflect-metadata';
|
2
|
+
import type { ConfigOptions, IConfigManager, IConfigSource } from './interfaces';
|
3
|
+
/**
|
4
|
+
* 配置管理器实现
|
5
|
+
*/
|
6
|
+
export declare class ConfigManager implements IConfigManager {
|
7
|
+
private sources;
|
8
|
+
private subscriptions;
|
9
|
+
/**
|
10
|
+
* 添加配置源
|
11
|
+
*/
|
12
|
+
addSource(source: IConfigSource, priority?: number): void;
|
13
|
+
/**
|
14
|
+
* 获取配置值
|
15
|
+
*/
|
16
|
+
get<T>(key: string, defaultValue?: T, options?: ConfigOptions): Promise<T>;
|
17
|
+
/**
|
18
|
+
* 获取强类型配置对象
|
19
|
+
*/
|
20
|
+
getConfig<T>(configClass: new () => T, options?: ConfigOptions): Promise<T>;
|
21
|
+
/**
|
22
|
+
* 订阅配置变更
|
23
|
+
*/
|
24
|
+
subscribe<T>(key: string, callback: (value: T) => void, options?: ConfigOptions): void;
|
25
|
+
/**
|
26
|
+
* 取消订阅配置变更
|
27
|
+
*/
|
28
|
+
unsubscribe(key: string, options?: ConfigOptions): void;
|
29
|
+
/**
|
30
|
+
* 设置配置源的变更订阅
|
31
|
+
*/
|
32
|
+
private setupSourceSubscription;
|
33
|
+
}
|
34
|
+
//# sourceMappingURL=config-manager.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../src/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACV,aAAa,EAEb,cAAc,EACd,aAAa,EACd,MAAM,cAAc,CAAC;AAWtB;;GAEG;AACH,qBACa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,aAAa,CAAmD;IAExE;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,SAAI,GAAG,IAAI;IAWpD;;OAEG;IACG,GAAG,CAAC,CAAC,EACT,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,CAAC,EAChB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,CAAC,CAAC;IAoBb;;OAEG;IACG,SAAS,CAAC,CAAC,EACf,WAAW,EAAE,UAAU,CAAC,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,CAAC,CAAC;IAkBb;;OAEG;IACH,SAAS,CAAC,CAAC,EACT,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAC5B,OAAO,CAAC,EAAE,aAAa,GACtB,IAAI;IAsCP;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;IAkBvD;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAchC"}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
import { __decorate } from "tslib";
|
2
|
+
import 'reflect-metadata';
|
3
|
+
import { injectable } from 'tsyringe';
|
4
|
+
import { CONFIG_PROPERTY_METADATA, CONFIG_SECTION_METADATA, } from './interfaces';
|
5
|
+
/**
|
6
|
+
* 配置管理器实现
|
7
|
+
*/
|
8
|
+
let ConfigManager = class ConfigManager {
|
9
|
+
constructor() {
|
10
|
+
this.sources = [];
|
11
|
+
this.subscriptions = new Map();
|
12
|
+
}
|
13
|
+
/**
|
14
|
+
* 添加配置源
|
15
|
+
*/
|
16
|
+
addSource(source, priority = 0) {
|
17
|
+
this.sources.push({ source, priority });
|
18
|
+
// 根据优先级排序,高优先级的在前面
|
19
|
+
this.sources.sort((a, b) => b.priority - a.priority);
|
20
|
+
// 如果配置源支持热更新,设置变更监听
|
21
|
+
if (source.supportsHotReload() && source.subscribe) {
|
22
|
+
this.setupSourceSubscription(source);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* 获取配置值
|
27
|
+
*/
|
28
|
+
async get(key, defaultValue, options) {
|
29
|
+
for (const { source } of this.sources) {
|
30
|
+
try {
|
31
|
+
// 如果指定了配置源名称,只从该配置源获取
|
32
|
+
if (options?.sourceName && source.getName() !== options.sourceName) {
|
33
|
+
continue;
|
34
|
+
}
|
35
|
+
const value = await source.load(key, options?.pathPrefix);
|
36
|
+
if (value !== undefined && value !== null) {
|
37
|
+
return value;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
catch (error) {
|
41
|
+
// eslint-disable-next-line no-console
|
42
|
+
console.warn(`配置源 ${source.getName()} 加载键 ${key} 时出错:`, error);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return defaultValue;
|
46
|
+
}
|
47
|
+
/**
|
48
|
+
* 获取强类型配置对象
|
49
|
+
*/
|
50
|
+
async getConfig(configClass, options) {
|
51
|
+
const instance = new configClass();
|
52
|
+
const section = Reflect.getMetadata(CONFIG_SECTION_METADATA, configClass);
|
53
|
+
const properties = Reflect.getMetadata(CONFIG_PROPERTY_METADATA, configClass) ?? [];
|
54
|
+
for (const { key, propertyKey } of properties) {
|
55
|
+
const configKey = section ? `${section}.${key}` : key;
|
56
|
+
const value = await this.get(configKey, undefined, options);
|
57
|
+
if (value !== undefined) {
|
58
|
+
instance[propertyKey] = value;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
return instance;
|
62
|
+
}
|
63
|
+
/**
|
64
|
+
* 订阅配置变更
|
65
|
+
*/
|
66
|
+
subscribe(key, callback, options) {
|
67
|
+
const subscriptionKey = options?.pathPrefix
|
68
|
+
? `${options.pathPrefix}:${key}`
|
69
|
+
: key;
|
70
|
+
const callbacks = this.subscriptions.get(subscriptionKey) ?? [];
|
71
|
+
callbacks.push(callback);
|
72
|
+
this.subscriptions.set(subscriptionKey, callbacks);
|
73
|
+
// 只订阅第一个支持热更新的配置源,避免重复订阅
|
74
|
+
let subscribed = false;
|
75
|
+
for (const { source } of this.sources) {
|
76
|
+
if (source.supportsHotReload() && source.subscribe && !subscribed) {
|
77
|
+
// 如果配置源支持动态路径,传递路径前缀
|
78
|
+
if (source.supportsDynamicPath && source.supportsDynamicPath()) {
|
79
|
+
source.subscribe(key, newValue => {
|
80
|
+
// 通知所有订阅此键的回调
|
81
|
+
const currentCallbacks = this.subscriptions.get(subscriptionKey) ?? [];
|
82
|
+
currentCallbacks.forEach(cb => cb(newValue));
|
83
|
+
}, options?.pathPrefix);
|
84
|
+
}
|
85
|
+
else {
|
86
|
+
source.subscribe(key, newValue => {
|
87
|
+
// 通知所有订阅此键的回调
|
88
|
+
const currentCallbacks = this.subscriptions.get(subscriptionKey) ?? [];
|
89
|
+
currentCallbacks.forEach(cb => cb(newValue));
|
90
|
+
});
|
91
|
+
}
|
92
|
+
subscribed = true;
|
93
|
+
break; // 只订阅第一个配置源
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
* 取消订阅配置变更
|
99
|
+
*/
|
100
|
+
unsubscribe(key, options) {
|
101
|
+
const subscriptionKey = options?.pathPrefix
|
102
|
+
? `${options.pathPrefix}:${key}`
|
103
|
+
: key;
|
104
|
+
this.subscriptions.delete(subscriptionKey);
|
105
|
+
// 通知配置源取消订阅
|
106
|
+
for (const { source } of this.sources) {
|
107
|
+
if (source.supportsHotReload() && source.unsubscribe) {
|
108
|
+
if (source.supportsDynamicPath && source.supportsDynamicPath()) {
|
109
|
+
source.unsubscribe(key, options?.pathPrefix);
|
110
|
+
}
|
111
|
+
else {
|
112
|
+
source.unsubscribe(key);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
/**
|
118
|
+
* 设置配置源的变更订阅
|
119
|
+
*/
|
120
|
+
setupSourceSubscription(source) {
|
121
|
+
// 确保 subscribe 方法存在
|
122
|
+
const subscribeMethod = source.subscribe;
|
123
|
+
if (!subscribeMethod) {
|
124
|
+
return;
|
125
|
+
}
|
126
|
+
// 为每个订阅的键设置变更监听
|
127
|
+
this.subscriptions.forEach((callbacks, key) => {
|
128
|
+
subscribeMethod.call(source, key, newValue => {
|
129
|
+
callbacks.forEach(callback => callback(newValue));
|
130
|
+
});
|
131
|
+
});
|
132
|
+
}
|
133
|
+
};
|
134
|
+
ConfigManager = __decorate([
|
135
|
+
injectable()
|
136
|
+
], ConfigManager);
|
137
|
+
export { ConfigManager };
|
138
|
+
//# sourceMappingURL=config-manager.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../src/config-manager.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"consul-debug.d.ts","sourceRoot":"","sources":["../../src/debug/consul-debug.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,iBAAe,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuChD;AAUD,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { createLogger } from '@nexe/logger';
|
2
|
+
import { ConsulConfigSource } from '../sources/consul-config-source';
|
3
|
+
const logger = createLogger('ConsulDebug');
|
4
|
+
/**
|
5
|
+
* 调试Consul配置的工具函数
|
6
|
+
*/
|
7
|
+
async function debugConsulConfig() {
|
8
|
+
const consulConfig = new ConsulConfigSource({
|
9
|
+
host: '127.0.0.1',
|
10
|
+
port: 8500,
|
11
|
+
secure: false,
|
12
|
+
defaultKeyPrefix: 'app/config',
|
13
|
+
});
|
14
|
+
try {
|
15
|
+
// 1. 加载所有配置
|
16
|
+
logger.info('=== 调试:加载所有配置 ===');
|
17
|
+
const allConfig = await consulConfig.load();
|
18
|
+
logger.info('所有配置:', JSON.stringify(allConfig, null, 2));
|
19
|
+
// 2. 尝试加载特定的registrationMethod配置
|
20
|
+
logger.info('=== 调试:加载registrationMethod配置 ===');
|
21
|
+
const registrationMethod = await consulConfig.load('registrationMethod');
|
22
|
+
logger.info('registrationMethod配置:', registrationMethod);
|
23
|
+
// 3. 测试订阅
|
24
|
+
logger.info('=== 调试:测试配置订阅 ===');
|
25
|
+
consulConfig.subscribe('registrationMethod', (newValue) => {
|
26
|
+
logger.info('🔄 配置变更回调被触发');
|
27
|
+
logger.info('新值类型:', typeof newValue);
|
28
|
+
logger.info('新值内容:', JSON.stringify(newValue, null, 2));
|
29
|
+
});
|
30
|
+
// 等待一些时间来观察变更
|
31
|
+
await new Promise(resolve => {
|
32
|
+
setTimeout(() => {
|
33
|
+
logger.info('调试完成,清理资源...');
|
34
|
+
resolve();
|
35
|
+
}, 10000);
|
36
|
+
});
|
37
|
+
}
|
38
|
+
catch (error) {
|
39
|
+
logger.error('调试失败:', error);
|
40
|
+
}
|
41
|
+
finally {
|
42
|
+
consulConfig.dispose();
|
43
|
+
}
|
44
|
+
}
|
45
|
+
// 如果直接运行此文件,执行调试
|
46
|
+
if (require.main === module) {
|
47
|
+
debugConsulConfig().catch(error => {
|
48
|
+
logger.error('调试执行失败:', error);
|
49
|
+
process.exit(1);
|
50
|
+
});
|
51
|
+
}
|
52
|
+
export { debugConsulConfig };
|
53
|
+
//# sourceMappingURL=consul-debug.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"consul-debug.js","sourceRoot":"","sources":["../../src/debug/consul-debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAE3C;;GAEG;AACH,KAAK,UAAU,iBAAiB;IAC9B,MAAM,YAAY,GAAG,IAAI,kBAAkB,CAAC;QAC1C,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,KAAK;QACb,gBAAgB,EAAE,YAAY;KAC/B,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,YAAY;QACZ,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEzD,iCAAiC;QACjC,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACjD,MAAM,kBAAkB,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;QAEzD,UAAU;QACV,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjC,YAAY,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC,QAAiB,EAAE,EAAE;YACjE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,QAAQ,CAAC,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,cAAc;QACd,MAAM,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;YAChC,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC5B,OAAO,EAAE,CAAC;YACZ,CAAC,EAAE,KAAK,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,iBAAiB;AACjB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,iBAAiB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QAChC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import 'reflect-metadata';
|
2
|
+
/**
|
3
|
+
* 配置属性装饰器,用于将配置值映射到类属性
|
4
|
+
* @param key 配置键,如果不提供则使用属性名
|
5
|
+
*/
|
6
|
+
export declare function ConfigProperty(key?: string): PropertyDecorator;
|
7
|
+
/**
|
8
|
+
* 配置分区装饰器,用于定义配置类所对应的配置分区
|
9
|
+
* @param section 配置分区名称
|
10
|
+
*/
|
11
|
+
export declare function ConfigSection(section: string): ClassDecorator;
|
12
|
+
//# sourceMappingURL=decorators.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAmB9D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAK7D"}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import 'reflect-metadata';
|
2
|
+
import { CONFIG_PROPERTY_METADATA, CONFIG_SECTION_METADATA, } from './interfaces';
|
3
|
+
/**
|
4
|
+
* 配置属性装饰器,用于将配置值映射到类属性
|
5
|
+
* @param key 配置键,如果不提供则使用属性名
|
6
|
+
*/
|
7
|
+
export function ConfigProperty(key) {
|
8
|
+
return (target, propertyKey) => {
|
9
|
+
const configKey = key ?? String(propertyKey);
|
10
|
+
// 存储配置属性元数据
|
11
|
+
const existingProperties = Reflect.getMetadata(CONFIG_PROPERTY_METADATA, target.constructor) ?? [];
|
12
|
+
existingProperties.push({
|
13
|
+
key: configKey,
|
14
|
+
propertyKey: String(propertyKey),
|
15
|
+
});
|
16
|
+
Reflect.defineMetadata(CONFIG_PROPERTY_METADATA, existingProperties, target.constructor);
|
17
|
+
};
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* 配置分区装饰器,用于定义配置类所对应的配置分区
|
21
|
+
* @param section 配置分区名称
|
22
|
+
*/
|
23
|
+
export function ConfigSection(section) {
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
25
|
+
return (target) => {
|
26
|
+
Reflect.defineMetadata(CONFIG_SECTION_METADATA, section, target);
|
27
|
+
};
|
28
|
+
}
|
29
|
+
//# sourceMappingURL=decorators.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAEtB;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,OAAO,CAAC,MAAc,EAAE,WAA4B,EAAQ,EAAE;QAC5D,MAAM,SAAS,GAAG,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;QAE7C,YAAY;QACZ,MAAM,kBAAkB,GACtB,OAAO,CAAC,WAAW,CAAC,wBAAwB,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAE1E,kBAAkB,CAAC,IAAI,CAAC;YACtB,GAAG,EAAE,SAAS;YACd,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC;SACjC,CAAC,CAAC;QAEH,OAAO,CAAC,cAAc,CACpB,wBAAwB,EACxB,kBAAkB,EAClB,MAAM,CAAC,WAAW,CACnB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,sEAAsE;IACtE,OAAO,CAAC,MAAgB,EAAQ,EAAE;QAChC,OAAO,CAAC,cAAc,CAAC,uBAAuB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
//# sourceMappingURL=annotation-example.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"annotation-example.d.ts","sourceRoot":"","sources":["../../src/examples/annotation-example.ts"],"names":[],"mappings":""}
|