From d9f579cf4400610af7245b1d736a14e3179bcacc Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Sat, 25 Feb 2023 13:14:40 +0100 Subject: [PATCH] Feature/monorepo (#24) * refactor to include all necessary dependencies directly here * move indexer into monorepo * add snapshot tests and seperate sub.project for builtin types * add more missing builtins such as fromTOML --- .gitignore | 39 +- flake.lock | 174 +- flake.nix | 123 +- indexer/.gitignore | 4 + indexer/.travis.yml | 2 + indexer/Cargo.lock | 381 + indexer/Cargo.toml | 14 + indexer/makeMarkdown.js | 36 + indexer/src/main.rs | 286 + indexer/test/types.nix | 987 +++ nix_systems | 1 - projects.toml | 57 + scripts/.gitignore | 2 + scripts/data/builtins-names.json | 114 + scripts/data/builtins.types.json | 4 + scripts/data/fromTOML.md | 32 + scripts/data/more.json | 47 + scripts/make-builtins.js | 76 +- scripts/package.json | 11 + tests/.gitignore | 3 + tests/__snapshots__/data.test.js.snap | 6919 +++++++++++++++++ tests/data.test.js | 13 + tests/jest.config.js | 10 + tests/package-lock.json | 3434 ++++++++ tests/package.json | 15 + .eslintrc.json => website/.eslintrc.json | 0 website/.gitignore | 44 + .../components}/NixFunctions/index.ts | 0 .../components}/NixFunctions/nixFunctions.tsx | 0 .../components}/basicList/basicList.tsx | 0 .../components}/basicList/index.tsx | 0 .../codeHighlight/codeHighlight.module.css | 0 .../codeHighlight/codeHighlight.tsx | 4 +- .../components}/codeHighlight/index.ts | 0 .../emptyRecordsPlaceholder.tsx | 0 .../emptyRecordsPlaceholder/index.tsx | 0 .../components}/functionItem/functionItem.tsx | 0 .../functionOfTheDay/functionOfTheDay.tsx | 0 .../components}/functionOfTheDay/index.ts | 0 .../components}/image/image.tsx | 0 .../components}/image/index.tsx | 0 .../components}/layout/index.ts | 0 .../components}/layout/layout.tsx | 0 .../markdownPreview/MarkdownPreview.tsx | 0 .../components}/markdownPreview/index.ts | 0 .../components}/pageContext/index.ts | 0 .../components}/pageContext/pageContext.tsx | 0 .../components}/preview/index.tsx | 0 .../components}/preview/preview.tsx | 0 .../components}/searchInput/index.tsx | 0 .../components}/searchInput/searchInput.tsx | 0 .../components}/selectOption/index.ts | 0 .../components}/selectOption/selectOption.tsx | 0 .../createEmotionCache.ts | 0 {models => website/models}/data/index.ts | 0 {models => website/models}/internals.ts | 0 {models => website/models}/nix.ts | 0 next.config.js => website/next.config.js | 0 .../package-lock.json | 0 package.json => website/package.json | 2 +- {pages => website/pages}/_app.tsx | 0 {pages => website/pages}/index.tsx | 0 {public => website/public}/favicon.ico | Bin {public => website/public}/favicon.png | Bin {public => website/public}/nix-snowflake.svg | 0 {public => website/public}/search.xml | 0 {public => website/public}/vercel.svg | 0 {public => website/public}/white.svg | 0 {queries => website/queries}/byQuery.ts | 0 {queries => website/queries}/byType.ts | 0 {queries => website/queries}/index.ts | 0 {queries => website/queries}/lib.ts | 0 {styles => website/styles}/globals.css | 0 .../styles}/theme/darkThemeOptions.ts | 0 {styles => website/styles}/theme/index.tsx | 0 .../styles}/theme/lightThemeOptions.ts | 0 tsconfig.json => website/tsconfig.json | 0 {types => website/types}/basicDataView.ts | 0 78 files changed, 12621 insertions(+), 213 deletions(-) create mode 100644 indexer/.gitignore create mode 100644 indexer/.travis.yml create mode 100644 indexer/Cargo.lock create mode 100644 indexer/Cargo.toml create mode 100644 indexer/makeMarkdown.js create mode 100644 indexer/src/main.rs create mode 100644 indexer/test/types.nix delete mode 100644 nix_systems create mode 100644 projects.toml create mode 100644 scripts/.gitignore create mode 100644 scripts/data/builtins-names.json create mode 100644 scripts/data/fromTOML.md create mode 100644 scripts/data/more.json mode change 100644 => 100755 scripts/make-builtins.js create mode 100644 scripts/package.json create mode 100644 tests/.gitignore create mode 100644 tests/__snapshots__/data.test.js.snap create mode 100644 tests/data.test.js create mode 100644 tests/jest.config.js create mode 100644 tests/package-lock.json create mode 100644 tests/package.json rename .eslintrc.json => website/.eslintrc.json (100%) create mode 100644 website/.gitignore rename {components => website/components}/NixFunctions/index.ts (100%) rename {components => website/components}/NixFunctions/nixFunctions.tsx (100%) rename {components => website/components}/basicList/basicList.tsx (100%) rename {components => website/components}/basicList/index.tsx (100%) rename {components => website/components}/codeHighlight/codeHighlight.module.css (100%) rename {components => website/components}/codeHighlight/codeHighlight.tsx (91%) rename {components => website/components}/codeHighlight/index.ts (100%) rename {components => website/components}/emptyRecordsPlaceholder/emptyRecordsPlaceholder.tsx (100%) rename {components => website/components}/emptyRecordsPlaceholder/index.tsx (100%) rename {components => website/components}/functionItem/functionItem.tsx (100%) rename {components => website/components}/functionOfTheDay/functionOfTheDay.tsx (100%) rename {components => website/components}/functionOfTheDay/index.ts (100%) rename {components => website/components}/image/image.tsx (100%) rename {components => website/components}/image/index.tsx (100%) rename {components => website/components}/layout/index.ts (100%) rename {components => website/components}/layout/layout.tsx (100%) rename {components => website/components}/markdownPreview/MarkdownPreview.tsx (100%) rename {components => website/components}/markdownPreview/index.ts (100%) rename {components => website/components}/pageContext/index.ts (100%) rename {components => website/components}/pageContext/pageContext.tsx (100%) rename {components => website/components}/preview/index.tsx (100%) rename {components => website/components}/preview/preview.tsx (100%) rename {components => website/components}/searchInput/index.tsx (100%) rename {components => website/components}/searchInput/searchInput.tsx (100%) rename {components => website/components}/selectOption/index.ts (100%) rename {components => website/components}/selectOption/selectOption.tsx (100%) rename createEmotionCache.ts => website/createEmotionCache.ts (100%) rename {models => website/models}/data/index.ts (100%) rename {models => website/models}/internals.ts (100%) rename {models => website/models}/nix.ts (100%) rename next.config.js => website/next.config.js (100%) rename package-lock.json => website/package-lock.json (100%) rename package.json => website/package.json (97%) rename {pages => website/pages}/_app.tsx (100%) rename {pages => website/pages}/index.tsx (100%) rename {public => website/public}/favicon.ico (100%) rename {public => website/public}/favicon.png (100%) rename {public => website/public}/nix-snowflake.svg (100%) rename {public => website/public}/search.xml (100%) rename {public => website/public}/vercel.svg (100%) rename {public => website/public}/white.svg (100%) rename {queries => website/queries}/byQuery.ts (100%) rename {queries => website/queries}/byType.ts (100%) rename {queries => website/queries}/index.ts (100%) rename {queries => website/queries}/lib.ts (100%) rename {styles => website/styles}/globals.css (100%) rename {styles => website/styles}/theme/darkThemeOptions.ts (100%) rename {styles => website/styles}/theme/index.tsx (100%) rename {styles => website/styles}/theme/lightThemeOptions.ts (100%) rename tsconfig.json => website/tsconfig.json (100%) rename {types => website/types}/basicDataView.ts (100%) diff --git a/.gitignore b/.gitignore index 5d0844b..0fe1497 100644 --- a/.gitignore +++ b/.gitignore @@ -1,47 +1,18 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -# dependencies -/node_modules -/.pnp -.pnp.js + # testing -/coverage -/models/data/* -# !/models/data/index.ts +coverage # nix .direnv/ result result-* - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem -result -result-* - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# local env files -.env*.local .pre-commit-config.yaml -# vercel -.vercel +# dream2nix -# typescript -*.tsbuildinfo -next-env.d.ts +## dream2nix internal cache +.dream2nix \ No newline at end of file diff --git a/flake.lock b/flake.lock index 6e4a159..5e0cc97 100644 --- a/flake.lock +++ b/flake.lock @@ -43,11 +43,11 @@ "crane": { "flake": false, "locked": { - "lastModified": 1670284777, - "narHash": "sha256-JF0pc0s4z/X+Iy+lNHOwUQ8I5bz+q7uX4HrKTNIEj24=", + "lastModified": 1670900067, + "narHash": "sha256-VXVa+KBfukhmWizaiGiHRVX/fuk66P8dgSFfkVN4/MY=", "owner": "ipetkov", "repo": "crane", - "rev": "2243fb9c872de25cb564a02d324ea6a5b9853052", + "rev": "59b31b41a589c0a65e4a1f86b0e5eac68081468b", "type": "github" }, "original": { @@ -86,14 +86,15 @@ "nix-pypi-fetcher": "nix-pypi-fetcher", "nixpkgs": "nixpkgs", "poetry2nix": "poetry2nix", - "pre-commit-hooks": "pre-commit-hooks" + "pre-commit-hooks": "pre-commit-hooks", + "pruned-racket-catalog": "pruned-racket-catalog" }, "locked": { - "lastModified": 1670559747, - "narHash": "sha256-yT/ofVjhgGrdFQeFONFpLNnVJa8ALMuSvlILczvIIn4=", + "lastModified": 1676992344, + "narHash": "sha256-TEn5kEi/jL9Dt6O+ZZ7kQwnlAgEv0r4VgQZnav/cfV4=", "owner": "nix-community", "repo": "dream2nix", - "rev": "8b4d355e8008c47791219da30fc390baf78c4099", + "rev": "db72710500a80bdf4589b6807d2491a4a0dae3ad", "type": "github" }, "original": { @@ -143,14 +144,17 @@ }, "flake-parts": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" + "nixpkgs-lib": [ + "dream2nix", + "nixpkgs" + ] }, "locked": { - "lastModified": 1668450977, - "narHash": "sha256-cfLhMhnvXn6x1vPm+Jow3RiFAUSCw/l1utktCw5rVA4=", + "lastModified": 1675933616, + "narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "d591857e9d7dd9ddbfba0ea02b43b927c3c0f1fa", + "rev": "47478a4a003e745402acf63be7f9a092d51b83d7", "type": "github" }, "original": { @@ -161,11 +165,11 @@ }, "flake-utils": { "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "owner": "numtide", "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "type": "github" }, "original": { @@ -189,21 +193,6 @@ "type": "github" } }, - "flake-utils_2": { - "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "flakeCompat": { "flake": false, "locked": { @@ -304,30 +293,6 @@ "type": "github" } }, - "nixdoc-fork": { - "inputs": { - "flake-utils": [ - "nixdoc-fork", - "rust-overlay", - "flake-utils" - ], - "nixpkgs": "nixpkgs_2", - "rust-overlay": "rust-overlay" - }, - "locked": { - "lastModified": 1675862788, - "narHash": "sha256-TS8YpNtYKBWP6xXrJ7DIdmJwwcCq0Tuf9NhQYWXoPXA=", - "owner": "hsjobeki", - "repo": "nixdoc", - "rev": "76276fdb30ab4fcbe7ba19844a2afd9447256674", - "type": "github" - }, - "original": { - "owner": "hsjobeki", - "repo": "nixdoc", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1665580254, @@ -343,22 +308,19 @@ "type": "indirect" } }, - "nixpkgs-lib": { + "nixpkgs-master": { "locked": { - "dir": "lib", - "lastModified": 1665349835, - "narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=", + "lastModified": 1677165478, + "narHash": "sha256-bWABTj9vlT26d3zpI+NQmuOwcXAzwJGNIgdgPfsnyk8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1", + "rev": "21d1c5425c1c0f4b4ae6203086951164920d9fab", "type": "github" }, "original": { - "dir": "lib", - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "ref": "master", + "type": "indirect" } }, "nixpkgs-stable": { @@ -379,46 +341,16 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1675333202, - "narHash": "sha256-ZcZqGz2K7V9/uIrWfdmKUfC5PkcuR29DKTqUTF5BURo=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "a2780dc543d24f33d7a2d7fa5b2bf609ed8c1849", - "type": "github" - }, - "original": { - "owner": "nixos", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1665296151, - "narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=", + "lastModified": 1677063315, + "narHash": "sha256-qiB4ajTeAOVnVSAwCNEEkoybrAlA+cpeiBxLobHndE8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "14ccaaedd95a488dd7ae142757884d8e125b3363", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1675249806, - "narHash": "sha256-u8Rcqekusl3pMZm68hZqr6zozI8Ug5IxqOiqDLAlu1k=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "79feedf38536de2a27d13fe2eaf200a9c05193ba", + "rev": "988cc958c57ce4350ec248d2d53087777f9e1949", "type": "github" }, "original": { "id": "nixpkgs", + "ref": "nixos-unstable", "type": "indirect" } }, @@ -467,7 +399,7 @@ "pre-commit-hooks_2": { "inputs": { "flake-compat": "flake-compat", - "flake-utils": "flake-utils_2", + "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -475,11 +407,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1674550893, - "narHash": "sha256-HXI8AB96PP7UZ7iPANACXM8qc9eMz0ljxBEDM8JJKhY=", + "lastModified": 1677160285, + "narHash": "sha256-tBzpCjMP+P3Y3nKLYvdBkXBg3KvTMo3gvi8tLQaqXVY=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "7bdf85f6bbef581eb687838d19f2b35a4c9d77f0", + "rev": "2bd861ab81469428d9c823ef72c4bb08372dd2c4", "type": "github" }, "original": { @@ -488,11 +420,28 @@ "type": "github" } }, + "pruned-racket-catalog": { + "flake": false, + "locked": { + "lastModified": 1672537287, + "narHash": "sha256-SuOvXVcLfakw18oJB/PuRMyvGyGG1+CQD3R+TGHIv44=", + "owner": "nix-community", + "repo": "pruned-racket-catalog", + "rev": "c8b89557fb53b36efa2ee48a769c7364df0f6262", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "catalog", + "repo": "pruned-racket-catalog", + "type": "github" + } + }, "root": { "inputs": { "dream2nix": "dream2nix", - "nixdoc-fork": "nixdoc-fork", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs_2", + "nixpkgs-master": "nixpkgs-master", "pre-commit-hooks": "pre-commit-hooks_2" } }, @@ -512,25 +461,6 @@ "repo": "rust-analyzer", "type": "github" } - }, - "rust-overlay": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1670380307, - "narHash": "sha256-7fJN5ndnE8YbrrtYdqMo3gDV/BW37M4wNBRhjdfP/XY=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "fc98242f5f49d39b8fd3a611c146741a35dc012d", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 2defff2..20969e7 100644 --- a/flake.nix +++ b/flake.nix @@ -1,55 +1,109 @@ { inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + nixpkgs-master.url = "nixpkgs/master"; + dream2nix.url = "github:nix-community/dream2nix"; - nixdoc-fork.url = "github:hsjobeki/nixdoc"; + pre-commit-hooks = { url = "github:cachix/pre-commit-hooks.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; }; - outputs = { self, nixpkgs, pre-commit-hooks, ... }@inp: + outputs = { self, nixpkgs, pre-commit-hooks, dream2nix, nixpkgs-master }: let system = "x86_64-linux"; - pkgs = inp.nixpkgs.legacyPackages.${system}; - inherit (builtins.fromJSON (builtins.readFile ./package.json)) name; - prepareData = '' - cp -f ${inp.nixdoc-fork.packages.${system}.data.lib} ./models/data/lib.json - cp -f ${inp.nixdoc-fork.packages.${system}.data.build_support} ./models/data/trivial-builders.json - node ./scripts/make-builtins.js + pkgs = nixpkgs.legacyPackages.${system}; + websiteName = (builtins.fromJSON (builtins.readFile ./website/package.json)).name; + inherit (self.packages.${system}) indexer nixpkgs-data builtins-data; + + prepareData = prefix: '' + cp -f ${nixpkgs-data.lib} ${prefix}/lib.json + cp -f ${nixpkgs-data.build_support} ${prefix}/trivial-builders.json + cp -f ${builtins-data}/lib/data.json ${prefix}/builtins.json ''; - in - (inp.dream2nix.lib.makeFlakeOutputs { - systemsFromFile = ./nix_systems; - config.projectRoot = ./.; - source = ./.; - settings = [ - { - subsystemInfo.nodejs = 18; - } - ]; - packageOverrides = { - ${name}.staticPage = { - preBuild = prepareData; - installPhase = '' - runHook preInstall - npm run export - mkdir -p $out/static - cp -r ./out/* $out/static/ + dream2nixOutput = dream2nix.lib.makeFlakeOutputs { + systems = [ system ]; + projects = ./projects.toml; + config.projectRoot = ./.; + source = ./.; - runHook postInstall - ''; + packageOverrides = { + ${websiteName}.staticPage = { + preBuild = prepareData "models/data"; + installPhase = '' + runHook preInstall + + npm run export + mkdir -p $out/static + cp -r ./out/* $out/static/ + cp -r ./ $lib + + runHook postInstall + ''; + }; + tests.run = { + installPhase = ""; + preBuild = '' + ls -la + mkdir -p data + ${prepareData "data"} + + ''; + doCheck = true; + checkPhase = '' + ls -la + npm run test -- --ci + ''; + }; }; }; - }) - // { + in + { + packages.${system} = dream2nixOutput.packages.${system} // { + nixpkgs-data = pkgs.stdenv.mkDerivation { + pname = "data"; + version = "0.1.0"; + description = '' + wrapper around the indexer. + + Calls the indexer with ''/path. + and defines one output for every specified input path + + currently this list is manually maintained below. + ''; + src = nixpkgs-master; + outputs = [ "out" "lib" "build_support" ]; + nativeBuildInputs = [ indexer ]; + buildPhase = '' + echo "running nix metadata collect in nixpkgs/lib" + ${indexer}/bin/indexer --dir ./lib + ${indexer}/bin/indexer --dir ./pkgs/build-support + ''; + installPhase = '' + cat lib.json > $lib + cat build-support.json > $build_support + + mkdir $out + ln -s $lib $out/lib + ln -s $build_support $out/build_support + ''; + }; + + default = self.packages.${system}.noogle; + }; + devShells.${system}.default = pkgs.mkShell { - buildInputs = with pkgs; [ nodejs-18_x ]; + buildInputs = with pkgs; [ nodejs-18_x rustfmt rustc cargo clippy ]; + inputsFrom = [ indexer ]; shellHook = '' - ${prepareData} + ${prepareData "website/models/data"} + ${prepareData "tests/data"} ${self.checks.${system}.pre-commit-check.shellHook} ''; }; + checks.${system} = { pre-commit-check = pre-commit-hooks.lib.${system}.run { src = ./.; @@ -58,6 +112,11 @@ statix.enable = true; markdownlint.enable = true; }; + excludes = [ "indexer/test" ".github" "scripts/data" ]; + settings = { + statix.ignore = [ "indexer/test" ]; + }; + }; }; }; diff --git a/indexer/.gitignore b/indexer/.gitignore new file mode 100644 index 0000000..0722ec3 --- /dev/null +++ b/indexer/.gitignore @@ -0,0 +1,4 @@ + +target/ +**/*.rs.bk +data.json \ No newline at end of file diff --git a/indexer/.travis.yml b/indexer/.travis.yml new file mode 100644 index 0000000..2a8d154 --- /dev/null +++ b/indexer/.travis.yml @@ -0,0 +1,2 @@ +language: nix +sudo: true diff --git a/indexer/Cargo.lock b/indexer/Cargo.lock new file mode 100644 index 0000000..2029177 --- /dev/null +++ b/indexer/Cargo.lock @@ -0,0 +1,381 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "arenatree" +version = "0.1.1" +source = "git+https://gitlab.com/jD91mZM2/arenatree#f9bf7efa9a5ef4c2dd9e2acc5a4cc79a987cb648" + +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +dependencies = [ + "nodrop", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +dependencies = [ + "libc", + "termion", + "winapi", +] + +[[package]] +name = "backtrace" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +dependencies = [ + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", + "winapi", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" + +[[package]] +name = "cc" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" + +[[package]] +name = "cfg-if" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" + +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "failure" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" +dependencies = [ + "proc-macro2 0.4.20", + "quote 0.6.8", + "syn 0.15.15", + "synstructure", +] + +[[package]] +name = "indexer" +version = "0.1.0" +dependencies = [ + "rnix", + "serde", + "serde_json", + "structopt", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "libc" +version = "0.2.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" + +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" + +[[package]] +name = "proc-macro2" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +dependencies = [ + "proc-macro2 0.4.20", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2 1.0.47", +] + +[[package]] +name = "redox_syscall" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +dependencies = [ + "redox_syscall", +] + +[[package]] +name = "rnix" +version = "0.4.1" +source = "git+https://gitlab.com/jD91mZM2/rnix.git?rev=10b86c94291b4864470158ef8750de85ddd8d4ba#10b86c94291b4864470158ef8750de85ddd8d4ba" +dependencies = [ + "arenatree", + "arrayvec", + "failure", + "smol_str", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "serde" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +dependencies = [ + "proc-macro2 1.0.47", + "quote 1.0.21", + "syn 1.0.105", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "smol_str" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ed6f19b800d76574926e458d5f8e2dbea86c2b58c08d33a982448f09ac8d0c" + +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" + +[[package]] +name = "structopt" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77af7242f18c40fd19cb270985930f239ee1646cfb482050bbae9da1d18743b" +dependencies = [ + "clap", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ff01fe96de9d16e7372ae5f19dd7ece2c703b51043c3db9ea27f9e393ea311" +dependencies = [ + "proc-macro2 0.4.20", + "quote 0.6.8", + "syn 0.15.15", +] + +[[package]] +name = "syn" +version = "0.15.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a9c2bf1e53c21704a7cce1b2a42768f1ae32a6777108a0d7f1faa4bfe7f7c04" +dependencies = [ + "proc-macro2 0.4.20", + "quote 0.6.8", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2 1.0.47", + "quote 1.0.21", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" +dependencies = [ + "proc-macro2 0.4.20", + "quote 0.6.8", + "syn 0.15.15", + "unicode-xid", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +dependencies = [ + "libc", + "redox_syscall", + "redox_termios", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/indexer/Cargo.toml b/indexer/Cargo.toml new file mode 100644 index 0000000..93fff82 --- /dev/null +++ b/indexer/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "indexer" +version = "0.1.0" +authors = ["Johannes Kirschbauer "] +edition = "2021" + +[dependencies] +structopt = "0.2" +serde_json = "1.0.89" +serde = { version = "1.0.148", features = ["derive"] } + +[dependencies.rnix] +git = "https://gitlab.com/jD91mZM2/rnix.git" +rev = "10b86c94291b4864470158ef8750de85ddd8d4ba" diff --git a/indexer/makeMarkdown.js b/indexer/makeMarkdown.js new file mode 100644 index 0000000..e0445e6 --- /dev/null +++ b/indexer/makeMarkdown.js @@ -0,0 +1,36 @@ +// simple script +// test.json in generated with "cargo run -- --dir ./test" +const data = require("./test.json"); +const fs = require("fs"); + +const all_docs = data.reduce( + (acc, doc) => `${acc} +## ${doc.name} + +### Description + +\`\`\`nix +${doc.description} +\`\`\` + +### Example + +\`\`\`nix +${doc.example} +\`\`\` + +### Type + +\`\`\`nix +${doc.fn_type} +\`\`\` + +`, + "" +); + +fs.writeFile("content.md", `# Functions\n${all_docs}`, (err) => { + if (err) { + console.error(err); + } +}); diff --git a/indexer/src/main.rs b/indexer/src/main.rs new file mode 100644 index 0000000..4e803d8 --- /dev/null +++ b/indexer/src/main.rs @@ -0,0 +1,286 @@ +extern crate rnix; +extern crate serde; +extern crate serde_json; +extern crate structopt; +use rnix::parser::{ASTKind, ASTNode, Arena, Data}; +use rnix::tokenizer::Trivia; +use rnix::tokenizer::{Meta, Span}; +use serde::{Deserialize, Serialize}; +use std::fs::{self, File}; +use std::path::PathBuf; +use structopt::StructOpt; + +/// Command line arguments for the indexer +#[derive(Debug, StructOpt)] +#[structopt(name = "indexer", about = "Generate Metadata from Nix files")] +struct Options { + /// directory to process. + #[structopt(short = "D", long = "dir", parse(from_os_str))] + dir: PathBuf, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ManualEntry { + pub id: String, + pub line: Option, + pub category: String, + pub name: String, + pub fn_type: Option, + pub description: String, + pub example: Option, +} +#[derive(Debug)] +struct DocComment { + /// Primary documentation string. + doc: String, + + /// Optional type annotation for the thing being documented. + doc_type: Option, + + /// Usage example(s) (interpreted as a single code block) + example: Option, +} + +#[derive(Debug)] +struct DocItem { + name: String, + span: Span, + comment: DocComment, +} + +/// Retrieve documentation comments. For now only multiline comments are considered +fn retrieve_doc_comment(allow_single_line: bool, meta: &Meta) -> Option { + for item in meta.leading.iter() { + if let Trivia::Comment { + multiline, content, .. + } = item + { + if *multiline || allow_single_line { + return Some(content.to_string()); + } + } + } + return None; +} + +/// Transforms an AST node into a `DocItem` if it has a leading +/// documentation comment. +fn retrieve_doc_item(node: &ASTNode) -> Option { + // We are only interested in identifiers. + + if let Data::Ident(meta, name) = &node.data { + let comment = retrieve_doc_comment(false, meta)?; + return Some(DocItem { + span: node.span, + name: name.to_string(), + comment: parse_doc_comment(&comment), + }); + } + return None; +} + +fn get_indentation(line: &str) -> usize { + return line + .char_indices() + .find(|(_, ch)| !(ch.is_whitespace() && *ch != '\n')) + .map(|(i, _)| i) + .unwrap_or_else(|| line.len()); +} + +/// *Really* dumb, mutable, hacky doc comment "parser". +fn parse_doc_comment(raw: &str) -> DocComment { + enum ParseState { + Doc, + Type, + Example, + } + + let mut doc = String::new(); + let mut doc_type = String::new(); + let mut example = String::new(); + let mut state = ParseState::Doc; + + let mut type_ident = 0; + let mut doc_ident = 0; + let mut example_ident = 0; + + for line in raw.clone().lines() { + let mut line = line.clone().trim_end(); + let trimmed = line.clone().trim(); + if trimmed.starts_with("Type:") { + state = ParseState::Type; + line = &trimmed[5..]; // trim 'Type:' + } + + if trimmed.starts_with("Example:") { + state = ParseState::Example; + line = &trimmed[8..]; // trim 'Example:' + } + match state { + ParseState::Type => { + let curr_indent = get_indentation(line); + if curr_indent > 0 && type_ident == 0 { + type_ident = curr_indent; + } + } + ParseState::Doc => { + let curr_indent = get_indentation(line); + if curr_indent > 0 && doc_ident == 0 { + doc_ident = curr_indent; + } + } + ParseState::Example => { + let curr_indent = get_indentation(line); + if curr_indent > 0 && example_ident == 0 { + example_ident = curr_indent; + } + } + } + } + state = ParseState::Doc; + + for line in raw.lines() { + let mut line = line.trim_end(); + let trimmed = line.clone().trim(); + if trimmed.starts_with("Type:") { + state = ParseState::Type; + line = &trimmed[5..]; // trim 'Type:' + } + + if trimmed.starts_with("Example:") { + state = ParseState::Example; + line = &trimmed[8..]; // trim 'Example:' + } + match state { + // important: trim only trailing whitespaces; as leading ones might be markdown formatting or code examples. + ParseState::Type => { + let stripped = line.trim_end(); + let formatted = stripped.replacen(&" ".repeat(type_ident), "", 1); + doc_type.push_str(&formatted); + doc_type.push('\n'); + } + ParseState::Doc => { + let stripped = line.trim_end(); + let formatted = stripped.replacen(&" ".repeat(doc_ident), "", 1); + doc.push_str(&formatted); + doc.push('\n'); + } + ParseState::Example => { + let stripped = line.trim_end(); + let formatted = stripped.replacen(&" ".repeat(example_ident), "", 1); + example.push_str(&formatted); + example.push('\n'); + } + } + } + let f = |mut s: String| { + if s.is_empty() { + None + } else { + let len = s.trim_end_matches(&['\r', '\n'][..]).len(); + s.truncate(len); + return Some(s.trim_start().into()); + } + }; + // let doc_f = f(doc); + DocComment { + doc: f(doc).unwrap_or("".to_owned()), + doc_type: f(doc_type), + example: f(example), + } +} + +fn get_line(span: Span, src: &String) -> Option { + let mut line_nr: usize = 1; + for (count, char) in src.chars().enumerate() { + if char == '\n' { + line_nr = line_nr + 1; + } + if count == span.start as usize { + return Some(line_nr); + } + } + None +} + +/// Traverse a pattern argument, collecting its argument names. +/// Traverse a Nix lambda and collect the identifiers of arguments +/// until an unexpected AST node is encountered. +/// +/// This will collect the argument names for curried functions in the +/// `a: b: c: ...`-style, but does not currently work with pattern +/// functions (`{ a, b, c }: ...`). +/// +/// In the AST representation used by rnix, any lambda node has an +/// immediate child that is the identifier of its argument. The "body" +/// of the lambda is two steps to the right from that identifier, if +/// it is a lambda the function is curried and we can recurse. +/// Traverse the arena from a top-level SetEntry and collect, where +/// possible: +/// +/// 1. The identifier of the set entry itself. +/// 2. The attached doc comment on the entry. +/// 3. The argument names of any curried functions (pattern functions +/// not yet supported). +fn collect_entry_information<'a>(arena: &Arena<'a>, entry_node: &ASTNode) -> Option { + // The "root" of any attribute set entry is this `SetEntry` node. + // It has an `Attribute` child, which in turn has the identifier + // (on which the documentation comment is stored) as its child. + let attr_node = &arena[entry_node.node.child?]; + let ident_node = &arena[attr_node.node.child?]; + // At this point we can retrieve the `DocItem` from the identifier + // node - this already contains most of the information we are + // interested in. + let doc_item = retrieve_doc_item(ident_node)?; + + // From our entry we can walk two nodes to the right and check + // whether we are dealing with a lambda. If so, we can start + // collecting the function arguments - otherwise we're done. + // let assign_node = &arena[attr_node.node.sibling?]; + // let content_node = &arena[assign_node.node.sibling?]; + Some(doc_item) +} + +fn main() { + let opts = Options::from_args(); + let paths = fs::read_dir(&opts.dir).unwrap(); + let mut data: Vec = vec![]; + for path in paths { + let file_path = path.unwrap(); + let file_type = file_path.file_type().unwrap(); + let file = file_path.path(); + if file_type.is_file() && file.extension().unwrap() == "nix" { + // sources.push(file); + let src = fs::read_to_string(&file).unwrap(); + let nix = rnix::parse(&src).unwrap(); + let filename = file.file_stem().unwrap().to_str().unwrap(); + let parent = file + .parent() + .unwrap() + .file_name() + .unwrap() + .to_str() + .unwrap(); + + let entries: Vec = nix + .arena + .into_iter() + .filter(|node| node.kind == ASTKind::SetEntry) + .filter_map(|node| collect_entry_information(&nix.arena, node)) + .map(|d| ManualEntry { + id: format!("{}.{}.{}", parent, filename, d.name), + line: Some(get_line(d.span, &src)).unwrap_or(None), + category: file.display().to_string(), + name: d.name, + description: d.comment.doc, + fn_type: d.comment.doc_type, + example: d.comment.example, + }) + .collect(); + data.extend(entries); + } + } + let json_file = + File::create(opts.dir.file_name().unwrap().to_str().unwrap().to_owned() + ".json").unwrap(); + ::serde_json::to_writer(&json_file, &data).unwrap(); +} diff --git a/indexer/test/types.nix b/indexer/test/types.nix new file mode 100644 index 0000000..ac480ab --- /dev/null +++ b/indexer/test/types.nix @@ -0,0 +1,987 @@ +# Definitions related to run-time type checking. Used in particular +# to type-check NixOS configurations. +{ lib }: + +let + inherit (lib) + elem + flip + isAttrs + isBool + isDerivation + isFloat + isFunction + isInt + isList + isString + isStorePath + toDerivation + toList + ; + inherit (lib.lists) + all + concatLists + count + elemAt + filter + foldl' + head + imap1 + last + length + tail + ; + inherit (lib.attrsets) + attrNames + filterAttrs + hasAttr + mapAttrs + optionalAttrs + zipAttrsWith + ; + inherit (lib.options) + getFiles + getValues + mergeDefaultOption + mergeEqualOption + mergeOneOption + mergeUniqueOption + showFiles + showOption + ; + inherit (lib.strings) + concatMapStringsSep + concatStringsSep + escapeNixString + hasInfix + isStringLike + ; + inherit (lib.trivial) + boolToString + ; + + inherit (lib.modules) + mergeDefinitions + fixupOptionType + mergeOptionDecls + ; + outer_types = +rec { + isType = type: x: (x._type or "") == type; + + setType = typeName: value: value // { + _type = typeName; + }; + + + /* Default type merging function + takes two type functors and return the merged type + + */ + defaultTypeMerge = f: f': + let wrapped = f.wrapped.typeMerge f'.wrapped.functor; + payload = f.binOp f.payload f'.payload; + in + # cannot merge different types + if f.name != f'.name + then null + # simple types + else if (f.wrapped == null && f'.wrapped == null) + && (f.payload == null && f'.payload == null) + then f.type + # composed types + else if (f.wrapped != null && f'.wrapped != null) && (wrapped != null) + then f.type wrapped + # value types + else if (f.payload != null && f'.payload != null) && (payload != null) + then f.type payload + else null; + + /* Default type functor */ + defaultFunctor = name: { + inherit name; + type = types.${name} or null; + wrapped = null; + payload = null; + binOp = a: b: null; + }; + + isOptionType = isType "option-type"; + /* + Function that creates an optionType to be used in the module system. + + Example: + + Type: + { + name :: String; + description :: String ?; + descriptionClass :: "noun" | "conjunction" | "composite" ?; + check :: (a -> Bool) ?; + merge :: + emptyValue :: {} ?; + getSubOptions :: ( [String] -> {}) ?; + getSubModules :: ( [Module] ) ?; + substSubModules :: ( [Module] ) ?; + typeMerge :: + functor :: + deprecationMessage :: + nestedTypes :: + } + -> + { + name :: String + name check merge emptyValue getSubOptions getSubModules substSubModules + typeMerge functor deprecationMessage nestedTypes descriptionClass; + description = if description == null then name else description; + + _type :: "option-type"; + }; + + */ + mkOptionType = + { # Human-readable representation of the type, should be equivalent to + # the type function name. + name + , # Description of the type, defined recursively by embedding the wrapped type if any. + description ? null + # A hint for whether or not this description needs parentheses. Possible values: + # - "noun": a simple noun phrase such as "positive integer" + # - "conjunction": a phrase with a potentially ambiguous "or" connective. + # - "composite": a phrase with an "of" connective + # See the `optionDescriptionPhrase` function. + , descriptionClass ? null + , # DO NOT USE WITHOUT KNOWING WHAT YOU ARE DOING! + # Function applied to each definition that must return false when a definition + # does not match the type. It should not check more than the root of the value, + # because checking nested values reduces laziness, leading to unnecessary + # infinite recursions in the module system. + # Further checks of nested values should be performed by throwing in + # the merge function. + # Strict and deep type checking can be performed by calling lib.deepSeq on + # the merged value. + # + # See https://github.com/NixOS/nixpkgs/pull/6794 that introduced this change, + # https://github.com/NixOS/nixpkgs/pull/173568 and + # https://github.com/NixOS/nixpkgs/pull/168295 that attempted to revert this, + # https://github.com/NixOS/nixpkgs/issues/191124 and + # https://github.com/NixOS/nixos-search/issues/391 for what happens if you ignore + # this disclaimer. + check ? (x: true) + , # Merge a list of definitions together into a single value. + # This function is called with two arguments: the location of + # the option in the configuration as a list of strings + # (e.g. ["boot" "loader "grub" "enable"]), and a list of + # definition values and locations (e.g. [ { file = "/foo.nix"; + # value = 1; } { file = "/bar.nix"; value = 2 } ]). + merge ? mergeDefaultOption + , # Whether this type has a value representing nothingness. If it does, + # this should be a value of the form { value = ; } + # If it doesn't, this should be {} + # This may be used when a value is required for `mkIf false`. This allows the extra laziness in e.g. `lazyAttrsOf`. + emptyValue ? {} + , # Return a flat list of sub-options. Used to generate + # documentation. + getSubOptions ? prefix: {} + , # List of modules if any, or null if none. + getSubModules ? null + , # Function for building the same option type with a different list of + # modules. + substSubModules ? m: null + , # Function that merge type declarations. + # internal, takes a functor as argument and returns the merged type. + # returning null means the type is not mergeable + typeMerge ? defaultTypeMerge functor + , # The type functor. + # internal, representation of the type as an attribute set. + # name: name of the type + # type: type function. + # wrapped: the type wrapped in case of compound types. + # payload: values of the type, two payloads of the same type must be + # combinable with the binOp binary operation. + # binOp: binary operation that merge two payloads of the same type. + functor ? defaultFunctor name + , # The deprecation message to display when this type is used by an option + # If null, the type isn't deprecated + deprecationMessage ? null + , # The types that occur in the definition of this type. This is used to + # issue deprecation warnings recursively. Can also be used to reuse + # nested types + nestedTypes ? {} + }: + { _type = "option-type"; + inherit + name check merge emptyValue getSubOptions getSubModules substSubModules + typeMerge functor deprecationMessage nestedTypes descriptionClass; + description = if description == null then name else description; + }; + + # optionDescriptionPhrase :: (str -> bool) -> optionType -> str + # + # Helper function for producing unambiguous but readable natural language + # descriptions of types. + # + # Parameters + # + # optionDescriptionPhase unparenthesize optionType + # + # `unparenthesize`: A function from descriptionClass string to boolean. + # It must return true when the class of phrase will fit unambiguously into + # the description of the caller. + # + # `optionType`: The option type to parenthesize or not. + # The option whose description we're returning. + # + # Return value + # + # The description of the `optionType`, with parentheses if there may be an + # ambiguity. + optionDescriptionPhrase = unparenthesize: t: + if unparenthesize (t.descriptionClass or null) + then t.description + else "(${t.description})"; + + # When adding new types don't forget to document them in + # nixos/doc/manual/development/option-types.xml! + types = rec { + /* + Can be anything. + + Merge behavior: None; Merging is disabled. + + */ + raw = mkOptionType rec { + name = "raw"; + description = "raw value"; + descriptionClass = "noun"; + check = value: true; + merge = mergeOneOption; + }; + /* + Can be anything. + + Merge behavior: Custom Logic + */ + anything = mkOptionType { + name = "anything"; + description = "anything"; + descriptionClass = "noun"; + check = value: true; + merge = loc: defs: + let + getType = value: + if isAttrs value && isStringLike value + then "stringCoercibleSet" + else builtins.typeOf value; + + # Returns the common type of all definitions, throws an error if they + # don't have the same type + commonType = foldl' (type: def: + if getType def.value == type + then type + else throw "The option `${showOption loc}' has conflicting option types in ${showFiles (getFiles defs)}" + ) (getType (head defs).value) defs; + + mergeFunction = { + # Recursively merge attribute sets + set = (attrsOf anything).merge; + # Safe and deterministic behavior for lists is to only accept one definition + # listOf only used to apply mkIf and co. + list = + if length defs > 1 + then throw "The option `${showOption loc}' has conflicting definitions, in ${showFiles (getFiles defs)}." + else (listOf anything).merge; + # This is the type of packages, only accept a single definition + stringCoercibleSet = mergeOneOption; + lambda = loc: defs: arg: anything.merge + (loc ++ [ "" ]) + (map (def: { + file = def.file; + value = def.value arg; + }) defs); + # Otherwise fall back to only allowing all equal definitions + }.${commonType} or mergeEqualOption; + in mergeFunction loc defs; + }; + + /* + Can be anything. + + Merge behavior: Default logic + */ + unspecified = mkOptionType { + name = "unspecified"; + description = "unspecified value"; + descriptionClass = "noun"; + }; + + + /* + Allows Boolean values + + Merge behavior: Enabled; see lib.mergeEqualOption; + */ + bool = mkOptionType { + name = "bool"; + description = "boolean"; + descriptionClass = "noun"; + check = isBool; + merge = mergeEqualOption; + }; + + int = mkOptionType { + name = "int"; + description = "signed integer"; + descriptionClass = "noun"; + check = isInt; + merge = mergeEqualOption; + }; + + /* Specialized subdomains of int + + - ints.between + - ints.unsigned + - ints.u8 + - ints.u16 + - ints.u32 + - ints.s8 + - ints.s16 + - ints.s32 + + + Example: + (ints.between 0 100).check (-1) + => false + (ints.between 0 100).check (101) + => false + (ints.between 0 0).check 0 + => true + */ + ints = + let + betweenDesc = lowest: highest: + "${toString lowest} and ${toString highest} (both inclusive)"; + between = lowest: highest: + assert lib.assertMsg (lowest <= highest) + "ints.between: lowest must be smaller than highest"; + addCheck int (x: x >= lowest && x <= highest) // { + name = "intBetween"; + description = "integer between ${betweenDesc lowest highest}"; + }; + ign = lowest: highest: name: docStart: + between lowest highest // { + inherit name; + description = docStart + "; between ${betweenDesc lowest highest}"; + }; + unsign = bit: range: ign 0 (range - 1) + "unsignedInt${toString bit}" "${toString bit} bit unsigned integer"; + sign = bit: range: ign (0 - (range / 2)) (range / 2 - 1) + "signedInt${toString bit}" "${toString bit} bit signed integer"; + + in { + /* An int with a fixed range. + + Example: + (ints.between 0 100).check (-1) + => false + (ints.between 0 100).check (101) + => false + (ints.between 0 0).check 0 + => true + */ + inherit between; + + unsigned = addCheck types.int (x: x >= 0) // { + name = "unsignedInt"; + description = "unsigned integer, meaning >=0"; + }; + positive = addCheck types.int (x: x > 0) // { + name = "positiveInt"; + description = "positive integer, meaning >0"; + }; + u8 = unsign 8 256; + u16 = unsign 16 65536; + # the biggest int Nix accepts is 2^63 - 1 (9223372036854775808) + # the smallest int Nix accepts is -2^63 (-9223372036854775807) + u32 = unsign 32 4294967296; + # u64 = unsign 64 18446744073709551616; + + s8 = sign 8 256; + s16 = sign 16 65536; + s32 = sign 32 4294967296; + }; + + /* + Port number can be unsigned 16 bit + + from 0 to 65536 + + Alias of ints.u16 for a port number. -> See tye.ints for more infos. + */ + port = ints.u16; + + /* + A Float number + + For more information about validation see: lib.isFloat + + Merge behavior: Enabled; see lib.mergeEqualOption + */ + float = mkOptionType { + name = "float"; + description = "floating point number"; + descriptionClass = "noun"; + check = isFloat; + merge = mergeEqualOption; + }; + + /* + Can be either an Int or a Float + + + + */ + number = either int float; + + numbers = let + betweenDesc = lowest: highest: + "${builtins.toJSON lowest} and ${builtins.toJSON highest} (both inclusive)"; + in { + between = lowest: highest: + assert lib.assertMsg (lowest <= highest) + "numbers.between: lowest must be smaller than highest"; + addCheck number (x: x >= lowest && x <= highest) // { + name = "numberBetween"; + description = "integer or floating point number between ${betweenDesc lowest highest}"; + }; + + nonnegative = addCheck number (x: x >= 0) // { + name = "numberNonnegative"; + description = "nonnegative integer or floating point number, meaning >=0"; + }; + positive = addCheck number (x: x > 0) // { + name = "numberPositive"; + description = "positive integer or floating point number, meaning >0"; + }; + }; + + str = mkOptionType { + name = "str"; + description = "string"; + descriptionClass = "noun"; + check = isString; + merge = mergeEqualOption; + }; + + nonEmptyStr = mkOptionType { + name = "nonEmptyStr"; + description = "non-empty string"; + descriptionClass = "noun"; + check = x: str.check x && builtins.match "[ \t\n]*" x == null; + inherit (str) merge; + }; + + # Allow a newline character at the end and trim it in the merge function. + singleLineStr = + let + inherit (strMatching "[^\n\r]*\n?") check merge; + in + mkOptionType { + name = "singleLineStr"; + description = "(optionally newline-terminated) single-line string"; + descriptionClass = "noun"; + inherit check; + merge = loc: defs: + lib.removeSuffix "\n" (merge loc defs); + }; + + strMatching = pattern: mkOptionType { + name = "strMatching ${escapeNixString pattern}"; + description = "string matching the pattern ${pattern}"; + descriptionClass = "noun"; + check = x: str.check x && builtins.match pattern x != null; + inherit (str) merge; + }; + + # Merge multiple definitions by concatenating them (with the given + # separator between the values). + separatedString = sep: mkOptionType rec { + name = "separatedString"; + description = if sep == "" + then "Concatenated string" # for types.string. + else "strings concatenated with ${builtins.toJSON sep}" + ; + descriptionClass = "noun"; + check = isString; + merge = loc: defs: concatStringsSep sep (getValues defs); + functor = (defaultFunctor name) // { + payload = sep; + binOp = sepLhs: sepRhs: + if sepLhs == sepRhs then sepLhs + else null; + }; + }; + + lines = separatedString "\n"; + commas = separatedString ","; + envVar = separatedString ":"; + + # Deprecated; should not be used because it quietly concatenates + # strings, which is usually not what you want. + string = separatedString "" // { + name = "string"; + deprecationMessage = "See https://github.com/NixOS/nixpkgs/pull/66346 for better alternative types."; + }; + + passwdEntry = entryType: addCheck entryType (str: !(hasInfix ":" str || hasInfix "\n" str)) // { + name = "passwdEntry ${entryType.name}"; + description = "${optionDescriptionPhrase (class: class == "noun") entryType}, not containing newlines or colons"; + }; + + attrs = mkOptionType { + name = "attrs"; + description = "attribute set"; + check = isAttrs; + merge = loc: foldl' (res: def: res // def.value) {}; + emptyValue = { value = {}; }; + }; + + /* + A package is a top-level store path (/nix/store/hash-name). This includes: + + - derivations + - more generally, attribute sets with an `outPath` or `__toString` attribute + pointing to a store path, e.g. flake inputs + - strings with context, e.g. "${pkgs.foo}" or (toString pkgs.foo) + - hardcoded store path literals (/nix/store/hash-foo) or strings without context + ("/nix/store/hash-foo"). These get a context added to them using builtins.storePath. + */ + package = mkOptionType { + name = "package"; + descriptionClass = "noun"; + check = x: isDerivation x || isStorePath x; + merge = loc: defs: + let res = mergeOneOption loc defs; + in if builtins.isPath res || (builtins.isString res && ! builtins.hasContext res) + then toDerivation res + else res; + }; + + shellPackage = package // { + check = x: isDerivation x && hasAttr "shellPath" x; + }; + + path = mkOptionType { + name = "path"; + descriptionClass = "noun"; + check = x: isStringLike x && builtins.substring 0 1 (toString x) == "/"; + merge = mergeEqualOption; + }; + + listOf = elemType: mkOptionType rec { + name = "listOf"; + description = "list of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}"; + descriptionClass = "composite"; + check = isList; + merge = loc: defs: + map (x: x.value) (filter (x: x ? value) (concatLists (imap1 (n: def: + imap1 (m: def': + (mergeDefinitions + (loc ++ ["[definition ${toString n}-entry ${toString m}]"]) + elemType + [{ inherit (def) file; value = def'; }] + ).optionalValue + ) def.value + ) defs))); + emptyValue = { value = []; }; + getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]); + getSubModules = elemType.getSubModules; + substSubModules = m: listOf (elemType.substSubModules m); + functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; + }; + + nonEmptyListOf = elemType: + let list = addCheck (types.listOf elemType) (l: l != []); + in list // { + description = "non-empty ${optionDescriptionPhrase (class: class == "noun") list}"; + emptyValue = { }; # no .value attr, meaning unset + }; + + attrsOf = elemType: mkOptionType rec { + name = "attrsOf"; + description = "attribute set of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}"; + descriptionClass = "composite"; + check = isAttrs; + merge = loc: defs: + mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs: + (mergeDefinitions (loc ++ [name]) elemType defs).optionalValue + ) + # Push down position info. + (map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value) defs))); + emptyValue = { value = {}; }; + getSubOptions = prefix: elemType.getSubOptions (prefix ++ [""]); + getSubModules = elemType.getSubModules; + substSubModules = m: attrsOf (elemType.substSubModules m); + functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; + }; + + # A version of attrsOf that's lazy in its values at the expense of + # conditional definitions not working properly. E.g. defining a value with + # `foo.attr = mkIf false 10`, then `foo ? attr == true`, whereas with + # attrsOf it would correctly be `false`. Accessing `foo.attr` would throw an + # error that it's not defined. Use only if conditional definitions don't make sense. + lazyAttrsOf = elemType: mkOptionType rec { + name = "lazyAttrsOf"; + description = "lazy attribute set of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}"; + descriptionClass = "composite"; + check = isAttrs; + merge = loc: defs: + zipAttrsWith (name: defs: + let merged = mergeDefinitions (loc ++ [name]) elemType defs; + # mergedValue will trigger an appropriate error when accessed + in merged.optionalValue.value or elemType.emptyValue.value or merged.mergedValue + ) + # Push down position info. + (map (def: mapAttrs (n: v: { inherit (def) file; value = v; }) def.value) defs); + emptyValue = { value = {}; }; + getSubOptions = prefix: elemType.getSubOptions (prefix ++ [""]); + getSubModules = elemType.getSubModules; + substSubModules = m: lazyAttrsOf (elemType.substSubModules m); + functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; + }; + + # TODO: deprecate this in the future: + loaOf = elemType: types.attrsOf elemType // { + name = "loaOf"; + deprecationMessage = "Mixing lists with attribute values is no longer" + + " possible; please use `types.attrsOf` instead. See" + + " https://github.com/NixOS/nixpkgs/issues/1800 for the motivation."; + nestedTypes.elemType = elemType; + }; + + # Value of given type but with no merging (i.e. `uniq list`s are not concatenated). + uniq = elemType: mkOptionType rec { + name = "uniq"; + inherit (elemType) description descriptionClass check; + merge = mergeOneOption; + emptyValue = elemType.emptyValue; + getSubOptions = elemType.getSubOptions; + getSubModules = elemType.getSubModules; + substSubModules = m: uniq (elemType.substSubModules m); + functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; + }; + + unique = { message }: type: mkOptionType rec { + name = "unique"; + inherit (type) description descriptionClass check; + merge = mergeUniqueOption { inherit message; }; + emptyValue = type.emptyValue; + getSubOptions = type.getSubOptions; + getSubModules = type.getSubModules; + substSubModules = m: uniq (type.substSubModules m); + functor = (defaultFunctor name) // { wrapped = type; }; + nestedTypes.elemType = type; + }; + + # Null or value of ... + nullOr = elemType: mkOptionType rec { + name = "nullOr"; + description = "null or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") elemType}"; + descriptionClass = "conjunction"; + check = x: x == null || elemType.check x; + merge = loc: defs: + let nrNulls = count (def: def.value == null) defs; in + if nrNulls == length defs then null + else if nrNulls != 0 then + throw "The option `${showOption loc}` is defined both null and not null, in ${showFiles (getFiles defs)}." + else elemType.merge loc defs; + emptyValue = { value = null; }; + getSubOptions = elemType.getSubOptions; + getSubModules = elemType.getSubModules; + substSubModules = m: nullOr (elemType.substSubModules m); + functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; + }; + + functionTo = elemType: mkOptionType { + name = "functionTo"; + description = "function that evaluates to a(n) ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}"; + descriptionClass = "composite"; + check = isFunction; + merge = loc: defs: + fnArgs: (mergeDefinitions (loc ++ [ "" ]) elemType (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs)).mergedValue; + getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "" ]); + getSubModules = elemType.getSubModules; + substSubModules = m: functionTo (elemType.substSubModules m); + functor = (defaultFunctor "functionTo") // { wrapped = elemType; }; + nestedTypes.elemType = elemType; + }; + + # A submodule (like typed attribute set). See NixOS manual. + submodule = modules: submoduleWith { + shorthandOnlyDefinesConfig = true; + modules = toList modules; + }; + + # A module to be imported in some other part of the configuration. + deferredModule = deferredModuleWith { }; + + # A module to be imported in some other part of the configuration. + # `staticModules`' options will be added to the documentation, unlike + # options declared via `config`. + deferredModuleWith = attrs@{ staticModules ? [] }: mkOptionType { + name = "deferredModule"; + description = "module"; + descriptionClass = "noun"; + check = x: isAttrs x || isFunction x || path.check x; + merge = loc: defs: { + imports = staticModules ++ map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs; + }; + inherit (submoduleWith { modules = staticModules; }) + getSubOptions + getSubModules; + substSubModules = m: deferredModuleWith (attrs // { + staticModules = m; + }); + functor = defaultFunctor "deferredModuleWith" // { + type = types.deferredModuleWith; + payload = { + inherit staticModules; + }; + binOp = lhs: rhs: { + staticModules = lhs.staticModules ++ rhs.staticModules; + }; + }; + }; + + # The type of a type! + optionType = mkOptionType { + name = "optionType"; + description = "optionType"; + descriptionClass = "noun"; + check = value: value._type or null == "option-type"; + merge = loc: defs: + if length defs == 1 + then (head defs).value + else let + # Prepares the type definitions for mergeOptionDecls, which + # annotates submodules types with file locations + optionModules = map ({ value, file }: + { + _file = file; + # There's no way to merge types directly from the module system, + # but we can cheat a bit by just declaring an option with the type + options = lib.mkOption { + type = value; + }; + } + ) defs; + # Merges all the types into a single one, including submodule merging. + # This also propagates file information to all submodules + mergedOption = fixupOptionType loc (mergeOptionDecls loc optionModules); + in mergedOption.type; + }; + + submoduleWith = + { modules + , specialArgs ? {} + , shorthandOnlyDefinesConfig ? false + , description ? null + }@attrs: + let + inherit (lib.modules) evalModules; + + allModules = defs: map ({ value, file }: + if isAttrs value && shorthandOnlyDefinesConfig + then { _file = file; config = value; } + else { _file = file; imports = [ value ]; } + ) defs; + + base = evalModules { + inherit specialArgs; + modules = [{ + # This is a work-around for the fact that some sub-modules, + # such as the one included in an attribute set, expects an "args" + # attribute to be given to the sub-module. As the option + # evaluation does not have any specific attribute name yet, we + # provide a default for the documentation and the freeform type. + # + # This is necessary as some option declaration might use the + # "name" attribute given as argument of the submodule and use it + # as the default of option declarations. + # + # We use lookalike unicode single angle quotation marks because + # of the docbook transformation the options receive. In all uses + # > and < wouldn't be encoded correctly so the encoded values + # would be used, and use of `<` and `>` would break the XML document. + # It shouldn't cause an issue since this is cosmetic for the manual. + _module.args.name = lib.mkOptionDefault "‹name›"; + }] ++ modules; + }; + + freeformType = base._module.freeformType; + + name = "submodule"; + + in + mkOptionType { + inherit name; + description = + if description != null then description + else freeformType.description or name; + check = x: isAttrs x || isFunction x || path.check x; + merge = loc: defs: + (base.extendModules { + modules = [ { _module.args.name = last loc; } ] ++ allModules defs; + prefix = loc; + }).config; + emptyValue = { value = {}; }; + getSubOptions = prefix: (base.extendModules + { inherit prefix; }).options // optionalAttrs (freeformType != null) { + # Expose the sub options of the freeform type. Note that the option + # discovery doesn't care about the attribute name used here, so this + # is just to avoid conflicts with potential options from the submodule + _freeformOptions = freeformType.getSubOptions prefix; + }; + getSubModules = modules; + substSubModules = m: submoduleWith (attrs // { + modules = m; + }); + nestedTypes = lib.optionalAttrs (freeformType != null) { + freeformType = freeformType; + }; + functor = defaultFunctor name // { + type = types.submoduleWith; + payload = { + inherit modules specialArgs shorthandOnlyDefinesConfig description; + }; + binOp = lhs: rhs: { + modules = lhs.modules ++ rhs.modules; + specialArgs = + let intersecting = builtins.intersectAttrs lhs.specialArgs rhs.specialArgs; + in if intersecting == {} + then lhs.specialArgs // rhs.specialArgs + else throw "A submoduleWith option is declared multiple times with the same specialArgs \"${toString (attrNames intersecting)}\""; + shorthandOnlyDefinesConfig = + if lhs.shorthandOnlyDefinesConfig == null + then rhs.shorthandOnlyDefinesConfig + else if rhs.shorthandOnlyDefinesConfig == null + then lhs.shorthandOnlyDefinesConfig + else if lhs.shorthandOnlyDefinesConfig == rhs.shorthandOnlyDefinesConfig + then lhs.shorthandOnlyDefinesConfig + else throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values"; + description = + if lhs.description == null + then rhs.description + else if rhs.description == null + then lhs.description + else if lhs.description == rhs.description + then lhs.description + else throw "A submoduleWith option is declared multiple times with conflicting descriptions"; + }; + }; + }; + + # A value from a set of allowed ones. + enum = values: + let + inherit (lib.lists) unique; + show = v: + if builtins.isString v then ''"${v}"'' + else if builtins.isInt v then builtins.toString v + else if builtins.isBool v then boolToString v + else ''<${builtins.typeOf v}>''; + in + mkOptionType rec { + name = "enum"; + description = + # Length 0 or 1 enums may occur in a design pattern with type merging + # where an "interface" module declares an empty enum and other modules + # provide implementations, each extending the enum with their own + # identifier. + if values == [] then + "impossible (empty enum)" + else if builtins.length values == 1 then + "value ${show (builtins.head values)} (singular enum)" + else + "one of ${concatMapStringsSep ", " show values}"; + descriptionClass = + if builtins.length values < 2 + then "noun" + else "conjunction"; + check = flip elem values; + merge = mergeEqualOption; + functor = (defaultFunctor name) // { payload = values; binOp = a: b: unique (a ++ b); }; + }; + + # Either value of type `t1` or `t2`. + either = t1: t2: mkOptionType rec { + name = "either"; + description = "${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t1} or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction" || class == "composite") t2}"; + descriptionClass = "conjunction"; + check = x: t1.check x || t2.check x; + merge = loc: defs: + let + defList = map (d: d.value) defs; + in + if all (x: t1.check x) defList + then t1.merge loc defs + else if all (x: t2.check x) defList + then t2.merge loc defs + else mergeOneOption loc defs; + typeMerge = f': + let mt1 = t1.typeMerge (elemAt f'.wrapped 0).functor; + mt2 = t2.typeMerge (elemAt f'.wrapped 1).functor; + in + if (name == f'.name) && (mt1 != null) && (mt2 != null) + then functor.type mt1 mt2 + else null; + functor = (defaultFunctor name) // { wrapped = [ t1 t2 ]; }; + nestedTypes.left = t1; + nestedTypes.right = t2; + }; + + # Any of the types in the given list + oneOf = ts: + let + head' = if ts == [] then throw "types.oneOf needs to get at least one type in its argument" else head ts; + tail' = tail ts; + in foldl' either head' tail'; + + # Either value of type `coercedType` or `finalType`, the former is + # converted to `finalType` using `coerceFunc`. + coercedTo = coercedType: coerceFunc: finalType: + assert lib.assertMsg (coercedType.getSubModules == null) + "coercedTo: coercedType must not have submodules (it’s a ${ + coercedType.description})"; + mkOptionType rec { + name = "coercedTo"; + description = "${optionDescriptionPhrase (class: class == "noun") finalType} or ${optionDescriptionPhrase (class: class == "noun") coercedType} convertible to it"; + check = x: (coercedType.check x && finalType.check (coerceFunc x)) || finalType.check x; + merge = loc: defs: + let + coerceVal = val: + if coercedType.check val then coerceFunc val + else val; + in finalType.merge loc (map (def: def // { value = coerceVal def.value; }) defs); + emptyValue = finalType.emptyValue; + getSubOptions = finalType.getSubOptions; + getSubModules = finalType.getSubModules; + substSubModules = m: coercedTo coercedType coerceFunc (finalType.substSubModules m); + typeMerge = t1: t2: null; + functor = (defaultFunctor name) // { wrapped = finalType; }; + nestedTypes.coercedType = coercedType; + nestedTypes.finalType = finalType; + }; + + # Augment the given type with an additional type check function. + addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; }; + + }; +}; + +in outer_types // outer_types.types diff --git a/nix_systems b/nix_systems deleted file mode 100644 index 9bdfd5f..0000000 --- a/nix_systems +++ /dev/null @@ -1 +0,0 @@ -x86_64-linux \ No newline at end of file diff --git a/projects.toml b/projects.toml new file mode 100644 index 0000000..08d0cf2 --- /dev/null +++ b/projects.toml @@ -0,0 +1,57 @@ +# projects.toml file describing inputs for dream2nix +# +# To re-generate this file, run: +# nix run .#detect-projects $source +# ... where `$source` points to the source of your project. +# +# If the local flake is unavailable, alternatively execute the app from the +# upstream dream2nix flake: +# nix run github:nix-community/dream2nix#detect-projects $source + +[noogle] +name = "noogle" +relPath = "website" +subsystem = "nodejs" +translator = "package-lock" +builder = "strict-builder" +translators = ["package-lock", "package-json"] + +[noogle.subsystemInfo] +nodejs = 18 + +[indexer] +name = "indexer" +relPath = "indexer" +subsystem = "rust" +translator = "cargo-lock" +translators = ["cargo-lock", "cargo-toml"] + +[indexer.subsystemInfo] +workspaceMembers = [] +[[indexer.subsystemInfo.crates]] +name = "indexer" +relPath = "indexer" +version = "0.1.0" + +[builtins-data] +name = "builtins-data" +relPath = "scripts" +subsystem = "nodejs" +translator = "package-lock" +builder = "strict-builder" +translators = ["package-lock", "package-json"] + +[builtins-data.subsystemInfo] +nodejs = 18 + + +[tests] +name = "tests" +relPath = "tests" +subsystem = "nodejs" +translator = "package-lock" +builder = "strict-builder" +translators = ["package-lock", "package-json"] + +[tests.subsystemInfo] +nodejs = 18 diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 0000000..809ffcf --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1,2 @@ +data.json +node_modules \ No newline at end of file diff --git a/scripts/data/builtins-names.json b/scripts/data/builtins-names.json new file mode 100644 index 0000000..1b6ab1d --- /dev/null +++ b/scripts/data/builtins-names.json @@ -0,0 +1,114 @@ +[ + "abort", + "add", + "addErrorContext", + "all", + "any", + "appendContext", + "attrNames", + "attrValues", + "baseNameOf", + "bitAnd", + "bitOr", + "bitXor", + "break", + "builtins", + "catAttrs", + "ceil", + "compareVersions", + "concatLists", + "concatMap", + "concatStringsSep", + "currentSystem", + "currentTime", + "deepSeq", + "derivation", + "derivationStrict", + "dirOf", + "div", + "elem", + "elemAt", + "false", + "fetchGit", + "fetchMercurial", + "fetchTarball", + "fetchTree", + "fetchurl", + "filter", + "filterSource", + "findFile", + "floor", + "foldl'", + "fromJSON", + "fromTOML", + "functionArgs", + "genList", + "genericClosure", + "getAttr", + "getContext", + "getEnv", + "getFlake", + "groupBy", + "hasAttr", + "hasContext", + "hashFile", + "hashString", + "head", + "import", + "intersectAttrs", + "isAttrs", + "isBool", + "isFloat", + "isFunction", + "isInt", + "isList", + "isNull", + "isPath", + "isString", + "langVersion", + "length", + "lessThan", + "listToAttrs", + "map", + "mapAttrs", + "match", + "mul", + "nixPath", + "nixVersion", + "null", + "parseDrvName", + "partition", + "path", + "pathExists", + "placeholder", + "readDir", + "readFile", + "removeAttrs", + "replaceStrings", + "scopedImport", + "seq", + "sort", + "split", + "splitVersion", + "storeDir", + "storePath", + "stringLength", + "sub", + "substring", + "tail", + "throw", + "toFile", + "toJSON", + "toPath", + "toString", + "toXML", + "trace", + "traceVerbose", + "true", + "tryEval", + "typeOf", + "unsafeDiscardOutputDependency", + "unsafeDiscardStringContext", + "unsafeGetAttrPos", + "zipAttrsWith" +] diff --git a/scripts/data/builtins.types.json b/scripts/data/builtins.types.json index edec254..71ed6f3 100644 --- a/scripts/data/builtins.types.json +++ b/scripts/data/builtins.types.json @@ -108,5 +108,9 @@ "typeOf": { "fn_type": "typeOf :: a -> String" }, "zipAttrsWith": { "fn_type": "zipAttrsWith :: (String -> [a] ) -> [a] -> AttrSet" + }, + + "fromTOML": { + "fn_type": "fromTOML :: String -> { Any }" } } diff --git a/scripts/data/fromTOML.md b/scripts/data/fromTOML.md new file mode 100644 index 0000000..9deacd1 --- /dev/null +++ b/scripts/data/fromTOML.md @@ -0,0 +1,32 @@ +# Parse a TOML-configuration from String + +``` +builtins.fromTOML '' +# Toplevel +foo = "bar" + +# Simple Attrset +[set] +info = "foobar" + +# Nested Attrset +[set.nested] +meta = 42 +'' +-> +{ + foo = "bar"; + set = { + info = "foobar"; + nested = { + meta = 42; + }; + }; +} +``` + +Also works nicely with `readFile`: + +``` +builtins.fromTOML (builtins.readFile ./config.toml) +``` diff --git a/scripts/data/more.json b/scripts/data/more.json new file mode 100644 index 0000000..0250d94 --- /dev/null +++ b/scripts/data/more.json @@ -0,0 +1,47 @@ +{ + "addErrorContext": { + "args": ["s", "c"], + "arity": 2, + "doc": "" + }, + "appendContext": { + "args": ["s", "c"], + "arity": 2, + "doc": "" + }, + "builtins": { + "args": [], + "arity": 0, + "doc": "The set `builtins` contains all the built-in functions and values.\nYou can use `builtins` to test for the availability of features in\nthe Nix installation, e.g.,\n\n```nix\nif builtins ? getEnv then builtins.getEnv \"PATH\" else \"\"\n```\n\nThis allows a Nix expression to fall back gracefully on older Nix\ninstallations that don’t have the desired built-in function." + }, + "currentSystem": { + "args": [], + "arity": 0, + "doc": "The built-in value `currentSystem` evaluates to the Nix platform\nidentifier for the Nix installation on which the expression is being\nevaluated, such as `\"i686-linux\"` or `\"x86_64-darwin\"`." + }, + "currentTime": { + "args": [], + "arity": 0, + "doc": "The built-in value `currentSystem` evaluates to the current seconds since Jan 01 1970. (UTC)." + }, + "false": { + "args": [], + "arity": 0, + "doc": "The built-in boolean value `false`." + }, + "true": { + "args": [], + "arity": 0, + "doc": "The built-in boolean value `true`." + }, + "null": { + "args": [], + "arity": 0, + "doc": "The built-in value `null`." + }, + "fromTOML": { + "args": ["s"], + "arity": 1, + "doc": "# Parse a TOML-configuration from String\n\n```\nbuiltins.fromTOML ''\n# Toplevel\nfoo = \"bar\"\n\n# Simple Attrset\n[set]\ninfo = \"foobar\"\n\n# Nested Attrset\n[set.nested]\nmeta = 42\n''\n-> \n{\n foo = \"bar\";\n set = {\n info = \"foobar\";\n nested = {\n meta = 42;\n };\n };\n}\n```\n\nAlso works nicely with `readFile`:\n\n```\nbuiltins.fromTOML (builtins.readFile ./config.toml)\n```\n" + } +} diff --git a/scripts/make-builtins.js b/scripts/make-builtins.js old mode 100644 new mode 100755 index 682c794..e141203 --- a/scripts/make-builtins.js +++ b/scripts/make-builtins.js @@ -1,25 +1,59 @@ const builtins = require("./data/builtins.json"); +const names = require("./data/builtins-names.json"); const types = require("./data/builtins.types.json"); -const derivation = require("./data/derivation.json"); -builtins["derivation"] = derivation.derivation; - const fs = require("fs"); -const info = Object.entries(builtins).map(([name, meta]) => { - const fn_type = types[name]?.fn_type || null; - const { args, arity, doc } = meta; - return { - id: `builtins.${name}`, - category: "builtins", - fn_type, - name, - description: [ - `takes ${arity} arguments: __\`${args.join("` `")}\`__ \n`, - `${doc}\n`, - ], - }; -}); -fs.writeFile("./models/data/builtins.json", JSON.stringify(info), (err) => { - if (err) { - console.error(err); - } +const { exit } = require("process"); + +const { derivation } = require("./data/derivation.json"); + +const more = require("./data/more.json"); + +builtins["derivation"] = derivation; + +Object.entries(more).forEach((e) => { + const [name, meta] = e; + builtins[name] = meta; }); + +const DATA_PATH = process.argv.length >= 3 && process.argv[2]; + +if (!DATA_PATH) { + console.error("argument OUT_PATH is not set"); + console.info("usage: node make-builtins.js "); + exit(1); +} else { + let leftover = names; + const info = Object.entries(builtins).map(([name, meta]) => { + leftover = leftover.filter((e) => e !== name); + const fn_type = types[name]?.fn_type || null; + const { args, arity, doc } = meta; + console.log( + "arity:" + + `${ + arity > 0 + ? `takes ${arity} arguments: __\`${args.join("` `")}\`__ \n` + : "" + }` + ); + return { + id: `builtins.${name}`, + category: "builtins", + fn_type, + name, + description: [ + `${ + arity > 0 + ? `takes ${arity} arguments: __\`${args.join("` `")}\`__ \n` + : "" + }`, + `${doc}\n`, + ], + }; + }); + console.log({ leftover }); + fs.writeFile(`${DATA_PATH}/data.json`, JSON.stringify(info), (err) => { + if (err) { + console.error(err); + } + }); +} diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 0000000..40e5309 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,11 @@ +{ + "name": "builtins-data", + "version": "1.0.0", + "description": "", + "main": "make-builtins.js", + "scripts": { + "build": "node ./make-builtins.js ./" + }, + "author": "", + "license": "ISC" +} diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..e503ddd --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,3 @@ + +node_modules +data/* \ No newline at end of file diff --git a/tests/__snapshots__/data.test.js.snap b/tests/__snapshots__/data.test.js.snap new file mode 100644 index 0000000..5fcb7cf --- /dev/null +++ b/tests/__snapshots__/data.test.js.snap @@ -0,0 +1,6919 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`has not changed builtins data 1`] = ` +[ + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "Abort Nix expression evaluation and print the error message *s*. +", + ], + "fn_type": "abort :: String", + "id": "builtins.abort", + "name": "abort", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the sum of the numbers *e1* and *e2*. +", + ], + "fn_type": "add :: Number -> Number -> Number", + "id": "builtins.add", + "name": "add", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`pred\` \`list\`__ +", + "Return \`true\` if the function *pred* returns \`true\` for all elements +of *list*, and \`false\` otherwise. +", + ], + "fn_type": "all :: (a -> Bool) -> [a] -> Bool", + "id": "builtins.all", + "name": "all", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`pred\` \`list\`__ +", + "Return \`true\` if the function *pred* returns \`true\` for at least one +element of *list*, and \`false\` otherwise. +", + ], + "fn_type": null, + "id": "builtins.any", + "name": "any", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`set\`__ +", + "Return the names of the attributes in the set *set* in an +alphabetically sorted list. For instance, \`builtins.attrNames { y += 1; x = "foo"; }\` evaluates to \`[ "x" "y" ]\`. +", + ], + "fn_type": "attrNames :: AttrSet -> [a]", + "id": "builtins.attrNames", + "name": "attrNames", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`set\`__ +", + "Return the values of the attributes in the set *set* in the order +corresponding to the sorted attribute names. +", + ], + "fn_type": "attrValues :: AttrSet -> [a]", + "id": "builtins.attrValues", + "name": "attrValues", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "Return the *base name* of the string *s*, that is, everything +following the final slash in the string. This is similar to the GNU +\`basename\` command. +", + ], + "fn_type": "baseNameOf :: String -> String", + "id": "builtins.baseNameOf", + "name": "baseNameOf", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the bitwise AND of the integers *e1* and *e2*. +", + ], + "fn_type": "bitAnd :: Int -> Int -> Int", + "id": "builtins.bitAnd", + "name": "bitAnd", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the bitwise OR of the integers *e1* and *e2*. +", + ], + "fn_type": "bitOr :: Int -> Int -> Int", + "id": "builtins.bitOr", + "name": "bitOr", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the bitwise XOR of the integers *e1* and *e2*. +", + ], + "fn_type": "bitXor :: Int -> Int -> Int", + "id": "builtins.bitXor", + "name": "bitXor", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`v\`__ +", + "In debug mode (enabled using \`--debugger\`), pause Nix expression evaluation and enter the REPL. +Otherwise, return the argument \`v\`. +", + ], + "fn_type": "break :: a -> a", + "id": "builtins.break", + "name": "break", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`attr\` \`list\`__ +", + "Collect each attribute named *attr* from a list of attribute +sets. Attrsets that don't contain the named attribute are +ignored. For example, + +\`\`\`nix +builtins.catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}] +\`\`\` + +evaluates to \`[1 2]\`. +", + ], + "fn_type": "cattAtrs :: String -> [ { \${name} :: a } ] -> [a]", + "id": "builtins.catAttrs", + "name": "catAttrs", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`double\`__ +", + "Converts an IEEE-754 double-precision floating-point number (*double*) to +the next higher integer. + +If the datatype is neither an integer nor a "float", an evaluation error will be +thrown. +", + ], + "fn_type": "ceil :: Float -> Int", + "id": "builtins.ceil", + "name": "ceil", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`s1\` \`s2\`__ +", + "Compare two strings representing versions and return \`-1\` if +version *s1* is older than version *s2*, \`0\` if they are the same, +and \`1\` if *s1* is newer than *s2*. The version comparison +algorithm is the same as the one used by [\`nix-env +-u\`](../command-ref/nix-env.md#operation---upgrade). +", + ], + "fn_type": "compareVersions :: String -> String -> Int", + "id": "builtins.compareVersions", + "name": "compareVersions", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`lists\`__ +", + "Concatenate a list of lists into a single list. +", + ], + "fn_type": "concatLists :: [List] -> []", + "id": "builtins.concatLists", + "name": "concatLists", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`f\` \`list\`__ +", + "This function is equivalent to \`builtins.concatLists (map f list)\` +but is more efficient. +", + ], + "fn_type": "concatMap :: (a -> b) -> [a] -> [b]", + "id": "builtins.concatMap", + "name": "concatMap", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`separator\` \`list\`__ +", + "Concatenate a list of strings with a separator between each +element, e.g. \`concatStringsSep "/" ["usr" "local" "bin"] == +"usr/local/bin"\`. +", + ], + "fn_type": "concatStringsSep :: String -> [String] -> String", + "id": "builtins.concatStringsSep", + "name": "concatStringsSep", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "This is like \`seq e1 e2\`, except that *e1* is evaluated *deeply*: +if it’s a list or set, its elements or attributes are also +evaluated recursively. +", + ], + "fn_type": "deepSeq :: a -> b -> b", + "id": "builtins.deepSeq", + "name": "deepSeq", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "Return the directory part of the string *s*, that is, everything +before the final slash in the string. This is similar to the GNU +\`dirname\` command. +", + ], + "fn_type": "dirOf :: String -> String", + "id": "builtins.dirOf", + "name": "dirOf", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the quotient of the numbers *e1* and *e2*. +", + ], + "fn_type": "div :: Number -> Number -> Number", + "id": "builtins.div", + "name": "div", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`x\` \`xs\`__ +", + "Return \`true\` if a value equal to *x* occurs in the list *xs*, and +\`false\` otherwise. +", + ], + "fn_type": "elem :: a -> [b] -> Bool", + "id": "builtins.elem", + "name": "elem", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`xs\` \`n\`__ +", + "Return element *n* from the list *xs*. Elements are counted starting +from 0. A fatal error occurs if the index is out of bounds. +", + ], + "fn_type": "elemAt :: [a] -> Int -> b", + "id": "builtins.elemAt", + "name": "elemAt", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`args\`__ +", + "Fetch a Nix store closure from a binary cache, rewriting it into +content-addressed form. For example, + +\`\`\`nix +builtins.fetchClosure { + fromStore = "https://cache.nixos.org"; + fromPath = /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1; + toPath = /nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1; +} +\`\`\` + +fetches \`/nix/store/r2jd...\` from the specified binary cache, +and rewrites it into the content-addressed store path +\`/nix/store/ldbh...\`. + +If \`fromPath\` is already content-addressed, or if you are +allowing impure evaluation (\`--impure\`), then \`toPath\` may be +omitted. + +To find out the correct value for \`toPath\` given a \`fromPath\`, +you can use \`nix store make-content-addressed\`: + +\`\`\`console +# nix store make-content-addressed --from https://cache.nixos.org /nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1 +rewrote '/nix/store/r2jd6ygnmirm2g803mksqqjm4y39yi6i-git-2.33.1' to '/nix/store/ldbhlwhh39wha58rm61bkiiwm6j7211j-git-2.33.1' +\`\`\` + +This function is similar to \`builtins.storePath\` in that it +allows you to use a previously built store path in a Nix +expression. However, it is more reproducible because it requires +specifying a binary cache from which the path can be fetched. +Also, requiring a content-addressed final store path avoids the +need for users to configure binary cache public keys. + +This function is only available if you enable the experimental +feature \`fetch-closure\`. +", + ], + "fn_type": "fetchClosure :: AttrSet -> AttrSet", + "id": "builtins.fetchClosure", + "name": "fetchClosure", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`args\`__ +", + "Fetch a path from git. *args* can be a URL, in which case the HEAD +of the repo at that URL is fetched. Otherwise, it can be an +attribute with the following attributes (all except \`url\` optional): + + - url\\ + The URL of the repo. + + - name\\ + The name of the directory the repo should be exported to in the + store. Defaults to the basename of the URL. + + - rev\\ + The git revision to fetch. Defaults to the tip of \`ref\`. + + - ref\\ + The git ref to look for the requested revision under. This is + often a branch or tag name. Defaults to \`HEAD\`. + + By default, the \`ref\` value is prefixed with \`refs/heads/\`. As + of Nix 2.3.0 Nix will not prefix \`refs/heads/\` if \`ref\` starts + with \`refs/\`. + + - submodules\\ + A Boolean parameter that specifies whether submodules should be + checked out. Defaults to \`false\`. + + - shallow\\ + A Boolean parameter that specifies whether fetching a shallow clone + is allowed. Defaults to \`false\`. + + - allRefs\\ + Whether to fetch all refs of the repository. With this argument being + true, it's possible to load a \`rev\` from *any* \`ref\` (by default only + \`rev\`s from the specified \`ref\` are supported). + +Here are some examples of how to use \`fetchGit\`. + + - To fetch a private repository over SSH: + + \`\`\`nix + builtins.fetchGit { + url = "git@github.com:my-secret/repository.git"; + ref = "master"; + rev = "adab8b916a45068c044658c4158d81878f9ed1c3"; + } + \`\`\` + + - To fetch an arbitrary reference: + + \`\`\`nix + builtins.fetchGit { + url = "https://github.com/NixOS/nix.git"; + ref = "refs/heads/0.5-release"; + } + \`\`\` + + - If the revision you're looking for is in the default branch of + the git repository you don't strictly need to specify the branch + name in the \`ref\` attribute. + + However, if the revision you're looking for is in a future + branch for the non-default branch you will need to specify the + the \`ref\` attribute as well. + + \`\`\`nix + builtins.fetchGit { + url = "https://github.com/nixos/nix.git"; + rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452"; + ref = "1.11-maintenance"; + } + \`\`\` + + > **Note** + > + > It is nice to always specify the branch which a revision + > belongs to. Without the branch being specified, the fetcher + > might fail if the default branch changes. Additionally, it can + > be confusing to try a commit from a non-default branch and see + > the fetch fail. If the branch is specified the fault is much + > more obvious. + + - If the revision you're looking for is in the default branch of + the git repository you may omit the \`ref\` attribute. + + \`\`\`nix + builtins.fetchGit { + url = "https://github.com/nixos/nix.git"; + rev = "841fcbd04755c7a2865c51c1e2d3b045976b7452"; + } + \`\`\` + + - To fetch a specific tag: + + \`\`\`nix + builtins.fetchGit { + url = "https://github.com/nixos/nix.git"; + ref = "refs/tags/1.9"; + } + \`\`\` + + - To fetch the latest version of a remote branch: + + \`\`\`nix + builtins.fetchGit { + url = "ssh://git@github.com/nixos/nix.git"; + ref = "master"; + } + \`\`\` + + > **Note** + > + > Nix will refetch the branch in accordance with + > the option \`tarball-ttl\`. + + > **Note** + > + > This behavior is disabled in *Pure evaluation mode*. +", + ], + "fn_type": "fetchgit :: AttrSet -> AttrSet", + "id": "builtins.fetchGit", + "name": "fetchGit", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`args\`__ +", + "Download the specified URL, unpack it and return the path of the +unpacked tree. The file must be a tape archive (\`.tar\`) compressed +with \`gzip\`, \`bzip2\` or \`xz\`. The top-level path component of the +files in the tarball is removed, so it is best if the tarball +contains a single directory at top level. The typical use of the +function is to obtain external Nix expression dependencies, such as +a particular version of Nixpkgs, e.g. + +\`\`\`nix +with import (fetchTarball https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz) {}; + +stdenv.mkDerivation { … } +\`\`\` + +The fetched tarball is cached for a certain amount of time (1 +hour by default) in \`~/.cache/nix/tarballs/\`. You can change the +cache timeout either on the command line with \`--tarball-ttl\` +*number-of-seconds* or in the Nix configuration file by adding +the line \`tarball-ttl = \` *number-of-seconds*. + +Note that when obtaining the hash with \`nix-prefetch-url\` the +option \`--unpack\` is required. + +This function can also verify the contents against a hash. In that +case, the function takes a set instead of a URL. The set requires +the attribute \`url\` and the attribute \`sha256\`, e.g. + +\`\`\`nix +with import (fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz"; + sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2"; +}) {}; + +stdenv.mkDerivation { … } +\`\`\` + +This function is not available if [restricted evaluation +mode](../command-ref/conf-file.md) is enabled. +", + ], + "fn_type": "fetchTarball :: AttrSet -> AttrSet", + "id": "builtins.fetchTarball", + "name": "fetchTarball", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`url\`__ +", + "Download the specified URL and return the path of the downloaded +file. This function is not available if [restricted evaluation +mode](../command-ref/conf-file.md) is enabled. +", + ], + "fn_type": "fetchurl :: String -> AttrSet", + "id": "builtins.fetchurl", + "name": "fetchurl", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`f\` \`list\`__ +", + "Return a list consisting of the elements of *list* for which the +function *f* returns \`true\`. +", + ], + "fn_type": "filter :: (a -> Bool) -> [a] -> [b]", + "id": "builtins.filter", + "name": "filter", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "> **Warning** +> +> \`filterSource\` should not be used to filter store paths. Since +> \`filterSource\` uses the name of the input directory while naming +> the output directory, doing so will produce a directory name in +> the form of \`--\`, where \`-\` is +> the name of the input directory. Since \`\` depends on the +> unfiltered directory, the name of the output directory will +> indirectly depend on files that are filtered out by the +> function. This will trigger a rebuild even when a filtered out +> file is changed. Use \`builtins.path\` instead, which allows +> specifying the name of the output directory. + +This function allows you to copy sources into the Nix store while +filtering certain files. For instance, suppose that you want to use +the directory \`source-dir\` as an input to a Nix expression, e.g. + +\`\`\`nix +stdenv.mkDerivation { + ... + src = ./source-dir; +} +\`\`\` + +However, if \`source-dir\` is a Subversion working copy, then all +those annoying \`.svn\` subdirectories will also be copied to the +store. Worse, the contents of those directories may change a lot, +causing lots of spurious rebuilds. With \`filterSource\` you can +filter out the \`.svn\` directories: + +\`\`\`nix +src = builtins.filterSource + (path: type: type != "directory" || baseNameOf path != ".svn") + ./source-dir; +\`\`\` + +Thus, the first argument *e1* must be a predicate function that is +called for each regular file, directory or symlink in the source +tree *e2*. If the function returns \`true\`, the file is copied to the +Nix store, otherwise it is omitted. The function is called with two +arguments. The first is the full path of the file. The second is a +string that identifies the type of the file, which is either +\`"regular"\`, \`"directory"\`, \`"symlink"\` or \`"unknown"\` (for other +kinds of files such as device nodes or fifos — but note that those +cannot be copied to the Nix store, so if the predicate returns +\`true\` for them, the copy will fail). If you exclude a directory, +the entire corresponding subtree of *e2* will be excluded. +", + ], + "fn_type": "filterSource :: (Path -> String -> Bool) -> Path -> StorePath", + "id": "builtins.filterSource", + "name": "filterSource", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`double\`__ +", + "Converts an IEEE-754 double-precision floating-point number (*double*) to +the next lower integer. + +If the datatype is neither an integer nor a "float", an evaluation error will be +thrown. +", + ], + "fn_type": "floor :: Float -> Int", + "id": "builtins.floor", + "name": "floor", + }, + { + "category": "builtins", + "description": [ + "takes 3 arguments: __\`op\` \`nul\` \`list\`__ +", + "Reduce a list by applying a binary operator, from left to right, +e.g. \`foldl' op nul [x0 x1 x2 ...] = op (op (op nul x0) x1) x2) +...\`. The operator is applied strictly, i.e., its arguments are +evaluated first. For example, \`foldl' (x: y: x + y) 0 [1 2 3]\` +evaluates to 6. +", + ], + "fn_type": "foldl' :: (a -> b -> c) -> a -> [b] -> c", + "id": "builtins.foldl'", + "name": "foldl'", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Convert a JSON string to a Nix value. For example, + +\`\`\`nix +builtins.fromJSON ''{"x": [1, 2, 3], "y": null}'' +\`\`\` + +returns the value \`{ x = [ 1 2 3 ]; y = null; }\`. +", + ], + "fn_type": "fromJSON :: String -> a", + "id": "builtins.fromJSON", + "name": "fromJSON", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`f\`__ +", + "Return a set containing the names of the formal arguments expected +by the function *f*. The value of each attribute is a Boolean +denoting whether the corresponding argument has a default value. For +instance, \`functionArgs ({ x, y ? 123}: ...) = { x = false; y = +true; }\`. + +"Formal argument" here refers to the attributes pattern-matched by +the function. Plain lambdas are not included, e.g. \`functionArgs (x: +...) = { }\`. +", + ], + "fn_type": "functionArgs :: (a) -> AttrSet", + "id": "builtins.functionArgs", + "name": "functionArgs", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`generator\` \`length\`__ +", + "Generate list of size *length*, with each element *i* equal to the +value returned by *generator* \`i\`. For example, + +\`\`\`nix +builtins.genList (x: x * x) 5 +\`\`\` + +returns the list \`[ 0 1 4 9 16 ]\`. +", + ], + "fn_type": "genList :: (a -> b) -> a -> [b]", + "id": "builtins.genList", + "name": "genList", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`attrset\`__ +", + "Take an *attrset* with values named \`startSet\` and \`operator\` in order to +return a *list of attrsets* by starting with the \`startSet\`, recursively +applying the \`operator\` function to each element. The *attrsets* in the +\`startSet\` and produced by the \`operator\` must each contain value named +\`key\` which are comparable to each other. The result is produced by +repeatedly calling the operator for each element encountered with a +unique key, terminating when no new elements are produced. For example, + +\`\`\` +builtins.genericClosure { + startSet = [ {key = 5;} ]; + operator = item: [{ + key = if (item.key / 2 ) * 2 == item.key + then item.key / 2 + else 3 * item.key + 1; + }]; +} +\`\`\` +evaluates to +\`\`\` +[ { key = 5; } { key = 16; } { key = 8; } { key = 4; } { key = 2; } { key = 1; } ] +\`\`\` +", + ], + "fn_type": "genericClosure :: AttrSet -> [AttrSet]", + "id": "builtins.genericClosure", + "name": "genericClosure", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`s\` \`set\`__ +", + "\`getAttr\` returns the attribute named *s* from *set*. Evaluation +aborts if the attribute doesn’t exist. This is a dynamic version of +the \`.\` operator, since *s* is an expression rather than an +identifier. +", + ], + "fn_type": "getAttr :: String -> AttrSet -> a", + "id": "builtins.getAttr", + "name": "getAttr", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "\`getEnv\` returns the value of the environment variable *s*, or an +empty string if the variable doesn’t exist. This function should be +used with care, as it can introduce all sorts of nasty environment +dependencies in your Nix expression. + +\`getEnv\` is used in Nix Packages to locate the file +\`~/.nixpkgs/config.nix\`, which contains user-local settings for Nix +Packages. (That is, it does a \`getEnv "HOME"\` to locate the user’s +home directory.) +", + ], + "fn_type": "getEnv :: String -> String", + "id": "builtins.getEnv", + "name": "getEnv", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`args\`__ +", + "Fetch a flake from a flake reference, and return its output attributes and some metadata. For example: + +\`\`\`nix +(builtins.getFlake "nix/55bc52401966fbffa525c574c14f67b00bc4fb3a").packages.x86_64-linux.nix +\`\`\` + +Unless impure evaluation is allowed (\`--impure\`), the flake reference +must be "locked", e.g. contain a Git revision or content hash. An +example of an unlocked usage is: + +\`\`\`nix +(builtins.getFlake "github:edolstra/dwarffs").rev +\`\`\` + +This function is only available if you enable the experimental feature +\`flakes\`. +", + ], + "fn_type": "getFlake :: AttrSet -> AttrSet", + "id": "builtins.getFlake", + "name": "getFlake", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`f\` \`list\`__ +", + "Groups elements of *list* together by the string returned from the +function *f* called on each element. It returns an attribute set +where each attribute value contains the elements of *list* that are +mapped to the same corresponding attribute name returned by *f*. + +For example, + +\`\`\`nix +builtins.groupBy (builtins.substring 0 1) ["foo" "bar" "baz"] +\`\`\` + +evaluates to + +\`\`\`nix +{ b = [ "bar" "baz" ]; f = [ "foo" ]; } +\`\`\` +", + ], + "fn_type": "groupBy :: (a -> b) -> [a] -> AttrSet", + "id": "builtins.groupBy", + "name": "groupBy", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`s\` \`set\`__ +", + "\`hasAttr\` returns \`true\` if *set* has an attribute named *s*, and +\`false\` otherwise. This is a dynamic version of the \`?\` operator, +since *s* is an expression rather than an identifier. +", + ], + "fn_type": "hasAttr :: String -> AttrSet -> Bool", + "id": "builtins.hasAttr", + "name": "hasAttr", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`type\` \`p\`__ +", + "Return a base-16 representation of the cryptographic hash of the +file at path *p*. The hash algorithm specified by *type* must be one +of \`"md5"\`, \`"sha1"\`, \`"sha256"\` or \`"sha512"\`. +", + ], + "fn_type": "hashFile :: String -> Path -> String", + "id": "builtins.hashFile", + "name": "hashFile", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`type\` \`s\`__ +", + "Return a base-16 representation of the cryptographic hash of string +*s*. The hash algorithm specified by *type* must be one of \`"md5"\`, +\`"sha1"\`, \`"sha256"\` or \`"sha512"\`. +", + ], + "fn_type": "hashString :: String -> String -> String", + "id": "builtins.hashString", + "name": "hashString", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`list\`__ +", + "Return the first element of a list; abort evaluation if the argument +isn’t a list or is an empty list. You can test whether a list is +empty by comparing it with \`[]\`. +", + ], + "fn_type": "head :: [a] -> a", + "id": "builtins.head", + "name": "head", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`path\`__ +", + "Load, parse and return the Nix expression in the file *path*. If +*path* is a directory, the file \` default.nix \` in that directory +is loaded. Evaluation aborts if the file doesn’t exist or contains +an incorrect Nix expression. \`import\` implements Nix’s module +system: you can put any Nix expression (such as a set or a +function) in a separate file, and use it from Nix expressions in +other files. + +> **Note** +> +> Unlike some languages, \`import\` is a regular function in Nix. +> Paths using the angle bracket syntax (e.g., \`import\` *\\*) +> are [normal path values](language-values.md). + +A Nix expression loaded by \`import\` must not contain any *free +variables* (identifiers that are not defined in the Nix expression +itself and are not built-in). Therefore, it cannot refer to +variables that are in scope at the call site. For instance, if you +have a calling expression + +\`\`\`nix +rec { + x = 123; + y = import ./foo.nix; +} +\`\`\` + +then the following \`foo.nix\` will give an error: + +\`\`\`nix +x + 456 +\`\`\` + +since \`x\` is not in scope in \`foo.nix\`. If you want \`x\` to be +available in \`foo.nix\`, you should pass it as a function argument: + +\`\`\`nix +rec { + x = 123; + y = import ./foo.nix x; +} +\`\`\` + +and + +\`\`\`nix +x: x + 456 +\`\`\` + +(The function argument doesn’t have to be called \`x\` in \`foo.nix\`; +any name would work.) +", + ], + "fn_type": "import :: Path -> a", + "id": "builtins.import", + "name": "import", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return a set consisting of the attributes in the set *e2* that also +exist in the set *e1*. +", + ], + "fn_type": "intersectAttrs :: AttrSet -> AttrSet -> AttrSet", + "id": "builtins.intersectAttrs", + "name": "intersectAttrs", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a set, and \`false\` otherwise. +", + ], + "fn_type": "isAttrs :: a -> Bool", + "id": "builtins.isAttrs", + "name": "isAttrs", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a bool, and \`false\` otherwise. +", + ], + "fn_type": "isBool :: a -> Bool", + "id": "builtins.isBool", + "name": "isBool", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a float, and \`false\` otherwise. +", + ], + "fn_type": "isFloat :: a -> Bool", + "id": "builtins.isFloat", + "name": "isFloat", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a function, and \`false\` otherwise. +", + ], + "fn_type": "isFunction :: a -> Bool", + "id": "builtins.isFunction", + "name": "isFunction", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to an integer, and \`false\` otherwise. +", + ], + "fn_type": "isInt :: a -> Bool", + "id": "builtins.isInt", + "name": "isInt", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a list, and \`false\` otherwise. +", + ], + "fn_type": "isList :: a -> Bool", + "id": "builtins.isList", + "name": "isList", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to \`null\`, and \`false\` otherwise. + +> **Warning** +> +> This function is *deprecated*; just write \`e == null\` instead. +", + ], + "fn_type": "isNull :: a -> Bool", + "id": "builtins.isNull", + "name": "isNull", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a path, and \`false\` otherwise. +", + ], + "fn_type": "isPath :: a -> Bool", + "id": "builtins.isPath", + "name": "isPath", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return \`true\` if *e* evaluates to a string, and \`false\` otherwise. +", + ], + "fn_type": "isString :: a -> Bool", + "id": "builtins.isString", + "name": "isString", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return the length of the list *e*. +", + ], + "fn_type": "length :: [a] -> Int", + "id": "builtins.length", + "name": "length", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return \`true\` if the number *e1* is less than the number *e2*, and +\`false\` otherwise. Evaluation aborts if either *e1* or *e2* does not +evaluate to a number. +", + ], + "fn_type": "lessThan :: Number -> Number -> Bool", + "id": "builtins.lessThan", + "name": "lessThan", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Construct a set from a list specifying the names and values of each +attribute. Each element of the list should be a set consisting of a +string-valued attribute \`name\` specifying the name of the attribute, +and an attribute \`value\` specifying its value. Example: + +\`\`\`nix +builtins.listToAttrs + [ { name = "foo"; value = 123; } + { name = "bar"; value = 456; } + ] +\`\`\` + +evaluates to + +\`\`\`nix +{ foo = 123; bar = 456; } +\`\`\` +", + ], + "fn_type": "listToAttrs :: [{name :: String; value :: a}] -> AttrSet", + "id": "builtins.listToAttrs", + "name": "listToAttrs", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`f\` \`list\`__ +", + "Apply the function *f* to each element in the list *list*. For +example, + +\`\`\`nix +map (x: "foo" + x) [ "bar" "bla" "abc" ] +\`\`\` + +evaluates to \`[ "foobar" "foobla" "fooabc" ]\`. +", + ], + "fn_type": "map :: (a -> b) -> [a] -> [b]", + "id": "builtins.map", + "name": "map", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`f\` \`attrset\`__ +", + "Apply function *f* to every element of *attrset*. For example, + +\`\`\`nix +builtins.mapAttrs (name: value: value * 10) { a = 1; b = 2; } +\`\`\` + +evaluates to \`{ a = 10; b = 20; }\`. +", + ], + "fn_type": "mapAttrs :: (a -> b -> c) -> AttrSet -> AttrSet", + "id": "builtins.mapAttrs", + "name": "mapAttrs", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`regex\` \`str\`__ +", + "Returns a list if the [extended POSIX regular +expression](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04) +*regex* matches *str* precisely, otherwise returns \`null\`. Each item +in the list is a regex group. + +\`\`\`nix +builtins.match "ab" "abc" +\`\`\` + +Evaluates to \`null\`. + +\`\`\`nix +builtins.match "abc" "abc" +\`\`\` + +Evaluates to \`[ ]\`. + +\`\`\`nix +builtins.match "a(b)(c)" "abc" +\`\`\` + +Evaluates to \`[ "b" "c" ]\`. + +\`\`\`nix +builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO " +\`\`\` + +Evaluates to \`[ "FOO" ]\`. +", + ], + "fn_type": "match :: String -> String -> Bool", + "id": "builtins.match", + "name": "match", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the product of the numbers *e1* and *e2*. +", + ], + "fn_type": "mul :: Number -> Number -> Number", + "id": "builtins.mul", + "name": "mul", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "Split the string *s* into a package name and version. The package +name is everything up to but not including the first dash followed +by a digit, and the version is everything following that dash. The +result is returned in a set \`{ name, version }\`. Thus, +\`builtins.parseDrvName "nix-0.12pre12876"\` returns \`{ name = +"nix"; version = "0.12pre12876"; }\`. +", + ], + "fn_type": "parseDrvName :: String -> AttrSet", + "id": "builtins.parseDrvName", + "name": "parseDrvName", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`pred\` \`list\`__ +", + "Given a predicate function *pred*, this function returns an +attrset containing a list named \`right\`, containing the elements +in *list* for which *pred* returned \`true\`, and a list named +\`wrong\`, containing the elements for which it returned +\`false\`. For example, + +\`\`\`nix +builtins.partition (x: x > 10) [1 23 9 3 42] +\`\`\` + +evaluates to + +\`\`\`nix +{ right = [ 23 42 ]; wrong = [ 1 9 3 ]; } +\`\`\` +", + ], + "fn_type": "partition :: (a -> Bool) -> [a] -> AttrSet", + "id": "builtins.partition", + "name": "partition", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`args\`__ +", + "An enrichment of the built-in path type, based on the attributes +present in *args*. All are optional except \`path\`: + + - path\\ + The underlying path. + + - name\\ + The name of the path when added to the store. This can used to + reference paths that have nix-illegal characters in their names, + like \`@\`. + + - filter\\ + A function of the type expected by \`builtins.filterSource\`, + with the same semantics. + + - recursive\\ + When \`false\`, when \`path\` is added to the store it is with a + flat hash, rather than a hash of the NAR serialization of the + file. Thus, \`path\` must refer to a regular file, not a + directory. This allows similar behavior to \`fetchurl\`. Defaults + to \`true\`. + + - sha256\\ + When provided, this is the expected hash of the file at the + path. Evaluation will fail if the hash is incorrect, and + providing a hash allows \`builtins.path\` to be used even when the + \`pure-eval\` nix config option is on. +", + ], + "fn_type": null, + "id": "builtins.path", + "name": "path", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`path\`__ +", + "Return \`true\` if the path *path* exists at evaluation time, and +\`false\` otherwise. +", + ], + "fn_type": "pathExists :: Path -> Bool", + "id": "builtins.pathExists", + "name": "pathExists", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`output\`__ +", + "Return a placeholder string for the specified *output* that will be +substituted by the corresponding output path at build time. Typical +outputs would be \`"out"\`, \`"bin"\` or \`"dev"\`. +", + ], + "fn_type": "placeholder :: String -> String", + "id": "builtins.placeholder", + "name": "placeholder", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`path\`__ +", + "Return the contents of the directory *path* as a set mapping +directory entries to the corresponding file type. For instance, if +directory \`A\` contains a regular file \`B\` and another directory +\`C\`, then \`builtins.readDir ./A\` will return the set + +\`\`\`nix +{ B = "regular"; C = "directory"; } +\`\`\` + +The possible values for the file type are \`"regular"\`, +\`"directory"\`, \`"symlink"\` and \`"unknown"\`. +", + ], + "fn_type": "readDir :: Path -> AttrSet", + "id": "builtins.readDir", + "name": "readDir", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`path\`__ +", + "Return the contents of the file *path* as a string. +", + ], + "fn_type": "readFile :: Path -> String", + "id": "builtins.readFile", + "name": "readFile", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`set\` \`list\`__ +", + "Remove the attributes listed in *list* from *set*. The attributes +don’t have to exist in *set*. For instance, + +\`\`\`nix +removeAttrs { x = 1; y = 2; z = 3; } [ "a" "x" "z" ] +\`\`\` + +evaluates to \`{ y = 2; }\`. +", + ], + "fn_type": "removeAttrs :: AttrSet -> [a] -> AttrSet", + "id": "builtins.removeAttrs", + "name": "removeAttrs", + }, + { + "category": "builtins", + "description": [ + "takes 3 arguments: __\`from\` \`to\` \`s\`__ +", + "Given string *s*, replace every occurrence of the strings in *from* +with the corresponding string in *to*. For example, + +\`\`\`nix +builtins.replaceStrings ["oo" "a"] ["a" "i"] "foobar" +\`\`\` + +evaluates to \`"fabir"\`. +", + ], + "fn_type": "replaceStrings :: [String] -> [String] -> String -> String", + "id": "builtins.replaceStrings", + "name": "replaceStrings", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Evaluate *e1*, then evaluate and return *e2*. This ensures that a +computation is strict in the value of *e1*. +", + ], + "fn_type": "seq :: a -> b -> b", + "id": "builtins.seq", + "name": "seq", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`comparator\` \`list\`__ +", + "Return *list* in sorted order. It repeatedly calls the function +*comparator* with two elements. The comparator should return \`true\` +if the first element is less than the second, and \`false\` otherwise. +For example, + +\`\`\`nix +builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ] +\`\`\` + +produces the list \`[ 42 77 147 249 483 526 ]\`. + +This is a stable sort: it preserves the relative order of elements +deemed equal by the comparator. +", + ], + "fn_type": "sort :: (a -> b -> Bool) -> [a] -> [b]", + "id": "builtins.sort", + "name": "sort", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`regex\` \`str\`__ +", + "Returns a list composed of non matched strings interleaved with the +lists of the [extended POSIX regular +expression](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04) +*regex* matches of *str*. Each item in the lists of matched +sequences is a regex group. + +\`\`\`nix +builtins.split "(a)b" "abc" +\`\`\` + +Evaluates to \`[ "" [ "a" ] "c" ]\`. + +\`\`\`nix +builtins.split "([ac])" "abc" +\`\`\` + +Evaluates to \`[ "" [ "a" ] "b" [ "c" ] "" ]\`. + +\`\`\`nix +builtins.split "(a)|(c)" "abc" +\`\`\` + +Evaluates to \`[ "" [ "a" null ] "b" [ null "c" ] "" ]\`. + +\`\`\`nix +builtins.split "([[:upper:]]+)" " FOO " +\`\`\` + +Evaluates to \`[ " " [ "FOO" ] " " ]\`. +", + ], + "fn_type": "split :: String -> String -> [String]", + "id": "builtins.split", + "name": "split", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "Split a string representing a version into its components, by the +same version splitting logic underlying the version comparison in +[\`nix-env -u\`](../command-ref/nix-env.md#operation---upgrade). +", + ], + "fn_type": "splitVersion :: String -> [String]", + "id": "builtins.splitVersion", + "name": "splitVersion", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`path\`__ +", + "This function allows you to define a dependency on an already +existing store path. For example, the derivation attribute \`src += builtins.storePath /nix/store/f1d18v1y…-source\` causes the +derivation to depend on the specified path, which must exist or +be substitutable. Note that this differs from a plain path +(e.g. \`src = /nix/store/f1d18v1y…-source\`) in that the latter +causes the path to be *copied* again to the Nix store, resulting +in a new path (e.g. \`/nix/store/ld01dnzc…-source-source\`). + +This function is not available in pure evaluation mode. +", + ], + "fn_type": null, + "id": "builtins.storePath", + "name": "storePath", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return the length of the string *e*. If *e* is not a string, +evaluation is aborted. +", + ], + "fn_type": "stringLength :: String -> Int", + "id": "builtins.stringLength", + "name": "stringLength", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Return the difference between the numbers *e1* and *e2*. +", + ], + "fn_type": "sub :: Number -> Number -> Number", + "id": "builtins.sub", + "name": "sub", + }, + { + "category": "builtins", + "description": [ + "takes 3 arguments: __\`start\` \`len\` \`s\`__ +", + "Return the substring of *s* from character position *start* +(zero-based) up to but not including *start + len*. If *start* is +greater than the length of the string, an empty string is returned, +and if *start + len* lies beyond the end of the string, only the +substring up to the end of the string is returned. *start* must be +non-negative. For example, + +\`\`\`nix +builtins.substring 0 3 "nixos" +\`\`\` + +evaluates to \`"nix"\`. +", + ], + "fn_type": "substring :: Int -> Int -> String -> String", + "id": "builtins.substring", + "name": "substring", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`list\`__ +", + "Return the second to last elements of a list; abort evaluation if +the argument isn’t a list or is an empty list. + +> **Warning** +> +> This function should generally be avoided since it's inefficient: +> unlike Haskell's \`tail\`, it takes O(n) time, so recursing over a +> list by repeatedly calling \`tail\` takes O(n^2) time. +", + ], + "fn_type": "tail :: [a] -> a", + "id": "builtins.tail", + "name": "tail", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "Throw an error message *s*. This usually aborts Nix expression +evaluation, but in \`nix-env -qa\` and other commands that try to +evaluate a set of derivations to get information about those +derivations, a derivation that throws an error is silently skipped +(which is not the case for \`abort\`). +", + ], + "fn_type": "throw :: String", + "id": "builtins.throw", + "name": "throw", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`name\` \`s\`__ +", + "Store the string *s* in a file in the Nix store and return its +path. The file has suffix *name*. This file can be used as an +input to derivations. One application is to write builders +“inline”. For instance, the following Nix expression combines the +[Nix expression for GNU Hello](expression-syntax.md) and its +[build script](build-script.md) into one file: + +\`\`\`nix +{ stdenv, fetchurl, perl }: + +stdenv.mkDerivation { + name = "hello-2.1.1"; + + builder = builtins.toFile "builder.sh" " + source $stdenv/setup + + PATH=$perl/bin:$PATH + + tar xvfz $src + cd hello-* + ./configure --prefix=$out + make + make install + "; + + src = fetchurl { + url = "http://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz"; + sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465"; + }; + inherit perl; +} +\`\`\` + +It is even possible for one file to refer to another, e.g., + +\`\`\`nix +builder = let + configFile = builtins.toFile "foo.conf" " + # This is some dummy configuration file. + ... + "; +in builtins.toFile "builder.sh" " + source $stdenv/setup + ... + cp \${configFile} $out/etc/foo.conf +"; +\`\`\` + +Note that \`\${configFile}\` is an +[antiquotation](language-values.md), so the result of the +expression \`configFile\` +(i.e., a path like \`/nix/store/m7p7jfny445k...-foo.conf\`) will be +spliced into the resulting string. + +It is however *not* allowed to have files mutually referring to each +other, like so: + +\`\`\`nix +let + foo = builtins.toFile "foo" "...\${bar}..."; + bar = builtins.toFile "bar" "...\${foo}..."; +in foo +\`\`\` + +This is not allowed because it would cause a cyclic dependency in +the computation of the cryptographic hashes for \`foo\` and \`bar\`. + +It is also not possible to reference the result of a derivation. If +you are using Nixpkgs, the \`writeTextFile\` function is able to do +that. +", + ], + "fn_type": "toFile :: Path -> String -> StorePath ", + "id": "builtins.toFile", + "name": "toFile", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return a string containing a JSON representation of *e*. Strings, +integers, floats, booleans, nulls and lists are mapped to their JSON +equivalents. Sets (except derivations) are represented as objects. +Derivations are translated to a JSON string containing the +derivation’s output path. Paths are copied to the store and +represented as a JSON string of the resulting store path. +", + ], + "fn_type": "toJSON :: a -> String", + "id": "builtins.toJSON", + "name": "toJSON", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "**DEPRECATED.** Use \`/. + "/path"\` to convert a string into an absolute +path. For relative paths, use \`./. + "/path"\`. +", + ], + "fn_type": "toPath :: String -> Path", + "id": "builtins.toPath", + "name": "toPath", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Convert the expression *e* to a string. *e* can be: + + - A string (in which case the string is returned unmodified). + + - A path (e.g., \`toString /foo/bar\` yields \`"/foo/bar"\`. + + - A set containing \`{ __toString = self: ...; }\` or \`{ outPath = ...; }\`. + + - An integer. + + - A list, in which case the string representations of its elements + are joined with spaces. + + - A Boolean (\`false\` yields \`""\`, \`true\` yields \`"1"\`). + + - \`null\`, which yields the empty string. +", + ], + "fn_type": "toString :: a -> String", + "id": "builtins.toString", + "name": "toString", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return a string containing an XML representation of *e*. The main +application for \`toXML\` is to communicate information with the +builder in a more structured format than plain environment +variables. + +Here is an example where this is the case: + +\`\`\`nix +{ stdenv, fetchurl, libxslt, jira, uberwiki }: + +stdenv.mkDerivation (rec { + name = "web-server"; + + buildInputs = [ libxslt ]; + + builder = builtins.toFile "builder.sh" " + source $stdenv/setup + mkdir $out + echo "$servlets" | xsltproc \${stylesheet} - > $out/server-conf.xml ① + "; + + stylesheet = builtins.toFile "stylesheet.xsl" ② + " + + + + + + + + + + + + + "; + + servlets = builtins.toXML [ ③ + { path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; } + { path = "/wiki"; war = uberwiki + "/uberwiki.war"; } + ]; +}) +\`\`\` + +The builder is supposed to generate the configuration file for a +[Jetty servlet container](http://jetty.mortbay.org/). A servlet +container contains a number of servlets (\`*.war\` files) each +exported under a specific URI prefix. So the servlet configuration +is a list of sets containing the \`path\` and \`war\` of the servlet +(①). This kind of information is difficult to communicate with the +normal method of passing information through an environment +variable, which just concatenates everything together into a +string (which might just work in this case, but wouldn’t work if +fields are optional or contain lists themselves). Instead the Nix +expression is converted to an XML representation with \`toXML\`, +which is unambiguous and can easily be processed with the +appropriate tools. For instance, in the example an XSLT stylesheet +(at point ②) is applied to it (at point ①) to generate the XML +configuration file for the Jetty server. The XML representation +produced at point ③ by \`toXML\` is as follows: + +\`\`\`xml + + + + + + + + + + + + + + + + + + + + + +\`\`\` + +Note that we used the \`toFile\` built-in to write the builder and +the stylesheet “inline” in the Nix expression. The path of the +stylesheet is spliced into the builder using the syntax \`xsltproc +\${stylesheet}\`. +", + ], + "fn_type": "toXML :: a -> String", + "id": "builtins.toXML", + "name": "toXML", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Evaluate *e1* and print its abstract syntax representation on +standard error. Then return *e2*. This function is useful for +debugging. +", + ], + "fn_type": "trace :: a -> b -> b", + "id": "builtins.trace", + "name": "trace", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`e1\` \`e2\`__ +", + "Evaluate *e1* and print its abstract syntax representation on standard +error if \`--trace-verbose\` is enabled. Then return *e2*. This function +is useful for debugging. +", + ], + "fn_type": "traceVerbose :: a -> b -> b", + "id": "builtins.traceVerbose", + "name": "traceVerbose", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Try to shallowly evaluate *e*. Return a set containing the +attributes \`success\` (\`true\` if *e* evaluated successfully, +\`false\` if an error was thrown) and \`value\`, equalling *e* if +successful and \`false\` otherwise. \`tryEval\` will only prevent +errors created by \`throw\` or \`assert\` from being thrown. +Errors \`tryEval\` will not catch are for example those created +by \`abort\` and type errors generated by builtins. Also note that +this doesn't evaluate *e* deeply, so \`let e = { x = throw ""; }; +in (builtins.tryEval e).success\` will be \`true\`. Using +\`builtins.deepSeq\` one can get the expected result: +\`let e = { x = throw ""; }; in +(builtins.tryEval (builtins.deepSeq e e)).success\` will be +\`false\`. +", + ], + "fn_type": "tryEval :: a", + "id": "builtins.tryEval", + "name": "tryEval", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`e\`__ +", + "Return a string representing the type of the value *e*, namely +\`"int"\`, \`"bool"\`, \`"string"\`, \`"path"\`, \`"null"\`, \`"set"\`, +\`"list"\`, \`"lambda"\` or \`"float"\`. +", + ], + "fn_type": "typeOf :: a -> String", + "id": "builtins.typeOf", + "name": "typeOf", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`f\` \`list\`__ +", + "Transpose a list of attribute sets into an attribute set of lists, +then apply \`mapAttrs\`. + +\`f\` receives two arguments: the attribute name and a non-empty +list of all values encountered for that attribute name. + +The result is an attribute set where the attribute names are the +union of the attribute names in each element of \`list\`. The attribute +values are the return values of \`f\`. + +\`\`\`nix +builtins.zipAttrsWith + (name: values: { inherit name values; }) + [ { a = "x"; } { a = "y"; b = "z"; } ] +\`\`\` + +evaluates to + +\`\`\` +{ + a = { name = "a"; values = [ "x" "y" ]; }; + b = { name = "b"; values = [ "z" ]; }; +} +\`\`\` +", + ], + "fn_type": "zipAttrsWith :: (String -> [a] ) -> [a] -> AttrSet", + "id": "builtins.zipAttrsWith", + "name": "zipAttrsWith", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "# Derivations + +The most important built-in function is \`derivation\`, which is used to +describe a single derivation (a build task). It takes as input a set, +the attributes of which specify the inputs of the build. + + - There must be an attribute named [\`system\`]{#attr-system} whose value must be a + string specifying a Nix system type, such as \`"i686-linux"\` or + \`"x86_64-darwin"\`. (To figure out your system type, run \`nix -vv + --version\`.) The build can only be performed on a machine and + operating system matching the system type. (Nix can automatically + [forward builds for other + platforms](../advanced-topics/distributed-builds.md) by forwarding + them to other machines.) + + - There must be an attribute named \`name\` whose value must be a + string. This is used as a symbolic name for the package by + \`nix-env\`, and it is appended to the output paths of the derivation. + + - There must be an attribute named \`builder\` that identifies the + program that is executed to perform the build. It can be either a + derivation or a source (a local file reference, e.g., + \`./builder.sh\`). + + - Every attribute is passed as an environment variable to the builder. + Attribute values are translated to environment variables as follows: + + - Strings and numbers are just passed verbatim. + + - A *path* (e.g., \`../foo/sources.tar\`) causes the referenced file + to be copied to the store; its location in the store is put in + the environment variable. The idea is that all sources should + reside in the Nix store, since all inputs to a derivation should + reside in the Nix store. + + - A *derivation* causes that derivation to be built prior to the + present derivation; its default output path is put in the + environment variable. + + - Lists of the previous types are also allowed. They are simply + concatenated, separated by spaces. + + - \`true\` is passed as the string \`1\`, \`false\` and \`null\` are + passed as an empty string. + + - The optional attribute \`args\` specifies command-line arguments to be + passed to the builder. It should be a list. + + - The optional attribute \`outputs\` specifies a list of symbolic + outputs of the derivation. By default, a derivation produces a + single output path, denoted as \`out\`. However, derivations can + produce multiple output paths. This is useful because it allows + outputs to be downloaded or garbage-collected separately. For + instance, imagine a library package that provides a dynamic library, + header files, and documentation. A program that links against the + library doesn’t need the header files and documentation at runtime, + and it doesn’t need the documentation at build time. Thus, the + library package could specify: + + \`\`\`nix + outputs = [ "lib" "headers" "doc" ]; + \`\`\` + + This will cause Nix to pass environment variables \`lib\`, \`headers\` + and \`doc\` to the builder containing the intended store paths of each + output. The builder would typically do something like + + \`\`\`bash + ./configure \\n --libdir=$lib/lib \\n --includedir=$headers/include \\n --docdir=$doc/share/doc + \`\`\` + + for an Autoconf-style package. You can refer to each output of a + derivation by selecting it as an attribute, e.g. + + \`\`\`nix + buildInputs = [ pkg.lib pkg.headers ]; + \`\`\` + + The first element of \`outputs\` determines the *default output*. + Thus, you could also write + + \`\`\`nix + buildInputs = [ pkg pkg.headers ]; + \`\`\` + + since \`pkg\` is equivalent to \`pkg.lib\`. + +The function \`mkDerivation\` in the Nixpkgs standard environment is a +wrapper around \`derivation\` that adds a default value for \`system\` and +always uses Bash as the builder, to which the supplied builder is passed +as a command-line argument. See the Nixpkgs manual for details. + +The builder is executed as follows: + + - A temporary directory is created under the directory specified by + \`TMPDIR\` (default \`/tmp\`) where the build will take place. The + current directory is changed to this directory. + + - The environment is cleared and set to the derivation attributes, as + specified above. + + - In addition, the following variables are set: + + - \`NIX_BUILD_TOP\` contains the path of the temporary directory for + this build. + + - Also, \`TMPDIR\`, \`TEMPDIR\`, \`TMP\`, \`TEMP\` are set to point to the + temporary directory. This is to prevent the builder from + accidentally writing temporary files anywhere else. Doing so + might cause interference by other processes. + + - \`PATH\` is set to \`/path-not-set\` to prevent shells from + initialising it to their built-in default value. + + - \`HOME\` is set to \`/homeless-shelter\` to prevent programs from + using \`/etc/passwd\` or the like to find the user's home + directory, which could cause impurity. Usually, when \`HOME\` is + set, it is used as the location of the home directory, even if + it points to a non-existent path. + + - \`NIX_STORE\` is set to the path of the top-level Nix store + directory (typically, \`/nix/store\`). + + - For each output declared in \`outputs\`, the corresponding + environment variable is set to point to the intended path in the + Nix store for that output. Each output path is a concatenation + of the cryptographic hash of all build inputs, the \`name\` + attribute and the output name. (The output name is omitted if + it’s \`out\`.) + + - If an output path already exists, it is removed. Also, locks are + acquired to prevent multiple Nix instances from performing the same + build at the same time. + + - A log of the combined standard output and error is written to + \`/nix/var/log/nix\`. + + - The builder is executed with the arguments specified by the + attribute \`args\`. If it exits with exit code 0, it is considered to + have succeeded. + + - The temporary directory is removed (unless the \`-K\` option was + specified). + + - If the build was successful, Nix scans each output path for + references to input paths by looking for the hash parts of the input + paths. Since these are potential runtime dependencies, Nix registers + them as dependencies of the output paths. + + - After the build, Nix sets the last-modified timestamp on all files + in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to + the default group, and sets the mode of the file to 0444 or 0555 + (i.e., read-only, with execute permission enabled if the file was + originally executable). Note that possible \`setuid\` and \`setgid\` + bits are cleared. Setuid and setgid programs are not currently + supported by Nix. This is because the Nix archives used in + deployment have no concept of ownership information, and because it + makes the build result dependent on the user performing the build. +", + ], + "fn_type": "let + Derivation :: { + all :: [ Derivation ]; + builder :: String; + drvAttrs :: { + builder = String; + name = String; + outputs = [ output :: String ]; + system = String; + \${additionalArgs} :: String; + } + drvPath :: String; + name :: String; + outPath :: String; + outputName :: String; + outputs :: [ output :: String ]; + system :: String; + type :: "derivation"; + \${output} :: Derivation; + \${additionalArgs} :: String; + }; +in + builtins.derivation :: { + name :: String; + outputs :: [ output :: String ] ? [ "out" ]; + builder :: String; + system :: String; + \${additionalArgs} :: String; + } -> Derivation", + "id": "builtins.derivation", + "name": "derivation", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`s\` \`c\`__ +", + " +", + ], + "fn_type": null, + "id": "builtins.addErrorContext", + "name": "addErrorContext", + }, + { + "category": "builtins", + "description": [ + "takes 2 arguments: __\`s\` \`c\`__ +", + " +", + ], + "fn_type": null, + "id": "builtins.appendContext", + "name": "appendContext", + }, + { + "category": "builtins", + "description": [ + "", + "The set \`builtins\` contains all the built-in functions and values. +You can use \`builtins\` to test for the availability of features in +the Nix installation, e.g., + +\`\`\`nix +if builtins ? getEnv then builtins.getEnv "PATH" else "" +\`\`\` + +This allows a Nix expression to fall back gracefully on older Nix +installations that don’t have the desired built-in function. +", + ], + "fn_type": null, + "id": "builtins.builtins", + "name": "builtins", + }, + { + "category": "builtins", + "description": [ + "", + "The built-in value \`currentSystem\` evaluates to the Nix platform +identifier for the Nix installation on which the expression is being +evaluated, such as \`"i686-linux"\` or \`"x86_64-darwin"\`. +", + ], + "fn_type": null, + "id": "builtins.currentSystem", + "name": "currentSystem", + }, + { + "category": "builtins", + "description": [ + "", + "The built-in value \`currentSystem\` evaluates to the current seconds since Jan 01 1970. (UTC). +", + ], + "fn_type": null, + "id": "builtins.currentTime", + "name": "currentTime", + }, + { + "category": "builtins", + "description": [ + "", + "The built-in boolean value \`false\`. +", + ], + "fn_type": null, + "id": "builtins.false", + "name": "false", + }, + { + "category": "builtins", + "description": [ + "", + "The built-in boolean value \`true\`. +", + ], + "fn_type": null, + "id": "builtins.true", + "name": "true", + }, + { + "category": "builtins", + "description": [ + "", + "The built-in value \`null\`. +", + ], + "fn_type": null, + "id": "builtins.null", + "name": "null", + }, + { + "category": "builtins", + "description": [ + "takes 1 arguments: __\`s\`__ +", + "# Parse a TOML-configuration from String + +\`\`\` +builtins.fromTOML '' +# Toplevel +foo = "bar" + +# Simple Attrset +[set] +info = "foobar" + +# Nested Attrset +[set.nested] +meta = 42 +'' +-> +{ + foo = "bar"; + set = { + info = "foobar"; + nested = { + meta = 42; + }; + }; +} +\`\`\` + +Also works nicely with \`readFile\`: + +\`\`\` +builtins.fromTOML (builtins.readFile ./config.toml) +\`\`\` + +", + ], + "fn_type": "fromTOML :: String -> { Any }", + "id": "builtins.fromTOML", + "name": "fromTOML", + }, +] +`; + +exports[`has not changed lib data 1`] = ` +[ + { + "category": "./lib/versions.nix", + "description": "Break a version string into its component parts.", + "example": "splitVersion "1.2.3" +=> ["1" "2" "3"]", + "fn_type": null, + "id": "lib.versions.splitVersion", + "line": 12, + "name": "splitVersion", + }, + { + "category": "./lib/versions.nix", + "description": "Get the major version string from a string.", + "example": "major "1.2.3" +=> "1"", + "fn_type": null, + "id": "lib.versions.major", + "line": 20, + "name": "major", + }, + { + "category": "./lib/versions.nix", + "description": "Get the minor version string from a string.", + "example": "minor "1.2.3" +=> "2"", + "fn_type": null, + "id": "lib.versions.minor", + "line": 28, + "name": "minor", + }, + { + "category": "./lib/versions.nix", + "description": "Get the patch version string from a string.", + "example": "patch "1.2.3" +=> "3"", + "fn_type": null, + "id": "lib.versions.patch", + "line": 36, + "name": "patch", + }, + { + "category": "./lib/versions.nix", + "description": "Get string of the first two parts (major and minor) + of a version string.", + "example": "majorMinor "1.2.3" +=> "1.2"", + "fn_type": null, + "id": "lib.versions.majorMinor", + "line": 45, + "name": "majorMinor", + }, + { + "category": "./lib/versions.nix", + "description": "Pad a version string with zeros to match the given number of components.", + "example": "pad 3 "1.2" +=> "1.2.0" +pad 3 "1.3-rc1" +=> "1.3.0-rc1" +pad 3 "1.2.3.4" +=> "1.2.3"", + "fn_type": null, + "id": "lib.versions.pad", + "line": 59, + "name": "pad", + }, + { + "category": "./lib/trivial.nix", + "description": "The identity function + For when you need a function that does “nothing”.", + "example": null, + "fn_type": "id :: a -> a", + "id": "lib.trivial.id", + "line": 13, + "name": "id", + }, + { + "category": "./lib/trivial.nix", + "description": "The constant function + + Ignores the second argument. If called with only one argument, + constructs a function that always returns a static value.", + "example": "let f = const 5; in f 10 +=> 5", + "fn_type": "const :: a -> b -> a", + "id": "lib.trivial.const", + "line": 26, + "name": "const", + }, + { + "category": "./lib/trivial.nix", + "description": "Pipes a value through a list of functions, left to right.", + "example": "pipe 2 [ + (x: x + 2) # 2 + 2 = 4 + (x: x * 2) # 4 * 2 = 8 +] +=> 8 + +# ideal to do text transformations +pipe [ "a/b" "a/c" ] [ + + # create the cp command + (map (file: ''cp "\${src}/\${file}" $out\\n'')) + + # concatenate all commands into one string + lib.concatStrings + + # make that string into a nix derivation + (pkgs.runCommand "copy-to-out" {}) + +] +=> + + The output type of each function has to be the input type + of the next function, and the last function returns the + final value.", + "fn_type": "pipe :: a -> [] -> ", + "id": "lib.trivial.pipe", + "line": 61, + "name": "pipe", + }, + { + "category": "./lib/trivial.nix", + "description": "Concatenate two lists", + "example": "concat [ 1 2 ] [ 3 4 ] +=> [ 1 2 3 4 ]", + "fn_type": "concat :: [a] -> [a] -> [a]", + "id": "lib.trivial.concat", + "line": 80, + "name": "concat", + }, + { + "category": "./lib/trivial.nix", + "description": "boolean “or”", + "example": null, + "fn_type": null, + "id": "lib.trivial.or", + "line": 83, + "name": "or", + }, + { + "category": "./lib/trivial.nix", + "description": "boolean “and”", + "example": null, + "fn_type": null, + "id": "lib.trivial.and", + "line": 86, + "name": "and", + }, + { + "category": "./lib/trivial.nix", + "description": "bitwise “and”", + "example": null, + "fn_type": null, + "id": "lib.trivial.bitAnd", + "line": 89, + "name": "bitAnd", + }, + { + "category": "./lib/trivial.nix", + "description": "bitwise “or”", + "example": null, + "fn_type": null, + "id": "lib.trivial.bitOr", + "line": 95, + "name": "bitOr", + }, + { + "category": "./lib/trivial.nix", + "description": "bitwise “xor”", + "example": null, + "fn_type": null, + "id": "lib.trivial.bitXor", + "line": 100, + "name": "bitXor", + }, + { + "category": "./lib/trivial.nix", + "description": "bitwise “not”", + "example": null, + "fn_type": null, + "id": "lib.trivial.bitNot", + "line": 106, + "name": "bitNot", + }, + { + "category": "./lib/trivial.nix", + "description": "Convert a boolean to a string. + + This function uses the strings "true" and "false" to represent + boolean values. Calling \`toString\` on a bool instead returns "1" + and "" (sic!).", + "example": null, + "fn_type": "boolToString :: bool -> string", + "id": "lib.trivial.boolToString", + "line": 114, + "name": "boolToString", + }, + { + "category": "./lib/trivial.nix", + "description": "Merge two attribute sets shallowly, right side trumps left + + mergeAttrs :: attrs -> attrs -> attrs", + "example": "mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; } +=> { a = 1; b = 3; c = 4; }", + "fn_type": null, + "id": "lib.trivial.mergeAttrs", + "line": 125, + "name": "mergeAttrs", + }, + { + "category": "./lib/trivial.nix", + "description": "Flip the order of the arguments of a binary function.", + "example": "flip concat [1] [2] +=> [ 2 1 ]", + "fn_type": "flip :: (a -> b -> c) -> (b -> a -> c)", + "id": "lib.trivial.flip", + "line": 140, + "name": "flip", + }, + { + "category": "./lib/trivial.nix", + "description": "Apply function if the supplied argument is non-null.", + "example": "mapNullable (x: x+1) null +=> null +mapNullable (x: x+1) 22 +=> 23", + "fn_type": null, + "id": "lib.trivial.mapNullable", + "line": 149, + "name": "mapNullable", + }, + { + "category": "./lib/trivial.nix", + "description": "Returns the current full nixpkgs version number.", + "example": null, + "fn_type": null, + "id": "lib.trivial.version", + "line": 164, + "name": "version", + }, + { + "category": "./lib/trivial.nix", + "description": "Returns the current nixpkgs release number as string.", + "example": null, + "fn_type": null, + "id": "lib.trivial.release", + "line": 167, + "name": "release", + }, + { + "category": "./lib/trivial.nix", + "description": "The latest release that is supported, at the time of release branch-off, + if applicable. + + Ideally, out-of-tree modules should be able to evaluate cleanly with all + supported Nixpkgs versions (master, release and old release until EOL). + So if possible, deprecation warnings should take effect only when all + out-of-tree expressions/libs/modules can upgrade to the new way without + losing support for supported Nixpkgs versions. + + This release number allows deprecation warnings to be implemented such that + they take effect as soon as the oldest release reaches end of life.", + "example": null, + "fn_type": null, + "id": "lib.trivial.oldestSupportedRelease", + "line": 181, + "name": "oldestSupportedRelease", + }, + { + "category": "./lib/trivial.nix", + "description": "Whether a feature is supported in all supported releases (at the time of + release branch-off, if applicable). See \`oldestSupportedRelease\`.", + "example": null, + "fn_type": null, + "id": "lib.trivial.isInOldestRelease", + "line": 187, + "name": "isInOldestRelease", + }, + { + "category": "./lib/trivial.nix", + "description": "Returns the current nixpkgs release code name. + + On each release the first letter is bumped and a new animal is chosen + starting with that new letter.", + "example": null, + "fn_type": null, + "id": "lib.trivial.codeName", + "line": 200, + "name": "codeName", + }, + { + "category": "./lib/trivial.nix", + "description": "Returns the current nixpkgs version suffix as string.", + "example": null, + "fn_type": null, + "id": "lib.trivial.versionSuffix", + "line": 202, + "name": "versionSuffix", + }, + { + "category": "./lib/trivial.nix", + "description": "Attempts to return the the current revision of nixpkgs and + returns the supplied default value otherwise.", + "example": null, + "fn_type": "revisionWithDefault :: string -> string", + "id": "lib.trivial.revisionWithDefault", + "line": 213, + "name": "revisionWithDefault", + }, + { + "category": "./lib/trivial.nix", + "description": "Determine whether the function is being called from inside a Nix + shell.", + "example": null, + "fn_type": "inNixShell :: bool", + "id": "lib.trivial.inNixShell", + "line": 230, + "name": "inNixShell", + }, + { + "category": "./lib/trivial.nix", + "description": "Determine whether the function is being called from inside pure-eval mode + by seeing whether \`builtins\` contains \`currentSystem\`. If not, we must be in + pure-eval mode.", + "example": null, + "fn_type": "inPureEvalMode :: bool", + "id": "lib.trivial.inPureEvalMode", + "line": 238, + "name": "inPureEvalMode", + }, + { + "category": "./lib/trivial.nix", + "description": "Return minimum of two numbers.", + "example": null, + "fn_type": null, + "id": "lib.trivial.min", + "line": 243, + "name": "min", + }, + { + "category": "./lib/trivial.nix", + "description": "Return maximum of two numbers.", + "example": null, + "fn_type": null, + "id": "lib.trivial.max", + "line": 246, + "name": "max", + }, + { + "category": "./lib/trivial.nix", + "description": "Integer modulus", + "example": "mod 11 10 +=> 1 +mod 1 10 +=> 1", + "fn_type": null, + "id": "lib.trivial.mod", + "line": 256, + "name": "mod", + }, + { + "category": "./lib/trivial.nix", + "description": "C-style comparisons + + a < b, compare a b => -1 + a == b, compare a b => 0 + a > b, compare a b => 1", + "example": null, + "fn_type": null, + "id": "lib.trivial.compare", + "line": 269, + "name": "compare", + }, + { + "category": "./lib/trivial.nix", + "description": "Split type into two subtypes by predicate \`p\`, take all elements + of the first subtype to be less than all the elements of the + second subtype, compare elements of a single subtype with \`yes\` + and \`no\` respectively.", + "example": "let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in + +cmp "a" "z" => -1 +cmp "fooa" "fooz" => -1 + +cmp "f" "a" => 1 +cmp "fooa" "a" => -1 +# while +compare "fooa" "a" => 1", + "fn_type": "(a -> bool) -> (a -> a -> int) -> (a -> a -> int) -> (a -> a -> int)", + "id": "lib.trivial.splitByAndCompare", + "line": 293, + "name": "splitByAndCompare", + }, + { + "category": "./lib/trivial.nix", + "description": "Reads a JSON file. + + Type :: path -> any", + "example": null, + "fn_type": null, + "id": "lib.trivial.importJSON", + "line": 313, + "name": "importJSON", + }, + { + "category": "./lib/trivial.nix", + "description": "Reads a TOML file. + + Type :: path -> any", + "example": null, + "fn_type": null, + "id": "lib.trivial.importTOML", + "line": 320, + "name": "importTOML", + }, + { + "category": "./lib/trivial.nix", + "description": "Print a warning before returning the second argument. This function behaves +like \`builtins.trace\`, but requires a string message and formats it as a +warning, including the \`warning: \` prefix. + +To get a call stack trace and abort evaluation, set the environment variable +\`NIX_ABORT_ON_WARN=true\` and set the Nix options \`--option pure-eval false --show-trace\`", + "example": null, + "fn_type": "string -> a -> a", + "id": "lib.trivial.warn", + "line": 348, + "name": "warn", + }, + { + "category": "./lib/trivial.nix", + "description": "Like warn, but only warn when the first argument is \`true\`.", + "example": null, + "fn_type": "bool -> string -> a -> a", + "id": "lib.trivial.warnIf", + "line": 357, + "name": "warnIf", + }, + { + "category": "./lib/trivial.nix", + "description": "Like warnIf, but negated (warn if the first argument is \`false\`).", + "example": null, + "fn_type": "bool -> string -> a -> a", + "id": "lib.trivial.warnIfNot", + "line": 364, + "name": "warnIfNot", + }, + { + "category": "./lib/trivial.nix", + "description": "Like the \`assert b; e\` expression, but with a custom error message and +without the semicolon. + +If true, return the identity function, \`r: r\`. + +If false, throw the error message. + +Calls can be juxtaposed using function application, as \`(r: r) a = a\`, so +\`(r: r) (r: r) a = a\`, and so forth.", + "example": "throwIfNot (lib.isList overlays) "The overlays argument to nixpkgs must be a list." +lib.foldr (x: throwIfNot (lib.isFunction x) "All overlays passed to nixpkgs must be functions.") (r: r) overlays +pkgs", + "fn_type": "bool -> string -> a -> a", + "id": "lib.trivial.throwIfNot", + "line": 386, + "name": "throwIfNot", + }, + { + "category": "./lib/trivial.nix", + "description": "Like throwIfNot, but negated (throw if the first argument is \`true\`).", + "example": null, + "fn_type": "bool -> string -> a -> a", + "id": "lib.trivial.throwIf", + "line": 393, + "name": "throwIf", + }, + { + "category": "./lib/trivial.nix", + "description": "Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.", + "example": "let colorVariants = ["bright" "dark" "black"] +in checkListOfEnum "color variants" [ "standard" "light" "dark" ] colorVariants; +=> +error: color variants: bright, black unexpected; valid ones: standard, light, dark", + "fn_type": "String -> List ComparableVal -> List ComparableVal -> a -> a", + "id": "lib.trivial.checkListOfEnum", + "line": 405, + "name": "checkListOfEnum", + }, + { + "category": "./lib/trivial.nix", + "description": "Add metadata about expected function arguments to a function. + The metadata should match the format given by + builtins.functionArgs, i.e. a set from expected argument to a bool + representing whether that argument has a default or not. + setFunctionArgs : (a → b) → Map String Bool → (a → b) + + This function is necessary because you can't dynamically create a + function of the { a, b ? foo, ... }: format, but some facilities + like callPackage expect to be able to query expected arguments.", + "example": null, + "fn_type": null, + "id": "lib.trivial.setFunctionArgs", + "line": 429, + "name": "setFunctionArgs", + }, + { + "category": "./lib/trivial.nix", + "description": "Extract the expected function arguments from a function. + This works both with nix-native { a, b ? foo, ... }: style + functions and functions with args set with 'setFunctionArgs'. It + has the same return type and semantics as builtins.functionArgs. + setFunctionArgs : (a → b) → Map String Bool.", + "example": null, + "fn_type": null, + "id": "lib.trivial.functionArgs", + "line": 442, + "name": "functionArgs", + }, + { + "category": "./lib/trivial.nix", + "description": "Check whether something is a function or something + annotated with function args.", + "example": null, + "fn_type": null, + "id": "lib.trivial.isFunction", + "line": 449, + "name": "isFunction", + }, + { + "category": "./lib/trivial.nix", + "description": "Turns any non-callable values into constant functions. +Returns callable values as is.", + "example": "nix-repl> lib.toFunction 1 2 +1 + +nix-repl> lib.toFunction (x: x + 1) 2 +3", + "fn_type": null, + "id": "lib.trivial.toFunction", + "line": 466, + "name": "toFunction", + }, + { + "category": "./lib/trivial.nix", + "description": "Convert the given positive integer to a string of its hexadecimal + representation. For example: + + toHexString 0 => "0" + + toHexString 16 => "10" + + toHexString 250 => "FA"", + "example": null, + "fn_type": null, + "id": "lib.trivial.toHexString", + "line": 481, + "name": "toHexString", + }, + { + "category": "./lib/trivial.nix", + "description": "\`toBaseDigits base i\` converts the positive integer i to a list of its + digits in the given base. For example: + + toBaseDigits 10 123 => [ 1 2 3 ] + + toBaseDigits 2 6 => [ 1 1 0 ] + + toBaseDigits 16 250 => [ 15 10 ]", + "example": null, + "fn_type": null, + "id": "lib.trivial.toBaseDigits", + "line": 507, + "name": "toBaseDigits", + }, + { + "category": "./lib/strings.nix", + "description": "Concatenate a list of strings.", + "example": "concatStrings ["foo" "bar"] +=> "foobar"", + "fn_type": "concatStrings :: [string] -> string", + "id": "lib.strings.concatStrings", + "line": 45, + "name": "concatStrings", + }, + { + "category": "./lib/strings.nix", + "description": "Map a function over a list and concatenate the resulting strings.", + "example": "concatMapStrings (x: "a" + x) ["foo" "bar"] +=> "afooabar"", + "fn_type": "concatMapStrings :: (a -> string) -> [a] -> string", + "id": "lib.strings.concatMapStrings", + "line": 55, + "name": "concatMapStrings", + }, + { + "category": "./lib/strings.nix", + "description": "Like \`concatMapStrings\` except that the f functions also gets the + position as a parameter.", + "example": "concatImapStrings (pos: x: "\${toString pos}-\${x}") ["foo" "bar"] +=> "1-foo2-bar"", + "fn_type": "concatImapStrings :: (int -> a -> string) -> [a] -> string", + "id": "lib.strings.concatImapStrings", + "line": 66, + "name": "concatImapStrings", + }, + { + "category": "./lib/strings.nix", + "description": "Place an element between each element of a list", + "example": "intersperse "/" ["usr" "local" "bin"] +=> ["usr" "/" "local" "/" "bin"].", + "fn_type": "intersperse :: a -> [a] -> [a]", + "id": "lib.strings.intersperse", + "line": 76, + "name": "intersperse", + }, + { + "category": "./lib/strings.nix", + "description": "Concatenate a list of strings with a separator between each element", + "example": "concatStringsSep "/" ["usr" "local" "bin"] +=> "usr/local/bin"", + "fn_type": "concatStringsSep :: string -> [string] -> string", + "id": "lib.strings.concatStringsSep", + "line": 93, + "name": "concatStringsSep", + }, + { + "category": "./lib/strings.nix", + "description": "Maps a function over a list of strings and then concatenates the + result with the specified separator interspersed between + elements.", + "example": "concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"] +=> "FOO-BAR-BAZ"", + "fn_type": "concatMapStringsSep :: string -> (a -> string) -> [a] -> string", + "id": "lib.strings.concatMapStringsSep", + "line": 106, + "name": "concatMapStringsSep", + }, + { + "category": "./lib/strings.nix", + "description": "Same as \`concatMapStringsSep\`, but the mapping function + additionally receives the position of its argument.", + "example": "concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ] +=> "6-3-2"", + "fn_type": "concatIMapStringsSep :: string -> (int -> a -> string) -> [a] -> string", + "id": "lib.strings.concatImapStringsSep", + "line": 123, + "name": "concatImapStringsSep", + }, + { + "category": "./lib/strings.nix", + "description": "Concatenate a list of strings, adding a newline at the end of each one. + Defined as \`concatMapStrings (s: s + "\\n")\`.", + "example": "concatLines [ "foo" "bar" ] +=> "foo\\nbar\\n"", + "fn_type": "concatLines :: [string] -> string", + "id": "lib.strings.concatLines", + "line": 140, + "name": "concatLines", + }, + { + "category": "./lib/strings.nix", + "description": "Construct a Unix-style, colon-separated search path consisting of + the given \`subDir\` appended to each of the given paths.", + "example": "makeSearchPath "bin" ["/root" "/usr" "/usr/local"] +=> "/root/bin:/usr/bin:/usr/local/bin" +makeSearchPath "bin" [""] +=> "/bin"", + "fn_type": "makeSearchPath :: string -> [string] -> string", + "id": "lib.strings.makeSearchPath", + "line": 153, + "name": "makeSearchPath", + }, + { + "category": "./lib/strings.nix", + "description": "Construct a Unix-style search path by appending the given + \`subDir\` to the specified \`output\` of each of the packages. If no + output by the given name is found, fallback to \`.out\` and then to + the default.", + "example": "makeSearchPathOutput "dev" "bin" [ pkgs.openssl pkgs.zlib ] +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev/bin:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/bin"", + "fn_type": "string -> string -> [package] -> string", + "id": "lib.strings.makeSearchPathOutput", + "line": 171, + "name": "makeSearchPathOutput", + }, + { + "category": "./lib/strings.nix", + "description": "Construct a library search path (such as RPATH) containing the + libraries for a set of packages", + "example": "makeLibraryPath [ "/usr" "/usr/local" ] +=> "/usr/lib:/usr/local/lib" +pkgs = import { } +makeLibraryPath [ pkgs.openssl pkgs.zlib ] +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r/lib:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/lib"", + "fn_type": null, + "id": "lib.strings.makeLibraryPath", + "line": 189, + "name": "makeLibraryPath", + }, + { + "category": "./lib/strings.nix", + "description": "Construct a binary search path (such as $PATH) containing the + binaries for a set of packages.", + "example": "makeBinPath ["/root" "/usr" "/usr/local"] +=> "/root/bin:/usr/bin:/usr/local/bin"", + "fn_type": null, + "id": "lib.strings.makeBinPath", + "line": 198, + "name": "makeBinPath", + }, + { + "category": "./lib/strings.nix", + "description": "Normalize path, removing extraneous /s", + "example": "normalizePath "/a//b///c/" +=> "/a/b/c/"", + "fn_type": "normalizePath :: string -> string", + "id": "lib.strings.normalizePath", + "line": 208, + "name": "normalizePath", + }, + { + "category": "./lib/strings.nix", + "description": "Depending on the boolean \`cond', return either the given string + or the empty string. Useful to concatenate against a bigger string.", + "example": "optionalString true "some-string" +=> "some-string" +optionalString false "some-string" +=> """, + "fn_type": "optionalString :: bool -> string -> string", + "id": "lib.strings.optionalString", + "line": 221, + "name": "optionalString", + }, + { + "category": "./lib/strings.nix", + "description": "Determine whether a string has given prefix.", + "example": "hasPrefix "foo" "foobar" +=> true +hasPrefix "foo" "barfoo" +=> false", + "fn_type": "hasPrefix :: string -> string -> bool", + "id": "lib.strings.hasPrefix", + "line": 237, + "name": "hasPrefix", + }, + { + "category": "./lib/strings.nix", + "description": "Determine whether a string has given suffix.", + "example": "hasSuffix "foo" "foobar" +=> false +hasSuffix "foo" "barfoo" +=> true", + "fn_type": "hasSuffix :: string -> string -> bool", + "id": "lib.strings.hasSuffix", + "line": 253, + "name": "hasSuffix", + }, + { + "category": "./lib/strings.nix", + "description": "Determine whether a string contains the given infix", + "example": "hasInfix "bc" "abcd" +=> true +hasInfix "ab" "abcd" +=> true +hasInfix "cd" "abcd" +=> true +hasInfix "foo" "abcd" +=> false", + "fn_type": "hasInfix :: string -> string -> bool", + "id": "lib.strings.hasInfix", + "line": 278, + "name": "hasInfix", + }, + { + "category": "./lib/strings.nix", + "description": "Convert a string to a list of characters (i.e. singleton strings). + This allows you to, e.g., map a function over each character. However, + note that this will likely be horribly inefficient; Nix is not a + general purpose programming language. Complex string manipulations + should, if appropriate, be done in a derivation. + Also note that Nix treats strings as a list of bytes and thus doesn't + handle unicode.", + "example": "stringToCharacters "" +=> [ ] +stringToCharacters "abc" +=> [ "a" "b" "c" ] +stringToCharacters "🦄" +=> [ "�" "�" "�" "�" ]", + "fn_type": "stringToCharacters :: string -> [string]", + "id": "lib.strings.stringToCharacters", + "line": 299, + "name": "stringToCharacters", + }, + { + "category": "./lib/strings.nix", + "description": "Manipulate a string character by character and replace them by + strings before concatenating the results.", + "example": "stringAsChars (x: if x == "a" then "i" else x) "nax" +=> "nix"", + "fn_type": "stringAsChars :: (string -> string) -> string -> string", + "id": "lib.strings.stringAsChars", + "line": 311, + "name": "stringAsChars", + }, + { + "category": "./lib/strings.nix", + "description": "Convert char to ascii value, must be in printable range", + "example": "charToInt "A" +=> 65 +charToInt "(" +=> 40", + "fn_type": "charToInt :: string -> int", + "id": "lib.strings.charToInt", + "line": 330, + "name": "charToInt", + }, + { + "category": "./lib/strings.nix", + "description": "Escape occurrence of the elements of \`list\` in \`string\` by + prefixing it with a backslash.", + "example": "escape ["(" ")"] "(foo)" +=> "\\\\(foo\\\\)"", + "fn_type": "escape :: [string] -> string -> string", + "id": "lib.strings.escape", + "line": 343, + "name": "escape", + }, + { + "category": "./lib/strings.nix", + "description": "Escape occurrence of the element of \`list\` in \`string\` by + converting to its ASCII value and prefixing it with \\\\x. + Only works for printable ascii characters.", + "example": "escapeC [" "] "foo bar" +=> "foo\\\\x20bar"", + "fn_type": "escapeC = [string] -> string -> string", + "id": "lib.strings.escapeC", + "line": 356, + "name": "escapeC", + }, + { + "category": "./lib/strings.nix", + "description": "Quote string to be used safely within the Bourne shell.", + "example": "escapeShellArg "esc'ape\\nme" +=> "'esc'\\\\''ape\\nme'"", + "fn_type": "escapeShellArg :: string -> string", + "id": "lib.strings.escapeShellArg", + "line": 366, + "name": "escapeShellArg", + }, + { + "category": "./lib/strings.nix", + "description": "Quote all arguments to be safely passed to the Bourne shell.", + "example": "escapeShellArgs ["one" "two three" "four'five"] +=> "'one' 'two three' 'four'\\\\''five'"", + "fn_type": "escapeShellArgs :: [string] -> string", + "id": "lib.strings.escapeShellArgs", + "line": 376, + "name": "escapeShellArgs", + }, + { + "category": "./lib/strings.nix", + "description": "Test whether the given name is a valid POSIX shell variable name.", + "example": "isValidPosixName "foo_bar000" +=> true +isValidPosixName "0-bad.jpg" +=> false", + "fn_type": "string -> bool", + "id": "lib.strings.isValidPosixName", + "line": 388, + "name": "isValidPosixName", + }, + { + "category": "./lib/strings.nix", + "description": "Translate a Nix value into a shell variable declaration, with proper escaping. + + The value can be a string (mapped to a regular variable), a list of strings + (mapped to a Bash-style array) or an attribute set of strings (mapped to a + Bash-style associative array). Note that "string" includes string-coercible + values like paths or derivations. + + Strings are translated into POSIX sh-compatible code; lists and attribute sets + assume a shell that understands Bash syntax (e.g. Bash or ZSH).", + "example": "'' + \${toShellVar "foo" "some string"} + [[ "$foo" == "some string" ]] +''", + "fn_type": "string -> (string | listOf string | attrsOf string) -> string", + "id": "lib.strings.toShellVar", + "line": 408, + "name": "toShellVar", + }, + { + "category": "./lib/strings.nix", + "description": "Translate an attribute set into corresponding shell variable declarations + using \`toShellVar\`.", + "example": "let + foo = "value"; + bar = foo; +in '' + \${toShellVars { inherit foo bar; }} + [[ "$foo" == "$bar" ]] +''", + "fn_type": "attrsOf (string | listOf string | attrsOf string) -> string", + "id": "lib.strings.toShellVars", + "line": 436, + "name": "toShellVars", + }, + { + "category": "./lib/strings.nix", + "description": "Turn a string into a Nix expression representing that string", + "example": "escapeNixString "hello\\\${}\\n" +=> "\\"hello\\\\\\\${}\\\\n\\""", + "fn_type": "string -> string", + "id": "lib.strings.escapeNixString", + "line": 446, + "name": "escapeNixString", + }, + { + "category": "./lib/strings.nix", + "description": "Turn a string into an exact regular expression", + "example": "escapeRegex "[^a-z]*" +=> "\\\\[\\\\^a-z]\\\\*"", + "fn_type": "string -> string", + "id": "lib.strings.escapeRegex", + "line": 456, + "name": "escapeRegex", + }, + { + "category": "./lib/strings.nix", + "description": "Quotes a string if it can't be used as an identifier directly.", + "example": "escapeNixIdentifier "hello" +=> "hello" +escapeNixIdentifier "0abc" +=> "\\"0abc\\""", + "fn_type": "string -> string", + "id": "lib.strings.escapeNixIdentifier", + "line": 468, + "name": "escapeNixIdentifier", + }, + { + "category": "./lib/strings.nix", + "description": "Escapes a string such that it is safe to include verbatim in an XML + document.", + "example": "escapeXML ''"test" 'test' < & >'' +=> ""test" 'test' < & >"", + "fn_type": "string -> string", + "id": "lib.strings.escapeXML", + "line": 482, + "name": "escapeXML", + }, + { + "category": "./lib/strings.nix", + "description": "Converts an ASCII string to lower-case.", + "example": "toLower "HOME" +=> "home"", + "fn_type": "toLower :: string -> string", + "id": "lib.strings.toLower", + "line": 501, + "name": "toLower", + }, + { + "category": "./lib/strings.nix", + "description": "Converts an ASCII string to upper-case.", + "example": "toUpper "home" +=> "HOME"", + "fn_type": "toUpper :: string -> string", + "id": "lib.strings.toUpper", + "line": 511, + "name": "toUpper", + }, + { + "category": "./lib/strings.nix", + "description": "Appends string context from another string. This is an implementation + detail of Nix and should be used carefully. + + Strings in Nix carry an invisible \`context\` which is a list of strings + representing store paths. If the string is later used in a derivation + attribute, the derivation will properly populate the inputDrvs and + inputSrcs.", + "example": "pkgs = import { }; +addContextFrom pkgs.coreutils "bar" +=> "bar"", + "fn_type": null, + "id": "lib.strings.addContextFrom", + "line": 526, + "name": "addContextFrom", + }, + { + "category": "./lib/strings.nix", + "description": "Cut a string with a separator and produces a list of strings which + were separated by this separator.", + "example": "splitString "." "foo.bar.baz" +=> [ "foo" "bar" "baz" ] +splitString "/" "/usr/local/bin" +=> [ "" "usr" "local" "bin" ]", + "fn_type": null, + "id": "lib.strings.splitString", + "line": 537, + "name": "splitString", + }, + { + "category": "./lib/strings.nix", + "description": "Return a string without the specified prefix, if the prefix matches.", + "example": "removePrefix "foo." "foo.bar.baz" +=> "bar.baz" +removePrefix "xxx" "foo.bar.baz" +=> "foo.bar.baz"", + "fn_type": "string -> string -> string", + "id": "lib.strings.removePrefix", + "line": 553, + "name": "removePrefix", + }, + { + "category": "./lib/strings.nix", + "description": "Return a string without the specified suffix, if the suffix matches.", + "example": "removeSuffix "front" "homefront" +=> "home" +removeSuffix "xxx" "homefront" +=> "homefront"", + "fn_type": "string -> string -> string", + "id": "lib.strings.removeSuffix", + "line": 577, + "name": "removeSuffix", + }, + { + "category": "./lib/strings.nix", + "description": "Return true if string v1 denotes a version older than v2.", + "example": "versionOlder "1.1" "1.2" +=> true +versionOlder "1.1" "1.1" +=> false", + "fn_type": null, + "id": "lib.strings.versionOlder", + "line": 599, + "name": "versionOlder", + }, + { + "category": "./lib/strings.nix", + "description": "Return true if string v1 denotes a version equal to or newer than v2.", + "example": "versionAtLeast "1.1" "1.0" +=> true +versionAtLeast "1.1" "1.1" +=> true +versionAtLeast "1.1" "1.2" +=> false", + "fn_type": null, + "id": "lib.strings.versionAtLeast", + "line": 611, + "name": "versionAtLeast", + }, + { + "category": "./lib/strings.nix", + "description": "This function takes an argument that's either a derivation or a + derivation's "name" attribute and extracts the name part from that + argument.", + "example": "getName "youtube-dl-2016.01.01" +=> "youtube-dl" +getName pkgs.youtube-dl +=> "youtube-dl"", + "fn_type": null, + "id": "lib.strings.getName", + "line": 623, + "name": "getName", + }, + { + "category": "./lib/strings.nix", + "description": "This function takes an argument that's either a derivation or a + derivation's "name" attribute and extracts the version part from that + argument.", + "example": "getVersion "youtube-dl-2016.01.01" +=> "2016.01.01" +getVersion pkgs.youtube-dl +=> "2016.01.01"", + "fn_type": null, + "id": "lib.strings.getVersion", + "line": 640, + "name": "getVersion", + }, + { + "category": "./lib/strings.nix", + "description": "Extract name with version from URL. Ask for separator which is + supposed to start extension.", + "example": "nameFromURL "https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2" "-" +=> "nix" +nameFromURL "https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2" "_" +=> "nix-1.7-x86"", + "fn_type": null, + "id": "lib.strings.nameFromURL", + "line": 656, + "name": "nameFromURL", + }, + { + "category": "./lib/strings.nix", + "description": "Create a -D= string that can be passed to typical Meson + invocations.", + "example": "mesonOption "engine" "opengl" +=> "-Dengine=opengl"", + "fn_type": "mesonOption :: string -> string -> string + + @param feature The feature to be set + @param value The desired value", + "id": "lib.strings.mesonOption", + "line": 675, + "name": "mesonOption", + }, + { + "category": "./lib/strings.nix", + "description": "Create a -D={true,false} string that can be passed to typical + Meson invocations.", + "example": "mesonBool "hardened" true +=> "-Dhardened=true" +mesonBool "static" false +=> "-Dstatic=false"", + "fn_type": "mesonBool :: string -> bool -> string + + @param condition The condition to be made true or false + @param flag The controlling flag of the condition", + "id": "lib.strings.mesonBool", + "line": 694, + "name": "mesonBool", + }, + { + "category": "./lib/strings.nix", + "description": "Create a -D={enabled,disabled} string that can be passed to + typical Meson invocations.", + "example": "mesonEnable "docs" true +=> "-Ddocs=enabled" +mesonEnable "savage" false +=> "-Dsavage=disabled"", + "fn_type": "mesonEnable :: string -> bool -> string + + @param feature The feature to be enabled or disabled + @param flag The controlling flag", + "id": "lib.strings.mesonEnable", + "line": 713, + "name": "mesonEnable", + }, + { + "category": "./lib/strings.nix", + "description": "Create an --{enable,disable}- string that can be passed to + standard GNU Autoconf scripts.", + "example": "enableFeature true "shared" +=> "--enable-shared" +enableFeature false "shared" +=> "--disable-shared"", + "fn_type": null, + "id": "lib.strings.enableFeature", + "line": 727, + "name": "enableFeature", + }, + { + "category": "./lib/strings.nix", + "description": "Create an --{enable-=,disable-} string that can be passed to + standard GNU Autoconf scripts.", + "example": "enableFeatureAs true "shared" "foo" +=> "--enable-shared=foo" +enableFeatureAs false "shared" (throw "ignored") +=> "--disable-shared"", + "fn_type": null, + "id": "lib.strings.enableFeatureAs", + "line": 740, + "name": "enableFeatureAs", + }, + { + "category": "./lib/strings.nix", + "description": "Create an --{with,without}- string that can be passed to + standard GNU Autoconf scripts.", + "example": "withFeature true "shared" +=> "--with-shared" +withFeature false "shared" +=> "--without-shared"", + "fn_type": null, + "id": "lib.strings.withFeature", + "line": 751, + "name": "withFeature", + }, + { + "category": "./lib/strings.nix", + "description": "Create an --{with-=,without-} string that can be passed to + standard GNU Autoconf scripts.", + "example": "withFeatureAs true "shared" "foo" +=> "--with-shared=foo" +withFeatureAs false "shared" (throw "ignored") +=> "--without-shared"", + "fn_type": null, + "id": "lib.strings.withFeatureAs", + "line": 764, + "name": "withFeatureAs", + }, + { + "category": "./lib/strings.nix", + "description": "Create a fixed width string with additional prefix to match + required width. + + This function will fail if the input string is longer than the + requested length.", + "example": "fixedWidthString 5 "0" (toString 15) +=> "00015"", + "fn_type": "fixedWidthString :: int -> string -> string -> string", + "id": "lib.strings.fixedWidthString", + "line": 778, + "name": "fixedWidthString", + }, + { + "category": "./lib/strings.nix", + "description": "Format a number adding leading zeroes up to fixed width.", + "example": "fixedWidthNumber 5 15 +=> "00015"", + "fn_type": null, + "id": "lib.strings.fixedWidthNumber", + "line": 795, + "name": "fixedWidthNumber", + }, + { + "category": "./lib/strings.nix", + "description": "Convert a float to a string, but emit a warning when precision is lost + during the conversion", + "example": "floatToString 0.000001 +=> "0.000001" +floatToString 0.0000001 +=> trace: warning: Imprecise conversion from float to string 0.000000 + "0.000000"", + "fn_type": null, + "id": "lib.strings.floatToString", + "line": 807, + "name": "floatToString", + }, + { + "category": "./lib/strings.nix", + "description": "Soft-deprecated function. While the original implementation is available as + isConvertibleWithToString, consider using isStringLike instead, if suitable.", + "example": null, + "fn_type": null, + "id": "lib.strings.isCoercibleToString", + "line": 815, + "name": "isCoercibleToString", + }, + { + "category": "./lib/strings.nix", + "description": "Check whether a list or other value can be passed to toString. + + Many types of value are coercible to string this way, including int, float, + null, bool, list of similarly coercible values.", + "example": null, + "fn_type": null, + "id": "lib.strings.isConvertibleWithToString", + "line": 824, + "name": "isConvertibleWithToString", + }, + { + "category": "./lib/strings.nix", + "description": "Check whether a value can be coerced to a string. + The value must be a string, path, or attribute set. + + String-like values can be used without explicit conversion in + string interpolations and in most functions that expect a string.", + "example": null, + "fn_type": null, + "id": "lib.strings.isStringLike", + "line": 835, + "name": "isStringLike", + }, + { + "category": "./lib/strings.nix", + "description": "Check whether a value is a store path.", + "example": "isStorePath "/nix/store/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11/bin/python" +=> false +isStorePath "/nix/store/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11" +=> true +isStorePath pkgs.python +=> true +isStorePath [] || isStorePath 42 || isStorePath {} || … +=> false", + "fn_type": null, + "id": "lib.strings.isStorePath", + "line": 853, + "name": "isStorePath", + }, + { + "category": "./lib/strings.nix", + "description": "Parse a string as an int. Does not support parsing of integers with preceding zero due to + ambiguity between zero-padded and octal numbers. See toIntBase10.", + "example": "toInt "1337" +=> 1337 + +toInt "-4" +=> -4 + +toInt " 123 " +=> 123 + +toInt "00024" +=> error: Ambiguity in interpretation of 00024 between octal and zero padded integer. + +toInt "3.14" +=> error: floating point JSON numbers are not supported", + "fn_type": "string -> int", + "id": "lib.strings.toInt", + "line": 884, + "name": "toInt", + }, + { + "category": "./lib/strings.nix", + "description": "Parse a string as a base 10 int. This supports parsing of zero-padded integers.", + "example": "toIntBase10 "1337" +=> 1337 + +toIntBase10 "-4" +=> -4 + +toIntBase10 " 123 " +=> 123 + +toIntBase10 "00024" +=> 24 + +toIntBase10 "3.14" +=> error: floating point JSON numbers are not supported", + "fn_type": "string -> int", + "id": "lib.strings.toIntBase10", + "line": 934, + "name": "toIntBase10", + }, + { + "category": "./lib/strings.nix", + "description": "Read a list of paths from \`file\`, relative to the \`rootPath\`. + Lines beginning with \`#\` are treated as comments and ignored. + Whitespace is significant. + + NOTE: This function is not performant and should be avoided.", + "example": "readPathsFromFile /prefix + ./pkgs/development/libraries/qt-5/5.4/qtbase/series +=> [ "/prefix/dlopen-resolv.patch" "/prefix/tzdir.patch" + "/prefix/dlopen-libXcursor.patch" "/prefix/dlopen-openssl.patch" + "/prefix/dlopen-dbus.patch" "/prefix/xdg-config-dirs.patch" + "/prefix/nix-profiles-library-paths.patch" + "/prefix/compose-search-path.patch" ]", + "fn_type": null, + "id": "lib.strings.readPathsFromFile", + "line": 977, + "name": "readPathsFromFile", + }, + { + "category": "./lib/strings.nix", + "description": "Read the contents of a file removing the trailing \\n", + "example": "$ echo "1.0" > ./version + +fileContents ./version +=> "1.0"", + "fn_type": "fileContents :: path -> string", + "id": "lib.strings.fileContents", + "line": 997, + "name": "fileContents", + }, + { + "category": "./lib/strings.nix", + "description": "Creates a valid derivation name from a potentially invalid one.", + "example": "sanitizeDerivationName "../hello.bar # foo" +=> "-hello.bar-foo" +sanitizeDerivationName "" +=> "unknown" +sanitizeDerivationName pkgs.hello +=> "-nix-store-2g75chlbpxlrqn15zlby2dfh8hr9qwbk-hello-2.10"", + "fn_type": "sanitizeDerivationName :: String -> String", + "id": "lib.strings.sanitizeDerivationName", + "line": 1012, + "name": "sanitizeDerivationName", + }, + { + "category": "./lib/strings.nix", + "description": "Computes the Levenshtein distance between two strings. + Complexity O(n*m) where n and m are the lengths of the strings. + Algorithm adjusted from https://stackoverflow.com/a/9750974/6605742", + "example": "levenshtein "foo" "foo" +=> 0 +levenshtein "book" "hook" +=> 1 +levenshtein "hello" "Heyo" +=> 3", + "fn_type": "levenshtein :: string -> string -> int", + "id": "lib.strings.levenshtein", + "line": 1051, + "name": "levenshtein", + }, + { + "category": "./lib/strings.nix", + "description": "Returns the length of the prefix common to both strings.", + "example": null, + "fn_type": null, + "id": "lib.strings.commonPrefixLength", + "line": 1072, + "name": "commonPrefixLength", + }, + { + "category": "./lib/strings.nix", + "description": "Returns the length of the suffix common to both strings.", + "example": null, + "fn_type": null, + "id": "lib.strings.commonSuffixLength", + "line": 1080, + "name": "commonSuffixLength", + }, + { + "category": "./lib/strings.nix", + "description": "Returns whether the levenshtein distance between two strings is at most some value + Complexity is O(min(n,m)) for k <= 2 and O(n*m) otherwise", + "example": "levenshteinAtMost 0 "foo" "foo" +=> true +levenshteinAtMost 1 "foo" "boa" +=> false +levenshteinAtMost 2 "foo" "boa" +=> true +levenshteinAtMost 2 "This is a sentence" "this is a sentense." +=> false +levenshteinAtMost 3 "This is a sentence" "this is a sentense." +=> true", + "fn_type": "levenshteinAtMost :: int -> string -> string -> bool", + "id": "lib.strings.levenshteinAtMost", + "line": 1104, + "name": "levenshteinAtMost", + }, + { + "category": "./lib/strings-with-deps.nix", + "description": "!!! The interface of this function is kind of messed up, since + it's way too overloaded and almost but not quite computes a + topological sort of the depstrings.", + "example": null, + "fn_type": null, + "id": "lib.strings-with-deps.textClosureList", + "line": 59, + "name": "textClosureList", + }, + { + "category": "./lib/sources.nix", + "description": "Returns the type of a path: regular (for file), symlink, or directory.", + "example": null, + "fn_type": null, + "id": "lib.sources.pathType", + "line": 25, + "name": "pathType", + }, + { + "category": "./lib/sources.nix", + "description": "Returns true if the path exists and is a directory, false otherwise.", + "example": null, + "fn_type": null, + "id": "lib.sources.pathIsDirectory", + "line": 30, + "name": "pathIsDirectory", + }, + { + "category": "./lib/sources.nix", + "description": "Returns true if the path exists and is a regular file, false otherwise.", + "example": null, + "fn_type": null, + "id": "lib.sources.pathIsRegularFile", + "line": 35, + "name": "pathIsRegularFile", + }, + { + "category": "./lib/sources.nix", + "description": "A basic filter for \`cleanSourceWith\` that removes +directories of version control system, backup files (*~) +and some generated files.", + "example": null, + "fn_type": null, + "id": "lib.sources.cleanSourceFilter", + "line": 42, + "name": "cleanSourceFilter", + }, + { + "category": "./lib/sources.nix", + "description": "Filters a source tree removing version control files and directories using cleanSourceFilter.", + "example": "cleanSource ./.", + "fn_type": null, + "id": "lib.sources.cleanSource", + "line": 65, + "name": "cleanSource", + }, + { + "category": "./lib/sources.nix", + "description": "Like \`builtins.filterSource\`, except it will compose with itself, +allowing you to chain multiple calls together without any +intermediate copies being put in the nix store.", + "example": "lib.cleanSourceWith { + filter = f; + src = lib.cleanSourceWith { + filter = g; + src = ./.; + }; +} +# Succeeds! + +builtins.filterSource f (builtins.filterSource g ./.) +# Fails!", + "fn_type": null, + "id": "lib.sources.cleanSourceWith", + "line": 86, + "name": "cleanSourceWith", + }, + { + "category": "./lib/sources.nix", + "description": "Add logging to a source, for troubleshooting the filtering behavior.", + "example": null, + "fn_type": "sources.trace :: sourceLike -> Source", + "id": "lib.sources.trace", + "line": 114, + "name": "trace", + }, + { + "category": "./lib/sources.nix", + "description": "Filter sources by a list of regular expressions.", + "example": "src = sourceByRegex ./my-subproject [".*\\.py$" "^database.sql$"]", + "fn_type": null, + "id": "lib.sources.sourceByRegex", + "line": 137, + "name": "sourceByRegex", + }, + { + "category": "./lib/sources.nix", + "description": "Get all files ending with the specified suffices from the given +source directory or its descendants, omitting files that do not match +any suffix. The result of the example below will include files like +\`./dir/module.c\` and \`./dir/subdir/doc.xml\` if present.", + "example": "sourceFilesBySuffices ./. [ ".xml" ".c" ]", + "fn_type": "sourceLike -> [String] -> Source", + "id": "lib.sources.sourceFilesBySuffices", + "line": 159, + "name": "sourceFilesBySuffices", + }, + { + "category": "./lib/sources.nix", + "description": "Get the commit id of a git repo.", + "example": "commitIdFromGitRepo ", + "fn_type": null, + "id": "lib.sources.commitIdFromGitRepo", + "line": 176, + "name": "commitIdFromGitRepo", + }, + { + "category": "./lib/options.nix", + "description": "Returns true when the given argument is an option", + "example": "isOption 1 // => false +isOption (mkOption {}) // => true", + "fn_type": "isOption :: a -> bool", + "id": "lib.options.isOption", + "line": 53, + "name": "isOption", + }, + { + "category": "./lib/options.nix", + "description": "Creates an Option attribute set. mkOption accepts an attribute set with the following keys: + + All keys default to \`null\` when not given.", + "example": "mkOption { } // => { _type = "option"; } +mkOption { default = "foo"; } // => { _type = "option"; default = "foo"; }", + "fn_type": null, + "id": "lib.options.mkOption", + "line": 63, + "name": "mkOption", + }, + { + "category": "./lib/options.nix", + "description": "Creates an Option attribute set for a boolean value option i.e an + option to be toggled on or off:", + "example": "mkEnableOption "foo" +=> { _type = "option"; default = false; description = "Whether to enable foo."; example = true; type = { ... }; }", + "fn_type": null, + "id": "lib.options.mkEnableOption", + "line": 95, + "name": "mkEnableOption", + }, + { + "category": "./lib/options.nix", + "description": "Creates an Option attribute set for an option that specifies the + package a module should use for some purpose. + + The package is specified as a list of strings representing its attribute path in nixpkgs. + + Because of this, you need to pass nixpkgs itself as the first argument. + + The second argument is the name of the option, used in the description "The package to use.". + + You can also pass an example value, either a literal string or a package's attribute path. + + You can omit the default path if the name of the option is also attribute path in nixpkgs.", + "example": "mkPackageOption pkgs "hello" { } +=> { _type = "option"; default = «derivation /nix/store/3r2vg51hlxj3cx5vscp0vkv60bqxkaq0-hello-2.10.drv»; defaultText = { ... }; description = "The hello package to use."; type = { ... }; } + + +mkPackageOption pkgs "GHC" { + default = [ "ghc" ]; + example = "pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])"; +} +=> { _type = "option"; default = «derivation /nix/store/jxx55cxsjrf8kyh3fp2ya17q99w7541r-ghc-8.10.7.drv»; defaultText = { ... }; description = "The GHC package to use."; example = { ... }; type = { ... }; }", + "fn_type": "mkPackageOption :: pkgs -> string -> { default :: [string]; example :: null | string | [string]; } -> option", + "id": "lib.options.mkPackageOption", + "line": 133, + "name": "mkPackageOption", + }, + { + "category": "./lib/options.nix", + "description": "Like mkPackageOption, but emit an mdDoc description instead of DocBook.", + "example": null, + "fn_type": null, + "id": "lib.options.mkPackageOptionMD", + "line": 151, + "name": "mkPackageOptionMD", + }, + { + "category": "./lib/options.nix", + "description": "This option accepts anything, but it does not produce any result. + + This is useful for sharing a module across different module sets + without having to implement similar features as long as the + values of the options are not accessed.", + "example": null, + "fn_type": null, + "id": "lib.options.mkSinkUndeclaredOptions", + "line": 160, + "name": "mkSinkUndeclaredOptions", + }, + { + "category": "./lib/options.nix", + "description": ""Merge" option definitions by checking that they all have the same value.", + "example": null, + "fn_type": null, + "id": "lib.options.mergeEqualOption", + "line": 193, + "name": "mergeEqualOption", + }, + { + "category": "./lib/options.nix", + "description": "Extracts values of all "value" keys of the given list.", + "example": "getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ] +getValues [ ] // => [ ]", + "fn_type": "getValues :: [ { value :: a; } ] -> [a]", + "id": "lib.options.getValues", + "line": 213, + "name": "getValues", + }, + { + "category": "./lib/options.nix", + "description": "Extracts values of all "file" keys of the given list", + "example": "getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ] +getFiles [ ] // => [ ]", + "fn_type": "getFiles :: [ { file :: a; } ] -> [a]", + "id": "lib.options.getFiles", + "line": 223, + "name": "getFiles", + }, + { + "category": "./lib/options.nix", + "description": "This function recursively removes all derivation attributes from + \`x\` except for the \`name\` attribute. + + This is to make the generation of \`options.xml\` much more + efficient: the XML representation of derivations is very large + (on the order of megabytes) and is not actually used by the + manual generator. + + This function was made obsolete by renderOptionValue and is kept for + compatibility with out-of-tree code.", + "example": null, + "fn_type": null, + "id": "lib.options.scrubOptionValue", + "line": 281, + "name": "scrubOptionValue", + }, + { + "category": "./lib/options.nix", + "description": "Ensures that the given option value (default or example) is a \`_type\`d string + by rendering Nix values to \`literalExpression\`s.", + "example": null, + "fn_type": null, + "id": "lib.options.renderOptionValue", + "line": 292, + "name": "renderOptionValue", + }, + { + "category": "./lib/options.nix", + "description": "For use in the \`defaultText\` and \`example\` option attributes. Causes the + given string to be rendered verbatim in the documentation as Nix code. This + is necessary for complex values, e.g. functions, or values that depend on + other values or packages.", + "example": null, + "fn_type": null, + "id": "lib.options.literalExpression", + "line": 305, + "name": "literalExpression", + }, + { + "category": "./lib/options.nix", + "description": "For use in the \`defaultText\` and \`example\` option attributes. Causes the + given DocBook text to be inserted verbatim in the documentation, for when + a \`literalExpression\` would be too hard to read.", + "example": null, + "fn_type": null, + "id": "lib.options.literalDocBook", + "line": 316, + "name": "literalDocBook", + }, + { + "category": "./lib/options.nix", + "description": "Transition marker for documentation that's already migrated to markdown + syntax.", + "example": null, + "fn_type": null, + "id": "lib.options.mdDoc", + "line": 326, + "name": "mdDoc", + }, + { + "category": "./lib/options.nix", + "description": "For use in the \`defaultText\` and \`example\` option attributes. Causes the + given MD text to be inserted verbatim in the documentation, for when + a \`literalExpression\` would be too hard to read.", + "example": null, + "fn_type": null, + "id": "lib.options.literalMD", + "line": 334, + "name": "literalMD", + }, + { + "category": "./lib/options.nix", + "description": "Convert an option, described as a list of the option parts to a + human-readable version.", + "example": "(showOption ["foo" "bar" "baz"]) == "foo.bar.baz" +(showOption ["foo" "bar.baz" "tux"]) == "foo.\\"bar.baz\\".tux" +(showOption ["windowManager" "2bwm" "enable"]) == "windowManager.\\"2bwm\\".enable" + + Placeholders will not be quoted as they are not actual values: +(showOption ["foo" "*" "bar"]) == "foo.*.bar" +(showOption ["foo" "" "bar"]) == "foo..bar"", + "fn_type": null, + "id": "lib.options.showOption", + "line": 352, + "name": "showOption", + }, + { + "category": "./lib/modules.nix", + "description": "Evaluate a set of modules. The result is a set with the attributes: + + ‘options’: The nested set of all option declarations, + + ‘config’: The nested set of all option values. + + ‘type’: A module system type representing the module set as a submodule, + to be extended by configuration from the containing module set. + + This is also available as the module argument ‘moduleType’. + + ‘extendModules’: A function similar to ‘evalModules’ but building on top + of the module set. Its arguments, ‘modules’ and ‘specialArgs’ are + added to the existing values. + + Using ‘extendModules’ a few times has no performance impact as long + as you only reference the final ‘options’ and ‘config’. + If you do reference multiple ‘config’ (or ‘options’) from before and + after ‘extendModules’, performance is the same as with multiple + ‘evalModules’ invocations, because the new modules' ability to + override existing configuration fundamentally requires a new + fixpoint to be constructed. + + This is also available as a module argument. + + ‘_module’: A portion of the configuration tree which is elided from + ‘config’. It contains some values that are mostly internal to the + module system implementation. + + !!! Please think twice before adding to this argument list! The more + that is specified here instead of in the modules themselves the harder + it is to transparently move a set of modules to be a submodule of another + config (as the proper arguments need to be replicated at each call to + evalModules) and the less declarative the module set is.", + "example": null, + "fn_type": null, + "id": "lib.modules.evalModules", + "line": 103, + "name": "evalModules", + }, + { + "category": "./lib/modules.nix", + "description": "Collects all modules recursively into the form + + { + disabled = [ ]; + # All modules of the main module list + modules = [ + { + key = ; + module = ; + # All modules imported by the module for key1 + modules = [ + { + key = ; + module = ; + # All modules imported by the module for key1-1 + modules = [ ... ]; + } + ... + ]; + } + ... + ]; + }", + "example": null, + "fn_type": null, + "id": "lib.modules.collectStructuredModules", + "line": 394, + "name": "collectStructuredModules", + }, + { + "category": "./lib/modules.nix", + "description": "Wrap a module with a default location for reporting errors.", + "example": null, + "fn_type": null, + "id": "lib.modules.setDefaultModuleLocation", + "line": 430, + "name": "setDefaultModuleLocation", + }, + { + "category": "./lib/modules.nix", + "description": "Massage a module into canonical form, that is, a set consisting + of ‘options’, ‘config’ and ‘imports’ attributes.", + "example": null, + "fn_type": null, + "id": "lib.modules.unifyModuleSyntax", + "line": 437, + "name": "unifyModuleSyntax", + }, + { + "category": "./lib/modules.nix", + "description": "Merge a list of modules. This will recurse over the option + declarations in all modules, combining them into a single set. + At the same time, for each option declaration, it will merge the + corresponding option definitions in all machines, returning them + in the ‘value’ attribute of each option. + + This returns a set like + { + # A recursive set of options along with their final values + matchedOptions = { + foo = { _type = "option"; value = "option value of foo"; ... }; + bar.baz = { _type = "option"; value = "option value of bar.baz"; ... }; + ... + }; + # A list of definitions that weren't matched by any option + unmatchedDefns = [ + { file = "file.nix"; prefix = [ "qux" ]; value = "qux"; } + ... + ]; + }", + "example": null, + "fn_type": null, + "id": "lib.modules.mergeModules", + "line": 517, + "name": "mergeModules", + }, + { + "category": "./lib/modules.nix", + "description": "byName is like foldAttrs, but will look for attributes to merge in the + specified attribute name. + + byName "foo" (module: value: ["module.hidden=\${module.hidden},value=\${value}"]) + [ + { + hidden="baz"; + foo={qux="bar"; gla="flop";}; + } + { + hidden="fli"; + foo={qux="gne"; gli="flip";}; + } + ] + ===> + { + gla = [ "module.hidden=baz,value=flop" ]; + gli = [ "module.hidden=fli,value=flip" ]; + qux = [ "module.hidden=baz,value=bar" "module.hidden=fli,value=gne" ]; + }", + "example": null, + "fn_type": null, + "id": "lib.modules.byName", + "line": 544, + "name": "byName", + }, + { + "category": "./lib/modules.nix", + "description": "Merge multiple option declarations into a single declaration. In + general, there should be only one declaration of each option. + The exception is the ‘options’ attribute, which specifies + sub-options. These can be specified multiple times to allow one + module to add sub-options to an option declared somewhere else + (e.g. multiple modules define sub-options for ‘fileSystems’). + + 'loc' is the list of attribute names where the option is located. + + 'opts' is a list of modules. Each module has an options attribute which + correspond to the definition of 'loc' in 'opt.file'.", + "example": null, + "fn_type": null, + "id": "lib.modules.mergeOptionDecls", + "line": 670, + "name": "mergeOptionDecls", + }, + { + "category": "./lib/modules.nix", + "description": "Merge all the definitions of an option to produce the final + config value.", + "example": null, + "fn_type": null, + "id": "lib.modules.evalOptionValue", + "line": 702, + "name": "evalOptionValue", + }, + { + "category": "./lib/modules.nix", + "description": "Given a config set, expand mkMerge properties, and push down the + other properties into the children. The result is a list of + config sets that do not have properties at top-level. For + example, + + mkMerge [ { boot = set1; } (mkIf cond { boot = set2; services = set3; }) ] + + is transformed into + + [ { boot = set1; } { boot = mkIf cond set2; services = mkIf cond set3; } ]. + + This transform is the critical step that allows mkIf conditions + to refer to the full configuration without creating an infinite + recursion.", + "example": null, + "fn_type": null, + "id": "lib.modules.pushDownProperties", + "line": 797, + "name": "pushDownProperties", + }, + { + "category": "./lib/modules.nix", + "description": "Given a config value, expand mkMerge properties, and discharge + any mkIf conditions. That is, this is the place where mkIf + conditions are actually evaluated. The result is a list of + config values. For example, ‘mkIf false x’ yields ‘[]’, + ‘mkIf true x’ yields ‘[x]’, and + + mkMerge [ 1 (mkIf true 2) (mkIf true (mkIf false 3)) ] + + yields ‘[ 1 2 ]’.", + "example": null, + "fn_type": null, + "id": "lib.modules.dischargeProperties", + "line": 818, + "name": "dischargeProperties", + }, + { + "category": "./lib/modules.nix", + "description": "Given a list of config values, process the mkOverride properties, + that is, return the values that have the highest (that is, + numerically lowest) priority, and strip the mkOverride + properties. For example, + + [ { file = "/1"; value = mkOverride 10 "a"; } + { file = "/2"; value = mkOverride 20 "b"; } + { file = "/3"; value = "z"; } + { file = "/4"; value = mkOverride 10 "d"; } + ] + + yields + + [ { file = "/1"; value = "a"; } + { file = "/4"; value = "d"; } + ] + + Note that "z" has the default priority 100.", + "example": null, + "fn_type": null, + "id": "lib.modules.filterOverrides", + "line": 852, + "name": "filterOverrides", + }, + { + "category": "./lib/modules.nix", + "description": "Sort a list of properties. The sort priority of a property is + defaultOrderPriority by default, but can be overridden by wrapping the property + using mkOrder.", + "example": null, + "fn_type": null, + "id": "lib.modules.sortProperties", + "line": 867, + "name": "sortProperties", + }, + { + "category": "./lib/modules.nix", + "description": "Properties.", + "example": null, + "fn_type": null, + "id": "lib.modules.mkIf", + "line": 889, + "name": "mkIf", + }, + { + "category": "./lib/modules.nix", + "description": "Compatibility.", + "example": null, + "fn_type": null, + "id": "lib.modules.fixMergeModules", + "line": 964, + "name": "fixMergeModules", + }, + { + "category": "./lib/modules.nix", + "description": "Return a module that causes a warning to be shown if the + specified option is defined. For example, + + mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "" + + causes a assertion if the user defines boot.loader.grub.bootDevice. + + replacementInstructions is a string that provides instructions on + how to achieve the same functionality without the removed option, + or alternatively a reasoning why the functionality is not needed. + replacementInstructions SHOULD be provided!", + "example": null, + "fn_type": null, + "id": "lib.modules.mkRemovedOptionModule", + "line": 978, + "name": "mkRemovedOptionModule", + }, + { + "category": "./lib/modules.nix", + "description": "Return a module that causes a warning to be shown if the + specified "from" option is defined; the defined value is however + forwarded to the "to" option. This can be used to rename options + while providing backward compatibility. For example, + + mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ] + + forwards any definitions of boot.copyKernels to + boot.loader.grub.copyKernels while printing a warning. + + This also copies over the priority from the aliased option to the + non-aliased option.", + "example": null, + "fn_type": null, + "id": "lib.modules.mkRenamedOptionModule", + "line": 1009, + "name": "mkRenamedOptionModule", + }, + { + "category": "./lib/modules.nix", + "description": "Return a module that causes a warning to be shown if any of the "from" + option is defined; the defined values can be used in the "mergeFn" to set + the "to" value. + This function can be used to merge multiple options into one that has a + different type. + + "mergeFn" takes the module "config" as a parameter and must return a value + of "to" option type. + + mkMergedOptionModule + [ [ "a" "b" "c" ] + [ "d" "e" "f" ] ] + [ "x" "y" "z" ] + (config: + let value = p: getAttrFromPath p config; + in + if (value [ "a" "b" "c" ]) == true then "foo" + else if (value [ "d" "e" "f" ]) == true then "bar" + else "baz") + + - options.a.b.c is a removed boolean option + - options.d.e.f is a removed boolean option + - options.x.y.z is a new str option that combines a.b.c and d.e.f + functionality + + This show a warning if any a.b.c or d.e.f is set, and set the value of + x.y.z to the result of the merge function", + "example": null, + "fn_type": null, + "id": "lib.modules.mkMergedOptionModule", + "line": 1063, + "name": "mkMergedOptionModule", + }, + { + "category": "./lib/modules.nix", + "description": "Single "from" version of mkMergedOptionModule. + Return a module that causes a warning to be shown if the "from" option is + defined; the defined value can be used in the "mergeFn" to set the "to" + value. + This function can be used to change an option into another that has a + different type. + + "mergeFn" takes the module "config" as a parameter and must return a value of + "to" option type. + + mkChangedOptionModule [ "a" "b" "c" ] [ "x" "y" "z" ] + (config: + let value = getAttrFromPath [ "a" "b" "c" ] config; + in + if value > 100 then "high" + else "normal") + + - options.a.b.c is a removed int option + - options.x.y.z is a new str option that supersedes a.b.c + + This show a warning if a.b.c is set, and set the value of x.y.z to the + result of the change function", + "example": null, + "fn_type": null, + "id": "lib.modules.mkChangedOptionModule", + "line": 1110, + "name": "mkChangedOptionModule", + }, + { + "category": "./lib/modules.nix", + "description": "Like ‘mkRenamedOptionModule’, but doesn't show a warning.", + "example": null, + "fn_type": null, + "id": "lib.modules.mkAliasOptionModule", + "line": 1118, + "name": "mkAliasOptionModule", + }, + { + "category": "./lib/modules.nix", + "description": "Transitional version of mkAliasOptionModule that uses MD docs.", + "example": null, + "fn_type": null, + "id": "lib.modules.mkAliasOptionModuleMD", + "line": 1124, + "name": "mkAliasOptionModuleMD", + }, + { + "category": "./lib/modules.nix", + "description": "mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b + + Create config definitions with the same priority as the definition of another option. + This should be used for option definitions where one option sets the value of another as a convenience. + For instance a config file could be set with a \`text\` or \`source\` option, where text translates to a \`source\` + value using \`mkDerivedConfig options.text (pkgs.writeText "filename.conf")\`. + + It takes care of setting the right priority using \`mkOverride\`.", + "example": null, + "fn_type": null, + "id": "lib.modules.mkDerivedConfig", + "line": 1147, + "name": "mkDerivedConfig", + }, + { + "category": "./lib/modules.nix", + "description": "Use this function to import a JSON file as NixOS configuration. + + modules.importJSON :: path -> attrs", + "example": null, + "fn_type": null, + "id": "lib.modules.importJSON", + "line": 1185, + "name": "importJSON", + }, + { + "category": "./lib/modules.nix", + "description": "Use this function to import a TOML file as NixOS configuration. + + modules.importTOML :: path -> attrs", + "example": null, + "fn_type": null, + "id": "lib.modules.importTOML", + "line": null, + "name": "importTOML", + }, + { + "category": "./lib/meta.nix", + "description": "Add to or override the meta attributes of the given + derivation.", + "example": "addMetaAttrs {description = "Bla blah";} somePkg", + "fn_type": null, + "id": "lib.meta.addMetaAttrs", + "line": 15, + "name": "addMetaAttrs", + }, + { + "category": "./lib/meta.nix", + "description": "Disable Hydra builds of given derivation.", + "example": null, + "fn_type": null, + "id": "lib.meta.dontDistribute", + "line": 21, + "name": "dontDistribute", + }, + { + "category": "./lib/meta.nix", + "description": "Change the symbolic name of a package for presentation purposes + (i.e., so that nix-env users can tell them apart).", + "example": null, + "fn_type": null, + "id": "lib.meta.setName", + "line": 27, + "name": "setName", + }, + { + "category": "./lib/meta.nix", + "description": "Like \`setName\`, but takes the previous name as an argument.", + "example": "updateName (oldName: oldName + "-experimental") somePkg", + "fn_type": null, + "id": "lib.meta.updateName", + "line": 35, + "name": "updateName", + }, + { + "category": "./lib/meta.nix", + "description": "Append a suffix to the name of a package (before the version + part).", + "example": null, + "fn_type": null, + "id": "lib.meta.appendToName", + "line": 40, + "name": "appendToName", + }, + { + "category": "./lib/meta.nix", + "description": "Apply a function to each derivation and only to derivations in an attrset.", + "example": null, + "fn_type": null, + "id": "lib.meta.mapDerivationAttrset", + "line": 46, + "name": "mapDerivationAttrset", + }, + { + "category": "./lib/meta.nix", + "description": "Set the nix-env priority of the package.", + "example": null, + "fn_type": null, + "id": "lib.meta.setPrio", + "line": 50, + "name": "setPrio", + }, + { + "category": "./lib/meta.nix", + "description": "Decrease the nix-env priority of the package, i.e., other + versions/variants of the package will be preferred.", + "example": null, + "fn_type": null, + "id": "lib.meta.lowPrio", + "line": 55, + "name": "lowPrio", + }, + { + "category": "./lib/meta.nix", + "description": "Apply lowPrio to an attrset with derivations", + "example": null, + "fn_type": null, + "id": "lib.meta.lowPrioSet", + "line": 59, + "name": "lowPrioSet", + }, + { + "category": "./lib/meta.nix", + "description": "Increase the nix-env priority of the package, i.e., this + version/variant of the package will be preferred.", + "example": null, + "fn_type": null, + "id": "lib.meta.hiPrio", + "line": 65, + "name": "hiPrio", + }, + { + "category": "./lib/meta.nix", + "description": "Apply hiPrio to an attrset with derivations", + "example": null, + "fn_type": null, + "id": "lib.meta.hiPrioSet", + "line": 69, + "name": "hiPrioSet", + }, + { + "category": "./lib/meta.nix", + "description": "Check to see if a platform is matched by the given \`meta.platforms\` + element. + + A \`meta.platform\` pattern is either + + 1. (legacy) a system string. + + 2. (modern) a pattern for the entire platform structure (see \`lib.systems.inspect.platformPatterns\`). + + 3. (modern) a pattern for the platform \`parsed\` field (see \`lib.systems.inspect.patterns\`). + + We can inject these into a pattern for the whole of a structured platform, + and then match that.", + "example": null, + "fn_type": null, + "id": "lib.meta.platformMatch", + "line": 86, + "name": "platformMatch", + }, + { + "category": "./lib/meta.nix", + "description": "Check if a package is available on a given platform. + + A package is available on a platform if both + + 1. One of \`meta.platforms\` pattern matches the given + platform, or \`meta.platforms\` is not present. + + 2. None of \`meta.badPlatforms\` pattern matches the given platform.", + "example": null, + "fn_type": null, + "id": "lib.meta.availableOn", + "line": 104, + "name": "availableOn", + }, + { + "category": "./lib/meta.nix", + "description": "Get the corresponding attribute in lib.licenses + from the SPDX ID. + For SPDX IDs, see + https://spdx.org/licenses", + "example": "lib.getLicenseFromSpdxId "MIT" == lib.licenses.mit +=> true +lib.getLicenseFromSpdxId "mIt" == lib.licenses.mit +=> true +lib.getLicenseFromSpdxId "MY LICENSE" +=> trace: warning: getLicenseFromSpdxId: No license matches the given SPDX ID: MY LICENSE +=> { shortName = "MY LICENSE"; }", + "fn_type": "getLicenseFromSpdxId :: str -> AttrSet", + "id": "lib.meta.getLicenseFromSpdxId", + "line": 125, + "name": "getLicenseFromSpdxId", + }, + { + "category": "./lib/meta.nix", + "description": "Get the path to the main program of a derivation with either + meta.mainProgram or pname or name", + "example": "getExe pkgs.hello +=> "/nix/store/g124820p9hlv4lj8qplzxw1c44dxaw1k-hello-2.12/bin/hello" +getExe pkgs.mustache-go +=> "/nix/store/am9ml4f4ywvivxnkiaqwr0hyxka1xjsf-mustache-go-1.3.0/bin/mustache"", + "fn_type": "getExe :: derivation -> string", + "id": "lib.meta.getExe", + "line": 146, + "name": "getExe", + }, + { + "category": "./lib/lists.nix", + "description": "Create a list consisting of a single element. \`singleton x\` is + sometimes more convenient with respect to indentation than \`[x]\` + when x spans multiple lines.", + "example": "singleton "foo" +=> [ "foo" ]", + "fn_type": "singleton :: a -> [a]", + "id": "lib.lists.singleton", + "line": 23, + "name": "singleton", + }, + { + "category": "./lib/lists.nix", + "description": "Apply the function to each element in the list. Same as \`map\`, but arguments + flipped.", + "example": "forEach [ 1 2 ] (x: + toString x +) +=> [ "1" "2" ]", + "fn_type": "forEach :: [a] -> (a -> b) -> [b]", + "id": "lib.lists.forEach", + "line": 36, + "name": "forEach", + }, + { + "category": "./lib/lists.nix", + "description": "“right fold” a binary function \`op\` between successive elements of + \`list\` with \`nul\` as the starting value, i.e., + \`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))\`.", + "example": "concat = foldr (a: b: a + b) "z" +concat [ "a" "b" "c" ] +=> "abcz" +# different types +strange = foldr (int: str: toString (int + 1) + str) "a" +strange [ 1 2 3 4 ] +=> "2345a"", + "fn_type": "foldr :: (a -> b -> b) -> b -> [a] -> b", + "id": "lib.lists.foldr", + "line": 53, + "name": "foldr", + }, + { + "category": "./lib/lists.nix", + "description": "\`fold\` is an alias of \`foldr\` for historic reasons", + "example": null, + "fn_type": null, + "id": "lib.lists.fold", + "line": 64, + "name": "fold", + }, + { + "category": "./lib/lists.nix", + "description": "“left fold”, like \`foldr\`, but from the left: + \`foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)\`.", + "example": "lconcat = foldl (a: b: a + b) "z" +lconcat [ "a" "b" "c" ] +=> "zabc" +# different types +lstrange = foldl (str: int: str + toString (int + 1)) "a" +lstrange [ 1 2 3 4 ] +=> "a2345"", + "fn_type": "foldl :: (b -> a -> b) -> b -> [a] -> b", + "id": "lib.lists.foldl", + "line": 81, + "name": "foldl", + }, + { + "category": "./lib/lists.nix", + "description": "Strict version of \`foldl\`. + + The difference is that evaluation is forced upon access. Usually used + with small whole results (in contrast with lazily-generated list or large + lists where only a part is consumed.)", + "example": null, + "fn_type": "foldl' :: (b -> a -> b) -> b -> [a] -> b", + "id": "lib.lists.foldl'", + "line": 97, + "name": "foldl'", + }, + { + "category": "./lib/lists.nix", + "description": "Map with index starting from 0", + "example": "imap0 (i: v: "\${v}-\${toString i}") ["a" "b"] +=> [ "a-0" "b-1" ]", + "fn_type": "imap0 :: (int -> a -> b) -> [a] -> [b]", + "id": "lib.lists.imap0", + "line": 107, + "name": "imap0", + }, + { + "category": "./lib/lists.nix", + "description": "Map with index starting from 1", + "example": "imap1 (i: v: "\${v}-\${toString i}") ["a" "b"] +=> [ "a-1" "b-2" ]", + "fn_type": "imap1 :: (int -> a -> b) -> [a] -> [b]", + "id": "lib.lists.imap1", + "line": 117, + "name": "imap1", + }, + { + "category": "./lib/lists.nix", + "description": "Map and concatenate the result.", + "example": "concatMap (x: [x] ++ ["z"]) ["a" "b"] +=> [ "a" "z" "b" "z" ]", + "fn_type": "concatMap :: (a -> [b]) -> [a] -> [b]", + "id": "lib.lists.concatMap", + "line": 127, + "name": "concatMap", + }, + { + "category": "./lib/lists.nix", + "description": "Flatten the argument into a single list; that is, nested lists are + spliced into the top-level lists.", + "example": "flatten [1 [2 [3] 4] 5] +=> [1 2 3 4 5] +flatten 1 +=> [1]", + "fn_type": null, + "id": "lib.lists.flatten", + "line": 138, + "name": "flatten", + }, + { + "category": "./lib/lists.nix", + "description": "Remove elements equal to 'e' from a list. Useful for buildInputs.", + "example": "remove 3 [ 1 3 4 3 ] +=> [ 1 4 ]", + "fn_type": "remove :: a -> [a] -> [a]", + "id": "lib.lists.remove", + "line": 152, + "name": "remove", + }, + { + "category": "./lib/lists.nix", + "description": "Find the sole element in the list matching the specified + predicate, returns \`default\` if no such element exists, or + \`multiple\` if there are multiple matching elements.", + "example": "findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ] +=> "multiple" +findSingle (x: x == 3) "none" "multiple" [ 1 3 ] +=> 3 +findSingle (x: x == 3) "none" "multiple" [ 1 9 ] +=> "none"", + "fn_type": "findSingle :: (a -> bool) -> a -> a -> [a] -> a", + "id": "lib.lists.findSingle", + "line": 169, + "name": "findSingle", + }, + { + "category": "./lib/lists.nix", + "description": "Find the first element in the list matching the specified + predicate or return \`default\` if no such element exists.", + "example": "findFirst (x: x > 3) 7 [ 1 6 4 ] +=> 6 +findFirst (x: x > 9) 7 [ 1 6 4 ] +=> 7", + "fn_type": "findFirst :: (a -> bool) -> a -> [a] -> a", + "id": "lib.lists.findFirst", + "line": 194, + "name": "findFirst", + }, + { + "category": "./lib/lists.nix", + "description": "Return true if function \`pred\` returns true for at least one + element of \`list\`.", + "example": "any isString [ 1 "a" { } ] +=> true +any isString [ 1 { } ] +=> false", + "fn_type": "any :: (a -> bool) -> [a] -> bool", + "id": "lib.lists.any", + "line": 215, + "name": "any", + }, + { + "category": "./lib/lists.nix", + "description": "Return true if function \`pred\` returns true for all elements of + \`list\`.", + "example": "all (x: x < 3) [ 1 2 ] +=> true +all (x: x < 3) [ 1 2 3 ] +=> false", + "fn_type": "all :: (a -> bool) -> [a] -> bool", + "id": "lib.lists.all", + "line": 228, + "name": "all", + }, + { + "category": "./lib/lists.nix", + "description": "Count how many elements of \`list\` match the supplied predicate + function.", + "example": "count (x: x == 3) [ 3 2 3 4 6 ] +=> 2", + "fn_type": "count :: (a -> bool) -> [a] -> int", + "id": "lib.lists.count", + "line": 240, + "name": "count", + }, + { + "category": "./lib/lists.nix", + "description": "Return a singleton list or an empty list, depending on a boolean + value. Useful when building lists with optional elements + (e.g. \`++ optional (system == "i686-linux") firefox\`).", + "example": "optional true "foo" +=> [ "foo" ] +optional false "foo" +=> [ ]", + "fn_type": "optional :: bool -> a -> [a]", + "id": "lib.lists.optional", + "line": 255, + "name": "optional", + }, + { + "category": "./lib/lists.nix", + "description": "Return a list or an empty list, depending on a boolean value.", + "example": "optionals true [ 2 3 ] +=> [ 2 3 ] +optionals false [ 2 3 ] +=> [ ]", + "fn_type": "optionals :: bool -> [a] -> [a]", + "id": "lib.lists.optionals", + "line": 267, + "name": "optionals", + }, + { + "category": "./lib/lists.nix", + "description": "If argument is a list, return it; else, wrap it in a singleton + list. If you're using this, you should almost certainly + reconsider if there isn't a more "well-typed" approach.", + "example": "toList [ 1 2 ] +=> [ 1 2 ] +toList "hi" +=> [ "hi "]", + "fn_type": null, + "id": "lib.lists.toList", + "line": 284, + "name": "toList", + }, + { + "category": "./lib/lists.nix", + "description": "Return a list of integers from \`first\` up to and including \`last\`.", + "example": "range 2 4 +=> [ 2 3 4 ] +range 3 2 +=> [ ]", + "fn_type": "range :: int -> int -> [int]", + "id": "lib.lists.range", + "line": 297, + "name": "range", + }, + { + "category": "./lib/lists.nix", + "description": "Return a list with \`n\` copies of an element.", + "example": "replicate 3 "a" +=> [ "a" "a" "a" ] +replicate 2 true +=> [ true true ]", + "fn_type": "replicate :: int -> a -> [a]", + "id": "lib.lists.replicate", + "line": 316, + "name": "replicate", + }, + { + "category": "./lib/lists.nix", + "description": "Splits the elements of a list in two lists, \`right\` and + \`wrong\`, depending on the evaluation of a predicate.", + "example": "partition (x: x > 2) [ 5 1 2 3 4 ] +=> { right = [ 5 3 4 ]; wrong = [ 1 2 ]; }", + "fn_type": "(a -> bool) -> [a] -> { right :: [a]; wrong :: [a]; }", + "id": "lib.lists.partition", + "line": 327, + "name": "partition", + }, + { + "category": "./lib/lists.nix", + "description": "Splits the elements of a list into many lists, using the return value of a predicate. + Predicate should return a string which becomes keys of attrset \`groupBy\` returns. + + \`groupBy'\` allows to customise the combining function and initial value", + "example": "groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ] +=> { true = [ 5 3 4 ]; false = [ 1 2 ]; } +groupBy (x: x.name) [ {name = "icewm"; script = "icewm &";} + {name = "xfce"; script = "xfce4-session &";} + {name = "icewm"; script = "icewmbg &";} + {name = "mate"; script = "gnome-session &";} + ] +=> { icewm = [ { name = "icewm"; script = "icewm &"; } + { name = "icewm"; script = "icewmbg &"; } ]; + mate = [ { name = "mate"; script = "gnome-session &"; } ]; + xfce = [ { name = "xfce"; script = "xfce4-session &"; } ]; + } + +groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ] +=> { true = 12; false = 3; }", + "fn_type": null, + "id": "lib.lists.groupBy'", + "line": 356, + "name": "groupBy'", + }, + { + "category": "./lib/lists.nix", + "description": "Merges two lists of the same size together. If the sizes aren't the same + the merging stops at the shortest. How both lists are merged is defined + by the first argument.", + "example": "zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"] +=> ["he" "lo"]", + "fn_type": "zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + "id": "lib.lists.zipListsWith", + "line": 376, + "name": "zipListsWith", + }, + { + "category": "./lib/lists.nix", + "description": "Merges two lists of the same size together. If the sizes aren't the same + the merging stops at the shortest.", + "example": "zipLists [ 1 2 ] [ "a" "b" ] +=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]", + "fn_type": "zipLists :: [a] -> [b] -> [{ fst :: a; snd :: b; }]", + "id": "lib.lists.zipLists", + "line": 395, + "name": "zipLists", + }, + { + "category": "./lib/lists.nix", + "description": "Reverse the order of the elements of a list.", + "example": "reverseList [ "b" "o" "j" ] +=> [ "j" "o" "b" ]", + "fn_type": "reverseList :: [a] -> [a]", + "id": "lib.lists.reverseList", + "line": 406, + "name": "reverseList", + }, + { + "category": "./lib/lists.nix", + "description": "Depth-First Search (DFS) for lists \`list != []\`. + + \`before a b == true\` means that \`b\` depends on \`a\` (there's an + edge from \`b\` to \`a\`).", + "example": "listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ] + == { minimal = "/"; # minimal element + visited = [ "/home/user" ]; # seen elements (in reverse order) + rest = [ "/home" "other" ]; # everything else + } + +listDfs true hasPrefix [ "/home/user" "other" "/" "/home" "/" ] + == { cycle = "/"; # cycle encountered at this element + loops = [ "/" ]; # and continues to these elements + visited = [ "/" "/home/user" ]; # elements leading to the cycle (in reverse order) + rest = [ "/home" "other" ]; # everything else", + "fn_type": null, + "id": "lib.lists.listDfs", + "line": 428, + "name": "listDfs", + }, + { + "category": "./lib/lists.nix", + "description": "Sort a list based on a partial ordering using DFS. This + implementation is O(N^2), if your ordering is linear, use \`sort\` + instead. + + \`before a b == true\` means that \`b\` should be after \`a\` + in the result.", + "example": "toposort hasPrefix [ "/home/user" "other" "/" "/home" ] + == { result = [ "/" "/home" "/home/user" "other" ]; } + +toposort hasPrefix [ "/home/user" "other" "/" "/home" "/" ] + == { cycle = [ "/home/user" "/" "/" ]; # path leading to a cycle + loops = [ "/" ]; } # loops back to these elements + +toposort hasPrefix [ "other" "/home/user" "/home" "/" ] + == { result = [ "other" "/" "/home" "/home/user" ]; } + +toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }", + "fn_type": null, + "id": "lib.lists.toposort", + "line": 467, + "name": "toposort", + }, + { + "category": "./lib/lists.nix", + "description": "Sort a list based on a comparator function which compares two + elements and returns true if the first argument is strictly below + the second argument. The returned list is sorted in an increasing + order. The implementation does a quick-sort.", + "example": "sort (a: b: a < b) [ 5 3 7 ] +=> [ 3 5 7 ]", + "fn_type": null, + "id": "lib.lists.sort", + "line": 495, + "name": "sort", + }, + { + "category": "./lib/lists.nix", + "description": "Compare two lists element-by-element.", + "example": "compareLists compare [] [] +=> 0 +compareLists compare [] [ "a" ] +=> -1 +compareLists compare [ "a" ] [] +=> 1 +compareLists compare [ "a" "b" ] [ "a" "c" ] +=> -1", + "fn_type": null, + "id": "lib.lists.compareLists", + "line": 524, + "name": "compareLists", + }, + { + "category": "./lib/lists.nix", + "description": "Sort list using "Natural sorting". + Numeric portions of strings are sorted in numeric order.", + "example": "naturalSort ["disk11" "disk8" "disk100" "disk9"] +=> ["disk8" "disk9" "disk11" "disk100"] +naturalSort ["10.46.133.149" "10.5.16.62" "10.54.16.25"] +=> ["10.5.16.62" "10.46.133.149" "10.54.16.25"] +naturalSort ["v0.2" "v0.15" "v0.0.9"] +=> [ "v0.0.9" "v0.2" "v0.15" ]", + "fn_type": null, + "id": "lib.lists.naturalSort", + "line": 547, + "name": "naturalSort", + }, + { + "category": "./lib/lists.nix", + "description": "Return the first (at most) N elements of a list.", + "example": "take 2 [ "a" "b" "c" "d" ] +=> [ "a" "b" ] +take 2 [ ] +=> [ ]", + "fn_type": "take :: int -> [a] -> [a]", + "id": "lib.lists.take", + "line": 566, + "name": "take", + }, + { + "category": "./lib/lists.nix", + "description": "Remove the first (at most) N elements of a list.", + "example": "drop 2 [ "a" "b" "c" "d" ] +=> [ "c" "d" ] +drop 2 [ ] +=> [ ]", + "fn_type": "drop :: int -> [a] -> [a]", + "id": "lib.lists.drop", + "line": 580, + "name": "drop", + }, + { + "category": "./lib/lists.nix", + "description": "Return a list consisting of at most \`count\` elements of \`list\`, + starting at index \`start\`.", + "example": "sublist 1 3 [ "a" "b" "c" "d" "e" ] +=> [ "b" "c" "d" ] +sublist 1 3 [ ] +=> [ ]", + "fn_type": "sublist :: int -> int -> [a] -> [a]", + "id": "lib.lists.sublist", + "line": 596, + "name": "sublist", + }, + { + "category": "./lib/lists.nix", + "description": "Return the last element of a list. + + This function throws an error if the list is empty.", + "example": "last [ 1 2 3 ] +=> 3", + "fn_type": "last :: [a] -> a", + "id": "lib.lists.last", + "line": 620, + "name": "last", + }, + { + "category": "./lib/lists.nix", + "description": "Return all elements but the last. + + This function throws an error if the list is empty.", + "example": "init [ 1 2 3 ] +=> [ 1 2 ]", + "fn_type": "init :: [a] -> [a]", + "id": "lib.lists.init", + "line": 634, + "name": "init", + }, + { + "category": "./lib/lists.nix", + "description": "Return the image of the cross product of some lists by a function.", + "example": "crossLists (x:y: "\${toString x}\${toString y}") [[1 2] [3 4]] +=> [ "13" "14" "23" "24" ]", + "fn_type": null, + "id": "lib.lists.crossLists", + "line": 645, + "name": "crossLists", + }, + { + "category": "./lib/lists.nix", + "description": "Remove duplicate elements from the list. O(n^2) complexity.", + "example": "unique [ 3 2 3 4 ] +=> [ 3 2 4 ]", + "fn_type": "unique :: [a] -> [a]", + "id": "lib.lists.unique", + "line": 658, + "name": "unique", + }, + { + "category": "./lib/lists.nix", + "description": "Intersects list 'e' and another list. O(nm) complexity.", + "example": "intersectLists [ 1 2 3 ] [ 6 3 2 ] +=> [ 3 2 ]", + "fn_type": null, + "id": "lib.lists.intersectLists", + "line": 666, + "name": "intersectLists", + }, + { + "category": "./lib/lists.nix", + "description": "Subtracts list 'e' from another list. O(nm) complexity.", + "example": "subtractLists [ 3 2 ] [ 1 2 3 4 5 3 ] +=> [ 1 4 5 ]", + "fn_type": null, + "id": "lib.lists.subtractLists", + "line": 674, + "name": "subtractLists", + }, + { + "category": "./lib/lists.nix", + "description": "Test if two lists have no common element. + It should be slightly more efficient than (intersectLists a b == [])", + "example": null, + "fn_type": null, + "id": "lib.lists.mutuallyExclusive", + "line": 679, + "name": "mutuallyExclusive", + }, + { + "category": "./lib/licenses.nix", + "description": "License identifiers from spdx.org where possible. + * If you cannot find your license here, then look for a similar license or + * add it to this list. The URL mentioned above is a good source for inspiration.", + "example": null, + "fn_type": null, + "id": "lib.licenses.abstyles", + "line": 28, + "name": "abstyles", + }, + { + "category": "./lib/kernel.nix", + "description": "Common patterns/legacy used in common-config/hardened/config.nix", + "example": null, + "fn_type": null, + "id": "lib.kernel.whenHelpers", + "line": 19, + "name": "whenHelpers", + }, + { + "category": "./lib/generators.nix", + "description": "Convert a value to a sensible default string representation. + * The builtin \`toString\` function has some strange defaults, + * suitable for bash scripts but not much else.", + "example": null, + "fn_type": null, + "id": "lib.generators.mkValueStringDefault", + "line": 33, + "name": "mkValueStringDefault", + }, + { + "category": "./lib/generators.nix", + "description": "Generate a line of key k and value v, separated by + * character sep. If sep appears in k, it is escaped. + * Helper for synaxes with different separators. + * + * mkValueString specifies how values should be formatted. + * + * mkKeyValueDefault {} ":" "f:oo" "bar" + * > "f\\:oo:bar"", + "example": null, + "fn_type": null, + "id": "lib.generators.mkKeyValueDefault", + "line": 69, + "name": "mkKeyValueDefault", + }, + { + "category": "./lib/generators.nix", + "description": "Generate a key-value-style config file from an attrset. + * + * mkKeyValue is the same as in toINI.", + "example": null, + "fn_type": null, + "id": "lib.generators.toKeyValue", + "line": 82, + "name": "toKeyValue", + }, + { + "category": "./lib/generators.nix", + "description": "Generate an INI-style config file from an + * attrset of sections to an attrset of key-value pairs. + * + * generators.toINI {} { + * foo = { hi = "\${pkgs.hello}"; ciao = "bar"; }; + * baz = { "also, integers" = 42; }; + * } + * + *> [baz] + *> also, integers=42 + *> + *> [foo] + *> ciao=bar + *> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10 + * + * The mk* configuration attributes can generically change + * the way sections and key-value strings are generated. + * + * For more examples see the test cases in ./tests/misc.nix.", + "example": null, + "fn_type": null, + "id": "lib.generators.toINI", + "line": 113, + "name": "toINI", + }, + { + "category": "./lib/generators.nix", + "description": "Generate an INI-style config file from an attrset + * specifying the global section (no header), and an + * attrset of sections to an attrset of key-value pairs. + * + * generators.toINIWithGlobalSection {} { + * globalSection = { + * someGlobalKey = "hi"; + * }; + * sections = { + * foo = { hi = "\${pkgs.hello}"; ciao = "bar"; }; + * baz = { "also, integers" = 42; }; + * } + * + *> someGlobalKey=hi + *> + *> [baz] + *> also, integers=42 + *> + *> [foo] + *> ciao=bar + *> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10 + * + * The mk* configuration attributes can generically change + * the way sections and key-value strings are generated. + * + * For more examples see the test cases in ./tests/misc.nix. + * + * If you don’t need a global section, you can also use + * \`generators.toINI\` directly, which only takes + * the part in \`sections\`.", + "example": null, + "fn_type": null, + "id": "lib.generators.toINIWithGlobalSection", + "line": 164, + "name": "toINIWithGlobalSection", + }, + { + "category": "./lib/generators.nix", + "description": "Generate a git-config file from an attrset. + * + * It has two major differences from the regular INI format: + * + * 1. values are indented with tabs + * 2. sections can have sub-sections + * + * generators.toGitINI { + * url."ssh://git@github.com/".insteadOf = "https://github.com"; + * user.name = "edolstra"; + * } + * + *> [url "ssh://git@github.com/"] + *> insteadOf = https://github.com/ + *> + *> [user] + *> name = edolstra", + "example": null, + "fn_type": null, + "id": "lib.generators.toGitINI", + "line": 196, + "name": "toGitINI", + }, + { + "category": "./lib/generators.nix", + "description": "Generates JSON from an arbitrary (non-function) value. + * For more information see the documentation of the builtin.", + "example": null, + "fn_type": null, + "id": "lib.generators.toJSON", + "line": 235, + "name": "toJSON", + }, + { + "category": "./lib/generators.nix", + "description": "YAML has been a strict superset of JSON since 1.2, so we + * use toJSON. Before it only had a few differences referring + * to implicit typing rules, so it should work with older + * parsers as well.", + "example": null, + "fn_type": null, + "id": "lib.generators.toYAML", + "line": 243, + "name": "toYAML", + }, + { + "category": "./lib/generators.nix", + "description": "Pretty print a value, akin to \`builtins.trace\`. + * Should probably be a builtin as well. + * The pretty-printed string should be suitable for rendering default values + * in the NixOS manual. In particular, it should be as close to a valid Nix expression + * as possible.", + "example": null, + "fn_type": null, + "id": "lib.generators.toPretty", + "line": 286, + "name": "toPretty", + }, + { + "category": "./lib/generators.nix", + "description": "Translate a simple Nix expression to Dhall notation. + * Note that integers are translated to Integer and never + * the Natural type.", + "example": null, + "fn_type": null, + "id": "lib.generators.toDhall", + "line": 409, + "name": "toDhall", + }, + { + "category": "./lib/filesystem.nix", + "description": "A map of all haskell packages defined in the given path, +identified by having a cabal file with the same name as the +directory itself.", + "example": null, + "fn_type": "Path -> Map String Path", + "id": "lib.filesystem.haskellPathsInDir", + "line": 18, + "name": "haskellPathsInDir", + }, + { + "category": "./lib/filesystem.nix", + "description": "Find the first directory containing a file matching 'pattern' +upward from a given 'file'. +Returns 'null' if no directories contain a file matching 'pattern'.", + "example": null, + "fn_type": "RegExp -> Path -> Nullable { path : Path; matches : [ MatchResults ]; }", + "id": "lib.filesystem.locateDominatingFile", + "line": 41, + "name": "locateDominatingFile", + }, + { + "category": "./lib/filesystem.nix", + "description": "Given a directory, return a flattened list of all files within it recursively.", + "example": null, + "fn_type": "Path -> [ Path ]", + "id": "lib.filesystem.listFilesRecursive", + "line": 69, + "name": "listFilesRecursive", + }, + { + "category": "./lib/derivations.nix", + "description": "Restrict a derivation to a predictable set of attribute names, so +that the returned attrset is not strict in the actual derivation, +saving a lot of computation when the derivation is non-trivial. + +This is useful in situations where a derivation might only be used for its +passthru attributes, improving evaluation performance. + +The returned attribute set is lazy in \`derivation\`. Specifically, this +means that the derivation will not be evaluated in at least the +situations below. + +For illustration and/or testing, we define derivation such that its +evaluation is very noticeable. + + let derivation = throw "This won't be evaluated."; + +In the following expressions, \`derivation\` will _not_ be evaluated: + + (lazyDerivation { inherit derivation; }).type + + attrNames (lazyDerivation { inherit derivation; }) + + (lazyDerivation { inherit derivation; } // { foo = true; }).foo + + (lazyDerivation { inherit derivation; meta.foo = true; }).meta + +In these expressions, it \`derivation\` _will_ be evaluated: + + "\${lazyDerivation { inherit derivation }}" + + (lazyDerivation { inherit derivation }).outPath + + (lazyDerivation { inherit derivation }).meta + +And the following expressions are not valid, because the refer to +implementation details and/or attributes that may not be present on +some derivations: + + (lazyDerivation { inherit derivation }).buildInputs + + (lazyDerivation { inherit derivation }).passthru + + (lazyDerivation { inherit derivation }).pythonPath", + "example": null, + "fn_type": null, + "id": "lib.derivations.lazyDerivation", + "line": 53, + "name": "lazyDerivation", + }, + { + "category": "./lib/deprecated.nix", + "description": "deprecated: + + For historical reasons, imap has an index starting at 1. + + But for consistency with the rest of the library we want an index + starting at zero.", + "example": null, + "fn_type": null, + "id": "lib.deprecated.imap", + "line": 301, + "name": "imap", + }, + { + "category": "./lib/debug.nix", + "description": "Conditionally trace the supplied message, based on a predicate.", + "example": "traceIf true "hello" 3 +trace: hello +=> 3", + "fn_type": "traceIf :: bool -> string -> a -> a", + "id": "lib.debug.traceIf", + "line": 51, + "name": "traceIf", + }, + { + "category": "./lib/debug.nix", + "description": "Trace the supplied value after applying a function to it, and + return the original value.", + "example": "traceValFn (v: "mystring \${v}") "foo" +trace: mystring foo +=> "foo"", + "fn_type": "traceValFn :: (a -> b) -> a -> a", + "id": "lib.debug.traceValFn", + "line": 69, + "name": "traceValFn", + }, + { + "category": "./lib/debug.nix", + "description": "Trace the supplied value and return it.", + "example": "traceVal 42 +# trace: 42 +=> 42", + "fn_type": "traceVal :: a -> a", + "id": "lib.debug.traceVal", + "line": 84, + "name": "traceVal", + }, + { + "category": "./lib/debug.nix", + "description": "\`builtins.trace\`, but the value is \`builtins.deepSeq\`ed first.", + "example": "trace { a.b.c = 3; } null +trace: { a = ; } +=> null +traceSeq { a.b.c = 3; } null +trace: { a = { b = { c = 3; }; }; } +=> null", + "fn_type": "traceSeq :: a -> b -> b", + "id": "lib.debug.traceSeq", + "line": 98, + "name": "traceSeq", + }, + { + "category": "./lib/debug.nix", + "description": "Like \`traceSeq\`, but only evaluate down to depth n. + This is very useful because lots of \`traceSeq\` usages + lead to an infinite recursion.", + "example": "traceSeqN 2 { a.b.c = 3; } null +trace: { a = { b = {…}; }; } +=> null", + "fn_type": "traceSeqN :: Int -> a -> b -> b", + "id": "lib.debug.traceSeqN", + "line": 115, + "name": "traceSeqN", + }, + { + "category": "./lib/debug.nix", + "description": "A combination of \`traceVal\` and \`traceSeq\` that applies a + provided function to the value to be traced after \`deepSeq\`ing + it.", + "example": null, + "fn_type": null, + "id": "lib.debug.traceValSeqFn", + "line": 132, + "name": "traceValSeqFn", + }, + { + "category": "./lib/debug.nix", + "description": "A combination of \`traceVal\` and \`traceSeq\`.", + "example": null, + "fn_type": null, + "id": "lib.debug.traceValSeq", + "line": 139, + "name": "traceValSeq", + }, + { + "category": "./lib/debug.nix", + "description": "A combination of \`traceVal\` and \`traceSeqN\` that applies a + provided function to the value to be traced.", + "example": null, + "fn_type": null, + "id": "lib.debug.traceValSeqNFn", + "line": 143, + "name": "traceValSeqNFn", + }, + { + "category": "./lib/debug.nix", + "description": "A combination of \`traceVal\` and \`traceSeqN\`.", + "example": null, + "fn_type": null, + "id": "lib.debug.traceValSeqN", + "line": 151, + "name": "traceValSeqN", + }, + { + "category": "./lib/debug.nix", + "description": "Trace the input and output of a function \`f\` named \`name\`, + both down to \`depth\`. + + This is useful for adding around a function call, + to see the before/after of values as they are transformed.", + "example": "traceFnSeqN 2 "id" (x: x) { a.b.c = 3; } +trace: { fn = "id"; from = { a.b = {…}; }; to = { a.b = {…}; }; } +=> { a.b.c = 3; }", + "fn_type": null, + "id": "lib.debug.traceFnSeqN", + "line": 164, + "name": "traceFnSeqN", + }, + { + "category": "./lib/debug.nix", + "description": "Evaluates a set of tests. + + A test is an attribute set \`{expr, expected}\`, + denoting an expression and its expected result. + + The result is a \`list\` of __failed tests__, each represented as + \`{name, expected, result}\`, + + - expected + - What was passed as \`expected\` + - result + - The actual \`result\` of the test + + Used for regression testing of the functions in lib; see + tests.nix for more examples. + + Important: Only attributes that start with \`test\` are executed. + + - If you want to run only a subset of the tests add the attribute \`tests = ["testName"];\`", + "example": "runTests { + testAndOk = { + expr = lib.and true false; + expected = false; + }; + testAndFail = { + expr = lib.and true false; + expected = true; + }; +} +-> +[ + { + name = "testAndFail"; + expected = true; + result = false; + } +]", + "fn_type": "runTests :: { + tests = [ String ]; + \${testName} :: { + expr :: a; + expected :: a; + }; +} +-> +[ + { + name :: String; + expected :: a; + result :: a; + } +]", + "id": "lib.debug.runTests", + "line": 237, + "name": "runTests", + }, + { + "category": "./lib/debug.nix", + "description": "Create a test assuming that list elements are \`true\`.", + "example": "{ testX = allTrue [ true ]; }", + "fn_type": null, + "id": "lib.debug.testAllTrue", + "line": 252, + "name": "testAllTrue", + }, + { + "category": "./lib/customisation.nix", + "description": "\`overrideDerivation drv f\` takes a derivation (i.e., the result + of a call to the builtin function \`derivation\`) and returns a new + derivation in which the attributes of the original are overridden + according to the function \`f\`. The function \`f\` is called with + the original derivation attributes. + + \`overrideDerivation\` allows certain "ad-hoc" customisation + scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance, + if you want to "patch" the derivation returned by a package + function in Nixpkgs to build another version than what the + function itself provides, you can do something like this: + + mySed = overrideDerivation pkgs.gnused (oldAttrs: { + name = "sed-4.2.2-pre"; + src = fetchurl { + url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2; + sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k"; + }; + patches = []; + }); + + For another application, see build-support/vm, where this + function is used to build arbitrary derivations inside a QEMU + virtual machine. + + Note that in order to preserve evaluation errors, the new derivation's + outPath depends on the old one's, which means that this function cannot + be used in circular situations when the old derivation also depends on the + new one. + + You should in general prefer \`drv.overrideAttrs\` over this function; + see the nixpkgs manual for more information on overriding.", + "example": null, + "fn_type": null, + "id": "lib.customisation.overrideDerivation", + "line": 39, + "name": "overrideDerivation", + }, + { + "category": "./lib/customisation.nix", + "description": "\`makeOverridable\` takes a function from attribute set to attribute set and + injects \`override\` attribute which can be used to override arguments of + the function. + + nix-repl> x = {a, b}: { result = a + b; } + + nix-repl> y = lib.makeOverridable x { a = 1; b = 2; } + + nix-repl> y + { override = «lambda»; overrideDerivation = «lambda»; result = 3; } + + nix-repl> y.override { a = 10; } + { override = «lambda»; overrideDerivation = «lambda»; result = 12; } + + Please refer to "Nixpkgs Contributors Guide" section + ".overrideDerivation" to learn about \`overrideDerivation\` and caveats + related to its use.", + "example": null, + "fn_type": null, + "id": "lib.customisation.makeOverridable", + "line": 78, + "name": "makeOverridable", + }, + { + "category": "./lib/customisation.nix", + "description": "Call the package function in the file \`fn\` with the required + arguments automatically. The function is called with the + arguments \`args\`, but any missing arguments are obtained from + \`autoArgs\`. This function is intended to be partially + parameterised, e.g., + + callPackage = callPackageWith pkgs; + pkgs = { + libfoo = callPackage ./foo.nix { }; + libbar = callPackage ./bar.nix { }; + }; + + If the \`libbar\` function expects an argument named \`libfoo\`, it is + automatically passed as an argument. Overrides or missing + arguments can be supplied in \`args\`, e.g. + + libbar = callPackage ./bar.nix { + libfoo = null; + enableX11 = true; + };", + "example": null, + "fn_type": null, + "id": "lib.customisation.callPackageWith", + "line": 128, + "name": "callPackageWith", + }, + { + "category": "./lib/customisation.nix", + "description": "Like callPackage, but for a function that returns an attribute + set of derivations. The override function is added to the + individual attributes.", + "example": null, + "fn_type": null, + "id": "lib.customisation.callPackagesWith", + "line": 185, + "name": "callPackagesWith", + }, + { + "category": "./lib/customisation.nix", + "description": "Add attributes to each output of a derivation without changing + the derivation itself and check a given condition when evaluating.", + "example": null, + "fn_type": null, + "id": "lib.customisation.extendDerivation", + "line": 202, + "name": "extendDerivation", + }, + { + "category": "./lib/customisation.nix", + "description": "Strip a derivation of all non-essential attributes, returning + only those needed by hydra-eval-jobs. Also strictly evaluate the + result to ensure that there are no thunks kept alive to prevent + garbage collection.", + "example": null, + "fn_type": null, + "id": "lib.customisation.hydraJob", + "line": 229, + "name": "hydraJob", + }, + { + "category": "./lib/customisation.nix", + "description": "Make a set of packages with a common scope. All packages called + with the provided \`callPackage\` will be evaluated with the same + arguments. Any package in the set may depend on any other. The + \`overrideScope'\` function allows subsequent modification of the package + set in a consistent way, i.e. all packages in the set will be + called with the overridden packages. The package sets may be + hierarchical: the packages in the set are called with the scope + provided by \`newScope\` and the set provides a \`newScope\` attribute + which can form the parent scope for later package sets.", + "example": null, + "fn_type": null, + "id": "lib.customisation.makeScope", + "line": 267, + "name": "makeScope", + }, + { + "category": "./lib/customisation.nix", + "description": "Like the above, but aims to support cross compilation. It's still ugly, but + hopefully it helps a little bit.", + "example": null, + "fn_type": null, + "id": "lib.customisation.makeScopeWithSplicing", + "line": 281, + "name": "makeScopeWithSplicing", + }, + { + "category": "./lib/cli.nix", + "description": "Automatically convert an attribute set to command-line options. + + This helps protect against malformed command lines and also to reduce + boilerplate related to command-line construction for simple use cases. + + \`toGNUCommandLine\` returns a list of nix strings. + \`toGNUCommandLineShell\` returns an escaped shell string.", + "example": "cli.toGNUCommandLine {} { + data = builtins.toJSON { id = 0; }; + X = "PUT"; + retry = 3; + retry-delay = null; + url = [ "https://example.com/foo" "https://example.com/bar" ]; + silent = false; + verbose = true; +} +=> [ + "-X" "PUT" + "--data" "{\\"id\\":0}" + "--retry" "3" + "--url" "https://example.com/foo" + "--url" "https://example.com/bar" + "--verbose" +] + +cli.toGNUCommandLineShell {} { + data = builtins.toJSON { id = 0; }; + X = "PUT"; + retry = 3; + retry-delay = null; + url = [ "https://example.com/foo" "https://example.com/bar" ]; + silent = false; + verbose = true; +} +=> "'-X' 'PUT' '--data' '{\\"id\\":0}' '--retry' '3' '--url' 'https://example.com/foo' '--url' 'https://example.com/bar' '--verbose'";", + "fn_type": null, + "id": "lib.cli.toGNUCommandLineShell", + "line": 42, + "name": "toGNUCommandLineShell", + }, + { + "category": "./lib/attrsets.nix", + "description": "Return an attribute from nested attribute sets.", + "example": "x = { a = { b = 3; }; } +# ["a" "b"] is equivalent to x.a.b +# 6 is a default value to return if the path does not exist in attrset +attrByPath ["a" "b"] 6 x +=> 3 +attrByPath ["z" "z"] 6 x +=> 6", + "fn_type": "attrByPath :: [String] -> Any -> AttrSet -> Any", + "id": "lib.attrsets.attrByPath", + "line": 30, + "name": "attrByPath", + }, + { + "category": "./lib/attrsets.nix", + "description": "Return if an attribute from nested attribute set exists.", + "example": "x = { a = { b = 3; }; } +hasAttrByPath ["a" "b"] x +=> true +hasAttrByPath ["z" "z"] x +=> false", + "fn_type": "hasAttrByPath :: [String] -> AttrSet -> Bool", + "id": "lib.attrsets.hasAttrByPath", + "line": 56, + "name": "hasAttrByPath", + }, + { + "category": "./lib/attrsets.nix", + "description": "Create a new attribute set with \`value\` set at the nested attribute location specified in \`attrPath\`.", + "example": "setAttrByPath ["a" "b"] 3 +=> { a = { b = 3; }; }", + "fn_type": "setAttrByPath :: [String] -> Any -> AttrSet", + "id": "lib.attrsets.setAttrByPath", + "line": 78, + "name": "setAttrByPath", + }, + { + "category": "./lib/attrsets.nix", + "description": "Like \`attrByPath\`, but without a default value. If it doesn't find the + path it will throw an error.", + "example": "x = { a = { b = 3; }; } +getAttrFromPath ["a" "b"] x +=> 3 +getAttrFromPath ["z" "z"] x +=> error: cannot find attribute \`z.z'", + "fn_type": "getAttrFromPath :: [String] -> AttrSet -> Any", + "id": "lib.attrsets.getAttrFromPath", + "line": 104, + "name": "getAttrFromPath", + }, + { + "category": "./lib/attrsets.nix", + "description": "Map each attribute in the given set and merge them into a new attribute set.", + "example": "concatMapAttrs + (name: value: { + \${name} = value; + \${name + value} = value; + }) + { x = "a"; y = "b"; } +=> { x = "a"; xa = "a"; y = "b"; yb = "b"; }", + "fn_type": "concatMapAttrs :: (String -> a -> AttrSet) -> AttrSet -> AttrSet", + "id": "lib.attrsets.concatMapAttrs", + "line": 126, + "name": "concatMapAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Update or set specific paths of an attribute set. + + Takes a list of updates to apply and an attribute set to apply them to, + and returns the attribute set with the updates applied. Updates are + represented as \`{ path = ...; update = ...; }\` values, where \`path\` is a + list of strings representing the attribute path that should be updated, + and \`update\` is a function that takes the old value at that attribute path + as an argument and returns the new + value it should be. + + Properties: + + - Updates to deeper attribute paths are applied before updates to more + shallow attribute paths + + - Multiple updates to the same attribute path are applied in the order + they appear in the update list + + - If any but the last \`path\` element leads into a value that is not an + attribute set, an error is thrown + + - If there is an update for an attribute path that doesn't exist, + accessing the argument in the update function causes an error, but + intermediate attribute sets are implicitly created as needed", + "example": "updateManyAttrsByPath [ + { + path = [ "a" "b" ]; + update = old: { d = old.c; }; + } + { + path = [ "a" "b" "c" ]; + update = old: old + 1; + } + { + path = [ "x" "y" ]; + update = old: "xy"; + } +] { a.b.c = 0; } +=> { a = { b = { d = 1; }; }; x = { y = "xy"; }; }", + "fn_type": "updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet", + "id": "lib.attrsets.updateManyAttrsByPath", + "line": 173, + "name": "updateManyAttrsByPath", + }, + { + "category": "./lib/attrsets.nix", + "description": "Return the specified attributes from a set.", + "example": "attrVals ["a" "b" "c"] as +=> [as.a as.b as.c]", + "fn_type": "attrVals :: [String] -> AttrSet -> [Any]", + "id": "lib.attrsets.attrVals", + "line": 241, + "name": "attrVals", + }, + { + "category": "./lib/attrsets.nix", + "description": "Return the values of all attributes in the given set, sorted by + attribute name.", + "example": "attrValues {c = 3; a = 1; b = 2;} +=> [1 2 3]", + "fn_type": "attrValues :: AttrSet -> [Any]", + "id": "lib.attrsets.attrValues", + "line": 258, + "name": "attrValues", + }, + { + "category": "./lib/attrsets.nix", + "description": "Given a set of attribute names, return the set of the corresponding + attributes from the given set.", + "example": "getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; } +=> { a = 1; b = 2; }", + "fn_type": "getAttrs :: [String] -> AttrSet -> AttrSet", + "id": "lib.attrsets.getAttrs", + "line": 271, + "name": "getAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Collect each attribute named \`attr\` from a list of attribute + sets. Sets that don't contain the named attribute are ignored.", + "example": "catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}] +=> [1 2]", + "fn_type": "catAttrs :: String -> [AttrSet] -> [Any]", + "id": "lib.attrsets.catAttrs", + "line": 287, + "name": "catAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Filter an attribute set by removing all attributes for which the + given predicate return false.", + "example": "filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; } +=> { foo = 1; }", + "fn_type": "filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet", + "id": "lib.attrsets.filterAttrs", + "line": 301, + "name": "filterAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Filter an attribute set recursively by removing all attributes for + which the given predicate return false.", + "example": "filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; } +=> { foo = {}; }", + "fn_type": "filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet", + "id": "lib.attrsets.filterAttrsRecursive", + "line": 319, + "name": "filterAttrsRecursive", + }, + { + "category": "./lib/attrsets.nix", + "description": "Apply fold functions to values grouped by key.", + "example": "foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }] +=> { a = [ 2 3 ]; }", + "fn_type": "foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any", + "id": "lib.attrsets.foldAttrs", + "line": 346, + "name": "foldAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Recursively collect sets that verify a given predicate named \`pred\` + from the set \`attrs\`. The recursion is stopped when the predicate is + verified.", + "example": "collect isList { a = { b = ["b"]; }; c = [1]; } +=> [["b"] [1]] + +collect (x: x ? outPath) + { a = { outPath = "a/"; }; b = { outPath = "b/"; }; } +=> [{ outPath = "a/"; } { outPath = "b/"; }]", + "fn_type": "collect :: (AttrSet -> Bool) -> AttrSet -> [x]", + "id": "lib.attrsets.collect", + "line": 375, + "name": "collect", + }, + { + "category": "./lib/attrsets.nix", + "description": "Return the cartesian product of attribute set value combinations.", + "example": "cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; } +=> [ + { a = 1; b = 10; } + { a = 1; b = 20; } + { a = 2; b = 10; } + { a = 2; b = 20; } + ]", + "fn_type": "cartesianProductOfSets :: AttrSet -> [AttrSet]", + "id": "lib.attrsets.cartesianProductOfSets", + "line": 400, + "name": "cartesianProductOfSets", + }, + { + "category": "./lib/attrsets.nix", + "description": "Utility function that creates a \`{name, value}\` pair as expected by \`builtins.listToAttrs\`.", + "example": "nameValuePair "some" 6 +=> { name = "some"; value = 6; }", + "fn_type": "nameValuePair :: String -> Any -> { name :: String; value :: Any; }", + "id": "lib.attrsets.nameValuePair", + "line": 419, + "name": "nameValuePair", + }, + { + "category": "./lib/attrsets.nix", + "description": "Apply a function to each element in an attribute set, creating a new attribute set.", + "example": "mapAttrs (name: value: name + "-" + value) + { x = "foo"; y = "bar"; } +=> { x = "x-foo"; y = "y-bar"; }", + "fn_type": "mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet", + "id": "lib.attrsets.mapAttrs", + "line": 437, + "name": "mapAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Like \`mapAttrs\`, but allows the name of each attribute to be + changed in addition to the value. The applied function should + return both the new name and value as a \`nameValuePair\`.", + "example": "mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value)) + { x = "a"; y = "b"; } +=> { foo_x = "bar-a"; foo_y = "bar-b"; }", + "fn_type": "mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet", + "id": "lib.attrsets.mapAttrs'", + "line": 454, + "name": "mapAttrs'", + }, + { + "category": "./lib/attrsets.nix", + "description": "Call a function for each attribute in the given set and return + the result in a list.", + "example": "mapAttrsToList (name: value: name + value) + { x = "a"; y = "b"; } +=> [ "xa" "yb" ]", + "fn_type": "mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b]", + "id": "lib.attrsets.mapAttrsToList", + "line": 474, + "name": "mapAttrsToList", + }, + { + "category": "./lib/attrsets.nix", + "description": "Like \`mapAttrs\`, except that it recursively applies itself to + the *leaf* attributes of a potentially-nested attribute set: + the second argument of the function will never be an attrset. + Also, the first argument of the argument function is a *list* + of the attribute names that form the path to the leaf attribute. + + For a function that gives you control over what counts as a leaf, + see \`mapAttrsRecursiveCond\`.", + "example": "mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value])) + { n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; } +=> { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }", + "fn_type": "mapAttrsRecursive :: ([String] -> a -> b) -> AttrSet -> AttrSet", + "id": "lib.attrsets.mapAttrsRecursive", + "line": 499, + "name": "mapAttrsRecursive", + }, + { + "category": "./lib/attrsets.nix", + "description": "Like \`mapAttrsRecursive\`, but it takes an additional predicate + function that tells it whether to recurse into an attribute + set. If it returns false, \`mapAttrsRecursiveCond\` does not + recurse, but does apply the map function. If it returns true, it + does recurse, and does not apply the map function.", + "example": "# To prevent recursing into derivations (which are attribute +# sets with the attribute "type" equal to "derivation"): +mapAttrsRecursiveCond + (as: !(as ? "type" && as.type == "derivation")) + (x: ... do something ...) + attrs", + "fn_type": "mapAttrsRecursiveCond :: (AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet", + "id": "lib.attrsets.mapAttrsRecursiveCond", + "line": 524, + "name": "mapAttrsRecursiveCond", + }, + { + "category": "./lib/attrsets.nix", + "description": "Generate an attribute set by mapping a function over a list of + attribute names.", + "example": "genAttrs [ "foo" "bar" ] (name: "x_" + name) +=> { foo = "x_foo"; bar = "x_bar"; }", + "fn_type": "genAttrs :: [ String ] -> (String -> Any) -> AttrSet", + "id": "lib.attrsets.genAttrs", + "line": 553, + "name": "genAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Check whether the argument is a derivation. Any set with + \`{ type = "derivation"; }\` counts as a derivation.", + "example": "nixpkgs = import {} +isDerivation nixpkgs.ruby +=> true +isDerivation "foobar" +=> false", + "fn_type": "isDerivation :: Any -> Bool", + "id": "lib.attrsets.isDerivation", + "line": 574, + "name": "isDerivation", + }, + { + "category": "./lib/attrsets.nix", + "description": "Converts a store path to a fake derivation.", + "example": null, + "fn_type": "toDerivation :: Path -> Derivation", + "id": "lib.attrsets.toDerivation", + "line": 583, + "name": "toDerivation", + }, + { + "category": "./lib/attrsets.nix", + "description": "If \`cond\` is true, return the attribute set \`as\`, + otherwise an empty attribute set.", + "example": "optionalAttrs (true) { my = "set"; } +=> { my = "set"; } +optionalAttrs (false) { my = "set"; } +=> { }", + "fn_type": "optionalAttrs :: Bool -> AttrSet -> AttrSet", + "id": "lib.attrsets.optionalAttrs", + "line": 611, + "name": "optionalAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Merge sets of attributes and use the function \`f\` to merge attributes + values.", + "example": "zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}] +=> { a = ["x" "y"]; }", + "fn_type": "zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet", + "id": "lib.attrsets.zipAttrsWithNames", + "line": 629, + "name": "zipAttrsWithNames", + }, + { + "category": "./lib/attrsets.nix", + "description": "Merge sets of attributes and use the function f to merge attribute values. + Like \`lib.attrsets.zipAttrsWithNames\` with all key names are passed for \`names\`. + + Implementation note: Common names appear multiple times in the list of + names, hopefully this does not affect the system because the maximal + laziness avoid computing twice the same expression and \`listToAttrs\` does + not care about duplicated attribute names.", + "example": "zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}] +=> { a = ["x" "y"]; b = ["z"]; }", + "fn_type": "zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet", + "id": "lib.attrsets.zipAttrsWith", + "line": 657, + "name": "zipAttrsWith", + }, + { + "category": "./lib/attrsets.nix", + "description": "Merge sets of attributes and combine each attribute value in to a list. + + Like \`lib.attrsets.zipAttrsWith\` with \`(name: values: values)\` as the function.", + "example": "zipAttrs [{a = "x";} {a = "y"; b = "z";}] +=> { a = ["x" "y"]; b = ["z"]; }", + "fn_type": "zipAttrs :: [ AttrSet ] -> AttrSet", + "id": "lib.attrsets.zipAttrs", + "line": 672, + "name": "zipAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Does the same as the update operator '//' except that attributes are + merged until the given predicate is verified. The predicate should + accept 3 arguments which are the path to reach the attribute, a part of + the first attribute set and a part of the second attribute set. When + the predicate is satisfied, the value of the first attribute set is + replaced by the value of the second attribute set.", + "example": "recursiveUpdateUntil (path: l: r: path == ["foo"]) { + # first attribute set + foo.bar = 1; + foo.baz = 2; + bar = 3; +} { + #second attribute set + foo.bar = 1; + foo.quz = 2; + baz = 4; +} + +=> { + foo.bar = 1; # 'foo.*' from the second set + foo.quz = 2; # + bar = 3; # 'bar' from the first set + baz = 4; # 'baz' from the second set +}", + "fn_type": "recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet", + "id": "lib.attrsets.recursiveUpdateUntil", + "line": 708, + "name": "recursiveUpdateUntil", + }, + { + "category": "./lib/attrsets.nix", + "description": "A recursive variant of the update operator ‘//’. The recursion + stops when one of the attribute values is not an attribute set, + in which case the right hand side value takes precedence over the + left hand side value.", + "example": "recursiveUpdate { + boot.loader.grub.enable = true; + boot.loader.grub.device = "/dev/hda"; +} { + boot.loader.grub.device = ""; +} + +returns: { + boot.loader.grub.enable = true; + boot.loader.grub.device = ""; +}", + "fn_type": "recursiveUpdate :: AttrSet -> AttrSet -> AttrSet", + "id": "lib.attrsets.recursiveUpdate", + "line": 748, + "name": "recursiveUpdate", + }, + { + "category": "./lib/attrsets.nix", + "description": "Returns true if the pattern is contained in the set. False otherwise.", + "example": "matchAttrs { cpu = {}; } { cpu = { bits = 64; }; } +=> true", + "fn_type": "matchAttrs :: AttrSet -> AttrSet -> Bool", + "id": "lib.attrsets.matchAttrs", + "line": 765, + "name": "matchAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Override only the attributes that are already present in the old set + useful for deep-overriding.", + "example": "overrideExisting {} { a = 1; } +=> {} +overrideExisting { b = 2; } { a = 1; } +=> { b = 2; } +overrideExisting { a = 3; b = 2; } { a = 1; } +=> { a = 1; b = 2; }", + "fn_type": "overrideExisting :: AttrSet -> AttrSet -> AttrSet", + "id": "lib.attrsets.overrideExisting", + "line": 793, + "name": "overrideExisting", + }, + { + "category": "./lib/attrsets.nix", + "description": "Turns a list of strings into a human-readable description of those + strings represented as an attribute path. The result of this function is + not intended to be machine-readable. + Create a new attribute set with \`value\` set at the nested attribute location specified in \`attrPath\`.", + "example": "showAttrPath [ "foo" "10" "bar" ] +=> "foo.\\"10\\".bar" +showAttrPath [] +=> """, + "fn_type": "showAttrPath :: [String] -> String", + "id": "lib.attrsets.showAttrPath", + "line": 815, + "name": "showAttrPath", + }, + { + "category": "./lib/attrsets.nix", + "description": "Get a package output. + If no output is found, fallback to \`.out\` and then to the default.", + "example": "getOutput "dev" pkgs.openssl +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"", + "fn_type": "getOutput :: String -> Derivation -> String", + "id": "lib.attrsets.getOutput", + "line": 832, + "name": "getOutput", + }, + { + "category": "./lib/attrsets.nix", + "description": "Get a package's \`bin\` output. + If the output does not exist, fallback to \`.out\` and then to the default.", + "example": "getBin pkgs.openssl +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r"", + "fn_type": "getBin :: Derivation -> String", + "id": "lib.attrsets.getBin", + "line": 847, + "name": "getBin", + }, + { + "category": "./lib/attrsets.nix", + "description": "Get a package's \`lib\` output. + If the output does not exist, fallback to \`.out\` and then to the default.", + "example": "getLib pkgs.openssl +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib"", + "fn_type": "getLib :: Derivation -> String", + "id": "lib.attrsets.getLib", + "line": 860, + "name": "getLib", + }, + { + "category": "./lib/attrsets.nix", + "description": "Get a package's \`dev\` output. + If the output does not exist, fallback to \`.out\` and then to the default.", + "example": "getDev pkgs.openssl +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"", + "fn_type": "getDev :: Derivation -> String", + "id": "lib.attrsets.getDev", + "line": 873, + "name": "getDev", + }, + { + "category": "./lib/attrsets.nix", + "description": "Get a package's \`man\` output. + If the output does not exist, fallback to \`.out\` and then to the default.", + "example": "getMan pkgs.openssl +=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man"", + "fn_type": "getMan :: Derivation -> String", + "id": "lib.attrsets.getMan", + "line": 886, + "name": "getMan", + }, + { + "category": "./lib/attrsets.nix", + "description": "Pick the outputs of packages to place in \`buildInputs\`", + "example": null, + "fn_type": "chooseDevOutputs :: [Derivation] -> [String]", + "id": "lib.attrsets.chooseDevOutputs", + "line": 893, + "name": "chooseDevOutputs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Make various Nix tools consider the contents of the resulting + attribute set when looking for what to build, find, etc. + + This function only affects a single attribute set; it does not + apply itself recursively for nested attribute sets.", + "example": "{ pkgs ? import {} }: +{ + myTools = pkgs.lib.recurseIntoAttrs { + inherit (pkgs) hello figlet; + }; +}", + "fn_type": "recurseIntoAttrs :: AttrSet -> AttrSet", + "id": "lib.attrsets.recurseIntoAttrs", + "line": 916, + "name": "recurseIntoAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "Undo the effect of recurseIntoAttrs.", + "example": null, + "fn_type": "dontRecurseIntoAttrs :: AttrSet -> AttrSet", + "id": "lib.attrsets.dontRecurseIntoAttrs", + "line": 926, + "name": "dontRecurseIntoAttrs", + }, + { + "category": "./lib/attrsets.nix", + "description": "\`unionOfDisjoint x y\` is equal to \`x // y // z\` where the + attrnames in \`z\` are the intersection of the attrnames in \`x\` and + \`y\`, and all values \`assert\` with an error message. This + operator is commutative, unlike (//).", + "example": null, + "fn_type": "unionOfDisjoint :: AttrSet -> AttrSet -> AttrSet", + "id": "lib.attrsets.unionOfDisjoint", + "line": 938, + "name": "unionOfDisjoint", + }, + { + "category": "./lib/asserts.nix", + "description": "Throw if pred is false, else return pred. + Intended to be used to augment asserts with helpful error messages.", + "example": "assertMsg false "nope" +stderr> error: nope + +assert assertMsg ("foo" == "bar") "foo is not bar, silly"; "" +stderr> error: foo is not bar, silly", + "fn_type": "assertMsg :: Bool -> String -> Bool", + "id": "lib.asserts.assertMsg", + "line": 19, + "name": "assertMsg", + }, + { + "category": "./lib/asserts.nix", + "description": "Specialized \`assertMsg\` for checking if \`val\` is one of the elements + of the list \`xs\`. Useful for checking enums.", + "example": "let sslLibrary = "libressl"; +in assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ] +stderr> error: sslLibrary must be one of [ +stderr> "openssl" +stderr> "bearssl" +stderr> ], but is: "libressl"", + "fn_type": "assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool", + "id": "lib.asserts.assertOneOf", + "line": 40, + "name": "assertOneOf", + }, +] +`; + +exports[`has not changed trivial-builders data 1`] = ` +[ + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Run the shell command \`buildCommand' to produce a store path named + \`name'. The attributes in \`env' are added to the environment + prior to running the command. By default \`runCommand\` runs in a + stdenv with no compiler environment. \`runCommandCC\` uses the default + stdenv, \`pkgs.stdenv\`.", + "example": "runCommand "name" {envVariable = true;} ''echo hello > $out'' +runCommandCC "name" {} ''gcc -o myfile myfile.c; cp myfile $out''; + + +The \`*Local\` variants force a derivation to be built locally, +it is not substituted. + +This is intended for very cheap commands (<1s execution time). +It saves on the network roundrip and can speed up a build. + +It is the same as adding the special fields + +\`preferLocalBuild = true;\` +\`allowSubstitutes = false;\` + +to a derivation’s attributes.", + "fn_type": null, + "id": "build-support.trivial-builders.runCommand", + "line": 38, + "name": "runCommand", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Generalized version of the \`runCommand\`-variants + which does customized behavior via a single + attribute set passed as the first argument + instead of having a lot of variants like + \`runCommand*\`. Additionally it allows changing + the used \`stdenv\` freely and has a more explicit + approach to changing the arguments passed to + \`stdenv.mkDerivation\`.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.runCommandWith", + "line": 69, + "name": "runCommandWith", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to the nix store. + The contents of text is added to the file in the store.", + "example": "# Writes my-file to /nix/store/ +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; +} + + +See also the \`writeText\` helper function below. + + +# Writes executable my-file to /nix/store//bin/my-file +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; + executable = true; + destination = "/bin/my-file"; +}", + "fn_type": null, + "id": "build-support.trivial-builders.writeTextFile", + "line": 128, + "name": "writeTextFile", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to nix store with no optional parameters available.", + "example": "# Writes contents of file to /nix/store/ +writeText "my-file" + '' + Contents of File + '';", + "fn_type": null, + "id": "build-support.trivial-builders.writeText", + "line": 172, + "name": "writeText", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to nix store in a specific directory with no +optional parameters available.", + "example": "# Writes contents of file to /nix/store//share/my-file +writeTextDir "share/my-file" + '' + Contents of File + '';", + "fn_type": null, + "id": "build-support.trivial-builders.writeTextDir", + "line": 189, + "name": "writeTextDir", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to /nix/store/ and marks the file as +executable. + +If passed as a build input, will be used as a setup hook. This makes setup +hooks more efficient to create: you don't need a derivation that copies +them to $out/nix-support/setup-hook, instead you can use the file as is.", + "example": "# Writes my-file to /nix/store/ and makes executable +writeScript "my-file" + '' + Contents of File + '';", + "fn_type": null, + "id": "build-support.trivial-builders.writeScript", + "line": 214, + "name": "writeScript", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to /nix/store//bin/ and +marks the file as executable.", + "example": "# Writes my-file to /nix/store//bin/my-file and makes executable. +writeScriptBin "my-file" + '' + Contents of File + '';", + "fn_type": null, + "id": "build-support.trivial-builders.writeScriptBin", + "line": 232, + "name": "writeScriptBin", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Similar to writeScript. Writes a Shell script and checks its syntax. +Automatically includes interpreter above the contents passed.", + "example": "# Writes my-file to /nix/store/ and makes executable. +writeShellScript "my-file" + '' + Contents of File + '';", + "fn_type": null, + "id": "build-support.trivial-builders.writeShellScript", + "line": 249, + "name": "writeShellScript", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Similar to writeShellScript and writeScriptBin. +Writes an executable Shell script to /nix/store//bin/ and checks its syntax. +Automatically includes interpreter above the contents passed.", + "example": "# Writes my-file to /nix/store//bin/my-file and makes executable. +writeShellScriptBin "my-file" + '' + Contents of File + '';", + "fn_type": null, + "id": "build-support.trivial-builders.writeShellScriptBin", + "line": 278, + "name": "writeShellScriptBin", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Similar to writeShellScriptBin and writeScriptBin. +Writes an executable Shell script to /nix/store//bin/ and +checks its syntax with shellcheck and the shell's -n option. +Automatically includes sane set of shellopts (errexit, nounset, pipefail) +and handles creation of PATH based on runtimeInputs + +Note that the checkPhase uses stdenv.shell for the test run of the script, +while the generated shebang uses runtimeShell. If, for whatever reason, +those were to mismatch you might lose fidelity in the default checks.", + "example": "Writes my-file to /nix/store//bin/my-file and makes executable. + + +writeShellApplication { + name = "my-file"; + runtimeInputs = [ curl w3m ]; + text = '' + curl -s 'https://nixos.org' | w3m -dump -T text/html + ''; +}", + "fn_type": null, + "id": "build-support.trivial-builders.writeShellApplication", + "line": 317, + "name": "writeShellApplication", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "concat a list of files to the nix store. + The contents of files are added to the file in the store.", + "example": "# Writes my-file to /nix/store/ +concatTextFile { + name = "my-file"; + files = [ drv1 "\${drv2}/path/to/file" ]; +} + + +See also the \`concatText\` helper function below. + + +# Writes executable my-file to /nix/store//bin/my-file +concatTextFile { + name = "my-file"; + files = [ drv1 "\${drv2}/path/to/file" ]; + executable = true; + destination = "/bin/my-file"; +}", + "fn_type": null, + "id": "build-support.trivial-builders.concatTextFile", + "line": 397, + "name": "concatTextFile", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to nix store with no optional parameters available.", + "example": "# Writes contents of files to /nix/store/ +concatText "my-file" [ file1 file2 ]", + "fn_type": null, + "id": "build-support.trivial-builders.concatText", + "line": 428, + "name": "concatText", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Writes a text file to nix store with and mark it as executable.", + "example": "# Writes contents of files to /nix/store/ +concatScript "my-file" [ file1 file2 ]", + "fn_type": null, + "id": "build-support.trivial-builders.concatScript", + "line": 438, + "name": "concatScript", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Create a forest of symlinks to the files in \`paths'. + +This creates a single derivation that replicates the directory structure +of all the input paths. + +BEWARE: it may not "work right" when the passed paths contain symlinks to directories.", + "example": "# adds symlinks of hello to current build. +symlinkJoin { name = "myhello"; paths = [ pkgs.hello ]; } + + + + +# adds symlinks of hello and stack to current build and prints "links added" +symlinkJoin { name = "myexample"; paths = [ pkgs.hello pkgs.stack ]; postBuild = "echo links added"; } + + +This creates a derivation with a directory structure like the following: + + +/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample +|-- bin +| |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello +| \`-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack +\`-- share + |-- bash-completion + | \`-- completions + | \`-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack + |-- fish + | \`-- vendor_completions.d + | \`-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish +... + + +symlinkJoin and linkFarm are similar functions, but they output +derivations with different structure. + +symlinkJoin is used to create a derivation with a familiar directory +structure (top-level bin/, share/, etc), but with all actual files being symlinks to +the files in the input derivations. + +symlinkJoin is used many places in nixpkgs to create a single derivation +that appears to contain binaries, libraries, documentation, etc from +multiple input derivations. + +linkFarm is instead used to create a simple derivation with symlinks to +other derivations. A derivation created with linkFarm is often used in CI +as a easy way to build multiple derivations at once.", + "fn_type": null, + "id": "build-support.trivial-builders.symlinkJoin", + "line": 494, + "name": "symlinkJoin", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Quickly create a set of symlinks to derivations. + +This creates a simple derivation with symlinks to all inputs. + +entries can be a list of attribute sets like + +[ { name = "name" ; path = "/nix/store/..."; } ] + + +or an attribute set name -> path like: + +{ name = "/nix/store/..."; other = "/nix/store/..."; }", + "example": "# Symlinks hello and stack paths in store to current $out/hello-test and +# $out/foobar. +linkFarm "myexample" [ { name = "hello-test"; path = pkgs.hello; } { name = "foobar"; path = pkgs.stack; } ] + +This creates a derivation with a directory structure like the following: + +/nix/store/qc5728m4sa344mbks99r3q05mymwm4rw-myexample +|-- foobar -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1 +\`-- hello-test -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10 + + +See the note on symlinkJoin for the difference between linkFarm and symlinkJoin.", + "fn_type": null, + "id": "build-support.trivial-builders.linkFarm", + "line": 547, + "name": "linkFarm", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Easily create a linkFarm from a set of derivations. + +This calls linkFarm with a list of entries created from the list of input +derivations. It turns each input derivation into an attribute set +like { name = drv.name ; path = drv }, and passes this to linkFarm.", + "example": "# Symlinks the hello, gcc, and ghc derivations in $out +linkFarmFromDrvs "myexample" [ pkgs.hello pkgs.gcc pkgs.ghc ] + +This creates a derivation with a directory structure like the following: + + +/nix/store/m3s6wkjy9c3wy830201bqsb91nk2yj8c-myexample +|-- gcc-wrapper-9.2.0 -> /nix/store/fqhjxf9ii4w4gqcsx59fyw2vvj91486a-gcc-wrapper-9.2.0 +|-- ghc-8.6.5 -> /nix/store/gnf3s07bglhbbk4y6m76sbh42siym0s6-ghc-8.6.5 +\`-- hello-2.10 -> /nix/store/k0ll91c4npk4lg8lqhx00glg2m735g74-hello-2.10", + "fn_type": null, + "id": "build-support.trivial-builders.linkFarmFromDrvs", + "line": 591, + "name": "linkFarmFromDrvs", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Make a package that just contains a setup hook with the given contents. +This setup hook will be invoked by any package that includes this package +as a buildInput. Optionally takes a list of substitutions that should be +applied to the resulting script. + +Examples: +# setup hook that depends on the hello package and runs ./myscript.sh +myhellohook = makeSetupHook { deps = [ hello ]; } ./myscript.sh; + +# writes a Linux-exclusive setup hook where @bash@ myscript.sh is substituted for the +# bash interpreter. +myhellohookSub = makeSetupHook { + name = "myscript-hook"; + deps = [ hello ]; + substitutions = { bash = "\${pkgs.bash}/bin/bash"; }; + meta.platforms = lib.platforms.linux; + } ./myscript.sh; + +# setup hook with a package test +myhellohookTested = makeSetupHook { + name = "myscript-hook"; + deps = [ hello ]; + substitutions = { bash = "\${pkgs.bash}/bin/bash"; }; + meta.platforms = lib.platforms.linux; + passthru.tests.greeting = callPackage ./test { }; + } ./myscript.sh;", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.makeSetupHook", + "line": 624, + "name": "makeSetupHook", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Write the set of references to a file, that is, their immediate dependencies. + +This produces the equivalent of \`nix-store -q --references\`.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.writeDirectReferencesToFile", + "line": 673, + "name": "writeDirectReferencesToFile", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Extract a string's references to derivations and paths (its +context) and write them to a text file, removing the input string +itself from the dependency graph. This is useful when you want to +make a derivation depend on the string's references, but not its +contents (to avoid unnecessary rebuilds, for example). + +Note that this only works as intended on Nix >= 2.3.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.writeStringReferencesToFile", + "line": 707, + "name": "writeStringReferencesToFile", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Print an error message if the file with the specified name and + hash doesn't exist in the Nix store. This function should only + be used by non-redistributable software with an unfree license + that we need to require the user to download manually. It produces + packages that cannot be built automatically.", + "example": "requireFile { + name = "my-file"; + url = "http://example.com/download/"; + sha256 = "ffffffffffffffffffffffffffffffffffffffffffffffffffff"; +}", + "fn_type": null, + "id": "build-support.trivial-builders.requireFile", + "line": 795, + "name": "requireFile", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Copy a path to the Nix store. +Nix automatically copies files to the store before stringifying paths. +If you need the store path of a file, \${copyPathToStore } can be +shortened to \${}.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.copyPathToStore", + "line": 846, + "name": "copyPathToStore", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Copy a list of paths to the Nix store.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.copyPathsToStore", + "line": 852, + "name": "copyPathsToStore", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "Applies a list of patches to a source directory.", + "example": "# Patching nixpkgs: + +applyPatches { + src = pkgs.path; + patches = [ + (pkgs.fetchpatch { + url = "https://github.com/NixOS/nixpkgs/commit/1f770d20550a413e508e081ddc08464e9d08ba3d.patch"; + sha256 = "1nlzx171y3r3jbk0qhvnl711kmdk57jlq4na8f8bs8wz2pbffymr"; + }) + ]; +}", + "fn_type": null, + "id": "build-support.trivial-builders.applyPatches", + "line": 871, + "name": "applyPatches", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "An immutable file in the store with a length of 0 bytes.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.emptyFile", + "line": 891, + "name": "emptyFile", + }, + { + "category": "./pkgs/build-support/trivial-builders.nix", + "description": "An immutable empty directory in the store.", + "example": null, + "fn_type": null, + "id": "build-support.trivial-builders.emptyDirectory", + "line": 899, + "name": "emptyDirectory", + }, + { + "category": "./pkgs/build-support/plugins.nix", + "description": "Takes a list of expected plugin names + * and compares it to the found plugins given in the file, + * one plugin per line. + * If the lists differ, the build fails with a nice message. + * + * This is helpful to ensure maintainers don’t miss + * the addition or removal of a plugin.", + "example": null, + "fn_type": null, + "id": "build-support.plugins.diffPlugins", + "line": 13, + "name": "diffPlugins", + }, +] +`; diff --git a/tests/data.test.js b/tests/data.test.js new file mode 100644 index 0000000..d4cc6bf --- /dev/null +++ b/tests/data.test.js @@ -0,0 +1,13 @@ +import libData from "./data/lib.json"; +import trivialBuilders from "./data/trivial-builders.json"; +import builtins from "./data/builtins.json"; + +it("has not changed lib data", () => { + expect(libData).toMatchSnapshot(); +}); +it("has not changed trivial-builders data", () => { + expect(trivialBuilders).toMatchSnapshot(); +}); +it("has not changed builtins data", () => { + expect(builtins).toMatchSnapshot(); +}); diff --git a/tests/jest.config.js b/tests/jest.config.js new file mode 100644 index 0000000..043645f --- /dev/null +++ b/tests/jest.config.js @@ -0,0 +1,10 @@ +/** @type {import('jest').Config} */ + +import { defaults } from "jest-config"; + +const config = { + ...defaults, + // transform: {}, +}; + +export default config; diff --git a/tests/package-lock.json b/tests/package-lock.json new file mode 100644 index 0000000..8f1a0c2 --- /dev/null +++ b/tests/package-lock.json @@ -0,0 +1,3434 @@ +{ + "name": "tests", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "jest": "^29.4.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", + "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.0", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.0", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.0", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.21.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", + "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", + "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.1", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.2", + "@babel/types": "^7.21.2", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", + "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.3.tgz", + "integrity": "sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.3.tgz", + "integrity": "sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.3", + "@jest/reporters": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.4.3", + "jest-config": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-resolve-dependencies": "^29.4.3", + "jest-runner": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", + "jest-watcher": "^29.4.3", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.3", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.3.tgz", + "integrity": "sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "jest-mock": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.3.tgz", + "integrity": "sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ==", + "dev": true, + "dependencies": { + "expect": "^29.4.3", + "jest-snapshot": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.3.tgz", + "integrity": "sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.3.tgz", + "integrity": "sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.4.3", + "jest-mock": "^29.4.3", + "jest-util": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.3.tgz", + "integrity": "sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.3", + "@jest/expect": "^29.4.3", + "@jest/types": "^29.4.3", + "jest-mock": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.3.tgz", + "integrity": "sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", + "jest-worker": "^29.4.3", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.3.tgz", + "integrity": "sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.3.tgz", + "integrity": "sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.4.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.3.tgz", + "integrity": "sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.4.3", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.4.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.3.tgz", + "integrity": "sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/node": { + "version": "18.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.1.tgz", + "integrity": "sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.3.tgz", + "integrity": "sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.4.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.4.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.3.tgz", + "integrity": "sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.3.tgz", + "integrity": "sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.4.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001457", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz", + "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.310", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.310.tgz", + "integrity": "sha512-/xlATgfwkm5uDDwLw5nt/MNEf7c1oazLURMZLy39vOioGYyYzLWIDT8fZMJak6qTiAJ7udFTy7JG7ziyjNutiA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.3.tgz", + "integrity": "sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.3.tgz", + "integrity": "sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA==", + "dev": true, + "dependencies": { + "@jest/core": "^29.4.3", + "@jest/types": "^29.4.3", + "import-local": "^3.0.2", + "jest-cli": "^29.4.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.3.tgz", + "integrity": "sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.3.tgz", + "integrity": "sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.3", + "@jest/expect": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", + "p-limit": "^3.1.0", + "pretty-format": "^29.4.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.3.tgz", + "integrity": "sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.3.tgz", + "integrity": "sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.4.3", + "@jest/types": "^29.4.3", + "babel-jest": "^29.4.3", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.4.3", + "jest-environment-node": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-runner": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.4.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.3.tgz", + "integrity": "sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.3.tgz", + "integrity": "sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.4.3", + "pretty-format": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.3.tgz", + "integrity": "sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.3", + "@jest/fake-timers": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "jest-mock": "^29.4.3", + "jest-util": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.3.tgz", + "integrity": "sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.4.3", + "jest-worker": "^29.4.3", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.3.tgz", + "integrity": "sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz", + "integrity": "sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.3.tgz", + "integrity": "sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.4.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.3.tgz", + "integrity": "sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "@types/node": "*", + "jest-util": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.3.tgz", + "integrity": "sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.3", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.3.tgz", + "integrity": "sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.3.tgz", + "integrity": "sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.3", + "@jest/environment": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-leak-detector": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-util": "^29.4.3", + "jest-watcher": "^29.4.3", + "jest-worker": "^29.4.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.3.tgz", + "integrity": "sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.3", + "@jest/fake-timers": "^29.4.3", + "@jest/globals": "^29.4.3", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-mock": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.3.tgz", + "integrity": "sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.4.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", + "natural-compare": "^1.4.0", + "pretty-format": "^29.4.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.3.tgz", + "integrity": "sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.3.tgz", + "integrity": "sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.3.tgz", + "integrity": "sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.4.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.3.tgz", + "integrity": "sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.4.3", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.3.tgz", + "integrity": "sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/tests/package.json b/tests/package.json new file mode 100644 index 0000000..82328a5 --- /dev/null +++ b/tests/package.json @@ -0,0 +1,15 @@ +{ + "name": "tests", + "version": "1.0.0", + "description": "", + "module": "index.js", + "type": "module", + "scripts": { + "test": "NODE_OPTIONS=--experimental-vm-modules npx jest" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "jest": "^29.4.3" + } +} diff --git a/.eslintrc.json b/website/.eslintrc.json similarity index 100% rename from .eslintrc.json rename to website/.eslintrc.json diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..5c22230 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,44 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules +.pnp +.pnp.js + +# testing +coverage +/models/data/* +!/models/data/index.ts + +# nix +.direnv/ + + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem +result +result-* + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/components/NixFunctions/index.ts b/website/components/NixFunctions/index.ts similarity index 100% rename from components/NixFunctions/index.ts rename to website/components/NixFunctions/index.ts diff --git a/components/NixFunctions/nixFunctions.tsx b/website/components/NixFunctions/nixFunctions.tsx similarity index 100% rename from components/NixFunctions/nixFunctions.tsx rename to website/components/NixFunctions/nixFunctions.tsx diff --git a/components/basicList/basicList.tsx b/website/components/basicList/basicList.tsx similarity index 100% rename from components/basicList/basicList.tsx rename to website/components/basicList/basicList.tsx diff --git a/components/basicList/index.tsx b/website/components/basicList/index.tsx similarity index 100% rename from components/basicList/index.tsx rename to website/components/basicList/index.tsx diff --git a/components/codeHighlight/codeHighlight.module.css b/website/components/codeHighlight/codeHighlight.module.css similarity index 100% rename from components/codeHighlight/codeHighlight.module.css rename to website/components/codeHighlight/codeHighlight.module.css diff --git a/components/codeHighlight/codeHighlight.tsx b/website/components/codeHighlight/codeHighlight.tsx similarity index 91% rename from components/codeHighlight/codeHighlight.tsx rename to website/components/codeHighlight/codeHighlight.tsx index 9157537..6d87651 100644 --- a/components/codeHighlight/codeHighlight.tsx +++ b/website/components/codeHighlight/codeHighlight.tsx @@ -15,10 +15,10 @@ export const CodeHighlight = (props: CodeHighlightProps) => { const { theme, code, lang, background } = props; useEffect(() => { if (theme === "dark") { - // @ts-ignore - dont check type of css module + // @ts-ignore - don't check type of css module import("highlight.js/styles/github-dark.css"); } else { - // @ts-ignore - dont check type of css module + // @ts-ignore - don't check type of css module import("highlight.js/styles/github.css"); } }, [theme]); diff --git a/components/codeHighlight/index.ts b/website/components/codeHighlight/index.ts similarity index 100% rename from components/codeHighlight/index.ts rename to website/components/codeHighlight/index.ts diff --git a/components/emptyRecordsPlaceholder/emptyRecordsPlaceholder.tsx b/website/components/emptyRecordsPlaceholder/emptyRecordsPlaceholder.tsx similarity index 100% rename from components/emptyRecordsPlaceholder/emptyRecordsPlaceholder.tsx rename to website/components/emptyRecordsPlaceholder/emptyRecordsPlaceholder.tsx diff --git a/components/emptyRecordsPlaceholder/index.tsx b/website/components/emptyRecordsPlaceholder/index.tsx similarity index 100% rename from components/emptyRecordsPlaceholder/index.tsx rename to website/components/emptyRecordsPlaceholder/index.tsx diff --git a/components/functionItem/functionItem.tsx b/website/components/functionItem/functionItem.tsx similarity index 100% rename from components/functionItem/functionItem.tsx rename to website/components/functionItem/functionItem.tsx diff --git a/components/functionOfTheDay/functionOfTheDay.tsx b/website/components/functionOfTheDay/functionOfTheDay.tsx similarity index 100% rename from components/functionOfTheDay/functionOfTheDay.tsx rename to website/components/functionOfTheDay/functionOfTheDay.tsx diff --git a/components/functionOfTheDay/index.ts b/website/components/functionOfTheDay/index.ts similarity index 100% rename from components/functionOfTheDay/index.ts rename to website/components/functionOfTheDay/index.ts diff --git a/components/image/image.tsx b/website/components/image/image.tsx similarity index 100% rename from components/image/image.tsx rename to website/components/image/image.tsx diff --git a/components/image/index.tsx b/website/components/image/index.tsx similarity index 100% rename from components/image/index.tsx rename to website/components/image/index.tsx diff --git a/components/layout/index.ts b/website/components/layout/index.ts similarity index 100% rename from components/layout/index.ts rename to website/components/layout/index.ts diff --git a/components/layout/layout.tsx b/website/components/layout/layout.tsx similarity index 100% rename from components/layout/layout.tsx rename to website/components/layout/layout.tsx diff --git a/components/markdownPreview/MarkdownPreview.tsx b/website/components/markdownPreview/MarkdownPreview.tsx similarity index 100% rename from components/markdownPreview/MarkdownPreview.tsx rename to website/components/markdownPreview/MarkdownPreview.tsx diff --git a/components/markdownPreview/index.ts b/website/components/markdownPreview/index.ts similarity index 100% rename from components/markdownPreview/index.ts rename to website/components/markdownPreview/index.ts diff --git a/components/pageContext/index.ts b/website/components/pageContext/index.ts similarity index 100% rename from components/pageContext/index.ts rename to website/components/pageContext/index.ts diff --git a/components/pageContext/pageContext.tsx b/website/components/pageContext/pageContext.tsx similarity index 100% rename from components/pageContext/pageContext.tsx rename to website/components/pageContext/pageContext.tsx diff --git a/components/preview/index.tsx b/website/components/preview/index.tsx similarity index 100% rename from components/preview/index.tsx rename to website/components/preview/index.tsx diff --git a/components/preview/preview.tsx b/website/components/preview/preview.tsx similarity index 100% rename from components/preview/preview.tsx rename to website/components/preview/preview.tsx diff --git a/components/searchInput/index.tsx b/website/components/searchInput/index.tsx similarity index 100% rename from components/searchInput/index.tsx rename to website/components/searchInput/index.tsx diff --git a/components/searchInput/searchInput.tsx b/website/components/searchInput/searchInput.tsx similarity index 100% rename from components/searchInput/searchInput.tsx rename to website/components/searchInput/searchInput.tsx diff --git a/components/selectOption/index.ts b/website/components/selectOption/index.ts similarity index 100% rename from components/selectOption/index.ts rename to website/components/selectOption/index.ts diff --git a/components/selectOption/selectOption.tsx b/website/components/selectOption/selectOption.tsx similarity index 100% rename from components/selectOption/selectOption.tsx rename to website/components/selectOption/selectOption.tsx diff --git a/createEmotionCache.ts b/website/createEmotionCache.ts similarity index 100% rename from createEmotionCache.ts rename to website/createEmotionCache.ts diff --git a/models/data/index.ts b/website/models/data/index.ts similarity index 100% rename from models/data/index.ts rename to website/models/data/index.ts diff --git a/models/internals.ts b/website/models/internals.ts similarity index 100% rename from models/internals.ts rename to website/models/internals.ts diff --git a/models/nix.ts b/website/models/nix.ts similarity index 100% rename from models/nix.ts rename to website/models/nix.ts diff --git a/next.config.js b/website/next.config.js similarity index 100% rename from next.config.js rename to website/next.config.js diff --git a/package-lock.json b/website/package-lock.json similarity index 100% rename from package-lock.json rename to website/package-lock.json diff --git a/package.json b/website/package.json similarity index 97% rename from package.json rename to website/package.json index a717020..ae1affd 100644 --- a/package.json +++ b/website/package.json @@ -1,5 +1,5 @@ { - "name": "nextapp", + "name": "noogle", "version": "0.1.0", "private": true, "scripts": { diff --git a/pages/_app.tsx b/website/pages/_app.tsx similarity index 100% rename from pages/_app.tsx rename to website/pages/_app.tsx diff --git a/pages/index.tsx b/website/pages/index.tsx similarity index 100% rename from pages/index.tsx rename to website/pages/index.tsx diff --git a/public/favicon.ico b/website/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to website/public/favicon.ico diff --git a/public/favicon.png b/website/public/favicon.png similarity index 100% rename from public/favicon.png rename to website/public/favicon.png diff --git a/public/nix-snowflake.svg b/website/public/nix-snowflake.svg similarity index 100% rename from public/nix-snowflake.svg rename to website/public/nix-snowflake.svg diff --git a/public/search.xml b/website/public/search.xml similarity index 100% rename from public/search.xml rename to website/public/search.xml diff --git a/public/vercel.svg b/website/public/vercel.svg similarity index 100% rename from public/vercel.svg rename to website/public/vercel.svg diff --git a/public/white.svg b/website/public/white.svg similarity index 100% rename from public/white.svg rename to website/public/white.svg diff --git a/queries/byQuery.ts b/website/queries/byQuery.ts similarity index 100% rename from queries/byQuery.ts rename to website/queries/byQuery.ts diff --git a/queries/byType.ts b/website/queries/byType.ts similarity index 100% rename from queries/byType.ts rename to website/queries/byType.ts diff --git a/queries/index.ts b/website/queries/index.ts similarity index 100% rename from queries/index.ts rename to website/queries/index.ts diff --git a/queries/lib.ts b/website/queries/lib.ts similarity index 100% rename from queries/lib.ts rename to website/queries/lib.ts diff --git a/styles/globals.css b/website/styles/globals.css similarity index 100% rename from styles/globals.css rename to website/styles/globals.css diff --git a/styles/theme/darkThemeOptions.ts b/website/styles/theme/darkThemeOptions.ts similarity index 100% rename from styles/theme/darkThemeOptions.ts rename to website/styles/theme/darkThemeOptions.ts diff --git a/styles/theme/index.tsx b/website/styles/theme/index.tsx similarity index 100% rename from styles/theme/index.tsx rename to website/styles/theme/index.tsx diff --git a/styles/theme/lightThemeOptions.ts b/website/styles/theme/lightThemeOptions.ts similarity index 100% rename from styles/theme/lightThemeOptions.ts rename to website/styles/theme/lightThemeOptions.ts diff --git a/tsconfig.json b/website/tsconfig.json similarity index 100% rename from tsconfig.json rename to website/tsconfig.json diff --git a/types/basicDataView.ts b/website/types/basicDataView.ts similarity index 100% rename from types/basicDataView.ts rename to website/types/basicDataView.ts