recipe_deno.ts

Recipe for installing a pinned Deno runtime as a script resource.

deno_install builds the check/run payload, pinned and idempotent, for either destination:

  • system (privileged: true) — sudo install into a root-owned dir like /usr/local/bin/deno, readable + executable under a hardened unit's ProtectSystem=strict and on the default systemd PATH (a subprocess a service starts per call).
  • user-home (user: '<svc>') — install as the service user into a path under their home (/home/<svc>/.deno/bin/deno), so a bootstrap apply running as root still lands Deno owned by the service user, not /root (a long-running Deno backend).

The binary is fetched from the GitHub release zip of the pinned version (no curl | sh). The zip is not checked against a digest: its bytes are trusted as the release URL serves them over TLS. The check is the exact version pin, so a re-apply reinstalls only on a version bump. Warming a module cache (deno cache) is intentionally left to the caller — it's per-consumer (entrypoint + apply-vs-deploy timing).

Recipes are imported at config eval time inside zap's sandboxed config eval (fgro eval), which has no network, no writes, and no environment, and where the clock and randomness throw, so this is a pure function: it only assembles strings from its arguments. Deterministic output keeps it a reliable content-addressed plan artifact.

The caller spreads the result into a script resource, e.g. zap.script({id: 'deno-install', name: '...', ...deno_install({version: '2.8.2', bin_path: '/usr/local/bin/deno', privileged: true}), depends_on: ['curl', 'unzip']}). The host needs curl + unzip (declare them as pkg deps).

view source

Declarations
#

3 declarations

deno_install
#

recipe_deno.ts view source

(options: DenoInstallOptions): DenoScript import {deno_install} from '@fuzdev/zap/recipe_deno.js';

Build the check/run for a pinned-Deno install script resource.

check passes once the pinned version is present at bin_path (so a re-apply is a no-op until the version bumps); run downloads the pinned release zip, extracts it, and installs the binary to bin_path per the destination mode (user / privileged / same-user).

options

returns

DenoScript

the script check/run pair.

throws

  • Error - if `bin_path` isn't absolute, `user` and `privileged` are both given, or `user` is empty, starts with `#`, or is a reference

DenoInstallOptions
#

recipe_deno.ts view source

DenoInstallOptions import type {DenoInstallOptions} from '@fuzdev/zap/recipe_deno.js';

Options for deno_install.

version

Pinned Deno version, e.g. '2.8.2' (no leading v).

type string

bin_path

Absolute path the deno executable is installed to — e.g. '/usr/local/bin/deno' (system) or '/home/svc/.deno/bin/deno' (user-home). Parent dirs are created (install -D). Passed single-quoted, so it is taken literally: no ~ or $HOME expansion. Refused at eval unless it begins /.

type string

user?

Install as this user via sudo -u <user>, so bin_path (under their home) lands owned by them even when the apply runs as root. The check and the closing --version run the binary as this user too, never as the connecting user: the account owns the file, and could replace it. A user name written out: not empty, not #<uid>, and not a reference. Omit for a same-user or privileged system install. Mutually exclusive with privileged.

type string

privileged?

sudo the install into a root-owned system dir (e.g. /usr/local/bin). Defaults to false. Mutually exclusive with user.

type boolean

target?

Release-asset target triple. Defaults to 'x86_64-unknown-linux-gnu' (glibc). On an Alpine/musl host pass 'x86_64-unknown-linux-musl' — a glibc Deno binary won't run under musl without gcompat (this recipe is neutral, so the distro is the caller's to declare).

type string

DenoScript
#

recipe_deno.ts view source

DenoScript import type {DenoScript} from '@fuzdev/zap/recipe_deno.js';

The check/run pair deno_install returns (caller supplies id/name/depends_on).

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

Depends on
#