Skip to content

Commit 2201e81

Browse files
fix(config): prevent ERR_UNSUPPORTED_ESM_URL_SCHEME on Windows
Closes #327 Closes #328 Co-authored-by: Tyler Butler <tyler@tylerbutler.com>
1 parent 772bfc1 commit 2201e81

5 files changed

Lines changed: 59 additions & 14 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,5 @@ jobs:
6969
run: just check-clippy
7070
- name: Cargo test
7171
run: just test
72-
# - name: Test issue 327
73-
# run: just test-js-config-loading
7472
- name: Test issue 311 and 319
7573
run: just test-glob-matching

justfile

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,6 @@ serve-coverage:
156156
test:
157157
cargo test -- --nocapture --color=always
158158

159-
test-js-config-loading:
160-
#!/usr/bin/env bash
161-
set -euo pipefail
162-
cargo build
163-
PROJECT_ROOT=$(pwd)
164-
165-
echo "JS/TS Config should be read without errors"
166-
cd "$PROJECT_ROOT/fixtures/js-config-loading"
167-
../../target/debug/syncpack list
168-
169159
test-glob-matching:
170160
#!/usr/bin/env bash
171161
set -euo pipefail

src/rcfile/javascript.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use {serde::Deserialize, std::path::Path};
22

3+
#[cfg(test)]
4+
#[path = "javascript_test.rs"]
5+
mod tests;
6+
37
/// The JSON returned to Rust from JavaScript when evaluating a config file
48
#[derive(Debug, Deserialize)]
59
#[serde(tag = "_tag")]
@@ -16,10 +20,10 @@ pub enum JsResult {
1620
}
1721

1822
pub fn get_javascript_contents(file_path: &Path) -> String {
19-
let escaped_file_path = file_path.to_string_lossy().replace('\\', "\\\\");
23+
let escaped_file_path = file_path.to_string_lossy().replace('\\', "\\\\").replace('\'', "\\'");
2024
format!(
2125
r#"
22-
import('{escaped_file_path}')
26+
import(require('node:url').pathToFileURL('{escaped_file_path}').href)
2327
.then(findConfig)
2428
.then((value) => {{
2529
if (isNonEmptyObject(value)) {{

src/rcfile/javascript_test.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use {super::get_javascript_contents, std::path::Path};
2+
3+
#[test]
4+
fn import_uses_path_to_file_url() {
5+
let script = get_javascript_contents(Path::new("/home/jamie/syncpack.config.cjs"));
6+
assert!(script.contains("import(require('node:url').pathToFileURL("));
7+
}
8+
9+
#[test]
10+
fn require_uses_raw_path() {
11+
let script = get_javascript_contents(Path::new("/home/jamie/syncpack.config.cjs"));
12+
assert!(script.contains("require('/home/jamie/syncpack.config.cjs')"));
13+
}
14+
15+
#[test]
16+
fn escapes_windows_backslashes() {
17+
let script = get_javascript_contents(Path::new(r"C:\Users\jamie\syncpack.config.cjs"));
18+
assert!(script.contains(r"C:\\Users\\jamie\\syncpack.config.cjs"));
19+
assert!(!script.contains(r"'C:\Users"));
20+
}
21+
22+
#[test]
23+
fn escapes_single_quotes() {
24+
let script = get_javascript_contents(Path::new("/home/jamie's projects/syncpack.config.cjs"));
25+
assert!(script.contains(r"/home/jamie\'s projects/syncpack.config.cjs"));
26+
}

tests/js_config_loading_test.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use std::{path::PathBuf, process::Command};
2+
3+
fn fixture_dir() -> PathBuf {
4+
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("fixtures/js-config-loading")
5+
}
6+
7+
fn run_syncpack(args: &[&str]) -> (String, String, i32) {
8+
let output = Command::new(env!("CARGO_BIN_EXE_syncpack"))
9+
.args(args)
10+
.current_dir(fixture_dir())
11+
.output()
12+
.expect("failed to run syncpack");
13+
let stdout = String::from_utf8(output.stdout).unwrap();
14+
let stderr = String::from_utf8(output.stderr).unwrap();
15+
let code = output.status.code().unwrap_or(1);
16+
(stdout, stderr, code)
17+
}
18+
19+
#[test]
20+
fn loads_cjs_config_without_error() {
21+
let (_stdout, stderr, code) = run_syncpack(&["list"]);
22+
assert_eq!(code, 0, "syncpack list exited {code}\nstderr:\n{stderr}");
23+
assert!(
24+
!stderr.contains("ERR_UNSUPPORTED_ESM_URL_SCHEME"),
25+
"regression of issue #327:\n{stderr}"
26+
);
27+
}

0 commit comments

Comments
 (0)