/* eslint-disable no-tabs */ const glob = require('glob') const path = require('path') const fs = require('fs-extra') const config = require('../tribes/townconf.js') const logger = require('../core/logger') const Referentials = {} /* Manage Referential object data each object is compose of a list of fields each fields have it owns structur and check those common rules allow to be used to manage: - forms (creation to collect data) - data check - data access rights common referential data stored in /data/shared/referential/ */ Referentials.clientconf = (xworkOn, listkey) => { /* Retourne les info d'un clientconf.json sur une liste de [cle] */ let conf = {} const dataconf = {} // logger.info( `${config.tribes}/${xworkOn}/clientconf.json` ) try { conf = fs.readJsonSync(`${config.tribes}/${xworkOn}/clientconf.json`); // remove information notrelevant for ['emailFrom', 'emailClient', 'emailCc', 'commentkey', 'clezoomprivate', 'stripekeyprivate', 'genericpsw'].forEach(c => { delete conf[c] }) listkey.forEach(k => dataconf[k] = conf[k]) // logger.info( 'dataconf', dataconf ) } catch (err) { logger.info('Attention demande sur clienId inconnu ' + xworkOn) } return { status: 200, payload: { data: dataconf } } } Referentials.clientconfglob = () => ({ status: 200, payload: { data: fs.readJsonSync(`${config.tmp}/clientconfglob.json`) } }) Referentials.getref = (origin, source, ref, xworkOn, xlang) => { // If request origin then send back referential with all language in it // if not origin or json source return by language let referent = {} let src if (origin && ['object', 'data'].includes(source)) { src = `${config.tribes}/${xworkOn}/referentials/${source}/${ref}.json` } else { src = `${config.tribes}/${xworkOn}/referentials/${source}/${ref}_${xlang}.json` } // logger.info( src ) try { referent = fs.readJsonSync(src) } catch (err) { logger.info(`Request ${src} does not exist `) } return { status: 200, payload: { data: referent } } } Referentials.putref = (source, name, xworkOn, data) => { /* We get a referential, we have 3 kinds of sources: * data = [{uuid,DESC:{fr:,en,},DESCLONG:{fr:,en:}, other field}] only DESC and DESCLONG have a translation * json = are full complex object in language name_lg.json * object = [{uuid,DESC:{fr,en},DESCLONG:{fr,en}},tpl,}] Difference between data and object is that object defines rule to manage an object, and how to create a forms to get data each data is saved in one folder object/uuid.json and have to respect the corresponding object referentials definition. For data and object it is possible only to put a file with all language available. When store this script erase with the new file per _lg name for source=json must end by _lg */ // logger.info( data ) const pat = /.*_..\.json$/ const file = `${config.tribes}/${xworkOn}/referentials/${source}/${name}.json` if (['object', 'data'].includes(source)) { if (pat.test(name)) { return { status: 404, payload: { model: 'Referentials', info: ['nameunconsistent'], moreinfo: 'can not be update with one lang need a full file with language for object or data' } } } else { fs.outputJsonSync(file, data) return Refernetials.update(xworkOn, source, name) } } else { if (!pat.test(name)) { return { status: 404, payload: { model: 'Referentials', info: ['nameunconsistent'], moreinfo: 'can not be update without a lang _lg.json a referential json' } } } else { fs.outputJsonSync(file, data) return { status: 200, payload: { model: 'Referentials', info: ['successfull'], moreinfo: 'ref json updated ' } } } } ; } Referentials.updatefull = (tribeid) => { let err = '' let nbrefupdate = 0 const pat = /.*_..\.json$/; ['object', 'data'].forEach(o => { glob.sync(`${config.tribes}/${tribeid}/referentials/${o}/*.json`) .forEach(f => { if (!pat.test(f)) { const res = Referentials.update(tribeid, o, path.basename(f, '.json')) if (res.status !== 200) { err += `Error on ${o}/${path.basename(f)}` } else { nbrefupdate += 1 } } }) }) if (err !== '') { return { status: 500, payload: { info: ['Errupdateref'], model: 'Referentials', moreinfo: err } } } return { status: 200, payload: { info: ['Success'], model: 'Referentials', moreinfo: `Number of object and data ref updated: ${nbrefupdate}` } } } Referentials.inittribeid = () => { logger.info('Clientconf list for this server', `${config.tribes}/**/clientconf.json`) const TribesGlobalConfig = glob.sync(`${config.tribes}/**/clientconf.json`) .map(f => fs.readJsonSync(f)) // store global conf for sharing to other api fs.outputJsonSync(`${config.tmp}/clientconfglob.json`, TribesGlobalConfig, { spaces: 2 }) return { status: 200, payload: { moreinfo: TribesGlobalConfig } } } Referentials.generetribeids = () => { const tribeids = [] fs.readJsonSync(`${config.tmp}/clientconfglob.json`) .forEach(c => { if (!tribeids.includes(c.tribeid)) tribeids.push(c.tribeid) }) fs.outputJsonSync(`${config.tmp}/tribeids.json`, tribeids) logger.info(`update ${config.tribes}/tribeids`) return tribeids } Referentials.genereallowedDOM = () => { const confglob = fs.readJsonSync(`${config.tmp}/clientconfglob.json`) let allDom = [] confglob.forEach(c => { c.allowedDOMs.forEach(d => { if (!allDom.includes(d)) allDom = allDom.concat(d) }) }) return allDom } /* A voir si encore necessaire pour générer un environnement identique sur un autre server // Génére les domaines s'ils n'existe pas dans le repertoire function genereEnvClient() { const confglob = fs.readJsonSync( `${config.sharedData}/clientconfglob.json` ); confglob.forEach(function(c) { config.tribeidsConf[c.tribeid] = c; if (c.allowedURLs) { c.allowedURLs.forEach(u => { if (!config.allowedURLs.includes(u)) { config.allowedURLs.push(u); } }); } else { logger.info('erreur de fichier config d\'un site pour ', c); } // GLOBAL Tribes IDS INDEX maketribeidsIndex(); if (!fs.existsSync(`${config.tribes}/${c.tribeid}`)) { const execSync = require('child_process').execSync; execSync(`cp -r ${config.tribes}/modele ${config.tribes}/${c.tribeid}`); } }); } */ Referentials.update = (tribeid, source, name) => { /* Replace for each language the referential name for a tribeid After each update the version number is incremented by 1 in clientconf.json */ if (!fs.existsSync(`${config.tribes}/${tribeid}/referentials/${source}/${name}.json`)) { return { status: 500, payload: { info: ['unknownRef'], model: 'Referentials', moreinfo: `file does not exist ${config.tribes}/${tribeid}/referentials/${source}/${name}.json` } } } ; const clientconf = fs.readJsonSync(`${config.tribes}/${tribeid}/clientconf.json`) if (!clientconf.langueReferential) { return { status: 500, payload: { info: ['missingConf'], model: 'Referentials', moreinfo: ` ${config.tribes}/${tribeid}/clientconf.json does not contain langueReferential array` } } } const ref = fs.readJsonSync(`${config.tribes}/${tribeid}/referentials/${source}/${name}.json`) clientconf.langueReferential.forEach(lg => { // manage translation let refnew = [] refnew = [] ref.forEach(d => { if (d.DESC) d.DESC = d.DESC[lg] if (d.DESCLONG) d.DESCLONG = d.DESCLONG[lg] if (d.INFO) d.INFO = d.INFO[lg] if (d.desc) d.desc = d.desc[lg] if (d.desclong) d.desclong = d.desclong[lg] if (d.info) d.info = d.info[lg] if (d.placeholder) d.placeholder = d.placeholder[lg] refnew.push(d) }) // save new ref in language // logger.info( "New ref", refnew ) logger.info(`Update referentials per lg ${config.tribes}/${tribeid}/referentials/${source}/${name}_${lg}.json`) fs.outputJsonSync(`${config.tribes}/${tribeid}/referentials/${source}/${name}_${lg}.json`, refnew, { spaces: 2 }) }) // upgrade version number if (!clientconf.referentials) clientconf.referentials = {} if (!clientconf.referentials[source]) clientconf.referentials[source] = {} if (!clientconf.referentials[source][name]) clientconf.referentials[source][name] = { version: 0 } clientconf.referentials[source][name].version += 1 fs.outputJsonSync(`${config.tribes}/${tribeid}/clientconf.json`, clientconf, 'utf8') return { status: 200, payload: { info: ['successUpdate'], model: 'Referentials', moreinfo: `${name} updated` } } } // logger.info( Referentials.update( 'apixtribe', "object", "user" ) ) Referentials.genereobjet = (tribeid, destination, tplmustache, objet, filtre) => { /* @TODO Genere des objets d'agregat @tribeid = data/tribee/ identifiant client @destinations = [] of destination @tplmustache = fichier mustache de mise en page @objet = nom d'objet contact, companies, items, users @filtre = fonction a executer */ } /// ///// EN DESSOUS DE CETTE LIGNE A SUPPRIMER /* Le principe consistait à partager des referentiels dans shareddataLa gestion est trop compliqué => le principe chaque client duplique un referentiel pour que les app qui s'appuie sur des composants communs puissent fonctionner */ /* Referentials.genereClientObjectASUPP = () => { const confglob = fs.readJsonSync( `${config.tmp}/clientconfglob.json` ); // Check and update folder and data per lang // c as tribeid confglob.forEach( ( c, postribeid ) => { //check folder are well create const lstfolder = [ 'actions', 'actions/done', 'actions/todo', 'cards', 'logs', 'orders', 'orders/reservation', 'orders/purchase', 'orders/contact', 'public', 'public/reservation', 'tags', 'tags/stats', 'tags/archives', 'tags/hits', 'tags/imgtg', 'users' ]; lstfolder.forEach( fol => { if( !fs.existsSync( `${config.tribes}/${c.tribeid}/${fol}` ) ) { fs.mkdirSync( `${config.tribes}/${c.tribeid}/${fol}` ); } } ) if( c.referentials && !c.langue ) { logger.info( `ERREUR referentials mais pas de langue:[] pour ${c.tribeid}/clientconf.json` ) } if( c.referentials && c.langue ) { let majclientconf = false; // Create and check Object structure Object.keys( c.referentials.object ) .forEach( o => { // if object exist in shared then it merge sharedObject and domain referential object let objfull = []; const objshared = `${config.sharedData}/referentials/dataManagement/object/${o}.json`; if( fs.existsSync( objshared ) ) { objfull = objfull.concat( fs.readJsonSync( objshared ) ); } const objdomain = `${config.tribes}/${c.tribeid}/referentials/dataManagement/object/${o}.json`; if( fs.existsSync( objdomain ) ) { objfull = objfull.concat( fs.readJsonSync( objdomain ) ); } c.langue.forEach( lg => { const objfulllg = objfull.map( field => { if( field.DESC ) field.DESC = field.DESC[ lg ]; if( field.DESCLONG ) field.DESCLONG = field.DESCLONG[ lg ]; return field; } ); const objectdomlg = `${config.tribes}/${c.tribeid}/referentials/${lg}/object/${o}.json`; let savedObject = {}; if( fs.existsSync( objectdomlg ) ) { savedObject = fs.readJsonSync( objectdomlg ); } // TODO Always true change later to update only if needded if( !fs.existsSync( objectdomlg ) || objfulllg.length !==== savedObject.length || 1 === 1 ) { fs.outputJsonSync( objectdomlg, objfulllg, { spaces: 2 } ); confglob[ postribeid ].referentials.object[ o ].version += 1; majclientconf = true; } } ); } ); // datafile Object.keys( c.referentials.data ) .forEach( d => { // if object exist in shared then it merge sharedObject and domain referential object // logger.info(c.tribeid + '--' + d); let datafull = []; const datashared = `${ config.sharedData }/referentials/dataManagement/data/${d}.json`; if( fs.existsSync( datashared ) ) { datafull = datafull.concat( fs.readJsonSync( datashared ) ); } const datadomain = `${config.tribes}/${ c.tribeid }/referentials/dataManagement/data/${d}.json`; if( fs.existsSync( datadomain ) ) { datafull = datafull.concat( fs.readJsonSync( datadomain ) ); } /* const defdata = `${config.tribes}/${ c.tribeid }/referentials/dataManagement/data/${d}.json`; */ // for each Langues => generate fr.obj and compare it with existing file // if diff then => upgrade version number in clientconf // logger.info(datafull); // this could be improved by usind d.meta wich is the object that DESCribe this data /* c.langue.forEach( lg => { let meta; if( c.referentials.data[ d ].meta ) { meta = fs.readJsonSync( `${config.tribes}/${c.tribeid}/referentials/${lg}/object/${ c.referentials.data[d].meta }.json` ); } let datalg; const datafulllg = datafull.map( tup => { datalg = {}; meta.forEach( ch => { if( tup[ ch.idfield ] ) { if( ch.multilangue ) { datalg[ ch.idfield ] = tup[ ch.idfield ][ lg ]; } else { datalg[ ch.idfield ] = tup[ ch.idfield ]; } } } ); return datalg; } ); // lit le fichier correspondant et le compare si différent le sauvegarde // stocke l'information d'upgrade d ela version const datadomlg = `${config.tribes}/${ c.tribeid }/referentials/${lg}/data/${d}.json`; let saveddata = {}; if( fs.existsSync( datadomlg ) ) { saveddata = fs.readJsonSync( datadomlg ); } // Condition to improve // TODO always change file to improvelater by detecting real change. if( !fs.existsSync( datadomlg ) || datafulllg.length !== saveddata.length || 1 === 1 ) { fs.outputJsonSync( datadomlg, datafulllg, { spaces: 2 } ); confglob[ postribeid ].referentials.data[ d ].version += 1; majclientconf = true; } } ); } ); // json file that have to start with lg {lg:'':{json }} Object.keys( c.referentials.json ) .forEach( j => { // if object exist in shared then it merge sharedObject and domain referential object // logger.info(c.tribeid + '--' + d); let jsonfull = []; const jsondomain = `${config.tribes}/${c.tribeid}/referentials/dataManagement/json/${j}.json`; if( fs.existsSync( jsondomain ) ) { jsonfull = fs.readJsonSync( jsondomain ); } c.langue.forEach( lg => { const jsondomlg = `${config.tribes}/${ c.tribeid }/referentials/${lg}/json/${j}.json`; // logger.info('jsondomlg', jsondomlg); let datalg = jsonfull; if( jsonfull[ lg ] ) { datalg = jsonfull[ lg ]; } fs.outputJsonSync( jsondomlg, datalg, { spaces: 2 } ); } ); } ); // update clientconf domain with updated version if( majclientconf ) { fs.outputJsonSync( `${config.tribes}/${c.tribeid}/clientconf.json`, c, { spaces: 2 } ); } } } ); // update global conf fs.outputJsonSync( `${config.tmp}/clientconfglob.json`, confglob, { spaces: 2 } ); }; */ module.exports = Referentials