@fluwa-tool/sdk 1.0.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.
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ /**
3
+ * Interceptador de fetch nativo do navegador
4
+ * Responsabilidade única: interceptar e logar requisições fetch
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.FetchInterceptor = void 0;
8
+ const types_1 = require("../../types");
9
+ /**
10
+ * Implementação de interceptador de fetch
11
+ * Preserva fetch original e sobrescreve com versão interceptada
12
+ */
13
+ class FetchInterceptor {
14
+ constructor(logger, requestLogger, mockResolver, sessionId, appName) {
15
+ this.logger = logger;
16
+ this.requestLogger = requestLogger;
17
+ this.mockResolver = mockResolver;
18
+ this.sessionId = sessionId;
19
+ this.appName = appName;
20
+ this.originalFetch = null;
21
+ this.isInstalled = false;
22
+ }
23
+ /**
24
+ * Instalar o interceptador
25
+ * Substitui fetch global
26
+ */
27
+ install() {
28
+ if (this.isInstalled) {
29
+ this.logger.warn('Fetch interceptor já foi instalado');
30
+ return;
31
+ }
32
+ // Detectar ambiente (navegador ou Node.js)
33
+ const isBrowser = typeof window !== 'undefined';
34
+ const globalObj = isBrowser ? window : globalThis;
35
+ if (typeof globalObj.fetch === 'undefined') {
36
+ this.logger.warn('Fetch não disponível nesse ambiente');
37
+ return;
38
+ }
39
+ this.originalFetch = globalObj.fetch;
40
+ // Sobrescrever fetch global
41
+ globalObj.fetch = this.createInterceptedFetch();
42
+ this.isInstalled = true;
43
+ this.logger.success('Fetch interceptor instalado');
44
+ }
45
+ /**
46
+ * Desinstalar o interceptador
47
+ * Restaura fetch original
48
+ */
49
+ uninstall() {
50
+ if (!this.isInstalled || !this.originalFetch) {
51
+ return;
52
+ }
53
+ const isBrowser = typeof window !== 'undefined';
54
+ const globalObj = isBrowser ? window : globalThis;
55
+ globalObj.fetch = this.originalFetch;
56
+ this.originalFetch = null;
57
+ this.isInstalled = false;
58
+ this.logger.success('Fetch interceptor desinstalado');
59
+ }
60
+ /**
61
+ * Criar versão interceptada de fetch
62
+ */
63
+ createInterceptedFetch() {
64
+ return async (...args) => {
65
+ const startTime = performance.now();
66
+ const [resource, init] = args;
67
+ // Ignorar requisições internas do Fluwa (header X-Fluwa-Internal)
68
+ if (init?.headers && typeof init.headers === 'object') {
69
+ const headers = init.headers;
70
+ if (headers['X-Fluwa-Internal'] === 'true') {
71
+ // Usar fetch original para requisições internas
72
+ return this.originalFetch.apply(globalThis, args);
73
+ }
74
+ }
75
+ // Extrair informações da requisição
76
+ const method = (init?.method || 'GET').toUpperCase();
77
+ const url = typeof resource === 'string' ? resource : (resource instanceof Request ? resource.url : resource.toString());
78
+ const requestId = this.generateId();
79
+ const requestMetadata = {
80
+ id: requestId,
81
+ method,
82
+ url,
83
+ headers: init?.headers || {},
84
+ body: init?.body ? this.safeParseBody(init.body) : undefined,
85
+ timestamp: new Date().toISOString(),
86
+ sessionId: this.sessionId,
87
+ appName: this.appName,
88
+ source: types_1.RequestSource.REAL, // Default, pode mudar se usar mock
89
+ };
90
+ try {
91
+ // Registrar que começou
92
+ await this.requestLogger.logStart(requestMetadata);
93
+ // Verificar se há mock disponível
94
+ const mockResponse = await this.mockResolver.resolve(method, url);
95
+ if (mockResponse) {
96
+ // Usar mock
97
+ requestMetadata.source = types_1.RequestSource.MOCK;
98
+ requestMetadata.response = mockResponse.response;
99
+ requestMetadata.status = mockResponse.status;
100
+ // Aplicar delay se configurado
101
+ if (mockResponse.delay) {
102
+ await this.delay(mockResponse.delay);
103
+ }
104
+ const duration = performance.now() - startTime;
105
+ requestMetadata.duration = duration;
106
+ // Registrar completamento
107
+ await this.requestLogger.logComplete(requestMetadata);
108
+ // Retornar mock como Response
109
+ return new Response(JSON.stringify(mockResponse.response), {
110
+ status: mockResponse.status || 200,
111
+ statusText: 'Mock',
112
+ headers: { 'Content-Type': 'application/json' },
113
+ });
114
+ }
115
+ // Fazer request real
116
+ const response = await this.originalFetch.apply(globalThis, args);
117
+ const responseClone = response.clone();
118
+ requestMetadata.source = types_1.RequestSource.REAL;
119
+ requestMetadata.status = response.status;
120
+ // Tentar extrair body da resposta
121
+ try {
122
+ const responseBody = await responseClone.json();
123
+ requestMetadata.response = responseBody;
124
+ }
125
+ catch {
126
+ // Se não conseguir parsear JSON, deixa vazio
127
+ }
128
+ const duration = performance.now() - startTime;
129
+ requestMetadata.duration = duration;
130
+ // Registrar completamento
131
+ await this.requestLogger.logComplete(requestMetadata);
132
+ return response;
133
+ }
134
+ catch (error) {
135
+ const duration = performance.now() - startTime;
136
+ requestMetadata.source = types_1.RequestSource.ERROR;
137
+ requestMetadata.duration = duration;
138
+ requestMetadata.error = error instanceof Error ? error.message : String(error);
139
+ // Registrar erro
140
+ await this.requestLogger.logComplete(requestMetadata);
141
+ throw error;
142
+ }
143
+ };
144
+ }
145
+ /**
146
+ * Parse seguro do body (string ou object)
147
+ */
148
+ safeParseBody(body) {
149
+ if (typeof body === 'string') {
150
+ try {
151
+ return JSON.parse(body);
152
+ }
153
+ catch {
154
+ return body;
155
+ }
156
+ }
157
+ return body;
158
+ }
159
+ /**
160
+ * Gerar ID único para requisição
161
+ */
162
+ generateId() {
163
+ return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
164
+ }
165
+ /**
166
+ * Sleep (para delays de mock)
167
+ */
168
+ delay(ms) {
169
+ return new Promise((resolve) => setTimeout(resolve, ms));
170
+ }
171
+ }
172
+ exports.FetchInterceptor = FetchInterceptor;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Resolvedor de mocks
3
+ * Responsabilidade única: encontrar e retornar mock baseado em URL/método
4
+ */
5
+ import { ILogger } from '../../core/Logger';
6
+ import { HttpMethod, MockRoute } from '../../types';
7
+ import { IHttpClient } from '../communication/HttpClient';
8
+ export interface IMockResolver {
9
+ resolve(method: HttpMethod, url: string): Promise<MockRoute | null>;
10
+ setActiveScenario(scenarioId: string | null): void;
11
+ refreshActiveScenario(): Promise<void>;
12
+ }
13
+ /**
14
+ * Implementação do resolvedor de mocks
15
+ * Busca cenário ativo do servidor e faz matching local
16
+ */
17
+ export declare class MockResolver implements IMockResolver {
18
+ private httpClient;
19
+ private logger;
20
+ private cachedScenario;
21
+ private lastFetchTime;
22
+ private cacheTimeout;
23
+ constructor(httpClient: IHttpClient, logger: ILogger);
24
+ /**
25
+ * Resolver mock para método e URL
26
+ * Retorna null se não houver mock
27
+ */
28
+ resolve(method: HttpMethod, url: string): Promise<MockRoute | null>;
29
+ /**
30
+ * Atualizar cenário ativo do servidor
31
+ */
32
+ refreshActiveScenario(): Promise<void>;
33
+ /**
34
+ * Atualizar cenário ativo (interface anterior)
35
+ */
36
+ setActiveScenario(scenarioId: string | null): void;
37
+ /**
38
+ * Encontrar rota que corresponde ao método e URL
39
+ */
40
+ private findMatchingRoute;
41
+ /**
42
+ * Verificar se a URL atual corresponde ao padrão da rota
43
+ */
44
+ private urlMatches;
45
+ /**
46
+ * Verificar correspondência com parâmetros
47
+ */
48
+ private matchesParamPattern;
49
+ }
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ /**
3
+ * Resolvedor de mocks
4
+ * Responsabilidade única: encontrar e retornar mock baseado em URL/método
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.MockResolver = void 0;
8
+ /**
9
+ * Implementação do resolvedor de mocks
10
+ * Busca cenário ativo do servidor e faz matching local
11
+ */
12
+ class MockResolver {
13
+ constructor(httpClient, logger) {
14
+ this.httpClient = httpClient;
15
+ this.logger = logger;
16
+ this.cachedScenario = null;
17
+ this.lastFetchTime = 0;
18
+ this.cacheTimeout = 5000; // 5 segundos
19
+ }
20
+ /**
21
+ * Resolver mock para método e URL
22
+ * Retorna null se não houver mock
23
+ */
24
+ async resolve(method, url) {
25
+ try {
26
+ // Atualizar scenario do servidor se necessário
27
+ await this.refreshActiveScenario();
28
+ if (!this.cachedScenario) {
29
+ return null;
30
+ }
31
+ // Encontrar rota correspondente
32
+ const matchingRoute = this.findMatchingRoute(method, url, this.cachedScenario.routes);
33
+ if (matchingRoute) {
34
+ this.logger.debug(`Mock encontrado para ${method} ${url}`);
35
+ return matchingRoute;
36
+ }
37
+ return null;
38
+ }
39
+ catch (error) {
40
+ this.logger.warn(`Erro ao resolver mock: ${error}`);
41
+ return null;
42
+ }
43
+ }
44
+ /**
45
+ * Atualizar cenário ativo do servidor
46
+ */
47
+ async refreshActiveScenario() {
48
+ const now = Date.now();
49
+ // Usar cache se recente
50
+ if (this.lastFetchTime && now - this.lastFetchTime < this.cacheTimeout) {
51
+ return;
52
+ }
53
+ try {
54
+ const response = await this.httpClient.get('/api/scenarios/active');
55
+ this.cachedScenario = response.data || null;
56
+ this.lastFetchTime = now;
57
+ if (this.cachedScenario) {
58
+ this.logger.debug(`Cenário ativo atualizado: ${this.cachedScenario.name}`);
59
+ }
60
+ }
61
+ catch (error) {
62
+ this.logger.debug('Nenhum cenário ativo no servidor');
63
+ this.cachedScenario = null;
64
+ this.lastFetchTime = now;
65
+ }
66
+ }
67
+ /**
68
+ * Atualizar cenário ativo (interface anterior)
69
+ */
70
+ setActiveScenario(scenarioId) {
71
+ // Invalidar cache para forçar atualização do servidor
72
+ this.lastFetchTime = 0;
73
+ if (scenarioId) {
74
+ this.logger.info(`Cenário ativo definido para: ${scenarioId}`);
75
+ }
76
+ else {
77
+ this.logger.info('Mocks desativados');
78
+ }
79
+ }
80
+ /**
81
+ * Encontrar rota que corresponde ao método e URL
82
+ */
83
+ findMatchingRoute(method, url, routes) {
84
+ return routes.find((route) => {
85
+ // Verificar se o método corresponde
86
+ if (route.method.toString() !== method.toString()) {
87
+ return false;
88
+ }
89
+ // Verificar se a URL corresponde
90
+ return this.urlMatches(url, route.url);
91
+ });
92
+ }
93
+ /**
94
+ * Verificar se a URL atual corresponde ao padrão da rota
95
+ */
96
+ urlMatches(actualUrl, routePattern) {
97
+ // Remover query string e hash
98
+ const actualUrlPath = actualUrl.split('?')[0].split('#')[0];
99
+ // Correspondência exata
100
+ if (routePattern === actualUrlPath) {
101
+ return true;
102
+ }
103
+ // Correspondência com wildcard
104
+ if (routePattern.endsWith('/*')) {
105
+ const basePath = routePattern.slice(0, -2);
106
+ return actualUrlPath.startsWith(basePath);
107
+ }
108
+ // Correspondência com :param (ex: /api/users/:id)
109
+ return this.matchesParamPattern(actualUrlPath, routePattern);
110
+ }
111
+ /**
112
+ * Verificar correspondência com parâmetros
113
+ */
114
+ matchesParamPattern(actualUrl, pattern) {
115
+ const actualParts = actualUrl.split('/').filter(Boolean);
116
+ const patternParts = pattern.split('/').filter(Boolean);
117
+ if (actualParts.length !== patternParts.length) {
118
+ return false;
119
+ }
120
+ return patternParts.every((patternPart, index) => {
121
+ const actualPart = actualParts[index];
122
+ if (patternPart.startsWith(':')) {
123
+ return actualPart !== undefined;
124
+ }
125
+ return patternPart === actualPart;
126
+ });
127
+ }
128
+ }
129
+ exports.MockResolver = MockResolver;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Logger de requisições
3
+ * Responsabilidade única: enviar requisições para o servidor Fluwa
4
+ */
5
+ import { ILogger } from '../../core/Logger';
6
+ import { RequestMetadata } from '../../types';
7
+ import { IHttpClient } from '../communication/HttpClient';
8
+ export interface IRequestLogger {
9
+ logStart(request: RequestMetadata): Promise<void>;
10
+ logComplete(request: RequestMetadata): Promise<void>;
11
+ }
12
+ /**
13
+ * Implementação do logger de requisições
14
+ * Envia dados para servidor via HTTP
15
+ */
16
+ export declare class RequestLogger implements IRequestLogger {
17
+ private httpClient;
18
+ private logger;
19
+ constructor(httpClient: IHttpClient, logger: ILogger);
20
+ /**
21
+ * Logar início de uma requisição
22
+ */
23
+ logStart(request: RequestMetadata): Promise<void>;
24
+ /**
25
+ * Logar completamento de uma requisição
26
+ */
27
+ logComplete(request: RequestMetadata): Promise<void>;
28
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Logger de requisições
4
+ * Responsabilidade única: enviar requisições para o servidor Fluwa
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.RequestLogger = void 0;
8
+ /**
9
+ * Implementação do logger de requisições
10
+ * Envia dados para servidor via HTTP
11
+ */
12
+ class RequestLogger {
13
+ constructor(httpClient, logger) {
14
+ this.httpClient = httpClient;
15
+ this.logger = logger;
16
+ }
17
+ /**
18
+ * Logar início de uma requisição
19
+ */
20
+ async logStart(request) {
21
+ try {
22
+ await this.httpClient.post('/api/requests', request);
23
+ this.logger.debug(`Request iniciado: ${request.method} ${request.url}`);
24
+ }
25
+ catch (error) {
26
+ this.logger.warn(`Falha ao logar request start`, error);
27
+ }
28
+ }
29
+ /**
30
+ * Logar completamento de uma requisição
31
+ */
32
+ async logComplete(request) {
33
+ try {
34
+ await this.httpClient.put(`/api/requests/${request.id}`, request);
35
+ this.logger.debug(`Request completado: ${request.method} ${request.url}`);
36
+ }
37
+ catch (error) {
38
+ this.logger.warn(`Falha ao logar request complete`, error);
39
+ }
40
+ }
41
+ }
42
+ exports.RequestLogger = RequestLogger;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 🔧 Fluwa SDK
3
+ * Entry point principal do SDK
4
+ *
5
+ * Uso:
6
+ * import { initFluwaTool } from '@fluwa-tool/sdk';
7
+ * initFluwaTool({ serverUrl: 'http://localhost:5555' });
8
+ */
9
+ import { FluwaConfig } from './types';
10
+ /**
11
+ * Inicializar Fluwa-Tool
12
+ * Deve ser chamado no início da aplicação
13
+ */
14
+ export declare function initFluwaTool(partialConfig?: Partial<FluwaConfig>): Promise<void>;
15
+ /**
16
+ * Desativar Fluwa
17
+ */
18
+ export declare function disableFluwaTool(): void;
19
+ /**
20
+ * Habilitar Fluwa
21
+ */
22
+ export declare function enableFluwaTool(): Promise<void>;
23
+ /**
24
+ * Verificar se Fluwa está ativo
25
+ */
26
+ export declare function isFluwaTooIialized(): boolean;
27
+ export * from './types';
28
+ export { Logger, LogLevel } from './core/Logger';
29
+ export { ConfigManager } from './core/Config';
package/dist/index.js ADDED
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ /**
3
+ * 🔧 Fluwa SDK
4
+ * Entry point principal do SDK
5
+ *
6
+ * Uso:
7
+ * import { initFluwaTool } from '@fluwa-tool/sdk';
8
+ * initFluwaTool({ serverUrl: 'http://localhost:5555' });
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.ConfigManager = exports.LogLevel = exports.Logger = void 0;
26
+ exports.initFluwaTool = initFluwaTool;
27
+ exports.disableFluwaTool = disableFluwaTool;
28
+ exports.enableFluwaTool = enableFluwaTool;
29
+ exports.isFluwaTooIialized = isFluwaTooIialized;
30
+ const types_1 = require("./types");
31
+ const Logger_1 = require("./core/Logger");
32
+ const Config_1 = require("./core/Config");
33
+ const HttpClient_1 = require("./features/communication/HttpClient");
34
+ const WebSocketClient_1 = require("./features/communication/WebSocketClient");
35
+ const FetchInterceptor_1 = require("./features/network/FetchInterceptor");
36
+ const RequestLogger_1 = require("./features/network/RequestLogger");
37
+ const MockResolver_1 = require("./features/network/MockResolver");
38
+ const IdGenerator_1 = require("./core/IdGenerator");
39
+ // ============================================
40
+ // ESTADO GLOBAL
41
+ // ============================================
42
+ let isInitialized = false;
43
+ let logger = Logger_1.defaultLogger;
44
+ let config;
45
+ let sessionId;
46
+ let httpClient;
47
+ let wsClient;
48
+ let fetchInterceptor;
49
+ let mockResolver;
50
+ // ============================================
51
+ // INICIALIZAÇÃO
52
+ // ============================================
53
+ /**
54
+ * Inicializar Fluwa-Tool
55
+ * Deve ser chamado no início da aplicação
56
+ */
57
+ async function initFluwaTool(partialConfig = {}) {
58
+ if (isInitialized) {
59
+ logger.warn('Fluwa já foi inicializado');
60
+ return;
61
+ }
62
+ try {
63
+ // 1. Configurar
64
+ config = (0, Config_1.getConfigManager)(partialConfig);
65
+ logger = new Logger_1.Logger('Fluwa', config.getConfig().debug ? Logger_1.LogLevel.DEBUG : Logger_1.LogLevel.INFO);
66
+ logger.success('Inicializando Fluwa-Tool');
67
+ logger.debug('Configuração', config.getConfig());
68
+ if (!config.isEnabled()) {
69
+ logger.warn('Fluwa desativado via config.enabled=false');
70
+ return;
71
+ }
72
+ // 2. Gerar session ID
73
+ sessionId = IdGenerator_1.idGenerator.generate();
74
+ logger.debug(`Session ID: ${sessionId}`);
75
+ // 3. Criar clientes HTTP e WebSocket
76
+ const { requestTimeout, serverUrl } = config.getConfig();
77
+ httpClient = new HttpClient_1.HttpClient(serverUrl, logger, requestTimeout || 5000);
78
+ wsClient = new WebSocketClient_1.WebSocketClient(serverUrl, logger, config.getAppName());
79
+ // 4. Criar resolvedor de mocks
80
+ mockResolver = new MockResolver_1.MockResolver(httpClient, logger);
81
+ // 5. Criar logger de requisições
82
+ const requestLogger = new RequestLogger_1.RequestLogger(httpClient, logger);
83
+ // 6. Criar interceptador de fetch
84
+ fetchInterceptor = new FetchInterceptor_1.FetchInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName());
85
+ // 7. Instalar interceptadores
86
+ fetchInterceptor.install();
87
+ // 8. Conectar WebSocket
88
+ logger.debug('Conectando ao WebSocket...');
89
+ try {
90
+ await wsClient.connect();
91
+ setupWebSocketListeners();
92
+ }
93
+ catch (error) {
94
+ logger.warn('Falha ao conectar WebSocket, continuando em modo offline', error);
95
+ }
96
+ // 9. Enviar init session
97
+ wsClient.send({
98
+ type: types_1.WebSocketMessageType.INIT_SESSION,
99
+ sessionId,
100
+ appName: config.getAppName(),
101
+ });
102
+ isInitialized = true;
103
+ logger.success('Fluwa-Tool inicializado com sucesso!');
104
+ }
105
+ catch (error) {
106
+ logger.error('Erro ao inicializar Fluwa', error);
107
+ throw error;
108
+ }
109
+ }
110
+ /**
111
+ * Configurar listeners do WebSocket
112
+ */
113
+ function setupWebSocketListeners() {
114
+ wsClient.on('message', (message) => {
115
+ try {
116
+ if (message?.type === types_1.WebSocketMessageType.SCENARIO_CHANGED) {
117
+ mockResolver.setActiveScenario(message.scenario || null);
118
+ }
119
+ }
120
+ catch (error) {
121
+ logger.warn('Erro ao processar mensagem WebSocket', error);
122
+ }
123
+ });
124
+ wsClient.on('disconnected', () => {
125
+ logger.warn('WebSocket desconectado');
126
+ });
127
+ wsClient.on('error', (error) => {
128
+ logger.error('Erro no WebSocket', error);
129
+ });
130
+ }
131
+ // ============================================
132
+ // CONTROLE
133
+ // ============================================
134
+ /**
135
+ * Desativar Fluwa
136
+ */
137
+ function disableFluwaTool() {
138
+ if (!isInitialized) {
139
+ return;
140
+ }
141
+ fetchInterceptor.uninstall();
142
+ wsClient.disconnect();
143
+ isInitialized = false;
144
+ logger.success('Fluwa-Tool desativado');
145
+ }
146
+ /**
147
+ * Habilitar Fluwa
148
+ */
149
+ async function enableFluwaTool() {
150
+ if (isInitialized) {
151
+ return;
152
+ }
153
+ fetchInterceptor.install();
154
+ try {
155
+ await wsClient.connect();
156
+ }
157
+ catch (error) {
158
+ logger.warn('Falha ao reconectar WebSocket', error);
159
+ }
160
+ isInitialized = true;
161
+ logger.success('Fluwa-Tool habilitado');
162
+ }
163
+ /**
164
+ * Verificar se Fluwa está ativo
165
+ */
166
+ function isFluwaTooIialized() {
167
+ return isInitialized;
168
+ }
169
+ // ============================================
170
+ // EXPORTS
171
+ // ============================================
172
+ __exportStar(require("./types"), exports);
173
+ var Logger_2 = require("./core/Logger");
174
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return Logger_2.Logger; } });
175
+ Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return Logger_2.LogLevel; } });
176
+ var Config_2 = require("./core/Config");
177
+ Object.defineProperty(exports, "ConfigManager", { enumerable: true, get: function () { return Config_2.ConfigManager; } });