@emaenriquez/projectmanager-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/dist/application/ConfigManager.d.ts +73 -0
- package/dist/application/ConfigManager.d.ts.map +1 -0
- package/dist/application/ConfigManager.js +253 -0
- package/dist/application/ConfigManager.js.map +1 -0
- package/dist/application/errors/ErrorHandler.d.ts +27 -0
- package/dist/application/errors/ErrorHandler.d.ts.map +1 -0
- package/dist/application/errors/ErrorHandler.js +88 -0
- package/dist/application/errors/ErrorHandler.js.map +1 -0
- package/dist/application/state/StateManager.d.ts +26 -0
- package/dist/application/state/StateManager.d.ts.map +1 -0
- package/dist/application/state/StateManager.js +114 -0
- package/dist/application/state/StateManager.js.map +1 -0
- package/dist/application/use_cases/AddProjectUseCase.d.ts +9 -0
- package/dist/application/use_cases/AddProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/AddProjectUseCase.js +85 -0
- package/dist/application/use_cases/AddProjectUseCase.js.map +1 -0
- package/dist/application/use_cases/ListProjectsUseCase.d.ts +7 -0
- package/dist/application/use_cases/ListProjectsUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/ListProjectsUseCase.js +14 -0
- package/dist/application/use_cases/ListProjectsUseCase.js.map +1 -0
- package/dist/application/use_cases/OpenProjectUseCase.d.ts +10 -0
- package/dist/application/use_cases/OpenProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/OpenProjectUseCase.js +168 -0
- package/dist/application/use_cases/OpenProjectUseCase.js.map +1 -0
- package/dist/application/use_cases/RemoveProjectUseCase.d.ts +7 -0
- package/dist/application/use_cases/RemoveProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/RemoveProjectUseCase.js +24 -0
- package/dist/application/use_cases/RemoveProjectUseCase.js.map +1 -0
- package/dist/application/use_cases/ScanProjectsUseCase.d.ts +13 -0
- package/dist/application/use_cases/ScanProjectsUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/ScanProjectsUseCase.js +57 -0
- package/dist/application/use_cases/ScanProjectsUseCase.js.map +1 -0
- package/dist/application/use_cases/SyncProjectsUseCase.d.ts +12 -0
- package/dist/application/use_cases/SyncProjectsUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/SyncProjectsUseCase.js +74 -0
- package/dist/application/use_cases/SyncProjectsUseCase.js.map +1 -0
- package/dist/application/use_cases/SystemDiagnostics.d.ts +16 -0
- package/dist/application/use_cases/SystemDiagnostics.d.ts.map +1 -0
- package/dist/application/use_cases/SystemDiagnostics.js +35 -0
- package/dist/application/use_cases/SystemDiagnostics.js.map +1 -0
- package/dist/application/use_cases/TagProjectUseCase.d.ts +9 -0
- package/dist/application/use_cases/TagProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/TagProjectUseCase.js +41 -0
- package/dist/application/use_cases/TagProjectUseCase.js.map +1 -0
- package/dist/domain/patterns/ProjectPatterns.d.ts +47 -0
- package/dist/domain/patterns/ProjectPatterns.d.ts.map +1 -0
- package/dist/domain/patterns/ProjectPatterns.js +200 -0
- package/dist/domain/patterns/ProjectPatterns.js.map +1 -0
- package/dist/domain/services/GitService.d.ts +23 -0
- package/dist/domain/services/GitService.d.ts.map +1 -0
- package/dist/domain/services/GitService.js +155 -0
- package/dist/domain/services/GitService.js.map +1 -0
- package/dist/domain/services/IgnoreFileParser.d.ts +55 -0
- package/dist/domain/services/IgnoreFileParser.d.ts.map +1 -0
- package/dist/domain/services/IgnoreFileParser.js +200 -0
- package/dist/domain/services/IgnoreFileParser.js.map +1 -0
- package/dist/domain/services/ProjectScanner.d.ts +65 -0
- package/dist/domain/services/ProjectScanner.d.ts.map +1 -0
- package/dist/domain/services/ProjectScanner.js +207 -0
- package/dist/domain/services/ProjectScanner.js.map +1 -0
- package/dist/domain/services/TechnologyDetector.d.ts +78 -0
- package/dist/domain/services/TechnologyDetector.d.ts.map +1 -0
- package/dist/domain/services/TechnologyDetector.js +633 -0
- package/dist/domain/services/TechnologyDetector.js.map +1 -0
- package/dist/domain/services/ToolDetector.d.ts +74 -0
- package/dist/domain/services/ToolDetector.d.ts.map +1 -0
- package/dist/domain/services/ToolDetector.js +344 -0
- package/dist/domain/services/ToolDetector.js.map +1 -0
- package/dist/domain/services/index.d.ts +5 -0
- package/dist/domain/services/index.d.ts.map +1 -0
- package/dist/domain/services/index.js +12 -0
- package/dist/domain/services/index.js.map +1 -0
- package/dist/domain/types/Config.d.ts +37 -0
- package/dist/domain/types/Config.d.ts.map +1 -0
- package/dist/domain/types/Config.js +6 -0
- package/dist/domain/types/Config.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/database/DatabaseConnection.d.ts +88 -0
- package/dist/infrastructure/database/DatabaseConnection.d.ts.map +1 -0
- package/dist/infrastructure/database/DatabaseConnection.js +318 -0
- package/dist/infrastructure/database/DatabaseConnection.js.map +1 -0
- package/dist/infrastructure/database/DatabaseValidator.d.ts +154 -0
- package/dist/infrastructure/database/DatabaseValidator.d.ts.map +1 -0
- package/dist/infrastructure/database/DatabaseValidator.js +583 -0
- package/dist/infrastructure/database/DatabaseValidator.js.map +1 -0
- package/dist/infrastructure/database/index.d.ts +8 -0
- package/dist/infrastructure/database/index.d.ts.map +1 -0
- package/dist/infrastructure/database/index.js +14 -0
- package/dist/infrastructure/database/index.js.map +1 -0
- package/dist/infrastructure/database/migrations/001_initial.d.ts +24 -0
- package/dist/infrastructure/database/migrations/001_initial.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/001_initial.js +109 -0
- package/dist/infrastructure/database/migrations/001_initial.js.map +1 -0
- package/dist/infrastructure/database/migrations/Migration.d.ts +27 -0
- package/dist/infrastructure/database/migrations/Migration.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/Migration.js +3 -0
- package/dist/infrastructure/database/migrations/Migration.js.map +1 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.d.ts +52 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.js +167 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.js.map +1 -0
- package/dist/infrastructure/database/migrations/index.d.ts +10 -0
- package/dist/infrastructure/database/migrations/index.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/index.js +22 -0
- package/dist/infrastructure/database/migrations/index.js.map +1 -0
- package/dist/infrastructure/filesystem/DirectoryManager.d.ts +50 -0
- package/dist/infrastructure/filesystem/DirectoryManager.d.ts.map +1 -0
- package/dist/infrastructure/filesystem/DirectoryManager.js +143 -0
- package/dist/infrastructure/filesystem/DirectoryManager.js.map +1 -0
- package/dist/infrastructure/filesystem/index.d.ts +2 -0
- package/dist/infrastructure/filesystem/index.d.ts.map +1 -0
- package/dist/infrastructure/filesystem/index.js +6 -0
- package/dist/infrastructure/filesystem/index.js.map +1 -0
- package/dist/infrastructure/logging/LogRotator.d.ts +43 -0
- package/dist/infrastructure/logging/LogRotator.d.ts.map +1 -0
- package/dist/infrastructure/logging/LogRotator.js +172 -0
- package/dist/infrastructure/logging/LogRotator.js.map +1 -0
- package/dist/infrastructure/logging/Logger.d.ts +59 -0
- package/dist/infrastructure/logging/Logger.d.ts.map +1 -0
- package/dist/infrastructure/logging/Logger.js +182 -0
- package/dist/infrastructure/logging/Logger.js.map +1 -0
- package/dist/infrastructure/logging/index.d.ts +3 -0
- package/dist/infrastructure/logging/index.d.ts.map +1 -0
- package/dist/infrastructure/logging/index.js +8 -0
- package/dist/infrastructure/logging/index.js.map +1 -0
- package/dist/infrastructure/repositories/ProjectRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/ProjectRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/ProjectRepository.js +61 -0
- package/dist/infrastructure/repositories/ProjectRepository.js.map +1 -0
- package/dist/infrastructure/repositories/QueryBuilder.d.ts +24 -0
- package/dist/infrastructure/repositories/QueryBuilder.d.ts.map +1 -0
- package/dist/infrastructure/repositories/QueryBuilder.js +92 -0
- package/dist/infrastructure/repositories/QueryBuilder.js.map +1 -0
- package/dist/infrastructure/repositories/TagRepository.d.ts +18 -0
- package/dist/infrastructure/repositories/TagRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/TagRepository.js +66 -0
- package/dist/infrastructure/repositories/TagRepository.js.map +1 -0
- package/dist/infrastructure/repositories/TechnologyRepository.d.ts +16 -0
- package/dist/infrastructure/repositories/TechnologyRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/TechnologyRepository.js +46 -0
- package/dist/infrastructure/repositories/TechnologyRepository.js.map +1 -0
- package/dist/infrastructure/repositories/TransactionManager.d.ts +11 -0
- package/dist/infrastructure/repositories/TransactionManager.d.ts.map +1 -0
- package/dist/infrastructure/repositories/TransactionManager.js +21 -0
- package/dist/infrastructure/repositories/TransactionManager.js.map +1 -0
- package/dist/infrastructure/ui/ScreenManager.d.ts +11 -0
- package/dist/infrastructure/ui/ScreenManager.d.ts.map +1 -0
- package/dist/infrastructure/ui/ScreenManager.js +69 -0
- package/dist/infrastructure/ui/ScreenManager.js.map +1 -0
- package/dist/ui/cli/CLI.d.ts +9 -0
- package/dist/ui/cli/CLI.d.ts.map +1 -0
- package/dist/ui/cli/CLI.js +211 -0
- package/dist/ui/cli/CLI.js.map +1 -0
- package/dist/ui/components/DetailsPanel.d.ts +11 -0
- package/dist/ui/components/DetailsPanel.d.ts.map +1 -0
- package/dist/ui/components/DetailsPanel.js +181 -0
- package/dist/ui/components/DetailsPanel.js.map +1 -0
- package/dist/ui/components/ProjectListView.d.ts +15 -0
- package/dist/ui/components/ProjectListView.d.ts.map +1 -0
- package/dist/ui/components/ProjectListView.js +122 -0
- package/dist/ui/components/ProjectListView.js.map +1 -0
- package/dist/ui/tui/TUIApplication.d.ts +17 -0
- package/dist/ui/tui/TUIApplication.d.ts.map +1 -0
- package/dist/ui/tui/TUIApplication.js +532 -0
- package/dist/ui/tui/TUIApplication.js.map +1 -0
- package/dist/ui/tui/Theme.d.ts +25 -0
- package/dist/ui/tui/Theme.d.ts.map +1 -0
- package/dist/ui/tui/Theme.js +62 -0
- package/dist/ui/tui/Theme.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface IgnorePattern {
|
|
2
|
+
pattern: string;
|
|
3
|
+
negated: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Parser para archivos .project-hub-ignore
|
|
7
|
+
* Soporta:
|
|
8
|
+
* - Comentarios (líneas que comienzan con #)
|
|
9
|
+
* - Patrones glob simples (*, ?)
|
|
10
|
+
* - Negación (!)
|
|
11
|
+
*/
|
|
12
|
+
export declare class IgnoreFileParser {
|
|
13
|
+
/**
|
|
14
|
+
* Parsea un archivo .project-hub-ignore
|
|
15
|
+
* @param filePath Ruta al archivo .project-hub-ignore
|
|
16
|
+
* @returns Array de patrones de ignorar
|
|
17
|
+
*/
|
|
18
|
+
parseIgnoreFile(filePath: string): IgnorePattern[];
|
|
19
|
+
/**
|
|
20
|
+
* Parsea el contenido de un archivo .project-hub-ignore
|
|
21
|
+
* @param content Contenido del archivo
|
|
22
|
+
* @returns Array de patrones de ignorar
|
|
23
|
+
*/
|
|
24
|
+
parseContent(content: string): IgnorePattern[];
|
|
25
|
+
/**
|
|
26
|
+
* Normaliza una línea del archivo .project-hub-ignore
|
|
27
|
+
* @private
|
|
28
|
+
*/
|
|
29
|
+
private normalizeLine;
|
|
30
|
+
/**
|
|
31
|
+
* Normaliza un patrón para uso en coincidencia
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
private normalizePattern;
|
|
35
|
+
/**
|
|
36
|
+
* Verifica si una ruta coincide con patrones de ignorar
|
|
37
|
+
* @param dirPath Ruta del directorio
|
|
38
|
+
* @param patterns Patrones de ignorar
|
|
39
|
+
* @param baseDir Directorio base para resolución relativa (opcional)
|
|
40
|
+
* @returns true si la ruta debe ser ignorada
|
|
41
|
+
*/
|
|
42
|
+
matches(dirPath: string, patterns: IgnorePattern[], baseDir?: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Verifica si una ruta coincide con un patrón específico
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
private pathMatches;
|
|
48
|
+
/**
|
|
49
|
+
* Convierte un patrón glob a expresión regular
|
|
50
|
+
* Soporta: * (cualquier cosa excepto /), ** (múltiples niveles), ? (un carácter)
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
private globToRegex;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=IgnoreFileParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IgnoreFileParser.d.ts","sourceRoot":"","sources":["../../../src/domain/services/IgnoreFileParser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAclD;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE;IAO9C;;;OAGG;IACH,OAAO,CAAC,aAAa;IA2BrB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IA2B9E;;;OAGG;IACH,OAAO,CAAC,WAAW;IA4BnB;;;;OAIG;IACH,OAAO,CAAC,WAAW;CA4BpB"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.IgnoreFileParser = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
/**
|
|
40
|
+
* Parser para archivos .project-hub-ignore
|
|
41
|
+
* Soporta:
|
|
42
|
+
* - Comentarios (líneas que comienzan con #)
|
|
43
|
+
* - Patrones glob simples (*, ?)
|
|
44
|
+
* - Negación (!)
|
|
45
|
+
*/
|
|
46
|
+
class IgnoreFileParser {
|
|
47
|
+
/**
|
|
48
|
+
* Parsea un archivo .project-hub-ignore
|
|
49
|
+
* @param filePath Ruta al archivo .project-hub-ignore
|
|
50
|
+
* @returns Array de patrones de ignorar
|
|
51
|
+
*/
|
|
52
|
+
parseIgnoreFile(filePath) {
|
|
53
|
+
try {
|
|
54
|
+
if (!fs.existsSync(filePath)) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
58
|
+
return this.parseContent(content);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// Retornar array vacío si hay error al leer el archivo
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parsea el contenido de un archivo .project-hub-ignore
|
|
67
|
+
* @param content Contenido del archivo
|
|
68
|
+
* @returns Array de patrones de ignorar
|
|
69
|
+
*/
|
|
70
|
+
parseContent(content) {
|
|
71
|
+
return content
|
|
72
|
+
.split('\n')
|
|
73
|
+
.map((line) => this.normalizeLine(line))
|
|
74
|
+
.filter((line) => line !== null); // Filtrar líneas vacías
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Normaliza una línea del archivo .project-hub-ignore
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
normalizeLine(line) {
|
|
81
|
+
const trimmed = line.trim();
|
|
82
|
+
// Ignorar líneas vacías y comentarios
|
|
83
|
+
if (trimmed.length === 0 || trimmed.startsWith('#')) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
// Procesar negación (!)
|
|
87
|
+
let negated = false;
|
|
88
|
+
let pattern = trimmed;
|
|
89
|
+
if (pattern.startsWith('!')) {
|
|
90
|
+
negated = true;
|
|
91
|
+
pattern = pattern.slice(1).trim();
|
|
92
|
+
}
|
|
93
|
+
if (pattern.length === 0) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
pattern: this.normalizePattern(pattern),
|
|
98
|
+
negated,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Normaliza un patrón para uso en coincidencia
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
normalizePattern(pattern) {
|
|
106
|
+
// Eliminar barras iniciales
|
|
107
|
+
pattern = pattern.replace(/^\/+/, '');
|
|
108
|
+
// Eliminar barras finales
|
|
109
|
+
pattern = pattern.replace(/\/+$/, '');
|
|
110
|
+
return pattern;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Verifica si una ruta coincide con patrones de ignorar
|
|
114
|
+
* @param dirPath Ruta del directorio
|
|
115
|
+
* @param patterns Patrones de ignorar
|
|
116
|
+
* @param baseDir Directorio base para resolución relativa (opcional)
|
|
117
|
+
* @returns true si la ruta debe ser ignorada
|
|
118
|
+
*/
|
|
119
|
+
matches(dirPath, patterns, baseDir) {
|
|
120
|
+
let shouldIgnore = false;
|
|
121
|
+
// Obtener la ruta relativa si se proporciona baseDir
|
|
122
|
+
let relativePath = dirPath;
|
|
123
|
+
if (baseDir) {
|
|
124
|
+
try {
|
|
125
|
+
relativePath = path.relative(baseDir, dirPath).replace(/\\/g, '/');
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
relativePath = dirPath;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Procesar patrones en orden
|
|
132
|
+
for (const pattern of patterns) {
|
|
133
|
+
if (this.pathMatches(relativePath, pattern.pattern)) {
|
|
134
|
+
if (pattern.negated) {
|
|
135
|
+
shouldIgnore = false;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
shouldIgnore = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return shouldIgnore;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Verifica si una ruta coincide con un patrón específico
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
pathMatches(dirPath, pattern) {
|
|
149
|
+
// Normalizar separadores
|
|
150
|
+
const normalizedPath = dirPath.replace(/\\/g, '/');
|
|
151
|
+
// Si el patrón es exacto (sin wildcards), hacer coincidencia exacta
|
|
152
|
+
if (!pattern.includes('*') && !pattern.includes('?')) {
|
|
153
|
+
// Coincidencia exacta o como parte del nombre
|
|
154
|
+
const pathParts = normalizedPath.split('/');
|
|
155
|
+
const patternParts = pattern.split('/');
|
|
156
|
+
// Si es el nombre del directorio
|
|
157
|
+
if (pathParts[pathParts.length - 1] === pattern) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
// Si es parte de la ruta
|
|
161
|
+
if (normalizedPath === pattern || normalizedPath.endsWith('/' + pattern)) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
// Conversión de glob pattern a regex
|
|
167
|
+
const regexPattern = this.globToRegex(pattern);
|
|
168
|
+
return regexPattern.test(normalizedPath);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Convierte un patrón glob a expresión regular
|
|
172
|
+
* Soporta: * (cualquier cosa excepto /), ** (múltiples niveles), ? (un carácter)
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
globToRegex(glob) {
|
|
176
|
+
// Escapar caracteres especiales de regex excepto * y ?
|
|
177
|
+
let regex = glob
|
|
178
|
+
.replace(/\./g, '\\.')
|
|
179
|
+
.replace(/\+/g, '\\+')
|
|
180
|
+
.replace(/\{/g, '\\{')
|
|
181
|
+
.replace(/\}/g, '\\}')
|
|
182
|
+
.replace(/\(/g, '\\(')
|
|
183
|
+
.replace(/\)/g, '\\)')
|
|
184
|
+
.replace(/\|/g, '\\|')
|
|
185
|
+
.replace(/\^/g, '\\^')
|
|
186
|
+
.replace(/\$/g, '\\$');
|
|
187
|
+
// Procesar ** (múltiples niveles)
|
|
188
|
+
regex = regex.replace(/\*\*/g, '___DOUBLESTAR___');
|
|
189
|
+
// Procesar * (un nivel)
|
|
190
|
+
regex = regex.replace(/\*/g, '[^/]*');
|
|
191
|
+
// Procesar ? (un carácter)
|
|
192
|
+
regex = regex.replace(/\?/g, '[^/]');
|
|
193
|
+
// Reemplazar el marcador de **
|
|
194
|
+
regex = regex.replace(/___DOUBLESTAR___/g, '.*');
|
|
195
|
+
// Hacer que coincida en cualquier parte del path
|
|
196
|
+
return new RegExp(`(^|/)${regex}(/|$)`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
exports.IgnoreFileParser = IgnoreFileParser;
|
|
200
|
+
//# sourceMappingURL=IgnoreFileParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IgnoreFileParser.js","sourceRoot":"","sources":["../../../src/domain/services/IgnoreFileParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ProjectPattern } from '../patterns/ProjectPatterns';
|
|
2
|
+
export interface ProjectMetadata {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
timestamp: Date;
|
|
6
|
+
configFiles: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ScanResult {
|
|
9
|
+
projects: ProjectMetadata[];
|
|
10
|
+
scannedDirectories: number;
|
|
11
|
+
errors: ScanError[];
|
|
12
|
+
}
|
|
13
|
+
export interface ScanError {
|
|
14
|
+
path: string;
|
|
15
|
+
error: string;
|
|
16
|
+
severity: 'warning' | 'error';
|
|
17
|
+
}
|
|
18
|
+
export declare class ProjectScanner {
|
|
19
|
+
private readonly MAX_DEPTH;
|
|
20
|
+
private ignorePatterns;
|
|
21
|
+
private scannedDirectories;
|
|
22
|
+
private errors;
|
|
23
|
+
private ignoreFileParser;
|
|
24
|
+
private rootPath;
|
|
25
|
+
/**
|
|
26
|
+
* Escanea un directorio recursivamente en busca de proyectos
|
|
27
|
+
* @param rootPath Ruta raíz a escanear
|
|
28
|
+
* @param depth Profundidad máxima de escaneo (por defecto: MAX_DEPTH)
|
|
29
|
+
* @param patterns Patrones de configuración a detectar (por defecto: todos)
|
|
30
|
+
* @param ignoreFile Nombre del archivo de ignorar (por defecto: .project-hub-ignore)
|
|
31
|
+
* @returns ScanResult con proyectos encontrados, estadísticas y errores
|
|
32
|
+
*/
|
|
33
|
+
scanDirectory(rootPath: string, depth?: number, patterns?: ProjectPattern[], ignoreFile?: string): ScanResult;
|
|
34
|
+
/**
|
|
35
|
+
* Escanea recursivamente un directorio en busca de proyectos
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
private scanDirectoryRecursive;
|
|
39
|
+
/**
|
|
40
|
+
* Busca archivos de configuración en el directorio actual
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
private findConfigFiles;
|
|
44
|
+
/**
|
|
45
|
+
* Carga patrones de ignorar desde un archivo .project-hub-ignore
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
private loadIgnoreFile;
|
|
49
|
+
/**
|
|
50
|
+
* Verifica si una ruta debe ser ignorada según los patrones cargados
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
private shouldIgnore;
|
|
54
|
+
/**
|
|
55
|
+
* Obtiene el timestamp de creación/modificación del directorio
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
private getDirectoryTimestamp;
|
|
59
|
+
/**
|
|
60
|
+
* Resuelve una ruta relativa a absoluta, soportando ~
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
private resolvePath;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=ProjectScanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectScanner.d.ts","sourceRoot":"","sources":["../../../src/domain/services/ProjectScanner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;CAC/B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAM;IAChC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAc;IAE9B;;;;;;;OAOG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAuB,EAC9B,QAAQ,CAAC,EAAE,cAAc,EAAE,EAC3B,UAAU,GAAE,MAA8B,GACzC,UAAU;IA6Cb;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAwE9B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAWtB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAQpB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;;OAGG;IACH,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ProjectScanner = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const ProjectPatterns_1 = require("../patterns/ProjectPatterns");
|
|
40
|
+
const IgnoreFileParser_1 = require("./IgnoreFileParser");
|
|
41
|
+
class ProjectScanner {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.MAX_DEPTH = 10;
|
|
44
|
+
this.ignorePatterns = [];
|
|
45
|
+
this.scannedDirectories = 0;
|
|
46
|
+
this.errors = [];
|
|
47
|
+
this.ignoreFileParser = new IgnoreFileParser_1.IgnoreFileParser();
|
|
48
|
+
this.rootPath = '';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Escanea un directorio recursivamente en busca de proyectos
|
|
52
|
+
* @param rootPath Ruta raíz a escanear
|
|
53
|
+
* @param depth Profundidad máxima de escaneo (por defecto: MAX_DEPTH)
|
|
54
|
+
* @param patterns Patrones de configuración a detectar (por defecto: todos)
|
|
55
|
+
* @param ignoreFile Nombre del archivo de ignorar (por defecto: .project-hub-ignore)
|
|
56
|
+
* @returns ScanResult con proyectos encontrados, estadísticas y errores
|
|
57
|
+
*/
|
|
58
|
+
scanDirectory(rootPath, depth = this.MAX_DEPTH, patterns, ignoreFile = '.project-hub-ignore') {
|
|
59
|
+
this.scannedDirectories = 0;
|
|
60
|
+
this.errors = [];
|
|
61
|
+
this.ignorePatterns = [];
|
|
62
|
+
const absolutePath = this.resolvePath(rootPath);
|
|
63
|
+
this.rootPath = absolutePath;
|
|
64
|
+
// Validar que el directorio existe
|
|
65
|
+
if (!fs.existsSync(absolutePath)) {
|
|
66
|
+
this.errors.push({
|
|
67
|
+
path: rootPath,
|
|
68
|
+
error: `Directory does not exist: ${absolutePath}`,
|
|
69
|
+
severity: 'error',
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
projects: [],
|
|
73
|
+
scannedDirectories: 0,
|
|
74
|
+
errors: this.errors,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Cargar patrones de ignorar desde el directorio raíz
|
|
78
|
+
this.loadIgnoreFile(absolutePath, ignoreFile);
|
|
79
|
+
const patternsToUse = patterns || (0, ProjectPatterns_1.getAllPatterns)();
|
|
80
|
+
const projects = [];
|
|
81
|
+
// Realizar escaneo recursivo
|
|
82
|
+
const foundProjects = this.scanDirectoryRecursive(absolutePath, depth, patternsToUse, ignoreFile);
|
|
83
|
+
projects.push(...foundProjects);
|
|
84
|
+
return {
|
|
85
|
+
projects,
|
|
86
|
+
scannedDirectories: this.scannedDirectories,
|
|
87
|
+
errors: this.errors,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Escanea recursivamente un directorio en busca de proyectos
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
scanDirectoryRecursive(currentPath, remainingDepth, patterns, ignoreFile) {
|
|
95
|
+
const projects = [];
|
|
96
|
+
// Verificar límite de profundidad
|
|
97
|
+
if (remainingDepth <= 0) {
|
|
98
|
+
return projects;
|
|
99
|
+
}
|
|
100
|
+
// Verificar si debe ser ignorado
|
|
101
|
+
if (this.shouldIgnore(currentPath)) {
|
|
102
|
+
return projects;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
this.scannedDirectories++;
|
|
106
|
+
// Leer archivos en el directorio actual
|
|
107
|
+
const files = fs.readdirSync(currentPath, { withFileTypes: true });
|
|
108
|
+
// Cargar patrones de ignorar del directorio actual
|
|
109
|
+
this.loadIgnoreFile(currentPath, ignoreFile);
|
|
110
|
+
// Buscar archivos de configuración que indiquen un proyecto
|
|
111
|
+
const configFiles = this.findConfigFiles(files, patterns);
|
|
112
|
+
if (configFiles.length > 0) {
|
|
113
|
+
const projectMetadata = {
|
|
114
|
+
name: path.basename(currentPath),
|
|
115
|
+
path: currentPath,
|
|
116
|
+
timestamp: this.getDirectoryTimestamp(currentPath),
|
|
117
|
+
configFiles,
|
|
118
|
+
};
|
|
119
|
+
projects.push(projectMetadata);
|
|
120
|
+
// No continuar buscando en subdirectorios de un proyecto detectado
|
|
121
|
+
// (evitar detectar sub-proyectos)
|
|
122
|
+
return projects;
|
|
123
|
+
}
|
|
124
|
+
// Buscar en subdirectorios
|
|
125
|
+
for (const file of files) {
|
|
126
|
+
if (file.isDirectory() && !file.name.startsWith('.')) {
|
|
127
|
+
const subPath = path.join(currentPath, file.name);
|
|
128
|
+
if (!this.shouldIgnore(subPath)) {
|
|
129
|
+
const subProjects = this.scanDirectoryRecursive(subPath, remainingDepth - 1, patterns, ignoreFile);
|
|
130
|
+
projects.push(...subProjects);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
137
|
+
this.errors.push({
|
|
138
|
+
path: currentPath,
|
|
139
|
+
error: `Failed to scan directory: ${errorMessage}`,
|
|
140
|
+
severity: 'warning',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return projects;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Busca archivos de configuración en el directorio actual
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
findConfigFiles(files, patterns) {
|
|
150
|
+
const configFiles = [];
|
|
151
|
+
const fileNames = new Set(files.map((f) => f.name));
|
|
152
|
+
for (const pattern of patterns) {
|
|
153
|
+
if (fileNames.has(pattern.filename)) {
|
|
154
|
+
configFiles.push(pattern.filename);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return configFiles;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Carga patrones de ignorar desde un archivo .project-hub-ignore
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
loadIgnoreFile(dirPath, ignoreFile) {
|
|
164
|
+
const ignoreFilePath = path.join(dirPath, ignoreFile);
|
|
165
|
+
try {
|
|
166
|
+
const patterns = this.ignoreFileParser.parseIgnoreFile(ignoreFilePath);
|
|
167
|
+
this.ignorePatterns.push(...patterns);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
// Fallar silenciosamente si no se puede leer el archivo
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Verifica si una ruta debe ser ignorada según los patrones cargados
|
|
175
|
+
* @private
|
|
176
|
+
*/
|
|
177
|
+
shouldIgnore(dirPath) {
|
|
178
|
+
return this.ignoreFileParser.matches(dirPath, this.ignorePatterns, this.rootPath);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Obtiene el timestamp de creación/modificación del directorio
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
getDirectoryTimestamp(dirPath) {
|
|
185
|
+
try {
|
|
186
|
+
const stats = fs.statSync(dirPath);
|
|
187
|
+
// Usar birthtime si está disponible, sino mtime
|
|
188
|
+
return stats.birthtime || stats.mtime;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return new Date();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Resuelve una ruta relativa a absoluta, soportando ~
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
resolvePath(dirPath) {
|
|
199
|
+
if (dirPath.startsWith('~')) {
|
|
200
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
201
|
+
return path.join(homeDir, dirPath.slice(1));
|
|
202
|
+
}
|
|
203
|
+
return path.resolve(dirPath);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.ProjectScanner = ProjectScanner;
|
|
207
|
+
//# sourceMappingURL=ProjectScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectScanner.js","sourceRoot":"","sources":["../../../src/domain/services/ProjectScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a detected technology in a project
|
|
3
|
+
*/
|
|
4
|
+
export interface DetectedTechnology {
|
|
5
|
+
name: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
category: 'language' | 'framework' | 'tool';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* TechnologyDetector detects programming languages, frameworks, and tools
|
|
11
|
+
* used in a project by analyzing configuration files
|
|
12
|
+
*/
|
|
13
|
+
export declare class TechnologyDetector {
|
|
14
|
+
/**
|
|
15
|
+
* Detect all technologies in a project
|
|
16
|
+
* @param projectPath Path to the project directory
|
|
17
|
+
* @returns Array of detected technologies
|
|
18
|
+
*/
|
|
19
|
+
detect(projectPath: string): DetectedTechnology[];
|
|
20
|
+
/**
|
|
21
|
+
* Detect Node.js/TypeScript/JavaScript from package.json
|
|
22
|
+
*/
|
|
23
|
+
detectFromPackageJson(projectPath: string): DetectedTechnology[];
|
|
24
|
+
/**
|
|
25
|
+
* Detect Python from requirements.txt or pyproject.toml
|
|
26
|
+
*/
|
|
27
|
+
detectFromRequirements(projectPath: string): DetectedTechnology[];
|
|
28
|
+
/**
|
|
29
|
+
* Detect Rust from Cargo.toml
|
|
30
|
+
*/
|
|
31
|
+
detectFromCargoToml(projectPath: string): DetectedTechnology[];
|
|
32
|
+
/**
|
|
33
|
+
* Detect Go from go.mod
|
|
34
|
+
*/
|
|
35
|
+
detectFromGoMod(projectPath: string): DetectedTechnology[];
|
|
36
|
+
/**
|
|
37
|
+
* Detect Java from pom.xml or build.gradle
|
|
38
|
+
*/
|
|
39
|
+
detectFromPom(projectPath: string): DetectedTechnology[];
|
|
40
|
+
/**
|
|
41
|
+
* Detect PHP from composer.json
|
|
42
|
+
*/
|
|
43
|
+
detectFromComposerJson(projectPath: string): DetectedTechnology[];
|
|
44
|
+
/**
|
|
45
|
+
* Detect Ruby from Gemfile
|
|
46
|
+
*/
|
|
47
|
+
detectFromGemfile(projectPath: string): DetectedTechnology[];
|
|
48
|
+
/**
|
|
49
|
+
* Detect Python frameworks from requirements content
|
|
50
|
+
*/
|
|
51
|
+
private detectPythonFrameworks;
|
|
52
|
+
/**
|
|
53
|
+
* Detect frameworks from npm dependencies
|
|
54
|
+
*/
|
|
55
|
+
private detectFrameworksFromDependencies;
|
|
56
|
+
/**
|
|
57
|
+
* Parse JSON content
|
|
58
|
+
*/
|
|
59
|
+
private parseJSON;
|
|
60
|
+
/**
|
|
61
|
+
* Extract Node.js version from lock files (package-lock.json, yarn.lock, pnpm-lock.yaml)
|
|
62
|
+
*/
|
|
63
|
+
private extractNodeVersionFromLockFile;
|
|
64
|
+
/**
|
|
65
|
+
* Extract Python version from lock files or virtual environment
|
|
66
|
+
*/
|
|
67
|
+
private extractPythonVersionFromLockFile;
|
|
68
|
+
/**
|
|
69
|
+
* Extract Java version from Maven or Gradle build files
|
|
70
|
+
*/
|
|
71
|
+
private extractJavaVersionFromBuildFiles;
|
|
72
|
+
/**
|
|
73
|
+
* Extract version from version string
|
|
74
|
+
* Handles common formats like "^1.0.0", "~1.0.0", "1.0.0", etc.
|
|
75
|
+
*/
|
|
76
|
+
private extractVersion;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=TechnologyDetector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TechnologyDetector.d.ts","sourceRoot":"","sources":["../../../src/domain/services/TechnologyDetector.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;CAC7C;AAED;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B;;;;OAIG;IACI,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAuCxD;;OAEG;IACI,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAgDvE;;OAEG;IACI,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAuDxE;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAuBrE;;OAEG;IACI,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAuBjE;;OAEG;IACI,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IA0E/D;;OAEG;IACI,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IA8CxE;;OAEG;IACI,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IA2CnE;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAkExC;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACH,OAAO,CAAC,8BAA8B;IAgDtC;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAmDxC;;OAEG;IACH,OAAO,CAAC,gCAAgC;IAgCxC;;;OAGG;IACH,OAAO,CAAC,cAAc;CAYvB"}
|