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 <