# mjallen-lib Utility Functions

Utility functions for the NixOS/nix-darwin configuration. Exposed via Snowfall Lib as `lib.mjallen.*`.

## Directory Structure

- `default.nix` — Main entry point; exports `module`, `file`, and `versioning`
- `module/` — Module creation helpers (`mkModule`, `mkContainerService`, `mkSopsEnvFile`, `mkOpt`, etc.)
- `file/` — File and path utilities
- `versioning/` — Multi-source version pinning helpers (used by packages)

---

## Module Utilities (`lib.mjallen.module`)

### `mkModule`

Creates a NixOS service module with a standard set of options. All config is gated behind `cfg.enable`.

```nix
lib.mjallen.mkModule {
  config      # NixOS config attrset (pass-through from module args)
  name        # Service name — used for option path and systemd unit
  description # Text for mkEnableOption (defaults to name)
  options     # Extra options merged into the submodule
  moduleConfig # NixOS config body (applied when cfg.enable = true)
  domain      # Option namespace domain (default: "services")
  serviceName # Systemd service name (default: name)
}
```

**Standard options provided for free:**

| Option | Type | Default | Description |
|---|---|---|---|
| `enable` | bool | `false` | Enable/disable the service |
| `port` | int | `80` | Service listen port |
| `listenAddress` | str | `"0.0.0.0"` | Bind address |
| `openFirewall` | bool | `true` | Open TCP+UDP firewall ports |
| `configDir` | str | `/var/lib/<name>` | Config directory |
| `dataDir` | str | `/var/lib/<name>/data` | Data directory |
| `createUser` | bool | `false` | Create a dedicated system user |
| `configureDb` | bool | `false` | Create a PostgreSQL database |
| `environmentFile` | str\|null | `null` | Path to an env-file |
| `extraEnvironment` | attrs | `{}` | Extra environment variables |
| `hashedPassword` | str\|null | `null` | Hashed password for web auth |
| `puid` / `pgid` | str | `"911"` / `"100"` | UID/GID for container services |
| `timeZone` | str | `"UTC"` | Timezone for container services |
| `redis.enable` | bool | `false` | Create a Redis instance for this service |
| `redis.port` | int | `6379` | Redis port |
| `reverseProxy.enable` | bool | `false` | Add a Caddy reverse proxy block |
| `reverseProxy.subdomain` | str | `<name>` | Caddy subdomain |
| `reverseProxy.domain` | str | `"mjallen.dev"` | Caddy base domain |
| `reverseProxy.upstreamUrl` | str\|null | `null` | Override upstream URL |
| `reverseProxy.extraCaddyConfig` | lines | `""` | Extra Caddyfile directives |

**Default behaviour when enabled:**

- Adds Caddy reverse proxy block (if `reverseProxy.enable = true`)
- Opens firewall ports (if `openFirewall = true`)
- Creates system user/group (if `createUser = true`)
- Creates PostgreSQL database (if `configureDb = true`)
- Creates Redis instance (if `redis.enable = true`)
- Adds `RequiresMountsFor` systemd dependency for `configDir` and `dataDir`

---

### `mkContainerService`

Wraps `mkModule` for Podman/OCI container services. Generates the full container definition automatically.

```nix
lib.mjallen.mkContainerService {
  config        # NixOS config attrset
  name          # Service/container name
  image         # OCI image reference (e.g. "ghcr.io/example/app:latest")
  internalPort  # Port the container listens on internally
  description   # Human-readable description (defaults to name)
  options       # Extra mkModule options
  volumes       # Extra volume mount strings
  environment   # Extra environment variables (merged with PUID/PGID/TZ)
  environmentFiles # List of env-file paths (e.g. SOPS template paths)
  extraOptions  # Extra --opt strings for the container runtime
  devices       # Device mappings
  extraConfig   # Extra NixOS config merged into moduleConfig
}
```

The systemd service is named `podman-<name>`, and the port binding is `<cfg.port>:<internalPort>`.

---

### `mkSopsEnvFile`

Generates a SOPS secrets block and a SOPS template env-file in a single call. Useful for services that need secrets injected as environment variables.

```nix
lib.mjallen.mkSopsEnvFile {
  secrets     # attrset: sops-key → extra attrs (owner, group, etc.)
  name        # Template file name, e.g. "myapp.env"
  content     # Template body (use config.sops.placeholder."key")
  restartUnit # Systemd unit to restart when secrets change
  owner       # File owner (default: "nix-apps")
  group       # File group (default: "jallen-nas")
  mode        # File permissions (default: "660")
  sopsFile    # Default SOPS file for all secrets
}
```

---

### Option helpers

| Function | Signature | Description |
|---|---|---|
| `mkOpt` | `type → default → description → mkOption` | Standard option shorthand |
| `mkOpt'` | `type → default → mkOption` | `mkOpt` without description |
| `mkBoolOpt` | `default → description → mkOption` | Boolean option shorthand |
| `mkBoolOpt'` | `default → mkOption` | Boolean option without description |
| `mkReverseProxyOpt` | `name → attrset` | Standard Caddy reverse proxy sub-options |

---

### Convenience shorthands

| Value | Expands to |
|---|---|
| `enabled` | `{ enable = true; }` |
| `disabled` | `{ enable = false; }` |

---

### Attribute utilities

| Function | Description |
|---|---|
| `default-attrs` | Apply `lib.mkDefault` to every value in an attrset |
| `force-attrs` | Apply `lib.mkForce` to every value in an attrset |
| `nested-default-attrs` | Apply `default-attrs` one level deeper |
| `nested-force-attrs` | Apply `force-attrs` one level deeper |

---

### String utilities

| Function | Description |
|---|---|
| `capitalize` | Capitalise the first character of a string |

---

### Boolean utilities

| Function | Description |
|---|---|
| `boolToNum` | `true → 1`, `false → 0` |

---

## Home Manager Utilities (`lib.mjallen.module`)

### `mkHomeModule`

Creates a Home Manager module with a standard `enable` option.

```nix
lib.mjallen.mkHomeModule {
  config       # HM config attrset
  domain       # Option namespace domain, e.g. "programs" or "desktop"
  name         # Module name, e.g. "btop"
  description  # Text for mkEnableOption (defaults to name)
  options      # Extra options merged into the submodule
  moduleConfig # HM config body (applied when cfg.enable = true)
}
```

---

## File Utilities (`lib.mjallen.file`)

Helpers for resolving paths relative to the flake root. Primarily used internally by modules and packages.

---

## Versioning Utilities (`lib.mjallen.versioning`)

Used by packages that track multiple upstream variants (e.g. `proton-cachyos`, `linux-rpi`). Reads a `version.json` file and resolves sources with optional variable substitution and per-variant overrides.

See `lib/versioning/default.nix` for the full API and `docs/version.schema.json` for the `version.json` schema.
