{ config, lib, pkgs, ... }: let cfg = config.services.airdrome; # Base env object built at Nix eval time (no shell quoting needed). baseEnv = lib.optionalAttrs (cfg.serverUrl != null) { SERVER_URL = cfg.serverUrl; } // lib.optionalAttrs (cfg.username != null) { USERNAME = cfg.username; } // lib.optionalAttrs (cfg.password != null) { PASSWORD = cfg.password; }; baseEnvJson = pkgs.writeText "airdrome-env.json" (builtins.toJSON baseEnv); in { options.services.airdrome = { enable = lib.mkEnableOption "Airdrome web root assembly"; package = lib.mkOption { type = lib.types.package; defaultText = lib.literalExpression "pkgs.airdrome"; description = "Package to use."; }; serverUrl = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Navidrome server URL."; }; username = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Auto-login username."; }; password = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = '' Plaintext password (ends up in the Nix store — use {option}`passwordFile` instead). ''; }; passwordFile = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Runtime path to a file containing the password."; }; webRoot = lib.mkOption { type = lib.types.str; default = "/var/lib/airdrome/web"; readOnly = true; description = "Assembled web root to point your web server at."; }; }; config = lib.mkIf cfg.enable { assertions = [ { assertion = !(cfg.password != null && cfg.passwordFile != null); message = "services.airdrome.password and services.airdrome.passwordFile are mutually exclusive."; } ]; systemd.services.airdrome-config = { description = "Assemble Airdrome web root"; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; StateDirectory = "airdrome"; }; path = lib.optionals (cfg.passwordFile != null) [ pkgs.jq ]; script = let webRoot = cfg.webRoot; pkg = cfg.package; in '' # 1. Fresh web root rm -rf ${webRoot} mkdir -p ${webRoot} # 2. Symlink all package files except env.js for f in ${pkg}/*; do name="$(basename "$f")" [ "$name" = "env.js" ] && continue ln -s "$f" ${webRoot}/"$name" done # 3. Build env JSON '' + ( if cfg.passwordFile != null then '' env_json=$(jq --arg pw "$(cat ${cfg.passwordFile})" '. + {PASSWORD: $pw}' ${baseEnvJson}) '' else '' env_json=$(cat ${baseEnvJson}) '' ) + '' # 4. Write env.js printf 'window.env = %s;\n' "$env_json" > ${webRoot}/env.js ''; }; }; }