deno_ls_init/
lib.rs

1extern crate directories;
2extern crate pathdiff;
3#[macro_use]
4extern crate serde_json;
5
6use anyhow::{Result};
7use directories::BaseDirs;
8use pathdiff::diff_paths;
9use serde_json::Value;
10use std::env::current_dir;
11
12#[derive(Debug)]
13pub struct ConfigInfo {
14    deno: String,
15    deps_http: String,
16    deps_https: String,
17}
18
19impl ConfigInfo {
20    pub fn new() -> Option<ConfigInfo> {
21        let dir = BaseDirs::new();
22        if let Some(d) = dir {
23            let current_dir = current_dir().expect("failed to get current directory");
24            let cache_root = d.cache_dir();
25            let deno = diff_paths(cache_root.join("deno/lib.deno.d.ts"), &current_dir)
26                .unwrap()
27                .to_str()
28                .unwrap()
29                .to_string();
30            let deps = cache_root.join("deps");
31            let deps_http = diff_paths(deps.join("http/*"), &current_dir)
32                .unwrap()
33                .to_str()
34                .unwrap()
35                .to_string();
36            let deps_https = diff_paths(deps.join("https/*"), &current_dir)
37                .unwrap()
38                .to_str()
39                .unwrap()
40                .to_string();
41            Some(ConfigInfo {
42                deno,
43                deps_http,
44                deps_https,
45            })
46        } else {
47            None
48        }
49    }
50}
51
52pub fn deno_init(json_str: String, config_info: &ConfigInfo) -> Result<String> {
53    let mut v: Value;
54    if json_str != "" {
55        v = serde_json::from_str(&json_str)?;
56    } else {
57        v = json!({});
58    }
59
60    if let Value::Null = v["compilerOptions"] {
61        v.as_object_mut().unwrap().insert(
62            "compilerOptions".to_string(),
63            serde_json::to_value(json!({}))?,
64        );
65    }
66    if let Value::Null = v["compilerOptions"]["baseUrl"] {
67        v["compilerOptions"]
68            .as_object_mut()
69            .unwrap()
70            .insert("baseUrl".to_string(), serde_json::to_value(json!({}))?);
71    }
72    if let Value::Null = v["compilerOptions"]["paths"] {
73        v["compilerOptions"]
74            .as_object_mut()
75            .unwrap()
76            .insert("paths".to_string(), serde_json::to_value(json!({}))?);
77    }
78    if let Value::Null = v["compilerOptions"]["plugins"] {
79        v["compilerOptions"]
80            .as_object_mut()
81            .unwrap()
82            .insert("plugins".to_string(), serde_json::to_value(json!([]))?);
83    }
84
85    *v["compilerOptions"].get_mut("baseUrl").unwrap() = serde_json::to_value(".").unwrap();
86    v["compilerOptions"]["paths"]
87        .as_object_mut()
88        .unwrap()
89        .insert("deno".to_string(), serde_json::to_value(&config_info.deno)?);
90    println!("{:?}", &v);
91    v["compilerOptions"]["paths"]
92        .as_object_mut()
93        .unwrap()
94        .insert(
95            "http://*".to_string(),
96            serde_json::to_value(&config_info.deps_http)?,
97        );
98    v["compilerOptions"]["paths"]
99        .as_object_mut()
100        .unwrap()
101        .insert(
102            "https://*".to_string(),
103            serde_json::to_value(&config_info.deps_https)?,
104        );
105    v["compilerOptions"]["plugins"]
106        .as_array_mut()
107        .unwrap()
108        .push(json!({"name": "typescript-deno-plugin"}));
109
110    println!("{:?}", &v);
111
112    Ok(serde_json::to_string_pretty(&v).unwrap())
113}
114
115#[cfg(test)]
116fn config_gen() -> ConfigInfo {
117    ConfigInfo {
118        deno: "../../this/is/deno/path".to_string(),
119        deps_http: "../../this/is/http/path".to_string(),
120        deps_https: "../../this/is/https/path".to_string()
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn empty_string_test() {
130        let config = config_gen();
131        let result = deno_init("".to_string(), &config);
132        let expected = r#"{
133  "compilerOptions": {
134    "baseUrl": ".",
135    "paths": {
136      "deno": "../../this/is/deno/path",
137      "http://*": "../../this/is/http/path",
138      "https://*": "../../this/is/https/path"
139    },
140    "plugins": [
141      {
142        "name": "typescript-deno-plugin"
143      }
144    ]
145  }
146}"#;
147        assert_eq!(expected, result.unwrap());
148    }
149
150    #[test]
151    fn no_compiler_options() {
152        let config = config_gen();
153        let test_str = r#"
154{
155  "testOption": {
156    "testA": "test",
157    "testB": [
158      "testB-A",
159      1234,
160      "testB-B",
161      "aiueo"
162    ]
163  }
164}
165"#;
166        let result = deno_init(test_str.to_string(), &config);
167        let expected = r#"{
168  "compilerOptions": {
169    "baseUrl": ".",
170    "paths": {
171      "deno": "../../this/is/deno/path",
172      "http://*": "../../this/is/http/path",
173      "https://*": "../../this/is/https/path"
174    },
175    "plugins": [
176      {
177        "name": "typescript-deno-plugin"
178      }
179    ]
180  },
181  "testOption": {
182    "testA": "test",
183    "testB": [
184      "testB-A",
185      1234,
186      "testB-B",
187      "aiueo"
188    ]
189  }
190}"#;
191        assert_eq!(expected, result.unwrap());
192    }
193
194    #[test]
195    fn mix() {
196        let config = config_gen();
197        let test_str = r#"
198{
199  "compilerOptions": {
200    "baseUrl": ".",
201    "paths": {
202      "pathA": "/path/to/path/A",
203      "pathB": "/path/to/path/B"
204    },
205    "plugins": [
206      {
207        "name": "plugin-A"
208      },
209      {
210        "name": "plugin-B"
211      }
212    ],
213    "otherOption": "aaa"
214  },
215  "testOption": {
216    "testA": "test",
217    "testB": [
218      "testB-A",
219      1234,
220      "testB-B",
221      "aiueo"
222    ]
223  }
224}
225"#;
226        let result = deno_init(test_str.to_string(), &config);
227        let expected = r#"{
228  "compilerOptions": {
229    "baseUrl": ".",
230    "otherOption": "aaa",
231    "paths": {
232      "deno": "../../this/is/deno/path",
233      "http://*": "../../this/is/http/path",
234      "https://*": "../../this/is/https/path",
235      "pathA": "/path/to/path/A",
236      "pathB": "/path/to/path/B"
237    },
238    "plugins": [
239      {
240        "name": "plugin-A"
241      },
242      {
243        "name": "plugin-B"
244      },
245      {
246        "name": "typescript-deno-plugin"
247      }
248    ]
249  },
250  "testOption": {
251    "testA": "test",
252    "testB": [
253      "testB-A",
254      1234,
255      "testB-B",
256      "aiueo"
257    ]
258  }
259}"#;
260        assert_eq!(expected, result.unwrap());
261    }
262}