Http-functions.js

Question:
[ http-functions.js not working 404 error]

Product:
[Wix Studio Editor.]

What are you trying to achieve:

// backend/http-functions.js - Fichier principal des fonctions HTTP pour Wix
// ⚠️ CE FICHIER DOIT ÊTRE COPIÉ EXACTEMENT DANS WIX EDITOR -> BACKEND -> http-functions.js

// Importez les modules nécessaires
import { ok, badRequest } from 'wix-http-functions';
import wixData from 'wix-data';
import wixCdn from 'wix-cdn';

// Fonction utilitaire pour convertir les URLs d'images Wix en URLs publiques
function getPublicImageUrl(wixImageUrl) {
    if (!wixImageUrl || !wixImageUrl.startsWith('wix:image://v1/')) {
        return null;
    }

    const parts = wixImageUrl.substring('wix:image://v1/'.length);
    const fileKeyMatch = parts.match(/^([^~]+)~/); 
    const fileNameMatch = parts.match(/~mv2\.jpg\/(.*?)(#.*)?$/); 

    if (fileKeyMatch && fileKeyMatch[1] && fileNameMatch && fileNameMatch[1]) {
        const fileKey = fileKeyMatch[1];
        const fileName = fileNameMatch[1];
        return `https://static.wixstatic.com/media/${fileKey}/${decodeURIComponent(fileName)}`;
    }
    return null;
}

const headers = {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET",
    "Access-Control-Allow-Headers": "Content-Type, Authorization",
    "Content-Type": "application/json"
};

// ==================== FONCTIONS POUR LES PROFESSIONNELS ====================

/**
 * @function get_professionals (alias: professionals)
 * URL d'accès : https://www.immigrantindex.com/_functions/professionals
 */
export async function get_professionals(request) {
    try {
        const results = await wixData.query("Professionnel") 
            .include("sousCatgorie") 
            .limit(100) 
            .find();
            
        const professionals = results.items.map(item => {
            const sousCatgorieData = item.sousCatgorie; 
            return {
                _id: item._id,
                titleSlug: item.title || "", 
                image: item.image ? wixCdn.getPublicUrl(item.image) : null, 
                subtitle: item.subtitle || null, 
                sousCatgorie: sousCatgorieData ? { 
                    _id: sousCatgorieData._id,
                    name: sousCatgorieData.title || "Sans nom",
                    image: sousCatgorieData.image ? wixCdn.getPublicUrl(sousCatgorieData.image) : null, 
                    nomCategorie: sousCatgorieData.nomCategorie || null,
                } : null,
                ville: item.ville || null, 
                galeriesMedia: item.mediagallery && Array.isArray(item.mediagallery)
                    ? item.mediagallery.map(mediaItem => wixCdn.getPublicUrl(mediaItem))
                    : [], 
                adresse: item.address || null, 
                siteWeb: item.siteWeb || null, 
                lienFacebook: item.lienFacebook || null, 
                heureOuverture: item.time || null, 
                numeroTelephone: item.numroDeTlphone || null, 
                sponsor: item.sponsor || false, // 🔹 IMPORTANT : Champ sponsor
                createdDate: item._createdDate,
                updatedDate: item._updatedDate
            };
        });
        
        console.log(`Récupération de ${professionals.length} professionnels réussie.`);
        
        return ok({
            headers,
            body: {
                success: true,
                professionals: professionals
            }
        });
        
    } catch (error) {
        console.error("Erreur dans get_professionals:", error);
        return badRequest({
            headers,
            body: {
                success: false,
                message: "Erreur lors de la récupération des professionnels",
                error: error.toString()
            }
        });
    }
}

// Alias pour la fonction principale (support anglais et français)
export const professionals = get_professionals;
export const professionnels = get_professionals; // Alias en français

/**
 * @function get_sponsored_professionals
 * URL d'accès : https://www.immigrantindex.com/_functions/get_sponsored_professionals
 */
export async function get_sponsored_professionals(request) {
    try {
        const results = await wixData.query("Professionnel") 
            .eq("sponsor", true)
            .include("sousCatgorie") 
            .limit(100) 
            .find();
            
        const sponsoredProfessionals = results.items.map(item => {
            const sousCatgorieData = item.sousCatgorie; 
            return {
                _id: item._id,
                titleSlug: item.title || "", 
                image: item.image ? wixCdn.getPublicUrl(item.image) : null, 
                subtitle: item.subtitle || null, 
                sousCatgorie: sousCatgorieData ? { 
                    _id: sousCatgorieData._id,
                    name: sousCatgorieData.title || "Sans nom",
                    image: sousCatgorieData.image ? wixCdn.getPublicUrl(sousCatgorieData.image) : null, 
                    nomCategorie: sousCatgorieData.nomCategorie || null,
                } : null,
                ville: item.ville || null, 
                galeriesMedia: item.mediagallery && Array.isArray(item.mediagallery)
                    ? item.mediagallery.map(mediaItem => wixCdn.getPublicUrl(mediaItem))
                    : [], 
                adresse: item.address || null, 
                siteWeb: item.siteWeb || null, 
                lienFacebook: item.lienFacebook || null, 
                heureOuverture: item.time || null, 
                numeroTelephone: item.numroDeTlphone || null, 
                sponsor: true,
                createdDate: item._createdDate,
                updatedDate: item._updatedDate
            };
        });
        
        console.log(`Récupération de ${sponsoredProfessionals.length} professionnels sponsorisés réussie.`);
        
        return ok({
            headers,
            body: {
                success: true,
                professionals: sponsoredProfessionals
            }
        });
        
    } catch (error) {
        console.error("Erreur dans get_sponsored_professionals:", error);
        return badRequest({
            headers,
            body: {
                success: false,
                message: "Erreur lors de la récupération des professionnels sponsorisés",
                error: error.toString()
            }
        });
    }
}

// ==================== FONCTIONS POUR LES SOUS-CATÉGORIES ====================

/**
 * @function get_souscategories (alias: souscategories)
 * URL d'accès : https://www.immigrantindex.com/_functions/souscategories
 */
export async function get_souscategories(request) {
    try {
        const results = await wixData.query("SousCategorie") 
            .limit(100) 
            .find();
            
        const sousCategories = results.items.map(item => {
            return {
                _id: item._id,
                name: item.title || item.Title || "Catégorie sans nom", 
                image: item.image ? (wixCdn.getPublicUrl ? wixCdn.getPublicUrl(item.image) : getPublicImageUrl(item.image)) : null, 
                nomCategorie: item.NomCategorie || null, 
                createdDate: item._createdDate,
                updatedDate: item._updatedDate
            };
        });
        
        console.log(`Récupération de ${sousCategories.length} sous-catégories réussie.`);
        
        return ok({
            headers,
            body: {
                success: true,
                sousCategories: sousCategories
            }
        });
        
    } catch (error) {
        console.error("Erreur lors de la récupération des sous-catégories:", error);
        return badRequest({
            headers,
            body: {
                success: false,
                message: "Erreur lors de la récupération des sous-catégories",
                error: error.toString()
            }
        });
    }
}

// Alias pour la fonction principale
export const souscategories = get_souscategories;

/**
 * @function get_souscategorie_by_id
 * URL d'accès : https://www.immigrantindex.com/_functions/souscategories/{id}
 */
export async function get_souscategorie_by_id(request) {
    try {
        const id = request.path[0]; 
        
        if (!id) {
            return badRequest({
                headers,
                body: {
                    success: false,
                    message: "Aucun ID de sous-catégorie fourni"
                }
            });
        }
        
        const souscategorie = await wixData.get("SousCategorie", id); 
        
        if (!souscategorie) {
            return badRequest({
                headers,
                body: {
                    success: false,
                    message: `Aucune sous-catégorie trouvée avec l'ID: ${id}`
                }
            });
        }
        
        return ok({
            headers,
            body: {
                success: true,
                souscategorie: {
                    _id: souscategorie._id,
                    name: souscategorie.title || souscategorie.Title || "Catégorie sans nom",
                    image: souscategorie.image ? (wixCdn.getPublicUrl ? wixCdn.getPublicUrl(souscategorie.image) : getPublicImageUrl(souscategorie.image)) : null,
                    nomCategorie: souscategorie.NomCategorie || null,
                    createdDate: souscategorie._createdDate,
                    updatedDate: souscategorie._updatedDate
                }
            }
        });
        
    } catch (error) {
        console.error(`Erreur lors de la récupération de la sous-catégorie par ID: ${error}`);
        return badRequest({
            headers,
            body: {
                success: false,
                message: "Erreur lors de la récupération de la sous-catégorie par ID",
                error: error.toString()
            }
        });
    }
}

// Test des collections
export async function test_collections(request) {
    try {
        const professionnels = await wixData.query("Professionnel").limit(1).find();
        const sousCategories = await wixData.query("SousCategorie").limit(1).find();
        return ok({
            headers,
            body: {
                success: true,
                professionnelsCount: professionnels.totalCount,
                sousCategoriesCount: sousCategories.totalCount
            }
        });
    } catch (error) {
        return badRequest({
            headers,
            body: {
                success: false,
                error: error.toString()
            }
        });
    }
}

What have you already tried:
[(https://www.immigrantindex.com/_functions/professionals) give me 404 error]