{ lib, ... }: let inherit (lib) mkDefault mkEnableOption mkIf mkOption types ; in { isNotEmptyStr = str: builtins.isString str && str != ""; mkMailIntegrationOption = service: { enable = mkEnableOption "Mail integration for ${service}."; smtpHost = mkOption { type = types.str; default = "localhost"; description = "SMTP host for sending emails."; }; }; mkReverseProxyOption = service: subdomain: { enable = mkEnableOption "Nginx reverse proxy for ${service}."; subdomain = mkOption { type = types.str; default = subdomain; description = "Subdomain for Nginx virtual host. Leave empty for root domain."; }; forceSSL = mkOption { type = types.bool; default = true; description = "Force SSL for Nginx virtual host."; }; }; mkUrl = { fqdn, ssl ? false, port ? null, path ? "", ... }: let protocol = if ssl then "https" else "http"; portPart = if port != null then ":${toString port}" else ""; pathPart = if path != "" then "/${path}" else ""; in "${protocol}://${fqdn}${portPart}${pathPart}"; mkVirtualHost = { address ? "127.0.0.1", port ? null, socketPath ? null, location ? "/", ssl ? false, proxyWebsockets ? true, recommendedProxySettings ? true, extraConfig ? "", ... }: let target = if port != null then "http://${address}:${builtins.toString port}" else if socketPath != null then "http://unix:${socketPath}" else null; in { enableACME = ssl; forceSSL = ssl; locations = mkIf (target != null) { "${location}" = { proxyPass = mkDefault target; inherit proxyWebsockets recommendedProxySettings extraConfig; }; }; }; }