schema.ts

The zap.ts authoring schema — TypeScript types that mirror the Rust serde JSON boundary in crates/zap_types/src/schema/ (the authoritative source).

These give a config author full type-checking against the same contract the Rust engine parses: every resource payload, the nested content/source unions, the closed-set enums, and the deploy() block. The Rust structs carry #[serde(deny_unknown_fields)], so these interfaces have no index signatures — a misspelled field is a type error here exactly as it is a parse error in the engine.

Scalar newtypes on the Rust side (Mode / ContentHash / AccountName / ResourceId / EnvVarName) serialize as plain string; they are typed as string here with their format invariant noted, since TypeScript can't express the runtime validation the engine applies at parse.

A field is optional (?) here exactly when the Rust field is Option<T> or carries #[serde(default)]. The dual-gated kitchen-sink fixture (src/test/fixtures/kitchen_sink_config.ts — type-checked against these types, then eval'd and parsed by the Rust config_conformance test) guards this module and the Rust schema from drifting.

view source

Declarations
#

46 declarations

AptRepoResource
#

schema.ts view source

AptRepoResource import type {AptRepoResource} from '@fuzdev/zap/schema.js';

apt_repo resource payload — a GPG key + sources list.

key_url

The URL zap fetches the GPG signing key from, on the operator's machine: https://, or http:// to a loopback host; any other scheme is rejected by the structural gate. It may carry a reference. The key is pinned by the blake3 of its bytes, and only bytes that hash to the pin are installed.

type string

key_blake3?

The key's vendored pin: the blake3 of its bytes, 64 lowercase hex. Absent, the pin is tracked in zap.lock (zap lock / zap update mint and advance it).

type string

key_path?

Where the GPG key is stored; default /usr/share/keyrings/{id}.asc. It takes no reference (rejected when the config is read): it is written into the source line, inside double quotes.

type string

source

The deb source line (signed-by is auto-injected from key_path). It is expanded by the target shell inside double quotes, so $VERSION_CODENAME resolves there; it takes no reference (rejected when the config is read).

type string

list_file?

The .list file path; default /etc/apt/sources.list.d/{id}.list. It takes no reference (rejected when the config is read): detection reads it as declared.

type string

BuildResource
#

schema.ts view source

BuildResource import type {BuildResource} from '@fuzdev/zap/schema.js';

build resource payload — fetch a verified source, build it, install to output.

source

Where the source comes from + how its integrity is verified.

type BuildSource

run

The build command (e.g. zig build -p $HOME/.local -Doptimize=ReleaseFast).

type string

output

Path that exists iff the build is installed — the detection probe.

type string

cwd?

Working directory for run: absolute, or relative to the extracted source dir, which is the default. Takes no reference: zap rejects one here.

type string

env?

