const fs = require('fs'); const path = require('path'); // File Paths const IFS_BRC_MAP_PATH = 'IFSBRC.json'; const IFS_CONTENT_PATH = 'ifs_food_v8_fr.json'; const BRC_CONTENT_PATH = 'brcGSv9.json'; const OUTPUT_PATH = 'correspondances.json'; // Utility: Clean ID (remove trailing stuff like (KO N°1) for matching) function cleanId(id) { if (!id) return ''; // Removes "(KO N°...)" and whitespace return id.replace(/\s*\(KO N°\d+\)/, '').trim(); } function normalizeId(id) { return cleanId(id).replace(/\*$/, ''); // Remove trailing asterisks often found in IFS } // Main Function function buildData() { console.log('Reading files...'); let mapRaw = fs.readFileSync(IFS_BRC_MAP_PATH, 'utf8'); // detailed fix: IFSBRC.json might be multiple arrays simply concatenated like [...] [...] // We try to join them into one big array. mapRaw = mapRaw.trim(); // detailed logic: if it looks like `] [` or `]\r\n[` we replace with `,` // Regex: look for closing bracket, optional whitespace, opening bracket mapRaw = mapRaw.replace(/\]\s*\[/g, ','); const mapData = JSON.parse(mapRaw); const ifsData = JSON.parse(fs.readFileSync(IFS_CONTENT_PATH, 'utf8')); const brcData = JSON.parse(fs.readFileSync(BRC_CONTENT_PATH, 'utf8')); // 1. Flatten specific content into lookup maps for easy access const ifsLookup = {}; const brcLookup = {}; // Build IFS Lookup // Structure: Array of Chapters -> Sections -> Requirements ifsData.forEach(chapter => { chapter.sous_sections?.forEach(sub => { sub.exigences?.forEach(req => { const id = normalizeId(req.numero); ifsLookup[id] = { id: req.numero, text: req.texte, chapter: chapter.titre, section: sub.titre, ko: req.estKO }; }); }); }); // Build BRC Lookup // Structure: part_1_info ... sections -> subsections -> clauses // Note: brcGSv9.json is an array of parts // Some sections (like 3.5) have nested subsections brcData.forEach(part => { part.sections?.forEach(section => { processSubsection(section.subsections, section.title); }); }); // Recursive function to handle nested subsections (like section 3.5) function processSubsection(subsections, sectionTitle, parentSubsectionTitle = null) { if (!subsections) return; subsections.forEach(sub => { // Get the full subsection title (include parent if exists) const fullSubsectionTitle = parentSubsectionTitle ? `${parentSubsectionTitle} - ${sub.title}` : sub.title; // Process clauses at this level sub.clauses?.forEach(clause => { brcLookup[clause.clause_id] = { id: clause.clause_id, text: clause.requirement, section: sectionTitle, subsection: fullSubsectionTitle }; }); // Recursively process nested subsections (like 3.5.1, 3.5.2, etc.) if (sub.subsections) { processSubsection(sub.subsections, sectionTitle, sub.title); } }); } // 2. Build the Correspondence structure // We want a list of all IFS items, all BRC items, and the links. // The "mapData" (IFSBRC.json) drives the linking. const mappings = []; const usedIfsIds = new Set(); const usedBrcIds = new Set(); // Iterate Mapping File // Structure: Array of Chapters -> exigences -> ifs_ref, brc_refs (Array) mapData.forEach(chapter => { chapter.exigences?.forEach(mapping => { const ifsRefRaw = mapping.ifs_ref; const ifsIdClean = normalizeId(ifsRefRaw); const brcRefs = mapping.brc_refs || []; // Create Mapping Entry mappings.push({ source_id: ifsIdClean, // Normalized for matching target_ids: brcRefs, // We can keep original ref for display if needed ifs_original_ref: ifsRefRaw }); usedIfsIds.add(ifsIdClean); brcRefs.forEach(ref => usedBrcIds.add(ref)); }); }); // 3. Prepare Final JSON // We will dump the lookups as arrays for easier iteration in frontend // Convert lookups to arrays const ifsList = Object.values(ifsLookup); const brcList = Object.values(brcLookup); const output = { ifs_standards: ifsList, brc_standards: brcList, mappings: mappings }; const OUTPUT_JS_PATH = 'data.js'; console.log(`IFS Items: ${ifsList.length}`); console.log(`BRC Items: ${brcList.length}`); console.log(`Mappings: ${mappings.length}`); const fileContent = `window.APP_DATA = ${JSON.stringify(output, null, 2)};`; fs.writeFileSync(OUTPUT_JS_PATH, fileContent); console.log(`Successfully wrote to ${OUTPUT_JS_PATH}`); } try { buildData(); } catch (e) { console.error("Error building data:", e); }