@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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +208 -0
  3. package/dist/config-manager.d.ts +34 -0
  4. package/dist/config-manager.d.ts.map +1 -0
  5. package/dist/config-manager.js +138 -0
  6. package/dist/config-manager.js.map +1 -0
  7. package/dist/debug/consul-debug.d.ts +6 -0
  8. package/dist/debug/consul-debug.d.ts.map +1 -0
  9. package/dist/debug/consul-debug.js +53 -0
  10. package/dist/debug/consul-debug.js.map +1 -0
  11. package/dist/decorators.d.ts +12 -0
  12. package/dist/decorators.d.ts.map +1 -0
  13. package/dist/decorators.js +29 -0
  14. package/dist/decorators.js.map +1 -0
  15. package/dist/examples/annotation-example.d.ts +1 -0
  16. package/dist/examples/annotation-example.d.ts.map +1 -0
  17. package/dist/examples/annotation-example.js +273 -0
  18. package/dist/examples/annotation-example.js.map +1 -0
  19. package/dist/examples/config-example.d.ts +1 -0
  20. package/dist/examples/config-example.d.ts.map +1 -0
  21. package/dist/examples/config-example.js +83 -0
  22. package/dist/examples/config-example.js.map +1 -0
  23. package/dist/examples/consul-config-example.v2.d.ts +1 -0
  24. package/dist/examples/consul-config-example.v2.d.ts.map +1 -0
  25. package/dist/examples/consul-config-example.v2.js +145 -0
  26. package/dist/examples/consul-config-example.v2.js.map +1 -0
  27. package/dist/examples/database-config.d.ts +1 -0
  28. package/dist/examples/database-config.d.ts.map +1 -0
  29. package/dist/examples/database-config.js +23 -0
  30. package/dist/examples/database-config.js.map +1 -0
  31. package/dist/examples/hot-reload-test.d.ts +1 -0
  32. package/dist/examples/hot-reload-test.d.ts.map +1 -0
  33. package/dist/examples/hot-reload-test.js +65 -0
  34. package/dist/examples/hot-reload-test.js.map +1 -0
  35. package/dist/factory.d.ts +45 -0
  36. package/dist/factory.d.ts.map +1 -0
  37. package/dist/factory.js +46 -0
  38. package/dist/factory.js.map +1 -0
  39. package/dist/index.d.ts +5 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +5 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/interfaces.d.ts +100 -0
  44. package/dist/interfaces.d.ts.map +1 -0
  45. package/dist/interfaces.js +6 -0
  46. package/dist/interfaces.js.map +1 -0
  47. package/dist/sources/consul-config-source.d.ts +79 -0
  48. package/dist/sources/consul-config-source.d.ts.map +1 -0
  49. package/dist/sources/consul-config-source.js +332 -0
  50. package/dist/sources/consul-config-source.js.map +1 -0
  51. package/dist/sources/environment-config-source.d.ts +34 -0
  52. package/dist/sources/environment-config-source.d.ts.map +1 -0
  53. package/dist/sources/environment-config-source.js +77 -0
  54. package/dist/sources/environment-config-source.js.map +1 -0
  55. package/dist/sources/index.d.ts +6 -0
  56. package/dist/sources/index.d.ts.map +1 -0
  57. package/dist/sources/index.js +6 -0
  58. package/dist/sources/index.js.map +1 -0
  59. package/dist/sources/json-config-source.d.ts +57 -0
  60. package/dist/sources/json-config-source.d.ts.map +1 -0
  61. package/dist/sources/json-config-source.js +153 -0
  62. package/dist/sources/json-config-source.js.map +1 -0
  63. package/dist/sources/remote-api-config-source.d.ts +62 -0
  64. package/dist/sources/remote-api-config-source.d.ts.map +1 -0
  65. package/dist/sources/remote-api-config-source.js +169 -0
  66. package/dist/sources/remote-api-config-source.js.map +1 -0
  67. package/dist/sources/yaml-config-source.d.ts +57 -0
  68. package/dist/sources/yaml-config-source.d.ts.map +1 -0
  69. package/dist/sources/yaml-config-source.js +163 -0
  70. package/dist/sources/yaml-config-source.js.map +1 -0
  71. 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,6 @@
1
+ /**
2
+ * 调试Consul配置的工具函数
3
+ */
4
+ declare function debugConsulConfig(): Promise<void>;
5
+ export { debugConsulConfig };
6
+ //# sourceMappingURL=consul-debug.d.ts.map
@@ -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":""}