From 505b0cdb6f2f6c1507251b33df0d6850eb59893a Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Fri, 28 Jun 2024 21:21:18 -0600 Subject: [PATCH 01/31] Getting warmer. --- crates/turborepo-ui/src/tui/app.rs | 52 +- crates/turborepo-ui/src/tui/table.rs | 248 +- .../.eslintrc.js | 4 + .../child/child.js | 2 + .../package-lock.json | 1998 +++++++++++++++++ .../package.json | 6 + .../peer.js | 1 + .../turbo.json | 35 + .../apps/docs/package.json | 11 + .../apps/web/package.json | 11 + .../package-lock.json | 385 ++++ .../package.json | 16 + .../packages/tsconfig/package.json | 5 + .../packages/ui/package.json | 7 + 14 files changed, 2633 insertions(+), 148 deletions(-) create mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js create mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js create mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json create mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json create mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js create mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json create mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json create mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json create mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json create mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json create mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json create mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index e5a05f51f7fa4..5f6ee5cf1ef89 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -15,6 +15,12 @@ const PANE_SIZE_RATIO: f32 = 3.0 / 4.0; const FRAMERATE: Duration = Duration::from_millis(3); use super::{input, AppReceiver, Error, Event, InputOptions, TaskTable, TerminalPane}; +use crate::tui::task::Task; + +pub enum LayoutSections { + Pane, + TaskList, +} pub struct App { table: TaskTable, @@ -22,6 +28,9 @@ pub struct App { done: bool, input_options: InputOptions, started_tasks: Vec, + task_list: Vec, + selected_task_index: usize, + layout_focus: LayoutSections, } pub enum Direction { @@ -32,9 +41,17 @@ pub enum Direction { impl App { pub fn new(rows: u16, cols: u16, tasks: Vec) -> Self { debug!("tasks: {tasks:?}"); + let num_of_tasks = tasks.len(); - let mut this = Self { - table: TaskTable::new(tasks.clone()), + // TODO: Probably can manage this better? + let task_list = tasks.clone(); + + let mut planned_task_list = tasks.into_iter().map(Task::new).collect::>(); + planned_task_list.sort_unstable(); + planned_task_list.dedup(); + + Self { + table: TaskTable::new(planned_task_list.clone()), pane: TerminalPane::new(rows, cols, tasks), done: false, input_options: InputOptions { @@ -43,24 +60,31 @@ impl App { tty_stdin: atty::is(atty::Stream::Stdin), }, started_tasks: Vec::with_capacity(num_of_tasks), - }; - // Start with first task selected - this.next(); - this + task_list, + selected_task_index: 0, + layout_focus: LayoutSections::Pane, + } } pub fn next(&mut self) { - self.table.next(); - if let Some(task) = self.table.selected() { - self.pane.select(task).unwrap(); - } + let num_rows = self.table.len(); + let i = match self.table.scroll.selected() { + Some(i) => (i + 1).clamp(0, num_rows - 1), + None => 0, + }; + self.table.scroll.select(Some(i)); + let task = self.task_list[i].as_str(); + self.pane.select(task).unwrap(); } pub fn previous(&mut self) { - self.table.previous(); - if let Some(task) = self.table.selected() { - self.pane.select(task).unwrap(); - } + let i = match self.selected_task_index { + 0 => 0, + i => i - 1, + }; + self.table.scroll.select(Some(i)); + let task = self.task_list[i].as_str(); + self.pane.select(task).unwrap(); } pub fn interact(&mut self, interact: bool) { diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index 50611991e2dae..be200ff2fa158 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -26,7 +26,7 @@ pub struct TaskTable { // Ordered by task name planned: Vec>, // State used for showing things - scroll: TableState, + pub scroll: TableState, spinner: SpinnerState, } @@ -161,26 +161,6 @@ impl TaskTable { self.spinner.update(); } - /// Select the next row - pub fn next(&mut self) { - let num_rows = self.len(); - let i = match self.scroll.selected() { - Some(i) => (i + 1).clamp(0, num_rows - 1), - None => 0, - }; - self.scroll.select(Some(i)); - } - - /// Select the previous row - pub fn previous(&mut self) { - let i = match self.scroll.selected() { - Some(0) => 0, - Some(i) => i - 1, - None => 0, - }; - self.scroll.select(Some(i)); - } - pub fn get(&self, i: usize) -> Option<&str> { if i < self.finished.len() { let task = self.finished.get(i)?; @@ -287,116 +267,116 @@ impl<'a> StatefulWidget for &'a TaskTable { StatefulWidget::render(table, area, buf, state); } } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_scroll() { - let mut table = TaskTable::new(vec![ - "foo".to_string(), - "bar".to_string(), - "baz".to_string(), - ]); - assert_eq!(table.scroll.selected(), None, "starts with no selection"); - table.next(); - assert_eq!(table.scroll.selected(), Some(0), "scroll starts from 0"); - table.previous(); - assert_eq!(table.scroll.selected(), Some(0), "scroll stays in bounds"); - table.next(); - table.next(); - assert_eq!(table.scroll.selected(), Some(2), "scroll moves forwards"); - table.next(); - assert_eq!(table.scroll.selected(), Some(2), "scroll stays in bounds"); - } - - #[test] - fn test_selection_follows() { - let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), "c".to_string()]); - table.next(); - table.next(); - assert_eq!(table.scroll.selected(), Some(1), "selected b"); - assert_eq!(table.selected(), Some("b"), "selected b"); - table.start_task("b").unwrap(); - assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); - assert_eq!(table.selected(), Some("b"), "selected b"); - table.start_task("a").unwrap(); - assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); - assert_eq!(table.selected(), Some("b"), "selected b"); - table.finish_task("a", TaskResult::Success).unwrap(); - assert_eq!(table.scroll.selected(), Some(1), "b stays selected"); - assert_eq!(table.selected(), Some("b"), "selected b"); - } - - #[test] - fn test_restart_task() { - let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), "c".to_string()]); - table.next(); - table.next(); - // Start all tasks - table.start_task("b").unwrap(); - table.start_task("a").unwrap(); - table.start_task("c").unwrap(); - assert_eq!(table.get(0), Some("b"), "b is on top (running)"); - table.finish_task("a", TaskResult::Success).unwrap(); - assert_eq!( - (table.get(0), table.get(1)), - (Some("a"), Some("b")), - "a is on top (done), b is second (running)" - ); - - table.finish_task("b", TaskResult::Success).unwrap(); - assert_eq!( - (table.get(0), table.get(1)), - (Some("a"), Some("b")), - "a is on top (done), b is second (done)" - ); - - // Restart b - table.start_task("b").unwrap(); - assert_eq!( - (table.get(1), table.get(2)), - (Some("c"), Some("b")), - "b is third (running)" - ); - - // Restart a - table.start_task("a").unwrap(); - assert_eq!( - (table.get(0), table.get(1), table.get(2)), - (Some("c"), Some("b"), Some("a")), - "c is on top (running), b is second (running), a is third (running)" - ); - } - - #[test] - fn test_selection_stable() { - let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), "c".to_string()]); - table.next(); - table.next(); - assert_eq!(table.scroll.selected(), Some(1), "selected b"); - assert_eq!(table.selected(), Some("b"), "selected b"); - // start c which moves it to "running" which is before "planned" - table.start_task("c").unwrap(); - assert_eq!(table.scroll.selected(), Some(2), "selection stays on b"); - assert_eq!(table.selected(), Some("b"), "selected b"); - table.start_task("a").unwrap(); - assert_eq!(table.scroll.selected(), Some(2), "selection stays on b"); - assert_eq!(table.selected(), Some("b"), "selected b"); - // c - // a - // b <- - table.previous(); - table.previous(); - assert_eq!(table.scroll.selected(), Some(0), "selected c"); - assert_eq!(table.selected(), Some("c"), "selected c"); - table.finish_task("a", TaskResult::Success).unwrap(); - assert_eq!(table.scroll.selected(), Some(1), "c stays selected"); - assert_eq!(table.selected(), Some("c"), "selected c"); - table.previous(); - table.finish_task("c", TaskResult::Success).unwrap(); - assert_eq!(table.scroll.selected(), Some(0), "a stays selected"); - assert_eq!(table.selected(), Some("a"), "selected a"); - } -} +// +// #[cfg(test)] +// mod test { +// use super::*; +// +// #[test] +// fn test_scroll() { +// let mut table = TaskTable::new(vec![ +// "foo".to_string(), +// "bar".to_string(), +// "baz".to_string(), +// ]); +// assert_eq!(table.scroll.selected(), None, "starts with no +// selection"); table.next(); +// assert_eq!(table.scroll.selected(), Some(0), "scroll starts from 0"); +// table.previous(); +// assert_eq!(table.scroll.selected(), Some(0), "scroll stays in +// bounds"); table.next(); +// table.next(); +// assert_eq!(table.scroll.selected(), Some(2), "scroll moves +// forwards"); table.next(); +// assert_eq!(table.scroll.selected(), Some(2), "scroll stays in +// bounds"); } +// +// #[test] +// fn test_selection_follows() { +// let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), +// "c".to_string()]); table.next(); +// table.next(); +// assert_eq!(table.scroll.selected(), Some(1), "selected b"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// table.start_task("b").unwrap(); +// assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// table.start_task("a").unwrap(); +// assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// table.finish_task("a", TaskResult::Success).unwrap(); +// assert_eq!(table.scroll.selected(), Some(1), "b stays selected"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// } +// +// #[test] +// fn test_restart_task() { +// let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), +// "c".to_string()]); table.next(); +// table.next(); +// // Start all tasks +// table.start_task("b").unwrap(); +// table.start_task("a").unwrap(); +// table.start_task("c").unwrap(); +// assert_eq!(table.get(0), Some("b"), "b is on top (running)"); +// table.finish_task("a", TaskResult::Success).unwrap(); +// assert_eq!( +// (table.get(0), table.get(1)), +// (Some("a"), Some("b")), +// "a is on top (done), b is second (running)" +// ); +// +// table.finish_task("b", TaskResult::Success).unwrap(); +// assert_eq!( +// (table.get(0), table.get(1)), +// (Some("a"), Some("b")), +// "a is on top (done), b is second (done)" +// ); +// +// // Restart b +// table.start_task("b").unwrap(); +// assert_eq!( +// (table.get(1), table.get(2)), +// (Some("c"), Some("b")), +// "b is third (running)" +// ); +// +// // Restart a +// table.start_task("a").unwrap(); +// assert_eq!( +// (table.get(0), table.get(1), table.get(2)), +// (Some("c"), Some("b"), Some("a")), +// "c is on top (running), b is second (running), a is third +// (running)" ); +// } +// +// #[test] +// fn test_selection_stable() { +// let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), +// "c".to_string()]); table.next(); +// table.next(); +// assert_eq!(table.scroll.selected(), Some(1), "selected b"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// // start c which moves it to "running" which is before "planned" +// table.start_task("c").unwrap(); +// assert_eq!(table.scroll.selected(), Some(2), "selection stays on b"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// table.start_task("a").unwrap(); +// assert_eq!(table.scroll.selected(), Some(2), "selection stays on b"); +// assert_eq!(table.selected(), Some("b"), "selected b"); +// // c +// // a +// // b <- +// table.previous(); +// table.previous(); +// assert_eq!(table.scroll.selected(), Some(0), "selected c"); +// assert_eq!(table.selected(), Some("c"), "selected c"); +// table.finish_task("a", TaskResult::Success).unwrap(); +// assert_eq!(table.scroll.selected(), Some(1), "c stays selected"); +// assert_eq!(table.selected(), Some("c"), "selected c"); +// table.previous(); +// table.finish_task("c", TaskResult::Success).unwrap(); +// assert_eq!(table.scroll.selected(), Some(0), "a stays selected"); +// assert_eq!(table.selected(), Some("a"), "selected a"); +// } +// } diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js new file mode 100644 index 0000000000000..8dc66dca7067c --- /dev/null +++ b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ["plugin:turbo/recommended"], +}; diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js new file mode 100644 index 0000000000000..9e799a23c8a10 --- /dev/null +++ b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js @@ -0,0 +1,2 @@ +process.env.NONEXISTENT; +process.env.CI; diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json new file mode 100644 index 0000000000000..ca2acbac18aeb --- /dev/null +++ b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json @@ -0,0 +1,1998 @@ +{ + "name": "57acaa2d-c403-452b-b550-f134ce0c8ddd", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "eslint": "8.57.0", + "eslint-plugin-turbo": "../../" + } + }, + "../..": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "dotenv": "16.0.3" + }, + "devDependencies": { + "@turbo/eslint-config": "workspace:*", + "@turbo/test-utils": "workspace:*", + "@turbo/tsconfig": "workspace:*", + "@turbo/types": "workspace:*", + "@turbo/utils": "workspace:*", + "@types/eslint": "^8.4.5", + "@types/estree": "^1.0.0", + "@types/jest": "^27.4.0", + "@types/node": "^18.17.2", + "jest": "^27.4.3", + "json5": "^2.2.1", + "ts-jest": "^27.1.1", + "tsup": "^6.2.0", + "typescript": "5.3.3" + }, + "peerDependencies": { + "eslint": ">6.6.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-turbo": { + "resolved": "../..", + "link": true + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + } + }, + "eslint-plugin-turbo": { + "version": "file:../..", + "requires": { + "@turbo/eslint-config": "workspace:*", + "@turbo/test-utils": "workspace:*", + "@turbo/tsconfig": "workspace:*", + "@turbo/types": "workspace:*", + "@turbo/utils": "workspace:*", + "@types/eslint": "^8.4.5", + "@types/estree": "^1.0.0", + "@types/jest": "^27.4.0", + "@types/node": "^18.17.2", + "dotenv": "16.0.3", + "jest": "^27.4.3", + "json5": "^2.2.1", + "ts-jest": "^27.1.1", + "tsup": "^6.2.0", + "typescript": "5.3.3" + } + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json new file mode 100644 index 0000000000000..4dca370603c1b --- /dev/null +++ b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "eslint": "8.57.0", + "eslint-plugin-turbo": "../../" + } +} diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js new file mode 100644 index 0000000000000..16c8bb0522bbf --- /dev/null +++ b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js @@ -0,0 +1 @@ +process.env.CI; diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json new file mode 100644 index 0000000000000..6c6bcf357d80a --- /dev/null +++ b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalEnv": ["UNORDERED", "CI"], + "globalDotEnv": [".env", "missing.env"], + "pipeline": { + "build": { + // A workspace's `build` task depends on that workspace's + // topological dependencies' and devDependencies' + // `build` tasks being completed first. The `^` symbol + // indicates an upstream dependency. + "dependsOn": ["^build"] + }, + "test": { + // A workspace's `test` task depends on that workspace's + // own `build` task being completed first. + "dependsOn": ["build"], + "outputs": [], + // A workspace's `test` task should only be rerun when + // either a `.tsx` or `.ts` file has changed. + "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] + }, + "lint": { + // A workspace's `lint` task has no dependencies and + // can be run whenever. + "outputs": [] + }, + "deploy": { + // A workspace's `deploy` task depends on the `build`, + // `test`, and `lint` tasks of the same workspace + // being completed. + "dependsOn": ["build", "test", "lint"], + "outputs": [] + } + } +} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json new file mode 100644 index 0000000000000..e488bc3f07164 --- /dev/null +++ b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json @@ -0,0 +1,11 @@ +{ + "name": "docs", + "version": "1.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "1.0.0" + } +} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json new file mode 100644 index 0000000000000..163cee3e51e6c --- /dev/null +++ b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json @@ -0,0 +1,11 @@ +{ + "name": "web", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json new file mode 100644 index 0000000000000..6b6842b925119 --- /dev/null +++ b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json @@ -0,0 +1,385 @@ +{ + "name": "npm-workspaces", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "npm-workspaces", + "version": "0.0.0", + "workspaces": [ + "apps/*", + "packages/*" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "apps/docs": { + "version": "1.0.0", + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "1.0.0" + } + }, + "apps/docs/node_modules/tsconfig": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-1.0.0.tgz", + "integrity": "sha512-26lVKF/0MdkCnaU9t45wH8bsVH8nRKRt0zrvku/j/dD5uE+8v9vDfBS8/sVRs6ZjADXbcFvirN93kOpxdIszqQ==", + "dev": true, + "dependencies": { + "globby": "^2.1.0", + "xtend": "^4.0.0" + } + }, + "apps/web": { + "version": "0.0.0", + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/docs": { + "resolved": "apps/docs", + "link": true + }, + "node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globby": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-2.1.0.tgz", + "integrity": "sha512-CqRID2dMaN4Zi9PANiQHhmKaGu7ZASehBLnaDogjR9L3L1EqAGFhflafT0IrSN/zm9xFk+KMTXZCN8pUYOiO/Q==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "async": "^1.2.1", + "glob": "^5.0.3", + "object-assign": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tsconfig": { + "resolved": "packages/tsconfig", + "link": true + }, + "node_modules/ui": { + "resolved": "packages/ui", + "link": true + }, + "node_modules/web": { + "resolved": "apps/web", + "link": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "packages/tsconfig": { + "version": "1.0.0" + }, + "packages/ui": { + "version": "0.0.0", + "devDependencies": { + "tsconfig": "*" + } + } + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "docs": { + "version": "file:apps/docs", + "requires": { + "tsconfig": "1.0.0", + "ui": "*" + }, + "dependencies": { + "tsconfig": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-1.0.0.tgz", + "integrity": "sha512-26lVKF/0MdkCnaU9t45wH8bsVH8nRKRt0zrvku/j/dD5uE+8v9vDfBS8/sVRs6ZjADXbcFvirN93kOpxdIszqQ==", + "dev": true, + "requires": { + "globby": "^2.1.0", + "xtend": "^4.0.0" + } + } + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-2.1.0.tgz", + "integrity": "sha512-CqRID2dMaN4Zi9PANiQHhmKaGu7ZASehBLnaDogjR9L3L1EqAGFhflafT0IrSN/zm9xFk+KMTXZCN8pUYOiO/Q==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "async": "^1.2.1", + "glob": "^5.0.3", + "object-assign": "^3.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "tsconfig": { + "version": "file:packages/tsconfig" + }, + "ui": { + "version": "file:packages/ui", + "requires": { + "tsconfig": "*" + } + }, + "web": { + "version": "file:apps/web", + "requires": { + "tsconfig": "*", + "ui": "*" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + } + } +} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json new file mode 100644 index 0000000000000..3efdede615717 --- /dev/null +++ b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json @@ -0,0 +1,16 @@ +{ + "name": "npm-workspaces", + "version": "0.0.0", + "private": true, + "workspaces": { + "packages": [ + "apps/*", + "packages/*" + ] + }, + "engines": { + "node": ">=14.0.0" + }, + "dependencies": {}, + "packageManager": "npm@8.19.4" +} \ No newline at end of file diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json new file mode 100644 index 0000000000000..0d32af30031af --- /dev/null +++ b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json @@ -0,0 +1,5 @@ +{ + "name": "tsconfig", + "version": "1.0.0", + "private": true +} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json new file mode 100644 index 0000000000000..1e05d1a8ecc65 --- /dev/null +++ b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json @@ -0,0 +1,7 @@ +{ + "name": "ui", + "version": "0.0.0", + "devDependencies": { + "tsconfig": "*" + } +} From 4308fb9eb8528bc294af66d137fe56480cef6f62 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Fri, 28 Jun 2024 22:09:12 -0600 Subject: [PATCH 02/31] Hoist state, handle scrolling. --- crates/turborepo-ui/src/tui/app.rs | 51 ++++++++++--------- crates/turborepo-ui/src/tui/table.rs | 7 ++- crates/turborepo-ui/src/tui/task.rs | 6 +++ .../apps/docs/package.json | 11 ++++ .../apps/web/package.json | 11 ++++ .../packages/tsconfig/package.json | 5 ++ .../packages/ui/package.json | 7 +++ .../package.json | 8 +++ .../pnpm-lock.yaml | 33 ++++++++++++ .../apps/docs/package.json | 11 ++++ .../apps/web/package.json | 11 ++++ .../package.json | 14 +++++ .../packages/tsconfig/package.json | 5 ++ .../packages/ui/package.json | 7 +++ .../yarn.lock | 4 ++ 15 files changed, 166 insertions(+), 25 deletions(-) create mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json create mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json create mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json create mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json create mode 100644 packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json create mode 100644 packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml create mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json create mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json create mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json create mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json create mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json create mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 5f6ee5cf1ef89..f5168d1047f34 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -43,15 +43,24 @@ impl App { debug!("tasks: {tasks:?}"); let num_of_tasks = tasks.len(); - // TODO: Probably can manage this better? - let task_list = tasks.clone(); - let mut planned_task_list = tasks.into_iter().map(Task::new).collect::>(); - planned_task_list.sort_unstable(); - planned_task_list.dedup(); + // Initializes with the planned tasks + // and will mutate as tasks change their stateful_render + // to running, finished, etc. + let mut task_list = tasks + // TODO: Is cloning bad? + .clone() + .into_iter() + .map(Task::new) + .map(|task| task.name().to_string()) + .collect::>(); + task_list.sort_unstable(); + task_list.dedup(); + + let mut selected_task_index = 0; Self { - table: TaskTable::new(planned_task_list.clone()), + table: TaskTable::new(task_list.clone(), selected_task_index), pane: TerminalPane::new(rows, cols, tasks), done: false, input_options: InputOptions { @@ -61,19 +70,17 @@ impl App { }, started_tasks: Vec::with_capacity(num_of_tasks), task_list, - selected_task_index: 0, + selected_task_index, layout_focus: LayoutSections::Pane, } } pub fn next(&mut self) { - let num_rows = self.table.len(); - let i = match self.table.scroll.selected() { - Some(i) => (i + 1).clamp(0, num_rows - 1), - None => 0, - }; - self.table.scroll.select(Some(i)); - let task = self.task_list[i].as_str(); + let num_rows = self.task_list.len(); + let next_index = (self.selected_task_index + 1).clamp(0, num_rows - 1); + self.selected_task_index = next_index; + self.table.scroll.select(Some(next_index)); + let task = self.task_list[next_index].as_str(); self.pane.select(task).unwrap(); } @@ -82,27 +89,25 @@ impl App { 0 => 0, i => i - 1, }; + self.selected_task_index = i; self.table.scroll.select(Some(i)); let task = self.task_list[i].as_str(); self.pane.select(task).unwrap(); } pub fn interact(&mut self, interact: bool) { - let Some(selected_task) = self.table.selected() else { - return; - }; - if self.pane.has_stdin(selected_task) { + if self + .pane + .has_stdin(self.task_list[self.selected_task_index].as_str()) + { self.input_options.interact = interact; self.pane.highlight(interact); } } pub fn scroll(&mut self, direction: Direction) { - let Some(selected_task) = self.table.selected() else { - return; - }; self.pane - .scroll(selected_task, direction) + .scroll(self.task_list[self.selected_task_index].as_str(), direction) .expect("selected task should be in pane"); } @@ -111,7 +116,7 @@ impl App { } pub fn update_tasks(&mut self, tasks: Vec) { - self.table = TaskTable::new(tasks.clone()); + self.table = TaskTable::new(tasks.clone(), self.selected_task_index); self.next(); } } diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index be200ff2fa158..82d9dfa70df61 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -28,15 +28,17 @@ pub struct TaskTable { // State used for showing things pub scroll: TableState, spinner: SpinnerState, + selected_index: usize, } impl TaskTable { /// Construct a new table with all of the planned tasks - pub fn new(tasks: impl IntoIterator) -> Self { + pub fn new(tasks: Vec, selected_index: usize) -> Self { let mut planned = tasks.into_iter().map(Task::new).collect::>(); planned.sort_unstable(); planned.dedup(); Self { + selected_index, planned, running: Vec::new(), finished: Vec::new(), @@ -237,6 +239,7 @@ impl<'a> StatefulWidget for &'a TaskTable { fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer, state: &mut Self::State) { let width = area.width; + let active_index = self.selected_index; let bar = "─".repeat(usize::from(width)); let table = Table::new( self.finished_rows() @@ -251,7 +254,7 @@ impl<'a> StatefulWidget for &'a TaskTable { .highlight_style(Style::default().fg(Color::Yellow)) .column_spacing(0) .header( - vec![format!("Tasks\n{bar}"), " \n─".to_owned()] + vec![format!("Tasks {active_index}\n{bar}"), " \n─".to_owned()] .into_iter() .map(Cell::from) .collect::() diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index 9f514bc7b8697..88accd8a917ef 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -24,6 +24,12 @@ pub struct Task { state: S, } +pub enum TaskType { + Planned, + Running, + Finished, +} + impl Task { pub fn name(&self) -> &str { &self.name diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json new file mode 100644 index 0000000000000..835a58fb23458 --- /dev/null +++ b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json @@ -0,0 +1,11 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "workspace:*" + }, + "devDependencies": { + "tsconfig": "workspace:*" + } +} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json new file mode 100644 index 0000000000000..77c2e0f4bff49 --- /dev/null +++ b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json @@ -0,0 +1,11 @@ +{ + "name": "web", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "workspace:*" + }, + "devDependencies": { + "tsconfig": "workspace:*" + } +} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json new file mode 100644 index 0000000000000..3f406290b4667 --- /dev/null +++ b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json @@ -0,0 +1,5 @@ +{ + "name": "tsconfig", + "version": "0.0.0", + "private": true +} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json new file mode 100644 index 0000000000000..601ca4a8381ee --- /dev/null +++ b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json @@ -0,0 +1,7 @@ +{ + "name": "ui", + "version": "0.0.0", + "devDependencies": { + "tsconfig": "workspace:*" + } +} diff --git a/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json b/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json new file mode 100644 index 0000000000000..00885fa1e0a9f --- /dev/null +++ b/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json @@ -0,0 +1,8 @@ +{ + "name": "pnpm", + "version": "0.0.0", + "private": true, + "dependencies": {}, + "devDependencies": {}, + "packageManager": "pnpm@7.12.1" +} diff --git a/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml b/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml new file mode 100644 index 0000000000000..84c04af90e76b --- /dev/null +++ b/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml @@ -0,0 +1,33 @@ +lockfileVersion: 5.4 + +importers: + + .: + specifiers: {} + + apps/docs: + specifiers: + tsconfig: workspace:* + ui: workspace:* + dependencies: + ui: link:../../packages/ui + devDependencies: + tsconfig: link:../../packages/tsconfig + + apps/web: + specifiers: + tsconfig: workspace:* + ui: workspace:* + dependencies: + ui: link:../../packages/ui + devDependencies: + tsconfig: link:../../packages/tsconfig + + packages/tsconfig: + specifiers: {} + + packages/ui: + specifiers: + tsconfig: workspace:* + devDependencies: + tsconfig: link:../tsconfig diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json new file mode 100644 index 0000000000000..d3a490ca892f8 --- /dev/null +++ b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json @@ -0,0 +1,11 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json new file mode 100644 index 0000000000000..163cee3e51e6c --- /dev/null +++ b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json @@ -0,0 +1,11 @@ +{ + "name": "web", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json new file mode 100644 index 0000000000000..002944bd73343 --- /dev/null +++ b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json @@ -0,0 +1,14 @@ +{ + "name": "yarn-workspaces", + "version": "0.0.0", + "private": true, + "workspaces": [ + "apps/*", + "packages/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "dependencies": {}, + "packageManager": "yarn@1.22.19" +} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json new file mode 100644 index 0000000000000..3f406290b4667 --- /dev/null +++ b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json @@ -0,0 +1,5 @@ +{ + "name": "tsconfig", + "version": "0.0.0", + "private": true +} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json new file mode 100644 index 0000000000000..1e05d1a8ecc65 --- /dev/null +++ b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json @@ -0,0 +1,7 @@ +{ + "name": "ui", + "version": "0.0.0", + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock new file mode 100644 index 0000000000000..fb57ccd13afbd --- /dev/null +++ b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + From 9595037a316de4e9eb33124628d5c9a54b2693a9 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Sun, 30 Jun 2024 23:04:33 -0600 Subject: [PATCH 03/31] Feeling close. --- crates/turborepo-ui/src/tui/app.rs | 137 +++++++++++++++++--- crates/turborepo-ui/src/tui/table.rs | 179 +++++---------------------- crates/turborepo-ui/src/tui/task.rs | 38 ++++++ 3 files changed, 187 insertions(+), 167 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index f5168d1047f34..40a78ba13ffe6 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -14,8 +14,10 @@ use tracing::debug; const PANE_SIZE_RATIO: f32 = 3.0 / 4.0; const FRAMERATE: Duration = Duration::from_millis(3); -use super::{input, AppReceiver, Error, Event, InputOptions, TaskTable, TerminalPane}; -use crate::tui::task::Task; +use super::{ + event::TaskResult, input, AppReceiver, Error, Event, InputOptions, TaskTable, TerminalPane, +}; +use crate::tui::task::{Task, TasksByStatus}; pub enum LayoutSections { Pane, @@ -29,7 +31,9 @@ pub struct App { input_options: InputOptions, started_tasks: Vec, task_list: Vec, + tasks_by_status: TasksByStatus, selected_task_index: usize, + has_user_interacted: bool, layout_focus: LayoutSections, } @@ -45,22 +49,30 @@ impl App { let num_of_tasks = tasks.len(); // Initializes with the planned tasks - // and will mutate as tasks change their stateful_render + // and will mutate as tasks change // to running, finished, etc. - let mut task_list = tasks - // TODO: Is cloning bad? + let mut task_list = tasks.clone().into_iter().map(Task::new).collect::>(); + task_list.sort_unstable(); + task_list.dedup(); + + // TODO: WIP, I shouldn't need this when I'm done? + let task_list_as_strings = task_list .clone() .into_iter() - .map(Task::new) .map(|task| task.name().to_string()) .collect::>(); - task_list.sort_unstable(); - task_list.dedup(); - let mut selected_task_index = 0; + let tasks_by_status = TasksByStatus { + planned: task_list, + finished: Vec::new(), + running: Vec::new(), + }; + + let has_user_interacted = false; + let selected_task_index: usize = 0; Self { - table: TaskTable::new(task_list.clone(), selected_task_index), + table: TaskTable::new(&tasks_by_status, &selected_task_index, &has_user_interacted), pane: TerminalPane::new(rows, cols, tasks), done: false, input_options: InputOptions { @@ -69,8 +81,10 @@ impl App { tty_stdin: atty::is(atty::Stream::Stdin), }, started_tasks: Vec::with_capacity(num_of_tasks), - task_list, + task_list: task_list_as_strings, + tasks_by_status, selected_task_index, + has_user_interacted, layout_focus: LayoutSections::Pane, } } @@ -95,6 +109,84 @@ impl App { self.pane.select(task).unwrap(); } + /// Mark the given task as started. + /// If planned, pulls it from planned tasks and starts it. + /// If finished, removes from finished and starts again as new task. + pub fn start_task(&mut self, task: &str) -> Result<(), Error> { + // Name of currently highlighted task. + // We will use this after the order switches. + let highlighted_task = + &self.tasks_by_status.task_names_in_displayed_order()[self.selected_task_index]; + + let planned_idx = self + .tasks_by_status + .planned + .iter() + .position(|planned| planned.name() == task) + .ok_or_else(|| { + debug!("could not find '{task}' to start"); + Error::TaskNotFound { name: task.into() } + })?; + + let planned = self.tasks_by_status.planned.remove(planned_idx); + let running = planned.start(); + self.tasks_by_status.running.push(running); + + // If user hasn't interacted, keep highlighting top-most task in list. + if !self.has_user_interacted { + return Ok(()); + } + + // Find the highlighted task from before the list movement in the new list. + if let Ok(new_index_to_highlight) = self + .tasks_by_status + .task_names_in_displayed_order() + .binary_search_by(|task| task.cmp(highlighted_task)) + { + self.selected_task_index = new_index_to_highlight + } + + Ok(()) + } + + /// Mark the given running task as finished + /// Errors if given task wasn't a running task + pub fn finish_task(&mut self, task: &str, result: TaskResult) -> Result<(), Error> { + // Name of currently highlighted task. + // We will use this after the order switches. + let highlighted_task = + &self.tasks_by_status.task_names_in_displayed_order()[self.selected_task_index]; + + let running_idx = self + .tasks_by_status + .running + .iter() + .position(|running| running.name() == task) + .ok_or_else(|| { + debug!("could not find '{task}' to finish"); + Error::TaskNotFound { name: task.into() } + })?; + + let running = self.tasks_by_status.running.remove(running_idx); + self.tasks_by_status.finished.push(running.finish(result)); + + // If user hasn't interacted, keep highlighting top-most task in list. + if !self.has_user_interacted { + return Ok(()); + } + + // Find the highlighted task from before the list movement in the new list. + if let Ok(new_index_to_highlight) = self + .tasks_by_status + .task_names_in_displayed_order() + .binary_search_by(|task| task.cmp(highlighted_task)) + { + self.selected_task_index = new_index_to_highlight + } + + Ok(()) + } + pub fn interact(&mut self, interact: bool) { if self .pane @@ -116,7 +208,15 @@ impl App { } pub fn update_tasks(&mut self, tasks: Vec) { - self.table = TaskTable::new(tasks.clone(), self.selected_task_index); + let mut task_list = tasks.into_iter().map(Task::new).collect::>(); + task_list.sort_unstable(); + task_list.dedup(); + + self.table = TaskTable::new( + &self.tasks_by_status, + &self.selected_task_index, + &self.has_user_interacted, + ); self.next(); } } @@ -127,10 +227,7 @@ impl App { if !self.input_options.interact { return Ok(()); } - let selected_task = self - .table - .selected() - .expect("table should always have task selected"); + let selected_task = self.task_list[self.selected_task_index].as_str(); self.pane.process_input(selected_task, bytes)?; Ok(()) } @@ -255,7 +352,7 @@ fn update( ) -> Result>, Error> { match event { Event::StartTask { task } => { - app.table.start_task(&task)?; + app.start_task(&task)?; app.started_tasks.push(task); } Event::TaskOutput { task, output } => { @@ -275,7 +372,7 @@ fn update( app.table.tick(); } Event::EndTask { task, result } => { - app.table.finish_task(&task, result)?; + app.finish_task(&task, result)?; } Event::Up => { app.previous(); @@ -284,15 +381,19 @@ fn update( app.next(); } Event::ScrollUp => { + app.has_user_interacted = true; app.scroll(Direction::Up); } Event::ScrollDown => { + app.has_user_interacted = true; app.scroll(Direction::Down); } Event::EnterInteractive => { + app.has_user_interacted = true; app.interact(true); } Event::ExitInteractive => { + app.has_user_interacted = true; app.interact(false); } Event::Input { bytes } => { diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index 82d9dfa70df61..fa94961350f44 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -9,7 +9,7 @@ use tracing::debug; use super::{ event::TaskResult, spinner::SpinnerState, - task::{Finished, Planned, Running, Task}, + task::{Task, TasksByStatus}, Error, }; @@ -18,32 +18,26 @@ use super::{ /// The table contains finished tasks, running tasks, and planned tasks rendered /// in that order. pub struct TaskTable { - // Tasks to be displayed - // Ordered by when they finished - finished: Vec>, - // Ordered by when they started - running: Vec>, - // Ordered by task name - planned: Vec>, - // State used for showing things + tasks_by_type: &TasksByStatus, pub scroll: TableState, spinner: SpinnerState, - selected_index: usize, + selected_index: &usize, + user_has_interacted: &bool, } impl TaskTable { /// Construct a new table with all of the planned tasks - pub fn new(tasks: Vec, selected_index: usize) -> Self { - let mut planned = tasks.into_iter().map(Task::new).collect::>(); - planned.sort_unstable(); - planned.dedup(); + pub fn new( + tasks_by_type: &TasksByStatus, + selected_index: &usize, + user_has_interacted: &bool, + ) -> Self { Self { selected_index, - planned, - running: Vec::new(), - finished: Vec::new(), + tasks_by_type, scroll: TableState::default(), spinner: SpinnerState::default(), + user_has_interacted, } } @@ -60,133 +54,14 @@ impl TaskTable { task_name_width + 1 } - /// Number of rows in the table - pub fn len(&self) -> usize { - self.finished.len() + self.running.len() + self.planned.len() - } - - /// If there are no tasks in the table - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// Mark the given task as started. - /// If planned, pulls it from planned tasks and starts it. - /// If finished, removes from finished and starts again as new task. - pub fn start_task(&mut self, task: &str) -> Result<(), Error> { - if let Ok(planned_idx) = self - .planned - .binary_search_by(|planned_task| planned_task.name().cmp(task)) - { - let planned = self.planned.remove(planned_idx); - let old_row_idx = self.finished.len() + self.running.len() + planned_idx; - let new_row_idx = self.finished.len() + self.running.len(); - let running = planned.start(); - self.running.push(running); - - if let Some(selected_idx) = self.scroll.selected() { - // If task that was just started is selected, then update selection to follow - // task - if selected_idx == old_row_idx { - self.scroll.select(Some(new_row_idx)); - } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { - // If the selected task is between the old and new row positions - // then increment the selection index to keep selection the same. - self.scroll.select(Some(selected_idx + 1)); - } - } - } else if let Some(finished_idx) = self - .finished - .iter() - .position(|finished_task| finished_task.name() == task) - { - let finished = self.finished.remove(finished_idx); - let old_row_idx = finished_idx; - let new_row_idx = self.finished.len() + self.running.len(); - let running = Task::new(finished.name().to_string()).start(); - self.running.push(running); - - if let Some(selected_idx) = self.scroll.selected() { - // If task that was just started is selected, then update selection to follow - // task - if selected_idx == old_row_idx { - self.scroll.select(Some(new_row_idx)); - } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { - // If the selected task is between the old and new row positions - // then increment the selection index to keep selection the same. - self.scroll.select(Some(selected_idx + 1)); - } - } - } else { - debug!("could not find '{task}' to start"); - return Err(Error::TaskNotFound { name: task.into() }); - } - - self.tick(); - Ok(()) - } - - /// Mark the given running task as finished - /// Errors if given task wasn't a running task - pub fn finish_task(&mut self, task: &str, result: TaskResult) -> Result<(), Error> { - let running_idx = self - .running - .iter() - .position(|running| running.name() == task) - .ok_or_else(|| { - debug!("could not find '{task}' to finish"); - Error::TaskNotFound { name: task.into() } - })?; - let old_row_idx = self.finished.len() + running_idx; - let new_row_idx = self.finished.len(); - let running = self.running.remove(running_idx); - self.finished.push(running.finish(result)); - - if let Some(selected_row) = self.scroll.selected() { - // If task that was just started is selected, then update selection to follow - // task - if selected_row == old_row_idx { - self.scroll.select(Some(new_row_idx)); - } else if new_row_idx <= selected_row && selected_row < old_row_idx { - // If the selected task is between the old and new row positions then increment - // the selection index to keep selection the same. - self.scroll.select(Some(selected_row + 1)); - } - } - - self.tick(); - Ok(()) - } - /// Update the current time of the table pub fn tick(&mut self) { self.spinner.update(); } - pub fn get(&self, i: usize) -> Option<&str> { - if i < self.finished.len() { - let task = self.finished.get(i)?; - Some(task.name()) - } else if i < self.finished.len() + self.running.len() { - let task = self.running.get(i - self.finished.len())?; - Some(task.name()) - } else if i < self.finished.len() + self.running.len() + self.planned.len() { - let task = self - .planned - .get(i - (self.finished.len() + self.running.len()))?; - Some(task.name()) - } else { - None - } - } - - pub fn selected(&self) -> Option<&str> { - let i = self.scroll.selected()?; - self.get(i) - } - pub fn tasks_started(&self) -> Vec<&str> { let (errors, success): (Vec<_>, Vec<_>) = self + .tasks_by_type .finished .iter() .partition(|task| matches!(task.result(), TaskResult::Failure)); @@ -195,13 +70,13 @@ impl TaskTable { success .into_iter() .map(|task| task.name()) - .chain(self.running.iter().map(|task| task.name())) + .chain(self.tasks_by_type.running.iter().map(|task| task.name())) .chain(errors.into_iter().map(|task| task.name())) .collect() } fn finished_rows(&self) -> impl Iterator + '_ { - self.finished.iter().map(move |task| { + self.tasks_by_type.finished.iter().map(move |task| { Row::new(vec![ Cell::new(task.name()), Cell::new(match task.result() { @@ -214,13 +89,15 @@ impl TaskTable { fn running_rows(&self) -> impl Iterator + '_ { let spinner = self.spinner.current(); - self.running + self.tasks_by_type + .running .iter() .map(move |task| Row::new(vec![Cell::new(task.name()), Cell::new(Text::raw(spinner))])) } fn planned_rows(&self) -> impl Iterator + '_ { - self.planned + self.tasks_by_type + .planned .iter() .map(move |task| Row::new(vec![Cell::new(task.name()), Cell::new(" ")])) } @@ -240,11 +117,12 @@ impl<'a> StatefulWidget for &'a TaskTable { fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer, state: &mut Self::State) { let width = area.width; let active_index = self.selected_index; + let user_has_interacted = self.user_has_interacted; let bar = "─".repeat(usize::from(width)); let table = Table::new( - self.finished_rows() - .chain(self.running_rows()) - .chain(self.planned_rows()), + self.running_rows() + .chain(self.planned_rows()) + .chain(self.finished_rows()), [ Constraint::Min(14), // Status takes one cell to render @@ -254,11 +132,14 @@ impl<'a> StatefulWidget for &'a TaskTable { .highlight_style(Style::default().fg(Color::Yellow)) .column_spacing(0) .header( - vec![format!("Tasks {active_index}\n{bar}"), " \n─".to_owned()] - .into_iter() - .map(Cell::from) - .collect::() - .height(2), + vec![ + format!("Tasks {active_index} {user_has_interacted}\n{bar}"), + " \n─".to_owned(), + ] + .into_iter() + .map(Cell::from) + .collect::() + .height(2), ) .footer( vec![format!("{bar}\n↑ ↓ to navigate"), "─\n ".to_owned()] diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index 88accd8a917ef..e282e25a5c94e 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -30,6 +30,44 @@ pub enum TaskType { Finished, } +#[derive(Clone)] +pub struct TasksByStatus { + pub running: Vec>, + pub planned: Vec>, + pub finished: Vec>, +} + +impl TasksByStatus { + pub fn all_empty(&self) -> bool { + self.planned.is_empty() && self.finished.is_empty() && self.running.is_empty() + } + + pub fn task_names_in_displayed_order(&self) -> Vec { + let running_names = self + .running + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + let planned_names = self + .planned + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + let finished_names = self + .finished + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + + vec![ + running_names.as_slice(), + planned_names.as_slice(), + finished_names.as_slice(), + ] + .concat() + } +} + impl Task { pub fn name(&self) -> &str { &self.name From 806c6890628d7137846bf1259d3edc24a48aa7f3 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Sun, 30 Jun 2024 23:12:07 -0600 Subject: [PATCH 04/31] Begone, weird changes in packages. --- .../.eslintrc.js | 4 - .../child/child.js | 2 - .../package-lock.json | 1998 ----------------- .../package.json | 6 - .../peer.js | 1 - .../turbo.json | 35 - .../apps/docs/package.json | 11 - .../apps/web/package.json | 11 - .../packages/tsconfig/package.json | 5 - .../packages/ui/package.json | 7 - .../apps/docs/package.json | 11 - .../apps/web/package.json | 11 - .../package-lock.json | 385 ---- .../package.json | 16 - .../packages/tsconfig/package.json | 5 - .../packages/ui/package.json | 7 - .../package.json | 8 - .../pnpm-lock.yaml | 33 - .../apps/docs/package.json | 11 - .../apps/web/package.json | 11 - .../package.json | 14 - .../packages/tsconfig/package.json | 5 - .../packages/ui/package.json | 7 - .../yarn.lock | 4 - 24 files changed, 2608 deletions(-) delete mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js delete mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js delete mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json delete mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json delete mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js delete mode 100644 packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json delete mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json delete mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json delete mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json delete mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json delete mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json delete mode 100644 packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml delete mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json delete mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json delete mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js deleted file mode 100644 index 8dc66dca7067c..0000000000000 --- a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - root: true, - extends: ["plugin:turbo/recommended"], -}; diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js deleted file mode 100644 index 9e799a23c8a10..0000000000000 --- a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/child/child.js +++ /dev/null @@ -1,2 +0,0 @@ -process.env.NONEXISTENT; -process.env.CI; diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json deleted file mode 100644 index ca2acbac18aeb..0000000000000 --- a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package-lock.json +++ /dev/null @@ -1,1998 +0,0 @@ -{ - "name": "57acaa2d-c403-452b-b550-f134ce0c8ddd", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "devDependencies": { - "eslint": "8.57.0", - "eslint-plugin-turbo": "../../" - } - }, - "../..": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "dotenv": "16.0.3" - }, - "devDependencies": { - "@turbo/eslint-config": "workspace:*", - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^18.17.2", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "5.3.3" - }, - "peerDependencies": { - "eslint": ">6.6.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-turbo": { - "resolved": "../..", - "link": true - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - } - }, - "eslint-plugin-turbo": { - "version": "file:../..", - "requires": { - "@turbo/eslint-config": "workspace:*", - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^18.17.2", - "dotenv": "16.0.3", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "5.3.3" - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json deleted file mode 100644 index 4dca370603c1b..0000000000000 --- a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "devDependencies": { - "eslint": "8.57.0", - "eslint-plugin-turbo": "../../" - } -} diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js deleted file mode 100644 index 16c8bb0522bbf..0000000000000 --- a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/peer.js +++ /dev/null @@ -1 +0,0 @@ -process.env.CI; diff --git a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json b/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json deleted file mode 100644 index 6c6bcf357d80a..0000000000000 --- a/packages/eslint-plugin-turbo/dce99ea2-f086-4aeb-8b3a-30814acf5283/57acaa2d-c403-452b-b550-f134ce0c8ddd/turbo.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalEnv": ["UNORDERED", "CI"], - "globalDotEnv": [".env", "missing.env"], - "pipeline": { - "build": { - // A workspace's `build` task depends on that workspace's - // topological dependencies' and devDependencies' - // `build` tasks being completed first. The `^` symbol - // indicates an upstream dependency. - "dependsOn": ["^build"] - }, - "test": { - // A workspace's `test` task depends on that workspace's - // own `build` task being completed first. - "dependsOn": ["build"], - "outputs": [], - // A workspace's `test` task should only be rerun when - // either a `.tsx` or `.ts` file has changed. - "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] - }, - "lint": { - // A workspace's `lint` task has no dependencies and - // can be run whenever. - "outputs": [] - }, - "deploy": { - // A workspace's `deploy` task depends on the `build`, - // `test`, and `lint` tasks of the same workspace - // being completed. - "dependsOn": ["build", "test", "lint"], - "outputs": [] - } - } -} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json deleted file mode 100644 index 835a58fb23458..0000000000000 --- a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/docs/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "docs", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "workspace:*" - }, - "devDependencies": { - "tsconfig": "workspace:*" - } -} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json deleted file mode 100644 index 77c2e0f4bff49..0000000000000 --- a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/apps/web/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "web", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "workspace:*" - }, - "devDependencies": { - "tsconfig": "workspace:*" - } -} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json deleted file mode 100644 index 3f406290b4667..0000000000000 --- a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/tsconfig/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "tsconfig", - "version": "0.0.0", - "private": true -} diff --git a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json b/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json deleted file mode 100644 index 601ca4a8381ee..0000000000000 --- a/packages/turbo-workspaces/01659637-71c1-49a7-b186-3960adf8c7c8/9927992e-efd2-4200-bbc4-e07e2e523c1f/packages/ui/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ui", - "version": "0.0.0", - "devDependencies": { - "tsconfig": "workspace:*" - } -} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json deleted file mode 100644 index e488bc3f07164..0000000000000 --- a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/docs/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "1.0.0" - } -} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json deleted file mode 100644 index 163cee3e51e6c..0000000000000 --- a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/apps/web/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "web", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json deleted file mode 100644 index 6b6842b925119..0000000000000 --- a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package-lock.json +++ /dev/null @@ -1,385 +0,0 @@ -{ - "name": "npm-workspaces", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "npm-workspaces", - "version": "0.0.0", - "workspaces": [ - "apps/*", - "packages/*" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "apps/docs": { - "version": "1.0.0", - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "1.0.0" - } - }, - "apps/docs/node_modules/tsconfig": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-1.0.0.tgz", - "integrity": "sha512-26lVKF/0MdkCnaU9t45wH8bsVH8nRKRt0zrvku/j/dD5uE+8v9vDfBS8/sVRs6ZjADXbcFvirN93kOpxdIszqQ==", - "dev": true, - "dependencies": { - "globby": "^2.1.0", - "xtend": "^4.0.0" - } - }, - "apps/web": { - "version": "0.0.0", - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } - }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/docs": { - "resolved": "apps/docs", - "link": true - }, - "node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globby": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-2.1.0.tgz", - "integrity": "sha512-CqRID2dMaN4Zi9PANiQHhmKaGu7ZASehBLnaDogjR9L3L1EqAGFhflafT0IrSN/zm9xFk+KMTXZCN8pUYOiO/Q==", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "async": "^1.2.1", - "glob": "^5.0.3", - "object-assign": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tsconfig": { - "resolved": "packages/tsconfig", - "link": true - }, - "node_modules/ui": { - "resolved": "packages/ui", - "link": true - }, - "node_modules/web": { - "resolved": "apps/web", - "link": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "packages/tsconfig": { - "version": "1.0.0" - }, - "packages/ui": { - "version": "0.0.0", - "devDependencies": { - "tsconfig": "*" - } - } - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "docs": { - "version": "file:apps/docs", - "requires": { - "tsconfig": "1.0.0", - "ui": "*" - }, - "dependencies": { - "tsconfig": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-1.0.0.tgz", - "integrity": "sha512-26lVKF/0MdkCnaU9t45wH8bsVH8nRKRt0zrvku/j/dD5uE+8v9vDfBS8/sVRs6ZjADXbcFvirN93kOpxdIszqQ==", - "dev": true, - "requires": { - "globby": "^2.1.0", - "xtend": "^4.0.0" - } - } - } - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globby": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-2.1.0.tgz", - "integrity": "sha512-CqRID2dMaN4Zi9PANiQHhmKaGu7ZASehBLnaDogjR9L3L1EqAGFhflafT0IrSN/zm9xFk+KMTXZCN8pUYOiO/Q==", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "async": "^1.2.1", - "glob": "^5.0.3", - "object-assign": "^3.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "tsconfig": { - "version": "file:packages/tsconfig" - }, - "ui": { - "version": "file:packages/ui", - "requires": { - "tsconfig": "*" - } - }, - "web": { - "version": "file:apps/web", - "requires": { - "tsconfig": "*", - "ui": "*" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - } - } -} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json deleted file mode 100644 index 3efdede615717..0000000000000 --- a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "npm-workspaces", - "version": "0.0.0", - "private": true, - "workspaces": { - "packages": [ - "apps/*", - "packages/*" - ] - }, - "engines": { - "node": ">=14.0.0" - }, - "dependencies": {}, - "packageManager": "npm@8.19.4" -} \ No newline at end of file diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json deleted file mode 100644 index 0d32af30031af..0000000000000 --- a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/tsconfig/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "tsconfig", - "version": "1.0.0", - "private": true -} diff --git a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json b/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json deleted file mode 100644 index 1e05d1a8ecc65..0000000000000 --- a/packages/turbo-workspaces/51c0c0f2-b793-47f3-adf1-5b6fbb8f256a/f470387d-db52-450a-b249-23209a130752/packages/ui/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ui", - "version": "0.0.0", - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json b/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json deleted file mode 100644 index 00885fa1e0a9f..0000000000000 --- a/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "pnpm", - "version": "0.0.0", - "private": true, - "dependencies": {}, - "devDependencies": {}, - "packageManager": "pnpm@7.12.1" -} diff --git a/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml b/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml deleted file mode 100644 index 84c04af90e76b..0000000000000 --- a/packages/turbo-workspaces/b2b12497-6f77-4e8c-9e0f-f09ec961a5d7/bbc0652c-38f1-4196-81a2-5fd9a8bf67dd/pnpm-lock.yaml +++ /dev/null @@ -1,33 +0,0 @@ -lockfileVersion: 5.4 - -importers: - - .: - specifiers: {} - - apps/docs: - specifiers: - tsconfig: workspace:* - ui: workspace:* - dependencies: - ui: link:../../packages/ui - devDependencies: - tsconfig: link:../../packages/tsconfig - - apps/web: - specifiers: - tsconfig: workspace:* - ui: workspace:* - dependencies: - ui: link:../../packages/ui - devDependencies: - tsconfig: link:../../packages/tsconfig - - packages/tsconfig: - specifiers: {} - - packages/ui: - specifiers: - tsconfig: workspace:* - devDependencies: - tsconfig: link:../tsconfig diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json deleted file mode 100644 index d3a490ca892f8..0000000000000 --- a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/docs/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "docs", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json deleted file mode 100644 index 163cee3e51e6c..0000000000000 --- a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/apps/web/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "web", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json deleted file mode 100644 index 002944bd73343..0000000000000 --- a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "yarn-workspaces", - "version": "0.0.0", - "private": true, - "workspaces": [ - "apps/*", - "packages/*" - ], - "engines": { - "node": ">=14.0.0" - }, - "dependencies": {}, - "packageManager": "yarn@1.22.19" -} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json deleted file mode 100644 index 3f406290b4667..0000000000000 --- a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/tsconfig/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "tsconfig", - "version": "0.0.0", - "private": true -} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json deleted file mode 100644 index 1e05d1a8ecc65..0000000000000 --- a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/packages/ui/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ui", - "version": "0.0.0", - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock b/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock deleted file mode 100644 index fb57ccd13afbd..0000000000000 --- a/packages/turbo-workspaces/df086f14-8c27-4098-a378-7609ff78418e/9d796acb-95b5-484a-942e-8d478af17c22/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - From 431f25045ec43fc2dea7097faa4bb2bf2648e890 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Mon, 1 Jul 2024 12:47:34 -0600 Subject: [PATCH 05/31] Task table working sufficiently. --- crates/turborepo-ui/src/tui/app.rs | 54 ++++++++++++++++------------ crates/turborepo-ui/src/tui/table.rs | 44 +++++------------------ crates/turborepo-ui/src/tui/task.rs | 17 ++++++++- 3 files changed, 57 insertions(+), 58 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 40a78ba13ffe6..77435bde74f69 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -7,6 +7,7 @@ use std::{ use ratatui::{ backend::{Backend, CrosstermBackend}, layout::{Constraint, Layout}, + widgets::TableState, Frame, Terminal, }; use tracing::debug; @@ -25,12 +26,12 @@ pub enum LayoutSections { } pub struct App { - table: TaskTable, pane: TerminalPane, done: bool, input_options: InputOptions, started_tasks: Vec, task_list: Vec, + scroll: TableState, tasks_by_status: TasksByStatus, selected_task_index: usize, has_user_interacted: bool, @@ -72,7 +73,6 @@ impl App { let selected_task_index: usize = 0; Self { - table: TaskTable::new(&tasks_by_status, &selected_task_index, &has_user_interacted), pane: TerminalPane::new(rows, cols, tasks), done: false, input_options: InputOptions { @@ -83,6 +83,7 @@ impl App { started_tasks: Vec::with_capacity(num_of_tasks), task_list: task_list_as_strings, tasks_by_status, + scroll: TableState::default().with_selected(selected_task_index), selected_task_index, has_user_interacted, layout_focus: LayoutSections::Pane, @@ -93,9 +94,10 @@ impl App { let num_rows = self.task_list.len(); let next_index = (self.selected_task_index + 1).clamp(0, num_rows - 1); self.selected_task_index = next_index; - self.table.scroll.select(Some(next_index)); + self.scroll.select(Some(next_index)); let task = self.task_list[next_index].as_str(); self.pane.select(task).unwrap(); + self.has_user_interacted = true; } pub fn previous(&mut self) { @@ -104,9 +106,10 @@ impl App { i => i - 1, }; self.selected_task_index = i; - self.table.scroll.select(Some(i)); + self.scroll.select(Some(i)); let task = self.task_list[i].as_str(); self.pane.select(task).unwrap(); + self.has_user_interacted = true; } /// Mark the given task as started. @@ -138,12 +141,14 @@ impl App { } // Find the highlighted task from before the list movement in the new list. - if let Ok(new_index_to_highlight) = self + if let Some(new_index_to_highlight) = self .tasks_by_status .task_names_in_displayed_order() - .binary_search_by(|task| task.cmp(highlighted_task)) + .iter() + .position(|running| running == highlighted_task) { - self.selected_task_index = new_index_to_highlight + self.selected_task_index = new_index_to_highlight; + self.scroll.select(Some(new_index_to_highlight)); } Ok(()) @@ -164,6 +169,7 @@ impl App { .position(|running| running.name() == task) .ok_or_else(|| { debug!("could not find '{task}' to finish"); + println!("{:#?}", highlighted_task); Error::TaskNotFound { name: task.into() } })?; @@ -176,12 +182,14 @@ impl App { } // Find the highlighted task from before the list movement in the new list. - if let Ok(new_index_to_highlight) = self + if let Some(new_index_to_highlight) = self .tasks_by_status .task_names_in_displayed_order() - .binary_search_by(|task| task.cmp(highlighted_task)) + .iter() + .position(|running| running == highlighted_task) { - self.selected_task_index = new_index_to_highlight + self.selected_task_index = new_index_to_highlight; + self.scroll.select(Some(new_index_to_highlight)); } Ok(()) @@ -212,11 +220,6 @@ impl App { task_list.sort_unstable(); task_list.dedup(); - self.table = TaskTable::new( - &self.tasks_by_status, - &self.selected_task_index, - &self.has_user_interacted, - ); self.next(); } } @@ -337,8 +340,8 @@ fn cleanup( crossterm::event::DisableMouseCapture, crossterm::terminal::LeaveAlternateScreen, )?; - let started_tasks = app.table.tasks_started(); - app.pane.persist_tasks(&started_tasks)?; + app.pane + .persist_tasks(&app.tasks_by_status.tasks_started())?; crossterm::terminal::disable_raw_mode()?; terminal.show_cursor()?; // We can close the channel now that terminal is back restored to a normal state @@ -369,7 +372,7 @@ fn update( return Ok(Some(callback)); } Event::Tick => { - app.table.tick(); + // app.table.tick(); } Event::EndTask { task, result } => { app.finish_task(&task, result)?; @@ -404,7 +407,7 @@ fn update( } Event::UpdateTasks { tasks } => { app.update_tasks(tasks); - app.table.tick(); + // app.table.tick(); } } Ok(None) @@ -412,8 +415,15 @@ fn update( fn view(app: &mut App, f: &mut Frame) { let (_, width) = app.term_size(); - let vertical = Layout::horizontal([Constraint::Fill(1), Constraint::Length(width)]); - let [table, pane] = vertical.areas(f.size()); - app.table.stateful_render(f, table); + let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(width)]); + let [table, pane] = horizontal.areas(f.size()); + + let tabley_boi = TaskTable::new( + &app.tasks_by_status, + &app.selected_task_index, + &app.has_user_interacted, + ); + + f.render_stateful_widget(&tabley_boi, table, &mut app.scroll); f.render_widget(&app.pane, pane); } diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index fa94961350f44..0def4342c14d9 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -17,25 +17,23 @@ use super::{ /// /// The table contains finished tasks, running tasks, and planned tasks rendered /// in that order. -pub struct TaskTable { - tasks_by_type: &TasksByStatus, - pub scroll: TableState, +pub struct TaskTable<'b> { + tasks_by_type: &'b TasksByStatus, spinner: SpinnerState, - selected_index: &usize, - user_has_interacted: &bool, + selected_index: &'b usize, + user_has_interacted: &'b bool, } -impl TaskTable { +impl<'b> TaskTable<'b> { /// Construct a new table with all of the planned tasks pub fn new( - tasks_by_type: &TasksByStatus, - selected_index: &usize, - user_has_interacted: &bool, + tasks_by_type: &'b TasksByStatus, + selected_index: &'b usize, + user_has_interacted: &'b bool, ) -> Self { Self { selected_index, tasks_by_type, - scroll: TableState::default(), spinner: SpinnerState::default(), user_has_interacted, } @@ -59,22 +57,6 @@ impl TaskTable { self.spinner.update(); } - pub fn tasks_started(&self) -> Vec<&str> { - let (errors, success): (Vec<_>, Vec<_>) = self - .tasks_by_type - .finished - .iter() - .partition(|task| matches!(task.result(), TaskResult::Failure)); - - // We return errors last as they most likely have information users want to see - success - .into_iter() - .map(|task| task.name()) - .chain(self.tasks_by_type.running.iter().map(|task| task.name())) - .chain(errors.into_iter().map(|task| task.name())) - .collect() - } - fn finished_rows(&self) -> impl Iterator + '_ { self.tasks_by_type.finished.iter().map(move |task| { Row::new(vec![ @@ -101,17 +83,9 @@ impl TaskTable { .iter() .map(move |task| Row::new(vec![Cell::new(task.name()), Cell::new(" ")])) } - - /// Convenience method which renders and updates scroll state - pub fn stateful_render(&mut self, frame: &mut ratatui::Frame, area: Rect) { - let mut scroll = self.scroll.clone(); - self.spinner.update(); - frame.render_stateful_widget(&*self, area, &mut scroll); - self.scroll = scroll; - } } -impl<'a> StatefulWidget for &'a TaskTable { +impl<'a> StatefulWidget for &'a TaskTable<'a> { type State = TableState; fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer, state: &mut Self::State) { diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index e282e25a5c94e..6bdc858c68ed8 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -59,13 +59,28 @@ impl TasksByStatus { .map(|task| task.name().to_string()) .collect::>(); - vec![ + [ running_names.as_slice(), planned_names.as_slice(), finished_names.as_slice(), ] .concat() } + + pub fn tasks_started(&self) -> Vec<&str> { + let (errors, success): (Vec<_>, Vec<_>) = self + .finished + .iter() + .partition(|task| matches!(task.result(), TaskResult::Failure)); + + // We return errors last as they most likely have information users want to see + success + .into_iter() + .map(|task| task.name()) + .chain(self.running.iter().map(|task| task.name())) + .chain(errors.into_iter().map(|task| task.name())) + .collect() + } } impl Task { From 2d043ba479708598a8d6fa7ba7d3c9d77dd42d80 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Mon, 1 Jul 2024 13:52:12 -0600 Subject: [PATCH 06/31] Still movin'... --- crates/turborepo-ui/src/tui/app.rs | 63 ++++++++++++++++------------- crates/turborepo-ui/src/tui/pane.rs | 21 ++++++---- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 77435bde74f69..d5f302cc17632 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -25,8 +25,7 @@ pub enum LayoutSections { TaskList, } -pub struct App { - pane: TerminalPane, +pub struct App { done: bool, input_options: InputOptions, started_tasks: Vec, @@ -43,7 +42,7 @@ pub enum Direction { Down, } -impl App { +impl App { pub fn new(rows: u16, cols: u16, tasks: Vec) -> Self { debug!("tasks: {tasks:?}"); @@ -73,7 +72,6 @@ impl App { let selected_task_index: usize = 0; Self { - pane: TerminalPane::new(rows, cols, tasks), done: false, input_options: InputOptions { interact: false, @@ -95,8 +93,6 @@ impl App { let next_index = (self.selected_task_index + 1).clamp(0, num_rows - 1); self.selected_task_index = next_index; self.scroll.select(Some(next_index)); - let task = self.task_list[next_index].as_str(); - self.pane.select(task).unwrap(); self.has_user_interacted = true; } @@ -107,8 +103,6 @@ impl App { }; self.selected_task_index = i; self.scroll.select(Some(i)); - let task = self.task_list[i].as_str(); - self.pane.select(task).unwrap(); self.has_user_interacted = true; } @@ -196,12 +190,12 @@ impl App { } pub fn interact(&mut self, interact: bool) { + self.layout_focus = LayoutSections::Pane; if self .pane .has_stdin(self.task_list[self.selected_task_index].as_str()) { self.input_options.interact = interact; - self.pane.highlight(interact); } } @@ -224,7 +218,7 @@ impl App { } } -impl App { +impl App { pub fn forward_input(&mut self, bytes: &[u8]) -> Result<(), Error> { // If we aren't in interactive mode, ignore input if !self.input_options.interact { @@ -247,10 +241,15 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { let ratio_pane_width = (f32::from(size.width) * PANE_SIZE_RATIO) as u16; let full_task_width = size.width.saturating_sub(task_width_hint); - let mut app: App> = - App::new(size.height, full_task_width.max(ratio_pane_width), tasks); + let mut app: App = App::new(size.height, full_task_width.max(ratio_pane_width), tasks); - let (result, callback) = match run_app_inner(&mut terminal, &mut app, receiver) { + let (result, callback) = match run_app_inner( + &mut terminal, + &mut app, + receiver, + size.height, + full_task_width.max(ratio_pane_width), + ) { Ok(callback) => (Ok(()), callback), Err(err) => (Err(err), None), }; @@ -264,11 +263,13 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { // terminal. fn run_app_inner( terminal: &mut Terminal, - app: &mut App>, + app: &mut App, receiver: AppReceiver, + rows: u16, + cols: u16, ) -> Result>, Error> { // Render initial state to paint the screen - terminal.draw(|f| view(app, f))?; + terminal.draw(|f| view(app, f, rows, cols))?; let mut last_render = Instant::now(); let mut callback = None; while let Some(event) = poll(app.input_options, &receiver, last_render + FRAMERATE) { @@ -277,7 +278,7 @@ fn run_app_inner( break; } if FRAMERATE <= last_render.elapsed() { - terminal.draw(|f| view(app, f))?; + terminal.draw(|f| view(app, f, rows, cols))?; last_render = Instant::now(); } } @@ -329,9 +330,9 @@ fn startup() -> io::Result>> { } /// Restores terminal to expected state -fn cleanup( +fn cleanup( mut terminal: Terminal, - mut app: App, + mut app: App, callback: Option>, ) -> io::Result<()> { terminal.clear()?; @@ -340,8 +341,7 @@ fn cleanup( crossterm::event::DisableMouseCapture, crossterm::terminal::LeaveAlternateScreen, )?; - app.pane - .persist_tasks(&app.tasks_by_status.tasks_started())?; + app.persist_tasks(&app.tasks_by_status.tasks_started())?; crossterm::terminal::disable_raw_mode()?; terminal.show_cursor()?; // We can close the channel now that terminal is back restored to a normal state @@ -349,10 +349,7 @@ fn cleanup( Ok(()) } -fn update( - app: &mut App>, - event: Event, -) -> Result>, Error> { +fn update(app: &mut App, event: Event) -> Result>, Error> { match event { Event::StartTask { task } => { app.start_task(&task)?; @@ -413,17 +410,27 @@ fn update( Ok(None) } -fn view(app: &mut App, f: &mut Frame) { +fn view(app: &mut App, f: &mut Frame, rows: u16, cols: u16) { let (_, width) = app.term_size(); let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(width)]); let [table, pane] = horizontal.areas(f.size()); - let tabley_boi = TaskTable::new( + let pane_to_render: TerminalPane = TerminalPane::new( + rows, + cols, + app.tasks_by_status.task_names_in_displayed_order(), + match app.layout_focus { + LayoutSections::Pane => true, + LayoutSections::TaskList => false, + }, + ); + + let table_to_render = TaskTable::new( &app.tasks_by_status, &app.selected_task_index, &app.has_user_interacted, ); - f.render_stateful_widget(&tabley_boi, table, &mut app.scroll); - f.render_widget(&app.pane, pane); + f.render_stateful_widget(&table_to_render, table, &mut app.scroll); + f.render_widget(&pane_to_render, pane); } diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index 2593253198ba8..54c6ab0355378 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -16,7 +16,7 @@ const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; pub struct TerminalPane { tasks: BTreeMap>, - displayed: Option, + displayed_task: Option, rows: u16, cols: u16, highlight: bool, @@ -31,7 +31,12 @@ struct TerminalOutput { } impl TerminalPane { - pub fn new(rows: u16, cols: u16, tasks: impl IntoIterator) -> Self { + pub fn new( + rows: u16, + cols: u16, + tasks: impl IntoIterator, + highlight: bool, + ) -> Self { // We trim 2 from rows and cols as we use them for borders let rows = rows.saturating_sub(2); let cols = cols.saturating_sub(2); @@ -40,10 +45,10 @@ impl TerminalPane { .into_iter() .map(|name| (name, TerminalOutput::new(rows, cols, None))) .collect(), - displayed: None, + displayed_task: None, rows, cols, - highlight: false, + highlight, } } @@ -72,7 +77,7 @@ impl TerminalPane { self.cols = cols; if changed { // Eagerly resize currently displayed terminal - if let Some(task_name) = self.displayed.as_deref() { + if let Some(task_name) = self.displayed_task.as_deref() { let task = self .tasks .get_mut(task_name) @@ -91,7 +96,7 @@ impl TerminalPane { let terminal = self.task_mut(task)?; terminal.resize(rows, cols); } - self.displayed = Some(task.into()); + self.displayed_task = Some(task.into()); Ok(()) } @@ -130,7 +135,7 @@ impl TerminalPane { } fn selected(&self) -> Option<(&String, &TerminalOutput)> { - let task_name = self.displayed.as_deref()?; + let task_name = self.displayed_task.as_deref()?; self.tasks.get_key_value(task_name) } @@ -240,7 +245,7 @@ mod test { #[test] fn test_basic() { - let mut pane: TerminalPane<()> = TerminalPane::new(6, 8, vec!["foo".into()]); + let mut pane: TerminalPane<()> = TerminalPane::new(6, 8, vec!["foo".into()], false); pane.select("foo").unwrap(); pane.process_output("foo", b"1\r\n2\r\n3\r\n4\r\n5\r\n") .unwrap(); From 8d8af955aa67103941d9d11af6583b6639eb42fa Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Mon, 1 Jul 2024 18:50:58 -0600 Subject: [PATCH 07/31] Looking really good. --- crates/turborepo-ui/src/tui/app.rs | 165 +++++++++++++++------ crates/turborepo-ui/src/tui/input.rs | 21 ++- crates/turborepo-ui/src/tui/mod.rs | 2 + crates/turborepo-ui/src/tui/pane.rs | 81 +--------- crates/turborepo-ui/src/tui/task.rs | 3 +- crates/turborepo-ui/src/tui/term_output.rs | 59 ++++++++ 6 files changed, 196 insertions(+), 135 deletions(-) create mode 100644 crates/turborepo-ui/src/tui/term_output.rs diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index d5f302cc17632..ae29f35bcc3f3 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -1,4 +1,5 @@ use std::{ + collections::BTreeMap, io::{self, Stdout, Write}, sync::mpsc, time::{Duration, Instant}, @@ -18,14 +19,20 @@ const FRAMERATE: Duration = Duration::from_millis(3); use super::{ event::TaskResult, input, AppReceiver, Error, Event, InputOptions, TaskTable, TerminalPane, }; -use crate::tui::task::{Task, TasksByStatus}; +use crate::tui::{ + task::{Task, TasksByStatus}, + term_output::TerminalOutput, +}; pub enum LayoutSections { Pane, TaskList, } -pub struct App { +pub struct App { + rows: u16, + cols: u16, + tasks: BTreeMap>, done: bool, input_options: InputOptions, started_tasks: Vec, @@ -42,7 +49,7 @@ pub enum Direction { Down, } -impl App { +impl App { pub fn new(rows: u16, cols: u16, tasks: Vec) -> Self { debug!("tasks: {tasks:?}"); @@ -55,13 +62,6 @@ impl App { task_list.sort_unstable(); task_list.dedup(); - // TODO: WIP, I shouldn't need this when I'm done? - let task_list_as_strings = task_list - .clone() - .into_iter() - .map(|task| task.name().to_string()) - .collect::>(); - let tasks_by_status = TasksByStatus { planned: task_list, finished: Vec::new(), @@ -72,14 +72,22 @@ impl App { let selected_task_index: usize = 0; Self { + cols, + rows, done: false, input_options: InputOptions { - interact: false, + focus: LayoutSections::TaskList, // Check if stdin is a tty that we should read input from tty_stdin: atty::is(atty::Stream::Stdin), }, started_tasks: Vec::with_capacity(num_of_tasks), - task_list: task_list_as_strings, + // TODO: WIP, this should be able to disappear once I'm done? + task_list: tasks_by_status.task_names_in_displayed_order(), + tasks: tasks_by_status + .task_names_in_displayed_order() + .into_iter() + .map(|task_name| (task_name, TerminalOutput::new(rows, cols, None))) + .collect(), tasks_by_status, scroll: TableState::default().with_selected(selected_task_index), selected_task_index, @@ -88,6 +96,20 @@ impl App { } } + pub fn active_task(&self) -> String { + self.tasks_by_status + .task_names_in_displayed_order() + .remove(self.selected_task_index) + } + + pub fn get_full_task(&self) -> &TerminalOutput { + self.tasks.get(&self.active_task()).unwrap() + } + + pub fn get_full_task_mut(&mut self) -> &mut TerminalOutput { + self.tasks.get_mut(&self.active_task()).unwrap() + } + pub fn next(&mut self) { let num_rows = self.task_list.len(); let next_index = (self.selected_task_index + 1).clamp(0, num_rows - 1); @@ -189,24 +211,21 @@ impl App { Ok(()) } - pub fn interact(&mut self, interact: bool) { - self.layout_focus = LayoutSections::Pane; - if self - .pane - .has_stdin(self.task_list[self.selected_task_index].as_str()) - { - self.input_options.interact = interact; + pub fn has_stdin(&self) -> bool { + let active_task = self.active_task(); + if let Some(term) = self.tasks.get(&active_task) { + term.stdin.is_some() + } else { + false } } - pub fn scroll(&mut self, direction: Direction) { - self.pane - .scroll(self.task_list[self.selected_task_index].as_str(), direction) - .expect("selected task should be in pane"); - } - - pub fn term_size(&self) -> (u16, u16) { - self.pane.term_size() + pub fn interact(&mut self) { + if matches!(self.input_options.focus, LayoutSections::Pane) { + self.input_options.focus = LayoutSections::TaskList + } else if self.has_stdin() { + self.input_options.focus = LayoutSections::Pane; + } } pub fn update_tasks(&mut self, tasks: Vec) { @@ -216,16 +235,61 @@ impl App { self.next(); } + + /// Persist all task output to the after closing the TUI + pub fn persist_tasks(&mut self, started_tasks: Vec) -> std::io::Result<()> { + for (task_name, task) in started_tasks.into_iter().filter_map(|started_task| { + (Some(started_task.clone())).zip(self.tasks.get(&started_task)) + }) { + task.persist_screen(&task_name)?; + } + Ok(()) + } + + pub fn set_status(&mut self, status: String) -> Result<(), Error> { + let task = self.get_full_task_mut(); + task.status = Some(status); + Ok(()) + } } -impl App { +impl App { + /// Insert a stdin to be associated with a task + pub fn insert_stdin(&mut self, stdin: Option) -> Result<(), Error> { + let task = self.get_full_task_mut(); + task.stdin = stdin; + Ok(()) + } + pub fn forward_input(&mut self, bytes: &[u8]) -> Result<(), Error> { - // If we aren't in interactive mode, ignore input - if !self.input_options.interact { - return Ok(()); + if matches!(self.input_options.focus, LayoutSections::Pane) { + let task_output = self.get_full_task_mut(); + if let Some(stdin) = &mut task_output.stdin { + stdin.write_all(bytes).map_err(|e| Error::Stdin { + name: self.active_task().into(), + e, + })?; + } + Ok(()) + } else { + Ok(()) + } + } + + pub fn process_input(&mut self, task: &str, input: &[u8]) -> Result<(), Error> { + let task_output = self.get_full_task_mut(); + if let Some(stdin) = &mut task_output.stdin { + stdin.write_all(input).map_err(|e| Error::Stdin { + name: task.into(), + e, + })?; } - let selected_task = self.task_list[self.selected_task_index].as_str(); - self.pane.process_input(selected_task, bytes)?; + Ok(()) + } + + pub fn process_output(&mut self, task: &str, output: &[u8]) -> Result<(), Error> { + let task_output = self.tasks.get_mut(task).unwrap(); + task_output.parser.process(output); Ok(()) } } @@ -241,7 +305,7 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { let ratio_pane_width = (f32::from(size.width) * PANE_SIZE_RATIO) as u16; let full_task_width = size.width.saturating_sub(task_width_hint); - let mut app: App = App::new(size.height, full_task_width.max(ratio_pane_width), tasks); + let mut app: App> = App::new(size.height, size.width, tasks); let (result, callback) = match run_app_inner( &mut terminal, @@ -263,7 +327,7 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { // terminal. fn run_app_inner( terminal: &mut Terminal, - app: &mut App, + app: &mut App>, receiver: AppReceiver, rows: u16, cols: u16, @@ -272,7 +336,7 @@ fn run_app_inner( terminal.draw(|f| view(app, f, rows, cols))?; let mut last_render = Instant::now(); let mut callback = None; - while let Some(event) = poll(app.input_options, &receiver, last_render + FRAMERATE) { + while let Some(event) = poll(&app.input_options, &receiver, last_render + FRAMERATE) { callback = update(app, event)?; if app.done { break; @@ -288,7 +352,7 @@ fn run_app_inner( /// Blocking poll for events, will only return None if app handle has been /// dropped -fn poll(input_options: InputOptions, receiver: &AppReceiver, deadline: Instant) -> Option { +fn poll(input_options: &InputOptions, receiver: &AppReceiver, deadline: Instant) -> Option { match input(input_options) { Ok(Some(event)) => Some(event), Ok(None) => receiver.recv(deadline).ok(), @@ -332,7 +396,7 @@ fn startup() -> io::Result>> { /// Restores terminal to expected state fn cleanup( mut terminal: Terminal, - mut app: App, + mut app: App>, callback: Option>, ) -> io::Result<()> { terminal.clear()?; @@ -341,7 +405,8 @@ fn cleanup( crossterm::event::DisableMouseCapture, crossterm::terminal::LeaveAlternateScreen, )?; - app.persist_tasks(&app.tasks_by_status.tasks_started())?; + let tasks_started = app.tasks_by_status.tasks_started(); + app.persist_tasks(tasks_started)?; crossterm::terminal::disable_raw_mode()?; terminal.show_cursor()?; // We can close the channel now that terminal is back restored to a normal state @@ -349,17 +414,20 @@ fn cleanup( Ok(()) } -fn update(app: &mut App, event: Event) -> Result>, Error> { +fn update( + app: &mut App>, + event: Event, +) -> Result>, Error> { match event { Event::StartTask { task } => { app.start_task(&task)?; app.started_tasks.push(task); } Event::TaskOutput { task, output } => { - app.pane.process_output(&task, &output)?; + app.process_output(&task, &output)?; } Event::Status { task, status } => { - app.pane.set_status(&task, status)?; + app.set_status(status)?; } Event::InternalStop => { app.done = true; @@ -390,11 +458,11 @@ fn update(app: &mut App, event: Event) -> Result>, E } Event::EnterInteractive => { app.has_user_interacted = true; - app.interact(true); + app.interact(); } Event::ExitInteractive => { app.has_user_interacted = true; - app.interact(false); + app.interact(); } Event::Input { bytes } => { app.forward_input(&bytes)?; @@ -410,15 +478,14 @@ fn update(app: &mut App, event: Event) -> Result>, E Ok(None) } -fn view(app: &mut App, f: &mut Frame, rows: u16, cols: u16) { - let (_, width) = app.term_size(); - let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(width)]); +fn view(app: &mut App>, f: &mut Frame, rows: u16, cols: u16) { + let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(cols)]); let [table, pane] = horizontal.areas(f.size()); - let pane_to_render: TerminalPane = TerminalPane::new( + let pane_to_render: TerminalPane> = TerminalPane::new( rows, cols, - app.tasks_by_status.task_names_in_displayed_order(), + terms, match app.layout_focus { LayoutSections::Pane => true, LayoutSections::TaskList => false, diff --git a/crates/turborepo-ui/src/tui/input.rs b/crates/turborepo-ui/src/tui/input.rs index 5b8987f599da9..3ace134a5bcd7 100644 --- a/crates/turborepo-ui/src/tui/input.rs +++ b/crates/turborepo-ui/src/tui/input.rs @@ -2,19 +2,15 @@ use std::time::Duration; use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; -use super::{event::Event, Error}; +use super::{app::LayoutSections, event::Event, Error}; -#[derive(Debug, Clone, Copy)] pub struct InputOptions { - pub interact: bool, + pub focus: LayoutSections, pub tty_stdin: bool, } /// Return any immediately available event -pub fn input(options: InputOptions) -> Result, Error> { - let InputOptions { - interact, - tty_stdin, - } = options; +pub fn input(options: &InputOptions) -> Result, Error> { + let InputOptions { focus, tty_stdin } = options; // If stdin is not a tty, then we do not attempt to read from it if !tty_stdin { return Ok(None); @@ -23,7 +19,7 @@ pub fn input(options: InputOptions) -> Result, Error> { // for input if crossterm::event::poll(Duration::from_millis(0))? { match crossterm::event::read()? { - crossterm::event::Event::Key(k) => Ok(translate_key_event(interact, k)), + crossterm::event::Event::Key(k) => Ok(translate_key_event(&focus, k)), crossterm::event::Event::Mouse(m) => match m.kind { crossterm::event::MouseEventKind::ScrollDown => Ok(Some(Event::ScrollDown)), crossterm::event::MouseEventKind::ScrollUp => Ok(Some(Event::ScrollUp)), @@ -37,7 +33,7 @@ pub fn input(options: InputOptions) -> Result, Error> { } /// Converts a crossterm key event into a TUI interaction event -fn translate_key_event(interact: bool, key_event: KeyEvent) -> Option { +fn translate_key_event(interact: &LayoutSections, key_event: KeyEvent) -> Option { // On Windows events for releasing a key are produced // We skip these to avoid emitting 2 events per key press. // There is still a `Repeat` event for when a key is held that will pass through @@ -51,12 +47,13 @@ fn translate_key_event(interact: bool, key_event: KeyEvent) -> Option { } // Interactive branches KeyCode::Char('z') - if interact && key_event.modifiers == crossterm::event::KeyModifiers::CONTROL => + if matches!(interact, LayoutSections::Pane) + && key_event.modifiers == crossterm::event::KeyModifiers::CONTROL => { Some(Event::ExitInteractive) } // If we're in interactive mode, convert the key event to bytes to send to stdin - _ if interact => Some(Event::Input { + _ if matches!(interact, LayoutSections::Pane) => Some(Event::Input { bytes: encode_key(key_event), }), // Fall through if we aren't in interactive mode diff --git a/crates/turborepo-ui/src/tui/mod.rs b/crates/turborepo-ui/src/tui/mod.rs index 35b0deea7ba06..5bcb487873a69 100644 --- a/crates/turborepo-ui/src/tui/mod.rs +++ b/crates/turborepo-ui/src/tui/mod.rs @@ -6,6 +6,7 @@ mod pane; mod spinner; mod table; mod task; +mod term_output; pub use app::{run_app, terminal_big_enough}; use event::{Event, TaskResult}; @@ -13,6 +14,7 @@ pub use handle::{AppReceiver, AppSender, TuiTask}; use input::{input, InputOptions}; pub use pane::TerminalPane; pub use table::TaskTable; +pub use term_output::TerminalOutput; #[derive(Debug, thiserror::Error)] pub enum Error { diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index 54c6ab0355378..ce6b1dc18f321 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -7,48 +7,31 @@ use ratatui::{ }; use tracing::debug; use tui_term::widget::PseudoTerminal; -use turborepo_vt100 as vt100; -use super::{app::Direction, Error}; +use super::{app::Direction, Error, TerminalOutput}; const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; -pub struct TerminalPane { - tasks: BTreeMap>, +pub struct TerminalPane<'a, W> { + logs_output: &'a TerminalOutput, displayed_task: Option, rows: u16, cols: u16, highlight: bool, } -struct TerminalOutput { - rows: u16, - cols: u16, - parser: vt100::Parser, - stdin: Option, - status: Option, -} - -impl TerminalPane { - pub fn new( - rows: u16, - cols: u16, - tasks: impl IntoIterator, - highlight: bool, - ) -> Self { +impl<'a, W> TerminalPane<'a, W> { + pub fn new(rows: u16, cols: u16, highlight: bool, logs_output: &'a TerminalOutput) -> Self { // We trim 2 from rows and cols as we use them for borders let rows = rows.saturating_sub(2); let cols = cols.saturating_sub(2); Self { - tasks: tasks - .into_iter() - .map(|name| (name, TerminalOutput::new(rows, cols, None))) - .collect(), displayed_task: None, rows, cols, highlight, + logs_output, } } @@ -64,11 +47,8 @@ impl TerminalPane { Ok(()) } - pub fn has_stdin(&self, task: &str) -> bool { - self.tasks - .get(task) - .map(|task| task.stdin.is_some()) - .unwrap_or_default() + pub fn has_stdin(&self, task: &str) -> Option { + &self.logs_output.stdin } pub fn resize(&mut self, rows: u16, cols: u16) -> Result<(), Error> { @@ -166,51 +146,6 @@ impl TerminalPane { } } -impl TerminalOutput { - fn new(rows: u16, cols: u16, stdin: Option) -> Self { - Self { - parser: vt100::Parser::new(rows, cols, 1024), - stdin, - rows, - cols, - status: None, - } - } - - fn title(&self, task_name: &str) -> String { - match self.status.as_deref() { - Some(status) => format!(" {task_name} > {status} "), - None => format!(" {task_name} > "), - } - } - - fn resize(&mut self, rows: u16, cols: u16) { - if self.rows != rows || self.cols != cols { - self.parser.screen_mut().set_size(rows, cols); - } - self.rows = rows; - self.cols = cols; - } - - #[tracing::instrument(skip(self))] - fn persist_screen(&self, task_name: &str) -> std::io::Result<()> { - let screen = self.parser.entire_screen(); - let title = self.title(task_name); - let mut stdout = std::io::stdout().lock(); - stdout.write_all("┌".as_bytes())?; - stdout.write_all(title.as_bytes())?; - stdout.write_all(b"\r\n")?; - for row in screen.rows_formatted(0, self.cols) { - stdout.write_all("│ ".as_bytes())?; - stdout.write_all(&row)?; - stdout.write_all(b"\r\n")?; - } - stdout.write_all("└────>\r\n".as_bytes())?; - - Ok(()) - } -} - impl Widget for &TerminalPane { fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) where diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index 6bdc858c68ed8..ebc055c8b69e7 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -67,7 +67,7 @@ impl TasksByStatus { .concat() } - pub fn tasks_started(&self) -> Vec<&str> { + pub fn tasks_started(&self) -> Vec { let (errors, success): (Vec<_>, Vec<_>) = self .finished .iter() @@ -79,6 +79,7 @@ impl TasksByStatus { .map(|task| task.name()) .chain(self.running.iter().map(|task| task.name())) .chain(errors.into_iter().map(|task| task.name())) + .map(|task| task.to_string()) .collect() } } diff --git a/crates/turborepo-ui/src/tui/term_output.rs b/crates/turborepo-ui/src/tui/term_output.rs new file mode 100644 index 0000000000000..bc2a6f879be66 --- /dev/null +++ b/crates/turborepo-ui/src/tui/term_output.rs @@ -0,0 +1,59 @@ +use std::io::Write; + +use turborepo_vt100 as vt100; + +const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; +const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; + +pub struct TerminalOutput { + rows: u16, + cols: u16, + pub parser: vt100::Parser, + pub stdin: Option, + pub status: Option, +} + +impl TerminalOutput { + pub fn new(rows: u16, cols: u16, stdin: Option) -> Self { + Self { + parser: vt100::Parser::new(rows, cols, 1024), + stdin, + rows, + cols, + status: None, + } + } + + pub fn title(&self, task_name: &str) -> String { + match self.status.as_deref() { + Some(status) => format!(" {task_name} > {status} "), + None => format!(" {task_name} > "), + } + } + + pub fn resize(&mut self, rows: u16, cols: u16) { + if self.rows != rows || self.cols != cols { + self.parser.screen_mut().set_size(rows, cols); + } + self.rows = rows; + self.cols = cols; + } + + #[tracing::instrument(skip(self))] + pub fn persist_screen(&self, task_name: &str) -> std::io::Result<()> { + let screen = self.parser.entire_screen(); + let title = self.title(task_name); + let mut stdout = std::io::stdout().lock(); + stdout.write_all("┌".as_bytes())?; + stdout.write_all(title.as_bytes())?; + stdout.write_all(b"\r\n")?; + for row in screen.rows_formatted(0, self.cols) { + stdout.write_all("│ ".as_bytes())?; + stdout.write_all(&row)?; + stdout.write_all(b"\r\n")?; + } + stdout.write_all("└────>\r\n".as_bytes())?; + + Ok(()) + } +} From 4528c06d56cc5b7d459ff7910a80f761df8e80f4 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 08:14:44 -0600 Subject: [PATCH 08/31] At least it compiles. --- crates/turborepo-ui/src/tui/app.rs | 18 ++-- crates/turborepo-ui/src/tui/event.rs | 2 - crates/turborepo-ui/src/tui/handle.rs | 16 +--- crates/turborepo-ui/src/tui/pane.rs | 97 +++++++++++++--------- crates/turborepo-ui/src/tui/term_output.rs | 12 +++ 5 files changed, 82 insertions(+), 63 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index ae29f35bcc3f3..6319ada540c27 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -426,7 +426,7 @@ fn update( Event::TaskOutput { task, output } => { app.process_output(&task, &output)?; } - Event::Status { task, status } => { + Event::Status { status } => { app.set_status(status)?; } Event::InternalStop => { @@ -450,11 +450,17 @@ fn update( } Event::ScrollUp => { app.has_user_interacted = true; - app.scroll(Direction::Up); + app.tasks + .get_mut(&app.active_task()) + .unwrap() + .scroll(Direction::Up); } Event::ScrollDown => { app.has_user_interacted = true; - app.scroll(Direction::Down); + app.tasks + .get_mut(&app.active_task()) + .unwrap() + .scroll(Direction::Down); } Event::EnterInteractive => { app.has_user_interacted = true; @@ -467,8 +473,8 @@ fn update( Event::Input { bytes } => { app.forward_input(&bytes)?; } - Event::SetStdin { task, stdin } => { - app.pane.insert_stdin(&task, Some(stdin))?; + Event::SetStdin { stdin } => { + app.insert_stdin(Some(stdin))?; } Event::UpdateTasks { tasks } => { app.update_tasks(tasks); @@ -485,11 +491,11 @@ fn view(app: &mut App>, f: &mut Frame, rows: u16, cols let pane_to_render: TerminalPane> = TerminalPane::new( rows, cols, - terms, match app.layout_focus { LayoutSections::Pane => true, LayoutSections::TaskList => false, }, + &mut app.tasks, ); let table_to_render = TaskTable::new( diff --git a/crates/turborepo-ui/src/tui/event.rs b/crates/turborepo-ui/src/tui/event.rs index 5f6e5cee6e345..c4f0b892b9ae7 100644 --- a/crates/turborepo-ui/src/tui/event.rs +++ b/crates/turborepo-ui/src/tui/event.rs @@ -11,7 +11,6 @@ pub enum Event { result: TaskResult, }, Status { - task: String, status: String, }, Stop(std::sync::mpsc::SyncSender<()>), @@ -23,7 +22,6 @@ pub enum Event { ScrollUp, ScrollDown, SetStdin { - task: String, stdin: Box, }, EnterInteractive, diff --git a/crates/turborepo-ui/src/tui/handle.rs b/crates/turborepo-ui/src/tui/handle.rs index 59dd8d9682807..c07681cb14c8b 100644 --- a/crates/turborepo-ui/src/tui/handle.rs +++ b/crates/turborepo-ui/src/tui/handle.rs @@ -116,13 +116,7 @@ impl TuiTask { } pub fn set_stdin(&self, stdin: Box) { - self.handle - .primary - .send(Event::SetStdin { - task: self.name.clone(), - stdin, - }) - .ok(); + self.handle.primary.send(Event::SetStdin { stdin }).ok(); } pub fn status(&self, status: &str) { @@ -130,13 +124,7 @@ impl TuiTask { // handled. // TODO: prevent the status from having ANSI codes in this scenario let status = console::strip_ansi_codes(status).into_owned(); - self.handle - .primary - .send(Event::Status { - task: self.name.clone(), - status, - }) - .ok(); + self.handle.primary.send(Event::Status { status }).ok(); } } diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index ce6b1dc18f321..745769cece8b6 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -14,15 +14,20 @@ const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; pub struct TerminalPane<'a, W> { - logs_output: &'a TerminalOutput, displayed_task: Option, rows: u16, cols: u16, highlight: bool, + tasks: &'a mut BTreeMap>, } impl<'a, W> TerminalPane<'a, W> { - pub fn new(rows: u16, cols: u16, highlight: bool, logs_output: &'a TerminalOutput) -> Self { + pub fn new( + rows: u16, + cols: u16, + highlight: bool, + tasks: &'a mut BTreeMap>, + ) -> Self { // We trim 2 from rows and cols as we use them for borders let rows = rows.saturating_sub(2); let cols = cols.saturating_sub(2); @@ -31,7 +36,7 @@ impl<'a, W> TerminalPane<'a, W> { rows, cols, highlight, - logs_output, + tasks, } } @@ -47,8 +52,18 @@ impl<'a, W> TerminalPane<'a, W> { Ok(()) } - pub fn has_stdin(&self, task: &str) -> Option { - &self.logs_output.stdin + pub fn hassss_stdin(&self, task: &str) -> bool { + self.tasks + .get(task) + .map(|task| task.stdin.is_some()) + .unwrap_or_default() + } + + pub fn has_stdin(&self, task: &str) -> bool { + self.tasks + .get(task) + .map(|task| task.stdin.is_some()) + .unwrap_or_default() } pub fn resize(&mut self, rows: u16, cols: u16) -> Result<(), Error> { @@ -126,7 +141,7 @@ impl<'a, W> TerminalPane<'a, W> { } } -impl TerminalPane { +impl<'a, W: Write> TerminalPane<'a, W> { /// Insert a stdin to be associated with a task pub fn insert_stdin(&mut self, task_name: &str, stdin: Option) -> Result<(), Error> { let task = self.task_mut(task_name)?; @@ -146,7 +161,7 @@ impl TerminalPane { } } -impl Widget for &TerminalPane { +impl<'a, W> Widget for &TerminalPane<'a, W> { fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) where Self: Sized, @@ -169,37 +184,37 @@ impl Widget for &TerminalPane { } } -#[cfg(test)] -mod test { - // Used by assert_buffer_eq - #[allow(unused_imports)] - use indoc::indoc; - use ratatui::{assert_buffer_eq, buffer::Buffer, layout::Rect}; - - use super::*; - - #[test] - fn test_basic() { - let mut pane: TerminalPane<()> = TerminalPane::new(6, 8, vec!["foo".into()], false); - pane.select("foo").unwrap(); - pane.process_output("foo", b"1\r\n2\r\n3\r\n4\r\n5\r\n") - .unwrap(); - - let area = Rect::new(0, 0, 8, 6); - let mut buffer = Buffer::empty(area); - pane.render(area, &mut buffer); - // Reset style change of the cursor - buffer.set_style(Rect::new(1, 4, 1, 1), Style::reset()); - assert_buffer_eq!( - buffer, - Buffer::with_lines(vec![ - "│ foo > ", - "│3 ", - "│4 ", - "│5 ", - "│█ ", - "│Press `", - ]) - ); - } -} +// #[cfg(test)] +// mod test { +// // Used by assert_buffer_eq +// #[allow(unused_imports)] +// use indoc::indoc; +// use ratatui::{assert_buffer_eq, buffer::Buffer, layout::Rect}; +// +// use super::*; +// +// #[test] +// fn test_basic() { +// let mut pane: TerminalPane<()> = TerminalPane::new(6, 8, +// vec!["foo".into()], false); pane.select("foo").unwrap(); +// pane.process_output("foo", b"1\r\n2\r\n3\r\n4\r\n5\r\n") +// .unwrap(); +// +// let area = Rect::new(0, 0, 8, 6); +// let mut buffer = Buffer::empty(area); +// pane.render(area, &mut buffer); +// // Reset style change of the cursor +// buffer.set_style(Rect::new(1, 4, 1, 1), Style::reset()); +// assert_buffer_eq!( +// buffer, +// Buffer::with_lines(vec![ +// "│ foo > ", +// "│3 ", +// "│4 ", +// "│5 ", +// "│█ ", +// "│Press `", +// ]) +// ); +// } +// } diff --git a/crates/turborepo-ui/src/tui/term_output.rs b/crates/turborepo-ui/src/tui/term_output.rs index bc2a6f879be66..0fef350c8f792 100644 --- a/crates/turborepo-ui/src/tui/term_output.rs +++ b/crates/turborepo-ui/src/tui/term_output.rs @@ -2,6 +2,8 @@ use std::io::Write; use turborepo_vt100 as vt100; +use super::{app::Direction, Error}; + const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; @@ -39,6 +41,16 @@ impl TerminalOutput { self.cols = cols; } + pub fn scroll(&mut self, direction: Direction) -> Result<(), Error> { + let scrollback = self.parser.screen().scrollback(); + let new_scrollback = match direction { + Direction::Up => scrollback + 1, + Direction::Down => scrollback.saturating_sub(1), + }; + self.parser.screen_mut().set_scrollback(new_scrollback); + Ok(()) + } + #[tracing::instrument(skip(self))] pub fn persist_screen(&self, task_name: &str) -> std::io::Result<()> { let screen = self.parser.entire_screen(); From 9eaf4edaa32397501262053a57630f94e02ac8c4 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 08:22:00 -0600 Subject: [PATCH 09/31] Minor cleanups. --- crates/turborepo-ui/src/tui/app.rs | 27 ++++------------------ crates/turborepo-ui/src/tui/term_output.rs | 3 --- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 6319ada540c27..d7e1eddbf4b9e 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -30,8 +30,6 @@ pub enum LayoutSections { } pub struct App { - rows: u16, - cols: u16, tasks: BTreeMap>, done: bool, input_options: InputOptions, @@ -72,8 +70,6 @@ impl App { let selected_task_index: usize = 0; Self { - cols, - rows, done: false, input_options: InputOptions { focus: LayoutSections::TaskList, @@ -102,10 +98,6 @@ impl App { .remove(self.selected_task_index) } - pub fn get_full_task(&self) -> &TerminalOutput { - self.tasks.get(&self.active_task()).unwrap() - } - pub fn get_full_task_mut(&mut self) -> &mut TerminalOutput { self.tasks.get_mut(&self.active_task()).unwrap() } @@ -266,7 +258,7 @@ impl App { let task_output = self.get_full_task_mut(); if let Some(stdin) = &mut task_output.stdin { stdin.write_all(bytes).map_err(|e| Error::Stdin { - name: self.active_task().into(), + name: self.active_task(), e, })?; } @@ -276,17 +268,6 @@ impl App { } } - pub fn process_input(&mut self, task: &str, input: &[u8]) -> Result<(), Error> { - let task_output = self.get_full_task_mut(); - if let Some(stdin) = &mut task_output.stdin { - stdin.write_all(input).map_err(|e| Error::Stdin { - name: task.into(), - e, - })?; - } - Ok(()) - } - pub fn process_output(&mut self, task: &str, output: &[u8]) -> Result<(), Error> { let task_output = self.tasks.get_mut(task).unwrap(); task_output.parser.process(output); @@ -453,14 +434,16 @@ fn update( app.tasks .get_mut(&app.active_task()) .unwrap() - .scroll(Direction::Up); + .scroll(Direction::Up) + .unwrap_or_default(); } Event::ScrollDown => { app.has_user_interacted = true; app.tasks .get_mut(&app.active_task()) .unwrap() - .scroll(Direction::Down); + .scroll(Direction::Down) + .unwrap_or_default(); } Event::EnterInteractive => { app.has_user_interacted = true; diff --git a/crates/turborepo-ui/src/tui/term_output.rs b/crates/turborepo-ui/src/tui/term_output.rs index 0fef350c8f792..765c130733204 100644 --- a/crates/turborepo-ui/src/tui/term_output.rs +++ b/crates/turborepo-ui/src/tui/term_output.rs @@ -4,9 +4,6 @@ use turborepo_vt100 as vt100; use super::{app::Direction, Error}; -const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; -const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; - pub struct TerminalOutput { rows: u16, cols: u16, From b64d1a8dcdf1c95a1270c1e2cd61c6aebefc8760 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 08:49:52 -0600 Subject: [PATCH 10/31] Trivially working... --- crates/turborepo-ui/src/tui/app.rs | 3 +++ crates/turborepo-ui/src/tui/pane.rs | 22 ++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index d7e1eddbf4b9e..bc3ca540008d2 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -471,6 +471,8 @@ fn view(app: &mut App>, f: &mut Frame, rows: u16, cols let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(cols)]); let [table, pane] = horizontal.areas(f.size()); + let active_task = app.active_task(); + let pane_to_render: TerminalPane> = TerminalPane::new( rows, cols, @@ -479,6 +481,7 @@ fn view(app: &mut App>, f: &mut Frame, rows: u16, cols LayoutSections::TaskList => false, }, &mut app.tasks, + &active_task, ); let table_to_render = TaskTable::new( diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index 745769cece8b6..24c1a83be6457 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -14,7 +14,7 @@ const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; pub struct TerminalPane<'a, W> { - displayed_task: Option, + displayed_task: &'a String, rows: u16, cols: u16, highlight: bool, @@ -27,16 +27,17 @@ impl<'a, W> TerminalPane<'a, W> { cols: u16, highlight: bool, tasks: &'a mut BTreeMap>, + displayed_task: &'a String, ) -> Self { // We trim 2 from rows and cols as we use them for borders let rows = rows.saturating_sub(2); let cols = cols.saturating_sub(2); Self { - displayed_task: None, rows, cols, highlight, tasks, + displayed_task, } } @@ -72,13 +73,11 @@ impl<'a, W> TerminalPane<'a, W> { self.cols = cols; if changed { // Eagerly resize currently displayed terminal - if let Some(task_name) = self.displayed_task.as_deref() { - let task = self - .tasks - .get_mut(task_name) - .expect("displayed should always point to valid task"); - task.resize(rows, cols); - } + let task = self + .tasks + .get_mut(self.displayed_task) + .expect("displayed should always point to valid task"); + task.resize(rows, cols); } Ok(()) @@ -91,7 +90,7 @@ impl<'a, W> TerminalPane<'a, W> { let terminal = self.task_mut(task)?; terminal.resize(rows, cols); } - self.displayed_task = Some(task.into()); + self.displayed_task; Ok(()) } @@ -130,8 +129,7 @@ impl<'a, W> TerminalPane<'a, W> { } fn selected(&self) -> Option<(&String, &TerminalOutput)> { - let task_name = self.displayed_task.as_deref()?; - self.tasks.get_key_value(task_name) + self.tasks.get_key_value(self.displayed_task) } fn task_mut(&mut self, task: &str) -> Result<&mut TerminalOutput, Error> { From 89a89bbf24ef6a00de499f1cec7f004501fe5257 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 08:52:56 -0600 Subject: [PATCH 11/31] Correct focus on intialization. --- crates/turborepo-ui/src/tui/app.rs | 2 +- crates/turborepo-ui/src/tui/pane.rs | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index bc3ca540008d2..c35bec1d03fba 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -88,7 +88,7 @@ impl App { scroll: TableState::default().with_selected(selected_task_index), selected_task_index, has_user_interacted, - layout_focus: LayoutSections::Pane, + layout_focus: LayoutSections::TaskList, } } diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index 24c1a83be6457..f8c6e43ff0dc7 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -41,10 +41,6 @@ impl<'a, W> TerminalPane<'a, W> { } } - pub fn highlight(&mut self, highlight: bool) { - self.highlight = highlight; - } - pub fn process_output(&mut self, task: &str, output: &[u8]) -> Result<(), Error> { let task = self .task_mut(task) From 5aba68e029568b2ff1ae7871c29e0afc9b976167 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 09:03:42 -0600 Subject: [PATCH 12/31] Small cleanup. --- crates/turborepo-ui/src/tui/app.rs | 6 +---- crates/turborepo-ui/src/tui/table.rs | 33 ++++++---------------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index c35bec1d03fba..e5cb5e78779e8 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -484,11 +484,7 @@ fn view(app: &mut App>, f: &mut Frame, rows: u16, cols &active_task, ); - let table_to_render = TaskTable::new( - &app.tasks_by_status, - &app.selected_task_index, - &app.has_user_interacted, - ); + let table_to_render = TaskTable::new(&app.tasks_by_status); f.render_stateful_widget(&table_to_render, table, &mut app.scroll); f.render_widget(&pane_to_render, pane); diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index 0def4342c14d9..b2fa38cb29c05 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -4,14 +4,8 @@ use ratatui::{ text::Text, widgets::{Cell, Row, StatefulWidget, Table, TableState}, }; -use tracing::debug; -use super::{ - event::TaskResult, - spinner::SpinnerState, - task::{Task, TasksByStatus}, - Error, -}; +use super::{event::TaskResult, spinner::SpinnerState, task::TasksByStatus}; /// A widget that renders a table of their tasks and their current status /// @@ -20,22 +14,14 @@ use super::{ pub struct TaskTable<'b> { tasks_by_type: &'b TasksByStatus, spinner: SpinnerState, - selected_index: &'b usize, - user_has_interacted: &'b bool, } impl<'b> TaskTable<'b> { /// Construct a new table with all of the planned tasks - pub fn new( - tasks_by_type: &'b TasksByStatus, - selected_index: &'b usize, - user_has_interacted: &'b bool, - ) -> Self { + pub fn new(tasks_by_type: &'b TasksByStatus) -> Self { Self { - selected_index, tasks_by_type, spinner: SpinnerState::default(), - user_has_interacted, } } @@ -90,8 +76,6 @@ impl<'a> StatefulWidget for &'a TaskTable<'a> { fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer, state: &mut Self::State) { let width = area.width; - let active_index = self.selected_index; - let user_has_interacted = self.user_has_interacted; let bar = "─".repeat(usize::from(width)); let table = Table::new( self.running_rows() @@ -106,14 +90,11 @@ impl<'a> StatefulWidget for &'a TaskTable<'a> { .highlight_style(Style::default().fg(Color::Yellow)) .column_spacing(0) .header( - vec![ - format!("Tasks {active_index} {user_has_interacted}\n{bar}"), - " \n─".to_owned(), - ] - .into_iter() - .map(Cell::from) - .collect::() - .height(2), + vec![format!("Tasks\n{bar}"), " \n─".to_owned()] + .into_iter() + .map(Cell::from) + .collect::() + .height(2), ) .footer( vec![format!("{bar}\n↑ ↓ to navigate"), "─\n ".to_owned()] From 1902f47a47c6d8636b5f33a711e65d52acd67d8c Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 10:58:11 -0600 Subject: [PATCH 13/31] Correct focus handling. --- crates/turborepo-ui/src/tui/app.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index e5cb5e78779e8..68001601b08ab 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -39,7 +39,6 @@ pub struct App { tasks_by_status: TasksByStatus, selected_task_index: usize, has_user_interacted: bool, - layout_focus: LayoutSections, } pub enum Direction { @@ -88,7 +87,13 @@ impl App { scroll: TableState::default().with_selected(selected_task_index), selected_task_index, has_user_interacted, - layout_focus: LayoutSections::TaskList, + } + } + + pub fn is_focusing_pane(&self) -> bool { + match self.input_options.focus { + LayoutSections::Pane => true, + LayoutSections::TaskList => false, } } @@ -148,7 +153,6 @@ impl App { return Ok(()); } - // Find the highlighted task from before the list movement in the new list. if let Some(new_index_to_highlight) = self .tasks_by_status .task_names_in_displayed_order() @@ -476,10 +480,7 @@ fn view(app: &mut App>, f: &mut Frame, rows: u16, cols let pane_to_render: TerminalPane> = TerminalPane::new( rows, cols, - match app.layout_focus { - LayoutSections::Pane => true, - LayoutSections::TaskList => false, - }, + app.is_focusing_pane(), &mut app.tasks, &active_task, ); From 2c12ef744fa98a717461b8f6b30a40c415dd7f40 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 11:19:44 -0600 Subject: [PATCH 14/31] I win? --- crates/turborepo-ui/src/tui/app.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 68001601b08ab..9b14c363f8bdf 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -228,8 +228,6 @@ impl App { let mut task_list = tasks.into_iter().map(Task::new).collect::>(); task_list.sort_unstable(); task_list.dedup(); - - self.next(); } /// Persist all task output to the after closing the TUI From ff6f20d116dfe762a16764f3e24704b4cf1274a9 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 12:39:17 -0600 Subject: [PATCH 15/31] Simplifying. --- crates/turborepo-ui/src/tui/app.rs | 39 ++++---- crates/turborepo-ui/src/tui/task.rs | 142 +++++++++++++++++----------- 2 files changed, 106 insertions(+), 75 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 9b14c363f8bdf..bc42e319ffbe7 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -30,15 +30,14 @@ pub enum LayoutSections { } pub struct App { + // TODO: Could I reasonably get to only one representation of the tasks? tasks: BTreeMap>, - done: bool, + tasks_by_status: TasksByStatus, input_options: InputOptions, - started_tasks: Vec, - task_list: Vec, scroll: TableState, - tasks_by_status: TasksByStatus, selected_task_index: usize, - has_user_interacted: bool, + has_user_scrolled: bool, + done: bool, } pub enum Direction { @@ -50,8 +49,6 @@ impl App { pub fn new(rows: u16, cols: u16, tasks: Vec) -> Self { debug!("tasks: {tasks:?}"); - let num_of_tasks = tasks.len(); - // Initializes with the planned tasks // and will mutate as tasks change // to running, finished, etc. @@ -75,9 +72,6 @@ impl App { // Check if stdin is a tty that we should read input from tty_stdin: atty::is(atty::Stream::Stdin), }, - started_tasks: Vec::with_capacity(num_of_tasks), - // TODO: WIP, this should be able to disappear once I'm done? - task_list: tasks_by_status.task_names_in_displayed_order(), tasks: tasks_by_status .task_names_in_displayed_order() .into_iter() @@ -86,7 +80,7 @@ impl App { tasks_by_status, scroll: TableState::default().with_selected(selected_task_index), selected_task_index, - has_user_interacted, + has_user_scrolled: has_user_interacted, } } @@ -108,11 +102,11 @@ impl App { } pub fn next(&mut self) { - let num_rows = self.task_list.len(); + let num_rows = self.tasks_by_status.count_all(); let next_index = (self.selected_task_index + 1).clamp(0, num_rows - 1); self.selected_task_index = next_index; self.scroll.select(Some(next_index)); - self.has_user_interacted = true; + self.has_user_scrolled = true; } pub fn previous(&mut self) { @@ -122,7 +116,7 @@ impl App { }; self.selected_task_index = i; self.scroll.select(Some(i)); - self.has_user_interacted = true; + self.has_user_scrolled = true; } /// Mark the given task as started. @@ -149,7 +143,7 @@ impl App { self.tasks_by_status.running.push(running); // If user hasn't interacted, keep highlighting top-most task in list. - if !self.has_user_interacted { + if !self.has_user_scrolled { return Ok(()); } @@ -189,7 +183,7 @@ impl App { self.tasks_by_status.finished.push(running.finish(result)); // If user hasn't interacted, keep highlighting top-most task in list. - if !self.has_user_interacted { + if !self.has_user_scrolled { return Ok(()); } @@ -404,7 +398,10 @@ fn update( match event { Event::StartTask { task } => { app.start_task(&task)?; - app.started_tasks.push(task); + app.tasks_by_status + .groups_as_task_names() + .running + .push(task); } Event::TaskOutput { task, output } => { app.process_output(&task, &output)?; @@ -432,7 +429,7 @@ fn update( app.next(); } Event::ScrollUp => { - app.has_user_interacted = true; + app.has_user_scrolled = true; app.tasks .get_mut(&app.active_task()) .unwrap() @@ -440,7 +437,7 @@ fn update( .unwrap_or_default(); } Event::ScrollDown => { - app.has_user_interacted = true; + app.has_user_scrolled = true; app.tasks .get_mut(&app.active_task()) .unwrap() @@ -448,11 +445,11 @@ fn update( .unwrap_or_default(); } Event::EnterInteractive => { - app.has_user_interacted = true; + app.has_user_scrolled = true; app.interact(); } Event::ExitInteractive => { - app.has_user_interacted = true; + app.has_user_scrolled = true; app.interact(); } Event::Input { bytes } => { diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index ebc055c8b69e7..b62ae5b810d63 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -30,60 +30,6 @@ pub enum TaskType { Finished, } -#[derive(Clone)] -pub struct TasksByStatus { - pub running: Vec>, - pub planned: Vec>, - pub finished: Vec>, -} - -impl TasksByStatus { - pub fn all_empty(&self) -> bool { - self.planned.is_empty() && self.finished.is_empty() && self.running.is_empty() - } - - pub fn task_names_in_displayed_order(&self) -> Vec { - let running_names = self - .running - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - let planned_names = self - .planned - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - let finished_names = self - .finished - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - - [ - running_names.as_slice(), - planned_names.as_slice(), - finished_names.as_slice(), - ] - .concat() - } - - pub fn tasks_started(&self) -> Vec { - let (errors, success): (Vec<_>, Vec<_>) = self - .finished - .iter() - .partition(|task| matches!(task.result(), TaskResult::Failure)); - - // We return errors last as they most likely have information users want to see - success - .into_iter() - .map(|task| task.name()) - .chain(self.running.iter().map(|task| task.name())) - .chain(errors.into_iter().map(|task| task.name())) - .map(|task| task.to_string()) - .collect() - } -} - impl Task { pub fn name(&self) -> &str { &self.name @@ -142,3 +88,91 @@ impl Task { self.state.result } } + +pub struct TaskNamesByStatus { + pub running: Vec, + pub planned: Vec, + pub finished: Vec, +} + +#[derive(Clone)] +pub struct TasksByStatus { + pub running: Vec>, + pub planned: Vec>, + pub finished: Vec>, +} + +impl TasksByStatus { + pub fn all_empty(&self) -> bool { + self.planned.is_empty() && self.finished.is_empty() && self.running.is_empty() + } + + pub fn count_all(&self) -> usize { + self.task_names_in_displayed_order().len() + } + + pub fn groups_as_task_names(&self) -> TaskNamesByStatus { + let running = self + .running + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + let planned = self + .planned + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + let finished = self + .finished + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + + TaskNamesByStatus { + running, + planned, + finished, + } + } + + pub fn task_names_in_displayed_order(&self) -> Vec { + let running_names = self + .running + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + let planned_names = self + .planned + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + let finished_names = self + .finished + .iter() + .map(|task| task.name().to_string()) + .collect::>(); + + [ + running_names.as_slice(), + planned_names.as_slice(), + finished_names.as_slice(), + ] + .concat() + } + + pub fn tasks_started(&self) -> Vec { + let (errors, success): (Vec<_>, Vec<_>) = self + .finished + .iter() + .partition(|task| matches!(task.result(), TaskResult::Failure)); + + // We return errors last as they most likely have information users want to see + success + .into_iter() + .map(|task| task.name()) + .chain(self.running.iter().map(|task| task.name())) + .chain(errors.into_iter().map(|task| task.name())) + .map(|task| task.to_string()) + .collect() + } +} From bf5891bd74dafb420f4b83d47108ed0c7d9703d1 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Tue, 2 Jul 2024 15:14:23 -0600 Subject: [PATCH 16/31] All but one test... --- crates/turborepo-ui/examples/pane.rs | 124 ------------------ crates/turborepo-ui/examples/table.rs | 131 ------------------- crates/turborepo-ui/src/tui/app.rs | 177 ++++++++++++++++++++++++++ crates/turborepo-ui/src/tui/pane.rs | 35 ----- crates/turborepo-ui/src/tui/table.rs | 113 ---------------- 5 files changed, 177 insertions(+), 403 deletions(-) delete mode 100644 crates/turborepo-ui/examples/pane.rs delete mode 100644 crates/turborepo-ui/examples/table.rs diff --git a/crates/turborepo-ui/examples/pane.rs b/crates/turborepo-ui/examples/pane.rs deleted file mode 100644 index 289d0fd85d4e9..0000000000000 --- a/crates/turborepo-ui/examples/pane.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::{error::Error, io, sync::mpsc, time::Duration}; - -use crossterm::{ - event::KeyCode, - terminal::{disable_raw_mode, enable_raw_mode}, -}; -use ratatui::{ - backend::{Backend, CrosstermBackend}, - text::Text, - widgets::Widget, - Terminal, TerminalOptions, Viewport, -}; -use turborepo_ui::TerminalPane; - -fn main() -> Result<(), Box> { - enable_raw_mode()?; - let stdout = io::stdout(); - let backend = CrosstermBackend::new(stdout); - - let mut terminal = Terminal::with_options( - backend, - TerminalOptions { - viewport: Viewport::Inline(24), - }, - )?; - - terminal.insert_before(1, |buf| { - Text::raw("Press q to exit, use arrow keys to switch panes").render(buf.area, buf) - })?; - - let (tx, rx) = mpsc::sync_channel(1); - - std::thread::spawn(move || handle_input(tx)); - - let size = terminal.get_frame().size(); - - let pane = TerminalPane::new( - size.height, - size.width, - vec!["foo".into(), "bar".into(), "baz".into()], - ); - - run_app(&mut terminal, pane, rx)?; - - terminal.clear()?; - - // restore terminal - disable_raw_mode()?; - terminal.show_cursor()?; - println!(); - - Ok(()) -} - -fn run_app( - terminal: &mut Terminal, - mut pane: TerminalPane<()>, - rx: mpsc::Receiver, -) -> io::Result<()> { - let tasks = ["foo", "bar", "baz"]; - let mut idx: usize = 0; - pane.select("foo").unwrap(); - let mut tick = 0; - while let Ok(event) = rx.recv() { - match event { - Event::Up => { - idx = idx.saturating_sub(1); - let task = tasks[idx]; - pane.select(task).unwrap(); - } - Event::Down => { - idx = (idx + 1).clamp(0, 2); - let task = tasks[idx]; - pane.select(task).unwrap(); - } - Event::Stop => break, - Event::Tick => { - if tick % 3 == 0 { - let color = format!("\x1b[{}m", 30 + (tick % 10)); - for task in tasks { - pane.process_output( - task, - format!("{task}: {color}tick {tick}\x1b[0m\r\n").as_bytes(), - ) - .unwrap(); - } - } - } - } - terminal.draw(|f| f.render_widget(&pane, f.size()))?; - tick += 1; - } - - Ok(()) -} -enum Event { - Up, - Down, - Stop, - Tick, -} - -fn handle_input(tx: mpsc::SyncSender) -> std::io::Result<()> { - loop { - if crossterm::event::poll(Duration::from_millis(20))? { - let event = crossterm::event::read()?; - if let crossterm::event::Event::Key(key_event) = event { - if let Some(event) = match key_event.code { - KeyCode::Up => Some(Event::Up), - KeyCode::Down => Some(Event::Down), - KeyCode::Char('q') => Some(Event::Stop), - _ => None, - } { - if tx.send(event).is_err() { - break; - } - } - } - } else if tx.send(Event::Tick).is_err() { - break; - } - } - Ok(()) -} diff --git a/crates/turborepo-ui/examples/table.rs b/crates/turborepo-ui/examples/table.rs deleted file mode 100644 index e39c5272bf8dd..0000000000000 --- a/crates/turborepo-ui/examples/table.rs +++ /dev/null @@ -1,131 +0,0 @@ -use std::{error::Error, io, sync::mpsc, time::Duration}; - -use crossterm::{ - event::{KeyCode, KeyModifiers}, - terminal::{disable_raw_mode, enable_raw_mode}, -}; -use ratatui::prelude::*; -use turborepo_ui::{tui::event::TaskResult, TaskTable}; - -enum Event { - Tick(u64), - Start(&'static str), - Finish(&'static str), - Up, - Down, - Stop, -} - -fn main() -> Result<(), Box> { - enable_raw_mode()?; - let stdout = io::stdout(); - let backend = CrosstermBackend::new(stdout); - - let mut terminal = Terminal::with_options( - backend, - TerminalOptions { - viewport: Viewport::Inline(8), - }, - )?; - - let (tx, rx) = mpsc::sync_channel(1); - let input_tx = tx.clone(); - // Thread forwards user input - let input = std::thread::spawn(move || handle_input(input_tx)); - // Thread simulates starting/finishing of tasks - let events = std::thread::spawn(move || send_events(tx)); - - let table = TaskTable::new((0..6).map(|i| format!("task_{i}"))); - - run_app(&mut terminal, table, rx)?; - - events.join().expect("event thread panicked"); - input.join().expect("input thread panicked")?; - - // restore terminal - disable_raw_mode()?; - terminal.show_cursor()?; - println!(); - - Ok(()) -} - -fn run_app( - terminal: &mut Terminal, - mut table: TaskTable, - rx: mpsc::Receiver, -) -> io::Result<()> { - while let Ok(event) = rx.recv() { - match event { - Event::Tick(_) => { - table.tick(); - } - Event::Start(task) => table.start_task(task).unwrap(), - Event::Finish(task) => table.finish_task(task, TaskResult::Success).unwrap(), - Event::Up => table.previous(), - Event::Down => table.next(), - Event::Stop => break, - } - terminal.draw(|f| table.stateful_render(f, f.size()))?; - } - - Ok(()) -} - -fn send_events(tx: mpsc::SyncSender) { - let mut events = vec![ - Event::Start("task_0"), - Event::Start("task_1"), - Event::Tick(10), - Event::Start("task_2"), - Event::Tick(30), - Event::Start("task_3"), - Event::Finish("task_2"), - Event::Tick(30), - Event::Start("task_4"), - Event::Finish("task_0"), - Event::Tick(10), - Event::Finish("task_1"), - Event::Start("task_5"), - Event::Tick(30), - Event::Finish("task_3"), - Event::Finish("task_4"), - Event::Tick(50), - Event::Finish("task_5"), - Event::Stop, - ]; - events.reverse(); - while let Some(event) = events.pop() { - if let Event::Tick(ticks) = event { - std::thread::sleep(Duration::from_millis(50 * ticks)); - } - if tx.send(event).is_err() { - break; - } - } -} - -fn handle_input(tx: mpsc::SyncSender) -> std::io::Result<()> { - loop { - if crossterm::event::poll(Duration::from_millis(10))? { - let event = crossterm::event::read()?; - if let crossterm::event::Event::Key(key_event) = event { - if let Some(event) = match key_event.code { - KeyCode::Up => Some(Event::Up), - KeyCode::Down => Some(Event::Down), - KeyCode::Char('c') if key_event.modifiers == KeyModifiers::CONTROL => { - Some(Event::Stop) - } - _ => None, - } { - if tx.send(event).is_err() { - break; - } - } - } - } else if tx.send(Event::Tick(0)).is_err() { - break; - } - } - Ok(()) -} diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index bc42e319ffbe7..bf59736028ed9 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -485,3 +485,180 @@ fn view(app: &mut App>, f: &mut Frame, rows: u16, cols f.render_stateful_widget(&table_to_render, table, &mut app.scroll); f.render_widget(&pane_to_render, pane); } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_scroll() { + let mut app: App = App::new( + 100, + 100, + vec!["foo".to_string(), "bar".to_string(), "baz".to_string()], + ); + assert_eq!( + app.scroll.selected(), + Some(0), + "starts with first selection" + ); + app.next(); + assert_eq!( + app.scroll.selected(), + Some(1), + "scroll starts from 0 and goes to 1" + ); + app.previous(); + assert_eq!(app.scroll.selected(), Some(0), "scroll stays in bounds"); + app.next(); + app.next(); + assert_eq!(app.scroll.selected(), Some(2), "scroll moves forwards"); + app.next(); + assert_eq!(app.scroll.selected(), Some(2), "scroll stays in bounds"); + } + + #[test] + fn test_selection_follows() { + let mut app: App = App::new( + 100, + 100, + vec!["a".to_string(), "b".to_string(), "c".to_string()], + ); + app.next(); + assert_eq!(app.scroll.selected(), Some(1), "selected b"); + assert_eq!(app.active_task(), "b", "selected b"); + app.start_task("b").unwrap(); + assert_eq!(app.scroll.selected(), Some(0), "b stays selected"); + assert_eq!(app.active_task(), "b", "selected b"); + app.start_task("a").unwrap(); + assert_eq!(app.scroll.selected(), Some(0), "b stays selected"); + assert_eq!(app.active_task(), "b", "selected b"); + app.finish_task("a", TaskResult::Success).unwrap(); + assert_eq!(app.scroll.selected(), Some(0), "b stays selected"); + assert_eq!(app.active_task(), "b", "selected b"); + } + + #[test] + fn test_restart_task() { + let mut app: App<()> = App::new( + 100, + 100, + vec!["a".to_string(), "b".to_string(), "c".to_string()], + ); + app.next(); + app.next(); + // Start all tasks + app.start_task("b").unwrap(); + app.start_task("a").unwrap(); + app.start_task("c").unwrap(); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[0], + "b", + "b is on top (running)" + ); + app.finish_task("a", TaskResult::Success).unwrap(); + assert_eq!( + ( + &app.tasks_by_status.task_names_in_displayed_order()[2], + &app.tasks_by_status.task_names_in_displayed_order()[0] + ), + (&"a".to_string(), &"b".to_string()), + "a is on bottom (done), b is second (running)" + ); + + app.finish_task("b", TaskResult::Success).unwrap(); + assert_eq!( + ( + &app.tasks_by_status.task_names_in_displayed_order()[1], + &app.tasks_by_status.task_names_in_displayed_order()[2] + ), + (&"a".to_string(), &"b".to_string()), + "a is second (done), b is last (done)" + ); + + // Restart b + app.start_task("b").unwrap(); + assert_eq!( + ( + &app.tasks_by_status.task_names_in_displayed_order()[1], + &app.tasks_by_status.task_names_in_displayed_order()[0] + ), + (&"b".to_string(), &"c".to_string()), + "b is second (running), c is first (running)" + ); + + // Restart a + app.start_task("a").unwrap(); + assert_eq!( + ( + &app.tasks_by_status.task_names_in_displayed_order()[0], + &app.tasks_by_status.task_names_in_displayed_order()[1], + &app.tasks_by_status.task_names_in_displayed_order()[2] + ), + (&"c".to_string(), &"b".to_string(), &"a".to_string()), + "c is on top (running), b is second (running), a is third + (running)" + ); + } + + #[test] + fn test_selection_stable() { + let mut app: App = App::new( + 100, + 100, + vec!["a".to_string(), "b".to_string(), "c".to_string()], + ); + app.next(); + app.next(); + assert_eq!(app.scroll.selected(), Some(2), "selected c"); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[2], + "c", + "selected c" + ); + // start c which moves it to "running" which is before "planned" + app.start_task("c").unwrap(); + assert_eq!(app.scroll.selected(), Some(0), "selection stays on c"); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[0], + "c", + "selected c" + ); + app.start_task("a").unwrap(); + assert_eq!(app.scroll.selected(), Some(0), "selection stays on c"); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[0], + "c", + "selected c" + ); + // c + // a + // b <- + app.next(); + app.next(); + assert_eq!(app.scroll.selected(), Some(2), "selected b"); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[2], + "b", + "selected b" + ); + app.finish_task("a", TaskResult::Success).unwrap(); + assert_eq!(app.scroll.selected(), Some(1), "b stays selected"); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[1], + "b", + "selected b" + ); + // c <- + // b + // a + app.previous(); + app.finish_task("c", TaskResult::Success).unwrap(); + assert_eq!(app.scroll.selected(), Some(2), "c stays selected"); + assert_eq!( + app.tasks_by_status.task_names_in_displayed_order()[2], + "c", + "selected c" + ); + } +} diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index f8c6e43ff0dc7..7398688a43906 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -177,38 +177,3 @@ impl<'a, W> Widget for &TerminalPane<'a, W> { term.render(area, buf) } } - -// #[cfg(test)] -// mod test { -// // Used by assert_buffer_eq -// #[allow(unused_imports)] -// use indoc::indoc; -// use ratatui::{assert_buffer_eq, buffer::Buffer, layout::Rect}; -// -// use super::*; -// -// #[test] -// fn test_basic() { -// let mut pane: TerminalPane<()> = TerminalPane::new(6, 8, -// vec!["foo".into()], false); pane.select("foo").unwrap(); -// pane.process_output("foo", b"1\r\n2\r\n3\r\n4\r\n5\r\n") -// .unwrap(); -// -// let area = Rect::new(0, 0, 8, 6); -// let mut buffer = Buffer::empty(area); -// pane.render(area, &mut buffer); -// // Reset style change of the cursor -// buffer.set_style(Rect::new(1, 4, 1, 1), Style::reset()); -// assert_buffer_eq!( -// buffer, -// Buffer::with_lines(vec![ -// "│ foo > ", -// "│3 ", -// "│4 ", -// "│5 ", -// "│█ ", -// "│Press `", -// ]) -// ); -// } -// } diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index b2fa38cb29c05..7d832e776ef20 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -106,116 +106,3 @@ impl<'a> StatefulWidget for &'a TaskTable<'a> { StatefulWidget::render(table, area, buf, state); } } -// -// #[cfg(test)] -// mod test { -// use super::*; -// -// #[test] -// fn test_scroll() { -// let mut table = TaskTable::new(vec![ -// "foo".to_string(), -// "bar".to_string(), -// "baz".to_string(), -// ]); -// assert_eq!(table.scroll.selected(), None, "starts with no -// selection"); table.next(); -// assert_eq!(table.scroll.selected(), Some(0), "scroll starts from 0"); -// table.previous(); -// assert_eq!(table.scroll.selected(), Some(0), "scroll stays in -// bounds"); table.next(); -// table.next(); -// assert_eq!(table.scroll.selected(), Some(2), "scroll moves -// forwards"); table.next(); -// assert_eq!(table.scroll.selected(), Some(2), "scroll stays in -// bounds"); } -// -// #[test] -// fn test_selection_follows() { -// let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), -// "c".to_string()]); table.next(); -// table.next(); -// assert_eq!(table.scroll.selected(), Some(1), "selected b"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// table.start_task("b").unwrap(); -// assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// table.start_task("a").unwrap(); -// assert_eq!(table.scroll.selected(), Some(0), "b stays selected"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// table.finish_task("a", TaskResult::Success).unwrap(); -// assert_eq!(table.scroll.selected(), Some(1), "b stays selected"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// } -// -// #[test] -// fn test_restart_task() { -// let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), -// "c".to_string()]); table.next(); -// table.next(); -// // Start all tasks -// table.start_task("b").unwrap(); -// table.start_task("a").unwrap(); -// table.start_task("c").unwrap(); -// assert_eq!(table.get(0), Some("b"), "b is on top (running)"); -// table.finish_task("a", TaskResult::Success).unwrap(); -// assert_eq!( -// (table.get(0), table.get(1)), -// (Some("a"), Some("b")), -// "a is on top (done), b is second (running)" -// ); -// -// table.finish_task("b", TaskResult::Success).unwrap(); -// assert_eq!( -// (table.get(0), table.get(1)), -// (Some("a"), Some("b")), -// "a is on top (done), b is second (done)" -// ); -// -// // Restart b -// table.start_task("b").unwrap(); -// assert_eq!( -// (table.get(1), table.get(2)), -// (Some("c"), Some("b")), -// "b is third (running)" -// ); -// -// // Restart a -// table.start_task("a").unwrap(); -// assert_eq!( -// (table.get(0), table.get(1), table.get(2)), -// (Some("c"), Some("b"), Some("a")), -// "c is on top (running), b is second (running), a is third -// (running)" ); -// } -// -// #[test] -// fn test_selection_stable() { -// let mut table = TaskTable::new(vec!["a".to_string(), "b".to_string(), -// "c".to_string()]); table.next(); -// table.next(); -// assert_eq!(table.scroll.selected(), Some(1), "selected b"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// // start c which moves it to "running" which is before "planned" -// table.start_task("c").unwrap(); -// assert_eq!(table.scroll.selected(), Some(2), "selection stays on b"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// table.start_task("a").unwrap(); -// assert_eq!(table.scroll.selected(), Some(2), "selection stays on b"); -// assert_eq!(table.selected(), Some("b"), "selected b"); -// // c -// // a -// // b <- -// table.previous(); -// table.previous(); -// assert_eq!(table.scroll.selected(), Some(0), "selected c"); -// assert_eq!(table.selected(), Some("c"), "selected c"); -// table.finish_task("a", TaskResult::Success).unwrap(); -// assert_eq!(table.scroll.selected(), Some(1), "c stays selected"); -// assert_eq!(table.selected(), Some("c"), "selected c"); -// table.previous(); -// table.finish_task("c", TaskResult::Success).unwrap(); -// assert_eq!(table.scroll.selected(), Some(0), "a stays selected"); -// assert_eq!(table.selected(), Some("a"), "selected a"); -// } -// } From 5fb167a9f96002002036b796ff0c055ad7a5fafc Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 07:24:12 -0600 Subject: [PATCH 17/31] Update crates/turborepo-ui/src/tui/app.rs Co-authored-by: Chris Olszewski --- crates/turborepo-ui/src/tui/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index bf59736028ed9..0a35de926c372 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -282,7 +282,7 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { let ratio_pane_width = (f32::from(size.width) * PANE_SIZE_RATIO) as u16; let full_task_width = size.width.saturating_sub(task_width_hint); - let mut app: App> = App::new(size.height, size.width, tasks); + let mut app: App> = App::new(size.height, full_task_width.max(ratio_pane_width), tasks); let (result, callback) = match run_app_inner( &mut terminal, From f2ca89e71a66278eea28c978b8422f8c85e282c6 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 07:53:10 -0600 Subject: [PATCH 18/31] Answering to code review, 1. --- crates/turborepo-ui/src/tui/app.rs | 13 +++++-------- crates/turborepo-ui/src/tui/input.rs | 3 ++- crates/turborepo-ui/src/tui/task.rs | 24 ------------------------ 3 files changed, 7 insertions(+), 33 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 0a35de926c372..e3798dc9f0589 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -24,13 +24,13 @@ use crate::tui::{ term_output::TerminalOutput, }; +#[derive(Debug, Clone, Copy)] pub enum LayoutSections { Pane, TaskList, } pub struct App { - // TODO: Could I reasonably get to only one representation of the tasks? tasks: BTreeMap>, tasks_by_status: TasksByStatus, input_options: InputOptions, @@ -282,7 +282,8 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { let ratio_pane_width = (f32::from(size.width) * PANE_SIZE_RATIO) as u16; let full_task_width = size.width.saturating_sub(task_width_hint); - let mut app: App> = App::new(size.height, full_task_width.max(ratio_pane_width), tasks); + let mut app: App> = + App::new(size.height, full_task_width.max(ratio_pane_width), tasks); let (result, callback) = match run_app_inner( &mut terminal, @@ -313,7 +314,7 @@ fn run_app_inner( terminal.draw(|f| view(app, f, rows, cols))?; let mut last_render = Instant::now(); let mut callback = None; - while let Some(event) = poll(&app.input_options, &receiver, last_render + FRAMERATE) { + while let Some(event) = poll(app.input_options, &receiver, last_render + FRAMERATE) { callback = update(app, event)?; if app.done { break; @@ -329,7 +330,7 @@ fn run_app_inner( /// Blocking poll for events, will only return None if app handle has been /// dropped -fn poll(input_options: &InputOptions, receiver: &AppReceiver, deadline: Instant) -> Option { +fn poll(input_options: InputOptions, receiver: &AppReceiver, deadline: Instant) -> Option { match input(input_options) { Ok(Some(event)) => Some(event), Ok(None) => receiver.recv(deadline).ok(), @@ -398,10 +399,6 @@ fn update( match event { Event::StartTask { task } => { app.start_task(&task)?; - app.tasks_by_status - .groups_as_task_names() - .running - .push(task); } Event::TaskOutput { task, output } => { app.process_output(&task, &output)?; diff --git a/crates/turborepo-ui/src/tui/input.rs b/crates/turborepo-ui/src/tui/input.rs index 3ace134a5bcd7..be8747672ec62 100644 --- a/crates/turborepo-ui/src/tui/input.rs +++ b/crates/turborepo-ui/src/tui/input.rs @@ -4,12 +4,13 @@ use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; use super::{app::LayoutSections, event::Event, Error}; +#[derive(Debug, Clone, Copy)] pub struct InputOptions { pub focus: LayoutSections, pub tty_stdin: bool, } /// Return any immediately available event -pub fn input(options: &InputOptions) -> Result, Error> { +pub fn input(options: InputOptions) -> Result, Error> { let InputOptions { focus, tty_stdin } = options; // If stdin is not a tty, then we do not attempt to read from it if !tty_stdin { diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index b62ae5b810d63..a784f02263b74 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -111,30 +111,6 @@ impl TasksByStatus { self.task_names_in_displayed_order().len() } - pub fn groups_as_task_names(&self) -> TaskNamesByStatus { - let running = self - .running - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - let planned = self - .planned - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - let finished = self - .finished - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - - TaskNamesByStatus { - running, - planned, - finished, - } - } - pub fn task_names_in_displayed_order(&self) -> Vec { let running_names = self .running From 4100d2652f0f64fecddd085a5ec10dd038639d3a Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 08:43:35 -0600 Subject: [PATCH 19/31] Feedback, 2. --- crates/turborepo-ui/src/tui/app.rs | 18 +-- crates/turborepo-ui/src/tui/pane.rs | 146 ++---------------- .../.eslintrc.js | 4 + .../child/child.js | 2 + .../package-lock.json | 58 +++++++ .../package.json | 6 + .../peer.js | 1 + .../turbo.json | 35 +++++ .../.eslintrc.js | 4 + .../child/child.js | 2 + .../package-lock.json | 58 +++++++ .../package.json | 6 + .../peer.js | 1 + .../turbo.json | 35 +++++ .../packages/tsconfig/package.json | 5 + .../packages/ui/package.json | 7 + .../package.json | 8 + .../yarn.lock | 4 + .../bun.lockb | Bin 0 -> 3506 bytes .../package.json | 9 ++ .../package.json | 8 + .../pnpm-lock.yaml | 33 ++++ .../apps/docs/package.json | 11 ++ .../apps/web/package.json | 11 ++ .../bun.lockb | Bin 0 -> 2235 bytes .../package.json | 14 ++ .../apps/docs/package.json | 11 ++ .../apps/web/package.json | 11 ++ .../package.json | 14 ++ .../packages/tsconfig/package.json | 5 + .../packages/ui/package.json | 7 + .../yarn.lock | 4 + .../package-lock.json | 12 ++ .../package.json | 6 + 34 files changed, 407 insertions(+), 149 deletions(-) create mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js create mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js create mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json create mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json create mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js create mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json create mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js create mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js create mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json create mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json create mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js create mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json create mode 100644 packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json create mode 100644 packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json create mode 100644 packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json create mode 100644 packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock create mode 100755 packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/bun.lockb create mode 100644 packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json create mode 100644 packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json create mode 100644 packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml create mode 100644 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json create mode 100644 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json create mode 100755 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/bun.lockb create mode 100644 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/package.json create mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json create mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json create mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json create mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json create mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json create mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock create mode 100644 packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json create mode 100644 packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index e3798dc9f0589..23826fdce3050 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -289,7 +289,6 @@ pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { &mut terminal, &mut app, receiver, - size.height, full_task_width.max(ratio_pane_width), ) { Ok(callback) => (Ok(()), callback), @@ -307,11 +306,10 @@ fn run_app_inner( terminal: &mut Terminal, app: &mut App>, receiver: AppReceiver, - rows: u16, cols: u16, ) -> Result>, Error> { // Render initial state to paint the screen - terminal.draw(|f| view(app, f, rows, cols))?; + terminal.draw(|f| view(app, f, cols))?; let mut last_render = Instant::now(); let mut callback = None; while let Some(event) = poll(app.input_options, &receiver, last_render + FRAMERATE) { @@ -320,7 +318,7 @@ fn run_app_inner( break; } if FRAMERATE <= last_render.elapsed() { - terminal.draw(|f| view(app, f, rows, cols))?; + terminal.draw(|f| view(app, f, cols))?; last_render = Instant::now(); } } @@ -463,19 +461,15 @@ fn update( Ok(None) } -fn view(app: &mut App>, f: &mut Frame, rows: u16, cols: u16) { +fn view(app: &mut App>, f: &mut Frame, cols: u16) { let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(cols)]); let [table, pane] = horizontal.areas(f.size()); let active_task = app.active_task(); - let pane_to_render: TerminalPane> = TerminalPane::new( - rows, - cols, - app.is_focusing_pane(), - &mut app.tasks, - &active_task, - ); + let output_logs = app.tasks.get(&active_task).unwrap(); + let pane_to_render: TerminalPane> = + TerminalPane::new(output_logs, &active_task, app.is_focusing_pane()); let table_to_render = TaskTable::new(&app.tasks_by_status); diff --git a/crates/turborepo-ui/src/tui/pane.rs b/crates/turborepo-ui/src/tui/pane.rs index 7398688a43906..ff34d52142476 100644 --- a/crates/turborepo-ui/src/tui/pane.rs +++ b/crates/turborepo-ui/src/tui/pane.rs @@ -1,157 +1,32 @@ -use std::{collections::BTreeMap, io::Write}; - use ratatui::{ style::Style, text::Line, widgets::{Block, Borders, Widget}, }; -use tracing::debug; use tui_term::widget::PseudoTerminal; -use super::{app::Direction, Error, TerminalOutput}; +use super::TerminalOutput; const FOOTER_TEXT_ACTIVE: &str = "Press`Ctrl-Z` to stop interacting."; const FOOTER_TEXT_INACTIVE: &str = "Press `Enter` to interact."; pub struct TerminalPane<'a, W> { - displayed_task: &'a String, - rows: u16, - cols: u16, + terminal_output: &'a TerminalOutput, + task_name: &'a str, highlight: bool, - tasks: &'a mut BTreeMap>, } impl<'a, W> TerminalPane<'a, W> { pub fn new( - rows: u16, - cols: u16, + terminal_output: &'a TerminalOutput, + task_name: &'a str, highlight: bool, - tasks: &'a mut BTreeMap>, - displayed_task: &'a String, ) -> Self { - // We trim 2 from rows and cols as we use them for borders - let rows = rows.saturating_sub(2); - let cols = cols.saturating_sub(2); Self { - rows, - cols, + terminal_output, highlight, - tasks, - displayed_task, - } - } - - pub fn process_output(&mut self, task: &str, output: &[u8]) -> Result<(), Error> { - let task = self - .task_mut(task) - .inspect_err(|_| debug!("cannot find task on process output"))?; - task.parser.process(output); - Ok(()) - } - - pub fn hassss_stdin(&self, task: &str) -> bool { - self.tasks - .get(task) - .map(|task| task.stdin.is_some()) - .unwrap_or_default() - } - - pub fn has_stdin(&self, task: &str) -> bool { - self.tasks - .get(task) - .map(|task| task.stdin.is_some()) - .unwrap_or_default() - } - - pub fn resize(&mut self, rows: u16, cols: u16) -> Result<(), Error> { - let changed = self.rows != rows || self.cols != cols; - self.rows = rows; - self.cols = cols; - if changed { - // Eagerly resize currently displayed terminal - let task = self - .tasks - .get_mut(self.displayed_task) - .expect("displayed should always point to valid task"); - task.resize(rows, cols); - } - - Ok(()) - } - - pub fn select(&mut self, task: &str) -> Result<(), Error> { - let rows = self.rows; - let cols = self.cols; - { - let terminal = self.task_mut(task)?; - terminal.resize(rows, cols); - } - self.displayed_task; - - Ok(()) - } - - pub fn set_status(&mut self, task: &str, status: String) -> Result<(), Error> { - let task = self.task_mut(task)?; - task.status = Some(status); - Ok(()) - } - - pub fn scroll(&mut self, task: &str, direction: Direction) -> Result<(), Error> { - let task = self.task_mut(task)?; - let scrollback = task.parser.screen().scrollback(); - let new_scrollback = match direction { - Direction::Up => scrollback + 1, - Direction::Down => scrollback.saturating_sub(1), - }; - task.parser.screen_mut().set_scrollback(new_scrollback); - Ok(()) - } - - /// Persist all task output to the terminal - pub fn persist_tasks(&mut self, started_tasks: &[&str]) -> std::io::Result<()> { - for (task_name, task) in started_tasks - .iter() - .copied() - .filter_map(|started_task| (Some(started_task)).zip(self.tasks.get(started_task))) - { - task.persist_screen(task_name)?; - } - Ok(()) - } - - pub fn term_size(&self) -> (u16, u16) { - (self.rows, self.cols) - } - - fn selected(&self) -> Option<(&String, &TerminalOutput)> { - self.tasks.get_key_value(self.displayed_task) - } - - fn task_mut(&mut self, task: &str) -> Result<&mut TerminalOutput, Error> { - self.tasks.get_mut(task).ok_or_else(|| Error::TaskNotFound { - name: task.to_string(), - }) - } -} - -impl<'a, W: Write> TerminalPane<'a, W> { - /// Insert a stdin to be associated with a task - pub fn insert_stdin(&mut self, task_name: &str, stdin: Option) -> Result<(), Error> { - let task = self.task_mut(task_name)?; - task.stdin = stdin; - Ok(()) - } - - pub fn process_input(&mut self, task: &str, input: &[u8]) -> Result<(), Error> { - let task_output = self.task_mut(task)?; - if let Some(stdin) = &mut task_output.stdin { - stdin.write_all(input).map_err(|e| Error::Stdin { - name: task.into(), - e, - })?; + task_name, } - Ok(()) } } @@ -160,13 +35,10 @@ impl<'a, W> Widget for &TerminalPane<'a, W> { where Self: Sized, { - let Some((task_name, task)) = self.selected() else { - return; - }; - let screen = task.parser.screen(); + let screen = self.terminal_output.parser.screen(); let mut block = Block::default() .borders(Borders::LEFT) - .title(task.title(task_name)); + .title(self.terminal_output.title(self.task_name)); if self.highlight { block = block.title_bottom(Line::from(FOOTER_TEXT_ACTIVE).centered()); block = block.border_style(Style::new().fg(ratatui::style::Color::Yellow)); diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js new file mode 100644 index 0000000000000..8dc66dca7067c --- /dev/null +++ b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ["plugin:turbo/recommended"], +}; diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js new file mode 100644 index 0000000000000..9e799a23c8a10 --- /dev/null +++ b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js @@ -0,0 +1,2 @@ +process.env.NONEXISTENT; +process.env.CI; diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json new file mode 100644 index 0000000000000..fc022e93cc969 --- /dev/null +++ b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json @@ -0,0 +1,58 @@ +{ + "name": "workspace", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "eslint-plugin-turbo": "../../" + } + }, + "../..": { + "version": "1.9.0", + "license": "MPL-2.0", + "devDependencies": { + "@turbo/test-utils": "workspace:*", + "@turbo/tsconfig": "workspace:*", + "@turbo/types": "workspace:*", + "@turbo/utils": "workspace:*", + "@types/eslint": "^8.4.5", + "@types/estree": "^1.0.0", + "@types/jest": "^27.4.0", + "@types/node": "^16.11.12", + "jest": "^27.4.3", + "json5": "^2.2.1", + "ts-jest": "^27.1.1", + "tsup": "^6.2.0", + "typescript": "5.3.3" + }, + "peerDependencies": { + "eslint": ">6.6.0" + } + }, + "node_modules/eslint-plugin-turbo": { + "resolved": "../..", + "link": true + } + }, + "dependencies": { + "eslint-plugin-turbo": { + "version": "file:../..", + "requires": { + "@turbo/test-utils": "workspace:*", + "@turbo/tsconfig": "workspace:*", + "@turbo/types": "workspace:*", + "@turbo/utils": "workspace:*", + "@types/eslint": "^8.4.5", + "@types/estree": "^1.0.0", + "@types/jest": "^27.4.0", + "@types/node": "^16.11.12", + "jest": "^27.4.3", + "json5": "^2.2.1", + "ts-jest": "^27.1.1", + "tsup": "^6.2.0", + "typescript": "5.3.3" + } + } + } +} diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json new file mode 100644 index 0000000000000..4dca370603c1b --- /dev/null +++ b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "eslint": "8.57.0", + "eslint-plugin-turbo": "../../" + } +} diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js new file mode 100644 index 0000000000000..16c8bb0522bbf --- /dev/null +++ b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js @@ -0,0 +1 @@ +process.env.CI; diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json new file mode 100644 index 0000000000000..6c6bcf357d80a --- /dev/null +++ b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalEnv": ["UNORDERED", "CI"], + "globalDotEnv": [".env", "missing.env"], + "pipeline": { + "build": { + // A workspace's `build` task depends on that workspace's + // topological dependencies' and devDependencies' + // `build` tasks being completed first. The `^` symbol + // indicates an upstream dependency. + "dependsOn": ["^build"] + }, + "test": { + // A workspace's `test` task depends on that workspace's + // own `build` task being completed first. + "dependsOn": ["build"], + "outputs": [], + // A workspace's `test` task should only be rerun when + // either a `.tsx` or `.ts` file has changed. + "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] + }, + "lint": { + // A workspace's `lint` task has no dependencies and + // can be run whenever. + "outputs": [] + }, + "deploy": { + // A workspace's `deploy` task depends on the `build`, + // `test`, and `lint` tasks of the same workspace + // being completed. + "dependsOn": ["build", "test", "lint"], + "outputs": [] + } + } +} diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js new file mode 100644 index 0000000000000..8dc66dca7067c --- /dev/null +++ b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ["plugin:turbo/recommended"], +}; diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js new file mode 100644 index 0000000000000..9e799a23c8a10 --- /dev/null +++ b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js @@ -0,0 +1,2 @@ +process.env.NONEXISTENT; +process.env.CI; diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json new file mode 100644 index 0000000000000..fc022e93cc969 --- /dev/null +++ b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json @@ -0,0 +1,58 @@ +{ + "name": "workspace", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "eslint-plugin-turbo": "../../" + } + }, + "../..": { + "version": "1.9.0", + "license": "MPL-2.0", + "devDependencies": { + "@turbo/test-utils": "workspace:*", + "@turbo/tsconfig": "workspace:*", + "@turbo/types": "workspace:*", + "@turbo/utils": "workspace:*", + "@types/eslint": "^8.4.5", + "@types/estree": "^1.0.0", + "@types/jest": "^27.4.0", + "@types/node": "^16.11.12", + "jest": "^27.4.3", + "json5": "^2.2.1", + "ts-jest": "^27.1.1", + "tsup": "^6.2.0", + "typescript": "5.3.3" + }, + "peerDependencies": { + "eslint": ">6.6.0" + } + }, + "node_modules/eslint-plugin-turbo": { + "resolved": "../..", + "link": true + } + }, + "dependencies": { + "eslint-plugin-turbo": { + "version": "file:../..", + "requires": { + "@turbo/test-utils": "workspace:*", + "@turbo/tsconfig": "workspace:*", + "@turbo/types": "workspace:*", + "@turbo/utils": "workspace:*", + "@types/eslint": "^8.4.5", + "@types/estree": "^1.0.0", + "@types/jest": "^27.4.0", + "@types/node": "^16.11.12", + "jest": "^27.4.3", + "json5": "^2.2.1", + "ts-jest": "^27.1.1", + "tsup": "^6.2.0", + "typescript": "5.3.3" + } + } + } +} diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json new file mode 100644 index 0000000000000..4dca370603c1b --- /dev/null +++ b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "eslint": "8.57.0", + "eslint-plugin-turbo": "../../" + } +} diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js new file mode 100644 index 0000000000000..16c8bb0522bbf --- /dev/null +++ b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js @@ -0,0 +1 @@ +process.env.CI; diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json new file mode 100644 index 0000000000000..6c6bcf357d80a --- /dev/null +++ b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalEnv": ["UNORDERED", "CI"], + "globalDotEnv": [".env", "missing.env"], + "pipeline": { + "build": { + // A workspace's `build` task depends on that workspace's + // topological dependencies' and devDependencies' + // `build` tasks being completed first. The `^` symbol + // indicates an upstream dependency. + "dependsOn": ["^build"] + }, + "test": { + // A workspace's `test` task depends on that workspace's + // own `build` task being completed first. + "dependsOn": ["build"], + "outputs": [], + // A workspace's `test` task should only be rerun when + // either a `.tsx` or `.ts` file has changed. + "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] + }, + "lint": { + // A workspace's `lint` task has no dependencies and + // can be run whenever. + "outputs": [] + }, + "deploy": { + // A workspace's `deploy` task depends on the `build`, + // `test`, and `lint` tasks of the same workspace + // being completed. + "dependsOn": ["build", "test", "lint"], + "outputs": [] + } + } +} diff --git a/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json b/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json new file mode 100644 index 0000000000000..0d32af30031af --- /dev/null +++ b/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json @@ -0,0 +1,5 @@ +{ + "name": "tsconfig", + "version": "1.0.0", + "private": true +} diff --git a/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json b/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json new file mode 100644 index 0000000000000..1e05d1a8ecc65 --- /dev/null +++ b/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json @@ -0,0 +1,7 @@ +{ + "name": "ui", + "version": "0.0.0", + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json b/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json new file mode 100644 index 0000000000000..970aa3eb898a2 --- /dev/null +++ b/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json @@ -0,0 +1,8 @@ +{ + "name": "yarn", + "version": "0.0.0", + "private": true, + "dependencies": {}, + "devDependencies": {}, + "packageManager": "yarn@1.22.19" +} diff --git a/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock b/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock new file mode 100644 index 0000000000000..fb57ccd13afbd --- /dev/null +++ b/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + diff --git a/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/bun.lockb b/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..69d76bb9ab0d6034a786c2fdc1a3abe6f6158e95 GIT binary patch literal 3506 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_lOexn&z2 z7c4aBDxD>D{JVS6>76EtEj!yzZ|Z+J{e@4yr4lbt5fE@dC=9v*DxLvTzyP!iELKul zl#~x-^#ZXl14BbCkQM;aIY3$vNXG$bJ|OJ_q=kUAEs*91(gzyvtvq|r`pV-gj|Bb* zh9q=XvCO#QW-Kf8GH9i1&GZN<&oJ>+rpuFV^4pw0^nmqjf<1$^^!aQhohkQ-_bI(kqVQ@{NJa zC)kYt>6e<;>YId*i0=vNjL4waX7Q|JWR2;=EQo&++KvTj#mU?s&@mexB2>2+ZH0 zFyv?e(#${%11#QCKY5B@yTQ5K_nE1peP`Lewngin9nFxM8yLSXYs#-xtM0tqKW{JF z#G~RrmYi68vwzK9=6mx3!W06}y)0m#u`Up35Xim2as)^s0Lvu>uYD?Qj+}`%UfgVu zX6tjlzF7LAveavxZKo~wa4xRq>uLNlt#MgM$1+Jhm;1SI794-{uYXPFjVHHRO(%pO zehW62fdgbNE5cX?mJ2#FW))4|yi(@){!W+L=QdtV^G)aOIIGxyu>bEW+15oWI#(Jb z*!H=pNuFP@Td}zAsB7Z0UDy0d&FVvzDC-?71DneNb}J|?!T?LfDNgQ})(tH?y0f}p zZCbXbh0T8H>Tksr3-5exC`@nIa;7Uw<>tX|?W);o=lq_;UuU`~=fb(}=#%ubJi^m| ztOJE9D11R-087^(vsw0KK9Kyjtt?DGek*HOxsHjko`35%jX(YBNy)#Z??0=)Fn3D* zo%Uvd%s9#Dp6(xkXKyTDEF->()3z>9jj^jF9%Kj>07@IM@*E@$EE^j@^gxM$>?Rf< z=NDr2jH)9X0vn(;{t+n6Wm8;~te2TrT#}fRqX%nl=!F!errIeO87LHIR;A{r=_r^e zB<5tM=jEq?Dpe@>_a6d4Tu^%c05y{bR0#tCmrbd$ksVMg4nsh33`(P*d;!W6pgau9 zZx&GfAw-x1G6Q5cNFPW)$Q+P)AagsQ`t6`@=CX-4GK(#>0D8;}?j}Q2kHPW=tR2I_ zl#^JJT3o`w0Bh;MS}ZJ#hI)nudWOcJ`WoC8g0*Q7GO*SXtkr{%$pPvCwWnb1B7_XA z#RY3QA!J}}GFaORA=3f%A&f?i)#B9LveY6y*NT$VqP)bM;F6-uymUJSLqs50zyo0i z)Fdfr!wDFN!0m`F}$UTFnf9>PPC25L^pFE55Gfbqdf2suj^ zMK#=!D5A(tCfYnR6AZ)5Oh_^b$)j+iki^I^3&~BeFeS+pXiR|v7VacuL2^t(auhrz MAe#fsD1#CJ05LtO!~g&Q literal 0 HcmV?d00001 diff --git a/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json b/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json new file mode 100644 index 0000000000000..324b7ae1b3e02 --- /dev/null +++ b/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json @@ -0,0 +1,9 @@ +{ + "name": "bun", + "version": "0.0.0", + "private": true, + "dependencies": {}, + "devDependencies": { + "turbo": "latest" + } +} diff --git a/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json b/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json new file mode 100644 index 0000000000000..27935c2559d14 --- /dev/null +++ b/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json @@ -0,0 +1,8 @@ +{ + "name": "pnpm", + "version": "0.0.0", + "private": true, + "dependencies": {}, + "devDependencies": {}, + "packageManager": "pnpm@1.2.3" +} diff --git a/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml b/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml new file mode 100644 index 0000000000000..84c04af90e76b --- /dev/null +++ b/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml @@ -0,0 +1,33 @@ +lockfileVersion: 5.4 + +importers: + + .: + specifiers: {} + + apps/docs: + specifiers: + tsconfig: workspace:* + ui: workspace:* + dependencies: + ui: link:../../packages/ui + devDependencies: + tsconfig: link:../../packages/tsconfig + + apps/web: + specifiers: + tsconfig: workspace:* + ui: workspace:* + dependencies: + ui: link:../../packages/ui + devDependencies: + tsconfig: link:../../packages/tsconfig + + packages/tsconfig: + specifiers: {} + + packages/ui: + specifiers: + tsconfig: workspace:* + devDependencies: + tsconfig: link:../tsconfig diff --git a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json new file mode 100644 index 0000000000000..d3a490ca892f8 --- /dev/null +++ b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json @@ -0,0 +1,11 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json new file mode 100644 index 0000000000000..163cee3e51e6c --- /dev/null +++ b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json @@ -0,0 +1,11 @@ +{ + "name": "web", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/bun.lockb b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..11dacfe2b9a15eefadebfa9492b4d74360c48491 GIT binary patch literal 2235 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p-7I-6W9 zP8@6Y`d#tdWmk0Cui4Ud`+ZZVIMoEV#GUoC)8+sw0s>YD#Q^2P=?18HAxr_7&&R;f zP@b9uW|w9{l#~=F=jWwmrl;g57lTA%X3U)OeQ~L3+*8(5U%E7VB95-uP#s{=e(7X> z(c7HsLd(w2`5oExwTuy>onZo$-oYf2F&}8#Dky*ooDK^?0o62+t6vAYF2GKC~1gKe6(87buCfdj>w$uXX zFEhBC3{m|BEAL_DxdI!kB!krmuo7Q^4OT|N>I_(&puh$zePOi=14.0.0" + }, + "dependencies": {}, + "packageManager": "bun@1.0.1" +} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json new file mode 100644 index 0000000000000..d3a490ca892f8 --- /dev/null +++ b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json @@ -0,0 +1,11 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json new file mode 100644 index 0000000000000..163cee3e51e6c --- /dev/null +++ b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json @@ -0,0 +1,11 @@ +{ + "name": "web", + "version": "0.0.0", + "private": true, + "dependencies": { + "ui": "*" + }, + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json new file mode 100644 index 0000000000000..002944bd73343 --- /dev/null +++ b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json @@ -0,0 +1,14 @@ +{ + "name": "yarn-workspaces", + "version": "0.0.0", + "private": true, + "workspaces": [ + "apps/*", + "packages/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "dependencies": {}, + "packageManager": "yarn@1.22.19" +} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json new file mode 100644 index 0000000000000..3f406290b4667 --- /dev/null +++ b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json @@ -0,0 +1,5 @@ +{ + "name": "tsconfig", + "version": "0.0.0", + "private": true +} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json new file mode 100644 index 0000000000000..1e05d1a8ecc65 --- /dev/null +++ b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json @@ -0,0 +1,7 @@ +{ + "name": "ui", + "version": "0.0.0", + "devDependencies": { + "tsconfig": "*" + } +} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock new file mode 100644 index 0000000000000..fb57ccd13afbd --- /dev/null +++ b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + diff --git a/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json b/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json new file mode 100644 index 0000000000000..067bf2152cf6e --- /dev/null +++ b/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json @@ -0,0 +1,12 @@ +{ + "name": "npm", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "npm", + "version": "0.0.0" + } + } +} diff --git a/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json b/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json new file mode 100644 index 0000000000000..47f30c6da0600 --- /dev/null +++ b/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json @@ -0,0 +1,6 @@ +{ + "name": "npm", + "version": "0.0.0", + "private": true, + "packageManager": "npm@8.19.4" +} From ac6ea6dd2b42d32eee40741c72bd3cfdb0389dc9 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 08:48:16 -0600 Subject: [PATCH 20/31] Thanks eslint, very cool. --- .../.eslintrc.js | 4 -- .../child/child.js | 2 - .../package-lock.json | 58 ------------------- .../package.json | 6 -- .../peer.js | 1 - .../turbo.json | 35 ----------- .../.eslintrc.js | 4 -- .../child/child.js | 2 - .../package-lock.json | 58 ------------------- .../package.json | 6 -- .../peer.js | 1 - .../turbo.json | 35 ----------- 12 files changed, 212 deletions(-) delete mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js delete mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js delete mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json delete mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json delete mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js delete mode 100644 packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json delete mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js delete mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js delete mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json delete mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json delete mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js delete mode 100644 packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js deleted file mode 100644 index 8dc66dca7067c..0000000000000 --- a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - root: true, - extends: ["plugin:turbo/recommended"], -}; diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js deleted file mode 100644 index 9e799a23c8a10..0000000000000 --- a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/child/child.js +++ /dev/null @@ -1,2 +0,0 @@ -process.env.NONEXISTENT; -process.env.CI; diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json deleted file mode 100644 index fc022e93cc969..0000000000000 --- a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package-lock.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "workspace", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "eslint-plugin-turbo": "../../" - } - }, - "../..": { - "version": "1.9.0", - "license": "MPL-2.0", - "devDependencies": { - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "5.3.3" - }, - "peerDependencies": { - "eslint": ">6.6.0" - } - }, - "node_modules/eslint-plugin-turbo": { - "resolved": "../..", - "link": true - } - }, - "dependencies": { - "eslint-plugin-turbo": { - "version": "file:../..", - "requires": { - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "5.3.3" - } - } - } -} diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json deleted file mode 100644 index 4dca370603c1b..0000000000000 --- a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "devDependencies": { - "eslint": "8.57.0", - "eslint-plugin-turbo": "../../" - } -} diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js deleted file mode 100644 index 16c8bb0522bbf..0000000000000 --- a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/peer.js +++ /dev/null @@ -1 +0,0 @@ -process.env.CI; diff --git a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json b/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json deleted file mode 100644 index 6c6bcf357d80a..0000000000000 --- a/packages/eslint-plugin-turbo/1d67dc0d-eb4a-4d30-90bb-5b92769af1e1/3db10458-dfa8-4219-943e-98af073d78c1/turbo.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalEnv": ["UNORDERED", "CI"], - "globalDotEnv": [".env", "missing.env"], - "pipeline": { - "build": { - // A workspace's `build` task depends on that workspace's - // topological dependencies' and devDependencies' - // `build` tasks being completed first. The `^` symbol - // indicates an upstream dependency. - "dependsOn": ["^build"] - }, - "test": { - // A workspace's `test` task depends on that workspace's - // own `build` task being completed first. - "dependsOn": ["build"], - "outputs": [], - // A workspace's `test` task should only be rerun when - // either a `.tsx` or `.ts` file has changed. - "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] - }, - "lint": { - // A workspace's `lint` task has no dependencies and - // can be run whenever. - "outputs": [] - }, - "deploy": { - // A workspace's `deploy` task depends on the `build`, - // `test`, and `lint` tasks of the same workspace - // being completed. - "dependsOn": ["build", "test", "lint"], - "outputs": [] - } - } -} diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js deleted file mode 100644 index 8dc66dca7067c..0000000000000 --- a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - root: true, - extends: ["plugin:turbo/recommended"], -}; diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js deleted file mode 100644 index 9e799a23c8a10..0000000000000 --- a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/child/child.js +++ /dev/null @@ -1,2 +0,0 @@ -process.env.NONEXISTENT; -process.env.CI; diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json deleted file mode 100644 index fc022e93cc969..0000000000000 --- a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package-lock.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "workspace", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "eslint-plugin-turbo": "../../" - } - }, - "../..": { - "version": "1.9.0", - "license": "MPL-2.0", - "devDependencies": { - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "5.3.3" - }, - "peerDependencies": { - "eslint": ">6.6.0" - } - }, - "node_modules/eslint-plugin-turbo": { - "resolved": "../..", - "link": true - } - }, - "dependencies": { - "eslint-plugin-turbo": { - "version": "file:../..", - "requires": { - "@turbo/test-utils": "workspace:*", - "@turbo/tsconfig": "workspace:*", - "@turbo/types": "workspace:*", - "@turbo/utils": "workspace:*", - "@types/eslint": "^8.4.5", - "@types/estree": "^1.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.12", - "jest": "^27.4.3", - "json5": "^2.2.1", - "ts-jest": "^27.1.1", - "tsup": "^6.2.0", - "typescript": "5.3.3" - } - } - } -} diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json deleted file mode 100644 index 4dca370603c1b..0000000000000 --- a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "devDependencies": { - "eslint": "8.57.0", - "eslint-plugin-turbo": "../../" - } -} diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js deleted file mode 100644 index 16c8bb0522bbf..0000000000000 --- a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/peer.js +++ /dev/null @@ -1 +0,0 @@ -process.env.CI; diff --git a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json b/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json deleted file mode 100644 index 6c6bcf357d80a..0000000000000 --- a/packages/eslint-plugin-turbo/4e380a7d-d1fe-4bec-906a-dca8a8fbc371/d90bb164-33de-4ed3-8e58-ba82c1698a86/turbo.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "globalEnv": ["UNORDERED", "CI"], - "globalDotEnv": [".env", "missing.env"], - "pipeline": { - "build": { - // A workspace's `build` task depends on that workspace's - // topological dependencies' and devDependencies' - // `build` tasks being completed first. The `^` symbol - // indicates an upstream dependency. - "dependsOn": ["^build"] - }, - "test": { - // A workspace's `test` task depends on that workspace's - // own `build` task being completed first. - "dependsOn": ["build"], - "outputs": [], - // A workspace's `test` task should only be rerun when - // either a `.tsx` or `.ts` file has changed. - "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] - }, - "lint": { - // A workspace's `lint` task has no dependencies and - // can be run whenever. - "outputs": [] - }, - "deploy": { - // A workspace's `deploy` task depends on the `build`, - // `test`, and `lint` tasks of the same workspace - // being completed. - "dependsOn": ["build", "test", "lint"], - "outputs": [] - } - } -} From ec4791fd889e5e6ab4c873e772160029d914e02b Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 08:49:13 -0600 Subject: [PATCH 21/31] eslint very cool. --- .../packages/tsconfig/package.json | 5 --- .../packages/ui/package.json | 7 ---- .../package.json | 8 ----- .../yarn.lock | 4 --- .../bun.lockb | Bin 3506 -> 0 bytes .../package.json | 9 ----- .../package.json | 8 ----- .../pnpm-lock.yaml | 33 ------------------ .../apps/docs/package.json | 11 ------ .../apps/web/package.json | 11 ------ .../bun.lockb | Bin 2235 -> 0 bytes .../package.json | 14 -------- .../apps/docs/package.json | 11 ------ .../apps/web/package.json | 11 ------ .../package.json | 14 -------- .../packages/tsconfig/package.json | 5 --- .../packages/ui/package.json | 7 ---- .../yarn.lock | 4 --- .../package-lock.json | 12 ------- .../package.json | 6 ---- 20 files changed, 180 deletions(-) delete mode 100644 packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json delete mode 100644 packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock delete mode 100755 packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/bun.lockb delete mode 100644 packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json delete mode 100644 packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json delete mode 100644 packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml delete mode 100644 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json delete mode 100755 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/bun.lockb delete mode 100644 packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/package.json delete mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json delete mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json delete mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json delete mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json delete mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json delete mode 100644 packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock delete mode 100644 packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json delete mode 100644 packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json diff --git a/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json b/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json deleted file mode 100644 index 0d32af30031af..0000000000000 --- a/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/tsconfig/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "tsconfig", - "version": "1.0.0", - "private": true -} diff --git a/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json b/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json deleted file mode 100644 index 1e05d1a8ecc65..0000000000000 --- a/packages/turbo-workspaces/0fc7d570-ac7d-4aba-8337-36c5bf3c4522/c586c49d-e47e-4d98-98e2-197f39201b41/packages/ui/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ui", - "version": "0.0.0", - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json b/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json deleted file mode 100644 index 970aa3eb898a2..0000000000000 --- a/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "yarn", - "version": "0.0.0", - "private": true, - "dependencies": {}, - "devDependencies": {}, - "packageManager": "yarn@1.22.19" -} diff --git a/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock b/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock deleted file mode 100644 index fb57ccd13afbd..0000000000000 --- a/packages/turbo-workspaces/16a9ce55-2ccf-4ab6-a0f4-b13049c37e85/bd089582-52c7-40a3-b0ad-87be95914b2a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - diff --git a/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/bun.lockb b/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/bun.lockb deleted file mode 100755 index 69d76bb9ab0d6034a786c2fdc1a3abe6f6158e95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3506 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_lOexn&z2 z7c4aBDxD>D{JVS6>76EtEj!yzZ|Z+J{e@4yr4lbt5fE@dC=9v*DxLvTzyP!iELKul zl#~x-^#ZXl14BbCkQM;aIY3$vNXG$bJ|OJ_q=kUAEs*91(gzyvtvq|r`pV-gj|Bb* zh9q=XvCO#QW-Kf8GH9i1&GZN<&oJ>+rpuFV^4pw0^nmqjf<1$^^!aQhohkQ-_bI(kqVQ@{NJa zC)kYt>6e<;>YId*i0=vNjL4waX7Q|JWR2;=EQo&++KvTj#mU?s&@mexB2>2+ZH0 zFyv?e(#${%11#QCKY5B@yTQ5K_nE1peP`Lewngin9nFxM8yLSXYs#-xtM0tqKW{JF z#G~RrmYi68vwzK9=6mx3!W06}y)0m#u`Up35Xim2as)^s0Lvu>uYD?Qj+}`%UfgVu zX6tjlzF7LAveavxZKo~wa4xRq>uLNlt#MgM$1+Jhm;1SI794-{uYXPFjVHHRO(%pO zehW62fdgbNE5cX?mJ2#FW))4|yi(@){!W+L=QdtV^G)aOIIGxyu>bEW+15oWI#(Jb z*!H=pNuFP@Td}zAsB7Z0UDy0d&FVvzDC-?71DneNb}J|?!T?LfDNgQ})(tH?y0f}p zZCbXbh0T8H>Tksr3-5exC`@nIa;7Uw<>tX|?W);o=lq_;UuU`~=fb(}=#%ubJi^m| ztOJE9D11R-087^(vsw0KK9Kyjtt?DGek*HOxsHjko`35%jX(YBNy)#Z??0=)Fn3D* zo%Uvd%s9#Dp6(xkXKyTDEF->()3z>9jj^jF9%Kj>07@IM@*E@$EE^j@^gxM$>?Rf< z=NDr2jH)9X0vn(;{t+n6Wm8;~te2TrT#}fRqX%nl=!F!errIeO87LHIR;A{r=_r^e zB<5tM=jEq?Dpe@>_a6d4Tu^%c05y{bR0#tCmrbd$ksVMg4nsh33`(P*d;!W6pgau9 zZx&GfAw-x1G6Q5cNFPW)$Q+P)AagsQ`t6`@=CX-4GK(#>0D8;}?j}Q2kHPW=tR2I_ zl#^JJT3o`w0Bh;MS}ZJ#hI)nudWOcJ`WoC8g0*Q7GO*SXtkr{%$pPvCwWnb1B7_XA z#RY3QA!J}}GFaORA=3f%A&f?i)#B9LveY6y*NT$VqP)bM;F6-uymUJSLqs50zyo0i z)Fdfr!wDFN!0m`F}$UTFnf9>PPC25L^pFE55Gfbqdf2suj^ zMK#=!D5A(tCfYnR6AZ)5Oh_^b$)j+iki^I^3&~BeFeS+pXiR|v7VacuL2^t(auhrz MAe#fsD1#CJ05LtO!~g&Q diff --git a/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json b/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json deleted file mode 100644 index 324b7ae1b3e02..0000000000000 --- a/packages/turbo-workspaces/787ad597-2d93-4418-84c9-6b6d9ade936d/b3fd8bd3-a83e-480f-9ca2-b8a9d084a2e6/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "bun", - "version": "0.0.0", - "private": true, - "dependencies": {}, - "devDependencies": { - "turbo": "latest" - } -} diff --git a/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json b/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json deleted file mode 100644 index 27935c2559d14..0000000000000 --- a/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "pnpm", - "version": "0.0.0", - "private": true, - "dependencies": {}, - "devDependencies": {}, - "packageManager": "pnpm@1.2.3" -} diff --git a/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml b/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml deleted file mode 100644 index 84c04af90e76b..0000000000000 --- a/packages/turbo-workspaces/79d32db2-668f-4dc1-a6d2-b60d7bd35ba4/efd57d0d-d9d6-47d8-a903-53309101a1ac/pnpm-lock.yaml +++ /dev/null @@ -1,33 +0,0 @@ -lockfileVersion: 5.4 - -importers: - - .: - specifiers: {} - - apps/docs: - specifiers: - tsconfig: workspace:* - ui: workspace:* - dependencies: - ui: link:../../packages/ui - devDependencies: - tsconfig: link:../../packages/tsconfig - - apps/web: - specifiers: - tsconfig: workspace:* - ui: workspace:* - dependencies: - ui: link:../../packages/ui - devDependencies: - tsconfig: link:../../packages/tsconfig - - packages/tsconfig: - specifiers: {} - - packages/ui: - specifiers: - tsconfig: workspace:* - devDependencies: - tsconfig: link:../tsconfig diff --git a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json deleted file mode 100644 index d3a490ca892f8..0000000000000 --- a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/docs/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "docs", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json deleted file mode 100644 index 163cee3e51e6c..0000000000000 --- a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/apps/web/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "web", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/bun.lockb b/packages/turbo-workspaces/84987077-008d-4b21-b4fb-a43c6198740c/5c0e8b9d-2475-4462-b9f6-e160e0a24eb6/bun.lockb deleted file mode 100755 index 11dacfe2b9a15eefadebfa9492b4d74360c48491..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2235 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p-7I-6W9 zP8@6Y`d#tdWmk0Cui4Ud`+ZZVIMoEV#GUoC)8+sw0s>YD#Q^2P=?18HAxr_7&&R;f zP@b9uW|w9{l#~=F=jWwmrl;g57lTA%X3U)OeQ~L3+*8(5U%E7VB95-uP#s{=e(7X> z(c7HsLd(w2`5oExwTuy>onZo$-oYf2F&}8#Dky*ooDK^?0o62+t6vAYF2GKC~1gKe6(87buCfdj>w$uXX zFEhBC3{m|BEAL_DxdI!kB!krmuo7Q^4OT|N>I_(&puh$zePOi=14.0.0" - }, - "dependencies": {}, - "packageManager": "bun@1.0.1" -} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json deleted file mode 100644 index d3a490ca892f8..0000000000000 --- a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/docs/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "docs", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json deleted file mode 100644 index 163cee3e51e6c..0000000000000 --- a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/apps/web/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "web", - "version": "0.0.0", - "private": true, - "dependencies": { - "ui": "*" - }, - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json deleted file mode 100644 index 002944bd73343..0000000000000 --- a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "yarn-workspaces", - "version": "0.0.0", - "private": true, - "workspaces": [ - "apps/*", - "packages/*" - ], - "engines": { - "node": ">=14.0.0" - }, - "dependencies": {}, - "packageManager": "yarn@1.22.19" -} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json deleted file mode 100644 index 3f406290b4667..0000000000000 --- a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/tsconfig/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "tsconfig", - "version": "0.0.0", - "private": true -} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json deleted file mode 100644 index 1e05d1a8ecc65..0000000000000 --- a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/packages/ui/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ui", - "version": "0.0.0", - "devDependencies": { - "tsconfig": "*" - } -} diff --git a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock b/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock deleted file mode 100644 index fb57ccd13afbd..0000000000000 --- a/packages/turbo-workspaces/ba358ccf-f5e8-4877-8ce5-d412d0dc48cb/6993968d-edb1-4154-8796-0f4a993eca63/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - diff --git a/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json b/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json deleted file mode 100644 index 067bf2152cf6e..0000000000000 --- a/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package-lock.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "npm", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "npm", - "version": "0.0.0" - } - } -} diff --git a/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json b/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json deleted file mode 100644 index 47f30c6da0600..0000000000000 --- a/packages/turbo-workspaces/f9070aa5-c5e2-4aa6-acd0-baa69afab672/419d783b-49b6-4544-b287-2f9d3a265f84/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "npm", - "version": "0.0.0", - "private": true, - "packageManager": "npm@8.19.4" -} From 706ec2a4a5367ebbcafefe63f86355144f4617f1 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 08:54:39 -0600 Subject: [PATCH 22/31] Fixing up types. --- crates/turborepo-ui/src/tui/app.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 23826fdce3050..ef1ba54d85bd4 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -461,14 +461,14 @@ fn update( Ok(None) } -fn view(app: &mut App>, f: &mut Frame, cols: u16) { +fn view(app: &mut App, f: &mut Frame, cols: u16) { let horizontal = Layout::horizontal([Constraint::Fill(1), Constraint::Length(cols)]); let [table, pane] = horizontal.areas(f.size()); let active_task = app.active_task(); let output_logs = app.tasks.get(&active_task).unwrap(); - let pane_to_render: TerminalPane> = + let pane_to_render: TerminalPane = TerminalPane::new(output_logs, &active_task, app.is_focusing_pane()); let table_to_render = TaskTable::new(&app.tasks_by_status); From 79f65a3f3d62a3576957a47749c7e2c56ef1cfb2 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 08:58:39 -0600 Subject: [PATCH 23/31] Move term scrolling logic to App. --- crates/turborepo-ui/src/tui/app.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index ef1ba54d85bd4..a273855fedd1c 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -7,7 +7,7 @@ use std::{ use ratatui::{ backend::{Backend, CrosstermBackend}, - layout::{Constraint, Layout}, + layout::{Constraint, Direction, Layout}, widgets::TableState, Frame, Terminal, }; @@ -119,6 +119,14 @@ impl App { self.has_user_scrolled = true; } + pub fn scroll_terminal_output(&mut self, direction: Direction) { + self.tasks + .get_mut(&self.active_task()) + .unwrap() + .scroll(direction) + .unwrap_or_default(); + } + /// Mark the given task as started. /// If planned, pulls it from planned tasks and starts it. /// If finished, removes from finished and starts again as new task. @@ -425,19 +433,11 @@ fn update( } Event::ScrollUp => { app.has_user_scrolled = true; - app.tasks - .get_mut(&app.active_task()) - .unwrap() - .scroll(Direction::Up) - .unwrap_or_default(); + app.scroll_terminal_output(Direction::Up) } Event::ScrollDown => { app.has_user_scrolled = true; - app.tasks - .get_mut(&app.active_task()) - .unwrap() - .scroll(Direction::Down) - .unwrap_or_default(); + app.scroll_terminal_output(Direction::Down) } Event::EnterInteractive => { app.has_user_scrolled = true; From 39b11a6f63baf5f4d723c9b5dd66be8e911b1bd1 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 09:02:51 -0600 Subject: [PATCH 24/31] Make clippy happy. --- crates/turborepo-ui/src/tui/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index a273855fedd1c..0a957e212f6e5 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -7,7 +7,7 @@ use std::{ use ratatui::{ backend::{Backend, CrosstermBackend}, - layout::{Constraint, Direction, Layout}, + layout::{Constraint, Layout}, widgets::TableState, Frame, Terminal, }; From 6e7a8a262bb47feea3d05bea7585d7c45912e6a2 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Wed, 3 Jul 2024 08:46:11 -0700 Subject: [PATCH 25/31] fix: overwrite state on task list update --- crates/turborepo-ui/src/tui/app.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 0a957e212f6e5..78f6cfb3e363e 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -31,6 +31,8 @@ pub enum LayoutSections { } pub struct App { + rows: u16, + cols: u16, tasks: BTreeMap>, tasks_by_status: TasksByStatus, input_options: InputOptions, @@ -66,6 +68,8 @@ impl App { let selected_task_index: usize = 0; Self { + rows, + cols, done: false, input_options: InputOptions { focus: LayoutSections::TaskList, @@ -227,9 +231,23 @@ impl App { } pub fn update_tasks(&mut self, tasks: Vec) { + // Make sure all tasks have a terminal output + for task in &tasks { + self.tasks + .entry(task.clone()) + .or_insert_with(|| TerminalOutput::new(self.rows, self.cols, None)); + } + // Trim the terminal output to only tasks that exist in new list + self.tasks.retain(|name, _| tasks.contains(name)); + // Update task list let mut task_list = tasks.into_iter().map(Task::new).collect::>(); task_list.sort_unstable(); task_list.dedup(); + self.tasks_by_status = TasksByStatus { + planned: task_list, + running: Default::default(), + finished: Default::default(), + }; } /// Persist all task output to the after closing the TUI From 3cc43d6474c1ad65d12596f92f20fdb858e88bb7 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Wed, 3 Jul 2024 09:50:40 -0600 Subject: [PATCH 26/31] Still have a bad type but trying to fix starting watch mode tasks. --- crates/turborepo-ui/src/tui/app.rs | 32 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 78f6cfb3e363e..5ac7f9dcc5284 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -140,19 +140,35 @@ impl App { let highlighted_task = &self.tasks_by_status.task_names_in_displayed_order()[self.selected_task_index]; - let planned_idx = self + let found_task = false; + + if let Some(planned_idx) = self .tasks_by_status .planned .iter() .position(|planned| planned.name() == task) - .ok_or_else(|| { - debug!("could not find '{task}' to start"); - Error::TaskNotFound { name: task.into() } - })?; + { + let planned = self.tasks_by_status.planned.remove(planned_idx); + let running = planned.start(); + self.tasks_by_status.running.push(running); + + found_task = true; + } else if let Some(finished_idx) = self + .tasks_by_status + .finished + .iter() + .position(|finished| finished.name() == task) + { + let finished = self.tasks_by_status.finished.remove(finished_idx); + let finished = finished.start(); + self.tasks_by_status.running.push(finished); - let planned = self.tasks_by_status.planned.remove(planned_idx); - let running = planned.start(); - self.tasks_by_status.running.push(running); + found_task = true; + } + + if !found_task { + return Err(Error::TaskNotFound { name: task.into() }); + } // If user hasn't interacted, keep highlighting top-most task in list. if !self.has_user_scrolled { From dc7bdc5dc32c5f0730653189d1a035020f88c551 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Wed, 3 Jul 2024 09:14:13 -0700 Subject: [PATCH 27/31] fix: compile works --- crates/turborepo-ui/src/tui/app.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 5ac7f9dcc5284..0ac7897751fc7 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -140,7 +140,7 @@ impl App { let highlighted_task = &self.tasks_by_status.task_names_in_displayed_order()[self.selected_task_index]; - let found_task = false; + let mut found_task = false; if let Some(planned_idx) = self .tasks_by_status @@ -159,9 +159,10 @@ impl App { .iter() .position(|finished| finished.name() == task) { - let finished = self.tasks_by_status.finished.remove(finished_idx); - let finished = finished.start(); - self.tasks_by_status.running.push(finished); + let _finished = self.tasks_by_status.finished.remove(finished_idx); + self.tasks_by_status + .running + .push(Task::new(task.to_owned()).start()); found_task = true; } From f2d0f5165a71104b60739660d417000226e94b7c Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Wed, 3 Jul 2024 12:59:32 -0700 Subject: [PATCH 28/31] chore(tui): slight refactor to avoid allocations --- crates/turborepo-ui/src/tui/app.rs | 86 +++++++++++------------------ crates/turborepo-ui/src/tui/task.rs | 35 ++++-------- 2 files changed, 43 insertions(+), 78 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 0ac7897751fc7..81326c30b0f68 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -79,7 +79,7 @@ impl App { tasks: tasks_by_status .task_names_in_displayed_order() .into_iter() - .map(|task_name| (task_name, TerminalOutput::new(rows, cols, None))) + .map(|task_name| (task_name.to_owned(), TerminalOutput::new(rows, cols, None))) .collect(), tasks_by_status, scroll: TableState::default().with_selected(selected_task_index), @@ -97,8 +97,8 @@ impl App { pub fn active_task(&self) -> String { self.tasks_by_status - .task_names_in_displayed_order() - .remove(self.selected_task_index) + .task_name(self.selected_task_index) + .to_string() } pub fn get_full_task_mut(&mut self) -> &mut TerminalOutput { @@ -137,8 +137,10 @@ impl App { pub fn start_task(&mut self, task: &str) -> Result<(), Error> { // Name of currently highlighted task. // We will use this after the order switches. - let highlighted_task = - &self.tasks_by_status.task_names_in_displayed_order()[self.selected_task_index]; + let highlighted_task = self + .tasks_by_status + .task_name(self.selected_task_index) + .to_string(); let mut found_task = false; @@ -179,7 +181,6 @@ impl App { if let Some(new_index_to_highlight) = self .tasks_by_status .task_names_in_displayed_order() - .iter() .position(|running| running == highlighted_task) { self.selected_task_index = new_index_to_highlight; @@ -194,8 +195,10 @@ impl App { pub fn finish_task(&mut self, task: &str, result: TaskResult) -> Result<(), Error> { // Name of currently highlighted task. // We will use this after the order switches. - let highlighted_task = - &self.tasks_by_status.task_names_in_displayed_order()[self.selected_task_index]; + let highlighted_task = self + .tasks_by_status + .task_name(self.selected_task_index) + .to_string(); let running_idx = self .tasks_by_status @@ -220,8 +223,7 @@ impl App { if let Some(new_index_to_highlight) = self .tasks_by_status .task_names_in_displayed_order() - .iter() - .position(|running| running == highlighted_task) + .position(|running| running == highlighted_task.as_str()) { self.selected_task_index = new_index_to_highlight; self.scroll.select(Some(new_index_to_highlight)); @@ -578,27 +580,27 @@ mod test { app.start_task("a").unwrap(); app.start_task("c").unwrap(); assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[0], + app.tasks_by_status.task_name(0), "b", "b is on top (running)" ); app.finish_task("a", TaskResult::Success).unwrap(); assert_eq!( ( - &app.tasks_by_status.task_names_in_displayed_order()[2], - &app.tasks_by_status.task_names_in_displayed_order()[0] + app.tasks_by_status.task_name(2), + app.tasks_by_status.task_name(0) ), - (&"a".to_string(), &"b".to_string()), + ("a", "b"), "a is on bottom (done), b is second (running)" ); app.finish_task("b", TaskResult::Success).unwrap(); assert_eq!( ( - &app.tasks_by_status.task_names_in_displayed_order()[1], - &app.tasks_by_status.task_names_in_displayed_order()[2] + app.tasks_by_status.task_name(1), + app.tasks_by_status.task_name(2) ), - (&"a".to_string(), &"b".to_string()), + ("a", "b"), "a is second (done), b is last (done)" ); @@ -606,10 +608,10 @@ mod test { app.start_task("b").unwrap(); assert_eq!( ( - &app.tasks_by_status.task_names_in_displayed_order()[1], - &app.tasks_by_status.task_names_in_displayed_order()[0] + app.tasks_by_status.task_name(1), + app.tasks_by_status.task_name(0) ), - (&"b".to_string(), &"c".to_string()), + ("b", "c"), "b is second (running), c is first (running)" ); @@ -617,11 +619,11 @@ mod test { app.start_task("a").unwrap(); assert_eq!( ( - &app.tasks_by_status.task_names_in_displayed_order()[0], - &app.tasks_by_status.task_names_in_displayed_order()[1], - &app.tasks_by_status.task_names_in_displayed_order()[2] + app.tasks_by_status.task_name(0), + app.tasks_by_status.task_name(1), + app.tasks_by_status.task_name(2) ), - (&"c".to_string(), &"b".to_string(), &"a".to_string()), + ("c", "b", "a"), "c is on top (running), b is second (running), a is third (running)" ); @@ -637,54 +639,30 @@ mod test { app.next(); app.next(); assert_eq!(app.scroll.selected(), Some(2), "selected c"); - assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[2], - "c", - "selected c" - ); + assert_eq!(app.tasks_by_status.task_name(2), "c", "selected c"); // start c which moves it to "running" which is before "planned" app.start_task("c").unwrap(); assert_eq!(app.scroll.selected(), Some(0), "selection stays on c"); - assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[0], - "c", - "selected c" - ); + assert_eq!(app.tasks_by_status.task_name(0), "c", "selected c"); app.start_task("a").unwrap(); assert_eq!(app.scroll.selected(), Some(0), "selection stays on c"); - assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[0], - "c", - "selected c" - ); + assert_eq!(app.tasks_by_status.task_name(0), "c", "selected c"); // c // a // b <- app.next(); app.next(); assert_eq!(app.scroll.selected(), Some(2), "selected b"); - assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[2], - "b", - "selected b" - ); + assert_eq!(app.tasks_by_status.task_name(2), "b", "selected b"); app.finish_task("a", TaskResult::Success).unwrap(); assert_eq!(app.scroll.selected(), Some(1), "b stays selected"); - assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[1], - "b", - "selected b" - ); + assert_eq!(app.tasks_by_status.task_name(1), "b", "selected b"); // c <- // b // a app.previous(); app.finish_task("c", TaskResult::Success).unwrap(); assert_eq!(app.scroll.selected(), Some(2), "c stays selected"); - assert_eq!( - app.tasks_by_status.task_names_in_displayed_order()[2], - "c", - "selected c" - ); + assert_eq!(app.tasks_by_status.task_name(2), "c", "selected c"); } } diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index a784f02263b74..44f67a117e522 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -108,32 +108,19 @@ impl TasksByStatus { } pub fn count_all(&self) -> usize { - self.task_names_in_displayed_order().len() + self.task_names_in_displayed_order().count() } - pub fn task_names_in_displayed_order(&self) -> Vec { - let running_names = self - .running - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - let planned_names = self - .planned - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - let finished_names = self - .finished - .iter() - .map(|task| task.name().to_string()) - .collect::>(); - - [ - running_names.as_slice(), - planned_names.as_slice(), - finished_names.as_slice(), - ] - .concat() + pub fn task_names_in_displayed_order(&self) -> impl Iterator + '_ { + let running_names = self.running.iter().map(|task| task.name()); + let planned_names = self.planned.iter().map(|task| task.name()); + let finished_names = self.finished.iter().map(|task| task.name()); + + running_names.chain(planned_names).chain(finished_names) + } + + pub fn task_name(&self, index: usize) -> &str { + self.task_names_in_displayed_order().nth(index).unwrap() } pub fn tasks_started(&self) -> Vec { From b2f22c840b1fc962b0f2d0b6068605e5de36da6b Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Wed, 3 Jul 2024 13:12:51 -0700 Subject: [PATCH 29/31] fix clippy --- crates/turborepo-ui/src/tui/app.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 81326c30b0f68..d25ec1d9cbde2 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -78,7 +78,6 @@ impl App { }, tasks: tasks_by_status .task_names_in_displayed_order() - .into_iter() .map(|task_name| (task_name.to_owned(), TerminalOutput::new(rows, cols, None))) .collect(), tasks_by_status, From 5064f8ee4a35f60cc25b33bf32890367656be9ec Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Wed, 3 Jul 2024 13:40:26 -0700 Subject: [PATCH 30/31] fix(tui): fix stdin/status setting, add tests --- crates/turborepo-ui/src/tui/app.rs | 79 ++++++++++++++++++++++++--- crates/turborepo-ui/src/tui/event.rs | 2 + crates/turborepo-ui/src/tui/handle.rs | 16 +++++- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index d25ec1d9cbde2..4294e591d8af6 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -278,8 +278,13 @@ impl App { Ok(()) } - pub fn set_status(&mut self, status: String) -> Result<(), Error> { - let task = self.get_full_task_mut(); + pub fn set_status(&mut self, task: String, status: String) -> Result<(), Error> { + let task = self + .tasks + .get_mut(&task) + .ok_or_else(|| Error::TaskNotFound { + name: task.to_owned(), + })?; task.status = Some(status); Ok(()) } @@ -287,8 +292,13 @@ impl App { impl App { /// Insert a stdin to be associated with a task - pub fn insert_stdin(&mut self, stdin: Option) -> Result<(), Error> { - let task = self.get_full_task_mut(); + pub fn insert_stdin(&mut self, task: &str, stdin: Option) -> Result<(), Error> { + let task = self + .tasks + .get_mut(task) + .ok_or_else(|| Error::TaskNotFound { + name: task.to_owned(), + })?; task.stdin = stdin; Ok(()) } @@ -445,8 +455,8 @@ fn update( Event::TaskOutput { task, output } => { app.process_output(&task, &output)?; } - Event::Status { status } => { - app.set_status(status)?; + Event::Status { task, status } => { + app.set_status(task, status)?; } Event::InternalStop => { app.done = true; @@ -486,8 +496,8 @@ fn update( Event::Input { bytes } => { app.forward_input(&bytes)?; } - Event::SetStdin { stdin } => { - app.insert_stdin(Some(stdin))?; + Event::SetStdin { task, stdin } => { + app.insert_stdin(&task, Some(stdin))?; } Event::UpdateTasks { tasks } => { app.update_tasks(tasks); @@ -664,4 +674,57 @@ mod test { assert_eq!(app.scroll.selected(), Some(2), "c stays selected"); assert_eq!(app.tasks_by_status.task_name(2), "c", "selected c"); } + + #[test] + fn test_forward_stdin() { + let mut app: App> = App::new(100, 100, vec!["a".to_string(), "b".to_string()]); + app.next(); + assert_eq!(app.scroll.selected(), Some(1), "selected b"); + assert_eq!(app.tasks_by_status.task_name(1), "b", "selected b"); + // start c which moves it to "running" which is before "planned" + app.start_task("a").unwrap(); + app.start_task("b").unwrap(); + app.insert_stdin("a", Some(Vec::new())).unwrap(); + app.insert_stdin("b", Some(Vec::new())).unwrap(); + + // Interact and type "hello" + app.interact(); + app.forward_input(b"hello!").unwrap(); + + // Exit interaction and move up + app.interact(); + app.previous(); + app.interact(); + app.forward_input(b"world").unwrap(); + + assert_eq!( + app.tasks.get("b").unwrap().stdin.as_deref().unwrap(), + b"hello!" + ); + assert_eq!( + app.tasks.get("a").unwrap().stdin.as_deref().unwrap(), + b"world" + ); + } + + #[test] + fn test_interact() { + let mut app: App> = App::new(100, 100, vec!["a".to_string(), "b".to_string()]); + assert!(!app.is_focusing_pane(), "app starts focused on table"); + app.insert_stdin("a", Some(Vec::new())).unwrap(); + + app.interact(); + assert!(app.is_focusing_pane(), "can focus pane when task has stdin"); + + app.interact(); + assert!( + !app.is_focusing_pane(), + "interact changes focus to table if focused on pane" + ); + + app.next(); + assert!(!app.is_focusing_pane(), "pane isn't focused after move"); + app.interact(); + assert!(!app.is_focusing_pane(), "cannot focus task without stdin"); + } } diff --git a/crates/turborepo-ui/src/tui/event.rs b/crates/turborepo-ui/src/tui/event.rs index c4f0b892b9ae7..5f6e5cee6e345 100644 --- a/crates/turborepo-ui/src/tui/event.rs +++ b/crates/turborepo-ui/src/tui/event.rs @@ -11,6 +11,7 @@ pub enum Event { result: TaskResult, }, Status { + task: String, status: String, }, Stop(std::sync::mpsc::SyncSender<()>), @@ -22,6 +23,7 @@ pub enum Event { ScrollUp, ScrollDown, SetStdin { + task: String, stdin: Box, }, EnterInteractive, diff --git a/crates/turborepo-ui/src/tui/handle.rs b/crates/turborepo-ui/src/tui/handle.rs index c07681cb14c8b..59dd8d9682807 100644 --- a/crates/turborepo-ui/src/tui/handle.rs +++ b/crates/turborepo-ui/src/tui/handle.rs @@ -116,7 +116,13 @@ impl TuiTask { } pub fn set_stdin(&self, stdin: Box) { - self.handle.primary.send(Event::SetStdin { stdin }).ok(); + self.handle + .primary + .send(Event::SetStdin { + task: self.name.clone(), + stdin, + }) + .ok(); } pub fn status(&self, status: &str) { @@ -124,7 +130,13 @@ impl TuiTask { // handled. // TODO: prevent the status from having ANSI codes in this scenario let status = console::strip_ansi_codes(status).into_owned(); - self.handle.primary.send(Event::Status { status }).ok(); + self.handle + .primary + .send(Event::Status { + task: self.name.clone(), + status, + }) + .ok(); } } From be9a430186ff90fb74c9887ceca5df6ab54368ea Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Wed, 3 Jul 2024 14:00:38 -0700 Subject: [PATCH 31/31] chore(tui): add test for setting status --- crates/turborepo-ui/src/tui/app.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 4294e591d8af6..cd7a61cf7978f 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -727,4 +727,21 @@ mod test { app.interact(); assert!(!app.is_focusing_pane(), "cannot focus task without stdin"); } + + #[test] + fn test_task_status() { + let mut app: App> = App::new(100, 100, vec!["a".to_string(), "b".to_string()]); + app.next(); + assert_eq!(app.scroll.selected(), Some(1), "selected b"); + assert_eq!(app.tasks_by_status.task_name(1), "b", "selected b"); + // set status for a + app.set_status("a".to_string(), "building".to_string()) + .unwrap(); + + assert_eq!( + app.tasks.get("a").unwrap().status.as_deref(), + Some("building") + ); + assert!(app.tasks.get("b").unwrap().status.is_none()); + } }