Ekspresi nilai (Value Expressions)

Terakhir diperbarui: 20 Juli 2026

Setiap tempat di Script yang memerlukan nilai (URL, body permintaan, nilai field, kondisi, nilai filter, id target, dan sebagainya) mengambil salah satu dari tiga bentuk di bawah ini. Dokumen ini menjelaskan ketiga bentuk tersebut, dari mana nilai berasal (root konteks), serta aturan map locale yang khas untuk data WEEGLOO. Semua field pada katalog Statement mengikuti aturan ini.

Tiga bentuk

BentukAturanContoh
Referensi (reference)Me-resolve { /json-pointer } di dalam string terhadap konteks."{ /payload/fields/title }"
Literal (literal)Nilai tanpa { /ptr } (string, angka, boolean, objek, atau array). Digunakan apa adanya."draft", 42, true, { "a": 1 }
Operasi dan kondisi (JsonLogic)Objek yang memiliki satu operator sebagai key. Operannya sendiri kembali merupakan ekspresi nilai (referensi, literal, tersarang).{ "+": [ "{ /vars/n }", 1 ] }

Ketiga bentuk ini bersarang. Referensi ditempatkan pada operan JsonLogic, lalu hasil referensi tersebut dimasukkan kembali ke operasi lain.

Referensi: { /json-pointer }

Masukkan JSON Pointer RFC 6901 (harus diawali dengan /) di dalam kurung kurawal. Spasi di sekitar kurung kurawal diperbolehkan ({ /a/b } sama dengan {/a/b}).

Pointer tunggal vs. template campuran: aturan tipe

  • Ketika seluruh string adalah pointer tunggal, nilai mempertahankan tipe aslinya (angka tetap angka, objek tetap objek, array tetap array).
  • Ketika tercampur dengan teks literal, hasilnya adalah penggabungan string (concatenation).
"{ /payload/fields/count }"                 // jika nilai berupa angka, tetap angka (mis. 42)
"{ /payload/fields/tags }"                  // jika array, tetap array
"page-{ /payload/fields/n }-of-10"          // penggabungan string → "page-42-of-10"
"Bearer { /payload/fields/token }"          // penggabungan string → "Bearer abc123"

