faf-cli
Version:
😽 TURBO-CAT: The Rapid Catalytic Converter • Project DNA ✨ for ANY AI • Fully Integrated with React, Next.js, Svelte, TypeScript, Vite & n8n • FREE FOREVER • 10,000+ developers • Championship Edition
782 lines • 25.4 kB
JavaScript
;
/**
* 🏎️ Framework Detection Lookup Implementation
*
* Ready-to-use TypeScript/JSON structure for instant framework detection
* Import this directly into the .faf CLI for rapid framework identification
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FrameworkDetector = exports.PACKAGE_MANAGERS = exports.CONFIG_INDICATORS = exports.COMBINATION_PATTERNS = exports.DIRECTORY_PATTERNS = exports.UNIQUE_SIGNATURES = void 0;
exports.detectFramework = detectFramework;
/**
* TIER 1: Unique File Signatures
* These files identify specific frameworks with 100% confidence
*/
exports.UNIQUE_SIGNATURES = {
// Next.js
'next.config.js': {
framework: 'Next.js',
confidence: 100,
versionCheck: 'package.json:next',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
'next.config.mjs': {
framework: 'Next.js',
confidence: 100,
versionCheck: 'package.json:next',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
'next.config.ts': {
framework: 'Next.js 13+',
confidence: 100,
versionCheck: 'package.json:next',
ecosystem: 'npm/yarn/pnpm',
language: 'TypeScript'
},
// Nuxt
'nuxt.config.js': {
framework: 'Nuxt 2',
confidence: 100,
versionCheck: 'package.json:nuxt',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript'
},
'nuxt.config.ts': {
framework: 'Nuxt 3',
confidence: 100,
versionCheck: 'package.json:nuxt',
ecosystem: 'npm/yarn/pnpm',
language: 'TypeScript'
},
// Django
'manage.py': {
framework: 'Django',
confidence: 100,
additionalCheck: 'contains:django',
ecosystem: 'pip/pipenv/poetry',
language: 'Python'
},
// Laravel
'artisan': {
framework: 'Laravel',
confidence: 100,
additionalCheck: 'contains:laravel',
ecosystem: 'composer',
language: 'PHP'
},
// Angular
'angular.json': {
framework: 'Angular',
confidence: 100,
versionCheck: 'package.json:@angular/core',
ecosystem: 'npm/yarn/pnpm',
language: 'TypeScript'
},
// SvelteKit
'svelte.config.js': {
framework: 'SvelteKit',
confidence: 100,
versionCheck: 'package.json:@sveltejs/kit',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
// Remix
'remix.config.js': {
framework: 'Remix',
confidence: 100,
versionCheck: 'package.json:@remix-run/node',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
// Gatsby
'gatsby-config.js': {
framework: 'Gatsby',
confidence: 100,
versionCheck: 'package.json:gatsby',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript'
},
'gatsby-config.ts': {
framework: 'Gatsby 5+',
confidence: 100,
versionCheck: 'package.json:gatsby',
ecosystem: 'npm/yarn/pnpm',
language: 'TypeScript'
},
// Astro
'astro.config.mjs': {
framework: 'Astro',
confidence: 100,
versionCheck: 'package.json:astro',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
// Ruby on Rails
'Rakefile': {
framework: 'Ruby on Rails',
confidence: 85,
additionalCheck: 'contains:Rails',
ecosystem: 'bundler',
language: 'Ruby'
},
// Flutter
'pubspec.yaml': {
framework: 'Flutter/Dart',
confidence: 95,
additionalCheck: 'contains:flutter',
ecosystem: 'pub',
language: 'Dart'
},
// React Native
'metro.config.js': {
framework: 'React Native',
confidence: 95,
versionCheck: 'package.json:react-native',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
// Spring Boot
'mvnw': {
framework: 'Spring Boot/Maven',
confidence: 85,
additionalCheck: 'pom.xml:spring-boot',
ecosystem: 'maven',
language: 'Java'
},
'gradlew': {
framework: 'Spring Boot/Gradle',
confidence: 85,
additionalCheck: 'build.gradle:spring-boot',
ecosystem: 'gradle',
language: 'Java/Kotlin'
},
// Go
'go.mod': {
framework: 'Go',
confidence: 100,
ecosystem: 'go modules',
language: 'Go'
},
// Rust
'Cargo.toml': {
framework: 'Rust',
confidence: 100,
ecosystem: 'cargo',
language: 'Rust'
},
// Phoenix/Elixir
'mix.exs': {
framework: 'Phoenix/Elixir',
confidence: 95,
additionalCheck: 'contains:phoenix',
ecosystem: 'mix',
language: 'Elixir'
},
// RedwoodJS
'redwood.toml': {
framework: 'RedwoodJS',
confidence: 100,
versionCheck: 'package.json:@redwoodjs/core',
ecosystem: 'npm/yarn/pnpm',
language: 'JavaScript/TypeScript'
},
// Qwik
'qwik.config.ts': {
framework: 'Qwik',
confidence: 100,
versionCheck: 'package.json:@builder.io/qwik',
ecosystem: 'npm/yarn/pnpm',
language: 'TypeScript'
},
// NestJS
'nest-cli.json': {
framework: 'NestJS',
confidence: 100,
versionCheck: 'package.json:@nestjs/core',
ecosystem: 'npm/yarn/pnpm',
language: 'TypeScript'
}
};
/**
* TIER 2: Directory Pattern Signatures
* Specific folder structures that strongly indicate frameworks
*/
exports.DIRECTORY_PATTERNS = {
// Next.js App Router
'app/layout.tsx': {
framework: 'Next.js 13+ App Router',
confidence: 100,
language: 'TypeScript'
},
'app/page.tsx': {
framework: 'Next.js 13+ App Router',
confidence: 100,
language: 'TypeScript'
},
'app/layout.js': {
framework: 'Next.js 13+ App Router',
confidence: 100,
language: 'JavaScript'
},
// Next.js Pages Router
'pages/_app.tsx': {
framework: 'Next.js Pages Router',
confidence: 100,
language: 'TypeScript'
},
'pages/_document.tsx': {
framework: 'Next.js Pages Router',
confidence: 100,
language: 'TypeScript'
},
'pages/api': {
framework: 'Next.js API Routes',
confidence: 95,
language: 'JavaScript/TypeScript'
},
// Django
'models.py': {
framework: 'Django',
confidence: 90,
pattern: true,
language: 'Python'
},
'views.py': {
framework: 'Django',
confidence: 85,
pattern: true,
language: 'Python'
},
'serializers.py': {
framework: 'Django REST Framework',
confidence: 95,
pattern: true,
language: 'Python'
},
// Laravel
'app/Http/Controllers': {
framework: 'Laravel',
confidence: 95,
language: 'PHP'
},
'app/Models': {
framework: 'Laravel',
confidence: 95,
language: 'PHP'
},
'database/migrations': {
framework: 'Laravel',
confidence: 90,
language: 'PHP'
},
// Rails
'app/controllers': {
framework: 'Ruby on Rails',
confidence: 95,
language: 'Ruby'
},
'app/models': {
framework: 'Ruby on Rails',
confidence: 95,
language: 'Ruby'
},
'db/migrate': {
framework: 'Ruby on Rails',
confidence: 95,
language: 'Ruby'
},
// Angular
'src/app/app.module.ts': {
framework: 'Angular',
confidence: 100,
language: 'TypeScript'
},
'src/app/app.component.ts': {
framework: 'Angular',
confidence: 100,
language: 'TypeScript'
},
// Vue
'src/App.vue': {
framework: 'Vue',
confidence: 90,
language: 'JavaScript/TypeScript'
},
'src/components': {
framework: 'Vue',
confidence: 70,
pattern: true,
additionalCheck: '.vue files',
language: 'JavaScript/TypeScript'
},
// SvelteKit
'src/routes/+page.svelte': {
framework: 'SvelteKit',
confidence: 100,
language: 'JavaScript/TypeScript'
},
'src/lib': {
framework: 'SvelteKit',
confidence: 80,
language: 'JavaScript/TypeScript'
},
// Spring Boot
'src/main/java': {
framework: 'Spring Boot/Java',
confidence: 85,
language: 'Java'
},
'src/main/resources/application.properties': {
framework: 'Spring Boot',
confidence: 95,
language: 'Java'
},
'src/main/resources/application.yml': {
framework: 'Spring Boot',
confidence: 95,
language: 'Java'
},
// .NET
'Controllers': {
framework: '.NET MVC/API',
confidence: 90,
language: 'C#'
},
'Views': {
framework: '.NET MVC',
confidence: 95,
language: 'C#'
},
// Flutter
'lib/main.dart': {
framework: 'Flutter',
confidence: 100,
language: 'Dart'
},
'ios/Runner': {
framework: 'Flutter',
confidence: 95,
language: 'Dart'
}
};
/**
* TIER 3: File Combination Patterns
* Multiple files that together indicate a specific framework/stack
*/
exports.COMBINATION_PATTERNS = {
't3-stack': {
files: ['next.config.mjs', 'prisma/schema.prisma', 'src/server/api/routers'],
framework: 'T3 Stack',
confidence: 95,
features: ['Next.js', 'Prisma', 'tRPC', 'TypeScript'],
language: 'TypeScript'
},
'mean-stack': {
files: ['angular.json', 'server.js', 'package.json'],
checks: ['express', 'mongoose', '@angular/core'],
framework: 'MEAN Stack',
confidence: 90,
features: ['MongoDB', 'Express', 'Angular', 'Node.js'],
language: 'TypeScript/JavaScript'
},
'mern-stack': {
files: ['client/package.json', 'server/index.js'],
checks: ['react', 'express', 'mongoose'],
framework: 'MERN Stack',
confidence: 90,
features: ['MongoDB', 'Express', 'React', 'Node.js'],
language: 'JavaScript/TypeScript'
},
'django-drf': {
files: ['manage.py', 'requirements.txt'],
checks: ['djangorestframework'],
framework: 'Django + DRF',
confidence: 95,
features: ['Django', 'Django REST Framework'],
language: 'Python'
},
'laravel-vue': {
files: ['artisan', 'resources/js/app.js'],
checks: ['vue'],
framework: 'Laravel + Vue',
confidence: 90,
features: ['Laravel', 'Vue.js'],
language: 'PHP/JavaScript'
},
'fastapi': {
files: ['main.py', 'requirements.txt'],
checks: ['fastapi', 'uvicorn'],
framework: 'FastAPI',
confidence: 95,
features: ['FastAPI', 'Uvicorn'],
language: 'Python'
},
'nestjs-graphql': {
files: ['nest-cli.json', 'src/app.module.ts'],
checks: ['@nestjs/graphql'],
framework: 'NestJS + GraphQL',
confidence: 95,
features: ['NestJS', 'GraphQL'],
language: 'TypeScript'
}
};
/**
* TIER 4: Configuration File Indicators
* Files that indicate specific tools, features, or deployment targets
*/
exports.CONFIG_INDICATORS = {
// Testing Frameworks
'jest.config.js': { feature: 'Jest', type: 'testing' },
'jest.config.ts': { feature: 'Jest', type: 'testing' },
'vitest.config.ts': { feature: 'Vitest', type: 'testing' },
'cypress.config.js': { feature: 'Cypress', type: 'e2e-testing' },
'playwright.config.ts': { feature: 'Playwright', type: 'e2e-testing' },
// Linting & Formatting
'.eslintrc.js': { feature: 'ESLint', type: 'linting' },
'.eslintrc.json': { feature: 'ESLint', type: 'linting' },
'.prettierrc': { feature: 'Prettier', type: 'formatting' },
'biome.json': { feature: 'Biome', type: 'formatting' },
// CI/CD
'.github/workflows': { feature: 'GitHub Actions', type: 'ci-cd' },
'.gitlab-ci.yml': { feature: 'GitLab CI', type: 'ci-cd' },
'Jenkinsfile': { feature: 'Jenkins', type: 'ci-cd' },
'.circleci/config.yml': { feature: 'CircleCI', type: 'ci-cd' },
// Deployment
'vercel.json': { feature: 'Vercel', type: 'deployment' },
'netlify.toml': { feature: 'Netlify', type: 'deployment' },
'render.yaml': { feature: 'Render', type: 'deployment' },
'fly.toml': { feature: 'Fly.io', type: 'deployment' },
'railway.json': { feature: 'Railway', type: 'deployment' },
'Dockerfile': { feature: 'Docker', type: 'containerization' },
'docker-compose.yml': { feature: 'Docker Compose', type: 'orchestration' },
// Database/ORM
'prisma/schema.prisma': { feature: 'Prisma', type: 'orm' },
'drizzle.config.ts': { feature: 'Drizzle', type: 'orm' },
'ormconfig.js': { feature: 'TypeORM', type: 'orm' },
'knexfile.js': { feature: 'Knex.js', type: 'query-builder' },
// Monorepo Tools
'nx.json': { feature: 'Nx', type: 'monorepo' },
'turbo.json': { feature: 'Turborepo', type: 'monorepo' },
'lerna.json': { feature: 'Lerna', type: 'monorepo' },
'rush.json': { feature: 'Rush', type: 'monorepo' },
'pnpm-workspace.yaml': { feature: 'pnpm workspaces', type: 'monorepo' }
};
/**
* TIER 5: Package Manager Indicators
* Lock files that indicate the package manager being used
*/
exports.PACKAGE_MANAGERS = {
'package-lock.json': 'npm',
'yarn.lock': 'yarn',
'pnpm-lock.yaml': 'pnpm',
'bun.lockb': 'bun',
'Gemfile.lock': 'bundler',
'Pipfile.lock': 'pipenv',
'poetry.lock': 'poetry',
'composer.lock': 'composer',
'Cargo.lock': 'cargo',
'go.sum': 'go modules',
'Package.resolved': 'swift-pm',
'Podfile.lock': 'cocoapods'
};
/**
* Main Detection Class
*/
class FrameworkDetector {
projectPath;
detectionStartTime;
constructor(projectPath) {
this.projectPath = projectPath;
this.detectionStartTime = Date.now();
}
/**
* Run the complete detection pipeline
*/
async detect() {
// Phase 1: Check unique signatures (fastest)
const uniqueResult = await this.checkUniqueSignatures();
if (uniqueResult) {
return this.createResult(uniqueResult, 'unique');
}
// Phase 2: Check directory patterns
const dirResult = await this.checkDirectoryPatterns();
if (dirResult && dirResult.confidence && dirResult.confidence > 80) {
return this.createResult(dirResult, 'directory');
}
// Phase 3: Check file combinations
const comboResult = await this.checkCombinations();
if (comboResult && comboResult.confidence && comboResult.confidence > 70) {
return this.createResult(comboResult, 'combination');
}
// Phase 4: Package analysis fallback
const packageResult = await this.analyzePackages();
return this.createResult(packageResult, 'package');
}
/**
* Check for unique file signatures
*/
async checkUniqueSignatures() {
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
const path = await Promise.resolve().then(() => __importStar(require('path')));
for (const [file, signature] of Object.entries(exports.UNIQUE_SIGNATURES)) {
const filePath = path.join(this.projectPath, file);
try {
await fs.access(filePath);
// File exists, check additional conditions if needed
if (signature.additionalCheck) {
const content = await fs.readFile(filePath, 'utf-8');
if (!content.includes(signature.additionalCheck.split(':')[1])) {
continue;
}
}
// Get version if needed
let version;
if (signature.versionCheck) {
version = await this.getVersionFromPackageJson(signature.versionCheck);
}
return {
framework: signature.framework,
confidence: signature.confidence,
version,
ecosystem: signature.ecosystem,
language: signature.language,
features: []
};
}
catch {
// File doesn't exist, continue checking
continue;
}
}
return null;
}
/**
* Check directory patterns
*/
async checkDirectoryPatterns() {
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
const path = await Promise.resolve().then(() => __importStar(require('path')));
for (const [pattern, signature] of Object.entries(exports.DIRECTORY_PATTERNS)) {
const fullPath = path.join(this.projectPath, pattern);
try {
const stats = await fs.stat(fullPath);
if (stats.isDirectory() || stats.isFile()) {
return {
framework: signature.framework,
confidence: signature.confidence,
language: signature.language,
features: []
};
}
}
catch {
continue;
}
}
return null;
}
/**
* Check file combinations
*/
async checkCombinations() {
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
const path = await Promise.resolve().then(() => __importStar(require('path')));
for (const [key, pattern] of Object.entries(exports.COMBINATION_PATTERNS)) {
let allFilesExist = true;
for (const file of pattern.files) {
const filePath = path.join(this.projectPath, file);
try {
await fs.access(filePath);
}
catch {
allFilesExist = false;
break;
}
}
if (allFilesExist) {
// Check additional conditions
if ('checks' in pattern && pattern.checks) {
const packageJson = await this.readPackageJson();
if (packageJson) {
for (const check of ('checks' in pattern ? pattern.checks : [])) {
const deps = {
...packageJson.dependencies,
...packageJson.devDependencies
};
if (!deps[check]) {
allFilesExist = false;
break;
}
}
}
}
if (allFilesExist) {
return {
framework: pattern.framework,
confidence: pattern.confidence,
features: pattern.features || [],
language: pattern.language
};
}
}
}
return null;
}
/**
* Analyze package.json as fallback
*/
async analyzePackages() {
const packageJson = await this.readPackageJson();
if (!packageJson) {
return {
framework: 'Unknown',
confidence: 0,
features: []
};
}
const deps = {
...packageJson.dependencies,
...packageJson.devDependencies
};
// Check for common frameworks in dependencies
const frameworkChecks = [
{ dep: 'next', framework: 'Next.js' },
{ dep: '@angular/core', framework: 'Angular' },
{ dep: 'vue', framework: 'Vue' },
{ dep: 'react', framework: 'React' },
{ dep: 'svelte', framework: 'Svelte' },
{ dep: '@remix-run/node', framework: 'Remix' },
{ dep: 'gatsby', framework: 'Gatsby' },
{ dep: 'astro', framework: 'Astro' },
{ dep: '@nestjs/core', framework: 'NestJS' },
{ dep: 'express', framework: 'Express.js' },
{ dep: 'fastify', framework: 'Fastify' }
];
for (const check of frameworkChecks) {
if (deps[check.dep]) {
return {
framework: check.framework,
confidence: 70,
version: deps[check.dep],
features: Object.keys(deps).slice(0, 10),
language: 'JavaScript/TypeScript'
};
}
}
return {
framework: 'Node.js Project',
confidence: 50,
features: Object.keys(deps).slice(0, 10),
language: 'JavaScript/TypeScript'
};
}
/**
* Helper: Read package.json
*/
async readPackageJson() {
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
const path = await Promise.resolve().then(() => __importStar(require('path')));
try {
const content = await fs.readFile(path.join(this.projectPath, 'package.json'), 'utf-8');
return JSON.parse(content);
}
catch {
return null;
}
}
/**
* Helper: Get version from package.json
*/
async getVersionFromPackageJson(check) {
const [file, dep] = check.split(':');
if (file !== 'package.json')
return undefined;
const packageJson = await this.readPackageJson();
if (!packageJson)
return undefined;
return packageJson.dependencies?.[dep] ||
packageJson.devDependencies?.[dep];
}
/**
* Create final detection result
*/
createResult(partial, detectedBy) {
return {
framework: partial.framework || 'Unknown',
confidence: partial.confidence || 0,
version: partial.version,
ecosystem: partial.ecosystem,
language: partial.language,
features: partial.features || [],
deployment: partial.deployment,
database: partial.database,
testing: partial.testing,
monorepo: partial.monorepo,
detectedBy,
detectionTime: Date.now() - this.detectionStartTime
};
}
}
exports.FrameworkDetector = FrameworkDetector;
/**
* Export a simple detection function for CLI usage
*/
async function detectFramework(projectPath = '.') {
const detector = new FrameworkDetector(projectPath);
return detector.detect();
}
/**
* CLI Usage Example
*/
if (require.main === module) {
detectFramework(process.argv[2] || '.').then(result => {
console.log('🏎️ Framework Detection Result:');
console.log(` Framework: ${result.framework} (${result.confidence}% confidence)`);
console.log(` Language: ${result.language || 'Unknown'}`);
console.log(` Ecosystem: ${result.ecosystem || 'Unknown'}`);
console.log(` Detected by: ${result.detectedBy}`);
console.log(` Detection time: ${result.detectionTime}ms`);
if (result.version) {
console.log(` Version: ${result.version}`);
}
if (result.features.length > 0) {
console.log(` Features: ${result.features.join(', ')}`);
}
});
}
//# sourceMappingURL=framework-detector.js.map