coolify-deployment-cli
Version:
CLI tool for Coolify deployments
146 lines (124 loc) • 4.18 kB
JavaScript
class ResourceDetector {
constructor() {
this.domainPatterns = [
// Exact domain match
(domain) => domain,
// Domain with http/https
(domain) => `https://${domain}`,
(domain) => `http://${domain}`,
// Domain with www
(domain) => `www.${domain}`,
// Domain parts (subdomain and main domain)
(domain) => {
const parts = domain.split('.');
return parts.length > 2 ? parts.slice(1).join('.') : domain;
},
// Wildcard patterns
(domain) => `*.${domain}`,
// Base domain
(domain) => {
const parts = domain.split('.');
return parts.length > 2 ? parts.slice(-2).join('.') : domain;
}
];
}
searchForDomain(content, targetDomain) {
const foundVariations = [];
// Try all domain pattern variations
for (const pattern of this.domainPatterns) {
const variation = pattern(targetDomain);
if (content.includes(variation)) {
foundVariations.push({
pattern: variation,
context: this.extractContext(content, variation)
});
}
}
// Also search for partial matches
const partialMatches = this.searchPartialMatches(content, targetDomain);
return {
exactMatches: foundVariations,
partialMatches: partialMatches,
found: foundVariations.length > 0 || partialMatches.length > 0
};
}
searchPartialMatches(content, targetDomain) {
const parts = targetDomain.split('.');
const matches = [];
// Search for subdomain parts
for (let i = 0; i < parts.length - 1; i++) {
const partial = parts.slice(i).join('.');
if (content.includes(partial) && partial.length > 3) {
matches.push({
pattern: partial,
context: this.extractContext(content, partial),
type: 'partial'
});
}
}
return matches;
}
extractContext(content, searchTerm, contextLines = 3) {
const lines = content.split('\n');
const contexts = [];
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes(searchTerm)) {
const start = Math.max(0, i - contextLines);
const end = Math.min(lines.length - 1, i + contextLines);
const context = lines.slice(start, end + 1).join('\n');
contexts.push({
lineNumber: i + 1,
context: context,
cleanLine: lines[i].replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim()
});
}
}
return contexts;
}
extractAllDomains(content) {
const domainRegex = /\b[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}\b/g;
const domains = content.match(domainRegex) || [];
const uniqueDomains = [...new Set(domains)];
return uniqueDomains
.filter(domain =>
domain.length > 5 &&
!domain.includes('google') &&
!domain.includes('cloudflare') &&
!domain.includes('jsdelivr') &&
!domain.includes('fonts') &&
!domain.includes('github')
)
.slice(0, 20); // Limit to first 20 domains
}
extractProjectData(content) {
const projectData = {
projects: [],
environments: [],
applications: [],
services: []
};
// Extract project IDs
const projectMatches = content.match(/data-project-id="([^"]+)"/gi) || [];
projectData.projects = projectMatches.map(match =>
match.match(/data-project-id="([^"]+)"/)[1]
);
// Extract environment IDs
const envMatches = content.match(/data-environment-id="([^"]+)"/gi) || [];
projectData.environments = envMatches.map(match =>
match.match(/data-environment-id="([^"]+)"/)[1]
);
// Extract application IDs
const appMatches = content.match(/data-application-id="([^"]+)"/gi) || [];
projectData.applications = appMatches.map(match =>
match.match(/data-application-id="([^"]+)"/)[1]
);
// Extract service information
const serviceLinks = content.match(/href="\/project\/([^"]+)"/gi) || [];
projectData.services = serviceLinks.map(link =>
link.match(/href="\/project\/([^"]+)"/)[1]
);
return projectData;
}
}
module.exports = ResourceDetector;