1
0
Fork 0
mirror of https://github.com/betagouv/mon-entreprise synced 2025-02-09 04:05:01 +00:00
mon-entreprise/publicodes/source/ruleUtils.ts
Johan Girod 08e5b734ba ⚙️ améliore la résolution des noms dans les règles
Lorsque l'on cherche un nom de règle, on laisse la possibilité à
une règle de se référencer elle même, mais alors cette résolution
est la dernière à être envisagée.

Dans l'exemple :
```yaml
b: 5
a . b: b
```
`a . b` référence bien `b` qui vaut `5`

Et dans celui ci :
```
a: 0
a . b:
  remplace:a
  par: b * 5
  valeur: 2
```
`a . b` remplace `a` en la multipliant par sa propre valeur (ici 2)

fix #1081, fix #1083
2020-12-10 16:31:09 +01:00

58 lines
1.8 KiB
TypeScript

import { last, pipe, range, take } from 'ramda'
import { syntaxError } from './error'
import { RuleNode } from './rule'
const splitName = (str: string) => str.split(' . ')
const joinName = (strs) => strs.join(' . ')
export const nameLeaf = pipe<string, string[], string>(splitName, last)
export const encodeRuleName = (name) =>
name
?.replace(/\s\.\s/g, '/')
.replace(/-/g, '\u2011') // replace with a insecable tiret to differenciate from space
.replace(/\s/g, '-')
export const decodeRuleName = (name) =>
name
.replace(/\//g, ' . ')
.replace(/-/g, ' ')
.replace(/\u2011/g, '-')
export function ruleParents<Names extends string>(
dottedName: Names
): Array<Names> {
const fragments = splitName(dottedName) // dottedName ex. [CDD . événements . rupture]
return range(1, fragments.length)
.map((nbEl) => take(nbEl, fragments))
.map(joinName) // -> [ [CDD . événements . rupture], [CDD . événements], [CDD
.reverse()
}
export function disambiguateRuleReference<R extends Record<string, RuleNode>>(
rules: R,
contextName = '',
partialName: string
): keyof R {
const possibleDottedName = [contextName, ...ruleParents(contextName), '']
.map((x) => (x ? x + ' . ' + partialName : partialName))
// Rules can reference themselves, but it should be the last thing to check
.sort((a, b) => (a === contextName ? 1 : b === contextName ? -1 : 0))
const dottedName = possibleDottedName.find((name) => name in rules)
if (!dottedName) {
syntaxError(
contextName,
`La référence '${partialName}' est introuvable.
Vérifiez que l'orthographe et l'espace de nom sont corrects`
)
throw new Error()
}
return dottedName
}
export function ruleWithDedicatedDocumentationPage(rule) {
return (
rule.virtualRule !== true &&
rule.type !== 'groupe' &&
rule.type !== 'texte' &&
rule.type !== 'paragraphe' &&
rule.type !== 'notification'
)
}