diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd28d427..a9302363 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,6 +44,16 @@ jobs: run_install: false standalone: true + - name: Cache pnpm + uses: actions/cache@v3 + with: + key: ci-pnpm-${{ matrix.os }} + path: | + ${{ env.PNPM_HOME }}/store/v3 + ${{ env.HOME }}/.local/share/pnpm/store/v3 + timeout-minutes: 1 + continue-on-error: true + - name: Clippy run: cargo clippy --locked -- -D warnings @@ -52,18 +62,28 @@ jobs: RUSTDOCFLAGS: '-D warnings' run: cargo doc + - name: Install just + uses: taiki-e/install-action@just + + - name: Install dependencies + run: just install + - name: Install cargo-nextest uses: taiki-e/install-action@cargo-nextest - name: Test shell: bash run: | + just registry-mock launch + # removing env vars is a temporary workaround for unit tests in pacquet relying on external environment # this should be removed in the future unset PNPM_HOME unset XDG_DATA_HOME - cargo nextest run + just test + + just registry-mock end typos: name: Spell Check diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 5f9f4d41..e1612242 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -47,8 +47,26 @@ jobs: run_install: false standalone: true + - name: Cache pnpm + uses: actions/cache@v3 + with: + key: codecov-pnpm-${{ matrix.os }} + path: | + ${{ env.PNPM_HOME }}/store/v3 + ${{ env.HOME }}/.local/share/pnpm/store/v3 + timeout-minutes: 1 + continue-on-error: true + + - name: Install just + uses: taiki-e/install-action@just + + - name: Install dependencies + run: just install + - name: Run run: | + just registry-mock launch + # removing env vars is a temporary workaround for unit tests in pacquet relying on external environment # this should be removed in the future unset PNPM_HOME @@ -56,6 +74,8 @@ jobs: cargo codecov --lcov --output-path lcov.info + just registry-mock end + - name: Upload Artifact uses: actions/upload-artifact@v3 with: diff --git a/Cargo.lock b/Cargo.lock index 05d751cb..88afa540 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "advisory-lock" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6caee7d48f930f9ad3fc9546f8cbf843365da0c5b0ca4eee1d1ac3dd12d8f93" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "aho-corasick" version = "1.0.2" @@ -1172,6 +1182,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1480,6 +1499,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "pacquet-registry-mock" +version = "0.0.0" +dependencies = [ + "advisory-lock", + "assert_cmd", + "clap", + "pipe-trait", + "portpicker", + "reqwest", + "serde", + "serde_json", + "sysinfo", + "tokio", + "which", +] + [[package]] name = "pacquet-store-dir" version = "0.0.1" @@ -1526,6 +1562,7 @@ dependencies = [ "assert_cmd", "command-extra", "junction", + "pacquet-registry-mock", "tempfile", "text-block-macros", "walkdir", @@ -1612,6 +1649,15 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "portpicker" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be97d76faf1bfab666e1375477b23fde79eccf0276e9b63b92a39d676a889ba9" +dependencies = [ + "rand", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2165,6 +2211,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sysinfo" +version = "0.29.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + [[package]] name = "tar" version = "0.4.40" diff --git a/Cargo.toml b/Cargo.toml index 2b2109f7..4c84a056 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,11 @@ pacquet-executor = { path = "crates/executor" } pacquet-diagnostics = { path = "crates/diagnostics" } pacquet-store-dir = { path = "crates/store-dir" } +# Tasks +pacquet-registry-mock = { path = "tasks/registry-mock" } + # Dependencies +advisory-lock = { version = "0.3.0" } async-recursion = { version = "1.0.5" } clap = { version = "4", features = ["derive", "string"] } command-extra = { version = "1.0.0" } @@ -45,6 +49,7 @@ junction = { version = "1.0.0" } reqwest = { version = "0.11", default-features = false, features = ["json", "native-tls-vendored"] } node-semver = { version = "2.1.0" } pipe-trait = { version = "0.4.0" } +portpicker = { version = "0.1.1" } rayon = { version = "1.8.0" } serde = { version = "1.0.188", features = ["derive"] } serde_ini = { version = "0.2.0" } @@ -54,6 +59,7 @@ sha2 = { version = "0.10.8" } split-first-char = { version = "0.0.0" } ssri = { version = "9.0.0" } strum = { version = "0.25.0", features = ["derive"] } +sysinfo = { version = "0.29.10" } tar = { version = "0.4.40" } text-block-macros = { version = "0.1.1" } tracing = { version = "0.1.37" } diff --git a/README.md b/README.md index 9357dbd5..4aad6e23 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,19 @@ Experimental package manager for node.js written in rust. TRACE=pacquet_tarball just cli add fastify ``` +## Testing + +```sh +# Install necessary dependencies +just install + +# Start a mocked registry server (optional) +just registry-mock launch + +# Run test +just test +``` + ## Benchmarking ### Install between multiple revisions diff --git a/crates/cli/tests/_utils.rs b/crates/cli/tests/_utils.rs index 95399dba..ea7c9330 100644 --- a/crates/cli/tests/_utils.rs +++ b/crates/cli/tests/_utils.rs @@ -1,33 +1,8 @@ -use assert_cmd::prelude::*; -use command_extra::CommandExtra; use pacquet_store_dir::{PackageFileInfo, PackageFilesIndex}; -use pacquet_testing_utils::bin::CommandTempCwd; use pipe_trait::Pipe; -use std::{ - collections::BTreeMap, - ffi::OsStr, - fs::File, - path::{Path, PathBuf}, -}; -use tempfile::TempDir; +use std::{collections::BTreeMap, fs::File, path::Path}; use walkdir::{DirEntry, WalkDir}; -pub fn exec_pacquet_in_temp_cwd(create_npmrc: bool, args: Args) -> (TempDir, PathBuf) -where - Args: IntoIterator, - Args::Item: AsRef, -{ - let env = CommandTempCwd::init(); - let (command, root, workspace) = if create_npmrc { - let env = env.add_default_npmrc(); - (env.pacquet, env.root, env.workspace) - } else { - (env.pacquet, env.root, env.workspace) - }; - command.with_args(args).assert().success(); - (root, workspace) -} - pub fn index_file_contents( store_dir: &Path, ) -> BTreeMap> { diff --git a/crates/cli/tests/add.rs b/crates/cli/tests/add.rs index 64948809..5c782a0c 100644 --- a/crates/cli/tests/add.rs +++ b/crates/cli/tests/add.rs @@ -1,14 +1,29 @@ -pub mod _utils; -pub use _utils::*; - +use assert_cmd::prelude::*; +use command_extra::CommandExtra; use pacquet_package_manifest::{DependencyGroup, PackageManifest}; -use pacquet_testing_utils::fs::{get_all_folders, get_filenames_in_folder}; +use pacquet_testing_utils::{ + bin::{AddMockedRegistry, CommandTempCwd}, + fs::{get_all_folders, get_filenames_in_folder}, +}; use pretty_assertions::assert_eq; -use std::{env, fs}; +use std::{env, ffi::OsStr, fs, path::PathBuf}; +use tempfile::TempDir; + +fn exec_pacquet_in_temp_cwd(args: Args) -> (TempDir, PathBuf, AddMockedRegistry) +where + Args: IntoIterator, + Args::Item: AsRef, +{ + let CommandTempCwd { pacquet, root, workspace, npmrc_info, .. } = + CommandTempCwd::init().add_mocked_registry(); + pacquet.with_args(args).assert().success(); + (root, workspace, npmrc_info) +} #[test] fn should_install_all_dependencies() { - let (root, workspace) = exec_pacquet_in_temp_cwd(true, ["add", "is-even"]); + let (root, workspace, anchor) = + exec_pacquet_in_temp_cwd(["add", "@pnpm.e2e/hello-world-js-bin-parent"]); eprintln!("Directory list"); insta::assert_debug_snapshot!(get_all_folders(&workspace)); @@ -23,25 +38,29 @@ fn should_install_all_dependencies() { eprintln!("Ensure virtual store dir ({virtual_store_dir:?}) exists"); assert!(virtual_store_dir.exists()); - eprintln!("Ensure that is-buffer does not have any dependencies"); - let is_buffer_path = virtual_store_dir.join("is-buffer@1.1.6/node_modules"); - assert_eq!(get_filenames_in_folder(&is_buffer_path), vec!["is-buffer"]); - - eprintln!("Ensure that is-even have correct dependencies"); - let is_even_path = virtual_store_dir.join("is-even@1.0.0/node_modules"); - assert_eq!(get_filenames_in_folder(&is_even_path), vec!["is-even", "is-odd"]); + eprintln!("Ensure that @pnpm.e2e/hello-world-js-bin has no other dependencies than itself"); + let path = virtual_store_dir.join("@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules"); + assert_eq!(get_filenames_in_folder(&path), ["@pnpm.e2e"]); + assert_eq!(get_filenames_in_folder(&path.join("@pnpm.e2e")), ["hello-world-js-bin"]); - eprintln!("Ensure that is-number does not have any dependencies"); - let is_number_path = virtual_store_dir.join("is-number@3.0.0/node_modules"); - assert_eq!(get_filenames_in_folder(&is_number_path), vec!["is-number", "kind-of"]); + eprintln!("Ensure that @pnpm.e2e/hello-world-js-bin-parent has correct dependencies"); + let path = virtual_store_dir.join("@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules"); + assert_eq!(get_filenames_in_folder(&path), ["@pnpm.e2e"]); + assert_eq!( + get_filenames_in_folder(&path.join("@pnpm.e2e")), + ["hello-world-js-bin", "hello-world-js-bin-parent"], + ); - drop(root); // cleanup + drop((root, anchor)); // cleanup } #[test] #[cfg(unix)] pub fn should_symlink_correctly() { - let (root, workspace) = exec_pacquet_in_temp_cwd(true, ["add", "is-odd"]); + use pipe_trait::Pipe; + + let (root, workspace, anchor) = + exec_pacquet_in_temp_cwd(["add", "@pnpm.e2e/hello-world-js-bin-parent"]); eprintln!("Directory list"); insta::assert_debug_snapshot!(get_all_folders(&workspace)); @@ -58,38 +77,60 @@ pub fn should_symlink_correctly() { eprintln!("Make sure the symlinks are correct"); assert_eq!( - fs::read_link(virtual_store_dir.join("is-odd@3.0.1/node_modules/is-number")).unwrap(), - fs::canonicalize(virtual_store_dir.join("is-number@6.0.0/node_modules/is-number")).unwrap(), + virtual_store_dir + .join("@pnpm.e2e+hello-world-js-bin-parent@1.0.0") + .join("node_modules") + .join("@pnpm.e2e") + .join("hello-world-js-bin") + .pipe(fs::read_link) + .expect("read link"), + virtual_store_dir + .join("@pnpm.e2e+hello-world-js-bin@1.0.0") + .join("node_modules") + .join("@pnpm.e2e") + .join("hello-world-js-bin") + .pipe(fs::canonicalize) + .expect("canonicalize link target"), ); - drop(root); // cleanup + drop((root, anchor)); // cleanup } #[test] fn should_add_to_package_json() { - let (root, dir) = exec_pacquet_in_temp_cwd(true, ["add", "is-odd"]); + let (root, dir, anchor) = exec_pacquet_in_temp_cwd(["add", "@pnpm.e2e/hello-world-js-bin"]); let file = PackageManifest::from_path(dir.join("package.json")).unwrap(); - eprintln!("Ensure is-odd is added to package.json#dependencies"); - assert!(file.dependencies([DependencyGroup::Prod]).any(|(k, _)| k == "is-odd")); - drop(root); // cleanup + eprintln!("Ensure @pnpm.e2e/hello-world-js-bin is added to package.json#dependencies"); + assert!(file + .dependencies([DependencyGroup::Prod]) + .any(|(k, _)| k == "@pnpm.e2e/hello-world-js-bin")); + drop((root, anchor)); // cleanup } #[test] fn should_add_dev_dependency() { - let (root, dir) = exec_pacquet_in_temp_cwd(true, ["add", "is-odd", "--save-dev"]); + let (root, dir, anchor) = + exec_pacquet_in_temp_cwd(["add", "@pnpm.e2e/hello-world-js-bin", "--save-dev"]); let file = PackageManifest::from_path(dir.join("package.json")).unwrap(); - eprintln!("Ensure is-odd is added to package.json#devDependencies"); - assert!(file.dependencies([DependencyGroup::Dev]).any(|(k, _)| k == "is-odd")); - drop(root); // cleanup + eprintln!("Ensure @pnpm.e2e/hello-world-js-bin is added to package.json#devDependencies"); + assert!(file + .dependencies([DependencyGroup::Dev]) + .any(|(k, _)| k == "@pnpm.e2e/hello-world-js-bin")); + drop((root, anchor)); // cleanup } #[test] fn should_add_peer_dependency() { - let (root, dir) = exec_pacquet_in_temp_cwd(true, ["add", "is-odd", "--save-peer"]); + let (root, dir, anchor) = + exec_pacquet_in_temp_cwd(["add", "@pnpm.e2e/hello-world-js-bin", "--save-peer"]); let file = PackageManifest::from_path(dir.join("package.json")).unwrap(); - eprintln!("Ensure is-odd is added to package.json#devDependencies"); - assert!(file.dependencies([DependencyGroup::Dev]).any(|(k, _)| k == "is-odd")); - eprintln!("Ensure is-odd is added to package.json#peerDependencies"); - assert!(file.dependencies([DependencyGroup::Peer]).any(|(k, _)| k == "is-odd")); - drop(root); // cleanup + eprintln!("Ensure @pnpm.e2e/hello-world-js-bin is added to package.json#devDependencies"); + assert!(file + .dependencies([DependencyGroup::Dev]) + .any(|(k, _)| k == "@pnpm.e2e/hello-world-js-bin")); + eprintln!("Ensure @pnpm.e2e/hello-world-js-bin is added to package.json#peerDependencies"); + assert!(file + .dependencies([DependencyGroup::Peer]) + .any(|(k, _)| k == "@pnpm.e2e/hello-world-js-bin")); + drop((root, anchor)); // cleanup } diff --git a/crates/cli/tests/init.rs b/crates/cli/tests/init.rs index 996a55fe..8b459573 100644 --- a/crates/cli/tests/init.rs +++ b/crates/cli/tests/init.rs @@ -1,14 +1,16 @@ pub mod _utils; pub use _utils::*; +use assert_cmd::prelude::*; use command_extra::CommandExtra; use pacquet_testing_utils::{bin::CommandTempCwd, fs::get_filenames_in_folder}; use pretty_assertions::assert_eq; -use std::{env, fs}; +use std::fs; #[test] fn should_create_package_json() { - let (root, workspace) = exec_pacquet_in_temp_cwd(false, ["init"]); + let CommandTempCwd { pacquet, root, workspace, .. } = CommandTempCwd::init(); + pacquet.with_arg("init").assert().success(); let manifest_path = workspace.join("package.json"); dbg!(&manifest_path); diff --git a/crates/cli/tests/install.rs b/crates/cli/tests/install.rs index 8b187249..4a29651a 100644 --- a/crates/cli/tests/install.rs +++ b/crates/cli/tests/install.rs @@ -4,7 +4,7 @@ pub use _utils::*; use assert_cmd::prelude::*; use command_extra::CommandExtra; use pacquet_testing_utils::{ - bin::{AddDefaultNpmrcInfo, CommandTempCwd}, + bin::{AddMockedRegistry, CommandTempCwd}, fs::{get_all_files, get_all_folders, is_symlink_or_junction}, }; use pipe_trait::Pipe; @@ -13,17 +13,14 @@ use std::fs; #[test] fn should_install_dependencies() { let CommandTempCwd { pacquet, root, workspace, npmrc_info, .. } = - CommandTempCwd::init().add_default_npmrc(); - let AddDefaultNpmrcInfo { store_dir, .. } = npmrc_info; + CommandTempCwd::init().add_mocked_registry(); + let AddMockedRegistry { store_dir, mock_instance, .. } = npmrc_info; eprintln!("Creating package.json..."); let manifest_path = workspace.join("package.json"); let package_json_content = serde_json::json!({ "dependencies": { - "is-odd": "3.0.1", - }, - "devDependencies": { - "fast-decode-uri-component": "1.0.1", + "@pnpm.e2e/hello-world-js-bin-parent": "1.0.0", }, }); fs::write(&manifest_path, package_json_content.to_string()).expect("write to package.json"); @@ -32,38 +29,35 @@ fn should_install_dependencies() { pacquet.with_arg("install").assert().success(); eprintln!("Make sure the package is installed"); - assert!(is_symlink_or_junction(&workspace.join("node_modules/is-odd")).unwrap()); - assert!(workspace.join("node_modules/.pnpm/is-odd@3.0.1").exists()); + let symlink_path = workspace.join("node_modules/@pnpm.e2e/hello-world-js-bin-parent"); + assert!(is_symlink_or_junction(&symlink_path).unwrap()); + let virtual_path = + workspace.join("node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0"); + assert!(virtual_path.exists()); eprintln!("Make sure it installs direct dependencies"); - assert!(!workspace.join("node_modules/is-number").exists()); - assert!(workspace.join("node_modules/.pnpm/is-number@6.0.0").exists()); - - eprintln!("Make sure we install dev-dependencies as well"); - assert!( - is_symlink_or_junction(&workspace.join("node_modules/fast-decode-uri-component")).unwrap() - ); - assert!(workspace.join("node_modules/.pnpm/fast-decode-uri-component@1.0.1").is_dir()); + assert!(!workspace.join("node_modules/@pnpm.e2e/hello-world-js-bin").exists()); + assert!(workspace.join("node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0").exists()); eprintln!("Snapshot"); let workspace_folders = get_all_folders(&workspace); let store_files = get_all_files(&store_dir); insta::assert_debug_snapshot!((workspace_folders, store_files)); - drop(root); // cleanup + drop((root, mock_instance)); // cleanup } #[test] fn should_install_exec_files() { let CommandTempCwd { pacquet, root, workspace, npmrc_info, .. } = - CommandTempCwd::init().add_default_npmrc(); - let AddDefaultNpmrcInfo { store_dir, .. } = npmrc_info; + CommandTempCwd::init().add_mocked_registry(); + let AddMockedRegistry { store_dir, mock_instance, .. } = npmrc_info; eprintln!("Creating package.json..."); let manifest_path = workspace.join("package.json"); let package_json_content = serde_json::json!({ "dependencies": { - "pretty-exec": "0.3.10", + "@pnpm.e2e/hello-world-js-bin-parent": "1.0.0", }, }); fs::write(&manifest_path, package_json_content.to_string()).expect("write to package.json"); @@ -110,23 +104,20 @@ fn should_install_exec_files() { eprintln!("Snapshot"); insta::assert_debug_snapshot!(store_files); - drop(root); // cleanup + drop((root, mock_instance)); // cleanup } #[test] fn should_install_index_files() { let CommandTempCwd { pacquet, root, workspace, npmrc_info, .. } = - CommandTempCwd::init().add_default_npmrc(); - let AddDefaultNpmrcInfo { store_dir, .. } = npmrc_info; + CommandTempCwd::init().add_mocked_registry(); + let AddMockedRegistry { store_dir, mock_instance, .. } = npmrc_info; eprintln!("Creating package.json..."); let manifest_path = workspace.join("package.json"); let package_json_content = serde_json::json!({ "dependencies": { - "is-odd": "3.0.1", - }, - "devDependencies": { - "fast-decode-uri-component": "1.0.1", + "@pnpm.e2e/hello-world-js-bin-parent": "1.0.0", }, }); fs::write(&manifest_path, package_json_content.to_string()).expect("write to package.json"); @@ -138,5 +129,5 @@ fn should_install_index_files() { let index_file_contents = index_file_contents(&store_dir); insta::assert_yaml_snapshot!(index_file_contents); - drop(root); // cleanup + drop((root, mock_instance)); // cleanup } diff --git a/crates/cli/tests/pnpm_compatibility.rs b/crates/cli/tests/pnpm_compatibility.rs index 3758a6f9..bc215bb9 100644 --- a/crates/cli/tests/pnpm_compatibility.rs +++ b/crates/cli/tests/pnpm_compatibility.rs @@ -5,7 +5,7 @@ pub use _utils::*; use assert_cmd::prelude::*; use command_extra::CommandExtra; use pacquet_testing_utils::{ - bin::{AddDefaultNpmrcInfo, CommandTempCwd}, + bin::{AddMockedRegistry, CommandTempCwd}, fs::get_all_files, }; use pipe_trait::Pipe; @@ -15,17 +15,15 @@ use std::fs; #[test] #[ignore = "requires metadata cache feature which pacquet doesn't yet have"] fn store_usable_by_pnpm_offline() { - let CommandTempCwd { pacquet, pnpm, root, workspace, .. } = - CommandTempCwd::init().add_default_npmrc(); + let CommandTempCwd { pacquet, pnpm, root, workspace, npmrc_info, .. } = + CommandTempCwd::init().add_mocked_registry(); + let AddMockedRegistry { mock_instance, .. } = npmrc_info; eprintln!("Creating package.json..."); let manifest_path = workspace.join("package.json"); let package_json_content = serde_json::json!({ "dependencies": { - "is-odd": "3.0.1", - }, - "devDependencies": { - "pretty-exec": "0.3.10", + "@pnpm.e2e/hello-world-js-bin-parent": "1.0.0", }, }); fs::write(manifest_path, package_json_content.to_string()).expect("write to package.json"); @@ -37,14 +35,14 @@ fn store_usable_by_pnpm_offline() { eprintln!("pnpm install --offline --ignore-scripts"); pnpm.with_args(["install", "--offline", "--ignore-scripts"]).assert().success(); - drop(root); // cleanup + drop((root, mock_instance)); // cleanup } #[test] fn same_file_structure() { let CommandTempCwd { pacquet, pnpm, root, workspace, npmrc_info } = - CommandTempCwd::init().add_default_npmrc(); - let AddDefaultNpmrcInfo { store_dir, .. } = npmrc_info; + CommandTempCwd::init().add_mocked_registry(); + let AddMockedRegistry { store_dir, mock_instance, .. } = npmrc_info; let modules_dir = workspace.join("node_modules"); let cleanup = || { @@ -57,10 +55,7 @@ fn same_file_structure() { let manifest_path = workspace.join("package.json"); let package_json_content = serde_json::json!({ "dependencies": { - "is-odd": "3.0.1", - }, - "devDependencies": { - "pretty-exec": "0.3.10", + "@pnpm.e2e/hello-world-js-bin-parent": "1.0.0", }, }); fs::write(manifest_path, package_json_content.to_string()).expect("write to package.json"); @@ -80,14 +75,14 @@ fn same_file_structure() { eprintln!("Produce the same store dir structure"); assert_eq!(&pacquet_store_files, &pnpm_store_files); - drop(root); // cleanup + drop((root, mock_instance)); // cleanup } #[test] fn same_index_file_contents() { let CommandTempCwd { pacquet, pnpm, root, workspace, npmrc_info } = - CommandTempCwd::init().add_default_npmrc(); - let AddDefaultNpmrcInfo { store_dir, .. } = npmrc_info; + CommandTempCwd::init().add_mocked_registry(); + let AddMockedRegistry { store_dir, mock_instance, .. } = npmrc_info; let modules_dir = workspace.join("node_modules"); let cleanup = || { @@ -100,10 +95,7 @@ fn same_index_file_contents() { let manifest_path = workspace.join("package.json"); let package_json_content = serde_json::json!({ "dependencies": { - "is-odd": "3.0.1", - }, - "devDependencies": { - "fast-decode-uri-component": "1.0.1", + "@pnpm.e2e/hello-world-js-bin-parent": "1.0.0", }, }); fs::write(manifest_path, package_json_content.to_string()).expect("write to package.json"); @@ -129,5 +121,5 @@ fn same_index_file_contents() { eprintln!("Produce the same store dir structure"); assert_eq!(&pacquet_index_file_contents, &pnpm_index_file_contents); - drop(root); // cleanup + drop((root, mock_instance)); // cleanup } diff --git a/crates/cli/tests/snapshots/add__should_install_all_dependencies.snap b/crates/cli/tests/snapshots/add__should_install_all_dependencies.snap index 93fc2c04..655fd1d0 100644 --- a/crates/cli/tests/snapshots/add__should_install_all_dependencies.snap +++ b/crates/cli/tests/snapshots/add__should_install_all_dependencies.snap @@ -1,30 +1,20 @@ --- source: crates/cli/tests/add.rs -assertion_line: 14 +assertion_line: 29 expression: get_all_folders(&workspace) --- [ "node_modules", "node_modules/.pnpm", - "node_modules/.pnpm/is-buffer@1.1.6", - "node_modules/.pnpm/is-buffer@1.1.6/node_modules", - "node_modules/.pnpm/is-buffer@1.1.6/node_modules/is-buffer", - "node_modules/.pnpm/is-buffer@1.1.6/node_modules/is-buffer/test", - "node_modules/.pnpm/is-even@1.0.0", - "node_modules/.pnpm/is-even@1.0.0/node_modules", - "node_modules/.pnpm/is-even@1.0.0/node_modules/is-even", - "node_modules/.pnpm/is-even@1.0.0/node_modules/is-odd", - "node_modules/.pnpm/is-number@3.0.0", - "node_modules/.pnpm/is-number@3.0.0/node_modules", - "node_modules/.pnpm/is-number@3.0.0/node_modules/is-number", - "node_modules/.pnpm/is-number@3.0.0/node_modules/kind-of", - "node_modules/.pnpm/is-odd@0.1.2", - "node_modules/.pnpm/is-odd@0.1.2/node_modules", - "node_modules/.pnpm/is-odd@0.1.2/node_modules/is-number", - "node_modules/.pnpm/is-odd@0.1.2/node_modules/is-odd", - "node_modules/.pnpm/kind-of@3.2.2", - "node_modules/.pnpm/kind-of@3.2.2/node_modules", - "node_modules/.pnpm/kind-of@3.2.2/node_modules/is-buffer", - "node_modules/.pnpm/kind-of@3.2.2/node_modules/kind-of", - "node_modules/is-even", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin-parent", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules/@pnpm.e2e", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin", + "node_modules/@pnpm.e2e", + "node_modules/@pnpm.e2e/hello-world-js-bin-parent", ] diff --git a/crates/cli/tests/snapshots/add__should_symlink_correctly.snap b/crates/cli/tests/snapshots/add__should_symlink_correctly.snap index fde59937..d5e30abb 100644 --- a/crates/cli/tests/snapshots/add__should_symlink_correctly.snap +++ b/crates/cli/tests/snapshots/add__should_symlink_correctly.snap @@ -1,17 +1,20 @@ --- source: crates/cli/tests/add.rs -assertion_line: 47 +assertion_line: 61 expression: get_all_folders(&workspace) --- [ "node_modules", "node_modules/.pnpm", - "node_modules/.pnpm/is-number@6.0.0", - "node_modules/.pnpm/is-number@6.0.0/node_modules", - "node_modules/.pnpm/is-number@6.0.0/node_modules/is-number", - "node_modules/.pnpm/is-odd@3.0.1", - "node_modules/.pnpm/is-odd@3.0.1/node_modules", - "node_modules/.pnpm/is-odd@3.0.1/node_modules/is-number", - "node_modules/.pnpm/is-odd@3.0.1/node_modules/is-odd", - "node_modules/is-odd", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin-parent", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules/@pnpm.e2e", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin", + "node_modules/@pnpm.e2e", + "node_modules/@pnpm.e2e/hello-world-js-bin-parent", ] diff --git a/crates/cli/tests/snapshots/install__should_install_dependencies.snap b/crates/cli/tests/snapshots/install__should_install_dependencies.snap index e9080255..504201bf 100644 --- a/crates/cli/tests/snapshots/install__should_install_dependencies.snap +++ b/crates/cli/tests/snapshots/install__should_install_dependencies.snap @@ -1,40 +1,30 @@ --- source: crates/cli/tests/install.rs -assertion_line: 51 +assertion_line: 45 expression: "(workspace_folders, store_files)" --- ( [ "node_modules", "node_modules/.pnpm", - "node_modules/.pnpm/fast-decode-uri-component@1.0.1", - "node_modules/.pnpm/fast-decode-uri-component@1.0.1/node_modules", - "node_modules/.pnpm/fast-decode-uri-component@1.0.1/node_modules/fast-decode-uri-component", - "node_modules/.pnpm/is-number@6.0.0", - "node_modules/.pnpm/is-number@6.0.0/node_modules", - "node_modules/.pnpm/is-number@6.0.0/node_modules/is-number", - "node_modules/.pnpm/is-odd@3.0.1", - "node_modules/.pnpm/is-odd@3.0.1/node_modules", - "node_modules/.pnpm/is-odd@3.0.1/node_modules/is-number", - "node_modules/.pnpm/is-odd@3.0.1/node_modules/is-odd", - "node_modules/fast-decode-uri-component", - "node_modules/is-odd", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin-parent@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin-parent", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules/@pnpm.e2e", + "node_modules/.pnpm/@pnpm.e2e+hello-world-js-bin@1.0.0/node_modules/@pnpm.e2e/hello-world-js-bin", + "node_modules/@pnpm.e2e", + "node_modules/@pnpm.e2e/hello-world-js-bin-parent", ], [ - "v3/files/01/d306b80f4b1678c655f3b0685db1f7a741fc746d251c00e925298ab89630a3167bde8c7d8d779b72770c41f9f302bb1e3f312672ce7aa8e6c156c319eeeada", - "v3/files/17/54b7271ca0e30dc7d775986711a2b61b298200c12f867bde6f7e19d56047c9ab77a93304520fa1a31b0c3a4e6fb6b310f89dd8cb4d95a5c662807ef733f85f", - "v3/files/1a/5c01a1321e71a1c263fb83878cbba2686f71f571b42c2d40d93858bf1f4c6ff7f625125a68932c243e75ead4a9d2f18d9b22b3fe55c39fe6605a42b2e70620", - "v3/files/37/8eb16c230fce354ef7e72722ee708cbefea9a481aa597b06fefc12f665ab60176cbf04d6bc159be42ccdbc51764d71516f86bb28a01b0e60c76a2753f1cf44", - "v3/files/40/fe18b2c1f241075b732727110323f3e29f9d6c8765ff0222bccfa34784caa8abcd18ffbd4bbfab979e5478ace273a74ed3a0a22f0261334fa7c59e032edbde", - "v3/files/54/7bcd683e2f9f7b0c2790c637b9231539947be923479534592d91886a56d6262fdc1d8ced24ac2cc3adfda139fe399dc7502d382c7afc536e3057a7cf11e6c0", - "v3/files/55/dcbc7fff1ac1c4755f4cbf24ba21e0dcae062c802d3db937d2b6182f4554dd85d14529a0c9688eac825a345b63ab8b2e5d7699e2be07178df5bb8a072235eb", - "v3/files/58/01e592e94aa4076c179180956f33f8262fa7157a06bfe636a6854bd3b9b2ddf44780ffa1405642ad8ece2ed6514e19a28178cbecdcf5608a3be710bbf3c0d4", - "v3/files/60/ab54849d6cfd7b05076c3bc4d9baffe1f800f4d5e2d67c39c521a7a3d93b347ce5a8e45397102e40e2103652c543c8e7bb161c15d0a6e34ec1a9d11c168d2a", - "v3/files/88/1f101d2f1886fc5f9ac5c8d25e5540908e140031169ea41a4a9941cf95fe2711c1292c1995609c6f174b3815cc0dcc6cd2a10339a348d39fe75bc77b53ba9e", - "v3/files/9f/cbe5dc86bc33bdb4f125559e767c3aaad94c7c4b21b80b694d9b0158ee0f10ee53b127c2bf05db9768afdaf1fb6778fd08a19412fb3c1adad655863e6c351d", - "v3/files/ca/65df16eb450ab63f90f107a8cc9ac82da9635408e813a6f6d3e13cfba78917b31b66652479ebba54b612566600b2ab1bc16b82d082c5f87803961a8e9e3931", - "v3/files/e5/c2514d2b0d3d6bedad24fdd75c55e780211cf0692c21f401201c2d7dfa990ad00188bd68b30c826aaa2a72ecad12a74bc03430384f933b1751035dd1b18ca2", - "v3/files/f7/02180f4465a777127ad6a211306dd564993c17f7d3d9401604df4bc657d8d888902de632a4cf55b551ddfb9f84ba8a900788773f03c77836143ef94e182c7c", - "v3/files/ff/d3f3fed65d7b489216916772c6180b5c1714ddde16e7e2c99ff5f8a4214bb8f884a0c1d06a1b1a8a4b0d6252ad85b533b1626f0dd8d474f2283f6cdfd69f6c", + "v3/files/02/f9d952341eade675d0a8f5da14d4277fded62f937242292c2cf5f1bb0eda101b5f803098d64e2a138f4bfe4cdf326cfaf8f6b4015476ab86d25df03ddec731-exec", + "v3/files/68/b837b4fd7982b081521e51b14a167ccdb272b3c499202449d07d48d78a2fa7bb8652d3a894bb06ac6e3995e5126ee3470f73b5775584940751fce8be468405", + "v3/files/93/e31fcd9144a604f87d04fa8fb4a058202c579df17fd2b21301e17ac0ae4f3e2bae90ced7ae71b71218bd4a789e355ef7b8bd8899cdb785250071b229503b2e", + "v3/files/a5/541962367c9c3aaaa8be96312f7efedf7ae638bd051e80573649ca93b4852f4f2749efdce9f19fa7355b3a6d9130eded64e4b3c0efe753622735c5069482cd-index.json", + "v3/files/bf/0c878f2a4f2ec6f231bb2d414547efb15eb22a673815cba36acfd89633cd4c8affcbdc9378e90ad4d8fc654de921d1f67444be94e6a2f81bda9330be60be93-exec", + "v3/files/dd/feae8107ea156f46477e8e49e4dfb12365ba9ee122c953db785a5f776f4ff7b91b25378889dab77fb4188f8caaf45cc1c373b01ad326aef20d6a77c24ecefd-index.json", ], ) diff --git a/crates/cli/tests/snapshots/install__should_install_exec_files.snap b/crates/cli/tests/snapshots/install__should_install_exec_files.snap index 32193cf4..c52fbfd7 100644 --- a/crates/cli/tests/snapshots/install__should_install_exec_files.snap +++ b/crates/cli/tests/snapshots/install__should_install_exec_files.snap @@ -1,197 +1,13 @@ --- source: crates/cli/tests/install.rs -assertion_line: 111 +assertion_line: 105 expression: store_files --- [ - "v3/files/00/1bd318b4f0e816c9ded28091d256ae7ff7d3b0e9ff3b262376377857e0801e53b59d3ea434c2e032cd746ed135c655b1479cafe5e4473c7fbb224ae36f4ae8", - "v3/files/00/deb738ab63d081d3203475b2e1808204a4c84055a47deec42686a254f056e913b674f93421d29d110f38f44cec68dac711a5cc34b0b2353381b16d9fd8045d", - "v3/files/03/07a3d034d619f4687f8284d16bdb383888d588b568d69b9b072e184e714b078a3cef082b4570f168cce6664b5e56967385d2a80d9db03197d1a87efcb5ac7f", - "v3/files/04/2090ccf97b5cf02090e4e356ee48a07468d0a6c80c7085f1622c6dfde1da4eb9f54f2b97e3d17d9998b990804abeb0741c24b3d984a9102ed186dffdb9f53a", - "v3/files/06/dd9d01a8428becedfb67b9ee3747123a3111423eb66fa16330bd8b9723fcf0a76d46881f21d821fb3bc97d09107948676bb64913d0978e25444195ca874b52-exec", - "v3/files/07/63570393a082d18dbdfc05b88a99cfac9933976e13eaec2c2ff6cf4a05cf97bb9a7f67030339afb935e0f19b47d56ee0420a99d3726f1c65429e8635b537fe", - "v3/files/0b/49b251d76752186967f51c0fdc99c8c5a87505787d3db0c5c7ea6ff4e80f467df2707d59f58197a928355589fbc8f378658feb0423cfdcdd5fb527b9ad3f49", - "v3/files/0d/7059d65c4edb99ee6458b9a1b7de7c767f176341b0492ad213c975a7930d61627457a8bff08ee299d3d83b264ff6d2e39c6227f2bd2d1ab655b7bcdeda2216-exec", - "v3/files/0e/1fdd6e8f2e01d320901acfa388d0c9b30ee57303c7cec769b9f959ea4920f87a63f3392e362757106fd1a513dbf9037698adf291d604188cb44712d7afbafc", - "v3/files/0e/5dc92f9f523fa072574ccebb28df5b71f8d7ee7a3cfef6eddc92a67bf2a5285ec7ad7f9624b1ca89b9ec3a0105f288df826dcbc34d24f632d6721c3157615e", - "v3/files/10/9f64d9f1bc268b7e437e997251a1e3f61ae2ead5de65afbeb9322047115418524dfccbc0ce57de7f3f0b35004358b9f251c2ff60ba7cfafbcc89e57a62a7df", - "v3/files/10/a55f947076d0a3c6971b374e0579968ee67348344f4d057e1f8c22c3eafa82566ea8bf7710368ee3ec1ac69521761ae1ec698dc360303ad0c2b6284a0980c9", - "v3/files/10/c1a5869f7cba07590443f48fa421bd8b0a8f8b428f36865a3af68d1c87c745b98ab55e30379e15971f8e584a4efb84a05505a9b133ab5630d5ec745e3cedea", - "v3/files/10/fb8645d46738c3b242ae4689cb2c763515cf1ac3b8dcfced8be40ff94d60bfbd5737acd22596a1f971a3e30e2a5baf25c5123c65623edd190639e73c60a8a1", - "v3/files/11/1cf6caccbb64938b861705c769a92443357899afaefa92b82521bbf0cee7178df0110eed5891e1284f39b059c19321ff95cf8342623d16a5b1f9857c1b1e18", - "v3/files/12/06b1fa1dcb049bc96a0e252b4abc21c58975932a0e149c686964d4fcbc11702536d34de2fa6ab89c2384a620ac921b0d556185c7e856985c4ab606d9200dd4", - "v3/files/13/90ab3de4cd21a6407edc2a309a644fc3c335a994254aee6c72d367a4639f797d46f24a48bc3a3065d3e9201c44757796d2ce49339ad47be443bfc650ea1a1f", - "v3/files/14/1f74f51ee662fc5a263e0cb193c47c8eb66201a27dd1a146d253efb413684c7107e3910a02167de8c649693929fe1781f79a6783d6115e2ca17b7adef9c594", - "v3/files/16/053da13599a77fd7657897242f1e8a117dbfeb05126b21ae2bb2592da1b14fd2303991ba6759d6730651773b775c9e2c501e7b0e6f3ab9e25821192279ccf8", - "v3/files/16/12f5046e12d3e734174f9a81280e742bec42f06f948faf57c4c762ab9233e3c90b18be80fbced6c34e7d041066c70caed452c50ddb36b2ab1f3fb5af25d52f-exec", - "v3/files/17/260f7abd7803c7a179e485397421ec4f935ab216d8020610c923fbac0b4453ed4064df70d59c85ab09793b954c062a66b40faa975d95fa4aacc1f4f07ada81", - "v3/files/17/4b5d7ec4108f929bfe28012503ef50a56e823a3dd8133d58b9f5fa18870d0f8b890edb9ab4d654e27cf6cf659a09ff4b005ee1edf5bfe1afbc89f27bc4e2c0", - "v3/files/1c/90670b152f9adf41c4bbf08a94e0f5258296a6bc2689c7db5c77ac31731d441d14cce0de164584937a1ff25dcc158f4148efe5db5a2fea9cbabb47a90db227", - "v3/files/1c/90670b152f9adf41c4bbf08a94e0f5258296a6bc2689c7db5c77ac31731d441d14cce0de164584937a1ff25dcc158f4148efe5db5a2fea9cbabb47a90db227-exec", - "v3/files/1d/0688424f69c0e7322aeb720e4e28d9af3b5a7a2dc18b8b198156e377a61a6e05bc824528fca0f8e61ac39b137a028029ff82e5229ad400a3cc22e2bdb687ad", - "v3/files/1d/0688424f69c0e7322aeb720e4e28d9af3b5a7a2dc18b8b198156e377a61a6e05bc824528fca0f8e61ac39b137a028029ff82e5229ad400a3cc22e2bdb687ad-exec", - "v3/files/1d/7fd1d7ae2c1795a101f3fe95deb928c9d90019ff959c3f193895f0ac305f909fb93cf9d241d64ff7953a548b73cec21f1927ee6bba20d1915b9e21f0190ae3", - "v3/files/1d/c5fb24099f33d6874f65c424d9f53ee70c0dc3166b2493cbceb51372efe393a42fe2d083bc784e541a35b2e6472e31919425724d803185837d653a17e2095e", - "v3/files/27/b172c27f5f7b71e57a2b3aeda876e6b05f650f0b847b7916558e641eb93f8801664e936a62b13fbbd1fa91454fb2fc5b21dbcff7c25c92a9980b02eacc892d", - "v3/files/28/cf9314df893197ac3d1d263e761046cd8cea6ca77b9c761149792f6a9636a165c2fe132e676de5b9edc574482bf60c3354cd32419b22e3a91ffc9c626fd887", - "v3/files/2c/da59f0a6854323c1dc93f51ee88611c70d92fc28d3c8a32816d74d485dcd5ce828e5d020ec0a317a838b67da6a4459ceed4837cd73b6b85f7199c6d6545d1b", - "v3/files/2f/6d3fc9c5874a35976415e7d60bde746579a35d36a57fe379d562fcc84ebde3caa76174b57777317c445bdfaefe2ab44d0b60aad9da53252f900dce334edf39-exec", - "v3/files/31/46b9dfb4bec15e2dd76608b98911757a7ce619438d16a5ad6ca17a60dd79c8cdfe43adf2456b6413ed772097c9e6e0e726174758564459fb1153ee8563ab15", - "v3/files/34/ddb9208914ac53ed7c0e7162f74d0313a8f348f34db824414028313c03de674995ac98bbf856f5219d44d1af1455fa41678eb14dbc4639567b9227ef11ca31", - "v3/files/35/4bc6788ba428a39568ed879ffceb19bffc254068e3eeef3901bbc18ef78ae597c7c4963c0dfeec660629b7fa10a49d3a0e56a208741dd716d8827e0404c0ab", - "v3/files/35/7909a22fc6ae96328f87dda34b6d774e020b3fd1f5ecc513600dfb04c94c8b82e3558bd7907ef5c914a14d9857f7a04b92243c5e168f3cf1a3d47f1b9d956d", - "v3/files/35/eaad53a9a1909bd29444761da2fbb3e33ff865e784f1a48d4997f2e8d442eb613269d101fd494cd31b83abc2c1d2a8b13776be0027eaf330f86076e9f5e1a1-exec", - "v3/files/36/628b538527c1694a32d221d14ef43df9e4b129e6fa5740b5dda9ccb6fe8550ccb54a30a49565d665c6d93a23753ceab476eb488ed1b89f7c76a3b5b823c84c", - "v3/files/37/3874f9423a505c6f5a0255bfda9d7adc8917a5f40655e66ec4e70c8093e986dee47f1fbc2db07c08d420029723b1cf36a631042844c172dcc85914369744e4-exec", - "v3/files/37/ace9824bdf57e0a823e159e28c50498ba1751eabb2d6721d79c65891c11637fb4a6e5640de3fa717dcbe052c062888957b91b4ccb50a87f638aff0c0f7a3d2-exec", - "v3/files/3a/b5d1d90855d80fa4aca46de6de6926adbcd4c5cdfc8f893410fc9f4c4ad5792623e4e3da51f9f37f5ef5d99d41298c7bc5f6b8f13acc03ef472ab5018c1df4", - "v3/files/3d/4b41fed5868cef500302273fcdcf094294b3fe3c0f6337006d6a679ae82c717f8cd7b4beff4175f6b758295bbbf8d500aca8a185c728d91849cf3687420ec4-exec", - "v3/files/3e/cd249df6b3ae458d0a95123703e1637f56bddcaff48c3540425464cd174ff6a74342cf26a97b753d74f1381b8fc02eee457bcbe46c7d1f5e2f5638b2160579", - "v3/files/40/1949f50c5f620d8a88e5a85cd0ed52858bae660a0bd92eb2f03618ff90af19f1b527fb9bd8a003cfddf6f035a8e01fd2a9ca3fdbc34dc7c2582fd1a85a8aa4", - "v3/files/40/2757b9075dc4fe7a4467692d7110cf52efce013762a3cbcaa5e9f53f7982a47e0c6219e96ae2b2b9f56de82ec0317571c69f08d24f115c0f5f41a2338a4556-exec", - "v3/files/40/4846e68fa46356f1bace923489e6f10556da4f0d668447fafb6139b8ca4654754c915993f3fd947289a02be4f358620911f936e40573c6ecfa97ee33b9cc59", - "v3/files/42/b9aaa6efb15bd57f355f71b600b3f3fcb5bf831c8244eabccae7cac6bf23f538137e480196ac0bbc1962fc316b74ffa7f45fcc2d35cf426892c5a4c2595311-exec", - "v3/files/43/9a9061360cc18785d355bb18f07e186c55d114358b0d13b92ad479e826b0664021dfa1328613dfe9743ca528c79812e40d4f8594b26c09a04e7dc37d557d14", - "v3/files/44/9fbdf7888a5b9088b5f84aa6d1a42cf951782a062079f63fe5e1e797e709ed4737c3e19300d0a98a01013431e73652c5b81438913ba952ff1fb63bce460e5b", - "v3/files/49/7414c7053618e078df0c9047828041dfb0e656951a8fc3177cf12bac50232405c5eb37d897a105a861bc8ff896b4d1a2c699fd7ad91c6df22f71a33bc44578", - "v3/files/4a/74a235678af320bef5ca5746d31f31fb9c5c01ac3da499018c2f4216834a53096e104300911b22b80e16c2bb25d673cade6d73c4e8807ef17f12e7569d3e26", - "v3/files/4b/c429f636ec1587b9fdbf718f643fb56084dbd8354a028869586044d7ee9f9cc88cd3e076d8548dc33002ed902dbab8f4e9ddc375773ad8fd36b704c7cbc127-exec", - "v3/files/4b/d139044276d889c1130e6bfd0baaf3553ed57d18e6b00b129da4917e8037775ca118d5c7503863415c2802dace580aa2a8e4539bbeb796fbea889d85805bb6-exec", - "v3/files/4d/912cb78467a9b25e5fd1be0ea9371f6a5250a8ed5cecb42781f981ba1ee13763d229de2d2c33fb4361854a318f236f2fca0553bb5871ce6ba8cc6d670ae4ee", - "v3/files/4d/99655ebd3ac09430ab6beb431d4f95f71bac48c87f67d10cfe2614f77b20655a47eecb973da1355e15104344dc4688a6c7df128514005d9bd5462c8edc62c3", - "v3/files/4d/d0650cd0c02e62242867e80abb87a618f8d48fd25c16e969bb45a8157d6910ae9d798b95ecc715e1db88ee21e39eb857fd302ff075f583faf8e8b69b55c54f", - "v3/files/4e/e1c88f8c3f4e4cd34cb6c00339bf9d6d036ff4ade3af49e871cc8966b84c729d8b75492acc6413c9a664ac00a57958223ac13c4229da8c62ebe6a53e4f783f", - "v3/files/52/7e009073351c135b4b3d04d776d01dddd136f87c43804b6fff499ff7d63f0d698fcd3ee05fe337480c20e496776765cc8ae64f5c0449eb51d0c8e8a40a2e91", - "v3/files/53/a6c263fb42e0c2152aa4dba9117b14cc64b4bdc5b74f81895e0b50f141473abae3a491a198d3945a4c3edeeb3f957f26656e04132992b452e2574d47080f5c", - "v3/files/55/1f0f90d2a325182538c29ab593604aba75c93d20c5c29d6bb954f015bbd3b504472f2fa40a4ef78567ecec06d2b80db58fe99b50fdacc8b223ef2429ab4f82", - "v3/files/56/1c720a44e1f312ce669f6e442c71fe2c653b47b374811951820743098d98a179e34b29da9803bae82ed330477605f406a9050cbfe48760a97969e9d819a9ad-exec", - "v3/files/56/2af5ef79c1ebd3a4682b82a82019217500e17a65f00ac491755d1db3bd1b8beade4668756801ea753227e124b9f92352f6d56ef0ece29eda18ee61a4fc6fc3-exec", - "v3/files/56/d15758cfdca3ac1f606b6c65a83880e8c7781737a95c613f66cd1c1d258220f9accc963e781f2c52811e606d2709231f265f891917316a168e4eed3d65aebc-exec", - "v3/files/58/903154cb5a895f14ce6e72100d06e5e7dd71c4b720d0765bee818c35f3002c552d52b1b2c53b505ea8d9880592a1e265234b2dec6a0bc0bb1c01f7cef0b6af-exec", - "v3/files/59/b2b098e162b61370f317948f7bc671fb412bfa0c07977634f07755e663ed0c2d683aafae8eba41358d11f65074ea46891b40d852e83ad6bbd2951c7578cfee", - "v3/files/59/cc0bee5bc81251374911b5a241081796d45ea07324f13ec753bab1d5731a5d01b8e6ec023622e4db42db100c96547f75570a82e87293adc19324a4dd8f2be1-exec", - "v3/files/5b/335edf6056f57c261cc03eb1229799e64d2bbf2620f39182ffe7c87db5b39627c71fb7f10a22f0445ab66cc5b6d6f06689209dea5ea4f6265efad993104ac7", - "v3/files/5b/a65521cbda0287e641d44ae987a2736198f568385289347e1d47aba6e12b9979da56e7ca8853876e6125f469ed45dd576fd69dbad58cddbc354906347789a2", - "v3/files/5c/c390a443f845d6bf08545aac1885e0c8bce82f7d983bd313c98f688e31d03b0d97ee66717a013e14d1af0fac3ef3ecf9b0a5f13db328aa45e29776bea3eece-exec", - "v3/files/5f/a11ad79ad227c77d1f57c7ec9f736073f2919b8acfdd23ec743b500bdb335f97c1c1ffe721f0eff116502455f31f99a4344a0d9ca97c5bb5c7e2ebd54108bb", - "v3/files/60/ae951206f3444a5190c888d4e450d5a2ece233bb190551d0afcc40b7a68f11fdd0be68aab6249ea32f2155739f392b0e173c679747989a110c5d6d90edf17e", - "v3/files/61/c4590bd0ec5fa0e11e4a6f080b22b661b18043d38eb0b40b03d16e425ba2eac6a2c884cb687b0169fba3b2c8b155d86525316a783633367d474e3d5f9bd7ea-exec", - "v3/files/62/5122568344763ad0d6d84d788d52a3322adbb4cf6f26e48520c8a92e971d82968b799fe5b700f9cda268978204d5b93028c3c10808c1700ffeb1cdaa16ee09", - "v3/files/62/d42979c24a181b63ebf849efe07bc1d277db4aee36e4b8755f42387329d8cfd93bb190478141ac212bd90e3fda0a3c204213ccaa13fa37028f098cb8463982-exec", - "v3/files/63/159b500cb660028bb869598a6f9a0e7a5482dadb536f27381118b40fe230992fa156db1cabb150223689e5add0347b3fb318072ee77169078d93fc5bced2b3", - "v3/files/64/504f4c713fb006acbe01eedf3b374e7d2066140e85e6cd06d8a9bfb33df921c2424b6ceb06ce82b62403754f61efdb94a38c50ea070a4becbdfce407ebfb88-exec", - "v3/files/68/7a55d92a6fa64a792b3dd04ec2faede8ce4c83363d91d4a5561d469fbb97a8ce18d695f4e6a0f1f82522be82053cc52b3746a6d124bf24c43b8445bcb01165-exec", - "v3/files/68/c87ffa98edeb3d89e8505fe5eaf94977591f66b97a258581ac82332e8742013ba9479426fa713ec660444ebb5b42dd8ae9c992904c028f91a55c0aef64ccc9", - "v3/files/68/fcef5ff77884bb9aed8629affcb16058b7b96606a0c4cea59096ea90182f17ac4edfbefdd9c1b11c5c3de71778f2c43e5de732d83a5333f8a96cf089164367", - "v3/files/69/959d580d921ed0d1294e4a49904df9bd680d072aaafda4c7b656d4cd255e8682ee83b7c14ed658a55b443b5406b1211149c1fe17045626386699cd8aeb68e0", - "v3/files/6a/8011db36b113d52d7173b8904f456cf06021911593bbb767e9c43e60e8eabc1c62d874ecac6b5597a3544772d9798abe491c6fc3bf5ccf542b76cf73588c3f", - "v3/files/6c/3ce97565f2f9cbaf9d42c05f0154ef002b6836e3fee42b1e2f96ee3c42a8e54009f4a47f40f6fde196ebf3d9a635f880a093112013a75a01389fa3f2f15644", - "v3/files/6e/6f6bd9fc4f1b9be9c1df2a866dbec68cdc04169a42c7da4667fe4cd69b68647bd27572d5dd8fbc139ec9a4606ebdaffd9b23ac439b6c0e9f36d0d021a58cf3", - "v3/files/6f/294a4e02d24497ca0bf6670f9dec40755b5c8466873c0ac8bb6a28f4cb9b9397dfb1b071c49cf20707c32894aa319a8941d9221a3f352d3f25761d7f526951-exec", - "v3/files/71/794c245ed02030a6151b74239b44307a55a8f6f1eb399c7521b3c6d82349c8420d1195be9c78587c32633cfaaf77a3a71d64de3c6305ecf217722a5c35dc9f", - "v3/files/74/fc7841bb52c17b410f7f332c93320097507a273e05e43e00e9ff6095a831a63b0a24e3078a255cebc99f352d41ad424b12f421f657f3c92e7ba5e23421429c", - "v3/files/75/71ea25152542ffc2cc5a6ea5ece32fe0afb7b4658508cee10e3c5f456bf540e14c8a7c2325451ae1dce419feb858985530f52578c79667d75d9d33ae79c442", - "v3/files/76/5f0c1cdb710b9cf2ffe714c82cbd42cea740c8d5340fcb1aff5cae70c156598377f5ebac0925ec34252414e99a53d3fa5066ec90fa438913ef0e6f1a9874bf", - "v3/files/77/39d52696300e9b9b8f7c9663c8a02533c16621790eab060b34429f35d2857fafeda6034665dc675a73838b3b060fb3cc3319de60d58120d945343e3a70b71c-exec", - "v3/files/77/dc603406d1f4afd81568fc4e9f04981249f10212938e3c436e9dcb3b5d640b45b01139560c6d09b84e70eb9d85331c4a912ec8aad2ade3f677470fde2c880c-exec", - "v3/files/78/31cba562e1f7e03a9aba93441b496b79cd26ae5cae788daefdcf02d9de03f843a46774f1a43b55e997d5857abf7d4bfc3ea01ee2c7ae23e41eafbbe829c72f", - "v3/files/78/b1155ca28b8e1143f7d5fd497976349da9baffced3e614c6acb6a68e35841130b4325f004605ab33591d93d2387416a26880439cf16dfa8d84954a1b878fa1", - "v3/files/7a/df42cfe61a270231d0778a13715cad50e769aa632c86e978098deb07ddc665e67ed02ee830b072daab691aad71a825dfbe5e0a23b0e59736f6def8f45db000", - "v3/files/7b/0916d2add24d1616e7b6c611f9076832f190dc5074669a03698520c21baa28f7b2f6514216c64a453aea37c5c5ac89845e55b2ffd51bf9d3c65ec208401b8b-exec", - "v3/files/7c/045a8b58e40d57794462e7041249e9b262d71e7d765f35eadff05a849ae4ac7f3f6ea41eb55ce670195e4326cba42c9e39aa8421269a3c87946d4ec8f2a67e-exec", - "v3/files/7d/d4c7864159636d2e046813f76af1e6f14aa77914c04c7737ca1af3867807c49ca39955e43200716bb5f3b0d87bc69e8627e1dd7dd051927080a73a203ddb29", - "v3/files/7f/6f0047fd5ee304d158c34cd9d97a1aaf22a68e0dcf97bdb01e3d22efb2825f8e03ff28c72084dd0e6e9fa9e5d831b0c12d25819634be30bf6e03e8369a2746", - "v3/files/7f/9827a08004469d57872dfb5e541bc456eba6685d7e65044797df3554c0ba46b4d7b8549d94178f3a62b16baeb8b3827f71eeba5521cbe6a4effa4ef9085ca5", - "v3/files/80/5749e65c8acc1a444c249349a90f45f79ecadf4e0c847fe8e48740cc83391dc2f854d4f1b2c562f6762b0479f31b1281201baeaa31805c5cdd4e49bc110161", - "v3/files/81/03f6c7554de6667b68a121dce9482a3a052d4c4286a09e4e183740c25a70b3e7ae851d784b182f1473a0a94de90fc6cf26fbad3521e5c21207afc2ddc97bcd", - "v3/files/81/cf988f62c7bd603e3a6ed9c3ecff7476f48de8f63bf022df1bace6b920ef77fe715b74f6b5740a9ca1dcd429d2867d73a8d32cf7f9c85eb2d16ac3d35078e4", - "v3/files/84/66503ca6efa48cbf66a56f8578eeca93ab2dd1427227d0561c0e97aa3ec7c398324f0a85ed5f2dbe41bbadc1629aed864aca96e90c0a28e0ac54662adf2ff7", - "v3/files/85/2a6000d178c83e05c233be924f49f276aac9dcd8a93c79104da05bb45edb2232f88d7ae016f412bd239774f5b3186de452a3e6207b55a5d85b61eadb9bc066-exec", - "v3/files/85/42c50c2a195d857cb8e8d6e0e0ab50aa3179f7ca90744bb9926743a045b50b6959c658c656fffd8793051fcb8e4abac616b1677c47c93e9207b0df14741033", - "v3/files/85/ef15beae6788605513edd6ce46ea488a31ca1f4fcd34a9b2af0ee356e59885b089891c78bac98a744b69a249b00b9320f60227522fe3fb143e857778c44a1f", - "v3/files/87/8fd723b82a79c6867ef0ffb8d6dff4235a28176a5b547c59db4cf26d2e23a1c8fc93e45c55aebb7ed54a5aff2fb390cc9578b28c7c94fe0521f4994163b925", - "v3/files/89/927216209b9f9453a9d11d72e6479feecdd0e25f523e0dc5e471708081352728a7f0ad74e93d2e00e29f43bc36828fb4807d612eb81c431efc24d44a1b6fc7", - "v3/files/8a/029e32830002bc6b920148ef245ccb291b1b349b02848aa5ce99ca75c6d3a74e1db0bffdea1502a35925737bceb4c08223fa27850912e7a65b7da9788577a4-exec", - "v3/files/8b/1df454135be1140b6b93368e07c3e8827dfb55ca99e4442ab398bfbac3a161990a29f4eb4e6f131ded4c055be6436fb5e0b0670042fa71067d0e231cb83d17", - "v3/files/8b/b946cb640c1182d98c0ad15fcd1949acd4ccbe83e402efc0b240f8d306006b1ed9505641c7b80f53230b895bf4c2ed62d89ff52b79496e0025e82a6ec8bc02", - "v3/files/8d/bc3567b9616a81488e0da1b07a6de9017bee3ff19e009658d9214d1024002dc40d1cf5088470c420fb518aafd6d12e06a7230b91a951551b9624280a5554bf", - "v3/files/90/21f610d623865c7023b69ef3dca63083f6b5978d70924e72a9df89f9e61d088778ae265a719ce30f328288942291b5ab26aead99114ab62dc0708420c3616c", - "v3/files/90/593a81296a4f848dcd1302eea531f848fb574232dc289230c4302ae535552ae6437bda0684ca595857e48dc5fe46ecabd82bab63925a05c63b270af4a84236", - "v3/files/92/ca2a8d9a21324f0dbee51c50e2c953fb60ea681fd53251ce68fd21bda4ba03be900d20b334cff8cfaaa9bb10faad4b2b04a3cdec0184ab4131f7772b8482ea", - "v3/files/94/33bc9e6d478cfedd62c83ad0bd674514f3920edd1833569de1018dbeeacbb159726280fd5a9fbb79e703d1522d8e0a348ab94cb4b649df8e9effc9735fef1e-exec", - "v3/files/94/db0ff9a334a7f9a2a6540d6976023ea4f420aaf890284b3e5882e8e00d3a7905d2fe211517ebf563fa15f6f43d9368025276c4e5b375035b6290c06c7e781e", - "v3/files/98/d8250cb1b661359ada8be5d2a35bb7056856936ba21ab77e0c059a179db262b13a7ee11f5566907f744a780994578afeced2b1805a9c8a85ffe311caa63157", - "v3/files/9a/b96df11753b3923c1a191c05de6c6d3ae35f1f09052fffbc89837b44838c6547c57cf56dc176d44cf4a207275cfabf9bae02eed92028879a357c27044d9379", - "v3/files/9b/9b2bdd63c75e4d374106d78af27f7a87525ff3ee9b282be103cc3ce98171f4e17cd9a28eecf8e7004868103f609c453c7e777e3e9083c4a4a88e0c72a0fcba-exec", - "v3/files/9b/ad5f7b6f44db3f82215d60d462c4d28b00cc8c743e8167ceec9f112ea38ff5570726c3a79d49ea3ef70f34f0ed138e2b5664252b894f024564ef62054717c4", - "v3/files/9c/8b2def76ae5ffe4d636166bf9635d7abd69cdac4bf819a2145f7969646d39ae95c96364bc117f9fa544b98518c294233455d4f665af430c75d70798dd4ab13", - "v3/files/9d/e93ee7b458a9d6b97664022909ad25a7cb89c2cfdd8ee19aa2e126566b7a7a930b24143a2a76f83dbff19f1a67b0a71de93e8ab248720c2ee243396e869451", - "v3/files/9e/2449cf9cd108e7d15bc68c57b45ab4ecbb84b8ec7d6c2e7a367a47aa4ede65c7c4aa570b39940be77214c666730c1fa5250ac76740345b6e0eef852ccf8a52", - "v3/files/a0/09e43d84d4781d35163d895ca635ead87b2d2f8d9b1689ed09ab64e0536195764b067edbc893a1fed95367d6a99e382455cd8331c8d09cfe173b0fe1126c24-exec", - "v3/files/a0/680b324fe0a2ac774c6b55ae40c82ec51f49e42f59718c1fa708ff46f7861f3889bea1be376b684321788747fefabf9207469f3e46467ffc8cd2f0e6b9486e", - "v3/files/a1/c6cb0a6a96eac16d92b1b2b0563c03339d484429b2f4d543bded0481f0bae4dec7944dc51a5948b22cf3fa63205424c7f745ca2181b728106508292a66cf60", - "v3/files/a1/e2fc211820624ccf43443c0db06e9161ac1bfe2faf8d1b0fcbad391cbd7dfd65ba15dcab537ea42a35b297127d2513509fbb809d06bd666b3b8e9ab0d0b910", - "v3/files/a2/a9cb7d3de319d0f058f6af6f212c6d48d388cb17eaa833df307c81b9cd5a384ccbdd14dbe6616a401292e77c67f4ee311af75ec026ff2cb2bafc6449decdbd-exec", - "v3/files/a2/bbd0fc27dcb18788968a58f1c9d38fa49e27b32d6b942d1ea0f8d9d81a056400478137dcec81b6ddeda34addd14574690c5bef79b1b4d1145f0df7418d3abe-exec", - "v3/files/a4/a9e2494e1e0da2eea001379babc849ecd0349e3c00c7b0a1cb01fef1d387a9c7113631a156778fd6092fb5c1c75eb9afafabd80e898e8fc4abf1eb8094a216", - "v3/files/a6/e92c60a1d072f4572d295a8a3e7a0a105c02c9e7ab824dc5e7d41ecf1bed3e7b2ea56a944e8c11742d163070ca819dbd338119c1944343c0b28a6eef65bc1b", - "v3/files/a7/8bf25ca4359bdc9c5ae6f1f69c21dfe6c3bba4628fb2bbcbb8ced3440d43e77f3a46a2b85432fcffb75c320e9ccbef7a897b8218f087e5eeca58cc494b17b0", - "v3/files/a8/1983c1c62d075b3c76b1ddc412ed3ae745a30f6f11f580dcc64dcc2b088110e2b55e9dbaa9fbbaaadb3c2d81108773408658b653fed018c50804fe809b0297-exec", - "v3/files/a9/733d4214604b7aac76fb98b2d9cbb3109ee5142d37f2136672f2e2815ad5a826b36c5a8d5e8cfb39b4492bf7f51d1fcbd3a3193acd8adce9340a41f9035150", - "v3/files/ae/2f05ef38831679089b850b72dd72245ea3e51d65597dc11fafde5f6a991dde21f5f413f63c61a02cfdcb09417bcac06db5c006222c602d785a43b5a1f13032", - "v3/files/af/93b76be9167844f6d773f3e20038c6bcc415754e5402a5758e6b6dc59e29602997e2c831c17cf3a61e7b800a33f0eadee2a55708c6d7f2db1479c37ddb9780-exec", - "v3/files/b2/9f0073f86f7e9aed174fce942493e1e4a8fa5dac6afd4ff2108c74056f618e9e83cf6acf8fac63def0686fc46e266fa0bc90da004be5fb34df4f7f061e80a3-exec", - "v3/files/b4/6d960ff0ac8944ee6b1fd0306872c53a77640f5fb98ea7c66c352d21641441d8fc4bceb5d384aff7779feb5603a08488cd446e7a561ba408377db200815999", - "v3/files/b4/fe7072103387c586f37d90f27b6e7094f565aa61e9ff60cc09c0ecb80781741fb7d752f3b73820f4fbe9137165513f0cbb9b0f6d663b3838238c38af5f6b93", - "v3/files/b6/fc0809956c33c1eb37a0c6ad44c109f2c1c77a9b161c8b3df0562bc302391ded52c853033749fd9cd8af0c7c24fd6da57144f11c6dc4eadb5edcede5ffd877", - "v3/files/b7/f1e5dc2e73938d0dc0a7a1349c4c0e88ca1b5dff93164f254c4d03240ee7d58984b0f19fc42050ef51f79815ab41f8235953c87d46a894b62930f3ca32ccc8-exec", - "v3/files/b8/a7cb7d0dbfe703933a77aa6d41c78aac3c7f74bb0aa7d4ccb412b222558f8d7ca1ce361aecaa4e3713b0366bd999ca14c8d1dd0c3d9890badc208a0e436433", - "v3/files/b9/acf9e03ebcc7627deb8b26a0029e0b51fe3ff6b6d3a8601dd1fc684235fe0b527a0da83bb913a15fac0b86ee6776093ca69610e36774ad29f221969a23a766-exec", - "v3/files/bc/16419489153aa19e5a0c2989286941310a41478678fa91249878b232f9ffbfa5f9935846dc9ec57e98be60a489dd679de4ed9990f843570aa0fa3ba81e5356-exec", - "v3/files/bd/a3d5a1409e6cd87f61d971ddf347c11825130591ad261b6b92ec93e64872d146731283e14f497fc375c676298bed3446a0de53406b156781fb4c5342c33ade", - "v3/files/bd/acd8bef8171e84e07964785d04e504cc2017167cbc3cb6e284b6db802454e10a6797f4d02d1cfc0ff7dc44c9d63ac84157d22410ead7ca9c28cd50c4a8b065", - "v3/files/be/6f21427e4cba83248c962f0411d302db1dadcb97995aca6702f7144ab7da81a2285858e7ad85a144136d7bf6e30934af0255a60ae26d408e214f7c21a4bd32", - "v3/files/c0/997399d1b86a27a8e3d8bc4a285bfadc1243b9337381c9c13ea8e59b5709e0769a9863ec18656c1f6dab2ff6e29da5b0b008ad99c6e2b0fb4dec4de543a018", - "v3/files/c2/65c48634b48a6a4b70c9cfcdae4c44b2eaf59ab39152ef1fc40cd48c96c8a9da0b3549dcc3be6298edd9e75f891cd2cc3390854fb5c95a168165d0222876d2-exec", - "v3/files/c3/ee6434ab4d901f15830939ca719016c24f7ad4d3809214a7682c571a67b0b4546868e662a21b12d74be6416012d2ebc9f2f45e8c909dceb29e9d123b8d3536", - "v3/files/c5/57dce947b9939088714d013c9a417e8d38d08b63efe74ec1e309f7d08302ebe27a4931078c131a40ce223315d4f679dd6241f9a8a98f6c48e6b71789a4fc70", - "v3/files/c6/703e2577c586d276c218902674852f8bfd6ca4b07f018512e255e1f20853ca182ee85769961e78431ea9812bfeb09f031ad581f9e31533f12b9d43e587e757-exec", - "v3/files/c9/a6d4755cb30105d20d11099b30b209c9b923b90aa928da22a4b2532398931bedde1b7da8f7fd6ca72d20241b2684d7e200d38da79c024bab9d646540e1154e", - "v3/files/cc/6ef388a93c5c4bbb57078ad84343df773366871a5239468ec1c1757b6dcea5e14d571261cd017a935bc493def5d5fc61009dfe680db01c55595a1ff2b9bc40", - "v3/files/cd/02624dcc73c24ee0b488b1798a60de203d3487d6b0f75a869bd0bc9845f30e907a90ee727d1f64ffc3c6824fb2dfc900f13406ab63c827da719babc3407c9e", - "v3/files/d1/c303436fde8d31686f2375b30b31e6b107c7b4f3cb2566194347049e385ebfb241aa56491516a815f8a5395d256ba121b71cd2a5032cc3c94c2755ca4fb29b", - "v3/files/d1/dbaab34145159f6b9cdf552f24a4e817e98369d330b7cad8d28d9a71dde33601d57f36e0e6cbadafee8a3df4dac525f7a47d164f262fe8afdf0dd1f0847abc", - "v3/files/d2/fa1afc9873a0f4de45cd958ed20fbcfb11096759be6eee582f4de939e03bb6a07c8ae7cfee86a50d57949dd3f9fe3b053a95947ef44ff06f7a3d02a4f1eb9b", - "v3/files/d5/b90e7a534ce77c513674a4a09c8fa9908601060f8bd44bba7ac40243a7fc011a6c65be7e72134202872698103451c8b979bba2f15e6b6147c6e70008007f9c", - "v3/files/d6/f84a85f42a7c7971d607ee2df1952351246b079278bcbafda757f643094c9bbafb430e1aca63af939433b2216232e30aed4d5ea7854fb1ff824051e171d91e-exec", - "v3/files/d9/9fbd174c3f4bcefcbcf765b2e8f76211f7867059fd423580cef58ad3012e6fcbbdc87f3d849ed0d3c88c3e52304e59b6eb27c10307c514064807af43893877", - "v3/files/d9/b1f8849e09ebe0ccce0995993ccf7f83ee38f9414cefbf0ef34dcae21d42f315ccad4032a40eebdd7751765e338423fe7fb4e5b85b71d5debbe3bba894d9f8", - "v3/files/da/2d40a90eb81ee2fd0f2add4293f43902903711af0a64c16a7d78e20913842c4fb0ca62c04c4d92ceb2703a966423d962fa60fb4181fc213d99f1a0b4339297", - "v3/files/dd/8a7b4d525f8cba564e94846ed484f960663b4df324cbedccc422cd899b2139e88317e811a5e3c269baa641a7348de6359314ef3a5c1e6cc3f7ff5f23b8e1fe-exec", - "v3/files/de/3d6710a6195ac143a35a4688c78ddd8154ab002733f8c9cc1a4d9bd5cd77c77fcae53e97fd04c9f2a15b6ae245c8f4ad0b7abf13f064efe028f77635ba93fc", - "v3/files/e1/d0af67959826971b20963844f5213816c5b9dd75e7a46bed1a61b91d76ffe997294788a42c68976fee58be160c534d9521fdd3d336018e1f88b589a3cf9f4f", - "v3/files/e3/b6870966beed0a421519f885a8e6a9f69b7cd06319ed7250276913f1863e5f8b5c967895d205ca8d66f11da1f0ce631c2ed7506391132d12001db7bf8fa1bc", - "v3/files/e4/39669d73b83f43eeaabee13f4a06190c43b831544e44617fd955d5dddfefe0073d0d84edc0a614387a5cfce618668041ef0238234f2be99f48d35f7efe23c0-exec", - "v3/files/e5/3dee301557be2befd6403b92ad496e2473c0398c67072ae929675626e0f9bba070459ed772735fdc105a594a87f07900c68e745a5e636be753e0ba6b9c315a-exec", - "v3/files/e7/61df28bc8959531918e3b4a245629170909f6effd65f7e9db86a7bb81c9c83dd806ff3fb81426256dfaef29eb1588f49f4531952d54de35de431be6b914da8", - "v3/files/e7/787d498e4bc304540dc76364d498e72b750c870a4550b5bf1d4cb1bd0eccac00d2817482b834dfac86c1160790d772041d1a384e6a0545ef26f95e8bdada94", - "v3/files/ea/e061696e3726f2ce3c01f38e142982820ea7076590c8825dc7ba721a4e66af2742e6e59d90532dcec3a6c3647dc8a6e207d109b371b4905674409fe4ac4923", - "v3/files/eb/3773b87d3b91f4cd2d92a80c21ddff13189c501f1e17c06183f3e0b31cc95af66c99c5b7e36b393d9f7b23faf566d9c1cd623794c36e29de1df96708e19abd", - "v3/files/ed/41899967bb0874f42354d98be31d21cb9b6ce94294a994eef5214deff81fe8a9e287f926d0b54405e1ac2737ede914fdd4e67fb6461e874306cd22dcdbddb7", - "v3/files/ee/ae99bb2392ca88e1e3dfc2d23960c3c5c3b38870773c5a6e1bfce88de2b8989b2fa1b0ecf68a26e06cb4c9c46efe840c86be78b62bbf5c2abca2023ba7f536", - "v3/files/f0/3e0687f9a3d13087f7b966cd0ef1a143e5e70216be4209073bb15738e6c45a0864f619ca3274269d658020c9837b6c5584601fc1dbea2601fd2314df1830c6-exec", - "v3/files/f1/3a40e1bc634f7d71b88cff6c2a94cc32507508bf6c9dd5a5122e5dfeeaf7e8b56148b2ad4acfcc2ca4866a27315d4d1d59d4482cdb948692e0226982833a80", - "v3/files/f1/eac3da4b2d7d1965a923a7fd9d09fefccd711d7f8438d1156fcf0fbd46e678ccb4c60262a80ca9eb9380df498812d7b5ec893d82bd68f8c0148c71e1df0530-exec", - "v3/files/f2/5d079a1627100d33f0d252fc22bd535b4393dc7720b0abc77f167c98a5c88f81f571a06010fbdcd3fbe2f25e0b5ce0ed8242c19987bd922b47580c9ca2d8f2", - "v3/files/f2/9cacfaa15744fc96690a101e4224d95fe85e119fd93fee568a040b3cf80062b9876e9335e5fce60950ce95a7f8cd4f140e3dc9dc34919192b8c326677c84bc", - "v3/files/f4/a393da4150b41f91fa7f3206945627f98a728a65379c6f32c33b074fc58c7219d0ab2c84c8d9d91e54e958c05601589713f9ccfc34070f7e1cda87d86dd475", - "v3/files/f5/cb35226d3afdf2c03c1a57398f1f1cc0f62e050cde444468a94e5fb4ba7cb5b06c6e46f94aa552ba9d9132a5a113de0e084409ecf13a251fcef5ba9671230e", - "v3/files/f5/e89cbeefdbbfe6152bbf665b784ce61b88406b5a77354583bf88600731ba8b33f2d259ccfc519fe2ecfd7aa72cd0c955b322dc509f334ae4aed9d3895f0205", - "v3/files/f7/9436e735ef8c9de2498ac5febc9a9544b2930345686a982ce3ce9c85492e1b15d0fa4a51d016db4752c2e9a8c15ac54d19e55c943f5176292594b3f7a5adb8", - "v3/files/fa/a9e95cb8bef48d68623066d67d307a9f9a9606d88dfc7aca7780a5eba852ba395bbc48bcc4340cc07575b6661658ec6c993f30cf7077b1a0dcb381d1c0279b", - "v3/files/fb/2bd0916b04c64593856912b1a45034d575a7619df1e2f495712b11dfdd9a78f7d8a290dfc8785ddc1978c623057687836c6e460dbe62ab8c2a9874452ada59", - "v3/files/fc/1d65352c114c7594c9bedf5be432ba39d426feaf50bf8f7c52d32781323c84bfc9a68531aefb558c97ebe46e712e1d35d860ba1e1a6ab48b4a79b894092540", - "v3/files/fd/310b991968382a88f0cd0490ee6db22c2199a0133b6926972ee620e1b62ea45606a10c82d0c2c0367e732f261d9f26f7bbfcae71d6e72c80d9273706cafec1", - "v3/files/fe/198650f9a9d205e0c7f3afe68196e83014ddce21e1a2cc6bf6c4d539296473d4edd0b1e49152f61a18338ffef75f4458268fb41856ccafbaa46ffac5dc7e36", - "v3/files/ff/00a34fb9c309279edf249bca6d5e54c22d2151b118f358f4e737875bb6e8162e2af9cf5f6f60693f0f3c481b0c2f4a3d28e6f91dcc5c9db7cfe3c527efabbc-exec", + "v3/files/02/f9d952341eade675d0a8f5da14d4277fded62f937242292c2cf5f1bb0eda101b5f803098d64e2a138f4bfe4cdf326cfaf8f6b4015476ab86d25df03ddec731-exec", + "v3/files/68/b837b4fd7982b081521e51b14a167ccdb272b3c499202449d07d48d78a2fa7bb8652d3a894bb06ac6e3995e5126ee3470f73b5775584940751fce8be468405", + "v3/files/93/e31fcd9144a604f87d04fa8fb4a058202c579df17fd2b21301e17ac0ae4f3e2bae90ced7ae71b71218bd4a789e355ef7b8bd8899cdb785250071b229503b2e", + "v3/files/a5/541962367c9c3aaaa8be96312f7efedf7ae638bd051e80573649ca93b4852f4f2749efdce9f19fa7355b3a6d9130eded64e4b3c0efe753622735c5069482cd-index.json", + "v3/files/bf/0c878f2a4f2ec6f231bb2d414547efb15eb22a673815cba36acfd89633cd4c8affcbdc9378e90ad4d8fc654de921d1f67444be94e6a2f81bda9330be60be93-exec", + "v3/files/dd/feae8107ea156f46477e8e49e4dfb12365ba9ee122c953db785a5f776f4ff7b91b25378889dab77fb4188f8caaf45cc1c373b01ad326aef20d6a77c24ecefd-index.json", ] diff --git a/crates/cli/tests/snapshots/install__should_install_index_files.snap b/crates/cli/tests/snapshots/install__should_install_index_files.snap index 27b535e2..6b1009c7 100644 --- a/crates/cli/tests/snapshots/install__should_install_index_files.snap +++ b/crates/cli/tests/snapshots/install__should_install_index_files.snap @@ -1,69 +1,24 @@ --- source: crates/cli/tests/install.rs -assertion_line: 134 +assertion_line: 130 expression: index_file_contents --- -v3/files/09/0a6758fac3c263f5f923075d986d2ed26ff74ca2c957e5b86b17e62342564ae142d5374d01ec5163c6f7091d93d2e0779c8da4083d8d0128f7408169781630-index.json: - LICENSE: - integrity: sha512-Vdy8f/8awcR1X0y/JLoh4NyuBiyALT25N9K2GC9FVN2F0UUpoMlojqyCWjRbY6uLLl12meK+BxeN9buKByI16w== - mode: 420 - size: 1091 - README.md: - integrity: sha512-QP4YssHyQQdbcycnEQMj8+KfnWyHZf8CIrzPo0eEyqirzRj/vUu/q5eeVHis4nOnTtOgoi8CYTNPp8WeAy7b3g== - mode: 420 - size: 3495 +v3/files/a5/541962367c9c3aaaa8be96312f7efedf7ae638bd051e80573649ca93b4852f4f2749efdce9f19fa7355b3a6d9130eded64e4b3c0efe753622735c5069482cd-index.json: index.js: - integrity: sha512-iB8QHS8YhvxfmsXI0l5VQJCOFAAxFp6kGkqZQc+V/icRwSksGZVgnG8XSzgVzA3MbNKhAzmjSNOf51vHe1O6ng== - mode: 420 - size: 543 + integrity: sha512-AvnZUjQereZ10Kj12hTUJ3/e1i+TckIpLCz18bsO2hAbX4AwmNZOKhOPS/5M3zJs+vj2tAFUdquG0l3wPd7HMQ== + mode: 493 + size: 79 package.json: - integrity: sha512-VHvNaD4vn3sMJ5DGN7kjFTmUe+kjR5U0WS2RiGpW1iYv3B2M7SSsLMOt/aE5/jmdx1AtOCx6/FNuMFenzxHmwA== - mode: 420 - size: 1381 -v3/files/58/a80a5a0e5e531bd1646c16f05bdf6da1fb0174a1d9c2fede3e5f306cd4302c56049ddd5776bb5b3f32d9ffee4347b707a5a6a1d0f7a12e788d343d1d54c822-index.json: - ".travis.yml": - integrity: sha512-N46xbCMPzjVO9+cnIu5wjL7+qaSBqll7Bv78EvZlq2AXbL8E1rwVm+QszbxRdk1xUW+GuyigGw5gx2onU/HPRA== + integrity: sha512-k+MfzZFEpgT4fQT6j7SgWCAsV53xf9KyEwHhesCuTz4rrpDO165xtxIYvUp4njVe97i9iJnNt4UlAHGyKVA7Lg== mode: 420 - size: 132 - LICENSE: - integrity: sha512-5cJRTSsNPWvtrST911xV54AhHPBpLCH0ASAcLX36mQrQAYi9aLMMgmqqKnLsrRKnS8A0MDhPkzsXUQNd0bGMog== - mode: 420 - size: 1174 - README.md: - integrity: sha512-ymXfFutFCrY/kPEHqMyayC2pY1QI6BOm9tPhPPuniRezG2ZlJHnrulS2ElZmALKrG8FrgtCCxfh4A5Yajp45MQ== - mode: 420 - size: 1941 - bench.js: - integrity: sha512-YKtUhJ1s/XsFB2w7xNm6/+H4APTV4tZ8OcUhp6PZOzR85ajkU5cQLkDiEDZSxUPI57sWHBXQpuNOwanRHBaNKg== - mode: 420 - size: 941 + size: 537 +v3/files/dd/feae8107ea156f46477e8e49e4dfb12365ba9ee122c953db785a5f776f4ff7b91b25378889dab77fb4188f8caaf45cc1c373b01ad326aef20d6a77c24ecefd-index.json: index.js: - integrity: sha512-GlwBoTIecaHCY/uDh4y7omhvcfVxtCwtQNk4WL8fTG/39iUSWmiTLCQ+derUqdLxjZsis/5Vw5/mYFpCsucGIA== - mode: 420 - size: 3219 - package.json: - integrity: sha512-/9Pz/tZde0iSFpFncsYYC1wXFN3eFufiyZ/1+KQhS7j4hKDB0GobGopLDWJSrYW1M7Fibw3Y1HTyKD9s39afbA== - mode: 420 - size: 818 - test.js: - integrity: sha512-9wIYD0Rlp3cSetaiETBt1WSZPBf309lAFgTfS8ZX2NiIkC3mMqTPVbVR3fufhLqKkAeIdz8Dx3g2FD75ThgsfA== - mode: 420 - size: 1007 -v3/files/5a/ed551de20b04af0a016254022499417f781a6384e39460ebfe77f1f2b08a5a14bb6d4a9dc1246063eaa1bda8499e66513ef7bcb1ab1d08cac3728c3f07c3ce-index.json: - LICENSE: - integrity: sha512-n8vl3Ia8M7208SVVnnZ8OqrZTHxLIbgLaU2bAVjuDxDuU7Enwr8F25dor9rx+2d4/QihlBL7PBra1lWGPmw1HQ== - mode: 420 - size: 1088 - README.md: - integrity: sha512-WAHlkulKpAdsF5GAlW8z+CYvpxV6Br/mNqaFS9O5st30R4D/oUBWQq2Ozi7WUU4ZooF4y+zc9WCKO+cQu/PA1A== - mode: 420 - size: 5766 - index.js: - integrity: sha512-F1S3Jxyg4w3H13WYZxGithspggDBL4Z73m9+GdVgR8mrd6kzBFIPoaMbDDpOb7azEPid2MtNlaXGYoB+9zP4Xw== - mode: 420 - size: 662 + integrity: sha512-vwyHjypPLsbyMbstQUVH77FesipnOBXLo2rP2JYzzUyK/8vck3jpCtTY/GVN6SHR9nREvpTmovgb2pMwvmC+kw== + mode: 493 + size: 48 package.json: - integrity: sha512-AdMGuA9LFnjGVfOwaF2x96dB/HRtJRwA6SUpiriWMKMWe96MfY13m3J3DEH58wK7Hj8xJnLOeqjmwVbDGe7q2g== + integrity: sha512-aLg3tP15grCBUh5RsUoWfM2ycrPEmSAkSdB9SNeKL6e7hlLTqJS7BqxuOZXlEm7jRw9ztXdVhJQHUfzovkaEBQ== mode: 420 - size: 1444 + size: 379 diff --git a/crates/testing-utils/Cargo.toml b/crates/testing-utils/Cargo.toml index db0a226b..d5594a32 100644 --- a/crates/testing-utils/Cargo.toml +++ b/crates/testing-utils/Cargo.toml @@ -11,6 +11,8 @@ license.workspace = true repository.workspace = true [dependencies] +pacquet-registry-mock = { workspace = true } + assert_cmd = { workspace = true } command-extra = { workspace = true } tempfile = { workspace = true } diff --git a/crates/testing-utils/src/bin.rs b/crates/testing-utils/src/bin.rs index ebf1a655..9c0e4e17 100644 --- a/crates/testing-utils/src/bin.rs +++ b/crates/testing-utils/src/bin.rs @@ -1,5 +1,6 @@ use assert_cmd::prelude::*; use command_extra::CommandExtra; +use pacquet_registry_mock::AutoMockInstance; use std::{fs, path::PathBuf, process::Command}; use tempfile::{tempdir, TempDir}; use text_block_macros::text_block_fnl; @@ -34,19 +35,22 @@ impl CommandTempCwd<()> { } } -/// Information after the creation of an `.npmrc` file from assets provided by [`CommandTempCwd`]. -pub struct AddDefaultNpmrcInfo { +/// Information after the creation of an `.npmrc` file and a mocked registry from assets provided by [`CommandTempCwd`]. +#[must_use] +pub struct AddMockedRegistry { /// Path to the created `.npmrc` file. pub npmrc_path: PathBuf, /// Absolute path to the store directory as defined by the `.npmrc` file. pub store_dir: PathBuf, /// Absolute path to the cache directory as defined by the `.npmrc` file. pub cache_dir: PathBuf, + /// Anchor to a mocked registry instance. The server will be stop when [dropped](Drop). + pub mock_instance: AutoMockInstance, } impl CommandTempCwd<()> { - /// Create a `.npmrc` file that defines `store-dir` and `cache-dir`. - pub fn add_default_npmrc(self) -> CommandTempCwd { + /// Create a mock registry and a `.npmrc` file that defines `store-dir`, `cache-dir`, and `registry`. + pub fn add_mocked_registry(self) -> CommandTempCwd { let store_dir = self.root.path().join("pacquet-store"); let cache_dir = self.root.path().join("pacquet-cache"); let npmrc_path = self.workspace.join(".npmrc"); @@ -54,8 +58,11 @@ impl CommandTempCwd<()> { "store-dir=../pacquet-store" "cache-dir=../pacquet-cache" }; + let mock_instance = AutoMockInstance::load_or_init(); + let mocked_registry = mock_instance.url(); + let npmrc_text = format!("registry={mocked_registry}\n{npmrc_text}"); fs::write(&npmrc_path, npmrc_text).expect("write to .npmrc"); - let npmrc_info = AddDefaultNpmrcInfo { npmrc_path, store_dir, cache_dir }; + let npmrc_info = AddMockedRegistry { npmrc_path, store_dir, cache_dir, mock_instance }; let CommandTempCwd { pacquet, pnpm, root, workspace, npmrc_info: () } = self; CommandTempCwd { pacquet, pnpm, root, workspace, npmrc_info } } diff --git a/crates/testing-utils/src/fs.rs b/crates/testing-utils/src/fs.rs index 9d83e269..62a98c50 100644 --- a/crates/testing-utils/src/fs.rs +++ b/crates/testing-utils/src/fs.rs @@ -38,7 +38,6 @@ pub fn get_all_files(root: &Path) -> Vec { .filter(|entry| !entry.file_type().is_dir()) .map(|entry| normalized_suffix(entry.path(), root)) .filter(|suffix| !suffix.is_empty()) - .filter(|suffix| !suffix.ends_with("-index.json")) // until we have a stable fake registry, this is necessary for now .collect() } diff --git a/deny.toml b/deny.toml index 0310ac4c..0702fbb2 100644 --- a/deny.toml +++ b/deny.toml @@ -103,11 +103,13 @@ unlicensed = "deny" # [possible values: any SPDX 3.11 short identifier (+ optional exception)]. allow = [ "MIT", + "MPL-2.0", # required by mockito, which is used by tasks/micro-benchmark "Apache-2.0", "Unicode-DFS-2016", "BSD-3-Clause", "BSL-1.0", "ISC", + "Unlicense", # required by portpicker, which is used by crates/registry-mock #"Apache-2.0 WITH LLVM-exception", ] # List of explicitly disallowed licenses diff --git a/justfile b/justfile index e3088017..1ff98cca 100644 --- a/justfile +++ b/justfile @@ -28,6 +28,10 @@ update: git pull git submodule update --init +# Install necessary dependencies +install: + cd tasks/registry-mock/ && pnpm install --frozen-lockfile --prefer-offline + # Run `cargo watch` # --no-vcs-ignores: cargo-watch has a bug loading all .gitignores, including the ones listed in .gitignore # use .ignore file getting the ignore list @@ -59,6 +63,10 @@ codecov: micro-benchmark: cargo run --bin=micro-benchmark --release +# Manage registry-mock +registry-mock +args: + cargo run --bin=pacquet-registry-mock -- {{args}} + integrated-benchmark +args: cargo run --bin=integrated-benchmark -- {{args}} diff --git a/tasks/registry-mock/Cargo.toml b/tasks/registry-mock/Cargo.toml new file mode 100644 index 00000000..7e3ed149 --- /dev/null +++ b/tasks/registry-mock/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "pacquet-registry-mock" +version = "0.0.0" +description = "Wrapper of @pnpm/registry-mock" +publish = false +authors.workspace = true +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +repository.workspace = true + +[lib] +name = "pacquet_registry_mock" +path = "src/lib.rs" +doc = true + +[[bin]] +name = "pacquet-registry-mock" +path = "src/main.rs" +doc = false + +[dependencies] +advisory-lock = { workspace = true } +assert_cmd = { workspace = true } +clap = { workspace = true } +pipe-trait = { workspace = true } +portpicker = { workspace = true } +reqwest = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true } +which = { workspace = true } +sysinfo = { workspace = true } diff --git a/tasks/registry-mock/package.json b/tasks/registry-mock/package.json new file mode 100644 index 00000000..080ef153 --- /dev/null +++ b/tasks/registry-mock/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "@pnpm/registry-mock": "^3.16.0" + } +} diff --git a/tasks/registry-mock/pnpm-lock.yaml b/tasks/registry-mock/pnpm-lock.yaml new file mode 100644 index 00000000..fc27d78b --- /dev/null +++ b/tasks/registry-mock/pnpm-lock.yaml @@ -0,0 +1,2494 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@pnpm/registry-mock': + specifier: ^3.16.0 + version: 3.16.0(typanion@3.14.0) + +packages: + + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@pnpm/registry-mock@3.16.0(typanion@3.14.0): + resolution: {integrity: sha512-lTkoNBAHth1wpEVsJzAED/uRvNAM40pN78aGcuYmoF37g2eQd3fw9xUhfOeq1DFL5KHm7Ql0eRLBWWg0t9xgGA==} + engines: {node: '>=10.13'} + hasBin: true + dependencies: + anonymous-npm-registry-client: 0.2.0 + execa: 5.1.1 + fs-extra: 11.1.1 + read-yaml-file: 2.1.0 + rimraf: 3.0.2 + tempy: 1.0.1 + verdaccio: 5.27.0(typanion@3.14.0) + write-yaml-file: 4.2.0 + transitivePeerDependencies: + - encoding + - supports-color + - typanion + dev: true + + /@types/lodash@4.14.201: + resolution: {integrity: sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==} + dev: true + + /@verdaccio/commons-api@10.2.0: + resolution: {integrity: sha512-F/YZANu4DmpcEV0jronzI7v2fGVWkQ5Mwi+bVmV+ACJ+EzR0c9Jbhtbe5QyLUuzR97t8R5E/Xe53O0cc2LukdQ==} + engines: {node: '>=8'} + dependencies: + http-errors: 2.0.0 + http-status-codes: 2.2.0 + dev: true + + /@verdaccio/config@7.0.0-next.3: + resolution: {integrity: sha512-DWBd7THRNDTd1UKwipCYyppdJ5h9sB495FPi9Vaad+DQtN5tNYRx3+aMvuqlDRwHZrssPJeAp8wu8cjLNpMokQ==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/core': 7.0.0-next.3 + '@verdaccio/utils': 7.0.0-next.3 + debug: 4.3.4 + js-yaml: 4.1.0 + lodash: 4.17.21 + minimatch: 7.4.6 + yup: 0.32.11 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/core@7.0.0-next.3: + resolution: {integrity: sha512-P6XniWZMPcXF/nYRqfyDZDzH5xUMQw9ZiJJ1l+H1SqfTNgxLhRhciOQG39lTvRb3aYnzRtWUjd3ink4IytXpjg==} + engines: {node: '>=12'} + dependencies: + ajv: 8.12.0 + core-js: 3.30.2 + http-errors: 2.0.0 + http-status-codes: 2.2.0 + process-warning: 1.0.0 + semver: 7.5.4 + dev: true + + /@verdaccio/file-locking@10.3.1: + resolution: {integrity: sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g==} + engines: {node: '>=12'} + dependencies: + lockfile: 1.0.4 + dev: true + + /@verdaccio/file-locking@12.0.0-next.1: + resolution: {integrity: sha512-Zb5G2HEhVRB0jCq4z7QA4dqTdRv/2kIsw2Nkm3j2HqC1OeJRxas3MJAF/OxzbAb1IN32lbg1zycMSk6NcbQkgQ==} + engines: {node: '>=12'} + dependencies: + lockfile: 1.0.4 + dev: true + + /@verdaccio/local-storage@10.3.3: + resolution: {integrity: sha512-/n0FH+1hxVg80YhYBfJuW7F2AuvLY2fra8/DTCilWDll9Y5yZDxwntZfcKHJLerCA4atrbJtvaqpWkoV3Q9x8w==} + engines: {node: '>=8'} + dependencies: + '@verdaccio/commons-api': 10.2.0 + '@verdaccio/file-locking': 10.3.1 + '@verdaccio/streams': 10.2.1 + async: 3.2.4 + debug: 4.3.4 + lodash: 4.17.21 + lowdb: 1.0.0 + mkdirp: 1.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/logger-7@7.0.0-next.3: + resolution: {integrity: sha512-JURPnpBnai+1/hgblJ5ayJGHJo068X00QzdZ8u/iB8t6fZRZIVKwVMSBfgOquDUODuJypaueG1MP+twvcUco0Q==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/logger-commons': 7.0.0-next.3 + pino: 7.11.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/logger-commons@7.0.0-next.3: + resolution: {integrity: sha512-j1+9OeGN7WCuo+QZve8fbJEH9ju8rW18H0/xC+OEx6hzmNrmREgc60S5H6OEdSs8mn6wfD4LcMuV8ZDx/JaLMQ==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/core': 7.0.0-next.3 + '@verdaccio/logger-prettify': 7.0.0-next.1 + colorette: 2.0.20 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/logger-prettify@7.0.0-next.1: + resolution: {integrity: sha512-ZF71AS2k0OiSnKVT05+NUWARZ+yn0keGAlpkgNWU7SHiYeFS1ZDVpapi9PXR23gJ5U756fyPKaqvlRcYgEpsgA==} + engines: {node: '>=12'} + dependencies: + colorette: 2.0.20 + dayjs: 1.11.7 + lodash: 4.17.21 + pino-abstract-transport: 1.0.0 + sonic-boom: 3.3.0 + dev: true + + /@verdaccio/middleware@7.0.0-next.3: + resolution: {integrity: sha512-7+K23DIakzewjVUiekU2n6gZVXdPZxStKZIh+wE3NGdfIP4tYOQQajJSoIycoLDAcax+ws6BpKRCt2/3DlU0bA==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/config': 7.0.0-next.3 + '@verdaccio/core': 7.0.0-next.3 + '@verdaccio/url': 12.0.0-next.3 + '@verdaccio/utils': 7.0.0-next.3 + debug: 4.3.4 + express: 4.18.2 + express-rate-limit: 5.5.1 + lodash: 4.17.21 + lru-cache: 7.18.3 + mime: 2.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/search@7.0.0-next.2: + resolution: {integrity: sha512-NoGSpubKB+SB4gRMIoEl3E3NkoKE5f0DnANghB3SnMtVxpJGdwZgylosqDxt8swhQ80+16hYdAp6g44uhjVE6Q==} + engines: {node: '>=12'} + dev: true + + /@verdaccio/signature@7.0.0-next.1: + resolution: {integrity: sha512-uq6divC36rcwyBd6+JeTJXQ9K7d4Kuh7HNg6ZMU4ItSCYkLHJjVqNC2Kzo/SdkYNOd11xJuNlYU8NNuhpqpVuw==} + engines: {node: '>=12'} + dependencies: + debug: 4.3.4 + jsonwebtoken: 9.0.2 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/streams@10.2.1: + resolution: {integrity: sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ==} + engines: {node: '>=12', npm: '>=5'} + dev: true + + /@verdaccio/tarball@12.0.0-next.3: + resolution: {integrity: sha512-pIZ24sVd5TmoKKrOcOvLqDU3rOjpjEpDCn3nsEk8UuWhWG121/3Hxr+9EirBjqWJ7Tnurz5mMl1jpgJNQOylKg==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/core': 7.0.0-next.3 + '@verdaccio/url': 12.0.0-next.3 + '@verdaccio/utils': 7.0.0-next.3 + debug: 4.3.4 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/ui-theme@7.0.0-next.3: + resolution: {integrity: sha512-mk132QldyfU1abdzLnV6OsYp46k6l4CtACyw0q3bgT8ytRp3fKF05/31vQObEayNWwhSDr/LvCz12s4e3BuVUA==} + dev: true + + /@verdaccio/url@12.0.0-next.3: + resolution: {integrity: sha512-iuGn4KU0sq7GBfefzMbOotWp3s/43VLSyGPf38AZ44cTErjsRH92q8UOx7E9CsVACPRiBfrhUfsKl8qTk/Qs9Q==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/core': 7.0.0-next.3 + debug: 4.3.4 + lodash: 4.17.21 + validator: 13.9.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@verdaccio/utils@7.0.0-next.3: + resolution: {integrity: sha512-yawwfOXVgR/woFbe4q30Zqyq95N0lPCry4L9YS7ytts7pPdB6FbDnOW9mFHbdKurkDQ563zxyuBWdBZGITG1kQ==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/core': 7.0.0-next.3 + lodash: 4.17.21 + minimatch: 7.4.6 + semver: 7.5.4 + dev: true + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: true + + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: true + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /anonymous-npm-registry-client@0.2.0: + resolution: {integrity: sha512-ym3GCDQU8B6PZrswCvanRiWoSg2QrrlPwoRlMr4oCpGvyK2KlwTujdCZfxrGapqxrqEY3TpxEqLf+7PhFnyaLA==} + dependencies: + concat-stream: 1.6.2 + graceful-fs: 4.2.11 + normalize-package-data: 2.5.0 + npm-package-arg: 6.1.1 + once: 1.4.0 + request: 2.88.2 + retry: 0.13.1 + safe-buffer: 5.2.1 + semver: 7.5.4 + slide: 1.1.6 + ssri: 8.0.1 + optionalDependencies: + npmlog: 4.1.2 + dev: true + + /ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: true + optional: true + + /apache-md5@1.1.8: + resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==} + engines: {node: '>=8'} + dev: true + + /aproba@1.2.0: + resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} + requiresBuild: true + dev: true + optional: true + + /are-we-there-yet@1.1.7: + resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==} + requiresBuild: true + dependencies: + delegates: 1.0.0 + readable-stream: 2.3.8 + dev: true + optional: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + dev: true + + /async@3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: true + + /aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: true + + /aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + dependencies: + tweetnacl: 0.14.5 + dev: true + + /bcryptjs@2.4.3: + resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} + dev: true + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /builtins@1.0.3: + resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} + dev: true + + /bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + dev: true + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: true + + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + dev: true + + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /clipanion@3.2.1(typanion@3.14.0): + resolution: {integrity: sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==} + peerDependencies: + typanion: '*' + dependencies: + typanion: 3.14.0 + dev: true + + /code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: true + optional: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + dev: true + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + requiresBuild: true + dev: true + optional: true + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: true + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: true + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + + /cookies@0.8.0: + resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + keygrip: 1.1.0 + dev: true + + /core-js@3.30.2: + resolution: {integrity: sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==} + requiresBuild: true + dev: true + + /core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + + /dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + + /dayjs@1.11.7: + resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /del@6.1.1: + resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} + engines: {node: '>=10'} + dependencies: + globby: 11.1.0 + graceful-fs: 4.2.11 + is-glob: 4.0.3 + is-path-cwd: 2.2.0 + is-path-inside: 3.0.3 + p-map: 4.0.0 + rimraf: 3.0.2 + slash: 3.0.0 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + requiresBuild: true + dev: true + optional: true + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: true + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /duplexify@4.1.2: + resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.1 + dev: true + + /ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + + /ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + + /envinfo@7.10.0: + resolution: {integrity: sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: true + + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: true + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /express-rate-limit@5.5.1: + resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==} + dev: true + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-redact@3.3.0: + resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} + engines: {node: '>=6'} + dev: true + + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: true + + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: true + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: true + + /fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /gauge@2.7.4: + resolution: {integrity: sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==} + requiresBuild: true + dependencies: + aproba: 1.2.0 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 1.0.2 + strip-ansi: 3.0.1 + wide-align: 1.1.5 + dev: true + optional: true + + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + dependencies: + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + dependencies: + assert-plus: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@6.0.4: + resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==} + dependencies: + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + dev: true + + /har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + dev: true + + /har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: true + + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + requiresBuild: true + dev: true + optional: true + + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: true + + /http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + dev: true + + /http-status-codes@2.2.0: + resolution: {integrity: sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==} + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dependencies: + number-is-nan: 1.0.1 + dev: true + optional: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.5.4 + dev: true + + /jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + + /jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: true + + /jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + dev: true + + /keygrip@1.1.0: + resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} + engines: {node: '>= 0.6'} + dependencies: + tsscmp: 1.0.6 + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /lockfile@1.0.4: + resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} + dependencies: + signal-exit: 3.0.7 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: true + + /lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + dev: true + + /lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + dev: true + + /lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + dev: true + + /lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true + + /lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /lowdb@1.0.0: + resolution: {integrity: sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.11 + is-promise: 2.2.2 + lodash: 4.17.21 + pify: 3.0.0 + steno: 0.4.4 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: true + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + dev: true + + /mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mv@2.1.1: + resolution: {integrity: sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==} + engines: {node: '>=0.8.0'} + dependencies: + mkdirp: 0.5.6 + ncp: 2.0.0 + rimraf: 2.4.5 + dev: true + + /nanoclone@0.2.1: + resolution: {integrity: sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==} + dev: true + + /ncp@2.0.0: + resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} + hasBin: true + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /npm-package-arg@6.1.1: + resolution: {integrity: sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==} + dependencies: + hosted-git-info: 2.8.9 + osenv: 0.1.5 + semver: 5.7.2 + validate-npm-package-name: 3.0.0 + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npmlog@4.1.2: + resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==} + requiresBuild: true + dependencies: + are-we-there-yet: 1.1.7 + console-control-strings: 1.1.0 + gauge: 2.7.4 + set-blocking: 2.0.0 + dev: true + optional: true + + /number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: true + optional: true + + /oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + dev: true + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + + /on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /osenv@0.1.5: + resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + dependencies: + duplexify: 4.1.2 + split2: 4.2.0 + dev: true + + /pino-abstract-transport@1.0.0: + resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==} + dependencies: + readable-stream: 4.4.2 + split2: 4.2.0 + dev: true + + /pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + dev: true + + /pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.3.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + dev: true + + /pkginfo@0.4.1: + resolution: {integrity: sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==} + engines: {node: '>= 0.4.0'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + dev: true + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + + /property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + dev: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: true + + /psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: true + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: true + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /read-yaml-file@2.1.0: + resolution: {integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==} + engines: {node: '>=10.13'} + dependencies: + js-yaml: 4.1.0 + strip-bom: 4.0.0 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@4.4.2: + resolution: {integrity: sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: true + + /real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: true + + /request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@2.4.5: + resolution: {integrity: sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==} + hasBin: true + dependencies: + glob: 6.0.4 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + requiresBuild: true + dev: true + optional: true + + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slide@1.1.6: + resolution: {integrity: sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==} + dev: true + + /sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + dependencies: + atomic-sleep: 1.0.0 + dev: true + + /sonic-boom@3.3.0: + resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==} + dependencies: + atomic-sleep: 1.0.0 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-license-ids@3.0.16: + resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + dev: true + + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: true + + /sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + + /ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: true + + /steno@0.4.4: + resolution: {integrity: sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==} + dependencies: + graceful-fs: 4.2.11 + dev: true + + /stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + dev: true + + /string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + dev: true + optional: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dependencies: + ansi-regex: 2.1.1 + dev: true + optional: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + dev: true + + /tempy@1.0.1: + resolution: {integrity: sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==} + engines: {node: '>=10'} + dependencies: + del: 6.1.1 + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + dev: true + + /thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + dependencies: + real-require: 0.1.0 + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: true + + /toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + dev: true + + /tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + dev: true + + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: true + + /typanion@3.14.0: + resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==} + dev: true + + /type-fest@0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: true + + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: true + + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: true + + /uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: true + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: true + + /unix-crypt-td-js@1.1.4: + resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==} + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: true + + /uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /validate-npm-package-name@3.0.0: + resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} + dependencies: + builtins: 1.0.3 + dev: true + + /validator@13.11.0: + resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + engines: {node: '>= 0.10'} + dev: true + + /validator@13.9.0: + resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==} + engines: {node: '>= 0.10'} + dev: true + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: true + + /verdaccio-audit@12.0.0-next.3: + resolution: {integrity: sha512-LdiCh0fG3u7lsVGxIWZFxZ7ZStsc8u+129T3Rt3wgYOnEn4+NsYGuZJZzoXTBJ+F1ymCjOg77+kpDFHECHxsYA==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/config': 7.0.0-next.3 + '@verdaccio/core': 7.0.0-next.3 + express: 4.18.2 + https-proxy-agent: 5.0.1 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /verdaccio-htpasswd@12.0.0-next.3: + resolution: {integrity: sha512-/jdfaGQy0ry2gcQiUB6JsKr2esPZtj5ITuYar+NaFIfIOHrUk+NRdmPNHr1XQyofCzwEyENlgtdZMs1K+yeI4w==} + engines: {node: '>=12'} + dependencies: + '@verdaccio/core': 7.0.0-next.3 + '@verdaccio/file-locking': 12.0.0-next.1 + apache-md5: 1.1.8 + bcryptjs: 2.4.3 + core-js: 3.30.2 + debug: 4.3.4 + http-errors: 2.0.0 + unix-crypt-td-js: 1.1.4 + transitivePeerDependencies: + - supports-color + dev: true + + /verdaccio@5.27.0(typanion@3.14.0): + resolution: {integrity: sha512-S0XCNgy+s8O3+Prm1uYMYR58WbvsnhUgAm6qk64suZs0YyBrTh/YJSRLYgsjAIiIpO/c2gnvNaDwz2EcX/C7nQ==} + engines: {node: '>=12.18'} + hasBin: true + dependencies: + '@verdaccio/config': 7.0.0-next.3 + '@verdaccio/core': 7.0.0-next.3 + '@verdaccio/local-storage': 10.3.3 + '@verdaccio/logger-7': 7.0.0-next.3 + '@verdaccio/middleware': 7.0.0-next.3 + '@verdaccio/search': 7.0.0-next.2 + '@verdaccio/signature': 7.0.0-next.1 + '@verdaccio/streams': 10.2.1 + '@verdaccio/tarball': 12.0.0-next.3 + '@verdaccio/ui-theme': 7.0.0-next.3 + '@verdaccio/url': 12.0.0-next.3 + '@verdaccio/utils': 7.0.0-next.3 + JSONStream: 1.3.5 + async: 3.2.4 + clipanion: 3.2.1(typanion@3.14.0) + compression: 1.7.4 + cookies: 0.8.0 + cors: 2.8.5 + debug: 4.3.4 + envinfo: 7.10.0 + express: 4.18.2 + express-rate-limit: 5.5.1 + fast-safe-stringify: 2.1.1 + handlebars: 4.7.8 + js-yaml: 4.1.0 + jsonwebtoken: 9.0.2 + kleur: 4.1.5 + lodash: 4.17.21 + lru-cache: 7.18.3 + mime: 3.0.0 + mkdirp: 1.0.4 + mv: 2.1.1 + pkginfo: 0.4.1 + request: 2.88.2 + semver: 7.5.4 + validator: 13.11.0 + verdaccio-audit: 12.0.0-next.3 + verdaccio-htpasswd: 12.0.0-next.3 + transitivePeerDependencies: + - encoding + - supports-color + - typanion + dev: true + + /verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + requiresBuild: true + dependencies: + string-width: 1.0.2 + dev: true + optional: true + + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: true + + /write-yaml-file@4.2.0: + resolution: {integrity: sha512-LwyucHy0uhWqbrOkh9cBluZBeNVxzHjDaE9mwepZG3n3ZlbM4v3ndrFw51zW/NXYFFqP+QWZ72ihtLWTh05e4Q==} + engines: {node: '>=10.13'} + dependencies: + js-yaml: 4.1.0 + write-file-atomic: 3.0.3 + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yup@0.32.11: + resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} + engines: {node: '>=10'} + dependencies: + '@babel/runtime': 7.23.2 + '@types/lodash': 4.14.201 + lodash: 4.17.21 + lodash-es: 4.17.21 + nanoclone: 0.2.1 + property-expr: 2.0.6 + toposort: 2.0.2 + dev: true diff --git a/tasks/registry-mock/src/dirs.rs b/tasks/registry-mock/src/dirs.rs new file mode 100644 index 00000000..5b9bdf8f --- /dev/null +++ b/tasks/registry-mock/src/dirs.rs @@ -0,0 +1,37 @@ +use pipe_trait::Pipe; +use std::{ + path::{Path, PathBuf}, + process::Command, + sync::OnceLock, +}; + +pub fn workspace_root() -> &'static Path { + static WORKSPACE_ROOT: OnceLock = OnceLock::new(); + WORKSPACE_ROOT.get_or_init(|| { + let output = env!("CARGO") + .pipe(Command::new) + .arg("locate-project") + .arg("--workspace") + .arg("--message-format=plain") + .output() + .expect("cargo locate-project"); + assert!( + output.status.success(), + "Command `cargo locate-project` exits with non-zero status code" + ); + output + .stdout + .pipe(String::from_utf8) + .expect("convert stdout to UTF-8") + .trim_end() + .pipe(PathBuf::from) + .parent() + .expect("parent of root manifest") + .to_path_buf() + }) +} + +pub fn registry_mock() -> &'static Path { + static REGISTRY_MOCK: OnceLock = OnceLock::new(); + REGISTRY_MOCK.get_or_init(|| workspace_root().join("tasks").join("registry-mock")) +} diff --git a/tasks/registry-mock/src/kill_verdaccio.rs b/tasks/registry-mock/src/kill_verdaccio.rs new file mode 100644 index 00000000..f86724e1 --- /dev/null +++ b/tasks/registry-mock/src/kill_verdaccio.rs @@ -0,0 +1,29 @@ +use pipe_trait::Pipe; +use sysinfo::{ + Pid, Process, ProcessExt, ProcessRefreshKind, RefreshKind, Signal, System, SystemExt, +}; + +fn is_descent_of(process: &Process, suspect_ancestor: Pid, system: &System) -> bool { + let Some(parent) = process.parent() else { return false }; + if parent == suspect_ancestor { + return true; + } + let Some(parent) = system.processes().get(&parent) else { return false }; + is_descent_of(parent, suspect_ancestor, system) +} + +pub fn kill_all_verdaccio_children_in(root: Pid, signal: Signal, system: &System) -> usize { + system + .processes() + .values() + .filter(|process| is_descent_of(process, root, system)) + .filter(|process| process.kill_with(signal).unwrap_or_else(|| process.kill())) + .count() +} + +pub fn kill_all_verdaccio_children(root: Pid, signal: Signal) -> usize { + let system = RefreshKind::new() + .with_processes(ProcessRefreshKind::new()) + .pipe(System::new_with_specifics); + kill_all_verdaccio_children_in(root, signal, &system) +} diff --git a/tasks/registry-mock/src/lib.rs b/tasks/registry-mock/src/lib.rs new file mode 100644 index 00000000..c9b0015e --- /dev/null +++ b/tasks/registry-mock/src/lib.rs @@ -0,0 +1,13 @@ +mod dirs; +mod kill_verdaccio; +mod mock_instance; +mod node_registry_mock; +mod port_to_url; +mod registry_anchor; +mod registry_info; + +pub use dirs::*; +pub use mock_instance::*; +pub use node_registry_mock::*; +pub use registry_anchor::*; +pub use registry_info::*; diff --git a/tasks/registry-mock/src/main.rs b/tasks/registry-mock/src/main.rs new file mode 100644 index 00000000..7d651115 --- /dev/null +++ b/tasks/registry-mock/src/main.rs @@ -0,0 +1,46 @@ +use std::env::temp_dir; + +use clap::Parser; +use pacquet_registry_mock::{MockInstanceOptions, PreparedRegistryInfo}; +use portpicker::pick_unused_port; +use reqwest::Client; +use tokio::time::Duration; + +/// Launch a single mocked registry server to be used in tests. +/// +/// This step is optional, but would help in machine with few CPU cores. +#[derive(Debug, Parser)] +enum Cli { + /// Start a single mocked registry server. + Launch, + /// Terminate the launched mocked registry server. + End, +} + +#[tokio::main] +async fn main() { + match Cli::parse() { + Cli::Launch => launch().await, + Cli::End => end(), + }; +} + +async fn launch() { + let stdout = temp_dir().join("pacquet-registry-mock-prepared.stdout.log"); + let stderr = temp_dir().join("pacquet-registry-mock-prepared.stderr.log"); + let options = MockInstanceOptions { + client: &Client::new(), + port: pick_unused_port().expect("pick an unused port"), + stdout: Some(&stdout), + stderr: Some(&stderr), + max_retries: 20, + retry_delay: Duration::from_millis(500), + }; + let saved_info = PreparedRegistryInfo::launch(options).await; + dbg!(&saved_info, &stdout, &stderr); +} + +fn end() { + let deleted_info = PreparedRegistryInfo::end(); + dbg!(&deleted_info); +} diff --git a/tasks/registry-mock/src/mock_instance.rs b/tasks/registry-mock/src/mock_instance.rs new file mode 100644 index 00000000..79b0b60f --- /dev/null +++ b/tasks/registry-mock/src/mock_instance.rs @@ -0,0 +1,166 @@ +use crate::{ + kill_verdaccio::kill_all_verdaccio_children, node_registry_mock, port_to_url::port_to_url, + PreparedRegistryInfo, RegistryAnchor, RegistryInfo, +}; +use assert_cmd::prelude::*; +use pipe_trait::Pipe; +use portpicker::pick_unused_port; +use reqwest::Client; +use std::{ + fs::File, + path::Path, + process::{Child, Command, Stdio}, +}; +use sysinfo::{Pid, PidExt, Signal}; +use tokio::time::{sleep, Duration}; + +/// Handler of a mocked registry server instance. +/// +/// The internal process will be killed on [drop](Drop). +#[derive(Debug)] +pub struct MockInstance { + pub(crate) process: Child, +} + +impl Drop for MockInstance { + fn drop(&mut self) { + let MockInstance { process, .. } = self; + let pid = process.id(); + eprintln!("info: Terminating all verdaccio instances below {pid}..."); + let kill_count = kill_all_verdaccio_children(Pid::from_u32(pid), Signal::Interrupt); + eprintln!("info: Terminated {kill_count} verdaccio instances"); + } +} + +/// Launch options for a [`MockInstance`]. +#[derive(Debug, Clone, Copy)] +pub struct MockInstanceOptions<'a> { + pub client: &'a Client, + pub port: u16, + pub stdout: Option<&'a Path>, + pub stderr: Option<&'a Path>, + pub max_retries: usize, + pub retry_delay: Duration, +} + +impl<'a> MockInstanceOptions<'a> { + async fn is_registry_ready(self) -> bool { + let MockInstanceOptions { client, port, .. } = self; + let url = port_to_url(port); + + let Err(error) = client.head(url).send().await else { + return true; + }; + + if error.is_connect() { + eprintln!("info: {error}"); + return false; + } + + panic!("{error}"); + } + + async fn wait_for_registry(self) { + let MockInstanceOptions { max_retries, retry_delay, .. } = self; + let mut retries = max_retries; + + while !self.is_registry_ready().await { + retries = retries.checked_sub(1).unwrap_or_else(|| { + panic!("Failed to check for the registry for {max_retries} times") + }); + + sleep(retry_delay).await; + } + } + + pub(crate) async fn spawn(self) -> MockInstance { + let MockInstanceOptions { port, stdout, stderr, .. } = self; + let port = port.to_string(); + + eprintln!("Preparing..."); + node_registry_mock() + .pipe(Command::new) + .arg("prepare") + .env("PNPM_REGISTRY_MOCK_PORT", &port) + .stdin(Stdio::null()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .assert() + .success(); + + let stdout = stdout.map_or_else(Stdio::null, |stdout| { + File::create(stdout).expect("create file for stdout").into() + }); + let stderr = stderr.map_or_else(Stdio::null, |stderr| { + File::create(stderr).expect("create file for stderr").into() + }); + let process = node_registry_mock() + .pipe(Command::new) + .env("PNPM_REGISTRY_MOCK_PORT", &port) + .stdin(Stdio::null()) + .stdout(stdout) + .stderr(stderr) + .spawn() + .expect("spawn mocked registry"); + + self.wait_for_registry().await; + + MockInstance { process } + } + + pub async fn spawn_if_necessary(self) -> Option { + let MockInstanceOptions { port, .. } = self; + if self.is_registry_ready().await { + eprintln!("info: {port} is already available"); + None + } else { + eprintln!("info: spawning mocked registry..."); + self.spawn().await.pipe(Some) + } + } +} + +/// Manage a single mocked registry server instance that is shared between multiple different tests. +/// +/// This instance can either be automatically be spawned by the first test and tracked by a reference counter +/// or be prepared by the CLI command. +#[derive(Debug)] +#[must_use] +pub enum AutoMockInstance { + /// The instance is created by the CLI command and managed manually. + Prepared(PreparedRegistryInfo), + /// The instance is automatically spawned by the first test to run and managed automatically by counting references. + RefCount(RegistryAnchor), +} + +impl AutoMockInstance { + pub fn load_or_init() -> Self { + if let Some(prepared) = PreparedRegistryInfo::try_load() { + return AutoMockInstance::Prepared(prepared); + } + + let anchor = RegistryAnchor::load_or_init({ + MockInstanceOptions { + client: &Client::new(), + port: pick_unused_port().expect("pick an unused port"), + stdout: None, + stderr: None, + max_retries: 20, + retry_delay: Duration::from_millis(500), + } + }); + + AutoMockInstance::RefCount(anchor) + } + + fn info(&self) -> &'_ RegistryInfo { + match self { + AutoMockInstance::Prepared(prepared) => &prepared.info, + AutoMockInstance::RefCount(anchor) => &anchor.info, + } + } + + pub fn url(&self) -> String { + self.info().url() + } +} diff --git a/tasks/registry-mock/src/node_registry_mock.rs b/tasks/registry-mock/src/node_registry_mock.rs new file mode 100644 index 00000000..52b05829 --- /dev/null +++ b/tasks/registry-mock/src/node_registry_mock.rs @@ -0,0 +1,25 @@ +use crate::registry_mock; +use pipe_trait::Pipe; +use std::{ + env, iter, + path::{Path, PathBuf}, + sync::OnceLock, +}; +use which::which_in; + +static NODE_REGISTRY_MOCK: OnceLock = OnceLock::new(); + +fn init() -> PathBuf { + let bin = registry_mock().join("node_modules").join(".bin"); + let paths = env::var_os("PATH") + .unwrap_or_default() + .pipe_ref(env::split_paths) + .chain(iter::once(bin)) + .pipe(env::join_paths) + .expect("append node_modules/.bin to PATH"); + which_in("registry-mock", Some(paths), ".").expect("find registry-mock binary") +} + +pub fn node_registry_mock() -> &'static Path { + NODE_REGISTRY_MOCK.get_or_init(init) +} diff --git a/tasks/registry-mock/src/port_to_url.rs b/tasks/registry-mock/src/port_to_url.rs new file mode 100644 index 00000000..b890d354 --- /dev/null +++ b/tasks/registry-mock/src/port_to_url.rs @@ -0,0 +1,5 @@ +use std::fmt::Display; + +pub fn port_to_url(port: impl Display) -> String { + format!("http://localhost:{port}/") +} diff --git a/tasks/registry-mock/src/registry_anchor.rs b/tasks/registry-mock/src/registry_anchor.rs new file mode 100644 index 00000000..472db3e6 --- /dev/null +++ b/tasks/registry-mock/src/registry_anchor.rs @@ -0,0 +1,147 @@ +use crate::{kill_verdaccio::kill_all_verdaccio_children, MockInstanceOptions, RegistryInfo}; +use advisory_lock::{AdvisoryFileLock, FileLockError, FileLockMode}; +use pipe_trait::Pipe; +use serde::{Deserialize, Serialize}; +use std::{ + env::temp_dir, + fs::{self, File, OpenOptions}, + mem::forget, + path::{Path, PathBuf}, + sync::OnceLock, +}; +use sysinfo::{Pid, PidExt, Signal}; + +/// Count references and automatically manage a single shared mocked registry server instance that is spawn +/// by the first test to run. +/// +/// The reference counter increases on [load](RegistryAnchor::load_or_init) and decreases on [drop](Drop). +#[derive(Debug, Deserialize, Serialize)] +pub struct RegistryAnchor { + pub ref_count: u32, + pub info: RegistryInfo, +} + +impl Drop for RegistryAnchor { + fn drop(&mut self) { + // information from self is outdated, do not use it. + + let guard = GuardFile::lock(); + + // load an up-to-date anchor, it is leaked to prevent dropping (again). + let anchor = RegistryAnchor::load().pipe(Box::new).pipe(Box::leak); + if self.info != anchor.info { + eprintln!("info: {:?} is outdated. Skip.", &self.info); + return; + } + + if let Some(ref_count) = anchor.ref_count.checked_sub(1) { + anchor.ref_count = ref_count; + anchor.save(); + if ref_count > 0 { + eprintln!("info: The mocked server is still used by {ref_count} users. Skip."); + return; + } + } + + let pid = anchor.info.pid; + eprintln!("info: There are no more users that use the mocked server"); + eprintln!("info: Terminating all verdaccio instances below {pid}..."); + let kill_count = kill_all_verdaccio_children(Pid::from_u32(pid), Signal::Interrupt); + eprintln!("info: Terminated {kill_count} verdaccio instances"); + + RegistryAnchor::delete(); + guard.unlock(); + } +} + +impl RegistryAnchor { + fn path() -> &'static Path { + static PATH: OnceLock = OnceLock::new(); + PATH.get_or_init(|| temp_dir().join("pacquet-registry-mock-anchor.json")) + } + + fn load() -> Self { + RegistryAnchor::path() + .pipe(fs::read_to_string) + .expect("read the anchor") + .pipe_as_ref(serde_json::from_str) + .expect("parse anchor") + } + + fn save(&self) { + let text = serde_json::to_string_pretty(self).expect("convert anchor to JSON"); + fs::write(RegistryAnchor::path(), text).expect("write to anchor"); + } + + pub fn load_or_init(init_options: MockInstanceOptions<'_>) -> Self { + if let Some(guard) = GuardFile::try_lock() { + let mock_instance = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("build tokio runtime") + .block_on(init_options.spawn()); + let port = init_options.port; + let pid = mock_instance.process.id(); + let info = RegistryInfo { port, pid }; + let anchor = RegistryAnchor { ref_count: 1, info }; + anchor.save(); + guard.unlock(); + forget(mock_instance); // prevent this process from killing itself on drop + anchor + } else { + let guard = GuardFile::lock(); + let mut anchor = RegistryAnchor::load(); + anchor.ref_count = anchor.ref_count.checked_add(1).expect("increment ref_count"); + anchor.save(); + guard.unlock(); + anchor + } + } + + fn delete() { + if let Err(error) = fs::remove_file(RegistryAnchor::path()) { + eprintln!("warn: Failed to delete the anchor file: {error}"); + } + } +} + +/// Prevent race condition between multiple tests. +#[must_use] +struct GuardFile; + +impl Drop for GuardFile { + fn drop(&mut self) { + GuardFile::path().unlock().expect("release file guard"); + } +} + +impl GuardFile { + fn path() -> &'static File { + static PATH: OnceLock = OnceLock::new(); + PATH.get_or_init(|| { + OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(temp_dir().join("pacquet-registry-mock-anchor.lock")) + .expect("open the guard file") + }) + } + + fn lock() -> Self { + GuardFile::path().lock(FileLockMode::Exclusive).expect("acquire file guard"); + GuardFile + } + + fn try_lock() -> Option { + match GuardFile::path().try_lock(FileLockMode::Exclusive) { + Ok(()) => Some(GuardFile), + Err(FileLockError::AlreadyLocked) => None, + Err(FileLockError::Io(error)) => panic!("Failed to acquire the file guard: {error}"), + } + } + + fn unlock(self) { + drop(self) + } +} diff --git a/tasks/registry-mock/src/registry_info.rs b/tasks/registry-mock/src/registry_info.rs new file mode 100644 index 00000000..0e8a7e5d --- /dev/null +++ b/tasks/registry-mock/src/registry_info.rs @@ -0,0 +1,89 @@ +use crate::{ + kill_verdaccio::kill_all_verdaccio_children, port_to_url::port_to_url, MockInstanceOptions, +}; +use pipe_trait::Pipe; +use serde::{Deserialize, Serialize}; +use std::{ + env::temp_dir, + fs, + io::ErrorKind, + mem::forget, + path::{Path, PathBuf}, + sync::OnceLock, +}; +use sysinfo::{Pid, PidExt, Signal}; + +/// Information of a spawned mocked registry server instance. +#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct RegistryInfo { + pub port: u16, + pub pid: u32, +} + +impl RegistryInfo { + pub fn url(&self) -> String { + port_to_url(self.port) + } +} + +/// Manage a single shared mocked registry server instance that is spawned by +/// the CLI command. +#[derive(Debug, Deserialize, Serialize)] +pub struct PreparedRegistryInfo { + pub info: RegistryInfo, +} + +impl PreparedRegistryInfo { + fn path() -> &'static Path { + static PATH: OnceLock = OnceLock::new(); + PATH.get_or_init(|| temp_dir().join("pacquet-registry-mock-prepared-registry-info.json")) + } + + pub fn try_load() -> Option { + match PreparedRegistryInfo::path().pipe(fs::read_to_string) { + Ok(text) => text + .pipe_as_ref(serde_json::from_str::) + .expect("parse prepared registry info") + .pipe(Some), + Err(error) if error.kind() == ErrorKind::NotFound => None, + Err(error) => panic!("Failed to load prepared registry info: {error}"), + } + } + + fn save(&self) { + let text = serde_json::to_string_pretty(self).expect("convert anchor to JSON"); + fs::write(PreparedRegistryInfo::path(), text).expect("write to anchor"); + } + + fn delete() { + fs::remove_file(PreparedRegistryInfo::path()).expect("delete prepared registry info") + } + + pub async fn launch(options: MockInstanceOptions<'_>) -> Self { + if let Some(prepared) = PreparedRegistryInfo::try_load() { + eprintln!("warn: Already launched. Skip."); + return prepared; + } + + let port = options.port; + let mock_instance = options.spawn().await; + let pid = mock_instance.process.id(); + let info = RegistryInfo { port, pid }; + let prepared = PreparedRegistryInfo { info }; + prepared.save(); + forget(mock_instance); // prevent this process from killing itself on drop + prepared + } + + pub fn end() -> Option { + let prepared = PreparedRegistryInfo::try_load()?; + let pid = prepared.info.pid; + + eprintln!("info: Terminating all verdaccio instances below {pid}..."); + let kill_count = kill_all_verdaccio_children(Pid::from_u32(pid), Signal::Interrupt); + eprintln!("info: Terminated {kill_count} verdaccio instances"); + + PreparedRegistryInfo::delete(); + Some(prepared) + } +}