node.rs

 1use std::{borrow::Cow, path::Path};
 2
 3use anyhow::{Result, bail};
 4use async_trait::async_trait;
 5use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
 6use gpui::SharedString;
 7
 8use task::{DebugScenario, SpawnInTerminal, TaskTemplate, VariableName};
 9
10pub(crate) struct NodeLocator;
11
12const TYPESCRIPT_RUNNER_VARIABLE: VariableName =
13    VariableName::Custom(Cow::Borrowed("TYPESCRIPT_RUNNER"));
14const TYPESCRIPT_JEST_TASK_VARIABLE: VariableName =
15    VariableName::Custom(Cow::Borrowed("TYPESCRIPT_JEST"));
16
17#[async_trait]
18impl DapLocator for NodeLocator {
19    fn name(&self) -> SharedString {
20        SharedString::new_static("Node")
21    }
22
23    /// Determines whether this locator can generate debug target for given task.
24    fn create_scenario(
25        &self,
26        build_config: &TaskTemplate,
27        resolved_label: &str,
28        adapter: DebugAdapterName,
29    ) -> Option<DebugScenario> {
30        if adapter.0.as_ref() != "JavaScript" {
31            return None;
32        }
33        if build_config.command != TYPESCRIPT_RUNNER_VARIABLE.template_value() {
34            return None;
35        }
36        let test_library = build_config.args.first()?;
37        let program_path = Path::new("$ZED_WORKTREE_ROOT")
38            .join("node_modules")
39            .join(".bin")
40            .join(test_library);
41
42        let mut args = if test_library == "jest"
43            || test_library == &TYPESCRIPT_JEST_TASK_VARIABLE.template_value()
44        {
45            vec!["--runInBand".to_owned()]
46        } else {
47            vec![]
48        };
49        args.extend(build_config.args[1..].iter().cloned());
50
51        let config = serde_json::json!({
52            "request": "launch",
53            "type": "pwa-node",
54            "runtimeExecutable": program_path,
55            "args": args,
56            "cwd": build_config.cwd.clone(),
57            "env": {
58                "VITEST_MIN_FORKS": "0",
59                "VITEST_MAX_FORKS": "1"
60            },
61            "runtimeArgs": ["--inspect-brk"],
62            "console": "integratedTerminal",
63        });
64
65        Some(DebugScenario {
66            adapter: adapter.0,
67            label: resolved_label.to_string().into(),
68            build: None,
69            config,
70            tcp_connection: None,
71        })
72    }
73
74    async fn run(&self, _: SpawnInTerminal) -> Result<DebugRequest> {
75        bail!("JavaScript locator should not require DapLocator::run to be ran");
76    }
77}