ObjectOS
リファレンス

CEL 式

数式、述語、スケジュール、テンプレート文字列に使用される式言語 — 5 つのタグ付きテンプレートを通じて提供されます。

CEL 式

ObjectOS は、小さく安全でサンドボックス化された式が必要なあらゆる場所で CEL(Common Expression Language)を使用します。対象は、数式フィールド、検証ルール、表示述語、共有条件、フロー ガード、スケジュール、テンプレート文字列です。

オーサリングは @objectstack/spec からインポートする 5 つのタグ付きテンプレート を通じて行います。これらはいずれも、ランタイムが解析する小さな JSON オブジェクトを生成します。

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

スキーマソース: packages/spec/src/shared/expression.zod.ts

5 つのタグ付きテンプレート

テンプレートDialect用途
F`...`cel数式フィールド — レコードと共に保存される派生値F`record.amount * 0.1`
P`...`cel述語 — 検証 / 共有 / 表示 / 条件のためのブール値P`record.status == "open"`
cel`...`cel汎用 CEL — F でも P でも合わない場合(例: パラメータ値)cel`now() + duration("P30D")`
tmpl`...`template{{var}} 補間を伴う 文字列テンプレートtmpl`Order from {{record.customer.name}}`
cron`...`cronスケジュール — 標準の 5 フィールド cron 構文cron`0 9 * * 1-5`

FPcel は評価時には機能的な違いはありません — いずれも CEL を実行します。この区別は、スキーマ(および AI エージェント)が式の役割を把握し、エディタが型チェックを行えるようにするために存在します(数式は値を返さなければならず、述語はブール値を返さなければなりません)。

インポート

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

それぞれの使用場所

spec 上のフィールドタグ使用場所の例
Field.expression(formula 型)F*.object.ts の数式フィールド
Field.conditionalRequiredPオブジェクトフィールド
Validation.predicatePオブジェクト検証
SharingRule.conditionP共有ルール
View.conditionalFormatting[].conditionPビュー
Flow.step.when / Flow.transition.whenPフロー
Action.guardPアクション
通知の件名 / メッセージ本文tmpl通知
Schedule.croncronスケジュール実行されるフロー / レポート
任意の値パラメータcelフローステップの入力

変数スコープ

CEL 式は、次のトップレベル変数を持つコンテキスト内で評価されます。

変数利用可能なタイミング内容
recordほぼ常時評価中の現在のレコード
previous更新フック / 変更検出時レコードの変更前の状態(または null
inputアクション、フローステップユーザーが指定した入力ペイロード
os.user常時{ id, roles: string[], permissions: string[] }
os.org常時組織 / テナントのコンテキスト
os.env常時式に公開される環境変数

レガシーの OLD / NEW 変数は M9.5 で削除されました。previousrecord を使用してください。

標準ライブラリ

packages/formula/src/stdlib.ts に登録されています。 最もよく使われる組み込み関数:

時刻

関数戻り値備考
now()Timestamp評価コンテキストに固定される — 1 つのクエリ内では安定
today()TimestampUTC の日の開始時刻
daysFromNow(int)Timestamp未来の日付
daysAgo(int)Timestamp過去の日付

CEL にはネイティブの timestamp(...)duration(...)date.getDayOfWeek() なども含まれます — CEL spec を参照してください。

ユーティリティ

関数目的
isBlank(x)nullundefined""、または空リストの場合に true
coalesce(a, b)最初の非 null 値
trim(s)空白を除去
joinNonEmpty(list, sep)空でないエントリを連結

ネイティブの CEL 文字列ヘルパー(.contains(...).startsWith(...).matches(...).size())は常に利用可能です。

数式フィールド — 明細項目の合計:

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

検証 — 完了日は今日より後でなければならない:

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

表示 — マネージャーにのみフィールドを表示する:

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

フローガード — 金額が小さい場合はステップをスキップする:

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

スケジュール — 平日の午前 9 時:

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

テンプレート — 通知の件名:

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

エラー

式はロード時にコンパイルされます。失敗はソースの場所とともに VALIDATION_ERROR として表示されます。

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

無効な式は暗黙的に失敗しません。不正な式や未知のフィールドを参照する式は、 上記の場所特定済みメッセージ(誤記したフィールドに対する did-you-mean ヒントを含む)とともに os compile を失敗させます。ランタイムでは、不正な式は暗黙的に nullfalse に 評価されるのではなく、帰属情報付きのエラーをスローします。そのため、数式の値や ガードの判定を静かに破壊する代わりに、ログと監査証跡で失敗を確認できます。

関連項目

On this page