type ArrondiNode = { explanation: { arrondi: ASTNode; valeur: ASTNode; }; nodeKind: 'arrondi'; }; type TrancheNode = { taux: ASTNode; } | { montant: ASTNode; }; type TrancheNodes = Array; type BarèmeNode = { explanation: { tranches: TrancheNodes; multiplicateur: ASTNode; assiette: ASTNode; }; nodeKind: 'barème'; }; type ConditionNode = { explanation: { si: ASTNode; alors: ASTNode; sinon: ASTNode; }; nodeKind: 'condition'; }; /** @experimental */ type getUnitKey = (writtenUnit: string) => string; /** @experimental */ type formatUnit = (unit: string, count: number) => string; /** * Parse a unit string into a Unit object * * @param string The unit string to parse * @param getUnitKey (@experimental DO NOT USE): A function to normalize the unit string * * @returns The parsed unit object * * @example * ```ts * parseUnit('m/s2') * // returns { numerators: ['m'], denominators: ['s', 's'] } * ``` * * @experimental */ declare function parseUnit(string: string, getUnitKey?: getUnitKey): Unit; /** * Serialize a unit to a readable string * @experimental */ declare function serializeUnit(rawUnit: Unit | undefined | string, count?: number, formatUnit?: formatUnit): string | undefined; type Cache = { inversionFail?: boolean; _meta: { evaluationRuleStack: Array; parentRuleStack: Array; currentContexteSituation?: string; }; /** * Every time we encounter a reference to a rule in an expression we add it * to the current Set of traversed variables. Because we evaluate the * expression graph “top to bottom” (ie. we start by the high-level goal and * recursively evaluate its dependencies), we need to handle rule * “boundaries”, so that when we “enter” in the evaluation of a dependency, * we start with a clear empty set of traversed variables. Then, when we go * back to the referencer rule, we need to add all to merge the two sets : * rules already traversed in the current expression and the one from the * reference. */ traversedVariablesStack?: Array>; nodes: Map; }; type StrictOptions = { /** * If set to true, the engine will throw when the * situation contains invalid values * (rules that don't exists, or values with syntax errors). * * If set to false, it will log the error and filter the invalid values from the situation * @default true */ situation?: boolean; /** * If set to true, the engine will throw when parsing a rule whose parent doesn't exist * This can be set to false to parse partial rule sets (e.g. optimized ones). * @default true */ noOrphanRule?: boolean; /** * If set to true, the engine will throw when a cycle is detected at runtime * @default false */ noCycleRuntime?: boolean; /** * If set to true, the engine will throw when a rule with 'une possibilité' * is evaluated to a value that is not in the list. * @default false */ checkPossibleValues?: boolean; }; type FlagOptions = { /** * When true, the engine will filter out possibilities that are not applicable based on the current situation. * @default false */ filterNotApplicablePossibilities?: boolean; /** * If true, a non applicable or false rule will automatically make all its children non applicable * @default true */ automaticNamespaceDisabling?: boolean; }; type WarnOptions = { /** * Enable warnings for experimental rules * @default true */ experimentalRules?: boolean; /** * Enable warnings for unit conversion issues * @default true */ unitConversion?: boolean; /** * Enable warnings for cyclic references in rules * @default true */ cyclicReferences?: boolean; /** * Enable warnings for deprecated syntax * @default true */ deprecatedSyntax?: boolean; /** * Enable warnings for situation issues. Warnings can be raised when the situation contains rules that are not in the base rules or when a value we try to set is not valid (it doesn't exist in the list of possible values for a given rule). * @default true */ situationIssues?: boolean; }; /** * Options for the engine constructor */ type EngineOptions = { /** * Don't throw an error if the parent of a rule is not found. * This is useful to parse partial rule sets (e.g. optimized ones). * @deprecated Use the `strict: { parentRule: false }` option instead */ allowOrphanRules?: boolean; /** * Whether the engine should trigger an error when it detects an anomaly, * or whether it should simply record it and continue. * * This option can be set globally (true or false) or for specific rules ({@link StrictOptions}). * */ strict?: boolean | StrictOptions; /** * The logger used to log errors and warnings (default to console). * @type {Logger} */ logger?: Logger; /** * getUnitKey is a function that allows to normalize the unit in the engine. * @experimental */ getUnitKey?: getUnitKey; /** * flag to enable new experimental features */ flag?: FlagOptions; /** * Specify which warnings should be enabled */ warn?: boolean | WarnOptions; }; type NodesTypes = WeakMap; type InferedType = { isNullable: boolean | undefined; } & Pick; /** * Represents a single possibility value in a "une possibilité" mechanism. It can be a constant value (string or number), or a reference to an existing rule. */ type Possibility = { type: 'number' | 'string' | 'reference'; /** * If the possibility is a reference, this contains a node that evaluates the applicability conditions of the referenced rule. * Otherwise, it contains a constant node evaluating to false (as constant possibility are always applicable, for now) */ notApplicable: ASTNode; /** * Representation of this possibility's value in publicodes syntax, can be used in {@link Engine.setSituation} to set the value of the rule. * * String are wrapped in single quotes, and numbers are represented as number followed by an optional unit * @example * ```ts * "'value'" * "42 m/s" * ``` */ publicodesValue: string; /** * The value of the possibility, as it appears in the evaluated node. */ nodeValue: string | number; /** * The unit of the possibility value, if it is a number * @see {@link serializeUnit} */ unit?: Unit; /** * The dotted name of the referenced rule, if the possibility is a reference. */ dottedName?: string; /** * The title of the referenced rule, if the possibility is a reference. */ title?: string; }; type RulePossibilités = Array> | { possibilités: Array>; }; type UnePossibilitéNode = { nodeKind: 'une possibilité'; type: 'number' | 'string' | 'reference'; unit?: Unit; /** * The list of possibility node, each representing a possible value for the rule. */ explanation: Array>; /** @deprecated : explicitely define a rule for the absence of choice (for instance : 'aucun' or 'non applicable' or 'autre' ) */ 'choix obligatoire'?: 'oui' | 'non'; }; type Rule = { formule?: Record | string | number; valeur?: Record | string | number; question?: string; description?: string; unité?: string; acronyme?: string; exemples?: any; résumé?: string; icônes?: string; titre?: string; sévérité?: string; experimental?: 'oui'; 'possiblement non applicable'?: 'oui'; privé?: 'oui'; note?: string; 'une possibilité'?: RulePossibilités; remplace?: Remplace | Array; 'rend non applicable'?: Remplace | Array; suggestions?: Record>; références?: { [source: string]: string; }; API?: string; 'identifiant court'?: string; } & Record; type Remplace = { 'références à': string; dans?: Array | string; 'sauf dans'?: Array | string; priorité?: number; } | string; type RuleNode = { dottedName: Name; title: string; nodeKind: 'rule'; virtualRule: boolean; private: boolean; rawNode: Rule; replacements: Array; possibilities: UnePossibilitéNode | undefined; explanation: { valeur: ASTNode; parents: Array; nullableParent?: ASTNode; ruleDisabledByItsParent: boolean; }; suggestions: Record; 'identifiant court'?: string; }; type ReplacementRule = { nodeKind: 'replacementRule'; definitionRule: ASTNode<'reference'> & { dottedName: string; }; replacedReference: ASTNode<'reference'>; priority?: number; whiteListedNames: Array>; rawNode: any; blackListedNames: Array>; remplacementRuleId: number; replaceByNonApplicable: boolean; }; type Context = { dottedName: RuleNames | ''; parsedRules: ParsedRules; nodesTypes: NodesTypes; referencesMaps: ReferencesMaps; rulesReplacements: RulesReplacements; logger: Logger; inversionMaxIterations?: number; /** * This is used to generate unique IDs for sub-engines, we need to generate them at * */ subEngineIncrementingNumber?: number; strict: Required; flag: Required; warn: Required; subEngines: Map>; subEngineId: SituationHash | undefined; evaluatedRule: RuleNames | undefined; getUnitKey: getUnitKey; }; type PartialContext = Partial, 'strict' | 'flag' | 'warn'> & { strict: StrictOptions; flag: FlagOptions; warn: WarnOptions; }>; type SituationHash = number; type RulesReplacements = Partial>; type ReferencesMaps = { referencesIn: Map>; rulesThatUse: Map>; }; type RawRule = Omit | PublicodesExpression | null; /** * Parse a set of publicodes rules * * Allows to add new rules to a previously parsed set of rules (partialContext) * * @param rawRules - The new rules to parse * @param partialContext - The context to use for the parsing (if we want to add a set of rules to a previously parsed one) * * @returns The new context containing the parsed rules, the nodes types, the references maps and the rules replacements * * @experimental */ declare function parsePublicodes(rawRules: RawPublicodes, partialContext?: PartialContext): Pick, 'parsedRules' | 'nodesTypes' | 'referencesMaps' | 'rulesReplacements'>; type ReferenceNode = { nodeKind: 'reference'; name: string; contextDottedName: string; dottedName?: string; title?: string; acronym?: string; }; type ContextNode = { explanation: { valeur: ASTNode; contexte: Array<[ReferenceNode, ASTNode]>; subEngineId: number; }; nodeKind: 'contexte'; }; type DuréeNode = { explanation: { depuis: ASTNode; "jusqu'à": ASTNode; }; unit: Unit; nodeKind: 'durée'; }; type EstNonDéfiniNode = { explanation: ASTNode; nodeKind: 'est non défini'; }; type EstNonApplicableNode = { explanation: ASTNode; nodeKind: 'est non applicable'; }; type GrilleNode = { explanation: { assiette: ASTNode; multiplicateur: ASTNode; tranches: TrancheNodes; }; nodeKind: 'grille'; }; type InversionNode = { explanation: { ruleToInverse: string; inversionCandidates: Array; min: number; max: number; errorTolerance: number; unit?: Unit; inversionGoal?: ASTNode; numberOfIteration?: number; inversionFail?: boolean; }; nodeKind: 'inversion'; }; type LogarithmeNode = { explanation: ASTNode; nodeKind: 'logarithme'; }; declare const knownOperations: { readonly '*': readonly [(a: any, b: any) => number, "×"]; readonly '/': readonly [(a: any, b: any) => number, "∕"]; readonly '//': readonly [(a: any, b: any) => number, "//"]; readonly '**': readonly [(a: any, b: any) => number, "**"]; readonly '+': readonly [(a: any, b: any) => any]; readonly '-': readonly [(a: any, b: any) => number, "−"]; readonly '<': readonly [(a: any, b: any) => boolean]; readonly '<=': readonly [(a: any, b: any) => boolean, "≤"]; readonly '>': readonly [(a: any, b: any) => boolean]; readonly '>=': readonly [(a: any, b: any) => boolean, "≥"]; readonly '=': readonly [(a: any, b: any) => boolean]; readonly '!=': readonly [(a: any, b: any) => boolean, "≠"]; readonly et: readonly [(a: any, b: any) => any]; readonly ou: readonly [(a: any, b: any) => any]; }; type OperationNode = { nodeKind: 'operation'; explanation: [ASTNode, ASTNode]; operationKind: keyof typeof knownOperations; operator: string; }; type RésoudreRéférenceCirculaireNode = { explanation: { ruleToSolve: string; valeur: ASTNode; }; nodeKind: 'résoudre référence circulaire'; }; type SimplifierUnitéNode = { explanation: ASTNode; nodeKind: 'simplifier unité'; }; type TauxProgressifNode = { explanation: { tranches: TrancheNodes; multiplicateur: ASTNode; assiette: ASTNode; }; nodeKind: 'taux progressif'; }; declare const NAME = "texte"; type TexteNode = { explanation: Array; nodeKind: typeof NAME; }; type UnitéNode = { unit: Unit; explanation: ASTNode; nodeKind: 'unité'; }; type VariableManquanteNode = { missingVariable: string; explanation: ASTNode; nodeKind: 'variable manquante'; }; type VariationNode = { explanation: Array<{ condition: ASTNode; consequence: ASTNode; satisfied?: boolean; }>; nodeKind: 'variations'; }; type ConstantNode = { nodeKind: 'constant'; isNullable?: boolean; isDefault?: boolean; fullPrecision?: boolean; dottedName?: string; nodeValue: Evaluation; } & ({ type: 'number'; unit?: Unit; } | { type: 'boolean' | 'string' | 'date' | undefined; }); type PossibleNodes = ArrondiNode | BarèmeNode | ConditionNode | ConstantNode | ContextNode | DuréeNode | EstNonApplicableNode | EstNonDéfiniNode | GrilleNode | InversionNode | OperationNode | ReferenceNode | ReplacementRule | RésoudreRéférenceCirculaireNode | RuleNode | SimplifierUnitéNode | TauxProgressifNode | TexteNode | UnePossibilitéNode | UnitéNode | VariableManquanteNode | VariationNode | LogarithmeNode; /**@hidden */ type NodeKind = PossibleNodes['nodeKind']; /** * Represents a node in the Abstract Syntax Tree of a publicodes expression. * * It can be browsed and transformed using the {@link transformAST}, {@link reduceAST} and {@link traverseASTNode} methods. * * * @warning * The ASTNode types are considered internal implementation details. * They are not covered by semantic versioning guarantees and may undergo breaking changes * without a major version bump. Use them at your own risk. * * @typeParam N - The kind of node this ASTNode represents (a string literal type). * * @example * ```ts * let node: ASTNode<'rule'> * ``` */ type ASTNode = PossibleNodes & { nodeKind: N; isDefault?: boolean; sourceMap?: { mecanismName: string; args: Record>; }; rawNode?: string | Rule; }; type ASTTransformer = (n: ASTNode) => ASTNode; type TraverseFunction = (fn: ASTTransformer, node: ASTNode) => ASTNode; /** * Represents the unit of a number. * * @example 'm/s²' * ```ts * { * numerators: ['m'], * denominators: ['s', 's'] * } * ``` * * @see {@link serializeUnit} * @see {@link parseUnit} */ type Unit = { numerators: Array; denominators: Array; }; type EvaluatedValueTypes = number | boolean | string; type Evaluation = T | null | undefined; /** * An {@link ASTNode} decorated with evaluation information * * Returned by {@link Engine.evaluate}. * */ type EvaluatedNode = { /** * The value of the node after evaluation. * * Can be a number, a string, a boolean, null (« non applicable ») or undefined (« non défini »). */ nodeValue: Evaluation; /** * The unit in which the value is expressed. */ unit?: Unit; /** * @experimental * The list of all the rules that have been traversed to evaluate this node. */ traversedVariables?: Array; /** * The rules that are needed in the situation to compute the exact value for this node. */ missingVariables: MissingVariables; } & ASTNode; type MissingVariables = Record; /** * The engine is used to parse rules and evaluate expressions. * It is the main entry point to the publicodes library. * * @typeParam RuleNames - All rules names. Allows to automatically autocomplete rules names in the engine when using {@link Engine.getRule} or {@link Engine.setSituation} * */ declare class Engine { /**@internal */ baseContext: Context; /**@internal */ context: Context; /**@internal */ publicParsedRules: ParsedRules; /**@internal */ publicSituation: Situation; /**@internal */ cache: Cache; /** * Creates an evaluation engine with the publicode rules given as arguments. * @param rules The publicodes model to use ({@link RawPublicodes} or {@link ParsedRules}) * @param options Configuration options */ constructor(rules?: RawPublicodes | ParsedRules, options?: EngineOptions); /** * Reset the engine cache. This will clear all the cached evaluations. */ resetCache(): void; /** * Set the situation used for the evaluation. * * All subsequent evaluations will use this situation. * Reset the evaluation cache to avoid inconsistencies, so it is costly to call this method frequently with the same situation. */ setSituation( /** * The situation to set (see {@link Situation}) */ situation?: Situation, options?: { /** * If true, the previous situation is kept and the new values are added to it. * @default false */ keepPreviousSituation?: boolean; /** * If set to true, the engine will throw when the * situation contains invalid values * (rules that don't exists, or values with syntax errors). * * If set to false, it will log the error and filter the invalid values from the situation * * Overrides the {@link EngineOptions} strict option */ strict?: boolean; }): this; /** * * @returns true if the engine has encountered an inversion error during the last evaluation */ inversionFail(): boolean; /** * Get the rule with the given dottedName. * @param dottedName * * @throws PublicodesError if the rule does not exist or is private */ getRule(dottedName: RuleNames): RuleNode; /** * * @returns the parsed rules used by the engine * * @remarks The private rules are not included in the parsed rules */ getParsedRules(): ParsedRules; /** * Retrieve the current situation used for the evaluation * * This situation can be slightly different from the one set with * {@link setSituation} if some values were filtered out because of * evaluation errors. * * @returns {@link Situation} used by the engine */ getSituation(): Situation; /** * Retrieves the list of possible values for a given rule. * * @param dottedName - The dotted name of the rule to get possibilities for * @param options - Options object * @param options.filterNotApplicable - When true, filters out possibilities that are not applicable based on the current situation. Defaults to false. * @returns Array of possibility nodes if the rule has possibilities defined, null otherwise * * @example * **Publicodes** * ```yaml * contrat: * une possibilité: * - "'CDI'" * - "'CDD'" * ```js * engine.getPossibilitiesFor('contrat') * * ``` */ getPossibilitiesFor(dottedName: RuleNames, { filterNotApplicable, }?: { filterNotApplicable?: boolean; }): Array | null; /** * Evaluate a publicodes expression. * * Use the current situation set by {@link setSituation}. * * @remarks * To improve performance, the engine will cache the evaluation of the expression, * and all its byproducts (intermediate evaluations). * The cache is reset when the situation is updated with {@link setSituation}. * You can also manually reset it with {@link resetCache}. * * @param value - The publicodes expression to evaluate. * @returns The {@link ASTNode} of the publicodes expression decorated with evaluation results (nodeValue, unit, missingVariables, etc.) * */ evaluate(value: PublicodesExpression | ASTNode): EvaluatedNode; /**@internal */ evaluateNode(parsedNode: T): EvaluatedNode & T; /** * Shallow Engine instance copy. Useful to evaluate the same rules with different situations. * * @returns a new Engine instance with the same baseContext, context, publicParsedRules, publicSituation and cache attributes. */ shallowCopy(): Engine; private checkExperimentalRule; private checkSituationRuleStatic; private checkSituationRulePossibilities; private parseSituationRules; } type GraphCycles = string[][]; type RawRules = Parameters[0]; /** * This function is useful so as to print the dependencies at each node of the * cycle. * ⚠️ Indeed, the findCycles function returns the cycle found using the * Tarjan method, which is **not necessarily the smallest cycle**. However, the * smallest cycle is more readable. */ declare function cyclicDependencies(rawRules: RawRules): [GraphCycles, string[]]; /** * Returns the last part of a dottedName (the leaf). */ declare const nameLeaf: (dottedName: string) => string; /** * Encodes a dottedName for the URL to be secure. * @see {@link decodeRuleName} */ declare const encodeRuleName: (dottedName: string) => string; /** * Decodes an encoded dottedName. * @see {@link encodeRuleName} */ declare const decodeRuleName: (dottedName: string) => string; /** * Return dottedName from contextName */ declare const contextNameToDottedName: (contextName: string) => string; /** * Returns the parent dottedName */ declare const ruleParent: (dottedName: string) => string; /** * Returns an array of dottedName from near parent to far parent. */ declare function ruleParents(dottedName: string): Array; /** * Returns an array of all child rules of a dottedName */ declare const getChildrenRules: (parsedRules: ParsedRules, dottedName: string) => string[]; /** * Finds the common ancestor of two dottedName */ declare function findCommonAncestor(dottedName1: string, dottedName2: string): string; /** * Check wether a rule is accessible from a namespace. * * Takes into account that some namespace can be `private`, i.e. that they can only be * accessed by immediate parent, children or siblings. * * @param rules The parsed rules * @param contextName The context of the call * @param name The namespace checked for accessibility */ declare function isAccessible(rules: ParsedRules, contextName: string, name: string): boolean; /** * Check wether a rule is tagged as experimental. * * Takes into account the a children of an experimental rule is also experimental * * @param rules The parsed rules * @param name The namespace checked for experimental */ declare function isExperimental(rules: ParsedRules, name: string): boolean; declare function disambiguateReference(rules: R, referencedFrom: string | undefined, partialName: string): keyof R; declare function ruleWithDedicatedDocumentationPage(rule: any): boolean; declare function updateReferencesMapsFromReferenceNode(node: ASTNode, referencesMaps: ReferencesMaps, ruleDottedName?: string): void; declare function disambiguateReferenceNode(node: ASTNode, parsedRules: ParsedRules): ReferenceNode | undefined; declare const ruleUtils_contextNameToDottedName: typeof contextNameToDottedName; declare const ruleUtils_cyclicDependencies: typeof cyclicDependencies; declare const ruleUtils_decodeRuleName: typeof decodeRuleName; declare const ruleUtils_disambiguateReference: typeof disambiguateReference; declare const ruleUtils_disambiguateReferenceNode: typeof disambiguateReferenceNode; declare const ruleUtils_encodeRuleName: typeof encodeRuleName; declare const ruleUtils_findCommonAncestor: typeof findCommonAncestor; declare const ruleUtils_getChildrenRules: typeof getChildrenRules; declare const ruleUtils_isAccessible: typeof isAccessible; declare const ruleUtils_isExperimental: typeof isExperimental; declare const ruleUtils_nameLeaf: typeof nameLeaf; declare const ruleUtils_ruleParent: typeof ruleParent; declare const ruleUtils_ruleParents: typeof ruleParents; declare const ruleUtils_ruleWithDedicatedDocumentationPage: typeof ruleWithDedicatedDocumentationPage; declare const ruleUtils_updateReferencesMapsFromReferenceNode: typeof updateReferencesMapsFromReferenceNode; declare namespace ruleUtils { export { ruleUtils_contextNameToDottedName as contextNameToDottedName, ruleUtils_cyclicDependencies as cyclicDependencies, ruleUtils_decodeRuleName as decodeRuleName, ruleUtils_disambiguateReference as disambiguateReference, ruleUtils_disambiguateReferenceNode as disambiguateReferenceNode, ruleUtils_encodeRuleName as encodeRuleName, ruleUtils_findCommonAncestor as findCommonAncestor, ruleUtils_getChildrenRules as getChildrenRules, ruleUtils_isAccessible as isAccessible, ruleUtils_isExperimental as isExperimental, ruleUtils_nameLeaf as nameLeaf, ruleUtils_ruleParent as ruleParent, ruleUtils_ruleParents as ruleParents, ruleUtils_ruleWithDedicatedDocumentationPage as ruleWithDedicatedDocumentationPage, ruleUtils_updateReferencesMapsFromReferenceNode as updateReferencesMapsFromReferenceNode }; } /** This function creates a transormation of the AST from on a simpler callback function `fn` `fn` will be called with the nodes of the ASTTree during the exploration The outcome of the callback function has an influence on the exploration of the AST : - `false`, the node is not updated and the exploration does not continue further down this branch - `undefined`, the node is not updated but the exploration continues and its children will be transformed - `ASTNode`, the node is transformed to the new value and the exploration does not continue further down the branch `updateFn` : It is possible to specifically use the updated version of a child by using the function passed as second argument. The returned value will be the transformed version of the node. */ declare function makeASTTransformer(fn: (node: ASTNode, transform: ASTTransformer) => ASTNode | undefined | false, stopOnUpdate?: boolean): ASTTransformer; /** * This function allows to construct a specific value while exploring the AST with * a simple reducing function as argument. * * `fn` will be called with the currently reduced value `acc` and the current node of the AST * * If the callback function returns: * - `undefined`, the exploration continues further down and all the children are reduced * successively to a single value * - `T`, the reduced value is returned * * `reduceFn` : It is possible to specifically use the reduced value of a child * by using the function passed as second argument. The returned value will be the reduced version * of the node */ declare function reduceAST(fn: (acc: T, n: ASTNode, reduceFn: (n: ASTNode) => T) => T | undefined, start: T, node: ASTNode): T; /** * Apply a transform function on children. Not recursive. */ declare const traverseASTNode: TraverseFunction; /** * Each error name with corresponding type in info value */ interface PublicodesErrorTypes { InternalError: { dottedName?: string; }; EngineError: Record; SyntaxError: { dottedName: string; }; EvaluationError: { dottedName: string; }; SituationError: { dottedName: string; }; UnknownRule: { dottedName: string; }; PrivateRule: { dottedName: string; }; TypeError: { dottedName: string; }; ParserError: { dottedName: string; position: number; expression: string; expected: string; found: string; }; } /** * @returns true if `error` is a PublicodesError * * @internal * * use `name` parameter to check and narow error type * @example * try { * new Engine().evaluate() * } catch (error) { * if (isPublicodesError(error, 'EngineError')) { * console.log(error.info) * } * } */ declare const isPublicodesError: (error: unknown, name?: Name) => error is PublicodesError; /** * Generic error for Publicodes * @internal */ declare class PublicodesError extends Error { name: Name; info: PublicodesErrorTypes[Name]; constructor(name: Name, message: string, info: PublicodesErrorTypes[Name], originalError?: Error); } declare function capitalise0(name: undefined): undefined; declare function capitalise0(name: string): string; /** * Format the result of an evaluation * * Useful to display the result of a calculation in a user interface. * It use the {@link Unit} to format the number and the unit. * * @param value - The value to format, usually a {@link EvaluatedNode} * @param options - Options to customize the formatting * @param options.language - @internal The language in which to display the result * @param options.displayedUnit - The unit to display, if different from the unit of the value * @param options.precision - The number of decimal digits to display * * @example * * ```ts * formatValue(engine.evaluate('3 € + 2 €')) // '5 €' * ``` */ declare function formatValue(value: number | { nodeValue: Evaluation; unit?: Unit; } | undefined, { language, displayedUnit, formatUnit, precision, }?: { language?: string; displayedUnit?: string; precision?: number; formatUnit?: formatUnit; }): any; /** * Simplify if possible the unit of a node * * If not used, the result of the evaluation of a node will have the * most precise unit possible, in order to prevent rounding errors. * * * @param node - The node to simplify * @returns The node its unit simplified * * @example * ```ts * simplifyNodeUnit(engine.evaluate('42 €/mois * 1 an')) * // returns { nodeValue: 504, unit: { numerators: ['€'], denominators: [] } } * ``` */ declare function simplifyNodeUnit(node: Node): Node; type BinaryOp = { '+': [ExprAST, ExprAST]; } | { '-': [ExprAST, ExprAST]; } | { '*': [ExprAST, ExprAST]; } | { '/': [ExprAST, ExprAST]; } | { '**': [ExprAST, ExprAST]; } | { '>': [ExprAST, ExprAST]; } | { '<': [ExprAST, ExprAST]; } | { '>=': [ExprAST, ExprAST]; } | { '<=': [ExprAST, ExprAST]; } | { '=': [ExprAST, ExprAST]; } | { '!=': [ExprAST, ExprAST]; }; type UnaryOp = { '-': [{ constant: { type: 'number'; nodeValue: 0; }; }, ExprAST]; }; /** AST of a publicodes expression. */ type ExprAST = BinaryOp | UnaryOp | { variable: string; } | { constant: { type: 'number'; nodeValue: number; rawUnit?: string; }; } | { constant: { type: 'boolean'; nodeValue: boolean; }; } | { constant: { type: 'string' | 'date'; nodeValue: string; }; }; declare function parseExpression(rawNode: string, dottedName?: string): ExprAST; /** * Serialize the evaluation of a node into a publicodes expression * */ declare function serializeEvaluation(node: EvaluatedNode): string | undefined; /** * A publicodes expression that can be evaluated by the {@link Engine}. * * It can be parsed to an ASTNode with the {@link parseExpression} function or evaluated directly by the engine with the {@link Engine.evaluate} method. * * @example * ```js * const expression1 = 'prix du panier' // Rule name * const expression2 = 'prix du panier + 20' // Operation * const expression3 = { valeur: "salaire brut", unité: "€/an", "arrondi": "oui" } // Mecanism * ``` */ type PublicodesExpression = string | Record | number; /** * A logger object that can be passed to the engine to log messages. * * Useful for debugging or customizing the engine's output. * @example only display errors and ignore warnings: * ```javascript * const logger = { * log: () => {}, * warn: () => {}, * error: console.error, * } * const engine = new Engine(rules, { logger }) * ``` */ type Logger = { log(message: string): void; warn(message: string): void; error(message: string): void; }; /**@internal */ type EvaluationFunction = (this: Engine, node: ASTNode & { nodeKind: Kind; }) => { nodeKind: Kind; } & EvaluatedNode; /** * A set of rules that have been parsed from a {@link RawPublicodes} object. * * @remarks The {@link Engine.evaluate} method is responsable for parsing the rules and cache them in the engine, but you can also parse them manually with the ${@link parsePublicodes} function. */ type ParsedRules = Record>; /** * Rules as they are output from the compilation step : a javascript object transformed from the yaml files * * They are parsed during the initialization of the engine (see {@link Engine.constructor}) */ type RawPublicodes = Partial>; /** * A situation object that can be passed to the engine * * Can be used to set the values of any existing rules with the {@link Engine.setSituation} method. * * Note: When strict option on `situation` (see {@link StrictOptions}) is set to the Engine, the situation passed to the engine can be filtered (but retrieved with {@link Engine.getSituation}). * * @example * ```js * const situation = { * "salaire brut": 30000 # can be a number * "contrat . heures travaillées": { * "valeur": 35, * "unité": "h/semaine" * } * */ type Situation = Partial>; export { type ASTNode, type BinaryOp, type EngineOptions, type EvaluatedNode, type Evaluation, type EvaluationFunction, type ExprAST, type FlagOptions, type Logger, type NodeKind, type ParsedRules, type Possibility, PublicodesError, type PublicodesExpression, type RawPublicodes, type Rule, type RuleNode, type Situation, type StrictOptions, type UnaryOp, type Unit, type WarnOptions, capitalise0, Engine as default, formatValue, isPublicodesError, parseExpression, parsePublicodes, parseUnit, reduceAST, serializeEvaluation, serializeUnit, simplifyNodeUnit, makeASTTransformer as transformAST, traverseASTNode, ruleUtils as utils };