You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(formula,email): render datetime in reference timezone (ADR-0053 Phase 2, #1981)
datetime template holes render in a reference timezone's wall-clock at the
presentation boundary; storage stays UTC. Calendar-day `date` rendering is
intentionally unaffected (tz-naive).
- formula: the `datetime` formatter takes tz from EvalContext.timezone (#1980)
→ Intl.DateTimeFormat; `datetime:iso` stays UTC. New exported
`formatValue(name, value, arg, { locale, timeZone })` so the whitelisted
formatters are reusable outside the CEL template engine.
- plugin-email: the renderer bypassed the formatter pipeline (raw String()),
so a datetime went out as raw ISO. Email holes now accept the shared formula
formatters via formatValue (single source of truth), keeping HTML-escaping
and `{{{ }}}` raw-output. SendTemplateInput.timezone (mirroring locale) flows
into rendering so a datetime shows the recipient's wall-clock.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(email): linear placeholder matcher — close CodeQL polynomial-ReDoS
The formatter-aware regex used two overlapping `\s*` groups (inside the
optional `| formatter` group and trailing), which CodeQL flagged as
js/polynomial-redos (slow on `{{{{.` + many tabs). Switch to a brace-free
inner capture (`[^{}]*` — single star, no nested quantifier) and parse the
hole body with plain string ops, the same linear strategy the formula
template engine uses. Adds a regression test on the flagged input shape.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(formula,email): render `datetime` in a reference timezone (ADR-0053 Phase 2)
8
+
9
+
`datetime` template holes now render in a reference timezone's wall-clock when one is supplied, at the presentation boundary — storage stays UTC.
10
+
11
+
-**Formula template engine** — the `datetime` formatter takes the reference timezone from `EvalContext.timezone` (threaded in #1980) and passes it to `Intl.DateTimeFormat`. `{{ ts | datetime }}` renders in that zone; `{{ ts | datetime:iso }}` stays UTC (machine-readable). Calendar-day `date` rendering is intentionally **unchanged** (tz-naive — a `Field.date` has no zone). New exported `formatValue(name, value, arg, { locale, timeZone })` makes the whitelisted formatters reusable outside the full CEL template engine.
12
+
-**Email pipeline** — `plugin-email`'s renderer previously bypassed the formatter pipeline (`String()` only), so a datetime went out as raw ISO. Email holes now accept the shared formula formatters — `{{ order.total | currency }}`, `{{ ts | datetime }}` — reusing `formatValue` (single source of truth), while keeping the engine's HTML-escaping and `{{{ }}}` raw-output semantics. `SendTemplateInput.timezone` (mirroring the existing `locale`) flows into rendering so an email's datetime shows the recipient's wall-clock.
0 commit comments