ObjectOS
Référence

Expressions CEL

Le langage d'expression utilisé pour les formules, les prédicats, les planifications et les chaînes à modèle — exposé via cinq tagged templates.

Expressions CEL

ObjectOS utilise CEL (Common Expression Language) partout où vous avez besoin d'une expression petite, sûre et isolée : champs de formule, règles de validation, prédicats de visibilité, conditions de partage, gardes de flux, planifications et chaînes à modèle.

La rédaction se fait via cinq tagged templates importés depuis @objectstack/spec. Ils produisent tous un petit objet JSON que le runtime analyse :

{ dialect: 'cel' | 'template' | 'cron', source: string }

Source du schéma : packages/spec/src/shared/expression.zod.ts.

Les cinq tagged templates

TemplateDialecteÀ utiliser pourExemple
F`...`celChamps de formule — valeurs dérivées stockées avec l'enregistrementF`record.amount * 0.1`
P`...`celPrédicats — booléens pour la validation / le partage / la visibilité / les conditionsP`record.status == "open"`
cel`...`celCEL générique — quand ni F ni P ne convient (par ex. une valeur de paramètre)cel`now() + duration("P30D")`
tmpl`...`templateChaînes à modèle avec interpolation {{var}}tmpl`Order from {{record.customer.name}}`
cron`...`cronPlanifications — syntaxe cron standard à 5 champscron`0 9 * * 1-5`

Il n'y a aucune différence fonctionnelle entre F, P et cel au moment de l'évaluation — ils exécutent tous CEL. La distinction existe pour que les schémas (et les agents IA) sachent quel rôle joue l'expression et pour que l'éditeur puisse vérifier les types (les formules doivent renvoyer une valeur, les prédicats doivent renvoyer un booléen).

Import

import { F, P, cel, tmpl, cron } from '@objectstack/spec'

Où chacun est utilisé

Champ sur une specTagEmplacement d'exemple
Field.expression (type formule)Fchamps de formule *.object.ts
Field.conditionalRequiredPchamps d'objet
Validation.predicatePvalidations d'objet
SharingRule.conditionPrègles de partage
View.conditionalFormatting[].conditionPvues
Flow.step.when / Flow.transition.whenPflux
Action.guardPactions
Sujets de notification / corps de messagetmplnotifications
Schedule.croncronflux / rapports planifiés
Toute valeur de paramètrecelentrées d'étape de flux

Portée des variables

Les expressions CEL s'évaluent dans un contexte comportant ces variables de premier niveau :

VariableDisponible quandContenu
recordpresque toujoursL'enregistrement en cours d'évaluation
previoussur les hooks de mise à jour / la détection de changementL'état de l'enregistrement avant le changement (ou null)
inputactions, étapes de fluxLa charge utile d'entrée fournie par l'utilisateur
os.usertoujours{ id, roles: string[], permissions: string[] }
os.orgtoujoursContexte d'organisation / de locataire
os.envtoujoursVariables d'environnement exposées aux expressions

Les anciennes variables OLD / NEW ont été supprimées en M9.5. Utilisez previous et record.

Bibliothèque standard

Enregistrée dans packages/formula/src/stdlib.ts. Les fonctions intégrées les plus utilisées :

Temps

FonctionRenvoieNotes
now()TimestampFigé au contexte d'évaluation — stable au sein d'une même requête
today()TimestampDébut du jour UTC
daysFromNow(int)TimestampDate future
daysAgo(int)TimestampDate passée

CEL inclut aussi les fonctions natives timestamp(...), duration(...), date.getDayOfWeek(), etc. — voir la spécification CEL.

Utilitaires

FonctionObjet
isBlank(x)true si null, undefined, "" ou liste vide
coalesce(a, b)Première valeur non nulle
trim(s)Supprime les espaces
joinNonEmpty(list, sep)Concatène les entrées non vides

Les fonctions natives CEL pour les chaînes (.contains(...), .startsWith(...), .matches(...), .size()) sont toujours disponibles.

Exemples

Champ de formule — total d'une ligne d'article :

{ name: 'subtotal', type: 'formula', expression: F`record.quantity * record.unit_price` }

Validation — la date de clôture doit être postérieure à aujourd'hui :

{ message: 'Close date must be in the future', predicate: P`record.close_date > today()` }

Visibilité — afficher le champ uniquement aux managers :

{ visibleIf: P`'manager' in os.user.roles` }

Garde de flux — ignorer l'étape lorsque le montant est faible :

{ when: P`record.amount >= 1000` }

Planification — 9h en semaine :

{ schedule: cron`0 9 * * 1-5` }

Modèle — sujet de notification :

{ subject: tmpl`[{{record.priority}}] {{record.subject}}` }

Erreurs

Les expressions sont compilées au moment du chargement. Les échecs apparaissent comme VALIDATION_ERROR avec l'emplacement source :

{ "code": "VALIDATION_ERROR", "message": "CEL: unknown field 'amout' on Record", "details": { "field": "subtotal", "expression": "record.amout * 0.1" } }

Les expressions invalides n'échouent pas silencieusement. Une expression mal formée ou comportant un champ inconnu fait échouer os compile avec le message localisé ci-dessus (y compris une suggestion « vouliez-vous dire » pour un champ mal orthographié). Au runtime, une mauvaise expression lève une erreur attribuée plutôt que de s'évaluer silencieusement à null ou false, de sorte que l'échec est visible dans les journaux et la piste d'audit au lieu de corrompre discrètement la valeur d'un formule ou la décision d'une garde.

Voir aussi

On this page