node.rs

 1use std::{borrow::Cow, path::PathBuf};
 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    async fn create_scenario(
23        &self,
24        build_config: &TaskTemplate,
25        resolved_label: &str,
26        adapter: &DebugAdapterName,
27    ) -> Option<DebugScenario> {
28        if adapter.0.as_ref() != "JavaScript" {
29            return None;
30        }
31        if build_config.command != TYPESCRIPT_RUNNER_VARIABLE.template_value() {
32            return None;
33        }
34        let test_library = build_config.args.first()?;
35        let program_path_base: PathBuf = match test_library.as_str() {
36            "jest" => "${ZED_CUSTOM_TYPESCRIPT_JEST_PACKAGE_PATH}".to_owned(),
37            "mocha" => "${ZED_CUSTOM_TYPESCRIPT_MOCHA_PACKAGE_PATH}".to_owned(),
38            "vitest" => "${ZED_CUSTOM_TYPESCRIPT_VITEST_PACKAGE_PATH}".to_owned(),
39            "jasmine" => "${ZED_CUSTOM_TYPESCRIPT_JASMINE_PACKAGE_PATH}".to_owned(),
40            _ => VariableName::WorktreeRoot.template_value(),
41        }
42        .into();
43
44        let program_path = program_path_base
45            .join("node_modules")
46            .join(".bin")
47            .join(test_library);
48
49        let mut args = if test_library == "jest" {
50            vec!["--runInBand".to_owned()]
51        } else {
52            vec![]
53        };
54        args.extend(build_config.args[1..].iter().cloned());
55
56        let config = serde_json::json!({
57            "request": "launch",
58            "type": "pwa-node",
59            "runtimeExecutable": program_path,
60            "args": args,
61            "cwd": build_config.cwd.clone(),
62            "env": {
63                "VITEST_MIN_FORKS": "0",
64                "VITEST_MAX_FORKS": "1"
65            },
66            "runtimeArgs": ["--inspect-brk"],
67            "console": "integratedTerminal",
68        });
69
70        Some(DebugScenario {
71            adapter: adapter.0.clone(),
72            label: resolved_label.to_string().into(),
73            build: None,
74            config,
75            tcp_connection: None,
76        })
77    }
78
79    async fn run(&self, _: SpawnInTerminal) -> Result<DebugRequest> {
80        bail!("JavaScript locator should not require DapLocator::run to be ran");
81    }
82}