types-nora-api 0.0.145 → 0.0.147

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/dist/classes.d.ts CHANGED
@@ -734,18 +734,17 @@ type PaginaChave = keyof typeof PAGINAS;
734
734
  type PaginaObjeto = typeof PAGINAS[PaginaChave];
735
735
  type TelemetryConnectionInfo = {
736
736
  socketId: string;
737
- userId?: number;
738
737
  username?: string;
739
738
  ip: string;
740
739
  userAgent?: string;
741
740
  connectedAt: number;
742
741
  };
743
- type TelemetryEventLog<T = any> = {
742
+ type TelemetryEventLog<TPayload extends Record<string, unknown> = Record<string, unknown>> = {
744
743
  direction: 'in' | 'out';
745
744
  event: string;
746
745
  socketId: string;
747
- userId?: number;
748
- payload: T;
746
+ username?: string;
747
+ payload: TPayload;
749
748
  timestamp: number;
750
749
  };
751
750
  type TelemetrySnapshot = {
@@ -0,0 +1,27 @@
1
+ /**
2
+ * CONFIGURAÇÃO DE EXTRAÇÃO DE TIPOS
3
+ * Arquivo: extrairClasses.config.ts
4
+ */
5
+ export declare const FilterType: {
6
+ readonly ALL: "ALL";
7
+ readonly MARKED: "MARKED";
8
+ };
9
+ export type FilterType = typeof FilterType[keyof typeof FilterType];
10
+ export interface ExtractionSource {
11
+ source: string;
12
+ filter: FilterType;
13
+ description?: string;
14
+ }
15
+ export interface OutputConfig {
16
+ file: string;
17
+ header: string;
18
+ }
19
+ /**
20
+ * CONFIGURAÇÃO PRINCIPAL DE EXTRAÇÃO
21
+ */
22
+ export declare const EXTRACTION_CONFIG: readonly ExtractionSource[];
23
+ export declare const OUTPUT_CONFIG: OutputConfig;
24
+ /**
25
+ * VALIDAÇÃO DA CONFIGURAÇÃO
26
+ */
27
+ export declare function validateConfig(): boolean;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * CONFIGURAÇÃO DE EXTRAÇÃO DE TIPOS
3
+ * Arquivo: extrairClasses.config.ts
4
+ */
5
+ import * as path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import { dirname } from 'path';
8
+ // Obter __dirname em ES Modules
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ // CORREÇÃO: Estamos em src/@types/scripts/, precisamos subir 2 níveis para src/
12
+ // e então acessar modules/ e shared/ que estão no MESMO nível de @types/
13
+ const SRC_ROOT = path.resolve(__dirname, '../../');
14
+ console.log('🔧 SRC_ROOT:', SRC_ROOT);
15
+ // Tipos de filtro disponíveis
16
+ export const FilterType = {
17
+ ALL: 'ALL',
18
+ MARKED: 'MARKED'
19
+ };
20
+ /**
21
+ * CONFIGURAÇÃO PRINCIPAL DE EXTRAÇÃO
22
+ */
23
+ export const EXTRACTION_CONFIG = [
24
+ {
25
+ source: path.join(SRC_ROOT, 'modules/**/*.type.ts'),
26
+ filter: FilterType.ALL,
27
+ description: 'Todos os arquivos .type.ts dentro de src/modules'
28
+ },
29
+ {
30
+ source: path.join(SRC_ROOT, 'shared/types.ts'),
31
+ filter: FilterType.MARKED,
32
+ description: 'Arquivo src/shared/types.ts (apenas com @tipoCompartilhadoFront)'
33
+ },
34
+ {
35
+ source: path.join(SRC_ROOT, 'shared/ws.types.ts'),
36
+ filter: FilterType.ALL,
37
+ description: 'Arquivo src/shared/ws.types.ts (todas as definições exportadas)'
38
+ }
39
+ ];
40
+ export const OUTPUT_CONFIG = {
41
+ file: path.resolve(__dirname, '../src/classes.ts'),
42
+ header: '// AUTO-GENERATED FILE - DO NOT EDIT\n// Gerado automaticamente por extrairClasses.ts\n\n'
43
+ };
44
+ /**
45
+ * VALIDAÇÃO DA CONFIGURAÇÃO
46
+ */
47
+ export function validateConfig() {
48
+ const errors = [];
49
+ EXTRACTION_CONFIG.forEach((config, index) => {
50
+ if (!Object.values(FilterType).includes(config.filter)) {
51
+ errors.push(`Configuração [${index}]: Filtro '${config.filter}' não é válido`);
52
+ }
53
+ if (!config.source || typeof config.source !== 'string') {
54
+ errors.push(`Configuração [${index}]: Source deve ser uma string não vazia`);
55
+ }
56
+ });
57
+ if (!OUTPUT_CONFIG.file || typeof OUTPUT_CONFIG.file !== 'string') {
58
+ errors.push('OUTPUT_CONFIG.file deve ser uma string não vazia');
59
+ }
60
+ if (errors.length > 0) {
61
+ throw new Error(`Erro na configuração:\n${errors.join('\n')}`);
62
+ }
63
+ return true;
64
+ }
65
+ // Validação automática
66
+ validateConfig();
@@ -0,0 +1,9 @@
1
+ /**
2
+ * SCRIPT PRINCIPAL DE EXTRAÇÃO DE TIPOS
3
+ * Arquivo: extrairClasses.ts
4
+ */
5
+ /**
6
+ * Função principal do script
7
+ */
8
+ declare function main(): Promise<void>;
9
+ export default main;
@@ -0,0 +1,161 @@
1
+ /**
2
+ * SCRIPT PRINCIPAL DE EXTRAÇÃO DE TIPOS
3
+ * Arquivo: extrairClasses.ts
4
+ */
5
+ import { existsSync, writeFileSync } from 'fs';
6
+ import * as path from 'path';
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname } from 'path';
9
+ // Configurações e utilitários
10
+ import { EXTRACTION_CONFIG, OUTPUT_CONFIG, validateConfig } from './extrairClasses.config.js';
11
+ import { findTypeFiles, ensureDirectoryExists, processFile, consolidateResults } from './extrairClasses.utils.js';
12
+ // ==================================================
13
+ // INICIALIZAÇÃO E CONFIGURAÇÃO
14
+ // ==================================================
15
+ // Obter __dirname em ES Modules
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ // ==================================================
19
+ // FUNÇÕES AUXILIARES
20
+ // ==================================================
21
+ /**
22
+ * Extrai mensagem de erro de forma segura
23
+ */
24
+ function getErrorMessage(error) {
25
+ if (error instanceof Error) {
26
+ return error.message;
27
+ }
28
+ return String(error);
29
+ }
30
+ // ==================================================
31
+ // FUNÇÕES DE PROCESSAMENTO
32
+ // ==================================================
33
+ /**
34
+ * Expande padrões glob para lista de arquivos concretos
35
+ */
36
+ function expandSourcePattern(sourcePattern) {
37
+ // Se for um padrão glob (contém **)
38
+ if (sourcePattern.includes('**')) {
39
+ const baseDir = path.dirname(sourcePattern.replace(/\*\*/g, ''));
40
+ if (!existsSync(baseDir)) {
41
+ console.log(` ❌ Diretório base não existe: ${baseDir}`);
42
+ return [];
43
+ }
44
+ return findTypeFiles(baseDir);
45
+ }
46
+ // Se for um arquivo específico
47
+ return [sourcePattern];
48
+ }
49
+ /**
50
+ * Processa uma configuração de extração individual
51
+ */
52
+ function processExtractionConfig(config) {
53
+ console.log(`\n📁 ${config.description}`);
54
+ console.log(` Source: ${config.source}`);
55
+ console.log(` Filtro: ${config.filter}`);
56
+ try {
57
+ const filesToProcess = expandSourcePattern(config.source);
58
+ console.log(` Arquivos encontrados: ${filesToProcess.length}`);
59
+ const results = [];
60
+ for (const filePath of filesToProcess) {
61
+ if (existsSync(filePath)) {
62
+ const result = processFile(filePath, config.filter);
63
+ results.push(result);
64
+ console.log(` ✅ ${path.relative(process.cwd(), filePath)} → ${result.exportedNames.length} definições`);
65
+ }
66
+ else {
67
+ console.warn(` ⚠️ Arquivo não encontrado: ${filePath}`);
68
+ }
69
+ }
70
+ return results;
71
+ }
72
+ catch (error) {
73
+ console.error(` ❌ Erro:`, getErrorMessage(error));
74
+ return [];
75
+ }
76
+ }
77
+ /**
78
+ * Executa o pipeline completo de extração
79
+ */
80
+ function executeExtractionPipeline() {
81
+ console.log('🚀 INICIANDO EXTRAÇÃO DE TIPOS');
82
+ console.log('='.repeat(60));
83
+ const allProcessingResults = [];
84
+ // Processa cada configuração na ordem definida
85
+ for (const config of EXTRACTION_CONFIG) {
86
+ const configResults = processExtractionConfig(config);
87
+ allProcessingResults.push(...configResults);
88
+ }
89
+ return {
90
+ processingResults: allProcessingResults,
91
+ totalFiles: allProcessingResults.length,
92
+ totalDefinitions: allProcessingResults.reduce((sum, result) => sum + result.exportedNames.length, 0)
93
+ };
94
+ }
95
+ /**
96
+ * Salva o conteúdo consolidado no arquivo de saída
97
+ */
98
+ function saveConsolidatedFile(consolidatedContent) {
99
+ try {
100
+ ensureDirectoryExists(path.dirname(OUTPUT_CONFIG.file));
101
+ writeFileSync(OUTPUT_CONFIG.file, consolidatedContent, 'utf8');
102
+ console.log(`\n💾 ARQUIVO SALVO: ${OUTPUT_CONFIG.file}`);
103
+ }
104
+ catch (error) {
105
+ throw new Error(`Erro ao salvar arquivo: ${getErrorMessage(error)}`);
106
+ }
107
+ }
108
+ /**
109
+ * Exibe resumo da execução
110
+ */
111
+ function displayExecutionSummary(extractionResult, outputPath) {
112
+ console.log('\n' + '='.repeat(60));
113
+ console.log('📊 RESUMO FINAL');
114
+ console.log('='.repeat(60));
115
+ console.log(`📁 Arquivos processados: ${extractionResult.totalFiles}`);
116
+ console.log(`📝 Definições extraídas: ${extractionResult.totalDefinitions}`);
117
+ console.log(`💾 Arquivo gerado: ${outputPath}`);
118
+ if (extractionResult.totalFiles === 0) {
119
+ console.log('❌ NENHUM ARQUIVO FOI PROCESSADO!');
120
+ }
121
+ else {
122
+ console.log('✅ EXTRAÇÃO CONCLUÍDA COM SUCESSO!');
123
+ }
124
+ }
125
+ // ==================================================
126
+ // EXECUÇÃO PRINCIPAL
127
+ // ==================================================
128
+ /**
129
+ * Função principal do script
130
+ */
131
+ async function main() {
132
+ try {
133
+ console.log('🔧 Iniciando validação da configuração...');
134
+ validateConfig();
135
+ console.log('🔧 Executando pipeline de extração...');
136
+ const extractionResult = executeExtractionPipeline();
137
+ if (extractionResult.totalFiles === 0) {
138
+ console.log('\n⚠️ ATENÇÃO: Nenhum arquivo foi processado!');
139
+ console.log(' Verifique:');
140
+ console.log(' 1. Se os diretórios modules/ e shared/ existem');
141
+ console.log(' 2. Se há arquivos .type.ts em modules/');
142
+ console.log(' 3. Se shared/types.ts e shared/ws.types.ts existem');
143
+ return;
144
+ }
145
+ console.log('\n🔧 Consolidando resultados...');
146
+ const consolidatedContent = consolidateResults(extractionResult.processingResults, OUTPUT_CONFIG.header);
147
+ console.log('🔧 Salvando arquivo final...');
148
+ saveConsolidatedFile(consolidatedContent);
149
+ displayExecutionSummary(extractionResult, OUTPUT_CONFIG.file);
150
+ }
151
+ catch (error) {
152
+ console.error('\n❌ ERRO CRÍTICO:', getErrorMessage(error));
153
+ process.exit(1);
154
+ }
155
+ }
156
+ // EXECUTAR SEMPRE - SEM CONDIÇÃO
157
+ main().catch(error => {
158
+ console.error('Erro não tratado:', getErrorMessage(error));
159
+ process.exit(1);
160
+ });
161
+ export default main;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * UTILITÁRIOS PARA EXTRAÇÃO DE TIPOS
3
+ * Arquivo: extrairClasses.utils.ts
4
+ */
5
+ import * as ts from 'typescript';
6
+ export interface FileProcessingResult {
7
+ content: string;
8
+ exportedNames: string[];
9
+ filePath: string;
10
+ }
11
+ /**
12
+ * Marcador para definições que devem ser compartilhadas com o frontend
13
+ */
14
+ export declare const TIPO_COMPARTILHADO_FRONT_MARKER = "@tipoCompartilhadoFront";
15
+ /**
16
+ * Verifica se um nó AST possui o marcador @tipoCompartilhadoFront
17
+ */
18
+ export declare function hasTipoCompartilhadoFrontMarker(node: ts.Node, fileContent: string): boolean;
19
+ /**
20
+ * Verifica se uma declaração de variável deve ser considerada para extração
21
+ */
22
+ export declare function shouldExtractVariableStatement(node: ts.VariableStatement, snippet: string): boolean;
23
+ /**
24
+ * Verifica se um nó deve ser extraído baseado no filtro
25
+ */
26
+ export declare function shouldExtractNode(node: ts.Node, filterType: string, fileContent: string, snippet: string): boolean;
27
+ /**
28
+ * Remove palavras-chave de export mantendo a declaração
29
+ */
30
+ export declare function removeExportKeywords(content: string): string;
31
+ /**
32
+ * Extrai nomes de identificadores de declarações de variável
33
+ */
34
+ export declare function extractVariableNames(node: ts.VariableStatement): string[];
35
+ /**
36
+ * Extrai o nome de um nó nomeado
37
+ */
38
+ export declare function extractNodeName(node: ts.Node): string | null;
39
+ /**
40
+ * Encontra recursivamente arquivos .type.ts em um diretório
41
+ */
42
+ export declare function findTypeFiles(dir: string): string[];
43
+ /**
44
+ * Garante que um diretório existe (cria se necessário)
45
+ */
46
+ export declare function ensureDirectoryExists(dirPath: string): void;
47
+ /**
48
+ * Cria um SourceFile TypeScript para análise AST
49
+ */
50
+ export declare function createTypeScriptSourceFile(filePath: string, fileContent: string): ts.SourceFile;
51
+ /**
52
+ * Processa um arquivo individual e extrai suas definições
53
+ */
54
+ export declare function processFile(filePath: string, filterType: string): FileProcessingResult;
55
+ /**
56
+ * Consolida resultados de múltiplos arquivos em conteúdo final
57
+ */
58
+ export declare function consolidateResults(processingResults: FileProcessingResult[], header?: string): string;
@@ -0,0 +1,255 @@
1
+ /**
2
+ * UTILITÁRIOS PARA EXTRAÇÃO DE TIPOS
3
+ * Arquivo: extrairClasses.utils.ts
4
+ */
5
+ import * as ts from 'typescript';
6
+ import { readFileSync, existsSync, readdirSync, statSync, mkdirSync } from 'fs';
7
+ import { join } from 'path';
8
+ // ==================================================
9
+ // CONSTANTES E CONFIGURAÇÕES COMPARTILHADAS
10
+ // ==================================================
11
+ /**
12
+ * Marcador para definições que devem ser compartilhadas com o frontend
13
+ */
14
+ export const TIPO_COMPARTILHADO_FRONT_MARKER = '@tipoCompartilhadoFront';
15
+ // ==================================================
16
+ // TYPE GUARDS MELHORADOS
17
+ // ==================================================
18
+ function isNamedNode(node) {
19
+ return 'name' in node &&
20
+ node.name !== undefined &&
21
+ ts.isIdentifier(node.name);
22
+ }
23
+ function isVariableStatement(node) {
24
+ return ts.isVariableStatement(node);
25
+ }
26
+ function isClassDeclarationWithName(node) {
27
+ return ts.isClassDeclaration(node) && node.name !== undefined && ts.isIdentifier(node.name);
28
+ }
29
+ function isInterfaceDeclarationWithName(node) {
30
+ return ts.isInterfaceDeclaration(node) && node.name !== undefined && ts.isIdentifier(node.name);
31
+ }
32
+ function isTypeAliasDeclarationWithName(node) {
33
+ return ts.isTypeAliasDeclaration(node) && node.name !== undefined && ts.isIdentifier(node.name);
34
+ }
35
+ function isEnumDeclarationWithName(node) {
36
+ return ts.isEnumDeclaration(node) && node.name !== undefined && ts.isIdentifier(node.name);
37
+ }
38
+ function isModuleDeclarationWithName(node) {
39
+ return ts.isModuleDeclaration(node) && node.name !== undefined && ts.isIdentifier(node.name);
40
+ }
41
+ function isFunctionDeclarationWithName(node) {
42
+ return ts.isFunctionDeclaration(node) && node.name !== undefined && ts.isIdentifier(node.name);
43
+ }
44
+ // ==================================================
45
+ // VALIDAÇÕES E VERIFICAÇÕES
46
+ // ==================================================
47
+ /**
48
+ * Verifica se um nó AST possui o marcador @tipoCompartilhadoFront
49
+ */
50
+ export function hasTipoCompartilhadoFrontMarker(node, fileContent) {
51
+ const leadingComments = ts.getLeadingCommentRanges(fileContent, node.pos);
52
+ if (!leadingComments)
53
+ return false;
54
+ return leadingComments.some(comment => {
55
+ const commentText = fileContent.substring(comment.pos, comment.end);
56
+ return commentText.includes(TIPO_COMPARTILHADO_FRONT_MARKER);
57
+ });
58
+ }
59
+ /**
60
+ * Verifica se uma declaração de variável deve ser considerada para extração
61
+ */
62
+ export function shouldExtractVariableStatement(node, snippet) {
63
+ const declarationList = node.declarationList;
64
+ const declarations = declarationList.declarations;
65
+ const hasAsConst = snippet.includes(' as const');
66
+ const hasTypeAnnotation = declarations.some(decl => decl.type);
67
+ const hasComplexInitializer = declarations.some(decl => {
68
+ if (!decl.initializer)
69
+ return false;
70
+ return (ts.isObjectLiteralExpression(decl.initializer) ||
71
+ ts.isArrayLiteralExpression(decl.initializer) ||
72
+ ts.isCallExpression(decl.initializer) ||
73
+ ts.isArrowFunction(decl.initializer) ||
74
+ ts.isFunctionExpression(decl.initializer));
75
+ });
76
+ return hasAsConst || hasTypeAnnotation || hasComplexInitializer;
77
+ }
78
+ // ==================================================
79
+ // IDENTIFICAÇÃO DE TIPOS DE NÓ
80
+ // ==================================================
81
+ /**
82
+ * Verifica se um nó deve ser extraído baseado no filtro
83
+ */
84
+ export function shouldExtractNode(node, filterType, fileContent, snippet) {
85
+ // Para filtro ALL, extrai tudo que é extraível
86
+ if (filterType === 'ALL') {
87
+ if (isVariableStatement(node)) {
88
+ return shouldExtractVariableStatement(node, snippet);
89
+ }
90
+ return (isClassDeclarationWithName(node) ||
91
+ isInterfaceDeclarationWithName(node) ||
92
+ isTypeAliasDeclarationWithName(node) ||
93
+ isEnumDeclarationWithName(node) ||
94
+ isModuleDeclarationWithName(node) ||
95
+ isFunctionDeclarationWithName(node));
96
+ }
97
+ // Para filtro MARKED, só extrai se tiver o marcador
98
+ if (filterType === 'MARKED') {
99
+ const hasMarker = hasTipoCompartilhadoFrontMarker(node, fileContent);
100
+ if (isVariableStatement(node)) {
101
+ return hasMarker || shouldExtractVariableStatement(node, snippet);
102
+ }
103
+ return hasMarker && (isClassDeclarationWithName(node) ||
104
+ isInterfaceDeclarationWithName(node) ||
105
+ isTypeAliasDeclarationWithName(node) ||
106
+ isEnumDeclarationWithName(node) ||
107
+ isModuleDeclarationWithName(node) ||
108
+ isFunctionDeclarationWithName(node));
109
+ }
110
+ return false;
111
+ }
112
+ // ==================================================
113
+ // MANIPULAÇÃO DE CONTEÚDO
114
+ // ==================================================
115
+ /**
116
+ * Remove palavras-chave de export mantendo a declaração
117
+ */
118
+ export function removeExportKeywords(content) {
119
+ return content
120
+ .replace(/^export\s+(default\s+)?/gm, '')
121
+ .replace(/export\s+(default\s+)?\{[^}]+\};?\n?/g, '')
122
+ .trim();
123
+ }
124
+ /**
125
+ * Extrai nomes de identificadores de declarações de variável
126
+ */
127
+ export function extractVariableNames(node) {
128
+ const names = [];
129
+ const declarationList = node.declarationList;
130
+ declarationList.declarations.forEach(declaration => {
131
+ if (ts.isIdentifier(declaration.name)) {
132
+ names.push(declaration.name.text);
133
+ }
134
+ });
135
+ return names;
136
+ }
137
+ /**
138
+ * Extrai o nome de um nó nomeado
139
+ */
140
+ export function extractNodeName(node) {
141
+ if (isClassDeclarationWithName(node))
142
+ return node.name.text;
143
+ if (isInterfaceDeclarationWithName(node))
144
+ return node.name.text;
145
+ if (isTypeAliasDeclarationWithName(node))
146
+ return node.name.text;
147
+ if (isEnumDeclarationWithName(node))
148
+ return node.name.text;
149
+ if (isModuleDeclarationWithName(node))
150
+ return node.name.text;
151
+ if (isFunctionDeclarationWithName(node))
152
+ return node.name.text;
153
+ return null;
154
+ }
155
+ // ==================================================
156
+ // PROCESSAMENTO DE ARQUIVOS
157
+ // ==================================================
158
+ /**
159
+ * Encontra recursivamente arquivos .type.ts em um diretório
160
+ */
161
+ export function findTypeFiles(dir) {
162
+ if (!existsSync(dir)) {
163
+ throw new Error(`Diretório não encontrado: ${dir}`);
164
+ }
165
+ let results = [];
166
+ const items = readdirSync(dir);
167
+ for (const item of items) {
168
+ const itemPath = join(dir, item);
169
+ const stat = statSync(itemPath);
170
+ if (stat.isDirectory()) {
171
+ results = results.concat(findTypeFiles(itemPath));
172
+ }
173
+ else if (item.endsWith('.type.ts')) {
174
+ results.push(itemPath);
175
+ }
176
+ }
177
+ return results;
178
+ }
179
+ /**
180
+ * Garante que um diretório existe (cria se necessário)
181
+ */
182
+ export function ensureDirectoryExists(dirPath) {
183
+ if (!existsSync(dirPath)) {
184
+ mkdirSync(dirPath, { recursive: true });
185
+ }
186
+ }
187
+ /**
188
+ * Cria um SourceFile TypeScript para análise AST
189
+ */
190
+ export function createTypeScriptSourceFile(filePath, fileContent) {
191
+ return ts.createSourceFile(filePath, fileContent, ts.ScriptTarget.Latest, true);
192
+ }
193
+ // ==================================================
194
+ // PROCESSAMENTO MODULAR DO OUTPUT
195
+ // ==================================================
196
+ /**
197
+ * Processa um arquivo individual e extrai suas definições
198
+ */
199
+ export function processFile(filePath, filterType) {
200
+ if (!existsSync(filePath)) {
201
+ console.warn(`Arquivo não encontrado: ${filePath}`);
202
+ return { content: '', exportedNames: [], filePath };
203
+ }
204
+ const fileContent = readFileSync(filePath, 'utf8');
205
+ const sourceFile = createTypeScriptSourceFile(filePath, fileContent);
206
+ let extractedContent = '';
207
+ const exportedNames = [];
208
+ ts.forEachChild(sourceFile, (node) => {
209
+ const snippet = fileContent.substring(node.pos, node.end);
210
+ if (shouldExtractNode(node, filterType, fileContent, snippet)) {
211
+ const cleanedContent = removeExportKeywords(snippet);
212
+ extractedContent += `${cleanedContent}\n`;
213
+ // Coleta nomes baseado no tipo de nó
214
+ if (isVariableStatement(node)) {
215
+ const names = extractVariableNames(node);
216
+ exportedNames.push(...names);
217
+ }
218
+ else {
219
+ const name = extractNodeName(node);
220
+ if (name) {
221
+ exportedNames.push(name);
222
+ }
223
+ }
224
+ }
225
+ });
226
+ console.log(`Processado: ${filePath} (${exportedNames.length} definições)`);
227
+ return {
228
+ content: extractedContent,
229
+ exportedNames,
230
+ filePath
231
+ };
232
+ }
233
+ /**
234
+ * Consolida resultados de múltiplos arquivos em conteúdo final
235
+ */
236
+ export function consolidateResults(processingResults, header = '') {
237
+ let consolidatedContent = header;
238
+ const allExportedNames = new Set();
239
+ // Adiciona conteúdo de cada arquivo
240
+ for (const result of processingResults) {
241
+ if (result.content) {
242
+ consolidatedContent += result.content + '\n';
243
+ result.exportedNames.forEach(name => allExportedNames.add(name));
244
+ }
245
+ }
246
+ // Adiciona export final se houver nomes
247
+ if (allExportedNames.size > 0) {
248
+ consolidatedContent += `\nexport {\n ${Array.from(allExportedNames).join(',\n ')}\n};\n`;
249
+ }
250
+ // Limpeza final
251
+ return consolidatedContent
252
+ .replace(/\n{3,}/g, '\n\n')
253
+ .replace(/^\s+$/gm, '')
254
+ .trim();
255
+ }