Nilai yang tidak ada dan escape

  • Ketika path tidak ada atau nilainya kosong, pointer tunggal menjadi null dan template campuran menjadi string kosong.
  • Untuk menggunakan { sebagai literal, escape sebagai \{ (posisi tersebut tidak diinterpretasikan sebagai pointer).

Root konteks: dari mana nilai berasal

Segmen tingkat teratas dari { /pointer } adalah salah satu dari lima berikut.

RootIsi
/payloadPayload JSON (input) yang diteruskan saat pemanggilan. Contoh: { /payload/fields/email }
/headersHeader HTTP permintaan yang diteruskan saat pemanggilan. Key dalam huruf kecil dan satu nilai per nama. Contoh: { /headers/authorization }
/<name>Hasil dari statement sebelumnya yang membawa name tersebut. Contoh: { /order/sys/id }
/vars/<name>Variabel mutable dengan scope script yang dideklarasikan dengan SetVar. Contoh: { /vars/total }
/errorHanya digunakan di dalam blok catch dari Try. Error yang tertangkap, { message, statement }. Contoh: { /error/message }

Bentuk hasil statement

Bentuk hasil dari statement yang membawa name berbeda-beda menurut tipenya.

StatementBentuk hasilContoh referensi
Http{ status, body }{ /resp/status }, { /resp/body/choices/0/message/content }
ResourceCreate, ResourceRead (tunggal), ResourceFind (tunggal)Resource itu sendiri{ /post/sys/id }, { /post/fields/title/en-US }
ResourcePageRead{ items, next }{ /page/items/0/sys/id }, { /page/next }
  • ResourceFind mengikat null jika tidak ada kecocokan. Bercabang berdasarkan keberadaan dengan { "==": [ "{ /found }", null ] }.
  • ResourceRead (tunggal) adalah error jika targetnya tidak ada (dapat ditangani dengan Try). Detailnya dibahas di Membaca resource pada katalog Statement.

Operasi dan kondisi: JsonLogic

Ketika membutuhkan kalkulasi atau kondisi, gunakan objek operator dari spesifikasi jsonlogic.com.

  • Akses data diseragamkan dengan referensi { /ptr }, bukan var vanilla (dot-path). Mesin me-resolve pointer operan terlebih dahulu, lalu menerapkan operator.
  • Ketika key dari objek key tunggal merupakan operator terdaftar, ia diperlakukan sebagai operasi; jika tidak, sebagai objek biasa.

Tabel operator

KategoriOperatorArti dan contoh
Kondisiif (alias ?:){ "if": [kondisi, nilai-benar, kondisi2, nilai-benar2, …, default] }. Nilai dari kondisi benar pertama, atau default terakhir jika tidak ada.
Logikaand, orEvaluasi short-circuit. and mengembalikan operan falsy pertama (atau yang terakhir), or mengembalikan operan truthy pertama (atau yang terakhir), sebagai nilai.
Logika! (not), !! (to-bool){ "!": x } menegasikan truthy, { "!!": x } menghasilkan status truthy. !! sering digunakan untuk pemeriksaan keberadaan.
Kesetaraan==, !=Perbandingan longgar (membandingkan setelah konversi paksa ke angka; "1"==1 bernilai benar).
Kesetaraan===, !==Perbandingan ketat (termasuk tipe).
Perbandingan<, <=, >, >=Dapat dirantai: { "<": [1,2,3] } berarti 1<2 AND 2<3. Jika tidak dapat dijadikan angka (NaN), hasilnya false.
Aritmetika+Jumlah dari semua operan.
Aritmetika-Dengan satu operan, negasi; dengan dua, pengurangan.
Aritmetika*, /, %Perkalian, pembagian, sisa.
Agregasimin, maxNilai minimum dan maksimum dari operan.
StringcatMenggabungkan semua operan sebagai string.
Keanggotaanin{ "in": [needle, haystack] }. Jika haystack berupa string, substring; jika koleksi, keanggotaan elemen.
ArraymergeMeratakan beberapa array atau nilai menjadi satu array (digunakan untuk akumulasi).

Operator iterasi array (map, filter, reduce, all, some, none) tidak didukung. Script mengiterasi array dengan Loop (lihat Loop pada katalog Statement).

Konversi numerik dan contoh

Aturan konversi numerik adalah sebagai berikut. Angka dibiarkan apa adanya, true menjadi 1, false menjadi 0, string di-parse (jika tidak dapat di-parse, kalkulasi menghasilkan nilai kegagalan), dan null menjadi 0.

{ "-":  [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] }   // saldo - biaya
{ "<":  [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] }   // saldo < biaya → boolean
{ "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }
{ "cat": [ "id-", "{ /payload/sys/id }" ] }                                    // "id-<uuid>"
{ "!!": "{ /found/sys/id }" }                                                  // true jika ada
{ "merge": [ "{ /vars/ids }", [ "{ /row/sys/id }" ] ] }                        // mengakumulasi satu elemen ke dalam array
{ "if": [ "{ /page/next }", "{ /page/next }", "END" ] }                        // next jika ada, jika tidak "END"

Penentuan benar dan salah (Truthiness)

if, and, or, !, !! beserta If.condition dan Loop.while menentukan benar dan salah dengan aturan berikut.

  • falsy: null, false, angka 0, string kosong "", koleksi kosong (array kosong).
  • truthy: selain itu semuanya (angka bukan 0, string dan array yang tidak kosong, dan semua objek).

Key juga bisa menjadi referensi

Key dari map seperti fields juga mendukung referensi { /ptr }. Key di-resolve saat runtime.

"fields": { "{ /payload/fields/fieldName }": { "en-US": "{ /payload/fields/fieldValue }" } }

Jika dua key di-resolve ke nilai yang sama, terjadi konflik dan menjadi error mesin.

Map locale (LocaleValueMap): aturan khusus Content dan Media

Di WEEGLOO, setiap field dari Content atau Media bukanlah sebuah nilai melainkan map per-locale (misalnya, balance bernilai { "en-US": 1, "ko-KR": 10 }). Karena itu, locale harus ditangani bersama saat membaca dan menulis. Pada Media juga, title dan description (skalar) serta file (instruksi ingest) merupakan map locale. JSON yang bukan Content maupun Media, seperti /payload atau respons HTTP, tidak terpengaruh aturan ini (strukturnya tetap sebagaimana ditentukan skema, dan skalar tetap skalar).

Membaca

  • Untuk memperoleh skalar, tentukan hingga locale: { /<name>/fields/<field>/<locale> } (misalnya, { /post/fields/title/en-US }).
  • Tanpa locale, { /<name>/fields/<field> } menghasilkan keseluruhan objek map locale.
  • Field localized:false hanya berada di bucket locale default, jadi dibaca dengan kode locale default tersebut.

Menulis (fields dari ResourceCreate, ResourceUpdate, ResourcePatch)

Nilainya adalah map locale { "<locale>": <ekspresi nilai skalar> }. Simetris dengan pembacaan.

"fields": {
  "title":  { "en-US": "Hello", "ko-KR": "안녕" },   // daftar bucket untuk beberapa locale
  "status": { "en-US": "paid" }
}
  • ResourceCreate harus menyertakan bucket locale default Space pada setiap field yang diisi (aturan default-locale).
  • ResourceUpdate adalah penggantian penuh. Field dan locale yang tidak ada di fields akan dihapus (termasuk file).
  • ResourcePatch hanya memperbarui field dan bucket yang ditentukan (field dan locale lainnya dipertahankan).
  • Menghapus dengan null literal: ketika nilainya adalah null literal, bucket (field, locale) tersebut dihapus (cara standar untuk mengosongkan locale tertentu dalam Patch). "" (string kosong) bukanlah penghapusan melainkan menetapkan nilai kosong. Ketika ekspresi nilai ({ /ptr }) dievaluasi menjadi null saat runtime, itu bukan penghapusan melainkan sebuah error (payload yang hilang tidak ditelan secara diam-diam). Hanya null literal yang menghapus.
  • Media file: nilainya bukan skalar melainkan instruksi ingest { "source": …, "encoding": "url"|"base64" }. Penulisan yang menyertakan file hanya tersedia untuk Async (lihat ResourceCreate pada katalog Statement).
  • Field localized:false hanya dimasukkan ke bucket locale default.
  • Kode locale (key map) juga bisa berupa referensi { /ptr } (lihat Key juga bisa menjadi referensi di atas). Digunakan saat membuat locale dinamis.

Field kemudahan locale

Ketika locale diberikan pada ResourceCreate, ResourceUpdate, atau ResourcePatch, mesin secara otomatis membungkus setiap nilai di fields ke dalam bucket { <locale>: nilai }. Artinya, cukup memberikan skalar saja.

// kedua contoh di bawah ini setara
{ "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" } } }

Jika locale diberikan sementara nilainya sudah menyarangkan map locale ({ "en-US": … }), hasilnya menjadi tersarang ganda sebagai { <locale>: { "en-US": … } } (kesalahan penulis). Satukan menjadi satu gaya: dengan locale, gunakan hanya skalar; tanpanya, gunakan hanya map locale eksplisit.

Locale dalam where dan order

  • Di where dan order, untuk fields.X mesin secara otomatis menerapkan locale default Space (sama seperti kueri CMA).
  • Untuk menargetkan locale tertentu, tentukan secara eksplisit sebagai fields.X.<locale>.
"where": { "fields.slug": { "eq": "{ /payload/fields/slug }" } }   // slug locale default
"where": { "fields.title.ko-KR": { "prefix": "안" } }              // locale tertentu