Build environment. Keys are POSIX names ([A-Za-z_][A-Za-z0-9_]*), validated at config-eval; a name beginning with __zap_ is rejected by the structural gate (zap's own wrapper variables). A value's references resolve before it is quoted, so it can hold any text but a NUL and the reference delimiters U+FDD0 and U+FDD1.

type Record<string, string>

BuildSource
#

schema.ts view source

BuildSource

type { type: "remote"; } & RemoteSource

import type {BuildSource} from '@fuzdev/zap/schema.js';

The source a build fetches + verifies. Internally tagged on type (only the remote-tarball flavor exists). Mirrors the Rust BuildSource.

type

A fetched source archive — fetched, verified, and content-addressed.

type "remote"

url

Fetch location: an https:// URL with no user:password@ (http:// only for a loopback host), or the structural gate rejects it. It may carry a reference, resolved when zap fetches (the lock addresses a secret reference by its token, any other by its value).

type string

extract?

How the fetched source is unpacked before run.

type ExtractMode

auth?

Optional fetch credential for a private byte-host (never hashed).

type RemoteAuth

verify?

Optional upstream-signature verification, run when a fetch fills the content cache, before the bytes are pinned or built. A cache hit is not re-verified: it is re-hashed against the pin.

type SourceVerify

blake3?

Vendored source pin. A declared pin self-pins; absent, the lock pins it. Mirrors ContentHash — exactly 64 lowercase hex on the wire.

type string

CommandAssertion
#

schema.ts view source

CommandAssertion import type {CommandAssertion} from '@fuzdev/zap/schema.js';

The payload of a command VerifyAssertion. Mirrors CommandAssertion.

run

The command to run.

type string

expect?

A substring that must appear in stdout.

type string

DatabaseAuth
#

schema.ts view source

DatabaseAuth import type {DatabaseAuth} from '@fuzdev/zap/schema.js';

PostgreSQL auth config for a database resource's pg_hba.conf rules: one host line per entry of hosts. A database without one declares no rule, so the role is reached over the Unix socket by the OS account of the same name (the stock peer rule). Mirrors the Rust DatabaseAuth.

method?

Auth method (default scram-sha-256).

type PgAuthMethod

hosts

Allowed client addresses, each an IP address with its prefix length (127.0.0.1/32); a keyword (all, samehost, samenet) or a host name is refused. At least one: an auth that names none is refused, since it would write no rule.

type string[]

DatabaseEngine
#

schema.ts view source

"postgresql" import type {DatabaseEngine} from '@fuzdev/zap/schema.js';

Database engine for a database resource (only postgresql).

DatabaseResource
#

schema.ts view source

DatabaseResource import type {DatabaseResource} from '@fuzdev/zap/schema.js';

database resource payload (PostgreSQL only).

engine

Database engine (only postgresql).

type "postgresql"

database_name

Database name to create. Taken literally (never shell-expanded); a reference resolves on the operator's machine.

type string

username

Role/user to create and own the database. Taken literally (never shell-expanded); zap.env('USER') declares "the operator's OS user".

type string

auth?

pg_hba.conf auth config. Absent, zap writes no rule, and the role is reached over the Unix socket by the OS account of the same name. A rule zap adds is put in force with pg_reload_conf(); the server isn't restarted, and the target needs no service_manager for it.

type DatabaseAuth

DeployHealth
#

schema.ts view source

DeployHealth import type {DeployHealth} from '@fuzdev/zap/schema.js';

Post-restart HTTP health check for a deploy. Mirrors the Rust DeployHealth.

domain lives inside this block, so declaring a health gate with nothing to poll is unrepresentable rather than a mistake caught at run time. Omit the whole block to deploy without a health gate.

domain

Host polled over HTTPS (e.g. app.example.com, or a zap.env('DEPLOY_DOMAIN') reference resolved at execution).

type string

path

Request path polled over HTTPS against domain, beginning with / (e.g. /health). Takes no reference: zap rejects one here.

type string

attempts?

How many times to poll before failing the deploy, at least 1 (default 15).

type number

interval_ms?

Delay between poll attempts, in milliseconds (default 2000).

type number

DeploySpec
#

schema.ts view source

DeploySpec import type {DeploySpec} from '@fuzdev/zap/schema.js';

The deploy() release-management block — what zap deploy packages and ships. Mirrors the Rust DeploySpec.

build?

Build command run locally before packaging (e.g. gro build).

type string

artifacts

Files/directories (relative to the operator cwd) to package into the tarball. An entry can't begin with - (write ./-name) or with @; either is rejected by the structural gate.

type string[]

path

Remote application root — holds releases/, shared/, and the current symlink. An absolute path, written out: no reference (rejected when the config is read) and no ~ (rejected by the structural gate).

type string

releases?

Number of releases to retain on the target, the live one included (default 5). Below 2 is rejected by the structural gate: the release just deployed and the one it replaced, which a failed deploy rolls back to, are always kept.

type number

service?

Service to restart after the symlink swap. Requires target.service_manager. Takes no reference (rejected when the config is read).

type string

shared?

Files under the remote shared/ directory to symlink into each release root. Each is a relative name of a file: no .. component, no control character, not ending in / or in a . component (anything else is rejected by the structural gate).

type string[]

prepare?

Post-extract commands run on the target, in the new release directory, before swap, each in a shell of its own (sh -ec): an exit in one ends that command, not the deploy, and one that fails stops the deploy before the swap. The release is still under its hidden staging name then, so a command shouldn't record its absolute path.

type string[]

health?

Optional post-restart HTTP health check.

type DeployHealth

DirectoryResource
#

schema.ts view source

DirectoryResource import type {DirectoryResource} from '@fuzdev/zap/schema.js';

directory resource payload — a directory with managed permissions.

path

Directory path, absolute or under ~ (may carry a reference).

type string

mode?

Desired octal mode (e.g. "755"). Mirrors Mode — octal, 7777 at most.

type string

owner?

Desired owner. Mirrors AccountName — a portable Unix name ([a-z_][a-z0-9_-]*, optional trailing $; anything else is rejected at parse).

type string

group?

Desired group. Mirrors AccountName — a portable Unix name ([a-z_][a-z0-9_-]*, optional trailing $; anything else is rejected at parse).

type string

ExtractMode
#

schema.ts view source

ExtractMode

type { type: "none"; } | { type: "tar.xz"; strip_components?: number | undefined; } | { type: "tar.gz"; strip_components?: number | undefined; }

import type {ExtractMode} from '@fuzdev/zap/schema.js';

How a fetched remote file / build source is materialized after fetch. Internally tagged on type. Mirrors the Rust ExtractMode.

FileContent
#

schema.ts view source

FileContent

type { type: "inline"; content: string; } | TemplateContent | { type: "source"; path: string; } | ({ type: "remote"; } & RemoteContent)

import type {FileContent} from '@fuzdev/zap/schema.js';

The content field of a file resource. Internally tagged on type. Mirrors the Rust FileContent.

FileResource
#

schema.ts view source

FileResource import type {FileResource} from '@fuzdev/zap/schema.js';

file resource payload — a file with managed content.

path

Target path (may carry a reference / ~).

type string

content

Content source.

type FileContent

mode?

Desired octal mode (e.g. "600"). Mirrors Mode — octal, 7777 at most.

type string

owner?

Desired owner. Mirrors AccountName — a portable Unix name ([a-z_][a-z0-9_-]*, optional trailing $; anything else is rejected at parse).

type string

group?

Desired group. Mirrors AccountName — a portable Unix name ([a-z_][a-z0-9_-]*, optional trailing $; anything else is rejected at parse).

type string

triggers?

Ids of service resources notified when this file changes.

type string[]

validate?

Command that must exit 0 after a write (e.g. NGINX_VALIDATE), or the write is rolled back — the previous bytes, owner, group, and mode restored, less any set-id or sticky bit the declared mode lacks (or a new file removed) — and the change fails. Runs against the file in place, so it suits a file some larger config includes. Text content only — rejected on remote.

type string

FileType
#

schema.ts view source

FileType

type "file" | "directory"

import type {FileType} from '@fuzdev/zap/schema.js';

The required type of a path_exists verify assertion's target. Mirrors FileType.

FirewallAllowRule
#

schema.ts view source

FirewallAllowRule

type string | { port: number; proto?: Protocol | undefined; }

import type {FirewallAllowRule} from '@fuzdev/zap/schema.js';

A firewall allow rule: a named ufw application profile (e.g. OpenSSH, ufw only — rejected under the nftables backend), or a port/proto pair (both backends). A named profile takes no reference (rejected when the config is read: detection reads it as declared) and can't begin with - (rejected by the structural gate). Untagged. Mirrors the Rust FirewallAllowRule.

FirewallBackend
#

schema.ts view source

FirewallBackend

type "ufw" | "nftables"

import type {FirewallBackend} from '@fuzdev/zap/schema.js';

Firewall backend for a firewall resource: ufw (Debian/Ubuntu — app profiles + port rules) or nftables (the Alpine-native declarative inet filter backend — port/proto rules only, no application profiles). Mirrors the Rust FirewallBackend.

FirewallPolicy
#

schema.ts view source

FirewallPolicy

type "allow" | "deny" | "reject"

import type {FirewallPolicy} from '@fuzdev/zap/schema.js';

A firewall default-policy verdict / allow disposition, on either backend. Mirrors FirewallPolicy.

FirewallResource
#

schema.ts view source

FirewallResource import type {FirewallResource} from '@fuzdev/zap/schema.js';

firewall resource payload — host firewall configuration (ufw or nftables).

backend

Firewall backend (ufw or nftables).

type FirewallBackend

default_incoming?

Default policy for incoming traffic (default deny).

type FirewallPolicy

default_outgoing?

Default policy for outgoing traffic (default allow).

type FirewallPolicy

allow

Allow rules (named profiles or port/proto pairs).

type FirewallAllowRule[]

InstallerResource
#

schema.ts view source

InstallerResource import type {InstallerResource} from '@fuzdev/zap/schema.js';

installer resource payload — software via a curl-piped script.

url

The install script's https:// URL, piped into shell; any other scheme is rejected by the structural gate.

type string

check

Path checked for existence to confirm installation (may carry ~).

type string

shell?

Command the fetched install script is piped into (default sh), run as written. The script is fetched whole first; a failed fetch, or an empty script, fails the step.

type string

LinkResource
#

schema.ts view source

LinkResource import type {LinkResource} from '@fuzdev/zap/schema.js';

link resource payload — a symbolic link.

path

Symlink path (may carry a reference / ~). A real directory at the path fails the step.

type string

target

The target the symlink should point to (resolved the same way).

type string

MinisignVerify
#

schema.ts view source

MinisignVerify import type {MinisignVerify} from '@fuzdev/zap/schema.js';

The payload of a minisign SourceVerify. Mirrors the Rust MinisignVerify.

public_key

The pinned minisign public key: the 56 base64 characters beginning RW (the key line of a .pub file, without its comment). Mirrors the Rust MinisignKey; any other shape is rejected at config eval.

type string

signature_url?

Explicit signature URL, held to the rule url is; it may carry a reference. Defaults to the source URL with .minisig appended to its path, before any query or fragment.

type string

PackageManager
#

schema.ts view source

PackageManager

type "apt" | "pacman" | "brew" | "apk"

import type {PackageManager} from '@fuzdev/zap/schema.js';

Package managers a target may declare. Mirrors the Rust PackageManager.

PackageResource
#

schema.ts view source

PackageResource import type {PackageResource} from '@fuzdev/zap/schema.js';

package resource payload — a system package via a package manager.

from

Package-manager → package-name mapping (e.g. {apt: "curl"}). A name takes no reference (rejected when the config is read): it is put into the manager's command unquoted, and detection asks the manager about it (under apt by the name alone, for name=version at exactly that version, and for name:arch by that architecture). So a name is one word in the manager's syntax — a letter or digit, then letters, digits, and `+ . _ - = ~ : /

type Partial<Record<PackageManager, string>>

check?

Optional custom check (a path, or a command); defaults to the PM query. A check beginning /, ~, or $HOME is a path and its references resolve; anything else is a command, run as written.

type string

PathExistsAssertion
#

schema.ts view source

PathExistsAssertion import type {PathExistsAssertion} from '@fuzdev/zap/schema.js';

The payload of a path_exists VerifyAssertion. Mirrors PathExistsAssertion.

path

The absolute path to check, as written: no reference; a ~ or relative path is rejected. A link is followed: type, mode and owner are its target's.

type string

file_type?

Required type; absent accepts either.

type FileType

mode?

Required octal mode (e.g. "600"). Mirrors Mode — octal, 7777 at most. 0644 and 644 compare the same.

type string

owner?

Required owner. Mirrors AccountName — a portable Unix user/group name ([a-z_][a-z0-9_-]*, optional trailing $; a numeric uid/gid or any other character is rejected at parse).

type string

not_empty?

Whether the path's size must be above zero (test -s). A directory's size depends on its filesystem, so this doesn't reliably check that a directory has entries.

type boolean

PgAuthMethod
#

schema.ts view source

PgAuthMethod

type "reject" | "scram-sha-256" | "md5" | "password" | "gss" | "ident" | "pam"

import type {PgAuthMethod} from '@fuzdev/zap/schema.js';

A PostgreSQL pg_hba.conf auth method — the set PostgreSQL documents, but for those that can't work on a plain TCP host line with no options, the only kind zap writes: trust (it admits any account on the machine as the role), peer (accepted only on a local line), cert (only on a hostssl line), ldap and radius (they need options zap doesn't write), and sspi and bsd (not built on Linux). Mirrors PgAuthMethod.

PipelineResource
#

schema.ts view source

PipelineResource import type {PipelineResource} from '@fuzdev/zap/schema.js';

pipeline resource payload — imperative multi-step execution.

env?

Environment variables shared across all steps. Rejected by the structural gate — the sequential executor doesn't apply it; inline the vars into each step's run.

type Record<string, string>

steps

The pipeline steps.

type PipelineStep[]

max_concurrency?

Max steps to run concurrently, at least 1. Any value above 1 is rejected by the structural gate: steps run sequentially.

type number

PipelineStep
#

schema.ts view source

PipelineStep import type {PipelineStep} from '@fuzdev/zap/schema.js';

One step in a pipeline resource. Mirrors the Rust PipelineStep.

id

Identifier for this step, unique within the pipeline: a repeated id is rejected by the structural gate.

type string

name?

Human-readable name for the step, printed under its id in a plan.

type string

run

The command this step runs.

type string

cwd?

Working directory for this step. Rejected by the structural gate — the sequential executor doesn't apply it; inline a cd into run.

type string

env?

Environment variables for this step. Rejected by the structural gate — the sequential executor doesn't apply it; inline the vars into run.

type Record<string, string>

depends_on?

Step ids this depends on (within the pipeline). Rejected by the structural gate: steps run sequentially in declaration order.

type string[]

Protocol
#

schema.ts view source

Protocol

type "tcp" | "udp" | "any"

import type {Protocol} from '@fuzdev/zap/schema.js';

The transport protocol of a firewall port rule. Mirrors Protocol.

RemoteAuth
#

schema.ts view source

RemoteAuth import type {RemoteAuth} from '@fuzdev/zap/schema.js';

A credential for fetching a remote file's bytes from a private host. Tagged on scheme (not type). Mirrors the Rust RemoteAuth.

scheme

Authorization: Bearer <token>.

type "bearer"

token

The bearer token; typically a reference, never a literal.

type string

RemoteContent
#

schema.ts view source

RemoteContent import type {RemoteContent} from '@fuzdev/zap/schema.js';

The payload of a remote FileContent. Mirrors the Rust RemoteContent.

url

Fetch location: an https:// URL with no user:password@ (http:// only for a loopback host), or the structural gate rejects it. It may carry a reference, resolved when zap fetches (the lock addresses a secret reference by its token, any other by its value).

type string

blake3?

Vendored content pin. A declared pin self-pins (skips the lock); absent, the lock pins the resolved hash. Mirrors ContentHash — exactly 64 lowercase hex on the wire.

type string

extract?

How the fetched bytes are materialized on the target.

type ExtractMode

auth?

Optional fetch credential for a private byte-host (never hashed).

type RemoteAuth

RemoteSource
#

schema.ts view source

RemoteSource import type {RemoteSource} from '@fuzdev/zap/schema.js';

The payload of a remote BuildSource. Mirrors the Rust RemoteSource.

url

Fetch location: an https:// URL with no user:password@ (http:// only for a loopback host), or the structural gate rejects it. It may carry a reference, resolved when zap fetches (the lock addresses a secret reference by its token, any other by its value).

type string

extract?

How the fetched source is unpacked before run.

type ExtractMode

auth?

Optional fetch credential for a private byte-host (never hashed).

type RemoteAuth

verify?

Optional upstream-signature verification, run when a fetch fills the content cache, before the bytes are pinned or built. A cache hit is not re-verified: it is re-hashed against the pin.

type SourceVerify

blake3?

Vendored source pin. A declared pin self-pins; absent, the lock pins it. Mirrors ContentHash — exactly 64 lowercase hex on the wire.

type string

ResourceIdentity
#

schema.ts view source

ResourceIdentity import type {ResourceIdentity} from '@fuzdev/zap/schema.js';

The common identity flattened onto every resource arg (id / name? / depends_on?). Mirrors the flat fields of the Rust Resource.

Each builder method takes ResourceIdentity intersected with the kind-specific payload; the builder shim injects the type discriminant, so authors never write type.

id

Stable identity within the config. Mirrors ResourceId (a plain string on the wire). A name: a letter, a digit, or _, then any of those and . + : @ -; anything else is rejected by the structural gate.

type string

name?

A label for whoever reads the config. A plan prints it under the change's header; everything else (apply's progress, events, triggers) names a resource by its id. It is carried in a change, so changing it changes the plan_hash of a plan that changes this resource, but never the lock entry's config_hash.

type string

depends_on?

Resource ids this depends on (the resource-graph edges).

type string[]

ScriptResource
#

schema.ts view source

ScriptResource import type {ScriptResource} from '@fuzdev/zap/schema.js';

script resource payload — an idempotent command (check / run).

check

Check command — exit 0 means the script is already applied (skip).

type string

run

The command the planner emits when the check fails.

type string

cwd?

Working directory for the check and for run. An absolute path, taken verbatim: no reference (rejected when the config is read) and no ~ (rejected by the structural gate). A check that can't enter it reads as not applied; a run that can't enter it fails without running.

type string

env?

Extra environment, exported to the check and to run (every command of a compound sees it). Keys are POSIX names ([A-Za-z_][A-Za-z0-9_]*), validated at config-eval; a name beginning with __zap_ is rejected by the structural gate (zap's own wrapper variables). A value's references resolve before it is quoted, so it can hold any text but a NUL and the reference delimiters U+FDD0 and U+FDD1 (a value with a ' goes here, not in the command text).

type Record<string, string>

ServiceManager
#

schema.ts view source

ServiceManager

type "systemd" | "launchd" | "openrc"

import type {ServiceManager} from '@fuzdev/zap/schema.js';

Service managers a target may declare. Mirrors the Rust ServiceManager.

ServiceResource
#

schema.ts view source

ServiceResource import type {ServiceResource} from '@fuzdev/zap/schema.js';

service resource payload — service lifecycle management.

service

Service name (interpreted by the target's service manager). Takes no reference (rejected when the config is read): it is put into the manager's command unquoted, and detection reads it as declared. So a name is one word — a letter or digit, then letters, digits, and _ . @ : - — and anything else is rejected when the config is read.

type string

enabled?

Whether the service should be enabled at boot (default true).

type boolean

running?

Whether the service should be running now; absent = don't manage runtime.

type boolean

restart_on?

Resource ids whose change triggers a restart of this service, if it is running (try-restart on systemd, rc-service --ifstarted on OpenRC). A trigger on a service with running: false is a config error.

type string[]

reload_on?

Resource ids whose change triggers a reload of this service, if it is running: try-reload-or-restart on systemd, rc-service --ifstarted <svc> reload on OpenRC (a service that can't reload fails the step).

type string[]

SourceVerify
#

schema.ts view source

SourceVerify

type { scheme: "minisign"; } & MinisignVerify

import type {SourceVerify} from '@fuzdev/zap/schema.js';

Upstream-signature verification for a build source. Tagged on scheme (not type); the one scheme is minisign. Mirrors the Rust SourceVerify.

scheme

minisign -V against public_key.

type "minisign"

public_key

The pinned minisign public key: the 56 base64 characters beginning RW (the key line of a .pub file, without its comment). Mirrors the Rust MinisignKey; any other shape is rejected at config eval.

type string

signature_url?

Explicit signature URL, held to the rule url is; it may carry a reference. Defaults to the source URL with .minisig appended to its path, before any query or fragment.

type string

SshKeys
#

schema.ts view source

SshKeys

type { copy_from: string; } | { keys: string[]; }

import type {SshKeys} from '@fuzdev/zap/schema.js';

SSH key configuration for a user resource: copy another user's authorized_keys, or supply explicit keys. Untagged — distinguished by which field is present. Exactly one of the two: an object with both copy_from and keys type-checks here and is rejected when the config is read. Mirrors the Rust SshKeys.

SudoMode
#

schema.ts view source

SudoMode

type "nopasswd" | "password"

import type {SudoMode} from '@fuzdev/zap/schema.js';

Sudo access mode for a user resource. Mirrors SudoMode.

SwapResource
#

schema.ts view source

SwapResource import type {SwapResource} from '@fuzdev/zap/schema.js';

swap resource payload — a swap file.

size

Swap size (e.g. "2G").

type string

path?

Swap file path (default /swapfile). Used verbatim — no ~ expansion, and no reference (rejected when the config is read: detection reads it as declared).

type string

TargetInput
#

schema.ts view source

TargetInput

type { local: true; package_manager?: PackageManager | undefined; service_manager?: ServiceManager | undefined; } | { local?: false | undefined; host?: string | undefined; user?: string | undefined; bootstrap_user?: string | undefined; port?: number | undefined; key_path?: string | undefined; home?: string | undefined; package_manager?: PackageManager | undefined; service_manager?: ServiceManager | undefined; }

import type {TargetInput} from '@fuzdev/zap/schema.js';

The zap.target({...}) machine descriptor. Modeled as a union so the contradictory local: true with remote connection fields is unrepresentable — a local target rejects host / user / bootstrap_user / port / key_path / home. Mirrors the Rust Target / TargetWire (local-vs-remote TargetLocation).

TemplateContent
#

schema.ts view source

TemplateContent import type {TemplateContent} from '@fuzdev/zap/schema.js';

template file content: a {{key}} template with per-variable substitution. Mirrors the Rust TemplateContent. The site and env recipes return one whole, with the kinds of the variables their templates place.

type

A {{key}} template with per-variable substitution.

type "template"

template

The template body, used as declared. It takes no reference. A placeholder is a variable's name between {{ and }} and nothing else; one that names no variable is rejected by the structural gate.

type string

vars?

Variable values substituted for {{key}}, in one pass: a value is never read for placeholders. A string value may be or carry a reference, resolved before it is substituted. A value that isn't a string is substituted as its compact JSON text and takes no reference at any depth. A variable no placeholder names is rejected by the structural gate. A reference whose value holds a line break (CR or LF) or a NUL holds the file and refuses its write: it would add a line.

type Record<string, unknown>

kinds?

The kind of value each named variable must render to (TemplateKind). Each key names a variable in vars, or the structural gate rejects it. A declared kind is checked on a value written out when the config is read, and on one carrying a reference once it resolves, which holds the file and refuses its write when it isn't its kind. A variable not named here declares no kind: a reference in its value is still held to 'text' once it resolves, and a value written out is substituted unchecked.

type Record<string, TemplateKind>

TemplateKind
#

schema.ts view source

TemplateKind

type "text" | "hostname" | "port" | "path" | "email" | "env_value"

import type {TemplateKind} from '@fuzdev/zap/schema.js';

The kind of value a template variable renders to, checked on its whole rendered value. Mirrors the Rust TemplateKind.

  • text — any one line: no line break, NUL, or reference delimiter. Every kind keeps this rule. A reference's value is held to it whether or not its variable declares a kind; a value written out is held to it only when its variable declares one.
  • hostname — a DNS host name (RFC 1123): dot-separated labels of ASCII letters, digits, and -, each 1 to 63 bytes, no leading or trailing -, at most 253 bytes, with no trailing dot, no wildcard, and no _.
  • port — a decimal number from 1 to 65535, with no sign or leading zero.
  • path — an absolute path whose names are ASCII letters, digits, ., _, -, +, and @, with no empty, ., or .. name.
  • email — a local part of ASCII letters, digits, ., _, %, +, and - (no leading, trailing, or doubled .), an @, and a hostname.
  • env_value — a value written inside single quotes in an env file: text with no ', which would end the quoting.

None of the hostname, port, path, or email alphabets holds a character a config grammar reads as structure (;, {, }, a quote, a blank), which is what a kind is for: a {{domain}} in an nginx server_name declared hostname can't end the directive.

UserResource
#

schema.ts view source

UserResource import type {UserResource} from '@fuzdev/zap/schema.js';

user resource payload — a Unix user (shell, home mode, SSH keys, sudoers).

username

Unix username to create/manage. Mirrors AccountName — a portable Unix name ([a-z_][a-z0-9_-]*, optional trailing $; anything else is rejected at parse). zap manages the user's home as /home/<username>, so 'root' (home /root) is rejected by the structural gate, and an existing account whose /etc/passwd home is anything else is held at detection when home_mode or ssh_keys is declared. With either declared, a /home/<username> directory root owns is given to the user when zap creates the account, and left as it is for an existing one; one another uid owns, a link, or a non-directory there holds the user.

type string

shell?

Login shell (e.g. /bin/bash); system default when absent. It takes no reference (rejected when the config is read): detection reads it as declared.

type string

home_mode?

Home-directory mode (e.g. "711"). Mirrors Mode — octal, 7777 at most.

type string

ssh_keys?

SSH key configuration, if managed.

type SshKeys

sudo?

Sudo access: a grant, or false to remove. Absent = unmanaged.

type UserSudo

groups?

Supplementary groups the user must belong to (additive — listed groups are added, never removed). Mirrors AccountName[] — portable Unix names (see AccountName). Absent/empty = unmanaged.

type string[]

UserSudo
#

schema.ts view source

UserSudo

type false | SudoMode | { mode: SudoMode; commands: string[]; }

import type {UserSudo} from '@fuzdev/zap/schema.js';

A user resource's sudo field: false to remove sudo, a bare mode string to grant unrestricted, or {mode, commands} to grant command-restricted. Untagged. Mirrors the Rust UserSudo.

VerifyAssertion
#

VerifyResource
#

schema.ts view source

VerifyResource import type {VerifyResource} from '@fuzdev/zap/schema.js';

verify resource payload — assertions checked at detection and, on a wetrun, checked again at its place in dependency order; one still failing there fails the run: changes ordered before it have run, the rest are skipped.

assertions

Assertions to check (all must pass for the resource to be met).

type VerifyAssertion[]

Imported by
#