Skip to main content

Module composite

Module composite 

Source
Expand description

Composite secrets (Phase 24.1) — one value with secrets inside it.

The motivating case is a calendar-sharing URL, https://outlook.office365.com/owa/calendar/{mailbox_id}@inf.elte.hu/{calendar_key}/calendar.ics, where two path segments are credentials and the rest is structure. The root is the template; each placeholder is a part. Parts are ordinary extra_vars — see the design note in src/ts/composite.rs’s TypeScript twin (src/ts/composite.ts) for why a second array was rejected. This module renders the template against a set of parts and does nothing else: it does not know about VaultEntry, redaction, or ${…} references.

This is a twin pair with src/ts/composite.ts, pinned by tests/fixtures/parity/composite.json — the form needs a live preview, so rendering exists in both languages, and two implementations of one template language drift silently if nothing asserts they agree.

§Encoding — decided 2026-09-14

A URL is several zones with different reserved characters, and a value inserted raw can change what the URL means (postgres://app:p@ss@db/prod parses with host ss@db). So: parts are stored raw (the vault holds the credential the issuer gave), and the renderer classifies each placeholder by the zone it sits in — from a parse of the template text, not of a URL built from real values — and percent-encodes accordingly. custom never encodes: the preview shows the encoded result, so what is copied is what was seen.

The encoder implements exactly RFC 3986’s unreserved set (ALPHA / DIGIT / "-" / "." / "_" / "~") rather than delegating to a JS/Rust built-in — encodeURIComponent and this module must byte-for-byte agree, and the built-ins on the two sides do not use the same unreserved set (JS additionally leaves ! ~ * ' ( ) unescaped).

Structs§

Part
One named {part} and the raw value it holds.
Rendered
The result of a successful render: the text, and which parts were used.

Enums§

Kind
What a composite template is, which decides its encoding and whether an Open action is offered. Open past the four presets, the same open-vocabulary reasoning as primary_role.
RenderError
What went wrong rendering a template. Display gives the user-facing text.

Functions§

placeholders
The placeholder names a template references, without needing any parts — used by the form to build “Make part” suggestions and by the health scan to find orphaned parts, without rendering (and therefore without needing every part filled in first).
render
Renders template against parts, refusing on any unfilled placeholder, unbalanced brace, or (for a URL-shaped kind) a control character in a part.