Expressões de valor (Value Expressions)
Última atualização: 20 de julho de 2026
Todo lugar em um Script onde é necessário um valor (uma URL, um corpo de requisição, um valor de campo, uma condição, um valor de filtro, um id de destino, etc.) assume uma das três formas abaixo. Este documento descreve essas três formas, de onde vêm os valores (as raízes de contexto) e as regras de mapa de locales específicas dos dados do WEEGLOO. Todos os campos do Catálogo de statements seguem essas regras.
As três formas
| Forma | Regra | Exemplo |
|---|---|---|
| Referência (reference) | Resolve um { /json-pointer } dentro de uma string contra o contexto. | "{ /payload/fields/title }" |
| Literal (literal) | Um valor sem { /ptr } (uma string, número, booleano, objeto ou array). Usado tal como está. | "draft", 42, true, { "a": 1 } |
| Operações e condições (JsonLogic) | Um objeto que tem um único operador como chave. Os operandos são, por sua vez, expressões de valor (referências, literais ou aninhamentos). | { "+": [ "{ /vars/n }", 1 ] } |
As três formas se aninham: você coloca uma referência em um operando de JsonLogic e reintroduz o resultado dessa referência em outra operação.
Referência: { /json-pointer }
Coloque um JSON Pointer conforme a RFC 6901 (que deve começar com /) dentro das chaves. Espaços em branco ao redor das chaves são permitidos ({ /a/b } é igual a {/a/b}).
Pointer único vs. template misto: regras de tipo
- Quando toda a string é um único pointer, o valor mantém seu tipo original (se for número, número; se for objeto, objeto; se for array, array).
- Quando é misturado com texto literal, o resultado é concatenação de strings (concatenation).
"{ /payload/fields/count }" // se for um valor numérico, número tal como está (ex.: 42)
"{ /payload/fields/tags }" // se for um array, array tal como está
"page-{ /payload/fields/n }-of-10" // concatenação de strings → "page-42-of-10"
"Bearer { /payload/fields/token }" // concatenação de strings → "Bearer abc123"Valores ausentes e escape
- Quando o caminho não existe ou o valor está vazio, um único pointer se torna
nulle um template misto se torna uma string vazia. - Para usar
{como literal, escape-o como\{(essa posição não é interpretada como pointer).
Raízes de contexto: de onde vêm os valores
O segmento de nível superior de um { /pointer } é um dos cinco a seguir.
| Raiz | Conteúdo |
|---|---|
/payload | O payload JSON (a entrada) passado na chamada. Exemplo: { /payload/fields/email } |
/headers | Os cabeçalhos HTTP da requisição passados na chamada. As chaves são minúsculas, com um único valor por nome. Exemplo: { /headers/authorization } |
/<name> | O resultado de um statement anterior que carrega esse name. Exemplo: { /order/sys/id } |
/vars/<name> | Uma variável mutável com escopo de script declarada com SetVar. Exemplo: { /vars/total } |
/error | Usado somente dentro do bloco catch de um Try. O erro capturado, { message, statement }. Exemplo: { /error/message } |
A forma do resultado de um statement
A forma do resultado de um statement que carrega um name varia conforme o tipo.
| Statement | Forma do resultado | Exemplo de referência |
|---|---|---|
Http | { status, body } | { /resp/status }, { /resp/body/choices/0/message/content } |
ResourceCreate, ResourceRead (individual), ResourceFind (individual) | O próprio recurso | { /post/sys/id }, { /post/fields/title/en-US } |
ResourcePageRead | { items, next } | { /page/items/0/sys/id }, { /page/next } |
ResourceFindvinculanullquando não há correspondência. Faça a ramificação por existência com{ "==": [ "{ /found }", null ] }.ResourceRead(individual) é um erro quando o alvo não existe (é possível tratá-lo comTry). Os detalhes são abordados em Leitura de recursos no Catálogo de statements.
Operações e condições: JsonLogic
Quando precisar de um cálculo ou uma condição, use um objeto operador da especificação de jsonlogic.com.
- O acesso aos dados é unificado em referências
{ /ptr }, não novarvanilla (dot-path). O motor resolve primeiro os pointers dos operandos e depois aplica o operador. - Quando a chave de um objeto de chave única é um operador registrado, ela é tratada como uma operação; caso contrário, como um objeto comum.
Tabela de operadores
| Categoria | Operador | Significado e exemplo |
|---|---|---|
| Condição | if (alias ?:) | { "if": [cond, então, cond2, então2, …, padrão] }. O valor da primeira condição verdadeira; se não houver nenhuma, o último padrão. |
| Lógica | and, or | Avaliação em curto-circuito. and retorna o primeiro operando falsy (ou o último); or, o primeiro truthy (ou o último), como valor. |
| Lógica | ! (not), !! (to-bool) | { "!": x } nega o truthy; { "!!": x } indica se é truthy. Para verificar a existência, usa-se !! com frequência. |
| Igualdade | ==, != | Comparação frouxa (compara após conversão numérica forçada; "1"==1 é verdadeiro). |
| Igualdade | ===, !== | Comparação estrita (incluindo o tipo). |
| Comparação | <, <=, >, >= | Encadeável: { "<": [1,2,3] } significa 1<2 AND 2<3. Se um valor não puder ser convertido em número (NaN), é false. |
| Aritmética | + | A soma de todos os operandos. |
| Aritmética | - | Com um operando, negação; com dois, subtração. |
| Aritmética | *, /, % | Multiplicação, divisão, resto. |
| Agregação | min, max | O mínimo e o máximo dos operandos. |
| String | cat | Concatena todos os operandos como strings. |
| Pertencimento | in | { "in": [needle, haystack] }. Se o haystack for uma string, é substring; se for uma coleção, é pertencimento de elemento. |
| Array | merge | Achata vários arrays ou valores em um único array (usado para acumulação). |
Os operadores de iteração de arrays (map, filter, reduce, all, some, none) não são suportados. O Script percorre um array com Loop (Loop no Catálogo de statements).
Conversão numérica e exemplos
As regras de conversão numérica são as seguintes. Um número é mantido como está, true vira 1, false vira 0, uma string é parseada (se não puder ser parseada, o cálculo produz um valor de falha) e null vira 0.
{ "-": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] } // saldo - custo
{ "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] } // saldo < custo → boolean
{ "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }
{ "cat": [ "id-", "{ /payload/sys/id }" ] } // "id-<uuid>"
{ "!!": "{ /found/sys/id }" } // true se existir
{ "merge": [ "{ /vars/ids }", [ "{ /row/sys/id }" ] ] } // acumula um elemento no array
{ "if": [ "{ /page/next }", "{ /page/next }", "END" ] } // next se existir, caso contrário "END"Avaliação de verdadeiro e falso (Truthiness)
if, and, or, !, !!, junto com If.condition e Loop.while, determinam verdadeiro e falso pelas regras a seguir.
- falsy:
null,false, o número0, a string vazia""e uma coleção vazia (um array vazio). - truthy: todo o resto (números diferentes de 0, strings e arrays não vazios, e todos os objetos).
As chaves também podem ser referências
As chaves de um mapa como fields também suportam referências { /ptr }. A chave é resolvida em tempo de execução.
"fields": { "{ /payload/fields/fieldName }": { "en-US": "{ /payload/fields/fieldValue }" } }Se duas chaves forem resolvidas para o mesmo valor, elas colidem e é um erro do motor.
Mapa de locales (LocaleValueMap): regras específicas de Content e Media
No WEEGLOO, cada campo de um Content ou Media não é um valor, mas um mapa por locale (por exemplo, balance é { "en-US": 1, "ko-KR": 10 }). Por isso, ao ler e escrever, é preciso tratar o locale em conjunto. No Media também, title e description (escalares) e file (a instrução de ingestão) são mapas por locale. O JSON que não é Content nem Media, como /payload ou uma resposta HTTP, não é afetado por essa regra (mantém a estrutura definida pelo esquema, e um escalar continua sendo um escalar).
Leitura
- Para obter um escalar, especifique até o locale:
{ /<name>/fields/<field>/<locale> }(por exemplo,{ /post/fields/title/en-US }). - Sem locale,
{ /<name>/fields/<field> }retorna o objeto completo do mapa por locale. - Um campo
localized:falsefica somente no bucket do locale padrão, portanto leia-o com o código desse locale padrão.
Escrita (os fields de ResourceCreate, ResourceUpdate e ResourcePatch)
O valor é um mapa por locale, { "<locale>": <expressão de valor escalar> }. É simétrico com a leitura.
"fields": {
"title": { "en-US": "Hello", "ko-KR": "안녕" }, // enumera os buckets para vários locales
"status": { "en-US": "paid" }
}ResourceCreatedeve incluir o bucket do locale padrão do Space em todos os campos que preenche (a regra default-locale).ResourceUpdateé uma substituição completa. Os campos e locales ausentes defieldssão removidos (incluindo o arquivo).ResourcePatchatualiza somente os campos e buckets especificados (os demais campos e locales são mantidos).- Exclusão com um
nullliteral: quando o valor é umnullliteral, esse bucket (field, locale) é excluído (a forma padrão de esvaziar um locale específico em um Patch).""(uma string vazia) não é uma exclusão, mas define um valor vazio. Quando uma expressão de valor ({ /ptr }) é avaliada como null em tempo de execução, não é uma exclusão, mas um erro (um payload ausente não é ignorado silenciosamente). Somente umnullliteral exclui. Mediafile: o valor não é um escalar, mas uma instrução de ingestão,{ "source": …, "encoding": "url"|"base64" }. A escrita que inclui um arquivo é exclusiva do modo Async (ResourceCreate no Catálogo de statements).- Coloque um campo
localized:falsesomente no bucket do locale padrão. - O código de locale (a chave do mapa) também pode ser uma referência
{ /ptr }(veja acima As chaves também podem ser referências). Use isso para criar um locale dinâmico.
Campo de conveniência locale
Ao passar locale para ResourceCreate, ResourceUpdate ou ResourcePatch, o motor envolve automaticamente cada valor de fields em um bucket { <locale>: valor }. Ou seja, basta passar escalares.
// os dois abaixo são equivalentes
{ "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" } } }Se você passar locale enquanto o valor já aninha um mapa por locale ({ "en-US": … }), ocorre um aninhamento duplo como { <locale>: { "en-US": … } } (erro do autor). Padronize um único estilo: com locale, use somente escalares; sem ele, use somente mapas de locale explícitos.
O locale em where e order
- Em
whereeorder, parafields.Xo motor aplica automaticamente o locale padrão do Space (igual a uma consulta na CMA). - Para direcionar a um locale específico, indique-o explicitamente como
fields.X.<locale>.
"where": { "fields.slug": { "eq": "{ /payload/fields/slug }" } } // slug do locale padrão
"where": { "fields.title.ko-KR": { "prefix": "안" } } // locale específicoDocumentos relacionados
- Catálogo de statements: os campos e resultados dos 17 tipos de statement que usam expressões de valor.
- Semântica de execução, restrições e segurança: ordem de execução, erros, bloqueio otimista e restrições estáticas.
- Cookbook: exemplos completos que combinam expressões de valor.
- Visão geral do Script: a estrutura de nível superior e os modos de execução.
