setup-next-project
Version:
CLI to quickly create a pre-configured Next.js project with modular components and features
159 lines • 5.09 kB
JavaScript
import { exec } from "child_process";
import degit from "degit";
import fs from "fs-extra";
import * as path from "path";
import { promisify } from "util";
const execAsync = promisify(exec);
/**
* Récupère la configuration d'un template depuis un fichier template.json
*/
async function getTemplateConfig(templatePath) {
const configPath = path.join(templatePath, "template.json");
if (await fs.pathExists(configPath)) {
return await fs.readJson(configPath);
}
return null;
}
/**
* Télécharge un template depuis GitHub
*/
async function downloadFromGitHub(source, tempDir) {
const emitter = degit(source);
await emitter.clone(tempDir);
}
/**
* Copie un template depuis un chemin local
*/
async function copyFromLocal(source, tempDir) {
if (!(await fs.pathExists(source))) {
throw new Error(`Template local introuvable : ${source}`);
}
await fs.copy(source, tempDir);
}
/**
* Télécharge un template depuis une URL (archive zip)
*/
async function downloadFromUrl(source, tempDir) {
// Pour l'instant, on utilise degit qui supporte les URLs
try {
const emitter = degit(source);
await emitter.clone(tempDir);
}
catch (error) {
throw new Error(`Impossible de télécharger depuis l'URL : ${source}`);
}
}
/**
* Détecte le type de source du template
*/
function detectSourceType(source) {
if (source.startsWith("https://github.com") || source.includes("/")) {
return "github";
}
if (source.startsWith("http://") || source.startsWith("https://")) {
return "url";
}
if (path.isAbsolute(source) || source.startsWith(".")) {
return "local";
}
return "builtin";
}
/**
* Récupère un template depuis sa source
*/
export async function fetchTemplate(source, tempDir) {
const sourceType = detectSourceType(source);
try {
switch (sourceType) {
case "github":
await downloadFromGitHub(source, tempDir);
break;
case "local":
await copyFromLocal(source, tempDir);
break;
case "url":
await downloadFromUrl(source, tempDir);
break;
default:
throw new Error(`Type de source non supporté : ${sourceType}`);
}
return await getTemplateConfig(tempDir);
}
catch (error) {
throw new Error(`Erreur lors de la récupération du template : ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Templates par défaut (built-in)
*/
const builtinTemplates = [
{
id: "basic",
name: "Next.js Basic",
description: "Next.js avec TypeScript et Tailwind CSS",
source: "builtin",
type: "builtin",
},
];
/**
* Charge la configuration des templates personnalisés
*/
async function loadCustomTemplates() {
// Utiliser le répertoire home de l'utilisateur pour stocker la config
const homeDir = process.env.HOME || process.env.USERPROFILE || process.cwd();
const configPath = path.join(homeDir, ".setup-next-project", "templates.config.json");
if (await fs.pathExists(configPath)) {
try {
const config = await fs.readJson(configPath);
return config.templates.map((t) => ({
...t,
type: detectSourceType(t.source),
}));
}
catch (error) {
console.warn(`Erreur lors du chargement des templates personnalisés : ${error}`);
}
}
return [];
}
/**
* Obtient tous les templates disponibles (built-in + personnalisés)
*/
export async function getAvailableTemplates() {
const customTemplates = await loadCustomTemplates();
return [...builtinTemplates, ...customTemplates];
}
/**
* Trouve un template par son ID
*/
export async function getTemplate(templateId) {
const templates = await getAvailableTemplates();
return templates.find((t) => t.id === templateId) || null;
}
/**
* Ajoute un nouveau template personnalisé
*/
export async function addCustomTemplate(template) {
// Utiliser le même répertoire que pour loadCustomTemplates
const homeDir = process.env.HOME || process.env.USERPROFILE || process.cwd();
const configDir = path.join(homeDir, ".setup-next-project");
const configPath = path.join(configDir, "templates.config.json");
// S'assurer que le répertoire existe
await fs.ensureDir(configDir);
let config = { templates: [] };
if (await fs.pathExists(configPath)) {
config = await fs.readJson(configPath);
}
// Vérifier que l'ID n'existe pas déjà
if (config.templates.some((t) => t.id === template.id)) {
throw new Error(`Un template avec l'ID "${template.id}" existe déjà`);
}
config.templates.push({
id: template.id,
name: template.name,
description: template.description,
source: template.source,
});
await fs.writeJson(configPath, config, { spaces: 2 });
}
//# sourceMappingURL=remoteTemplates.js.map