ruch
Version:
Revolutionary React TypeScript CLI with hexagonal architecture & AI-powered development assistance. Create maintainable, scalable applications with domain-driven design and integrated AI tooling.
102 lines (91 loc) • 3.27 kB
text/typescript
import fs from 'fs-extra';
import path from 'path';
import { buildDomainDirectoryPath, getDomainsSourceDirectoryPath, validateDomainName } from '../utils/paths';
import type { DomainGenerationOptions } from '../templates/domains';
import { getDomainFiles } from '../templates/domains';
import type { FileSystem } from '../utils/file-operations';
import {
validateFileExists,
createDirectory,
writeFile,
removeFile
} from '../utils/file-operations';
import type { Logger } from '../utils/logging';
import {
logError,
logSuccess,
logInfo,
logDomainAlreadyExists,
logInvalidDomainName
} from '../utils/logging';
// Pure function to get required domain folders
const getRequiredDomainFolders = (options: DomainGenerationOptions): string[] => {
const requiredFolders = [
'entities',
'ports',
'services',
'adapters',
'hooks'
];
if (options.withUi) requiredFolders.push('ui');
return requiredFolders;
};
export const createDomain = async (
domainName: string,
options: DomainGenerationOptions,
fileSystem: FileSystem = fs,
log: Logger = require('../utils/logger').logger
) => {
// Validation du nom
if (!validateDomainName(domainName)) {
logInvalidDomainName(log, domainName);
return;
}
const domainPath = buildDomainDirectoryPath(domainName);
const domainsSourcePath = getDomainsSourceDirectoryPath();
// Vérification de l'existence du domaine
if (await fileSystem.exists(domainPath)) {
logDomainAlreadyExists(log, domainName, domainPath);
return;
}
try {
// Création du dossier src
await fileSystem.ensureDir(path.join(process.cwd(), 'src'));
// Création du dossier src/domains si besoin
await fileSystem.ensureDir(domainsSourcePath);
logInfo(log, `Creating domain "${domainName}"...`);
// Création du dossier du domaine
await fileSystem.ensureDir(domainPath);
// Création des dossiers
const requiredFolders = getRequiredDomainFolders(options);
for (const folder of requiredFolders) {
await fileSystem.ensureDir(path.join(domainPath, folder));
}
// Génération des fichiers
const domainFiles = getDomainFiles(domainName, options);
for (const file of domainFiles) {
const filePath = path.join(domainPath, file.path);
const dir = path.dirname(filePath);
await fileSystem.ensureDir(dir);
await fileSystem.writeFile(filePath, file.content, 'utf8');
}
// Affichage du résumé
logSuccess(log, `Domain "${domainName}" created successfully!`);
logInfo(log, `Location: ${domainPath}`);
logInfo(log, 'Generated structure:');
log.log(`├── entities/`);
log.log(`├── ports/`);
log.log(`├── services/`);
log.log(`├── adapters/`);
log.log(`├── hooks/`);
if (options.withUi) log.log(`├── ui/`);
logInfo(log, `💡 You can now import the domain with: import { ... } from './src/domains/${domainName}'`);
} catch (error) {
logError(log, `Error creating domain: ${error instanceof Error ? error.message : 'Unknown error'}`);
// Nettoyage en cas d'erreur
if (await fileSystem.exists(domainPath)) {
await fileSystem.remove(domainPath);
logInfo(log, 'Cleanup completed after error.');
}
}
};