diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 7925dee746ab..49509171c3f6 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -485,6 +485,8 @@
./services/mail/roundcube.nix
./services/mail/sympa.nix
./services/mail/nullmailer.nix
+ ./services/matrix/mjolnir.nix
+ ./services/matrix/pantalaimon.nix
./services/misc/ananicy.nix
./services/misc/airsonic.nix
./services/misc/ankisyncd.nix
diff --git a/nixos/modules/services/matrix/mjolnir.nix b/nixos/modules/services/matrix/mjolnir.nix
new file mode 100644
index 000000000000..8a54f93d98d8
--- /dev/null
+++ b/nixos/modules/services/matrix/mjolnir.nix
@@ -0,0 +1,240 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.services.mjolnir;
+
+ yamlConfig = {
+ inherit (cfg) dataPath managementRoom protectedRooms;
+
+ accessToken = "@ACCESS_TOKEN@"; # will be replaced in "generateConfig"
+ homeserverUrl =
+ if cfg.pantalaimon.enable then
+ "http://${cfg.pantalaimon.options.listenAddress}:${toString cfg.pantalaimon.options.listenPort}"
+ else
+ cfg.homeserverUrl;
+
+ pantalaimon = {
+ inherit (cfg.pantalaimon) username;
+
+ use = cfg.pantalaimon.enable;
+ password = "@PANTALAIMON_PASSWORD@"; # will be replaced in "generateConfig"
+ };
+ };
+
+ moduleConfigFile = pkgs.writeText "module-config.yaml" (
+ generators.toYAML { } (filterAttrs (_: v: v != null)
+ (fold recursiveUpdate { } [ yamlConfig cfg.settings ])));
+
+ # these config files will be merged one after the other to build the final config
+ configFiles = [
+ "${pkgs.mjolnir}/share/mjolnir/config/default.yaml"
+ moduleConfigFile
+ ];
+
+ # this will generate the default.yaml file with all configFiles as inputs and
+ # replace all secret strings using replace-secret
+ generateConfig = pkgs.writeShellScript "mjolnir-generate-config" (
+ let
+ yqEvalStr = concatImapStringsSep " * " (pos: _: "select(fileIndex == ${toString (pos - 1)})") configFiles;
+ yqEvalArgs = concatStringsSep " " configFiles;
+ in
+ ''
+ set -euo pipefail
+
+ umask 077
+
+ # mjolnir will try to load a config from "./config/default.yaml" in the working directory
+ # -> let's place the generated config there
+ mkdir -p ${cfg.dataPath}/config
+
+ # merge all config files into one, overriding settings of the previous one with the next config
+ # e.g. "eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' filea.yaml fileb.yaml" will merge filea.yaml with fileb.yaml
+ ${pkgs.yq-go}/bin/yq eval-all -P '${yqEvalStr}' ${yqEvalArgs} > ${cfg.dataPath}/config/default.yaml
+
+ ${optionalString (cfg.accessTokenFile != null) ''
+ ${pkgs.replace-secret}/bin/replace-secret '@ACCESS_TOKEN@' '${cfg.accessTokenFile}' ${cfg.dataPath}/config/default.yaml
+ ''}
+ ${optionalString (cfg.pantalaimon.passwordFile != null) ''
+ ${pkgs.replace-secret}/bin/replace-secret '@PANTALAIMON_PASSWORD@' '${cfg.pantalaimon.passwordFile}' ${cfg.dataPath}/config/default.yaml
+ ''}
+ ''
+ );
+in
+{
+ options.services.mjolnir = {
+ enable = mkEnableOption "Mjolnir, a moderation tool for Matrix";
+
+ homeserverUrl = mkOption {
+ type = types.str;
+ default = "https://matrix.org";
+ description = ''
+ Where the homeserver is located (client-server URL).
+
+ If pantalaimon.enable is true, this option will become the homeserver to which pantalaimon connects.
+ The listen address of pantalaimon will then become the homeserverUrl of mjolnir.
+ '';
+ };
+
+ accessTokenFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ description = ''
+ File containing the matrix access token for the mjolnir user.
+ '';
+ };
+
+ pantalaimon = mkOption {
+ description = ''
+ pantalaimon options (enables E2E Encryption support).
+
+ This will create a pantalaimon instance with the name "mjolnir".
+ '';
+ default = { };
+ type = types.submodule {
+ options = {
+ enable = mkEnableOption ''
+ If true, accessToken is ignored and the username/password below will be
+ used instead. The access token of the bot will be stored in the dataPath.
+ '';
+
+ username = mkOption {
+ type = types.str;
+ description = "The username to login with.";
+ };
+
+ passwordFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ description = ''
+ File containing the matrix password for the mjolnir user.
+ '';
+ };
+
+ options = mkOption {
+ type = types.submodule (import ./pantalaimon-options.nix);
+ default = { };
+ description = ''
+ passthrough additional options to the pantalaimon service.
+ '';
+ };
+ };
+ };
+ };
+
+ dataPath = mkOption {
+ type = types.path;
+ default = "/var/lib/mjolnir";
+ description = ''
+ The directory the bot should store various bits of information in.
+ '';
+ };
+
+ managementRoom = mkOption {
+ type = types.str;
+ default = "#moderators:example.org";
+ description = ''
+ The room ID where people can use the bot. The bot has no access controls, so
+ anyone in this room can use the bot - secure your room!
+ This should be a room alias or room ID - not a matrix.to URL.
+ Note: mjolnir is fairly verbose - expect a lot of messages from it.
+ '';
+ };
+
+ protectedRooms = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = literalExpression ''
+ [
+ "https://matrix.to/#/#yourroom:example.org"
+ "https://matrix.to/#/#anotherroom:example.org"
+ ]
+ '';
+ description = ''
+ A list of rooms to protect (matrix.to URLs).
+ '';
+ };
+
+ settings = mkOption {
+ default = { };
+ type = (pkgs.formats.yaml { }).type;
+ example = literalExpression ''
+ {
+ autojoinOnlyIfManager = true;
+ automaticallyRedactForReasons = [ "spam" "advertising" ];
+ }
+ '';
+ description = ''
+ Additional settings (see mjolnir default config for available settings). These settings will override settings made by the module config.
+ '';
+ };
+ };
+
+ config = mkIf config.services.mjolnir.enable {
+ assertions = [
+ {
+ assertion = !(cfg.pantalaimon.enable && cfg.pantalaimon.passwordFile == null);
+ message = "Specify pantalaimon.passwordFile";
+ }
+ {
+ assertion = !(cfg.pantalaimon.enable && cfg.accessTokenFile != null);
+ message = "Do not specify accessTokenFile when using pantalaimon";
+ }
+ {
+ assertion = !(!cfg.pantalaimon.enable && cfg.accessTokenFile == null);
+ message = "Specify accessTokenFile when not using pantalaimon";
+ }
+ ];
+
+ services.pantalaimon-headless.instances."mjolnir" = mkIf cfg.pantalaimon.enable
+ {
+ homeserver = cfg.homeserverUrl;
+ } // cfg.pantalaimon.options;
+
+ systemd.services.mjolnir = {
+ description = "mjolnir - a moderation tool for Matrix";
+ wants = [ "network-online.target" ] ++ optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
+ after = [ "network-online.target" ] ++ optionals (cfg.pantalaimon.enable) [ "pantalaimon-mjolnir.service" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ ExecStart = ''${pkgs.mjolnir}/bin/mjolnir'';
+ ExecStartPre = [ generateConfig ];
+ WorkingDirectory = cfg.dataPath;
+ StateDirectory = "mjolnir";
+ StateDirectoryMode = "0700";
+ ProtectSystem = "strict";
+ ProtectHome = true;
+ PrivateTmp = true;
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ User = "mjolnir";
+ Restart = "on-failure";
+
+ /* TODO: wait for #102397 to be resolved. Then load secrets from $CREDENTIALS_DIRECTORY+"/NAME"
+ DynamicUser = true;
+ LoadCredential = [] ++
+ optionals (cfg.accessTokenFile != null) [
+ "access_token:${cfg.accessTokenFile}"
+ ] ++
+ optionals (cfg.pantalaimon.passwordFile != null) [
+ "pantalaimon_password:${cfg.pantalaimon.passwordFile}"
+ ];
+ */
+ };
+ };
+
+ users = {
+ users.mjolnir = {
+ group = "mjolnir";
+ isSystemUser = true;
+ };
+ groups.mjolnir = { };
+ };
+ };
+
+ meta = {
+ doc = ./mjolnir.xml;
+ maintainers = with maintainers; [ jojosch ];
+ };
+}
diff --git a/nixos/modules/services/matrix/mjolnir.xml b/nixos/modules/services/matrix/mjolnir.xml
new file mode 100644
index 000000000000..d462ddf7b01b
--- /dev/null
+++ b/nixos/modules/services/matrix/mjolnir.xml
@@ -0,0 +1,134 @@
+
+ Mjolnir (Matrix Moderation Tool)
+
+ This chapter will show you how to set up your own, self-hosted
+ Mjolnir
+ instance.
+
+
+ As an all-in-one moderation tool, it can protect your server from
+ malicious invites, spam messages, and whatever else you don't want.
+ In addition to server-level protection, Mjolnir is great for communities
+ wanting to protect their rooms without having to use their personal
+ accounts for moderation.
+
+
+ The bot by default includes support for bans, redactions, anti-spam,
+ server ACLs, room directory changes, room alias transfers, account
+ deactivation, room shutdown, and more.
+
+
+ See the README
+ page and the Moderator's guide
+ for additional instructions on how to setup and use Mjolnir.
+
+
+ For additional settings
+ see the default configuration.
+
+
+ Mjolnir Setup
+
+ First create a new Room which will be used as a management room for Mjolnir. In
+ this room, Mjolnir will log possible errors and debugging information. You'll
+ need to set this Room-ID in services.mjolnir.managementRoom.
+
+
+ Next, create a new user for Mjolnir on your homeserver, if not present already.
+
+
+ The Mjolnir Matrix user expects to be free of any rate limiting.
+ See Synapse #6286
+ for an example on how to achieve this.
+
+
+ If you want Mjolnir to be able to deactivate users, move room aliases, shutdown rooms, etc.
+ you'll need to make the Mjolnir user a Matrix server admin.
+
+
+ Now invite the Mjolnir user to the management room.
+
+
+ It is recommended to use Pantalaimon,
+ so your management room can be encrypted. This also applies if you are looking to moderate an encrypted room.
+
+
+ To enable the Pantalaimon E2E Proxy for mjolnir, enable
+ services.mjolnir.pantalaimon. This will
+ autoconfigure a new Pantalaimon instance, which will connect to the homeserver
+ set in services.mjolnir.homeserverUrl and Mjolnir itself
+ will be configured to connect to the new Pantalaimon instance.
+
+
+{
+ services.mjolnir = {
+ enable = true;
+ homeserverUrl = "https://matrix.domain.tld";
+ pantalaimon = {
+ enable = true;
+ username = "mjolnir";
+ passwordFile = "/run/secrets/mjolnir-password";
+ };
+ protectedRooms = [
+ "https://matrix.to/#/!xxx:domain.tld"
+ ];
+ managementRoom = "!yyy:domain.tld";
+ };
+}
+
+
+ Element Matrix Services (EMS)
+
+ If you are using a managed "Element Matrix Services (EMS)"
+ server, you will need to consent to the terms and conditions. Upon startup, an error
+ log entry with a URL to the consent page will be generated.
+
+
+
+
+
+ Synapse Antispam Module
+
+ A Synapse module is also available to apply the same rulesets the bot
+ uses across an entire homeserver.
+
+
+ To use the Antispam Module, add matrix-synapse-plugins.matrix-synapse-mjolnir-antispam
+ to the Synapse plugin list and enable the mjolnir.AntiSpam module.
+
+
+{
+ services.matrix-synapse = {
+ plugins = with pkgs; [
+ matrix-synapse-plugins.matrix-synapse-mjolnir-antispam
+ ];
+ extraConfig = ''
+ modules:
+ - module: mjolnir.AntiSpam
+ config:
+ # Prevent servers/users in the ban lists from inviting users on this
+ # server to rooms. Default true.
+ block_invites: true
+ # Flag messages sent by servers/users in the ban lists as spam. Currently
+ # this means that spammy messages will appear as empty to users. Default
+ # false.
+ block_messages: false
+ # Remove users from the user directory search by filtering matrix IDs and
+ # display names by the entries in the user ban list. Default false.
+ block_usernames: false
+ # The room IDs of the ban lists to honour. Unlike other parts of Mjolnir,
+ # this list cannot be room aliases or permalinks. This server is expected
+ # to already be joined to the room - Mjolnir will not automatically join
+ # these rooms.
+ ban_lists:
+ - "!roomid:example.org"
+ '';
+ };
+}
+
+
+
diff --git a/nixos/modules/services/matrix/pantalaimon-options.nix b/nixos/modules/services/matrix/pantalaimon-options.nix
new file mode 100644
index 000000000000..035c57540d09
--- /dev/null
+++ b/nixos/modules/services/matrix/pantalaimon-options.nix
@@ -0,0 +1,70 @@
+{ config, lib, name, ... }:
+
+with lib;
+{
+ options = {
+ dataPath = mkOption {
+ type = types.path;
+ default = "/var/lib/pantalaimon-${name}";
+ description = ''
+ The directory where pantalaimon should store its state such as the database file.
+ '';
+ };
+
+ logLevel = mkOption {
+ type = types.enum [ "info" "warning" "error" "debug" ];
+ default = "warning";
+ description = ''
+ Set the log level of the daemon.
+ '';
+ };
+
+ homeserver = mkOption {
+ type = types.str;
+ example = "https://matrix.org";
+ description = ''
+ The URI of the homeserver that the pantalaimon proxy should
+ forward requests to, without the matrix API path but including
+ the http(s) schema.
+ '';
+ };
+
+ ssl = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not SSL verification should be enabled for outgoing
+ connections to the homeserver.
+ '';
+ };
+
+ listenAddress = mkOption {
+ type = types.str;
+ default = "localhost";
+ description = ''
+ The address where the daemon will listen to client connections
+ for this homeserver.
+ '';
+ };
+
+ listenPort = mkOption {
+ type = types.port;
+ default = 8009;
+ description = ''
+ The port where the daemon will listen to client connections for
+ this homeserver. Note that the listen address/port combination
+ needs to be unique between different homeservers.
+ '';
+ };
+
+ extraSettings = mkOption {
+ type = types.attrs;
+ default = { };
+ description = ''
+ Extra configuration options. See
+ pantalaimon(5)
+ for available options.
+ '';
+ };
+ };
+}
diff --git a/nixos/modules/services/matrix/pantalaimon.nix b/nixos/modules/services/matrix/pantalaimon.nix
new file mode 100644
index 000000000000..63b40099ca5d
--- /dev/null
+++ b/nixos/modules/services/matrix/pantalaimon.nix
@@ -0,0 +1,70 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.services.pantalaimon-headless;
+
+ iniFmt = pkgs.formats.ini { };
+
+ mkConfigFile = name: instanceConfig: iniFmt.generate "pantalaimon.conf" {
+ Default = {
+ LogLevel = instanceConfig.logLevel;
+ Notifications = false;
+ };
+
+ ${name} = (recursiveUpdate
+ {
+ Homeserver = instanceConfig.homeserver;
+ ListenAddress = instanceConfig.listenAddress;
+ ListenPort = instanceConfig.listenPort;
+ SSL = instanceConfig.ssl;
+
+ # Set some settings to prevent user interaction for headless operation
+ IgnoreVerification = true;
+ UseKeyring = false;
+ }
+ instanceConfig.extraSettings
+ );
+ };
+
+ mkPantalaimonService = name: instanceConfig:
+ nameValuePair "pantalaimon-${name}" {
+ description = "pantalaimon instance ${name} - E2EE aware proxy daemon for matrix clients";
+ wants = [ "network-online.target" ];
+ after = [ "network-online.target" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ ExecStart = ''${pkgs.pantalaimon-headless}/bin/pantalaimon --config ${mkConfigFile name instanceConfig} --data-path ${instanceConfig.dataPath}'';
+ Restart = "on-failure";
+ DynamicUser = true;
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ PrivateTmp = true;
+ ProtectHome = true;
+ ProtectSystem = "strict";
+ StateDirectory = "pantalaimon-${name}";
+ };
+ };
+in
+{
+ options.services.pantalaimon-headless.instances = mkOption {
+ default = { };
+ type = types.attrsOf (types.submodule (import ./pantalaimon-options.nix));
+ description = ''
+ Declarative instance config.
+
+ Note: to use pantalaimon interactively, e.g. for a Matrix client which does not
+ support End-to-end encryption (like fractal), refer to the home-manager module.
+ '';
+ };
+
+ config = mkIf (config.services.pantalaimon-headless.instances != { })
+ {
+ systemd.services = mapAttrs' mkPantalaimonService config.services.pantalaimon-headless.instances;
+ };
+
+ meta = {
+ maintainers = with maintainers; [ jojosch ];
+ };
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 4c28b552679e..0ee91ebffbed 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -260,6 +260,7 @@ in
miniflux = handleTest ./miniflux.nix {};
minio = handleTest ./minio.nix {};
misc = handleTest ./misc.nix {};
+ mjolnir = handleTest ./matrix/mjolnir.nix {};
mod_perl = handleTest ./mod_perl.nix {};
moinmoin = handleTest ./moinmoin.nix {};
mongodb = handleTest ./mongodb.nix {};
@@ -340,6 +341,7 @@ in
packagekit = handleTest ./packagekit.nix {};
pam-oath-login = handleTest ./pam-oath-login.nix {};
pam-u2f = handleTest ./pam-u2f.nix {};
+ pantalaimon = handleTest ./matrix/pantalaimon.nix {};
pantheon = handleTest ./pantheon.nix {};
paperless-ng = handleTest ./paperless-ng.nix {};
parsedmarc = handleTest ./parsedmarc {};
diff --git a/nixos/tests/matrix/mjolnir.nix b/nixos/tests/matrix/mjolnir.nix
new file mode 100644
index 000000000000..bb55f6f5440b
--- /dev/null
+++ b/nixos/tests/matrix/mjolnir.nix
@@ -0,0 +1,165 @@
+import ../make-test-python.nix (
+ { pkgs, ... }:
+ let
+ # Set up SSL certs for Synapse to be happy.
+ runWithOpenSSL = file: cmd: pkgs.runCommand file
+ {
+ buildInputs = [ pkgs.openssl ];
+ }
+ cmd;
+
+ ca_key = runWithOpenSSL "ca-key.pem" "openssl genrsa -out $out 2048";
+ ca_pem = runWithOpenSSL "ca.pem" ''
+ openssl req \
+ -x509 -new -nodes -key ${ca_key} \
+ -days 10000 -out $out -subj "/CN=snakeoil-ca"
+ '';
+ key = runWithOpenSSL "matrix_key.pem" "openssl genrsa -out $out 2048";
+ csr = runWithOpenSSL "matrix.csr" ''
+ openssl req \
+ -new -key ${key} \
+ -out $out -subj "/CN=localhost" \
+ '';
+ cert = runWithOpenSSL "matrix_cert.pem" ''
+ openssl x509 \
+ -req -in ${csr} \
+ -CA ${ca_pem} -CAkey ${ca_key} \
+ -CAcreateserial -out $out \
+ -days 365
+ '';
+ in
+ {
+ name = "mjolnir";
+ meta = with pkgs.lib; {
+ maintainers = teams.matrix.members;
+ };
+
+ nodes = {
+ homeserver = { pkgs, ... }: {
+ services.matrix-synapse = {
+ enable = true;
+ database_type = "sqlite3";
+ tls_certificate_path = "${cert}";
+ tls_private_key_path = "${key}";
+ enable_registration = true;
+ registration_shared_secret = "supersecret-registration";
+
+ listeners = [
+ # The default but tls=false
+ {
+ "bind_address" = "";
+ "port" = 8448;
+ "resources" = [
+ { "compress" = true; "names" = [ "client" "webclient" ]; }
+ { "compress" = false; "names" = [ "federation" ]; }
+ ];
+ "tls" = false;
+ "type" = "http";
+ "x_forwarded" = false;
+ }
+ ];
+ };
+
+ networking.firewall.allowedTCPPorts = [ 8448 ];
+
+ environment.systemPackages = [
+ (pkgs.writeShellScriptBin "register_mjolnir_user" ''
+ exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
+ -u mjolnir \
+ -p mjolnir-password \
+ --admin \
+ --shared-secret supersecret-registration \
+ http://localhost:8448
+ ''
+ )
+ (pkgs.writeShellScriptBin "register_moderator_user" ''
+ exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
+ -u moderator \
+ -p moderator-password \
+ --no-admin \
+ --shared-secret supersecret-registration \
+ http://localhost:8448
+ ''
+ )
+ ];
+ };
+
+ mjolnir = { pkgs, ... }: {
+ services.mjolnir = {
+ enable = true;
+ homeserverUrl = "http://homeserver:8448";
+ pantalaimon = {
+ enable = true;
+ username = "mjolnir";
+ passwordFile = pkgs.writeText "password.txt" "mjolnir-password";
+ };
+ managementRoom = "#moderators:homeserver";
+ };
+ };
+
+ client = { pkgs, ... }: {
+ environment.systemPackages = [
+ (pkgs.writers.writePython3Bin "create_management_room_and_invite_mjolnir"
+ { libraries = [ pkgs.python3Packages.matrix-nio ]; } ''
+ import asyncio
+
+ from nio import (
+ AsyncClient,
+ EnableEncryptionBuilder
+ )
+
+
+ async def main() -> None:
+ client = AsyncClient("http://homeserver:8448", "moderator")
+
+ await client.login("moderator-password")
+
+ room = await client.room_create(
+ name="Moderators",
+ alias="moderators",
+ initial_state=[EnableEncryptionBuilder().as_dict()],
+ )
+
+ await client.join(room.room_id)
+ await client.room_invite(room.room_id, "@mjolnir:homeserver")
+
+ asyncio.run(main())
+ ''
+ )
+ ];
+ };
+ };
+
+ testScript = ''
+ with subtest("start homeserver"):
+ homeserver.start()
+
+ homeserver.wait_for_unit("matrix-synapse.service")
+ homeserver.wait_until_succeeds("curl --fail -L http://localhost:8448/")
+
+ with subtest("register users"):
+ # register mjolnir user
+ homeserver.succeed("register_mjolnir_user")
+ # register moderator user
+ homeserver.succeed("register_moderator_user")
+
+ with subtest("start mjolnir"):
+ mjolnir.start()
+
+ # wait for pantalaimon to be ready
+ mjolnir.wait_for_unit("pantalaimon-mjolnir.service")
+ mjolnir.wait_for_unit("mjolnir.service")
+
+ mjolnir.wait_until_succeeds("curl --fail -L http://localhost:8009/")
+
+ with subtest("ensure mjolnir can be invited to the management room"):
+ client.start()
+
+ client.wait_until_succeeds("curl --fail -L http://homeserver:8448/")
+
+ client.succeed("create_management_room_and_invite_mjolnir")
+
+ mjolnir.wait_for_console_text("Startup complete. Now monitoring rooms")
+ '';
+ }
+)
diff --git a/nixos/tests/matrix/pantalaimon.nix b/nixos/tests/matrix/pantalaimon.nix
new file mode 100644
index 000000000000..fcb9904b2138
--- /dev/null
+++ b/nixos/tests/matrix/pantalaimon.nix
@@ -0,0 +1,65 @@
+import ../make-test-python.nix (
+ { pkgs, ... }:
+ let
+ pantalaimonInstanceName = "testing";
+
+ # Set up SSL certs for Synapse to be happy.
+ runWithOpenSSL = file: cmd: pkgs.runCommand file
+ {
+ buildInputs = [ pkgs.openssl ];
+ }
+ cmd;
+
+ ca_key = runWithOpenSSL "ca-key.pem" "openssl genrsa -out $out 2048";
+ ca_pem = runWithOpenSSL "ca.pem" ''
+ openssl req \
+ -x509 -new -nodes -key ${ca_key} \
+ -days 10000 -out $out -subj "/CN=snakeoil-ca"
+ '';
+ key = runWithOpenSSL "matrix_key.pem" "openssl genrsa -out $out 2048";
+ csr = runWithOpenSSL "matrix.csr" ''
+ openssl req \
+ -new -key ${key} \
+ -out $out -subj "/CN=localhost" \
+ '';
+ cert = runWithOpenSSL "matrix_cert.pem" ''
+ openssl x509 \
+ -req -in ${csr} \
+ -CA ${ca_pem} -CAkey ${ca_key} \
+ -CAcreateserial -out $out \
+ -days 365
+ '';
+ in
+ {
+ name = "pantalaimon";
+ meta = with pkgs.lib; {
+ maintainers = teams.matrix.members;
+ };
+
+ machine = { pkgs, ... }: {
+ services.pantalaimon-headless.instances.${pantalaimonInstanceName} = {
+ homeserver = "https://localhost:8448";
+ listenAddress = "0.0.0.0";
+ listenPort = 8888;
+ logLevel = "debug";
+ ssl = false;
+ };
+
+ services.matrix-synapse = {
+ enable = true;
+ database_type = "sqlite3";
+ tls_certificate_path = "${cert}";
+ tls_private_key_path = "${key}";
+ };
+ };
+
+ testScript = ''
+ start_all()
+ machine.wait_for_unit("pantalaimon-${pantalaimonInstanceName}.service")
+ machine.wait_for_unit("matrix-synapse.service")
+ machine.wait_until_succeeds(
+ "curl --fail -L http://localhost:8888/"
+ )
+ '';
+ }
+)
diff --git a/pkgs/applications/networking/instant-messengers/pantalaimon/default.nix b/pkgs/applications/networking/instant-messengers/pantalaimon/default.nix
index 153819fc8417..9722d3b89e32 100644
--- a/pkgs/applications/networking/instant-messengers/pantalaimon/default.nix
+++ b/pkgs/applications/networking/instant-messengers/pantalaimon/default.nix
@@ -1,7 +1,7 @@
{ lib, stdenv, buildPythonApplication, fetchFromGitHub, pythonOlder,
attrs, aiohttp, appdirs, click, keyring, Logbook, peewee, janus,
prompt-toolkit, matrix-nio, dbus-python, pydbus, notify2, pygobject3,
- setuptools, installShellFiles,
+ setuptools, installShellFiles, nixosTests,
pytest, faker, pytest-aiohttp, aioresponses,
@@ -63,6 +63,10 @@ buildPythonApplication rec {
installManPage docs/man/*.[1-9]
'';
+ passthru.tests = {
+ inherit (nixosTests) pantalaimon;
+ };
+
meta = with lib; {
description = "An end-to-end encryption aware Matrix reverse proxy daemon";
homepage = "https://github.com/matrix-org/pantalaimon";
diff --git a/pkgs/servers/mjolnir/default.nix b/pkgs/servers/mjolnir/default.nix
new file mode 100644
index 000000000000..f6444ef386ac
--- /dev/null
+++ b/pkgs/servers/mjolnir/default.nix
@@ -0,0 +1,86 @@
+{ lib
+, nixosTests
+, stdenv
+, fetchFromGitHub
+, makeWrapper
+, nodejs
+, pkgs
+}:
+
+stdenv.mkDerivation rec {
+ pname = "mjolnir";
+ version = "1.1.20";
+
+ src = fetchFromGitHub {
+ owner = "matrix-org";
+ repo = "mjolnir";
+ rev = "v${version}";
+ sha256 = "yfMBnNriSpwitR4u664iz+8uWp/3iSTymyFajMBP5xg=";
+ };
+
+ nativeBuildInputs = [
+ nodejs
+ makeWrapper
+ ];
+
+ buildPhase =
+ let
+ nodeDependencies = ((import ./node-composition.nix {
+ inherit pkgs nodejs;
+ inherit (stdenv.hostPlatform) system;
+ }).nodeDependencies.override (old: {
+ # access to path '/nix/store/...-source' is forbidden in restricted mode
+ src = src;
+ dontNpmInstall = true;
+ }));
+ in
+ ''
+ runHook preBuild
+
+ ln -s ${nodeDependencies}/lib/node_modules .
+ export PATH="${nodeDependencies}/bin:$PATH"
+ npm run build
+
+ runHook postBuild
+ '';
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p $out/share
+ cp -a . $out/share/mjolnir
+
+ makeWrapper ${nodejs}/bin/node $out/bin/mjolnir \
+ --add-flags $out/share/mjolnir/lib/index.js
+
+ runHook postInstall
+ '';
+
+ passthru = {
+ tests = {
+ inherit (nixosTests) mjolnir;
+ };
+ updateScript = ./update.sh;
+ };
+
+ meta = with lib; {
+ description = "A moderation tool for Matrix";
+ homepage = "https://github.com/matrix-org/mjolnir";
+ longDescription = ''
+ As an all-in-one moderation tool, it can protect your server from
+ malicious invites, spam messages, and whatever else you don't want.
+ In addition to server-level protection, Mjolnir is great for communities
+ wanting to protect their rooms without having to use their personal
+ accounts for moderation.
+
+ The bot by default includes support for bans, redactions, anti-spam,
+ server ACLs, room directory changes, room alias transfers, account
+ deactivation, room shutdown, and more.
+
+ A Synapse module is also available to apply the same rulesets the bot
+ uses across an entire homeserver.
+ '';
+ license = licenses.asl20;
+ maintainers = with maintainers; [ jojosch ];
+ };
+}
diff --git a/pkgs/servers/mjolnir/node-composition.nix b/pkgs/servers/mjolnir/node-composition.nix
new file mode 100644
index 000000000000..ef810f1b06e7
--- /dev/null
+++ b/pkgs/servers/mjolnir/node-composition.nix
@@ -0,0 +1,17 @@
+# This file has been generated by node2nix 1.9.0. Do not edit!
+
+{pkgs ? import {
+ inherit system;
+ }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-12_x"}:
+
+let
+ nodeEnv = import ./node-env.nix {
+ inherit (pkgs) stdenv lib python2 runCommand writeTextFile;
+ inherit pkgs nodejs;
+ libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
+ };
+in
+import ./node-deps.nix {
+ inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit;
+ inherit nodeEnv;
+}
diff --git a/pkgs/servers/mjolnir/node-deps.nix b/pkgs/servers/mjolnir/node-deps.nix
new file mode 100644
index 000000000000..30c8a33277e4
--- /dev/null
+++ b/pkgs/servers/mjolnir/node-deps.nix
@@ -0,0 +1,3037 @@
+# This file has been generated by node2nix 1.9.0. Do not edit!
+
+{nodeEnv, fetchurl, fetchgit, nix-gitignore, stdenv, lib, globalBuildInputs ? []}:
+
+let
+ sources = {
+ "@babel/code-frame-7.14.5" = {
+ name = "_at_babel_slash_code-frame";
+ packageName = "@babel/code-frame";
+ version = "7.14.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz";
+ sha512 = "9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==";
+ };
+ };
+ "@babel/helper-validator-identifier-7.15.7" = {
+ name = "_at_babel_slash_helper-validator-identifier";
+ packageName = "@babel/helper-validator-identifier";
+ version = "7.15.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz";
+ sha512 = "K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==";
+ };
+ };
+ "@babel/highlight-7.14.5" = {
+ name = "_at_babel_slash_highlight";
+ packageName = "@babel/highlight";
+ version = "7.14.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz";
+ sha512 = "qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==";
+ };
+ };
+ "@jest/types-27.1.1" = {
+ name = "_at_jest_slash_types";
+ packageName = "@jest/types";
+ version = "27.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@jest/types/-/types-27.1.1.tgz";
+ sha512 = "yqJPDDseb0mXgKqmNqypCsb85C22K1aY5+LUxh7syIM9n/b0AsaltxNy+o6tt29VcfGDpYEve175bm3uOhcehA==";
+ };
+ };
+ "@types/body-parser-1.19.1" = {
+ name = "_at_types_slash_body-parser";
+ packageName = "@types/body-parser";
+ version = "1.19.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz";
+ sha512 = "a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==";
+ };
+ };
+ "@types/connect-3.4.35" = {
+ name = "_at_types_slash_connect";
+ packageName = "@types/connect";
+ version = "3.4.35";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz";
+ sha512 = "cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==";
+ };
+ };
+ "@types/express-4.17.13" = {
+ name = "_at_types_slash_express";
+ packageName = "@types/express";
+ version = "4.17.13";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz";
+ sha512 = "6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==";
+ };
+ };
+ "@types/express-serve-static-core-4.17.24" = {
+ name = "_at_types_slash_express-serve-static-core";
+ packageName = "@types/express-serve-static-core";
+ version = "4.17.24";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz";
+ sha512 = "3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==";
+ };
+ };
+ "@types/istanbul-lib-coverage-2.0.3" = {
+ name = "_at_types_slash_istanbul-lib-coverage";
+ packageName = "@types/istanbul-lib-coverage";
+ version = "2.0.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz";
+ sha512 = "sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==";
+ };
+ };
+ "@types/istanbul-lib-report-3.0.0" = {
+ name = "_at_types_slash_istanbul-lib-report";
+ packageName = "@types/istanbul-lib-report";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz";
+ sha512 = "plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==";
+ };
+ };
+ "@types/istanbul-reports-3.0.1" = {
+ name = "_at_types_slash_istanbul-reports";
+ packageName = "@types/istanbul-reports";
+ version = "3.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz";
+ sha512 = "c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==";
+ };
+ };
+ "@types/json5-0.0.29" = {
+ name = "_at_types_slash_json5";
+ packageName = "@types/json5";
+ version = "0.0.29";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz";
+ sha1 = "ee28707ae94e11d2b827bcbe5270bcea7f3e71ee";
+ };
+ };
+ "@types/mime-1.3.2" = {
+ name = "_at_types_slash_mime";
+ packageName = "@types/mime";
+ version = "1.3.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz";
+ sha512 = "YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==";
+ };
+ };
+ "@types/mocha-9.0.0" = {
+ name = "_at_types_slash_mocha";
+ packageName = "@types/mocha";
+ version = "9.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz";
+ sha512 = "scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==";
+ };
+ };
+ "@types/node-11.15.54" = {
+ name = "_at_types_slash_node";
+ packageName = "@types/node";
+ version = "11.15.54";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/node/-/node-11.15.54.tgz";
+ sha512 = "1RWYiq+5UfozGsU6MwJyFX6BtktcT10XRjvcAQmskCtMcW3tPske88lM/nHv7BQG1w9KBXI1zPGuu5PnNCX14g==";
+ };
+ };
+ "@types/qs-6.9.7" = {
+ name = "_at_types_slash_qs";
+ packageName = "@types/qs";
+ version = "6.9.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz";
+ sha512 = "FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==";
+ };
+ };
+ "@types/range-parser-1.2.4" = {
+ name = "_at_types_slash_range-parser";
+ packageName = "@types/range-parser";
+ version = "1.2.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz";
+ sha512 = "EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==";
+ };
+ };
+ "@types/serve-static-1.13.10" = {
+ name = "_at_types_slash_serve-static";
+ packageName = "@types/serve-static";
+ version = "1.13.10";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz";
+ sha512 = "nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==";
+ };
+ };
+ "@types/stack-utils-2.0.1" = {
+ name = "_at_types_slash_stack-utils";
+ packageName = "@types/stack-utils";
+ version = "2.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz";
+ sha512 = "Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==";
+ };
+ };
+ "@types/yargs-16.0.4" = {
+ name = "_at_types_slash_yargs";
+ packageName = "@types/yargs";
+ version = "16.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz";
+ sha512 = "T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==";
+ };
+ };
+ "@types/yargs-parser-20.2.1" = {
+ name = "_at_types_slash_yargs-parser";
+ packageName = "@types/yargs-parser";
+ version = "20.2.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz";
+ sha512 = "7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==";
+ };
+ };
+ "@ungap/promise-all-settled-1.1.2" = {
+ name = "_at_ungap_slash_promise-all-settled";
+ packageName = "@ungap/promise-all-settled";
+ version = "1.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz";
+ sha512 = "sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==";
+ };
+ };
+ "accepts-1.3.7" = {
+ name = "accepts";
+ packageName = "accepts";
+ version = "1.3.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz";
+ sha512 = "Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==";
+ };
+ };
+ "ajv-6.12.6" = {
+ name = "ajv";
+ packageName = "ajv";
+ version = "6.12.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz";
+ sha512 = "j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==";
+ };
+ };
+ "ansi-colors-4.1.1" = {
+ name = "ansi-colors";
+ packageName = "ansi-colors";
+ version = "4.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz";
+ sha512 = "JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==";
+ };
+ };
+ "ansi-regex-3.0.0" = {
+ name = "ansi-regex";
+ packageName = "ansi-regex";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz";
+ sha1 = "ed0317c322064f79466c02966bddb605ab37d998";
+ };
+ };
+ "ansi-regex-5.0.1" = {
+ name = "ansi-regex";
+ packageName = "ansi-regex";
+ version = "5.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz";
+ sha512 = "quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==";
+ };
+ };
+ "ansi-styles-3.2.1" = {
+ name = "ansi-styles";
+ packageName = "ansi-styles";
+ version = "3.2.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz";
+ sha512 = "VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==";
+ };
+ };
+ "ansi-styles-4.3.0" = {
+ name = "ansi-styles";
+ packageName = "ansi-styles";
+ version = "4.3.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz";
+ sha512 = "zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==";
+ };
+ };
+ "ansi-styles-5.2.0" = {
+ name = "ansi-styles";
+ packageName = "ansi-styles";
+ version = "5.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz";
+ sha512 = "Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==";
+ };
+ };
+ "anymatch-3.1.2" = {
+ name = "anymatch";
+ packageName = "anymatch";
+ version = "3.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz";
+ sha512 = "P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==";
+ };
+ };
+ "argparse-1.0.10" = {
+ name = "argparse";
+ packageName = "argparse";
+ version = "1.0.10";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz";
+ sha512 = "o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==";
+ };
+ };
+ "argparse-2.0.1" = {
+ name = "argparse";
+ packageName = "argparse";
+ version = "2.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz";
+ sha512 = "8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==";
+ };
+ };
+ "array-flatten-1.1.1" = {
+ name = "array-flatten";
+ packageName = "array-flatten";
+ version = "1.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz";
+ sha1 = "9a5f699051b1e7073328f2a008968b64ea2955d2";
+ };
+ };
+ "arrify-1.0.1" = {
+ name = "arrify";
+ packageName = "arrify";
+ version = "1.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz";
+ sha1 = "898508da2226f380df904728456849c1501a4b0d";
+ };
+ };
+ "asn1-0.2.4" = {
+ name = "asn1";
+ packageName = "asn1";
+ version = "0.2.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz";
+ sha512 = "jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==";
+ };
+ };
+ "assert-plus-1.0.0" = {
+ name = "assert-plus";
+ packageName = "assert-plus";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz";
+ sha1 = "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525";
+ };
+ };
+ "asynckit-0.4.0" = {
+ name = "asynckit";
+ packageName = "asynckit";
+ version = "0.4.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz";
+ sha1 = "c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79";
+ };
+ };
+ "aws-sign2-0.7.0" = {
+ name = "aws-sign2";
+ packageName = "aws-sign2";
+ version = "0.7.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz";
+ sha1 = "b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8";
+ };
+ };
+ "aws4-1.11.0" = {
+ name = "aws4";
+ packageName = "aws4";
+ version = "1.11.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz";
+ sha512 = "xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==";
+ };
+ };
+ "balanced-match-1.0.2" = {
+ name = "balanced-match";
+ packageName = "balanced-match";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz";
+ sha512 = "3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==";
+ };
+ };
+ "basic-auth-2.0.1" = {
+ name = "basic-auth";
+ packageName = "basic-auth";
+ version = "2.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz";
+ sha512 = "NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==";
+ };
+ };
+ "bcrypt-pbkdf-1.0.2" = {
+ name = "bcrypt-pbkdf";
+ packageName = "bcrypt-pbkdf";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz";
+ sha1 = "a4301d389b6a43f9b67ff3ca11a3f6637e360e9e";
+ };
+ };
+ "binary-extensions-2.2.0" = {
+ name = "binary-extensions";
+ packageName = "binary-extensions";
+ version = "2.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz";
+ sha512 = "jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==";
+ };
+ };
+ "bluebird-3.7.2" = {
+ name = "bluebird";
+ packageName = "bluebird";
+ version = "3.7.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz";
+ sha512 = "XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==";
+ };
+ };
+ "body-parser-1.19.0" = {
+ name = "body-parser";
+ packageName = "body-parser";
+ version = "1.19.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz";
+ sha512 = "dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==";
+ };
+ };
+ "brace-expansion-1.1.11" = {
+ name = "brace-expansion";
+ packageName = "brace-expansion";
+ version = "1.1.11";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz";
+ sha512 = "iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==";
+ };
+ };
+ "braces-3.0.2" = {
+ name = "braces";
+ packageName = "braces";
+ version = "3.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz";
+ sha512 = "b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==";
+ };
+ };
+ "browser-stdout-1.3.1" = {
+ name = "browser-stdout";
+ packageName = "browser-stdout";
+ version = "1.3.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz";
+ sha512 = "qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==";
+ };
+ };
+ "buffer-from-1.1.2" = {
+ name = "buffer-from";
+ packageName = "buffer-from";
+ version = "1.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz";
+ sha512 = "E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==";
+ };
+ };
+ "builtin-modules-1.1.1" = {
+ name = "builtin-modules";
+ packageName = "builtin-modules";
+ version = "1.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz";
+ sha1 = "270f076c5a72c02f5b65a47df94c5fe3a278892f";
+ };
+ };
+ "bytes-3.1.0" = {
+ name = "bytes";
+ packageName = "bytes";
+ version = "3.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz";
+ sha512 = "zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==";
+ };
+ };
+ "camelcase-6.2.0" = {
+ name = "camelcase";
+ packageName = "camelcase";
+ version = "6.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz";
+ sha512 = "c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==";
+ };
+ };
+ "caseless-0.12.0" = {
+ name = "caseless";
+ packageName = "caseless";
+ version = "0.12.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz";
+ sha1 = "1b681c21ff84033c826543090689420d187151dc";
+ };
+ };
+ "chalk-2.4.2" = {
+ name = "chalk";
+ packageName = "chalk";
+ version = "2.4.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz";
+ sha512 = "Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==";
+ };
+ };
+ "chalk-4.1.2" = {
+ name = "chalk";
+ packageName = "chalk";
+ version = "4.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz";
+ sha512 = "oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==";
+ };
+ };
+ "chokidar-3.5.2" = {
+ name = "chokidar";
+ packageName = "chokidar";
+ version = "3.5.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz";
+ sha512 = "ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==";
+ };
+ };
+ "cliui-7.0.4" = {
+ name = "cliui";
+ packageName = "cliui";
+ version = "7.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz";
+ sha512 = "OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==";
+ };
+ };
+ "color-convert-1.9.3" = {
+ name = "color-convert";
+ packageName = "color-convert";
+ version = "1.9.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz";
+ sha512 = "QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==";
+ };
+ };
+ "color-convert-2.0.1" = {
+ name = "color-convert";
+ packageName = "color-convert";
+ version = "2.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz";
+ sha512 = "RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==";
+ };
+ };
+ "color-name-1.1.3" = {
+ name = "color-name";
+ packageName = "color-name";
+ version = "1.1.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz";
+ sha1 = "a7d0558bd89c42f795dd42328f740831ca53bc25";
+ };
+ };
+ "color-name-1.1.4" = {
+ name = "color-name";
+ packageName = "color-name";
+ version = "1.1.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz";
+ sha512 = "dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==";
+ };
+ };
+ "colorette-1.4.0" = {
+ name = "colorette";
+ packageName = "colorette";
+ version = "1.4.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz";
+ sha512 = "Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==";
+ };
+ };
+ "combined-stream-1.0.8" = {
+ name = "combined-stream";
+ packageName = "combined-stream";
+ version = "1.0.8";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz";
+ sha512 = "FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==";
+ };
+ };
+ "commander-2.20.3" = {
+ name = "commander";
+ packageName = "commander";
+ version = "2.20.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz";
+ sha512 = "GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==";
+ };
+ };
+ "concat-map-0.0.1" = {
+ name = "concat-map";
+ packageName = "concat-map";
+ version = "0.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz";
+ sha1 = "d8a96bd77fd68df7793a73036a3ba0d5405d477b";
+ };
+ };
+ "config-3.3.6" = {
+ name = "config";
+ packageName = "config";
+ version = "3.3.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/config/-/config-3.3.6.tgz";
+ sha512 = "Hj5916C5HFawjYJat1epbyY2PlAgLpBtDUlr0MxGLgo3p5+7kylyvnRY18PqJHgnNWXcdd0eWDemT7eYWuFgwg==";
+ };
+ };
+ "content-disposition-0.5.3" = {
+ name = "content-disposition";
+ packageName = "content-disposition";
+ version = "0.5.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz";
+ sha512 = "ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==";
+ };
+ };
+ "content-type-1.0.4" = {
+ name = "content-type";
+ packageName = "content-type";
+ version = "1.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz";
+ sha512 = "hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==";
+ };
+ };
+ "cookie-0.4.0" = {
+ name = "cookie";
+ packageName = "cookie";
+ version = "0.4.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz";
+ sha512 = "+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==";
+ };
+ };
+ "cookie-signature-1.0.6" = {
+ name = "cookie-signature";
+ packageName = "cookie-signature";
+ version = "1.0.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz";
+ sha1 = "e303a882b342cc3ee8ca513a79999734dab3ae2c";
+ };
+ };
+ "core-util-is-1.0.2" = {
+ name = "core-util-is";
+ packageName = "core-util-is";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz";
+ sha1 = "b5fd54220aa2bc5ab57aab7140c940754503c1a7";
+ };
+ };
+ "dashdash-1.14.1" = {
+ name = "dashdash";
+ packageName = "dashdash";
+ version = "1.14.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz";
+ sha1 = "853cfa0f7cbe2fed5de20326b8dd581035f6e2f0";
+ };
+ };
+ "debug-2.6.9" = {
+ name = "debug";
+ packageName = "debug";
+ version = "2.6.9";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz";
+ sha512 = "bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==";
+ };
+ };
+ "debug-4.3.1" = {
+ name = "debug";
+ packageName = "debug";
+ version = "4.3.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz";
+ sha512 = "doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==";
+ };
+ };
+ "decamelize-4.0.0" = {
+ name = "decamelize";
+ packageName = "decamelize";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz";
+ sha512 = "9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==";
+ };
+ };
+ "deepmerge-4.2.2" = {
+ name = "deepmerge";
+ packageName = "deepmerge";
+ version = "4.2.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz";
+ sha512 = "FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==";
+ };
+ };
+ "delayed-stream-1.0.0" = {
+ name = "delayed-stream";
+ packageName = "delayed-stream";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz";
+ sha1 = "df3ae199acadfb7d440aaae0b29e2272b24ec619";
+ };
+ };
+ "depd-1.1.2" = {
+ name = "depd";
+ packageName = "depd";
+ version = "1.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz";
+ sha1 = "9bcd52e14c097763e749b274c4346ed2e560b5a9";
+ };
+ };
+ "depd-2.0.0" = {
+ name = "depd";
+ packageName = "depd";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz";
+ sha512 = "g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==";
+ };
+ };
+ "destroy-1.0.4" = {
+ name = "destroy";
+ packageName = "destroy";
+ version = "1.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz";
+ sha1 = "978857442c44749e4206613e37946205826abd80";
+ };
+ };
+ "diff-3.5.0" = {
+ name = "diff";
+ packageName = "diff";
+ version = "3.5.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz";
+ sha512 = "A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==";
+ };
+ };
+ "diff-4.0.2" = {
+ name = "diff";
+ packageName = "diff";
+ version = "4.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz";
+ sha512 = "58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==";
+ };
+ };
+ "diff-5.0.0" = {
+ name = "diff";
+ packageName = "diff";
+ version = "5.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz";
+ sha512 = "/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==";
+ };
+ };
+ "diff-sequences-27.0.6" = {
+ name = "diff-sequences";
+ packageName = "diff-sequences";
+ version = "27.0.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz";
+ sha512 = "ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==";
+ };
+ };
+ "dom-serializer-1.3.2" = {
+ name = "dom-serializer";
+ packageName = "dom-serializer";
+ version = "1.3.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz";
+ sha512 = "5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==";
+ };
+ };
+ "domelementtype-2.2.0" = {
+ name = "domelementtype";
+ packageName = "domelementtype";
+ version = "2.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz";
+ sha512 = "DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==";
+ };
+ };
+ "domhandler-3.3.0" = {
+ name = "domhandler";
+ packageName = "domhandler";
+ version = "3.3.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz";
+ sha512 = "J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==";
+ };
+ };
+ "domhandler-4.2.2" = {
+ name = "domhandler";
+ packageName = "domhandler";
+ version = "4.2.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz";
+ sha512 = "PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==";
+ };
+ };
+ "domutils-2.8.0" = {
+ name = "domutils";
+ packageName = "domutils";
+ version = "2.8.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz";
+ sha512 = "w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==";
+ };
+ };
+ "ecc-jsbn-0.1.2" = {
+ name = "ecc-jsbn";
+ packageName = "ecc-jsbn";
+ version = "0.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz";
+ sha1 = "3a83a904e54353287874c564b7549386849a98c9";
+ };
+ };
+ "ee-first-1.1.1" = {
+ name = "ee-first";
+ packageName = "ee-first";
+ version = "1.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz";
+ sha1 = "590c61156b0ae2f4f0255732a158b266bc56b21d";
+ };
+ };
+ "emoji-regex-8.0.0" = {
+ name = "emoji-regex";
+ packageName = "emoji-regex";
+ version = "8.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz";
+ sha512 = "MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==";
+ };
+ };
+ "encodeurl-1.0.2" = {
+ name = "encodeurl";
+ packageName = "encodeurl";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz";
+ sha1 = "ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59";
+ };
+ };
+ "entities-2.2.0" = {
+ name = "entities";
+ packageName = "entities";
+ version = "2.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz";
+ sha512 = "p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==";
+ };
+ };
+ "escalade-3.1.1" = {
+ name = "escalade";
+ packageName = "escalade";
+ version = "3.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz";
+ sha512 = "k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==";
+ };
+ };
+ "escape-html-1.0.3" = {
+ name = "escape-html";
+ packageName = "escape-html";
+ version = "1.0.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz";
+ sha1 = "0258eae4d3d0c0974de1c169188ef0051d1d1988";
+ };
+ };
+ "escape-string-regexp-1.0.5" = {
+ name = "escape-string-regexp";
+ packageName = "escape-string-regexp";
+ version = "1.0.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz";
+ sha1 = "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4";
+ };
+ };
+ "escape-string-regexp-2.0.0" = {
+ name = "escape-string-regexp";
+ packageName = "escape-string-regexp";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz";
+ sha512 = "UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==";
+ };
+ };
+ "escape-string-regexp-4.0.0" = {
+ name = "escape-string-regexp";
+ packageName = "escape-string-regexp";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz";
+ sha512 = "TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==";
+ };
+ };
+ "esprima-4.0.1" = {
+ name = "esprima";
+ packageName = "esprima";
+ version = "4.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz";
+ sha512 = "eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==";
+ };
+ };
+ "etag-1.8.1" = {
+ name = "etag";
+ packageName = "etag";
+ version = "1.8.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz";
+ sha1 = "41ae2eeb65efa62268aebfea83ac7d79299b0887";
+ };
+ };
+ "expect-27.2.1" = {
+ name = "expect";
+ packageName = "expect";
+ version = "27.2.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/expect/-/expect-27.2.1.tgz";
+ sha512 = "ekOA2mBtT2phxcoPVHCXIzbJxCvRXhx2fr7m28IgGdZxUOh8UvxvoRz1FcPlfgZMpE92biHB6woIcAKXqR28hA==";
+ };
+ };
+ "express-4.17.1" = {
+ name = "express";
+ packageName = "express";
+ version = "4.17.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/express/-/express-4.17.1.tgz";
+ sha512 = "mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==";
+ };
+ };
+ "extend-3.0.2" = {
+ name = "extend";
+ packageName = "extend";
+ version = "3.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz";
+ sha512 = "fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==";
+ };
+ };
+ "extsprintf-1.3.0" = {
+ name = "extsprintf";
+ packageName = "extsprintf";
+ version = "1.3.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz";
+ sha1 = "96918440e3041a7a414f8c52e3c574eb3c3e1e05";
+ };
+ };
+ "fast-deep-equal-3.1.3" = {
+ name = "fast-deep-equal";
+ packageName = "fast-deep-equal";
+ version = "3.1.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz";
+ sha512 = "f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==";
+ };
+ };
+ "fast-json-stable-stringify-2.1.0" = {
+ name = "fast-json-stable-stringify";
+ packageName = "fast-json-stable-stringify";
+ version = "2.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz";
+ sha512 = "lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==";
+ };
+ };
+ "fill-range-7.0.1" = {
+ name = "fill-range";
+ packageName = "fill-range";
+ version = "7.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz";
+ sha512 = "qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==";
+ };
+ };
+ "finalhandler-1.1.2" = {
+ name = "finalhandler";
+ packageName = "finalhandler";
+ version = "1.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz";
+ sha512 = "aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==";
+ };
+ };
+ "find-up-5.0.0" = {
+ name = "find-up";
+ packageName = "find-up";
+ version = "5.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz";
+ sha512 = "78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==";
+ };
+ };
+ "flat-5.0.2" = {
+ name = "flat";
+ packageName = "flat";
+ version = "5.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz";
+ sha512 = "b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==";
+ };
+ };
+ "forever-agent-0.6.1" = {
+ name = "forever-agent";
+ packageName = "forever-agent";
+ version = "0.6.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz";
+ sha1 = "fbc71f0c41adeb37f96c577ad1ed42d8fdacca91";
+ };
+ };
+ "form-data-2.3.3" = {
+ name = "form-data";
+ packageName = "form-data";
+ version = "2.3.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz";
+ sha512 = "1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==";
+ };
+ };
+ "forwarded-0.2.0" = {
+ name = "forwarded";
+ packageName = "forwarded";
+ version = "0.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz";
+ sha512 = "buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==";
+ };
+ };
+ "fresh-0.5.2" = {
+ name = "fresh";
+ packageName = "fresh";
+ version = "0.5.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz";
+ sha1 = "3d8cadd90d976569fa835ab1f8e4b23a105605a7";
+ };
+ };
+ "fs.realpath-1.0.0" = {
+ name = "fs.realpath";
+ packageName = "fs.realpath";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz";
+ sha1 = "1504ad2523158caa40db4a2787cb01411994ea4f";
+ };
+ };
+ "fsevents-2.3.2" = {
+ name = "fsevents";
+ packageName = "fsevents";
+ version = "2.3.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz";
+ sha512 = "xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==";
+ };
+ };
+ "function-bind-1.1.1" = {
+ name = "function-bind";
+ packageName = "function-bind";
+ version = "1.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz";
+ sha512 = "yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==";
+ };
+ };
+ "get-caller-file-2.0.5" = {
+ name = "get-caller-file";
+ packageName = "get-caller-file";
+ version = "2.0.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz";
+ sha512 = "DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==";
+ };
+ };
+ "getpass-0.1.7" = {
+ name = "getpass";
+ packageName = "getpass";
+ version = "0.1.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz";
+ sha1 = "5eff8e3e684d569ae4cb2b1282604e8ba62149fa";
+ };
+ };
+ "glob-7.1.7" = {
+ name = "glob";
+ packageName = "glob";
+ version = "7.1.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz";
+ sha512 = "OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==";
+ };
+ };
+ "glob-parent-5.1.2" = {
+ name = "glob-parent";
+ packageName = "glob-parent";
+ version = "5.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz";
+ sha512 = "AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==";
+ };
+ };
+ "glob-to-regexp-0.4.1" = {
+ name = "glob-to-regexp";
+ packageName = "glob-to-regexp";
+ version = "0.4.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz";
+ sha512 = "lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==";
+ };
+ };
+ "graceful-fs-4.2.8" = {
+ name = "graceful-fs";
+ packageName = "graceful-fs";
+ version = "4.2.8";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz";
+ sha512 = "qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==";
+ };
+ };
+ "growl-1.10.5" = {
+ name = "growl";
+ packageName = "growl";
+ version = "1.10.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz";
+ sha512 = "qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==";
+ };
+ };
+ "har-schema-2.0.0" = {
+ name = "har-schema";
+ packageName = "har-schema";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz";
+ sha1 = "a94c2224ebcac04782a0d9035521f24735b7ec92";
+ };
+ };
+ "har-validator-5.1.5" = {
+ name = "har-validator";
+ packageName = "har-validator";
+ version = "5.1.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz";
+ sha512 = "nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==";
+ };
+ };
+ "has-1.0.3" = {
+ name = "has";
+ packageName = "has";
+ version = "1.0.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/has/-/has-1.0.3.tgz";
+ sha512 = "f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==";
+ };
+ };
+ "has-flag-3.0.0" = {
+ name = "has-flag";
+ packageName = "has-flag";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz";
+ sha1 = "b5d454dc2199ae225699f3467e5a07f3b955bafd";
+ };
+ };
+ "has-flag-4.0.0" = {
+ name = "has-flag";
+ packageName = "has-flag";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz";
+ sha512 = "EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==";
+ };
+ };
+ "hash.js-1.1.7" = {
+ name = "hash.js";
+ packageName = "hash.js";
+ version = "1.1.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz";
+ sha512 = "taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==";
+ };
+ };
+ "he-1.2.0" = {
+ name = "he";
+ packageName = "he";
+ version = "1.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/he/-/he-1.2.0.tgz";
+ sha512 = "F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==";
+ };
+ };
+ "html-to-text-6.0.0" = {
+ name = "html-to-text";
+ packageName = "html-to-text";
+ version = "6.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/html-to-text/-/html-to-text-6.0.0.tgz";
+ sha512 = "r0KNC5aqCAItsjlgtirW6RW25c92Ee3ybQj8z//4Sl4suE3HIPqM4deGpYCUJULLjtVPEP1+Ma+1ZeX1iMsCiA==";
+ };
+ };
+ "htmlencode-0.0.4" = {
+ name = "htmlencode";
+ packageName = "htmlencode";
+ version = "0.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/htmlencode/-/htmlencode-0.0.4.tgz";
+ sha1 = "f7e2d6afbe18a87a78e63ba3308e753766740e3f";
+ };
+ };
+ "htmlparser2-4.1.0" = {
+ name = "htmlparser2";
+ packageName = "htmlparser2";
+ version = "4.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz";
+ sha512 = "4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==";
+ };
+ };
+ "htmlparser2-6.1.0" = {
+ name = "htmlparser2";
+ packageName = "htmlparser2";
+ version = "6.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz";
+ sha512 = "gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==";
+ };
+ };
+ "http-errors-1.7.2" = {
+ name = "http-errors";
+ packageName = "http-errors";
+ version = "1.7.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz";
+ sha512 = "uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==";
+ };
+ };
+ "http-signature-1.2.0" = {
+ name = "http-signature";
+ packageName = "http-signature";
+ version = "1.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz";
+ sha1 = "9aecd925114772f3d95b65a60abb8f7c18fbace1";
+ };
+ };
+ "iconv-lite-0.4.24" = {
+ name = "iconv-lite";
+ packageName = "iconv-lite";
+ version = "0.4.24";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz";
+ sha512 = "v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==";
+ };
+ };
+ "inflight-1.0.6" = {
+ name = "inflight";
+ packageName = "inflight";
+ version = "1.0.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz";
+ sha1 = "49bd6331d7d02d0c09bc910a1075ba8165b56df9";
+ };
+ };
+ "inherits-2.0.3" = {
+ name = "inherits";
+ packageName = "inherits";
+ version = "2.0.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz";
+ sha1 = "633c2c83e3da42a502f52466022480f4208261de";
+ };
+ };
+ "ipaddr.js-1.9.1" = {
+ name = "ipaddr.js";
+ packageName = "ipaddr.js";
+ version = "1.9.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz";
+ sha512 = "0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==";
+ };
+ };
+ "is-binary-path-2.1.0" = {
+ name = "is-binary-path";
+ packageName = "is-binary-path";
+ version = "2.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz";
+ sha512 = "ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==";
+ };
+ };
+ "is-core-module-2.6.0" = {
+ name = "is-core-module";
+ packageName = "is-core-module";
+ version = "2.6.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz";
+ sha512 = "wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==";
+ };
+ };
+ "is-extglob-2.1.1" = {
+ name = "is-extglob";
+ packageName = "is-extglob";
+ version = "2.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz";
+ sha1 = "a88c02535791f02ed37c76a1b9ea9773c833f8c2";
+ };
+ };
+ "is-fullwidth-code-point-2.0.0" = {
+ name = "is-fullwidth-code-point";
+ packageName = "is-fullwidth-code-point";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz";
+ sha1 = "a3b30a5c4f199183167aaab93beefae3ddfb654f";
+ };
+ };
+ "is-fullwidth-code-point-3.0.0" = {
+ name = "is-fullwidth-code-point";
+ packageName = "is-fullwidth-code-point";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz";
+ sha512 = "zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==";
+ };
+ };
+ "is-glob-4.0.1" = {
+ name = "is-glob";
+ packageName = "is-glob";
+ version = "4.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz";
+ sha512 = "5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==";
+ };
+ };
+ "is-number-7.0.0" = {
+ name = "is-number";
+ packageName = "is-number";
+ version = "7.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz";
+ sha512 = "41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==";
+ };
+ };
+ "is-plain-obj-2.1.0" = {
+ name = "is-plain-obj";
+ packageName = "is-plain-obj";
+ version = "2.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz";
+ sha512 = "YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==";
+ };
+ };
+ "is-plain-object-5.0.0" = {
+ name = "is-plain-object";
+ packageName = "is-plain-object";
+ version = "5.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz";
+ sha512 = "VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==";
+ };
+ };
+ "is-promise-2.2.2" = {
+ name = "is-promise";
+ packageName = "is-promise";
+ version = "2.2.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz";
+ sha512 = "+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==";
+ };
+ };
+ "is-typedarray-1.0.0" = {
+ name = "is-typedarray";
+ packageName = "is-typedarray";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz";
+ sha1 = "e479c80858df0c1b11ddda6940f96011fcda4a9a";
+ };
+ };
+ "is-unicode-supported-0.1.0" = {
+ name = "is-unicode-supported";
+ packageName = "is-unicode-supported";
+ version = "0.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz";
+ sha512 = "knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==";
+ };
+ };
+ "isexe-2.0.0" = {
+ name = "isexe";
+ packageName = "isexe";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz";
+ sha1 = "e8fbf374dc556ff8947a10dcb0572d633f2cfa10";
+ };
+ };
+ "isstream-0.1.2" = {
+ name = "isstream";
+ packageName = "isstream";
+ version = "0.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz";
+ sha1 = "47e63f7af55afa6f92e1500e690eb8b8529c099a";
+ };
+ };
+ "jest-diff-27.2.0" = {
+ name = "jest-diff";
+ packageName = "jest-diff";
+ version = "27.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.0.tgz";
+ sha512 = "QSO9WC6btFYWtRJ3Hac0sRrkspf7B01mGrrQEiCW6TobtViJ9RWL0EmOs/WnBsZDsI/Y2IoSHZA2x6offu0sYw==";
+ };
+ };
+ "jest-get-type-27.0.6" = {
+ name = "jest-get-type";
+ packageName = "jest-get-type";
+ version = "27.0.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz";
+ sha512 = "XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==";
+ };
+ };
+ "jest-matcher-utils-27.2.0" = {
+ name = "jest-matcher-utils";
+ packageName = "jest-matcher-utils";
+ version = "27.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.0.tgz";
+ sha512 = "F+LG3iTwJ0gPjxBX6HCyrARFXq6jjiqhwBQeskkJQgSLeF1j6ui1RTV08SR7O51XTUhtc8zqpDj8iCG4RGmdKw==";
+ };
+ };
+ "jest-message-util-27.2.0" = {
+ name = "jest-message-util";
+ packageName = "jest-message-util";
+ version = "27.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.0.tgz";
+ sha512 = "y+sfT/94CiP8rKXgwCOzO1mUazIEdEhrLjuiu+RKmCP+8O/TJTSne9dqQRbFIHBtlR2+q7cddJlWGir8UATu5w==";
+ };
+ };
+ "jest-regex-util-27.0.6" = {
+ name = "jest-regex-util";
+ packageName = "jest-regex-util";
+ version = "27.0.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz";
+ sha512 = "SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==";
+ };
+ };
+ "js-tokens-4.0.0" = {
+ name = "js-tokens";
+ packageName = "js-tokens";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz";
+ sha512 = "RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==";
+ };
+ };
+ "js-yaml-3.14.1" = {
+ name = "js-yaml";
+ packageName = "js-yaml";
+ version = "3.14.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz";
+ sha512 = "okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==";
+ };
+ };
+ "js-yaml-4.1.0" = {
+ name = "js-yaml";
+ packageName = "js-yaml";
+ version = "4.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz";
+ sha512 = "wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==";
+ };
+ };
+ "jsbn-0.1.1" = {
+ name = "jsbn";
+ packageName = "jsbn";
+ version = "0.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz";
+ sha1 = "a5e654c2e5a2deb5f201d96cefbca80c0ef2f513";
+ };
+ };
+ "json-schema-0.2.3" = {
+ name = "json-schema";
+ packageName = "json-schema";
+ version = "0.2.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz";
+ sha1 = "b480c892e59a2f05954ce727bd3f2a4e882f9e13";
+ };
+ };
+ "json-schema-traverse-0.4.1" = {
+ name = "json-schema-traverse";
+ packageName = "json-schema-traverse";
+ version = "0.4.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz";
+ sha512 = "xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==";
+ };
+ };
+ "json-stringify-safe-5.0.1" = {
+ name = "json-stringify-safe";
+ packageName = "json-stringify-safe";
+ version = "5.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz";
+ sha1 = "1296a2d58fd45f19a0f6ce01d65701e2c735b6eb";
+ };
+ };
+ "json5-1.0.1" = {
+ name = "json5";
+ packageName = "json5";
+ version = "1.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz";
+ sha512 = "aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==";
+ };
+ };
+ "json5-2.2.0" = {
+ name = "json5";
+ packageName = "json5";
+ version = "2.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz";
+ sha512 = "f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==";
+ };
+ };
+ "jsprim-1.4.1" = {
+ name = "jsprim";
+ packageName = "jsprim";
+ version = "1.4.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz";
+ sha1 = "313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2";
+ };
+ };
+ "klona-2.0.4" = {
+ name = "klona";
+ packageName = "klona";
+ version = "2.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz";
+ sha512 = "ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==";
+ };
+ };
+ "locate-path-6.0.0" = {
+ name = "locate-path";
+ packageName = "locate-path";
+ version = "6.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz";
+ sha512 = "iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==";
+ };
+ };
+ "lodash-4.17.21" = {
+ name = "lodash";
+ packageName = "lodash";
+ version = "4.17.21";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz";
+ sha512 = "v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==";
+ };
+ };
+ "log-symbols-4.1.0" = {
+ name = "log-symbols";
+ packageName = "log-symbols";
+ version = "4.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz";
+ sha512 = "8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==";
+ };
+ };
+ "lowdb-1.0.0" = {
+ name = "lowdb";
+ packageName = "lowdb";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz";
+ sha512 = "2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==";
+ };
+ };
+ "lru-cache-6.0.0" = {
+ name = "lru-cache";
+ packageName = "lru-cache";
+ version = "6.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz";
+ sha512 = "Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==";
+ };
+ };
+ "make-error-1.3.6" = {
+ name = "make-error";
+ packageName = "make-error";
+ version = "1.3.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz";
+ sha512 = "s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==";
+ };
+ };
+ "matrix-bot-sdk-0.5.19" = {
+ name = "matrix-bot-sdk";
+ packageName = "matrix-bot-sdk";
+ version = "0.5.19";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/matrix-bot-sdk/-/matrix-bot-sdk-0.5.19.tgz";
+ sha512 = "RIPyvQPkOVp2yTKeDgp5rcn6z/DiKdHb6E8c69K+utai8ypRGtfDRj0PGqP+1XzqC9Wb1OFrESCUB5t0ffdC9g==";
+ };
+ };
+ "media-typer-0.3.0" = {
+ name = "media-typer";
+ packageName = "media-typer";
+ version = "0.3.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz";
+ sha1 = "8710d7af0aa626f8fffa1ce00168545263255748";
+ };
+ };
+ "merge-descriptors-1.0.1" = {
+ name = "merge-descriptors";
+ packageName = "merge-descriptors";
+ version = "1.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz";
+ sha1 = "b00aaa556dd8b44568150ec9d1b953f3f90cbb61";
+ };
+ };
+ "methods-1.1.2" = {
+ name = "methods";
+ packageName = "methods";
+ version = "1.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz";
+ sha1 = "5529a4d67654134edcc5266656835b0f851afcee";
+ };
+ };
+ "micromatch-4.0.4" = {
+ name = "micromatch";
+ packageName = "micromatch";
+ version = "4.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz";
+ sha512 = "pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==";
+ };
+ };
+ "mime-1.6.0" = {
+ name = "mime";
+ packageName = "mime";
+ version = "1.6.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz";
+ sha512 = "x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==";
+ };
+ };
+ "mime-db-1.49.0" = {
+ name = "mime-db";
+ packageName = "mime-db";
+ version = "1.49.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz";
+ sha512 = "CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==";
+ };
+ };
+ "mime-types-2.1.32" = {
+ name = "mime-types";
+ packageName = "mime-types";
+ version = "2.1.32";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz";
+ sha512 = "hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==";
+ };
+ };
+ "minimalistic-assert-1.0.1" = {
+ name = "minimalistic-assert";
+ packageName = "minimalistic-assert";
+ version = "1.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz";
+ sha512 = "UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==";
+ };
+ };
+ "minimatch-3.0.4" = {
+ name = "minimatch";
+ packageName = "minimatch";
+ version = "3.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz";
+ sha512 = "yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==";
+ };
+ };
+ "minimist-1.2.5" = {
+ name = "minimist";
+ packageName = "minimist";
+ version = "1.2.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz";
+ sha512 = "FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==";
+ };
+ };
+ "mkdirp-0.5.5" = {
+ name = "mkdirp";
+ packageName = "mkdirp";
+ version = "0.5.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz";
+ sha512 = "NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==";
+ };
+ };
+ "mkdirp-1.0.4" = {
+ name = "mkdirp";
+ packageName = "mkdirp";
+ version = "1.0.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz";
+ sha512 = "vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==";
+ };
+ };
+ "mocha-9.1.1" = {
+ name = "mocha";
+ packageName = "mocha";
+ version = "9.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz";
+ sha512 = "0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==";
+ };
+ };
+ "morgan-1.10.0" = {
+ name = "morgan";
+ packageName = "morgan";
+ version = "1.10.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz";
+ sha512 = "AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==";
+ };
+ };
+ "ms-2.0.0" = {
+ name = "ms";
+ packageName = "ms";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz";
+ sha1 = "5608aeadfc00be6c2901df5f9861788de0d597c8";
+ };
+ };
+ "ms-2.1.1" = {
+ name = "ms";
+ packageName = "ms";
+ version = "2.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz";
+ sha512 = "tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==";
+ };
+ };
+ "ms-2.1.2" = {
+ name = "ms";
+ packageName = "ms";
+ version = "2.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz";
+ sha512 = "sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==";
+ };
+ };
+ "ms-2.1.3" = {
+ name = "ms";
+ packageName = "ms";
+ version = "2.1.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz";
+ sha512 = "6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==";
+ };
+ };
+ "nanoid-3.1.23" = {
+ name = "nanoid";
+ packageName = "nanoid";
+ version = "3.1.23";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz";
+ sha512 = "FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==";
+ };
+ };
+ "nanoid-3.1.25" = {
+ name = "nanoid";
+ packageName = "nanoid";
+ version = "3.1.25";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz";
+ sha512 = "rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==";
+ };
+ };
+ "negotiator-0.6.2" = {
+ name = "negotiator";
+ packageName = "negotiator";
+ version = "0.6.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz";
+ sha512 = "hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==";
+ };
+ };
+ "normalize-path-3.0.0" = {
+ name = "normalize-path";
+ packageName = "normalize-path";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz";
+ sha512 = "6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==";
+ };
+ };
+ "oauth-sign-0.9.0" = {
+ name = "oauth-sign";
+ packageName = "oauth-sign";
+ version = "0.9.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz";
+ sha512 = "fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==";
+ };
+ };
+ "on-finished-2.3.0" = {
+ name = "on-finished";
+ packageName = "on-finished";
+ version = "2.3.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz";
+ sha1 = "20f1336481b083cd75337992a16971aa2d906947";
+ };
+ };
+ "on-headers-1.0.2" = {
+ name = "on-headers";
+ packageName = "on-headers";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz";
+ sha512 = "pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==";
+ };
+ };
+ "once-1.4.0" = {
+ name = "once";
+ packageName = "once";
+ version = "1.4.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/once/-/once-1.4.0.tgz";
+ sha1 = "583b1aa775961d4b113ac17d9c50baef9dd76bd1";
+ };
+ };
+ "p-limit-3.1.0" = {
+ name = "p-limit";
+ packageName = "p-limit";
+ version = "3.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz";
+ sha512 = "TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==";
+ };
+ };
+ "p-locate-5.0.0" = {
+ name = "p-locate";
+ packageName = "p-locate";
+ version = "5.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz";
+ sha512 = "LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==";
+ };
+ };
+ "parse-srcset-1.0.2" = {
+ name = "parse-srcset";
+ packageName = "parse-srcset";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz";
+ sha1 = "f2bd221f6cc970a938d88556abc589caaaa2bde1";
+ };
+ };
+ "parseurl-1.3.3" = {
+ name = "parseurl";
+ packageName = "parseurl";
+ version = "1.3.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz";
+ sha512 = "CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==";
+ };
+ };
+ "path-exists-4.0.0" = {
+ name = "path-exists";
+ packageName = "path-exists";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz";
+ sha512 = "ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==";
+ };
+ };
+ "path-is-absolute-1.0.1" = {
+ name = "path-is-absolute";
+ packageName = "path-is-absolute";
+ version = "1.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz";
+ sha1 = "174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f";
+ };
+ };
+ "path-parse-1.0.7" = {
+ name = "path-parse";
+ packageName = "path-parse";
+ version = "1.0.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz";
+ sha512 = "LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==";
+ };
+ };
+ "path-to-regexp-0.1.7" = {
+ name = "path-to-regexp";
+ packageName = "path-to-regexp";
+ version = "0.1.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz";
+ sha1 = "df604178005f522f15eb4490e7247a1bfaa67f8c";
+ };
+ };
+ "performance-now-2.1.0" = {
+ name = "performance-now";
+ packageName = "performance-now";
+ version = "2.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz";
+ sha1 = "6309f4e0e5fa913ec1c69307ae364b4b377c9e7b";
+ };
+ };
+ "picomatch-2.3.0" = {
+ name = "picomatch";
+ packageName = "picomatch";
+ version = "2.3.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz";
+ sha512 = "lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==";
+ };
+ };
+ "pify-3.0.0" = {
+ name = "pify";
+ packageName = "pify";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz";
+ sha1 = "e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176";
+ };
+ };
+ "postcss-8.3.6" = {
+ name = "postcss";
+ packageName = "postcss";
+ version = "8.3.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz";
+ sha512 = "wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==";
+ };
+ };
+ "pretty-format-27.2.0" = {
+ name = "pretty-format";
+ packageName = "pretty-format";
+ version = "27.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.0.tgz";
+ sha512 = "KyJdmgBkMscLqo8A7K77omgLx5PWPiXJswtTtFV7XgVZv2+qPk6UivpXXO+5k6ZEbWIbLoKdx1pZ6ldINzbwTA==";
+ };
+ };
+ "proxy-addr-2.0.7" = {
+ name = "proxy-addr";
+ packageName = "proxy-addr";
+ version = "2.0.7";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz";
+ sha512 = "llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==";
+ };
+ };
+ "psl-1.8.0" = {
+ name = "psl";
+ packageName = "psl";
+ version = "1.8.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz";
+ sha512 = "RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==";
+ };
+ };
+ "punycode-2.1.1" = {
+ name = "punycode";
+ packageName = "punycode";
+ version = "2.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz";
+ sha512 = "XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==";
+ };
+ };
+ "qs-6.5.2" = {
+ name = "qs";
+ packageName = "qs";
+ version = "6.5.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz";
+ sha512 = "N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==";
+ };
+ };
+ "qs-6.7.0" = {
+ name = "qs";
+ packageName = "qs";
+ version = "6.7.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz";
+ sha512 = "VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==";
+ };
+ };
+ "randombytes-2.1.0" = {
+ name = "randombytes";
+ packageName = "randombytes";
+ version = "2.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz";
+ sha512 = "vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==";
+ };
+ };
+ "range-parser-1.2.1" = {
+ name = "range-parser";
+ packageName = "range-parser";
+ version = "1.2.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz";
+ sha512 = "Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==";
+ };
+ };
+ "raw-body-2.4.0" = {
+ name = "raw-body";
+ packageName = "raw-body";
+ version = "2.4.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz";
+ sha512 = "4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==";
+ };
+ };
+ "react-is-17.0.2" = {
+ name = "react-is";
+ packageName = "react-is";
+ version = "17.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz";
+ sha512 = "w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==";
+ };
+ };
+ "readdirp-3.6.0" = {
+ name = "readdirp";
+ packageName = "readdirp";
+ version = "3.6.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz";
+ sha512 = "hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==";
+ };
+ };
+ "request-2.88.2" = {
+ name = "request";
+ packageName = "request";
+ version = "2.88.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/request/-/request-2.88.2.tgz";
+ sha512 = "MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==";
+ };
+ };
+ "request-promise-4.2.6" = {
+ name = "request-promise";
+ packageName = "request-promise";
+ version = "4.2.6";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz";
+ sha512 = "HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==";
+ };
+ };
+ "request-promise-core-1.1.4" = {
+ name = "request-promise-core";
+ packageName = "request-promise-core";
+ version = "1.1.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz";
+ sha512 = "TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==";
+ };
+ };
+ "require-directory-2.1.1" = {
+ name = "require-directory";
+ packageName = "require-directory";
+ version = "2.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz";
+ sha1 = "8c64ad5fd30dab1c976e2344ffe7f792a6a6df42";
+ };
+ };
+ "resolve-1.20.0" = {
+ name = "resolve";
+ packageName = "resolve";
+ version = "1.20.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz";
+ sha512 = "wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==";
+ };
+ };
+ "safe-buffer-5.1.2" = {
+ name = "safe-buffer";
+ packageName = "safe-buffer";
+ version = "5.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz";
+ sha512 = "Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==";
+ };
+ };
+ "safer-buffer-2.1.2" = {
+ name = "safer-buffer";
+ packageName = "safer-buffer";
+ version = "2.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz";
+ sha512 = "YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==";
+ };
+ };
+ "sanitize-html-2.5.1" = {
+ name = "sanitize-html";
+ packageName = "sanitize-html";
+ version = "2.5.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.5.1.tgz";
+ sha512 = "hUITPitQk+eFNLtr4dEkaaiAJndG2YE87IOpcfBSL1XdklWgwcNDJdr9Ppe8QKL/C3jFt1xH/Mbj20e0GZQOfg==";
+ };
+ };
+ "semver-5.7.1" = {
+ name = "semver";
+ packageName = "semver";
+ version = "5.7.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz";
+ sha512 = "sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==";
+ };
+ };
+ "send-0.17.1" = {
+ name = "send";
+ packageName = "send";
+ version = "0.17.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/send/-/send-0.17.1.tgz";
+ sha512 = "BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==";
+ };
+ };
+ "serialize-javascript-6.0.0" = {
+ name = "serialize-javascript";
+ packageName = "serialize-javascript";
+ version = "6.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz";
+ sha512 = "Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==";
+ };
+ };
+ "serve-static-1.14.1" = {
+ name = "serve-static";
+ packageName = "serve-static";
+ version = "1.14.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz";
+ sha512 = "JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==";
+ };
+ };
+ "setprototypeof-1.1.1" = {
+ name = "setprototypeof";
+ packageName = "setprototypeof";
+ version = "1.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz";
+ sha512 = "JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==";
+ };
+ };
+ "slash-3.0.0" = {
+ name = "slash";
+ packageName = "slash";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz";
+ sha512 = "g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==";
+ };
+ };
+ "source-map-0.6.1" = {
+ name = "source-map";
+ packageName = "source-map";
+ version = "0.6.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz";
+ sha512 = "UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==";
+ };
+ };
+ "source-map-js-0.6.2" = {
+ name = "source-map-js";
+ packageName = "source-map-js";
+ version = "0.6.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz";
+ sha512 = "/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==";
+ };
+ };
+ "source-map-support-0.5.20" = {
+ name = "source-map-support";
+ packageName = "source-map-support";
+ version = "0.5.20";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz";
+ sha512 = "n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==";
+ };
+ };
+ "sprintf-js-1.0.3" = {
+ name = "sprintf-js";
+ packageName = "sprintf-js";
+ version = "1.0.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz";
+ sha1 = "04e6926f662895354f3dd015203633b857297e2c";
+ };
+ };
+ "sshpk-1.16.1" = {
+ name = "sshpk";
+ packageName = "sshpk";
+ version = "1.16.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz";
+ sha512 = "HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==";
+ };
+ };
+ "stack-utils-2.0.5" = {
+ name = "stack-utils";
+ packageName = "stack-utils";
+ version = "2.0.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz";
+ sha512 = "xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==";
+ };
+ };
+ "statuses-1.5.0" = {
+ name = "statuses";
+ packageName = "statuses";
+ version = "1.5.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz";
+ sha1 = "161c7dac177659fd9811f43771fa99381478628c";
+ };
+ };
+ "stealthy-require-1.1.1" = {
+ name = "stealthy-require";
+ packageName = "stealthy-require";
+ version = "1.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz";
+ sha1 = "35b09875b4ff49f26a777e509b3090a3226bf24b";
+ };
+ };
+ "steno-0.4.4" = {
+ name = "steno";
+ packageName = "steno";
+ version = "0.4.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz";
+ sha1 = "071105bdfc286e6615c0403c27e9d7b5dcb855cb";
+ };
+ };
+ "string-width-2.1.1" = {
+ name = "string-width";
+ packageName = "string-width";
+ version = "2.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz";
+ sha512 = "nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==";
+ };
+ };
+ "string-width-4.2.2" = {
+ name = "string-width";
+ packageName = "string-width";
+ version = "4.2.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz";
+ sha512 = "XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==";
+ };
+ };
+ "strip-ansi-4.0.0" = {
+ name = "strip-ansi";
+ packageName = "strip-ansi";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz";
+ sha1 = "a8479022eb1ac368a871389b635262c505ee368f";
+ };
+ };
+ "strip-ansi-6.0.0" = {
+ name = "strip-ansi";
+ packageName = "strip-ansi";
+ version = "6.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz";
+ sha512 = "AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==";
+ };
+ };
+ "strip-bom-3.0.0" = {
+ name = "strip-bom";
+ packageName = "strip-bom";
+ version = "3.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz";
+ sha1 = "2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3";
+ };
+ };
+ "strip-json-comments-3.1.1" = {
+ name = "strip-json-comments";
+ packageName = "strip-json-comments";
+ version = "3.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz";
+ sha512 = "6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==";
+ };
+ };
+ "supports-color-5.5.0" = {
+ name = "supports-color";
+ packageName = "supports-color";
+ version = "5.5.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz";
+ sha512 = "QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==";
+ };
+ };
+ "supports-color-7.2.0" = {
+ name = "supports-color";
+ packageName = "supports-color";
+ version = "7.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz";
+ sha512 = "qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==";
+ };
+ };
+ "supports-color-8.1.1" = {
+ name = "supports-color";
+ packageName = "supports-color";
+ version = "8.1.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz";
+ sha512 = "MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==";
+ };
+ };
+ "to-regex-range-5.0.1" = {
+ name = "to-regex-range";
+ packageName = "to-regex-range";
+ version = "5.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz";
+ sha512 = "65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==";
+ };
+ };
+ "toidentifier-1.0.0" = {
+ name = "toidentifier";
+ packageName = "toidentifier";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz";
+ sha512 = "yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==";
+ };
+ };
+ "tough-cookie-2.5.0" = {
+ name = "tough-cookie";
+ packageName = "tough-cookie";
+ version = "2.5.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz";
+ sha512 = "nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==";
+ };
+ };
+ "ts-mocha-8.0.0" = {
+ name = "ts-mocha";
+ packageName = "ts-mocha";
+ version = "8.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ts-mocha/-/ts-mocha-8.0.0.tgz";
+ sha512 = "Kou1yxTlubLnD5C3unlCVO7nh0HERTezjoVhVw/M5S1SqoUec0WgllQvPk3vzPMc6by8m6xD1uR1yRf8lnVUbA==";
+ };
+ };
+ "ts-node-7.0.1" = {
+ name = "ts-node";
+ packageName = "ts-node";
+ version = "7.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz";
+ sha512 = "BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==";
+ };
+ };
+ "tsconfig-paths-3.11.0" = {
+ name = "tsconfig-paths";
+ packageName = "tsconfig-paths";
+ version = "3.11.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz";
+ sha512 = "7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==";
+ };
+ };
+ "tslib-1.14.1" = {
+ name = "tslib";
+ packageName = "tslib";
+ version = "1.14.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz";
+ sha512 = "Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==";
+ };
+ };
+ "tslint-6.1.3" = {
+ name = "tslint";
+ packageName = "tslint";
+ version = "6.1.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz";
+ sha512 = "IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==";
+ };
+ };
+ "tsutils-2.29.0" = {
+ name = "tsutils";
+ packageName = "tsutils";
+ version = "2.29.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz";
+ sha512 = "g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==";
+ };
+ };
+ "tunnel-agent-0.6.0" = {
+ name = "tunnel-agent";
+ packageName = "tunnel-agent";
+ version = "0.6.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz";
+ sha1 = "27a5dea06b36b04a0a9966774b290868f0fc40fd";
+ };
+ };
+ "tweetnacl-0.14.5" = {
+ name = "tweetnacl";
+ packageName = "tweetnacl";
+ version = "0.14.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz";
+ sha1 = "5ae68177f192d4456269d108afa93ff8743f4f64";
+ };
+ };
+ "type-is-1.6.18" = {
+ name = "type-is";
+ packageName = "type-is";
+ version = "1.6.18";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz";
+ sha512 = "TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==";
+ };
+ };
+ "typescript-4.4.3" = {
+ name = "typescript";
+ packageName = "typescript";
+ version = "4.4.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz";
+ sha512 = "4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==";
+ };
+ };
+ "unpipe-1.0.0" = {
+ name = "unpipe";
+ packageName = "unpipe";
+ version = "1.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz";
+ sha1 = "b2bf4ee8514aae6165b4817829d21b2ef49904ec";
+ };
+ };
+ "uri-js-4.4.1" = {
+ name = "uri-js";
+ packageName = "uri-js";
+ version = "4.4.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz";
+ sha512 = "7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==";
+ };
+ };
+ "utils-merge-1.0.1" = {
+ name = "utils-merge";
+ packageName = "utils-merge";
+ version = "1.0.1";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz";
+ sha1 = "9f95710f50a267947b2ccc124741c1028427e713";
+ };
+ };
+ "uuid-3.4.0" = {
+ name = "uuid";
+ packageName = "uuid";
+ version = "3.4.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz";
+ sha512 = "HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==";
+ };
+ };
+ "vary-1.1.2" = {
+ name = "vary";
+ packageName = "vary";
+ version = "1.1.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz";
+ sha1 = "2299f02c6ded30d4a5961b0b9f74524a18f634fc";
+ };
+ };
+ "verror-1.10.0" = {
+ name = "verror";
+ packageName = "verror";
+ version = "1.10.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz";
+ sha1 = "3a105ca17053af55d6e270c1f8288682e18da400";
+ };
+ };
+ "which-2.0.2" = {
+ name = "which";
+ packageName = "which";
+ version = "2.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/which/-/which-2.0.2.tgz";
+ sha512 = "BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==";
+ };
+ };
+ "wide-align-1.1.3" = {
+ name = "wide-align";
+ packageName = "wide-align";
+ version = "1.1.3";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz";
+ sha512 = "QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==";
+ };
+ };
+ "workerpool-6.1.5" = {
+ name = "workerpool";
+ packageName = "workerpool";
+ version = "6.1.5";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz";
+ sha512 = "XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==";
+ };
+ };
+ "wrap-ansi-7.0.0" = {
+ name = "wrap-ansi";
+ packageName = "wrap-ansi";
+ version = "7.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz";
+ sha512 = "YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==";
+ };
+ };
+ "wrappy-1.0.2" = {
+ name = "wrappy";
+ packageName = "wrappy";
+ version = "1.0.2";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz";
+ sha1 = "b5243d8f3ec1aa35f1364605bc0d1036e30ab69f";
+ };
+ };
+ "y18n-5.0.8" = {
+ name = "y18n";
+ packageName = "y18n";
+ version = "5.0.8";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz";
+ sha512 = "0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==";
+ };
+ };
+ "yallist-4.0.0" = {
+ name = "yallist";
+ packageName = "yallist";
+ version = "4.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz";
+ sha512 = "3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==";
+ };
+ };
+ "yargs-16.2.0" = {
+ name = "yargs";
+ packageName = "yargs";
+ version = "16.2.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz";
+ sha512 = "D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==";
+ };
+ };
+ "yargs-parser-20.2.4" = {
+ name = "yargs-parser";
+ packageName = "yargs-parser";
+ version = "20.2.4";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz";
+ sha512 = "WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==";
+ };
+ };
+ "yargs-unparser-2.0.0" = {
+ name = "yargs-unparser";
+ packageName = "yargs-unparser";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz";
+ sha512 = "7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==";
+ };
+ };
+ "yn-2.0.0" = {
+ name = "yn";
+ packageName = "yn";
+ version = "2.0.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz";
+ sha1 = "e5adabc8acf408f6385fc76495684c88e6af689a";
+ };
+ };
+ "yocto-queue-0.1.0" = {
+ name = "yocto-queue";
+ packageName = "yocto-queue";
+ version = "0.1.0";
+ src = fetchurl {
+ url = "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz";
+ sha512 = "rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==";
+ };
+ };
+ };
+ args = {
+ name = "mjolnir";
+ packageName = "mjolnir";
+ version = "1.1.20";
+ src = ../../../../../../../nix/store/hc66j9i16g2n08v0laiyydqch4szfygn-source;
+ dependencies = [
+ sources."@babel/code-frame-7.14.5"
+ sources."@babel/helper-validator-identifier-7.15.7"
+ (sources."@babel/highlight-7.14.5" // {
+ dependencies = [
+ sources."ansi-styles-3.2.1"
+ sources."chalk-2.4.2"
+ sources."color-convert-1.9.3"
+ sources."color-name-1.1.3"
+ sources."escape-string-regexp-1.0.5"
+ sources."has-flag-3.0.0"
+ sources."supports-color-5.5.0"
+ ];
+ })
+ sources."@jest/types-27.1.1"
+ sources."@types/body-parser-1.19.1"
+ sources."@types/connect-3.4.35"
+ sources."@types/express-4.17.13"
+ sources."@types/express-serve-static-core-4.17.24"
+ sources."@types/istanbul-lib-coverage-2.0.3"
+ sources."@types/istanbul-lib-report-3.0.0"
+ sources."@types/istanbul-reports-3.0.1"
+ sources."@types/json5-0.0.29"
+ sources."@types/mime-1.3.2"
+ sources."@types/mocha-9.0.0"
+ sources."@types/node-11.15.54"
+ sources."@types/qs-6.9.7"
+ sources."@types/range-parser-1.2.4"
+ sources."@types/serve-static-1.13.10"
+ sources."@types/stack-utils-2.0.1"
+ sources."@types/yargs-16.0.4"
+ sources."@types/yargs-parser-20.2.1"
+ sources."@ungap/promise-all-settled-1.1.2"
+ sources."accepts-1.3.7"
+ sources."ajv-6.12.6"
+ sources."ansi-colors-4.1.1"
+ sources."ansi-regex-5.0.1"
+ sources."ansi-styles-4.3.0"
+ sources."anymatch-3.1.2"
+ sources."argparse-2.0.1"
+ sources."array-flatten-1.1.1"
+ sources."arrify-1.0.1"
+ sources."asn1-0.2.4"
+ sources."assert-plus-1.0.0"
+ sources."asynckit-0.4.0"
+ sources."aws-sign2-0.7.0"
+ sources."aws4-1.11.0"
+ sources."balanced-match-1.0.2"
+ sources."basic-auth-2.0.1"
+ sources."bcrypt-pbkdf-1.0.2"
+ sources."binary-extensions-2.2.0"
+ sources."bluebird-3.7.2"
+ sources."body-parser-1.19.0"
+ sources."brace-expansion-1.1.11"
+ sources."braces-3.0.2"
+ sources."browser-stdout-1.3.1"
+ sources."buffer-from-1.1.2"
+ sources."builtin-modules-1.1.1"
+ sources."bytes-3.1.0"
+ sources."camelcase-6.2.0"
+ sources."caseless-0.12.0"
+ sources."chalk-4.1.2"
+ sources."chokidar-3.5.2"
+ (sources."cliui-7.0.4" // {
+ dependencies = [
+ sources."is-fullwidth-code-point-3.0.0"
+ sources."string-width-4.2.2"
+ sources."strip-ansi-6.0.0"
+ ];
+ })
+ sources."color-convert-2.0.1"
+ sources."color-name-1.1.4"
+ sources."colorette-1.4.0"
+ sources."combined-stream-1.0.8"
+ sources."commander-2.20.3"
+ sources."concat-map-0.0.1"
+ sources."config-3.3.6"
+ sources."content-disposition-0.5.3"
+ sources."content-type-1.0.4"
+ sources."cookie-0.4.0"
+ sources."cookie-signature-1.0.6"
+ sources."core-util-is-1.0.2"
+ sources."dashdash-1.14.1"
+ sources."debug-2.6.9"
+ sources."decamelize-4.0.0"
+ sources."deepmerge-4.2.2"
+ sources."delayed-stream-1.0.0"
+ sources."depd-1.1.2"
+ sources."destroy-1.0.4"
+ sources."diff-5.0.0"
+ sources."diff-sequences-27.0.6"
+ (sources."dom-serializer-1.3.2" // {
+ dependencies = [
+ sources."domhandler-4.2.2"
+ ];
+ })
+ sources."domelementtype-2.2.0"
+ sources."domhandler-3.3.0"
+ (sources."domutils-2.8.0" // {
+ dependencies = [
+ sources."domhandler-4.2.2"
+ ];
+ })
+ sources."ecc-jsbn-0.1.2"
+ sources."ee-first-1.1.1"
+ sources."emoji-regex-8.0.0"
+ sources."encodeurl-1.0.2"
+ sources."entities-2.2.0"
+ sources."escalade-3.1.1"
+ sources."escape-html-1.0.3"
+ sources."escape-string-regexp-4.0.0"
+ sources."esprima-4.0.1"
+ sources."etag-1.8.1"
+ (sources."expect-27.2.1" // {
+ dependencies = [
+ sources."ansi-styles-5.2.0"
+ ];
+ })
+ sources."express-4.17.1"
+ sources."extend-3.0.2"
+ sources."extsprintf-1.3.0"
+ sources."fast-deep-equal-3.1.3"
+ sources."fast-json-stable-stringify-2.1.0"
+ sources."fill-range-7.0.1"
+ sources."finalhandler-1.1.2"
+ sources."find-up-5.0.0"
+ sources."flat-5.0.2"
+ sources."forever-agent-0.6.1"
+ sources."form-data-2.3.3"
+ sources."forwarded-0.2.0"
+ sources."fresh-0.5.2"
+ sources."fs.realpath-1.0.0"
+ sources."fsevents-2.3.2"
+ sources."function-bind-1.1.1"
+ sources."get-caller-file-2.0.5"
+ sources."getpass-0.1.7"
+ sources."glob-7.1.7"
+ sources."glob-parent-5.1.2"
+ sources."glob-to-regexp-0.4.1"
+ sources."graceful-fs-4.2.8"
+ sources."growl-1.10.5"
+ sources."har-schema-2.0.0"
+ sources."har-validator-5.1.5"
+ sources."has-1.0.3"
+ sources."has-flag-4.0.0"
+ sources."hash.js-1.1.7"
+ sources."he-1.2.0"
+ sources."html-to-text-6.0.0"
+ sources."htmlencode-0.0.4"
+ sources."htmlparser2-4.1.0"
+ sources."http-errors-1.7.2"
+ sources."http-signature-1.2.0"
+ sources."iconv-lite-0.4.24"
+ sources."inflight-1.0.6"
+ sources."inherits-2.0.3"
+ sources."ipaddr.js-1.9.1"
+ sources."is-binary-path-2.1.0"
+ sources."is-core-module-2.6.0"
+ sources."is-extglob-2.1.1"
+ sources."is-fullwidth-code-point-2.0.0"
+ sources."is-glob-4.0.1"
+ sources."is-number-7.0.0"
+ sources."is-plain-obj-2.1.0"
+ sources."is-plain-object-5.0.0"
+ sources."is-promise-2.2.2"
+ sources."is-typedarray-1.0.0"
+ sources."is-unicode-supported-0.1.0"
+ sources."isexe-2.0.0"
+ sources."isstream-0.1.2"
+ sources."jest-diff-27.2.0"
+ sources."jest-get-type-27.0.6"
+ sources."jest-matcher-utils-27.2.0"
+ sources."jest-message-util-27.2.0"
+ sources."jest-regex-util-27.0.6"
+ sources."js-tokens-4.0.0"
+ sources."js-yaml-4.1.0"
+ sources."jsbn-0.1.1"
+ sources."json-schema-0.2.3"
+ sources."json-schema-traverse-0.4.1"
+ sources."json-stringify-safe-5.0.1"
+ sources."json5-2.2.0"
+ sources."jsprim-1.4.1"
+ sources."klona-2.0.4"
+ sources."locate-path-6.0.0"
+ sources."lodash-4.17.21"
+ sources."log-symbols-4.1.0"
+ sources."lowdb-1.0.0"
+ sources."lru-cache-6.0.0"
+ sources."make-error-1.3.6"
+ sources."matrix-bot-sdk-0.5.19"
+ sources."media-typer-0.3.0"
+ sources."merge-descriptors-1.0.1"
+ sources."methods-1.1.2"
+ sources."micromatch-4.0.4"
+ sources."mime-1.6.0"
+ sources."mime-db-1.49.0"
+ sources."mime-types-2.1.32"
+ sources."minimalistic-assert-1.0.1"
+ sources."minimatch-3.0.4"
+ sources."minimist-1.2.5"
+ sources."mkdirp-1.0.4"
+ (sources."mocha-9.1.1" // {
+ dependencies = [
+ (sources."debug-4.3.1" // {
+ dependencies = [
+ sources."ms-2.1.2"
+ ];
+ })
+ sources."ms-2.1.3"
+ sources."nanoid-3.1.23"
+ sources."supports-color-8.1.1"
+ ];
+ })
+ (sources."morgan-1.10.0" // {
+ dependencies = [
+ sources."depd-2.0.0"
+ ];
+ })
+ sources."ms-2.0.0"
+ sources."nanoid-3.1.25"
+ sources."negotiator-0.6.2"
+ sources."normalize-path-3.0.0"
+ sources."oauth-sign-0.9.0"
+ sources."on-finished-2.3.0"
+ sources."on-headers-1.0.2"
+ sources."once-1.4.0"
+ sources."p-limit-3.1.0"
+ sources."p-locate-5.0.0"
+ sources."parse-srcset-1.0.2"
+ sources."parseurl-1.3.3"
+ sources."path-exists-4.0.0"
+ sources."path-is-absolute-1.0.1"
+ sources."path-parse-1.0.7"
+ sources."path-to-regexp-0.1.7"
+ sources."performance-now-2.1.0"
+ sources."picomatch-2.3.0"
+ sources."pify-3.0.0"
+ sources."postcss-8.3.6"
+ (sources."pretty-format-27.2.0" // {
+ dependencies = [
+ sources."ansi-styles-5.2.0"
+ ];
+ })
+ sources."proxy-addr-2.0.7"
+ sources."psl-1.8.0"
+ sources."punycode-2.1.1"
+ sources."qs-6.7.0"
+ sources."randombytes-2.1.0"
+ sources."range-parser-1.2.1"
+ sources."raw-body-2.4.0"
+ sources."react-is-17.0.2"
+ sources."readdirp-3.6.0"
+ (sources."request-2.88.2" // {
+ dependencies = [
+ sources."qs-6.5.2"
+ ];
+ })
+ sources."request-promise-4.2.6"
+ sources."request-promise-core-1.1.4"
+ sources."require-directory-2.1.1"
+ sources."resolve-1.20.0"
+ sources."safe-buffer-5.1.2"
+ sources."safer-buffer-2.1.2"
+ (sources."sanitize-html-2.5.1" // {
+ dependencies = [
+ sources."domhandler-4.2.2"
+ sources."htmlparser2-6.1.0"
+ ];
+ })
+ sources."semver-5.7.1"
+ (sources."send-0.17.1" // {
+ dependencies = [
+ sources."ms-2.1.1"
+ ];
+ })
+ sources."serialize-javascript-6.0.0"
+ sources."serve-static-1.14.1"
+ sources."setprototypeof-1.1.1"
+ sources."slash-3.0.0"
+ sources."source-map-0.6.1"
+ sources."source-map-js-0.6.2"
+ sources."source-map-support-0.5.20"
+ sources."sprintf-js-1.0.3"
+ sources."sshpk-1.16.1"
+ (sources."stack-utils-2.0.5" // {
+ dependencies = [
+ sources."escape-string-regexp-2.0.0"
+ ];
+ })
+ sources."statuses-1.5.0"
+ sources."stealthy-require-1.1.1"
+ sources."steno-0.4.4"
+ sources."string-width-2.1.1"
+ (sources."strip-ansi-4.0.0" // {
+ dependencies = [
+ sources."ansi-regex-3.0.0"
+ ];
+ })
+ sources."strip-bom-3.0.0"
+ sources."strip-json-comments-3.1.1"
+ sources."supports-color-7.2.0"
+ sources."to-regex-range-5.0.1"
+ sources."toidentifier-1.0.0"
+ sources."tough-cookie-2.5.0"
+ sources."ts-mocha-8.0.0"
+ (sources."ts-node-7.0.1" // {
+ dependencies = [
+ sources."diff-3.5.0"
+ sources."mkdirp-0.5.5"
+ ];
+ })
+ (sources."tsconfig-paths-3.11.0" // {
+ dependencies = [
+ sources."json5-1.0.1"
+ ];
+ })
+ sources."tslib-1.14.1"
+ (sources."tslint-6.1.3" // {
+ dependencies = [
+ sources."ansi-styles-3.2.1"
+ sources."argparse-1.0.10"
+ sources."chalk-2.4.2"
+ sources."color-convert-1.9.3"
+ sources."color-name-1.1.3"
+ sources."diff-4.0.2"
+ sources."escape-string-regexp-1.0.5"
+ sources."has-flag-3.0.0"
+ sources."js-yaml-3.14.1"
+ sources."mkdirp-0.5.5"
+ sources."supports-color-5.5.0"
+ ];
+ })
+ sources."tsutils-2.29.0"
+ sources."tunnel-agent-0.6.0"
+ sources."tweetnacl-0.14.5"
+ sources."type-is-1.6.18"
+ sources."typescript-4.4.3"
+ sources."unpipe-1.0.0"
+ sources."uri-js-4.4.1"
+ sources."utils-merge-1.0.1"
+ sources."uuid-3.4.0"
+ sources."vary-1.1.2"
+ sources."verror-1.10.0"
+ sources."which-2.0.2"
+ sources."wide-align-1.1.3"
+ sources."workerpool-6.1.5"
+ (sources."wrap-ansi-7.0.0" // {
+ dependencies = [
+ sources."is-fullwidth-code-point-3.0.0"
+ sources."string-width-4.2.2"
+ sources."strip-ansi-6.0.0"
+ ];
+ })
+ sources."wrappy-1.0.2"
+ sources."y18n-5.0.8"
+ sources."yallist-4.0.0"
+ (sources."yargs-16.2.0" // {
+ dependencies = [
+ sources."is-fullwidth-code-point-3.0.0"
+ sources."string-width-4.2.2"
+ sources."strip-ansi-6.0.0"
+ ];
+ })
+ sources."yargs-parser-20.2.4"
+ sources."yargs-unparser-2.0.0"
+ sources."yn-2.0.0"
+ sources."yocto-queue-0.1.0"
+ ];
+ buildInputs = globalBuildInputs;
+ meta = {
+ description = "A moderation tool for Matrix";
+ license = "Apache-2.0";
+ };
+ production = false;
+ bypassCache = true;
+ reconstructLock = true;
+ };
+in
+{
+ args = args;
+ sources = sources;
+ tarball = nodeEnv.buildNodeSourceDist args;
+ package = nodeEnv.buildNodePackage args;
+ shell = nodeEnv.buildNodeShell args;
+ nodeDependencies = nodeEnv.buildNodeDependencies (lib.overrideExisting args {
+ src = stdenv.mkDerivation {
+ name = args.name + "-package-json";
+ src = nix-gitignore.gitignoreSourcePure [
+ "*"
+ "!package.json"
+ "!package-lock.json"
+ ] args.src;
+ dontBuild = true;
+ installPhase = "mkdir -p $out; cp -r ./* $out;";
+ };
+ });
+}
diff --git a/pkgs/servers/mjolnir/node-env.nix b/pkgs/servers/mjolnir/node-env.nix
new file mode 100644
index 000000000000..21089c4d5459
--- /dev/null
+++ b/pkgs/servers/mjolnir/node-env.nix
@@ -0,0 +1,573 @@
+# This file originates from node2nix
+
+{lib, stdenv, nodejs, python2, pkgs, libtool, runCommand, writeTextFile}:
+
+let
+ # Workaround to cope with utillinux in Nixpkgs 20.09 and util-linux in Nixpkgs master
+ utillinux = if pkgs ? utillinux then pkgs.utillinux else pkgs.util-linux;
+
+ python = if nodejs ? python then nodejs.python else python2;
+
+ # Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
+ tarWrapper = runCommand "tarWrapper" {} ''
+ mkdir -p $out/bin
+
+ cat > $out/bin/tar <> $out/nix-support/hydra-build-products
+ '';
+ };
+
+ includeDependencies = {dependencies}:
+ lib.optionalString (dependencies != [])
+ (lib.concatMapStrings (dependency:
+ ''
+ # Bundle the dependencies of the package
+ mkdir -p node_modules
+ cd node_modules
+
+ # Only include dependencies if they don't exist. They may also be bundled in the package.
+ if [ ! -e "${dependency.name}" ]
+ then
+ ${composePackage dependency}
+ fi
+
+ cd ..
+ ''
+ ) dependencies);
+
+ # Recursively composes the dependencies of a package
+ composePackage = { name, packageName, src, dependencies ? [], ... }@args:
+ builtins.addErrorContext "while evaluating node package '${packageName}'" ''
+ DIR=$(pwd)
+ cd $TMPDIR
+
+ unpackFile ${src}
+
+ # Make the base dir in which the target dependency resides first
+ mkdir -p "$(dirname "$DIR/${packageName}")"
+
+ if [ -f "${src}" ]
+ then
+ # Figure out what directory has been unpacked
+ packageDir="$(find . -maxdepth 1 -type d | tail -1)"
+
+ # Restore write permissions to make building work
+ find "$packageDir" -type d -exec chmod u+x {} \;
+ chmod -R u+w "$packageDir"
+
+ # Move the extracted tarball into the output folder
+ mv "$packageDir" "$DIR/${packageName}"
+ elif [ -d "${src}" ]
+ then
+ # Get a stripped name (without hash) of the source directory.
+ # On old nixpkgs it's already set internally.
+ if [ -z "$strippedName" ]
+ then
+ strippedName="$(stripHash ${src})"
+ fi
+
+ # Restore write permissions to make building work
+ chmod -R u+w "$strippedName"
+
+ # Move the extracted directory into the output folder
+ mv "$strippedName" "$DIR/${packageName}"
+ fi
+
+ # Unset the stripped name to not confuse the next unpack step
+ unset strippedName
+
+ # Include the dependencies of the package
+ cd "$DIR/${packageName}"
+ ${includeDependencies { inherit dependencies; }}
+ cd ..
+ ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+ '';
+
+ pinpointDependencies = {dependencies, production}:
+ let
+ pinpointDependenciesFromPackageJSON = writeTextFile {
+ name = "pinpointDependencies.js";
+ text = ''
+ var fs = require('fs');
+ var path = require('path');
+
+ function resolveDependencyVersion(location, name) {
+ if(location == process.env['NIX_STORE']) {
+ return null;
+ } else {
+ var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json");
+
+ if(fs.existsSync(dependencyPackageJSON)) {
+ var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON));
+
+ if(dependencyPackageObj.name == name) {
+ return dependencyPackageObj.version;
+ }
+ } else {
+ return resolveDependencyVersion(path.resolve(location, ".."), name);
+ }
+ }
+ }
+
+ function replaceDependencies(dependencies) {
+ if(typeof dependencies == "object" && dependencies !== null) {
+ for(var dependency in dependencies) {
+ var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency);
+
+ if(resolvedVersion === null) {
+ process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n");
+ } else {
+ dependencies[dependency] = resolvedVersion;
+ }
+ }
+ }
+ }
+
+ /* Read the package.json configuration */
+ var packageObj = JSON.parse(fs.readFileSync('./package.json'));
+
+ /* Pinpoint all dependencies */
+ replaceDependencies(packageObj.dependencies);
+ if(process.argv[2] == "development") {
+ replaceDependencies(packageObj.devDependencies);
+ }
+ replaceDependencies(packageObj.optionalDependencies);
+
+ /* Write the fixed package.json file */
+ fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2));
+ '';
+ };
+ in
+ ''
+ node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"}
+
+ ${lib.optionalString (dependencies != [])
+ ''
+ if [ -d node_modules ]
+ then
+ cd node_modules
+ ${lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies}
+ cd ..
+ fi
+ ''}
+ '';
+
+ # Recursively traverses all dependencies of a package and pinpoints all
+ # dependencies in the package.json file to the versions that are actually
+ # being used.
+
+ pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args:
+ ''
+ if [ -d "${packageName}" ]
+ then
+ cd "${packageName}"
+ ${pinpointDependencies { inherit dependencies production; }}
+ cd ..
+ ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+ fi
+ '';
+
+ # Extract the Node.js source code which is used to compile packages with
+ # native bindings
+ nodeSources = runCommand "node-sources" {} ''
+ tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
+ mv node-* $out
+ '';
+
+ # Script that adds _integrity fields to all package.json files to prevent NPM from consulting the cache (that is empty)
+ addIntegrityFieldsScript = writeTextFile {
+ name = "addintegrityfields.js";
+ text = ''
+ var fs = require('fs');
+ var path = require('path');
+
+ function augmentDependencies(baseDir, dependencies) {
+ for(var dependencyName in dependencies) {
+ var dependency = dependencies[dependencyName];
+
+ // Open package.json and augment metadata fields
+ var packageJSONDir = path.join(baseDir, "node_modules", dependencyName);
+ var packageJSONPath = path.join(packageJSONDir, "package.json");
+
+ if(fs.existsSync(packageJSONPath)) { // Only augment packages that exist. Sometimes we may have production installs in which development dependencies can be ignored
+ console.log("Adding metadata fields to: "+packageJSONPath);
+ var packageObj = JSON.parse(fs.readFileSync(packageJSONPath));
+
+ if(dependency.integrity) {
+ packageObj["_integrity"] = dependency.integrity;
+ } else {
+ packageObj["_integrity"] = "sha1-000000000000000000000000000="; // When no _integrity string has been provided (e.g. by Git dependencies), add a dummy one. It does not seem to harm and it bypasses downloads.
+ }
+
+ if(dependency.resolved) {
+ packageObj["_resolved"] = dependency.resolved; // Adopt the resolved property if one has been provided
+ } else {
+ packageObj["_resolved"] = dependency.version; // Set the resolved version to the version identifier. This prevents NPM from cloning Git repositories.
+ }
+
+ if(dependency.from !== undefined) { // Adopt from property if one has been provided
+ packageObj["_from"] = dependency.from;
+ }
+
+ fs.writeFileSync(packageJSONPath, JSON.stringify(packageObj, null, 2));
+ }
+
+ // Augment transitive dependencies
+ if(dependency.dependencies !== undefined) {
+ augmentDependencies(packageJSONDir, dependency.dependencies);
+ }
+ }
+ }
+
+ if(fs.existsSync("./package-lock.json")) {
+ var packageLock = JSON.parse(fs.readFileSync("./package-lock.json"));
+
+ if(![1, 2].includes(packageLock.lockfileVersion)) {
+ process.stderr.write("Sorry, I only understand lock file versions 1 and 2!\n");
+ process.exit(1);
+ }
+
+ if(packageLock.dependencies !== undefined) {
+ augmentDependencies(".", packageLock.dependencies);
+ }
+ }
+ '';
+ };
+
+ # Reconstructs a package-lock file from the node_modules/ folder structure and package.json files with dummy sha1 hashes
+ reconstructPackageLock = writeTextFile {
+ name = "addintegrityfields.js";
+ text = ''
+ var fs = require('fs');
+ var path = require('path');
+
+ var packageObj = JSON.parse(fs.readFileSync("package.json"));
+
+ var lockObj = {
+ name: packageObj.name,
+ version: packageObj.version,
+ lockfileVersion: 1,
+ requires: true,
+ dependencies: {}
+ };
+
+ function augmentPackageJSON(filePath, dependencies) {
+ var packageJSON = path.join(filePath, "package.json");
+ if(fs.existsSync(packageJSON)) {
+ var packageObj = JSON.parse(fs.readFileSync(packageJSON));
+ dependencies[packageObj.name] = {
+ version: packageObj.version,
+ integrity: "sha1-000000000000000000000000000=",
+ dependencies: {}
+ };
+ processDependencies(path.join(filePath, "node_modules"), dependencies[packageObj.name].dependencies);
+ }
+ }
+
+ function processDependencies(dir, dependencies) {
+ if(fs.existsSync(dir)) {
+ var files = fs.readdirSync(dir);
+
+ files.forEach(function(entry) {
+ var filePath = path.join(dir, entry);
+ var stats = fs.statSync(filePath);
+
+ if(stats.isDirectory()) {
+ if(entry.substr(0, 1) == "@") {
+ // When we encounter a namespace folder, augment all packages belonging to the scope
+ var pkgFiles = fs.readdirSync(filePath);
+
+ pkgFiles.forEach(function(entry) {
+ if(stats.isDirectory()) {
+ var pkgFilePath = path.join(filePath, entry);
+ augmentPackageJSON(pkgFilePath, dependencies);
+ }
+ });
+ } else {
+ augmentPackageJSON(filePath, dependencies);
+ }
+ }
+ });
+ }
+ }
+
+ processDependencies("node_modules", lockObj.dependencies);
+
+ fs.writeFileSync("package-lock.json", JSON.stringify(lockObj, null, 2));
+ '';
+ };
+
+ prepareAndInvokeNPM = {packageName, bypassCache, reconstructLock, npmFlags, production}:
+ let
+ forceOfflineFlag = if bypassCache then "--offline" else "--registry http://www.example.com";
+ in
+ ''
+ # Pinpoint the versions of all dependencies to the ones that are actually being used
+ echo "pinpointing versions of dependencies..."
+ source $pinpointDependenciesScriptPath
+
+ # Patch the shebangs of the bundled modules to prevent them from
+ # calling executables outside the Nix store as much as possible
+ patchShebangs .
+
+ # Deploy the Node.js package by running npm install. Since the
+ # dependencies have been provided already by ourselves, it should not
+ # attempt to install them again, which is good, because we want to make
+ # it Nix's responsibility. If it needs to install any dependencies
+ # anyway (e.g. because the dependency parameters are
+ # incomplete/incorrect), it fails.
+ #
+ # The other responsibilities of NPM are kept -- version checks, build
+ # steps, postprocessing etc.
+
+ export HOME=$TMPDIR
+ cd "${packageName}"
+ runHook preRebuild
+
+ ${lib.optionalString bypassCache ''
+ ${lib.optionalString reconstructLock ''
+ if [ -f package-lock.json ]
+ then
+ echo "WARNING: Reconstruct lock option enabled, but a lock file already exists!"
+ echo "This will most likely result in version mismatches! We will remove the lock file and regenerate it!"
+ rm package-lock.json
+ else
+ echo "No package-lock.json file found, reconstructing..."
+ fi
+
+ node ${reconstructPackageLock}
+ ''}
+
+ node ${addIntegrityFieldsScript}
+ ''}
+
+ npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} rebuild
+
+ if [ "''${dontNpmInstall-}" != "1" ]
+ then
+ # NPM tries to download packages even when they already exist if npm-shrinkwrap is used.
+ rm -f npm-shrinkwrap.json
+
+ npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} install
+ fi
+ '';
+
+ # Builds and composes an NPM package including all its dependencies
+ buildNodePackage =
+ { name
+ , packageName
+ , version
+ , dependencies ? []
+ , buildInputs ? []
+ , production ? true
+ , npmFlags ? ""
+ , dontNpmInstall ? false
+ , bypassCache ? false
+ , reconstructLock ? false
+ , preRebuild ? ""
+ , dontStrip ? true
+ , unpackPhase ? "true"
+ , buildPhase ? "true"
+ , meta ? {}
+ , ... }@args:
+
+ let
+ extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "preRebuild" "unpackPhase" "buildPhase" "meta" ];
+ in
+ stdenv.mkDerivation ({
+ name = "${name}-${version}";
+ buildInputs = [ tarWrapper python nodejs ]
+ ++ lib.optional (stdenv.isLinux) utillinux
+ ++ lib.optional (stdenv.isDarwin) libtool
+ ++ buildInputs;
+
+ inherit nodejs;
+
+ inherit dontStrip; # Stripping may fail a build for some package deployments
+ inherit dontNpmInstall preRebuild unpackPhase buildPhase;
+
+ compositionScript = composePackage args;
+ pinpointDependenciesScript = pinpointDependenciesOfPackage args;
+
+ passAsFile = [ "compositionScript" "pinpointDependenciesScript" ];
+
+ installPhase = ''
+ # Create and enter a root node_modules/ folder
+ mkdir -p $out/lib/node_modules
+ cd $out/lib/node_modules
+
+ # Compose the package and all its dependencies
+ source $compositionScriptPath
+
+ ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
+
+ # Create symlink to the deployed executable folder, if applicable
+ if [ -d "$out/lib/node_modules/.bin" ]
+ then
+ ln -s $out/lib/node_modules/.bin $out/bin
+ fi
+
+ # Create symlinks to the deployed manual page folders, if applicable
+ if [ -d "$out/lib/node_modules/${packageName}/man" ]
+ then
+ mkdir -p $out/share
+ for dir in "$out/lib/node_modules/${packageName}/man/"*
+ do
+ mkdir -p $out/share/man/$(basename "$dir")
+ for page in "$dir"/*
+ do
+ ln -s $page $out/share/man/$(basename "$dir")
+ done
+ done
+ fi
+
+ # Run post install hook, if provided
+ runHook postInstall
+ '';
+
+ meta = {
+ # default to Node.js' platforms
+ platforms = nodejs.meta.platforms;
+ } // meta;
+ } // extraArgs);
+
+ # Builds a node environment (a node_modules folder and a set of binaries)
+ buildNodeDependencies =
+ { name
+ , packageName
+ , version
+ , src
+ , dependencies ? []
+ , buildInputs ? []
+ , production ? true
+ , npmFlags ? ""
+ , dontNpmInstall ? false
+ , bypassCache ? false
+ , reconstructLock ? false
+ , dontStrip ? true
+ , unpackPhase ? "true"
+ , buildPhase ? "true"
+ , ... }@args:
+
+ let
+ extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" ];
+ in
+ stdenv.mkDerivation ({
+ name = "node-dependencies-${name}-${version}";
+
+ buildInputs = [ tarWrapper python nodejs ]
+ ++ lib.optional (stdenv.isLinux) utillinux
+ ++ lib.optional (stdenv.isDarwin) libtool
+ ++ buildInputs;
+
+ inherit dontStrip; # Stripping may fail a build for some package deployments
+ inherit dontNpmInstall unpackPhase buildPhase;
+
+ includeScript = includeDependencies { inherit dependencies; };
+ pinpointDependenciesScript = pinpointDependenciesOfPackage args;
+
+ passAsFile = [ "includeScript" "pinpointDependenciesScript" ];
+
+ installPhase = ''
+ mkdir -p $out/${packageName}
+ cd $out/${packageName}
+
+ source $includeScriptPath
+
+ # Create fake package.json to make the npm commands work properly
+ cp ${src}/package.json .
+ chmod 644 package.json
+ ${lib.optionalString bypassCache ''
+ if [ -f ${src}/package-lock.json ]
+ then
+ cp ${src}/package-lock.json .
+ fi
+ ''}
+
+ # Go to the parent folder to make sure that all packages are pinpointed
+ cd ..
+ ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+
+ ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
+
+ # Expose the executables that were installed
+ cd ..
+ ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+
+ mv ${packageName} lib
+ ln -s $out/lib/node_modules/.bin $out/bin
+ '';
+ } // extraArgs);
+
+ # Builds a development shell
+ buildNodeShell =
+ { name
+ , packageName
+ , version
+ , src
+ , dependencies ? []
+ , buildInputs ? []
+ , production ? true
+ , npmFlags ? ""
+ , dontNpmInstall ? false
+ , bypassCache ? false
+ , reconstructLock ? false
+ , dontStrip ? true
+ , unpackPhase ? "true"
+ , buildPhase ? "true"
+ , ... }@args:
+
+ let
+ nodeDependencies = buildNodeDependencies args;
+ in
+ stdenv.mkDerivation {
+ name = "node-shell-${name}-${version}";
+
+ buildInputs = [ python nodejs ] ++ lib.optional (stdenv.isLinux) utillinux ++ buildInputs;
+ buildCommand = ''
+ mkdir -p $out/bin
+ cat > $out/bin/shell <