Expressions de valeur (Value Expressions)
Chaque emplacement d'un Script où une valeur est nécessaire (une URL, un body de requête, une valeur de champ, une condition, une valeur de filtre, un id de cible, etc.) prend l'une des trois formes ci-dessous. Il n'y a que deux exceptions : le pattern de Regex et le key de Cache ne s'écrivent qu'en littéral, et le { /pointer } qu'ils contiennent n'est pas remplacé par une valeur. Ce document décrit ces trois formes, d'où viennent les valeurs (les racines de contexte) et les règles de mappage de locale propres aux données de WEEGLOO. Tous les champs du Catalogue des statements suivent ces règles.
Les trois formes
| Forme | Règle | Exemple |
|---|---|---|
| Référence (reference) | Résout le { /json-pointer } contenu dans une chaîne contre le contexte. | "{ /payload/fields/title }" |
| Littéral (literal) | Une valeur sans { /ptr } (chaîne, nombre, booléen, objet, tableau). Utilisée telle quelle. | "draft", 42, true, { "a": 1 } |
| Opérations et conditions (JsonLogic) | Un objet dont l'unique clé est un opérateur. Ses opérandes sont à leur tour des expressions de valeur (référence, littéral, imbrication). Selon l'emplacement, l'opérateur requiert un $. | { "$+": [ "{ /vars/n }", 1 ] } |
Les trois formes s'imbriquent. On les combine en plaçant une référence comme opérande de JsonLogic, puis en réinjectant le résultat d'une référence dans une opération.
Emplacement de données et emplacement d'expression : quand ajouter $
Un même JSON se lit différemment selon l'emplacement. Le critère qui les sépare est à qui appartiennent les clés de cet emplacement. Les clés de fields sont les id de champ d'un Content Type et les clés de Http.body relèvent du schéma de l'API distante : à ces emplacements, cat ou in doivent donc être des noms de champ et non des opérateurs.
| Emplacement | Champs concernés | Mode de lecture |
|---|---|---|
| Emplacement de données | fields (ResourceCreate, ResourceUpdate, ResourcePatch), Http.body, Return.value, SetVar.value, Cache.value, Cache.defaultValue | Une clé sans $ est toujours un nom de champ. Pour employer une opération, on lui ajoute $. |
| Emplacement d'expression | If.condition, Loop.while, version | La valeur entière est une expression. L'opérateur s'écrit aussi bien cat que $cat. |
| Emplacement de modèle | Tout le reste (url, method, headers[].value, locale, order, over, target.sys.id, les champs d'EmailSend, les champs de valeur de Signature, Hash et Regex) | Comme c'est une chaîne, seul { /pointer } peut y figurer. |
| Littéral exclusivement | Regex.pattern, Cache.key | Ce n'est pas une expression de valeur. Un { /pointer } écrit dans Regex.pattern n'est pas substitué : il fait partie du motif. |
Les règles tiennent en deux lignes.
- À un emplacement de données, une clé sans
$est toujours un nom de champ. Pour employer une opération, on ajoute$à l'opérateur. - Une fois que l'on est entré dans une expression avec un
$, tout ce qu'elle contient est une expression. Les opérateurs imbriqués n'ont pas besoin de$(on peut toutefois l'ajouter).
En cas de doute, préfixez tous les opérateurs par
$. C'est correct à n'importe quel emplacement.
// Emplacement de données : cat est un nom de champ du Content Type (ce n'est pas l'opération de concaténation)
"fields": { "cat": { "en-US": "hello" } }
// Calcul à un emplacement de données : le $ uniquement à la frontière, l'intérieur reste tel quel
"fields": { "tier": { "en-US": { "$if": [ { ">=": [ "{ /p/score }", 700 ] }, "gold", "silver" ] } } }
// Emplacement d'expression : on écrit tel quel
"condition": { "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }Quand il faut un nom de champ commençant par $ : $$
Lorsqu'une clé doit réellement commencer par $, comme $ref ou $schema en JSON Schema, on écrit $ deux fois. "$$ref" désigne la clé de données $ref. Un seul $ de tête est retiré ($$$ref donne $$ref), et cela ne s'applique qu'aux clés (un $ situé dans une valeur reste tel quel).
"body": { "$$ref": "#/components/schemas/Item", "topK": { "$min": [ "{ /payload/fields/k }", 50 ] } }Les deux cas rejetés
Les deux cas ci-dessous ne sont pas interprétés silencieusement dans un autre sens : ils sont rejetés comme des erreurs.
- Une clé
$présente aux côtés d'autres clés du même objet est une erreur. Une opération doit être l'unique clé de son objet ; il suffit de sortir les données sœurs d'un niveau. - Une clé
$inconnue est une erreur.$cattn'est pas un champ nommé$catt: l'espace de noms$est réservé aux opérateurs.
À un emplacement d'expression, il est également erroné qu'un nom d'opérateur côtoie des clés sœurs ({ "and": […], "or": […] }). À cet emplacement, aucune interprétation comme donnée n'existe et tout objet est évalué à vrai : si on la laisse ainsi, la condition devient silencieusement toujours vraie.
Référence : { /json-pointer }
Dans les accolades, on place un JSON Pointer RFC 6901 (qui doit commencer par /). Les espaces autour des accolades sont autorisés ({ /a/b } est identique à {/a/b}).
Pointer unique et modèle mixte : règles de type
- Quand toute la chaîne est un pointer unique, la valeur conserve son type original (si c'est un nombre, un nombre ; si c'est un objet, un objet ; si c'est un tableau, un tableau).
- Quand elle est mélangée à du texte littéral, il y a concaténation de chaînes (concatenation).
"{ /payload/fields/count }" // si nombre, nombre tel quel (p. ex. 42)
"{ /payload/fields/tags }" // si tableau, tableau tel quel
"page-{ /payload/fields/n }-of-10" // concaténation de chaînes → "page-42-of-10"
"Bearer { /payload/fields/token }" // concaténation de chaînes → "Bearer abc123"Valeurs absentes
- Si le chemin n'existe pas ou si la valeur est vide, un pointer unique devient
nullet un modèle mixte devient une chaîne vide.
Racines de contexte : d'où viennent les valeurs
Le segment de plus haut niveau d'un { /pointer } est l'un des sept suivants.
| Racine | Contenu |
|---|---|
/payload | Le payload JSON (l'entrée) transmis lors de l'appel. Exemple : { /payload/fields/email } |
/rawPayload | La même entrée, conservée telle quelle sous la forme de la chaîne du corps envoyée par l'appelant (avant parsing). Exemple : { /rawPayload } |
/headers | Les en-têtes HTTP de la requête transmis lors de l'appel. Les clés sont en minuscules et il y a une seule valeur par nom. Exemple : { /headers/authorization } |
/now | L'instant où l'exécution a démarré. { /now/seconds }, { /now/millis }, { /now/iso } |
/<name> | Le résultat d'un statement précédent portant ce name. Exemple : { /order/sys/id } |
/vars/<name> | Une variable mutable à portée de script déclarée avec SetVar. Exemple : { /vars/total } |
/error | Utilisée uniquement dans le bloc catch d'un Try. L'erreur capturée { message }. Exemple : { /error/message } |
Les six noms autres que /<name> (payload, rawPayload, headers, now, vars, error) sont réservés et ne peuvent pas servir de name à un statement. Employer le même nom écraserait cette racine : c'est donc refusé à l'enregistrement (voir les règles de nom de liaison des champs communs).
/rawPayload : le corps tel qu'il a été envoyé
/payload est la valeur parsée, /rawPayload est la chaîne d'origine du même corps. Les deux désignent la même chose sans être identiques. Refaire une chaîne à partir de la valeur parsée normalise les espaces, la notation des nombres, les échappements et les clés en doublon, si bien qu'on ne retrouve pas les octets envoyés.
C'est pourquoi une valeur calculée sur les octets envoyés ne peut se traiter qu'avec /rawPayload. Le cas typique est la vérification de signature d'un webhook de prestataire de paiement (voir Signature). Les références ordinaires, celles qui extraient une valeur, se font avec /payload.
Le corps de l'appel n'accepte que des objets JSON. Un corps vide est considéré comme absent et, si ce n'est pas un objet JSON (JSON invalide, tableau, scalaire, null littéral), l'exécution n'a pas lieu et l'appel est refusé (voir Erreurs).
/now : l'instant où l'exécution a démarré
/now contient sous trois formes l'instant où cette exécution a démarré.
| Pointer | Valeur |
|---|---|
{ /now/seconds } | Les secondes epoch (entier) |
{ /now/millis } | Les millisecondes epoch (entier) |
{ /now/iso } | La chaîne de notation temporelle de la plateforme, comme sys.createdAt (UTC) |
- Une exécution n'a qu'un seul instant. Ce n'est pas un statement qui lit l'horloge, mais une valeur posée au démarrage de l'exécution : deux statements ne peuvent donc pas voir des valeurs différentes. Chaque branche d'un
Parallelhérite du même instant. N'étant pas un statement, il ne compte pas non plus dans le nombre de statements. - Il n'y a pas de champ pour choisir le fuseau horaire. Une valeur epoch est le même nombre partout, et
isoest une notation UTC. - On l'utilise pour vérifier la fenêtre de rejeu (replay window) d'un webhook, c'est-à-dire à combien de secondes de maintenant se situe l'horodatage porté par la signature. L'horodatage arrive généralement sous forme de chaîne, mais les opérations arithmétiques le convertissent en nombre : on le compare donc tel quel.
// L'horodatage porté par la signature est-il dans les 5 minutes (300 secondes) ?
{ "<": [ { "-": [ "{ /now/seconds }", "{ /sig/1 }" ] }, 300 ] }Forme du résultat d'un statement
La forme du résultat d'un statement portant un name varie selon le type.
| Statement | Forme du résultat | Exemple de référence |
|---|---|---|
Http | { status, body } | { /resp/status }, { /resp/body/choices/0/message/content } |
ResourceCreate, ResourceRead (individuel), ResourceFind (individuel) | La ressource elle-même | { /post/sys/id }, { /post/fields/title/en-US } |
ResourceForEach | (Pendant le parcours) name est l'élément courant = la ressource elle-même. Référencé uniquement à l'intérieur de onEach | { /post/sys/id }, { /post/fields/title/en-US } |
ResourceCount | Le nombre d'éléments correspondants (un entier) | { /commentCount } |
ParseJson | La valeur parsée elle-même (objet, tableau, scalaire) | { /quote/items/0/price } |
Signature | Boolean (la vérification est-elle passée) | { /verified } |
Hash | Une chaîne (le condensé dans la notation déclarée) | { /expectedSign } |
Regex | Match donne un Boolean. Capture donne un tableau (0 = la correspondance entière, les groupes de capture à partir de 1) ou null s'il n'y a pas de correspondance | { /isOrderId }, { /sig/1 } |
ResourceFindlienulls'il n'y a pas de correspondance. On teste l'existence avec{ "==": [ "{ /found }", null ] }.ResourceRead(individuel) est une erreur si la cible n'existe pas (gérable avecTry). Les détails sont traités dans Lecture de ressources dans le Catalogue des statements.- Lire un ServiceUser donne pour résultat la ressource membre elle-même (
{ /member/sys/id }). Contrairement à Content et Media, ses champs ne sont pas des mappages de locale mais les valeurs elles-mêmes. Les règles sont traitées dans Lecture de l'annuaire des membres.
Opérations et conditions : JsonLogic
Lorsqu'un calcul ou une condition est nécessaire, on utilise l'objet opérateur de la spécification jsonlogic.com.
- L'accès aux données est unifié via des références
{ /ptr }, et non via levarvanilla (dot-path). Le moteur résout d'abord les pointers des opérandes, puis applique l'opérateur. - L'opérateur doit être l'unique clé de son objet. À un emplacement de données, seules les clés préfixées de
$sont des opérations ; à un emplacement d'expression, la clé est une opération avec ou sans$(voir Emplacement de données et emplacement d'expression).
Tableau des opérateurs
Les noms du tableau sont les tokens d'opérateur. Pour les employer à un emplacement de données, on les préfixe de
$(catdevient$cat). À un emplacement d'expression, les deux formes conviennent.
| Catégorie | Opérateur | Signification et exemple |
|---|---|---|
| Condition | if (alias ?:) | { "if": [cond, alors, cond2, alors2, …, défaut] }. La valeur de la première condition vraie ; s'il n'y en a pas, la dernière valeur par défaut. |
| Logique | and, or | Évaluation en court-circuit. and renvoie le premier falsy (ou le dernier), or le premier truthy (ou le dernier), comme valeur. |
| Logique | ! (not), !! (to-bool) | { "!": x } nie le truthy, { "!!": x } indique si c'est truthy. Pour les contrôles d'existence, on utilise souvent !!. |
| Égalité | ==, != | Comparaison souple (comparaison après conversion numérique forcée ; "1"==1 est vrai). |
| Égalité | ===, !== | Comparaison stricte (y compris le type). |
| Comparaison | <, <=, >, >= | Enchaînable : { "<": [1,2,3] } équivaut à 1<2 AND 2<3. Non convertible en nombre (NaN) donne false. |
| Arithmétique | + | La somme de tous les opérandes. |
| Arithmétique | - | Avec un seul opérande, négation ; avec deux, soustraction. |
| Arithmétique | *, /, % | Multiplication, division, reste. |
| Agrégation | min, max | Le minimum et le maximum des opérandes. |
| Chaîne | cat | Concatène tous les opérandes en une chaîne. |
| Appartenance | in | { "in": [needle, haystack] }. Si haystack est une chaîne, sous-chaîne ; si c'est une collection, appartenance d'un élément. |
| Tableau | merge | Aplatit plusieurs tableaux ou valeurs en un seul tableau (utilisé pour l'accumulation). |
| Date | date | { "date": [valeur, unité de sortie] }. Normalise la valeur en un instant comparable. Les unités de sortie sont millis (par défaut), seconds, iso et day. Voir Normalisation des dates. |
Les opérateurs d'itération de tableau (map, filter, reduce, all, some, none) ne sont pas pris en charge. Script itère sur les tableaux avec Loop (Loop dans le Catalogue des statements). Sélectionner dans une liste les seuls éléments qui satisfont une condition de date n'est pas non plus l'affaire d'un parcours, mais celle d'un statement de lecture. Si l'on donne la condition au where de ResourceFind et de ResourceForEach, le serveur filtre et renvoie le résultat (les opérateurs disponibles figurent dans la liste des opérateurs).
Conversion numérique et exemples
Les règles de conversion numérique sont les suivantes. Un nombre reste tel quel, true devient 1, false devient 0, une chaîne est analysée (si elle ne peut pas être analysée, le calcul échoue) et null devient 0.
Une chaîne de date n'est pas un nombre. "2026-10-03" ne s'analyse pas comme un nombre : les opérateurs de comparaison renvoient donc toujours false, sans erreur. Pour comparer des dates, on les normalise d'abord avec date.
Les extraits ci-dessous sont donnés pour un emplacement d'expression. Pour les placer à un emplacement de données (fields, Http.body, Return.value, SetVar.value), on ajoute $ à l'opérateur de plus haut niveau et on laisse les opérandes internes tels quels.
{ "-": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] } // solde - coût
{ "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] } // solde < coût → boolean
{ "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }
{ "cat": [ "id-", "{ /payload/sys/id }" ] } // "id-<uuid>"
{ "!!": "{ /found/sys/id }" } // true s'il existe
{ "$merge": [ "{ /vars/ids }", [ "{ /row/sys/id }" ] ] } // accumulation dans un tableau : SetVar.value est un emplacement de données, d'où le $
{ "if": [ "{ /payload/fields/next }", "{ /payload/fields/next }", "END" ] } // next s'il existe, sinon "END"Normalisation des dates (date)
Les opérateurs de comparaison convertissent leurs opérandes en nombres avant de les comparer. Une chaîne de date n'étant pas un nombre, cette comparaison vaut toujours false, sans erreur. Passer à == ne résout pas le problème. Lorsque les deux côtés ne sont pas des nombres, le texte est comparé tel quel : "2026-10-03" et "2026-10-03T00:00:00.000Z", qui notent le même instant différemment, deviennent donc des valeurs différentes. Une date se normalise avec date avant d'être comparée.
{ "date": [ valeur, unité de sortie ] } // l'unité de sortie peut être omise
{ "date": "2026-10-03" } // avec une seule valeur, on peut retirer le tableauIl n'existe pas d'opérateurs dédiés before, after ou equal. La valeur normalisée étant un nombre, il suffit d'employer les opérateurs de comparaison, d'arithmétique et d'agrégation qui existent déjà.
| Ce que l'on veut déterminer | Expression à écrire |
|---|---|
| a est antérieur à b | { "<": [ { "date": a }, { "date": b } ] } |
| a est postérieur à b | { ">": [ { "date": a }, { "date": b } ] } |
| Le même instant | { "==": [ { "date": a }, { "date": b } ] } |
| Le même jour (heure ignorée) | { "==": [ { "date": [a, "day"] }, { "date": [b, "day"] } ] } |
| Entre from et to | { "<=": [ { "date": from }, { "date": x }, { "date": to } ] } (comparaison enchaînée) |
| Une semaine plus tard | { "date": [ { "+": [ { "date": x }, 604800000 ] }, "iso" ] } |
| L'écart en jours entre deux dates | { "/": [ { "-": [ { "date": a }, { "date": b } ] }, 86400000 ] } |
| La plus ancienne de plusieurs dates | { "min": [ { "date": a }, { "date": b } ] } |
Le résultat d'une opération arithmétique est de nouveau un nombre de millisecondes : on peut donc le repasser dans date pour le sortir en iso ou en day (voir « Une semaine plus tard » dans le tableau ci-dessus).
// Emplacement d'expression : le coupon est-il dans sa période de validité ? Les trois valeurs peuvent être notées différemment
{ "<=": [
{ "date": "{ /coupon/fields/startsAt/en-US }" },
{ "date": "{ /now/iso }" },
{ "date": "{ /coupon/fields/endsAt/en-US }" }
] }
// Emplacement d'expression : l'en-tête HTTP Date est-il à moins de 5 minutes (300 secondes) de maintenant ?
{ "<": [ { "-": [ "{ /now/seconds }", { "date": [ "{ /headers/date }", "seconds" ] } ] }, 300 ] }Les entrées reconnues
Toutes les valeurs ci-dessous sont lues comme le même instant.
| Format | Exemple |
|---|---|
| ISO-8601, RFC 3339 | 2026-10-03T00:00:00Z, 2026-10-03T00:00:00.000Z, 2026-10-03T09:00:00+09:00 |
| Un instant sans les secondes ni les décimales | 2026-10-03T00:00 |
Un instant avec une espace à la place du T | 2026-10-03 00:00:00 |
| La date seule (lue comme minuit UTC) | 2026-10-03 |
RFC 1123 (la notation de l'en-tête HTTP Date) | Sat, 03 Oct 2026 00:00:00 GMT |
| Un nombre epoch ou une chaîne numérique | 1790985600, 1790985600000, "1790985600" |
- En l'absence d'offset, la valeur est lue en UTC. L'offset accepte aussi bien
+09:00que+0900,+09ouZ. - Le parsing est strict. Même si le nombre de chiffres est correct, une date qui n'existe pas réellement (
2026-13-45) échoue. - Pour un epoch, l'unité se devine à la grandeur de la valeur absolue. En dessous de 100 000 000 000, ce sont des secondes ; au-delà, des millisecondes. C'est pourquoi
{ /now/seconds }comme{ /now/millis }sont lus correctement, chacun dans son unité. - La plage reconnue comme epoch va d'une valeur absolue de 100 000 000 incluse à 100 000 000 000 000 exclue. Comme l'unité doit se deviner à la grandeur, la plage est bornée des deux côtés. Les autres nombres échouent au lieu d'être lus comme l'année 1970. C'est le cas d'une date sans séparateurs comme
20261003, d'une année comme2026, ou du0transmis pour signifier l'absence de valeur.
Les unités de sortie
Le second opérande détermine la forme de sortie. Le nom de l'unité est insensible à la casse.
| Valeur | Résultat | Où l'employer |
|---|---|---|
Omis, millis | Millisecondes epoch (nombre) | Comparaison et arithmétique |
seconds | Secondes epoch (nombre). Les fractions de seconde sont abandonnées | Une API externe qui attend des secondes epoch |
iso | 2026-10-03T00:00:00.000Z | Écrire dans le champ Date d'un Content |
day | 2026-10-03 (en UTC) | Comparer un même jour, affichage |
Un nom absent de cette liste échoue, et le message d'erreur énumère les noms disponibles.
La sortie iso et l'écriture dans un champ Date
À l'écriture, le champ Date d'un Content n'accepte qu'un seul format : yyyy-MM-ddTHH:mm:ss[.décimales]Z. Le T, les secondes et le Z final doivent tous être présents, les décimales sont facultatives, et la valeur est lue en UTC. Écrire tel quel un 2026-10-03 ou un 2026-10-03T09:00:00+09:00 reçu dans le payload est donc rejeté comme valeur invalide. La sortie iso de date correspond exactement à ce format : on fait donc passer une fois la date reçue par date avant de l'écrire dans le champ.
// Emplacement de données : on écrit le "2026-10-03" du payload dans la date d'expiration du coupon
"fields": { "endsAt": { "en-US": { "$date": [ "{ /payload/fields/endsAt }", "iso" ] } } }Les valeurs illisibles
Dans les trois cas ci-dessous, le statement échoue (status 400). Comme l'échec survient pendant l'exécution, il peut être traité localement par le catch d'un Try.
- Le premier opérande est absent, ou la référence n'a pas trouvé de valeur.
- La valeur ne peut pas être lue comme une date. C'est le cas d'une chaîne vide, d'une chaîne faite uniquement d'espaces, d'une chaîne qui n'est pas une date, d'une date inexistante, d'un booléen, d'un objet ou d'un nombre hors de la plage reconnue.
- Le nom de l'unité de sortie est absent de la liste.
Ne pas renvoyer null lorsque la valeur est absente est un contrat voulu. null devient 0 à la conversion numérique et se retrouve donc comparé à l'année 1970 : un contrôle auquel la date manque n'échoue pas, il donne le résultat inverse. Qu'un coupon expiré soit accepté est pire que de voir l'exécution s'arrêter.
Évaluation du vrai et du faux (Truthiness)
if, and, or, !, !! ainsi que If.condition et Loop.while déterminent le vrai et le faux selon les règles suivantes.
- falsy :
null,false, le nombre0, la chaîne vide"", une collection vide (un tableau vide). - truthy : tout le reste (les nombres différents de 0, les chaînes et tableaux non vides, et tous les objets).
Les clés aussi peuvent être des références
La clé d'un mappage comme fields prend elle aussi en charge les références { /ptr }. La clé est résolue à l'exécution.
"fields": { "{ /payload/fields/fieldName }": { "en-US": "{ /payload/fields/fieldValue }" } }Si deux clés se résolvent à la même valeur, il y a collision et c'est une erreur du moteur.
Mappage de locale : règles spécifiques à Content et Media
Dans WEEGLOO, chaque champ d'un Content ou d'un Media n'est pas une valeur mais un mappage par locale (par exemple, balance vaut { "en-US": 1, "ko-KR": 10 }). Il faut donc gérer la locale conjointement lors de la lecture et de l'écriture. Pour Media aussi, title et description (des scalaires) ainsi que file (l'instruction d'ingestion) sont des mappages de locale. Le JSON qui n'est ni Content ni Media, comme /payload ou une réponse HTTP, n'est pas concerné par cette règle (il conserve la structure définie par le schéma, et un scalaire reste un scalaire).
Lecture
- Pour obtenir un scalaire, on précise jusqu'à la locale :
{ /<name>/fields/<field>/<locale> }(par exemple,{ /post/fields/title/en-US }). - Sans locale,
{ /<name>/fields/<field> }renvoie l'objet complet du mappage de locale. - Un champ
localized:falsese trouve uniquement dans le bucket de la locale par défaut, on le lit donc avec le code de cette locale par défaut.
Écriture (les fields de ResourceCreate, ResourceUpdate, ResourcePatch)
La valeur est un mappage de locale { "<locale>": <expression de valeur scalaire> }. C'est symétrique à la lecture.
"fields": {
"title": { "en-US": "Hello", "ko-KR": "안녕" }, // énumère les buckets pour plusieurs locales
"status": { "en-US": "paid" }
}ResourceCreatedoit obligatoirement inclure le bucket de la locale par défaut du Space dans chaque champ renseigné (la règle default-locale).ResourceUpdateest un remplacement complet. Les champs et les locales absents defieldssont supprimés (y compris le fichier).ResourcePatchne met à jour que les champs et buckets spécifiés (les autres champs et locales sont conservés).- Suppression avec un
nulllittéral : si la valeur est unnulllittéral, le bucket (field, locale) correspondant est supprimé (la méthode standard pour vider une locale précise dans un Patch).""(chaîne vide) n'est pas une suppression, mais l'affectation d'une valeur vide. Si une expression de valeur ({ /ptr }) s'évalue à null à l'exécution, ce n'est pas une suppression mais une erreur (un payload manquant n'est pas avalé silencieusement). Seul unnulllittéral supprime. Mediafile: la valeur n'est pas un scalaire mais une instruction d'ingestion{ "source": …, "encoding": "url"|"base64" }. Ce que l'ingestion fait réellement est traité dans ResourceCreate du Catalogue des statements.- Un champ
localized:falsen'est placé que dans le bucket de la locale par défaut. - Le code de locale (la clé du mappage) peut lui aussi être une référence
{ /ptr }(voir ci-dessus Les clés aussi peuvent être des références). On l'utilise pour créer des locales dynamiques.
Champ de commodité locale
Si l'on donne un locale à ResourceCreate, ResourceUpdate ou ResourcePatch, le moteur enveloppe automatiquement chaque valeur de fields dans un bucket { <locale>: valeur }. Il suffit donc de donner des scalaires.
// les deux suivants sont identiques
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
"locale": "en-US", "fields": { "title": "Hello" } }
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
"fields": { "title": { "en-US": "Hello" } } }Si l'on donne locale et que la valeur imbrique déjà un mappage de locale ({ "en-US": … }), on obtient une double imbrication { <locale>: { "en-US": … } } (erreur de l'auteur). On unifie sur un seul style : avec locale, uniquement des scalaires ; sans lui, uniquement des mappages de locale explicites.
La locale dans where et order
- Dans
whereetorder, pourfields.X, le moteur applique automatiquement la locale par défaut du Space (comme pour une requête CMA). - Pour désigner une locale précise, on la spécifie avec
fields.X.<locale>.
"where": { "fields.slug": { "eq": "{ /payload/fields/slug }" } } // slug de la locale par défaut
"where": { "fields.title.ko-KR": { "prefix": "안" } } // locale préciseErreurs
Ce sont les codes qui surviennent lorsqu'une règle des expressions de valeur est enfreinte. La vérification a lieu lors de l'enregistrement ; les codes qui sanctionnent une infraction aux autres contraintes statiques de la définition figurent dans Erreurs de Sémantique d'exécution, contraintes et sécurité, et les codes qui surviennent lors de l'appel dans Erreurs de Ressource Script et endpoints. Pour les codes communs à toutes les ressources, consultez Erreurs communes.
| Code | Condition |
|---|---|
WGL400056 | À un emplacement de donnée, une clé d'opération $ a été placée aux côtés d'autres clés du même objet. |
WGL400055 | À un emplacement de donnée figure une clé $ qui n'est définie comme aucun opérateur. |
Documents connexes
- Catalogue des statements : les champs et les résultats des 25 types de statement qui utilisent des expressions de valeur.
- Sémantique d'exécution, contraintes et sécurité : ordre d'exécution, erreurs, verrouillage optimiste, contraintes statiques.
- Cookbook : exemples complets combinant des expressions de valeur.
- Aperçu de Script : la structure de niveau supérieur et le temps alloué à une exécution.
