Expand description
Apply-order computation for content blocks.
§Why this module exists
Braze’s POST /content_blocks/create validates the body at create time
and rejects the request when a {{content_blocks.${other_block}}}
include refers to a block that does not yet exist in the workspace.
Worse, the failure surfaces as HTTP 500 with an opaque body, not
as a 4xx validation error — so a single forward reference halts the
whole apply pass and leaves earlier writes committed.
Default alphabetical apply order is unaware of these cross-block
dependencies and any A → B reference where A < B alphabetically
breaks on a fresh workspace. This module parses references out of
the local Liquid bodies, builds a referrer → target graph over the
actionable diffs, and re-emits them in dependency order (targets
before referrers). Cycles are reported with named blocks before any
HTTP write fires; references that point outside the actionable set
(already-present blocks, or out-of-scope names) are treated as
no-ops — the referrer becomes a leaf for sort purposes.
Pure module: no I/O, no Braze calls.
Structs§
- Cycle
- A dependency cycle. The path is reported in the order encountered
during DFS, with the closing node repeated so callers can render
A → B → C → A.
Functions§
- extract_
block_ references - Names of content blocks referenced by
bodyvia the Liquid include syntax. Order is source-order; duplicates are preserved (callers dedupe as needed). Self-references are not filtered here — the caller has the surrounding context to decide. - reorder_
content_ block_ diffs_ by_ dependency - Reorder content_block diffs so that, for every actionable
(
Added/Modified) diff with a{{content_blocks.${target}}}reference whosetargetis also in the actionable set,targetappears earlier in the returned list than the referrer. - topo_
sort - Topologically sort
nodesbyedges(referrer → targets). Targets that are not innodesare treated as no-op edges — the referrer just becomes a leaf for sort purposes. Output is dependency-order: targets before referrers. Stable across runs: ties broken by input order ofnodes, so the dry-run plan for the same repo state is reproducible. Edge target lists are walked in given order; callers who want deterministic cycle-path messages should pre-sort/dedup.