The pipe operator '<|' was added in Nix 2.24 as experimental. In typical nix community fashion, an eternity has passed, it's still experimental, and they're still arguing about it. Thus, in order not to burden any users of this flake, they have been removed. To get this done quickly a utility function has been added called 'compose'. It is 'lib.trivial.pipe' written in reverse. This eliminates any bugs and performance regressions from unnecessary thunk evaluation.
162 lines
5 KiB
Nix
162 lines
5 KiB
Nix
{
|
|
pkgs,
|
|
lib,
|
|
sLib,
|
|
info,
|
|
...
|
|
}:
|
|
|
|
let
|
|
submodule =
|
|
{ name, ... }:
|
|
{
|
|
options = {
|
|
packages = lib.mkOption {
|
|
type =
|
|
sLib.compose
|
|
[
|
|
lib.types.listOf
|
|
(lib.types.either lib.types.package)
|
|
(lib.types.submodule)
|
|
]
|
|
{
|
|
options = {
|
|
name = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = name;
|
|
example = "ublock-origin";
|
|
description = "The short name of the extension. To find the short name look at the extension's download link.";
|
|
};
|
|
|
|
guid = lib.mkOption {
|
|
type = lib.types.str;
|
|
example = "uBlock0@raymondhill.net";
|
|
description = "The guid of the extension. To find the guid go to https://addons.mozilla.org/api/v5/addons/addon/\${shortName}/";
|
|
};
|
|
};
|
|
};
|
|
default = [ ];
|
|
description = ''
|
|
Extensions to install for this profile. Takes either a package or a description of an extension.
|
|
* If a package is given, the extension will be preinstalled.
|
|
* If a description is given then ${info.name} will download the extension on startup.
|
|
'';
|
|
};
|
|
|
|
settings = lib.mkOption {
|
|
type =
|
|
let
|
|
jsonFormat = pkgs.formats.json { };
|
|
in
|
|
lib.types.attrsOf jsonFormat.type;
|
|
default = { };
|
|
description = "Settings for this extension, accessible by the managed storage API. The extension must be referenced by id.";
|
|
};
|
|
};
|
|
};
|
|
|
|
# (Package -> a) -> ({ name, guid } -> a) -> Extension -> a
|
|
withExtension =
|
|
f: g: x:
|
|
if lib.isDerivation x then f x else g x;
|
|
|
|
# ublock-origin wants its settings as a string, which is annoying
|
|
# to merge. For convenience, you can keep ublock-origin's config
|
|
# as a set and this function will turn it into a string at the
|
|
# last minute. As a bonus, we can also do other magic for other
|
|
# extensions if need be.
|
|
magicInfo = {
|
|
"uBlock0@raymondhill.net" =
|
|
x:
|
|
x
|
|
// lib.optionalAttrs (x ? adminSettings) {
|
|
adminSettings = sLib.compose [
|
|
builtins.toJSON
|
|
(
|
|
y:
|
|
y
|
|
// lib.optionalAttrs (y ? userFilters) {
|
|
userFilters = builtins.concatStringsSep "\n" y.userFilters;
|
|
}
|
|
)
|
|
(
|
|
y:
|
|
y
|
|
// lib.optionalAttrs (y ? urlFilteringString) {
|
|
urlFilteringString = builtins.concatStringsSep "\n" y.urlFilteringString;
|
|
}
|
|
)
|
|
(
|
|
y:
|
|
y
|
|
// lib.optionalAttrs (y ? hostnameSwitchesString) {
|
|
hostnameSwitchesString = builtins.concatStringsSep "\n" y.hostnameSwitchesString;
|
|
}
|
|
)
|
|
(
|
|
y:
|
|
y
|
|
// lib.optionalAttrs (y ? dynamicFilteringString) {
|
|
dynamicFilteringString = builtins.concatStringsSep "\n" y.dynamicFilteringString;
|
|
}
|
|
)
|
|
] x.adminSettings;
|
|
};
|
|
};
|
|
magic = guid: magicInfo.${guid} or lib.trivial.id;
|
|
in
|
|
{
|
|
options = {
|
|
extensions = lib.mkOption {
|
|
type = lib.types.submodule submodule;
|
|
default = { };
|
|
# example = {
|
|
# packages = [
|
|
# nur.repos.rycee.firefox-addons.ublock-origin
|
|
# { name = "decentraleyes"; guid = "jid1-BoFifL9Vbdl2zQ@jetpack"; }
|
|
# ];
|
|
# settings."uBlock0@raymondhill.net" = {
|
|
# whitelist = [ "example.org" ];
|
|
# };
|
|
# };
|
|
description = "The extensions to install.";
|
|
};
|
|
};
|
|
|
|
process =
|
|
{ extensions, ... }:
|
|
{
|
|
policies = {
|
|
"3rdparty".Extensions = extensions.settings;
|
|
ExtensionSettings = sLib.compose [
|
|
builtins.listToAttrs
|
|
(builtins.map (
|
|
withExtension
|
|
(x: {
|
|
name = x.addonId;
|
|
value = {
|
|
installation_mode = "force_installed";
|
|
private_browsing = true;
|
|
install_url = "file://${x}/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/${x.addonId}.xpi";
|
|
};
|
|
})
|
|
(x: {
|
|
name = x.guid;
|
|
value = {
|
|
installation_mode = "force_installed";
|
|
private_browsing = true;
|
|
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${x.name}/latest.xpi";
|
|
};
|
|
})
|
|
))
|
|
] extensions.packages;
|
|
};
|
|
prefs."extensions.autoDisableScopes" = 0;
|
|
};
|
|
|
|
postprocess =
|
|
{ policies, ... }:
|
|
lib.optionalAttrs (policies ? "3rdparty".Extensions) {
|
|
policies."3rdparty".Extensions = builtins.mapAttrs magic (policies."3rdparty".Extensions or { });
|
|
};
|
|
}
|