{ lib, ... }: let inherit (lib) mkOption types; emailType = types.submodule { options = { address = mkOption { type = types.nonEmptyStr; }; type = mkOption { type = types.enum [ "mxrouting" "office365" ]; }; }; }; accountType = types.submodule { options = { name = mkOption { type = types.nonEmptyStr; }; realName = mkOption { type = types.nonEmptyStr; }; homeDirectory = mkOption { type = types.nonEmptyStr; }; nixosConfigurationPath = mkOption { type = types.nonEmptyStr; }; emails = mkOption { type = types.attrsOf emailType; }; primaryEmail = mkOption { type = types.nonEmptyStr; }; }; }; accountOption = mkOption { type = accountType; apply = account: assert lib.assertMsg (builtins.hasAttr account.primaryEmail account.emails) "facts.account.primaryEmail must name an entry in facts.account.emails"; account; }; sshKeyType = types.submodule { options = { publicKey = mkOption { type = types.nonEmptyStr; }; privateKeyPath = mkOption { type = types.nullOr types.nonEmptyStr; default = null; }; }; }; displayType = types.submodule { options = { x = mkOption { type = types.int; default = 0; }; y = mkOption { type = types.int; default = 0; }; primary = mkOption { type = types.bool; default = false; }; scale = mkOption { type = types.nullOr types.number; default = null; }; width = mkOption { type = types.nullOr types.ints.positive; default = null; }; height = mkOption { type = types.nullOr types.ints.positive; default = null; }; refresh = mkOption { type = types.nullOr types.number; default = null; }; }; }; displaysOption = mkOption { type = types.attrsOf displayType; default = { }; apply = displays: assert lib.assertMsg (lib.all ( display: let values = [ display.width display.height display.refresh ]; in lib.all (value: value == null) values || lib.all (value: value != null) values ) (builtins.attrValues displays)) "display width, height, and refresh must be supplied together"; displays; }; machineType = { withName ? false, }: types.submodule ( { config, ... }: { options = { system = mkOption { type = types.nonEmptyStr; }; stateVersion = mkOption { type = types.nonEmptyStr; }; hmStateVersion = mkOption { type = types.nonEmptyStr; default = config.stateVersion; }; syncthingId = mkOption { type = types.nullOr types.nonEmptyStr; default = null; }; sshKeys = mkOption { type = types.attrsOf sshKeyType; default = { }; }; displays = displaysOption; } // lib.optionalAttrs withName { name = mkOption { type = types.nonEmptyStr; }; }; } ); endpointType = types.submodule ( { config, ... }: { options = { scheme = mkOption { type = types.enum [ "http" "https" ]; }; domain = mkOption { type = types.nonEmptyStr; }; origin = mkOption { type = types.nonEmptyStr; readOnly = true; default = "${config.scheme}://${config.domain}"; }; }; } ); externalDeviceType = types.submodule { options.syncthingId = mkOption { type = types.nullOr types.nonEmptyStr; default = null; }; }; topologyType = types.submodule { options.server = mkOption { type = types.submodule { options = { machine = mkOption { type = types.nonEmptyStr; }; sshAlias = mkOption { type = types.nonEmptyStr; }; }; }; }; }; factsType = { withMachine ? false, }: types.submodule { options = { account = accountOption; machines = mkOption { type = types.attrsOf (machineType { }); }; services = mkOption { type = types.attrsOf endpointType; }; externalDevices = mkOption { type = types.attrsOf externalDeviceType; default = { }; }; topology = mkOption { type = topologyType; }; } // lib.optionalAttrs withMachine { machine = mkOption { type = machineType { withName = true; }; }; }; }; in { options.facts = mkOption { type = factsType { }; }; config = { facts = { account = rec { name = "kiri"; realName = "Jelle Spreeuwenberg"; homeDirectory = "/home/${name}"; nixosConfigurationPath = "${homeDirectory}/.config/nixos"; primaryEmail = "personal"; emails = { personal = { address = "mail@jelles.net"; type = "mxrouting"; }; old = { address = "mail@jellespreeuwenberg.nl"; type = "mxrouting"; }; uni = { address = "j.spreeuwenberg@student.tue.nl"; type = "office365"; }; work = { address = "jelle.spreeuwenberg@yookr.org"; type = "office365"; }; }; }; services = { actual = { scheme = "https"; domain = "finance.jelles.net"; }; gitea = { scheme = "https"; domain = "git.jelles.net"; }; radicale = { scheme = "https"; domain = "radicale.jelles.net"; }; vaultwarden = { scheme = "https"; domain = "vault.jelles.net"; }; }; externalDevices.pixel-10.syncthingId = "MTJHEHA-UMZDQZ7-BTMRRLQ-Y7BFPUJ-ZTY6LZX-PDXV3IS-XVJCU7B-EPETBQZ"; topology.server = { machine = "orion"; sshAlias = "orion"; }; }; flake.modules.nixos.facts = { options.facts = mkOption { type = factsType { withMachine = true; }; }; }; flake.modules.homeManager.facts = { osConfig, ... }: { options.facts = mkOption { type = factsType { withMachine = true; }; }; config.facts = { inherit (osConfig.facts) account externalDevices machine machines topology ; services = lib.mapAttrs (_: service: { inherit (service) scheme domain; }) osConfig.facts.services; }; }; }; }