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"));
14
15#[async_trait]
16impl DapLocator for NodeLocator {
17    fn name(&self) -> SharedString {
18        SharedString::new_static("Node")
19    }
20
21    /// Determines whether this locator can generate debug target for given task.
22    fn create_scenario(
23        &self,
24        build_config: &TaskTemplate,
25        resolved_label: &str,
26        adapter: DebugAdapterName,
27    ) -> Option<DebugScenario> {
28        // TODO(debugger) fix issues with `await` breakpoint step
29        if cfg!(not(debug_assertions)) {
30            return None;
31        }
32
33        if adapter.as_ref() != "JavaScript" {
34            return None;
35        }
36        if build_config.command != TYPESCRIPT_RUNNER_VARIABLE.template_value() {
37            return None;
38        }
39        let test_library = build_config.args.first()?;
40        let program_path = Path::new("$ZED_WORKTREE_ROOT")
41            .join("node_modules")
42            .join(".bin")
43            .join(test_library);
44        let args = build_config.args[1..].to_vec();
45
46        let config = serde_json::json!({
47            "request": "launch",
48            "type": "pwa-node",
49            "program": program_path,
50            "args": args,
51            "cwd": build_config.cwd.clone(),
52            "runtimeArgs": ["--inspect-brk"],
53            "console": "integratedTerminal",
54        });
55
56        Some(DebugScenario {
57            adapter: adapter.0,
58            label: resolved_label.to_string().into(),
59            build: None,
60            config,
61            tcp_connection: None,
62        })
63    }
64
65    async fn run(&self, _: SpawnInTerminal) -> Result<DebugRequest> {
66        bail!("Python locator should not require DapLocator::run to be ran");
67    }
68}