feat: fixes and formatter

This commit is contained in:
2026-01-12 16:01:32 +01:00
parent 85c6084351
commit 11e632acff
353 changed files with 23315 additions and 27361 deletions
+47 -69
View File
@@ -1,137 +1,115 @@
exports.generatePicturePrompt = (project = {}) => {
const {
title = "",
title = '',
lyrics: lyricsRaw,
musicConfig = {},
coverStyle: coverStyleRaw = "",
artistName: artistNameRaw = "",
} = project || {};
coverStyle: coverStyleRaw = '',
artistName: artistNameRaw = '',
} = project || {}
// --- 1. Nettoyage et Normalisation ---
const sanitizeInline = (value = "") => {
if (typeof value !== "string") return "";
const sanitizeInline = (value = '') => {
if (typeof value !== 'string') return ''
return value
.replace(/[\r\n]+/g, " ")
.replace(/[<>]/g, "")
.trim();
};
.replace(/[\r\n]+/g, ' ')
.replace(/[<>]/g, '')
.trim()
}
const titleForPrompt = sanitizeInline(title) || "Sans titre";
const artistName =
sanitizeInline(artistNameRaw) || sanitizeInline(project?.userName || "");
const hasArtistName = artistName.length > 0;
const titleForPrompt = sanitizeInline(title) || 'Sans titre'
const artistName = sanitizeInline(artistNameRaw) || sanitizeInline(project?.userName || '')
const hasArtistName = artistName.length > 0
const {
genres = [],
tempo = "",
mood = "",
instruments = [],
} = musicConfig || {};
const userStyle = sanitizeInline(coverStyleRaw);
const { genres = [], tempo = '', mood = '', instruments = [] } = musicConfig || {}
const userStyle = sanitizeInline(coverStyleRaw)
// --- 2. Intelligence Visuelle (Mapping) ---
// Détermination de l'énergie visuelle
const isEnergetic =
tempo &&
/\b(rapid|fast|vite|agité|upbeat|energ|dance|rock|metal)\b/i.test(
String(tempo),
);
tempo && /\b(rapid|fast|vite|agité|upbeat|energ|dance|rock|metal)\b/i.test(String(tempo))
const isDark =
mood &&
/\b(sombre|triste|dark|sad|mélancoli|nuit|night|eerie)\b/i.test(
String(mood),
);
mood && /\b(sombre|triste|dark|sad|mélancoli|nuit|night|eerie)\b/i.test(String(mood))
// Construction de la Palette & Lumière
let visualAtmosphere = "";
let visualAtmosphere = ''
if (isDark) {
visualAtmosphere =
"Atmosphere: Cinematic atmosphere, moody shadows, deep contrast. Palette: Midnight blue, obsidian, deep purple, metallic accents.";
'Atmosphere: Cinematic atmosphere, moody shadows, deep contrast. Palette: Midnight blue, obsidian, deep purple, metallic accents.'
} else if (isEnergetic) {
visualAtmosphere =
"Atmosphere: Dynamic atmosphere, high energy, vibrant saturation. Palette: Neon colors, electric blue, magenta, bright yellow, high contrast.";
'Atmosphere: Dynamic atmosphere, high energy, vibrant saturation. Palette: Neon colors, electric blue, magenta, bright yellow, high contrast.'
} else {
visualAtmosphere =
"Atmosphere: Soft atmosphere, harmonious and ethereal. Palette: Pastel tones, warm gold, soft coral, balanced and elegant colors.";
'Atmosphere: Soft atmosphere, harmonious and ethereal. Palette: Pastel tones, warm gold, soft coral, balanced and elegant colors.'
}
// Définition du Style de Rendu (Si l'utilisateur est vague, on renforce)
let renderingStyle = userStyle
? `Art Style: ${userStyle}`
: "Art Style: Digital Art, Mixed Media";
let renderingStyle = userStyle ? `Art Style: ${userStyle}` : 'Art Style: Digital Art, Mixed Media'
if (
userStyle.toLowerCase().includes("realist") ||
userStyle.toLowerCase().includes("photo")
) {
if (userStyle.toLowerCase().includes('realist') || userStyle.toLowerCase().includes('photo')) {
renderingStyle +=
", 8k resolution, highly detailed texture, photorealistic, cinematic depth of field, raytracing.";
', 8k resolution, highly detailed texture, photorealistic, cinematic depth of field, raytracing.'
} else if (
userStyle.toLowerCase().includes("illu") ||
userStyle.toLowerCase().includes("dessin")
userStyle.toLowerCase().includes('illu') ||
userStyle.toLowerCase().includes('dessin')
) {
renderingStyle +=
", vector art, clean lines, professional illustration, flat design or detailed painting.";
', vector art, clean lines, professional illustration, flat design or detailed painting.'
} else {
// Style par défaut "Album Cover" qui marche bien
renderingStyle +=
", abstract surrealism, conceptual album art, high fidelity, masterpiece.";
renderingStyle += ', abstract surrealism, conceptual album art, high fidelity, masterpiece.'
}
// --- 3. Extraction de l'Inspiration (Lyrics) ---
// On cherche le REFRAIN en priorité pour l'image, car c'est le cœur visuel
const sections = Array.isArray(lyricsRaw) ? lyricsRaw : [];
const chorus = sections.find(
(s) => s.type === "refrain" || s.type === "chorus",
);
const verse = sections.find(
(s) => s.type === "couplet" || s.type === "verse",
);
const sections = Array.isArray(lyricsRaw) ? lyricsRaw : []
const chorus = sections.find((s) => s.type === 'refrain' || s.type === 'chorus')
const verse = sections.find((s) => s.type === 'couplet' || s.type === 'verse')
// On prend 2 lignes max du refrain, ou du premier couplet
const visualHook = (chorus?.lyrics || verse?.lyrics || "")
.split("\n")
const visualHook = (chorus?.lyrics || verse?.lyrics || '')
.split('\n')
.filter((l) => l.length > 10) // On évite les lignes trop courtes
.slice(0, 2)
.join(". ");
.join('. ')
const imageryPrompt = visualHook
? `Visual Inspiration: An interpretation of these lyrics: "${visualHook}".`
: "Visual Inspiration: Abstract visual representation of the song's mood.";
: "Visual Inspiration: Abstract visual representation of the song's mood."
// --- 4. Construction du Prompt Final (Structure Optimisée Imagen 3) ---
const promptParts = [
// Rôle
"Design a professional, high-quality music album cover.",
'Design a professional, high-quality music album cover.',
// 1. Le Texte (Crucial pour Imagen 3 - Doit être au début ou très clair)
`**Typography & Text:**`,
`The song title "${titleForPrompt}" must be the CENTERPIECE. Write it in a distinct font that matches the mood.`,
hasArtistName
? `The artist name "${artistName}" must appear smaller, elegant, and legible near the bottom or top.`
: "",
"Ensure perfect spelling. The text should be integrated into the artwork (e.g., metallic texture, neon glow, or bold cut-out), not just pasted on top.",
: '',
'Ensure perfect spelling. The text should be integrated into the artwork (e.g., metallic texture, neon glow, or bold cut-out), not just pasted on top.',
// 2. Le Visuel
`**Visuals:**`,
renderingStyle,
imageryPrompt,
`Subject: A central visual element that represents the song. ${isEnergetic ? "Dynamic composition." : "Balanced, centered composition."}`,
`Subject: A central visual element that represents the song. ${isEnergetic ? 'Dynamic composition.' : 'Balanced, centered composition.'}`,
// 3. L'Atmosphère (Context from music config)
`**Mood & Color:**`,
visualAtmosphere,
genres.length > 0 ? `Musical Vibe Reference: ${genres.join(", ")}.` : "",
genres.length > 0 ? `Musical Vibe Reference: ${genres.join(', ')}.` : '',
// 4. Contraintes Négatives (Phrasées positivement pour l'IA)
"**Constraints:**",
"Use a square 1:1 aspect ratio.",
"Do NOT depict literal musical instruments (like guitars or microphones) unless they are part of a surreal abstract composition.",
"No blurry text. No messy borders. No watermarks.",
];
'**Constraints:**',
'Use a square 1:1 aspect ratio.',
'Do NOT depict literal musical instruments (like guitars or microphones) unless they are part of a surreal abstract composition.',
'No blurry text. No messy borders. No watermarks.',
]
return promptParts.filter(Boolean).join("\n\n");
};
return promptParts.filter(Boolean).join('\n\n')
}