Tutoriel
Installation
Publicodes est distribué sous la forme d’une biblitothèque JavaScript permettant de compiler un jeu de règles publicodes et de l’évaluer dans une situation donnée.
Le paquet est disponible sur npm.
npm install publicodes
Premiers pas
La bibliothèque exporte une classe par défaut Engine
qui permet d’instancier le moteur avec un
jeu de règles publicodes.
import Engine from 'publicodes';
import { parse } from 'yaml';
// On définit une liste de règles publicodes
const rules = `
prix:
prix . carottes: 2€/kg
prix . champignons: 5€/kg
prix . avocat: 2€/avocat
dépenses primeur:
formule:
somme:
- prix . carottes * 1.5 kg
- prix . champignons * 500g
- prix . avocat * 3 avocat
`;
// publicodes ne prend plus en entrée du YAML, vous devez parser vous-même votre code source
const parsedRules = parse(rules);
// On initialise un moteur en lui donnant le publicodes sous forme d'objet javascript.
// Ce publicodes va être parsé
const engine = new Engine(parsedRules);
Évaluer une règle
L’objet engine
permet en ensuite de calculer la valeur d’une règle avec la méthode evaluate
:
console.log(engine.evaluate('dépenses primeur'));
Cette méthode retourne un objet contenant la valeur de l’expression dans la propriété nodeValue
, et son
unité dans la propriété unit
.
Pour un formatage sans effort, on préfèrera utiliser la fonction formatValue
:
import Engine, { formatValue } from 'publicodes';
// ...
const dépenses = engine.evaluate('dépenses primeur');
console.log(`J'ai dépensé ${formatValue(dépenses)} chez le primeur.`);
Modifier la situation
La méthode setSituation
permet de forcer la valeur d’une liste de règles. Elle
est utile pour préciser les paramètres spécifiques à une simulation :
// Ici on change le prix des avocats
engine.setSituation({
'prix . avocat': '3€/avocat'
});
La valeur de dépenses primeur
se base maintenant sur un avocat à 3€ :
// On ré-évalue la règle dans la nouvelle situation
console.log(
`Nouveau prix ! Dépenses mises à jour: ${formatValue(
engine.evaluate('dépenses primeur')
)}.`
);
Évaluation d’expressions
La fonction evaluate
permet d’évaluer des expressions Publicodes complètes :
// On va au marché une fois par semaine, amortissons la dépense sur 7 jours
const depensesParJour = engine.evaluate('dépenses primeur / 7 jours');
console.log(`J'ai dépensé ${formatValue(depensesParJour)}.`);
Conversion d’unité
Pour faire une conversion d’unité, il faut
indiquer l’unité désirée via le mécanisme unité
:
// on va au marché une fois par semaine en moyenne, combien dépense-t-on par mois ?
const depensesParMois = engine.evaluate({
valeur: 'dépenses primeur / 7 jours',
unité: '€/mois'
});
console.log(`J'ai dépensé ${formatValue(depensesParMois)}.`);
Variables manquantes
Publicodes calcule automatiquement les dépendances de chaque règle. Si la
valeur d’une dépendance est manquante et ne permet pas de faire le calcul, elle
apparaîtra dans la propriété missingVariables
:
const missingYEngine = new Engine({
x: 'y + 5',
y: null
});
console.log(missingYEngine.evaluate('x').missingVariables);
Cette information est utile pour intégrer Publicodes à votre application.
Les variables manquantes sont calculées lors de l’évaluation. Si une variable
apparaît dans la formule de calcul d’une règle elle ne sera rapportée que si
elle est effectivement nécessaire au calcul. Si elle est présente dans une
portion non active de l’évaluation (par exemple dans un bloc condition non
actif, ou la tranche d’un barème non actif) elle sera filtrée et n’apparaîtra
pas dans les missingVariables
.
Documentation interactive
Publicodes génère également pour vous une documentation interactive, très
facilement intégrable dans une app React. Pour cela, il vous suffit d’importer
le composant dédié, et passer l’engine
à afficher dans les props.
Il faut commencer par installer la librairie publicodes-react
:
npm install publicodes-react
Puis configurer le router en ajoutant les pages de documentations :
import { BrowserRouter as Router, Link } from 'react-router-dom';
import { RulePage } from '@publicodes/react-ui';
import rules from './rules.yaml';
const engine = new Publicodes(rules);
function MonApp() {
return (
<Router>
<Route
path="documentation/:name+"
render={({ match }) => (
<RulePage
engine={engine}
documentationPath="/documentation"
rulePath={match.params.name}
renderers={{ Link }}
/>
)}
/>
{/* Composants de l'app */}
</Router>
);
}
Note : si vous utilisez Next.js, utilisez l’option renderers suivante :
renderers={{ Link: ({ to, ...rest }) => <Link href={to} {...rest} /> }}
Vous pourrez ensuite faire un lien vers la documentation avec le composant RuleLink
.
import { Link } from 'react-router-dom';
import { RuleLink } from '@publicodes/react-ui';
function MesDépenses() {
return (
<p>
Accéder aux{' '}
<RuleLink
dottedName={'dépenses primeur'}
engine={engine}
documentationPath={'/documentation'}
linkComponent={Link}
/>
</p>
);
}