Skip to content

Commit 8a91c6b

Browse files
authoredFeb 27, 2025
feat: support TsImportCallOptions (#702)
1 parent b4b63fa commit 8a91c6b

File tree

11 files changed

+478
-128
lines changed

11 files changed

+478
-128
lines changed
 

‎Cargo.lock

+339-84
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ harness = false
3131

3232
[dependencies]
3333
anyhow = "1.0.64"
34-
deno_ast = { version = "0.45.0", features = ["view"] }
35-
dprint-core = { version = "0.66.2", features = ["formatting"] }
34+
deno_ast = { version = "0.46.0", features = ["view"] }
35+
dprint-core = { version = "0.67.4", features = ["formatting"] }
3636
dprint-core-macros = "0.1.0"
3737
percent-encoding = "2.3.1"
38-
rustc-hash = "1.1.0"
38+
rustc-hash = "2.1.1"
3939
serde = { version = "1.0.144", features = ["derive"] }
4040
serde_json = { version = "1.0", optional = true }
4141

‎deployment/npm/index.test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ const getPath = require("./index").getPath;
55

66
const buffer = require("fs").readFileSync(getPath());
77
const formatter = createFromBuffer(buffer);
8-
const result = formatter.formatText("file.ts", "const t = 5");
8+
const result = formatter.formatText({
9+
filePath: "file.ts",
10+
fileText: "const t = 5",
11+
});
912

1013
assert.strictEqual(result, "const t = 5;\n");

‎deployment/npm/package-lock.json

+9-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎deployment/npm/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
"test": "node index.test.js"
2626
},
2727
"devDependencies": {
28-
"@dprint/formatter": "~0.1.4"
28+
"@dprint/formatter": "~0.4.0"
2929
}
3030
}

‎rust-toolchain.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "1.81.0"
2+
channel = "1.85.0"
33
components = ["clippy"]

‎src/format_text.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ mod test {
111111
fn strips_bom() {
112112
for input_text in ["\u{FEFF}const t = 5;\n", "\u{FEFF}const t = 5;"] {
113113
let config = crate::configuration::ConfigurationBuilder::new().build();
114-
let result = format_text(&std::path::PathBuf::from("test.ts"), None, input_text.into(), &config).unwrap().unwrap();
114+
let result = format_text(&std::path::PathBuf::from("test.ts"), None, input_text.into(), &config)
115+
.unwrap()
116+
.unwrap();
115117
assert_eq!(result, "const t = 5;\n");
116118
}
117119
}

‎src/generation/generate.rs

+71-1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ fn gen_node_with_inner_gen<'a>(node: Node<'a>, context: &mut Context<'a>, inner_
312312
Node::TsSetterSignature(node) => gen_setter_signature(node, context),
313313
Node::TsKeywordType(node) => gen_keyword_type(node, context),
314314
Node::TsImportType(node) => gen_import_type(node, context),
315+
Node::TsImportCallOptions(node) => gen_ts_import_call_options(node, context),
315316
Node::TsIndexedAccessType(node) => gen_indexed_access_type(node, context),
316317
Node::TsInferType(node) => gen_infer_type(node, context),
317318
Node::TsInstantiation(node) => gen_ts_instantiation(node, context),
@@ -5833,6 +5834,10 @@ fn gen_import_type<'a>(node: &TsImportType<'a>, context: &mut Context<'a>) -> Pr
58335834
let mut items = PrintItems::new();
58345835
items.push_sc(sc!("import("));
58355836
items.extend(gen_node(node.arg.into(), context));
5837+
if let Some(attributes) = node.attributes {
5838+
items.push_sc(sc!(", "));
5839+
items.extend(gen_node(attributes.into(), context));
5840+
}
58365841
items.push_sc(sc!(")"));
58375842

58385843
if let Some(qualifier) = &node.qualifier {
@@ -5846,6 +5851,71 @@ fn gen_import_type<'a>(node: &TsImportType<'a>, context: &mut Context<'a>) -> Pr
58465851
items
58475852
}
58485853

5854+
fn gen_ts_import_call_options<'a>(node: &TsImportCallOptions<'a>, context: &mut Context<'a>) -> PrintItems {
5855+
let first_member_tokens = node.tokens_fast(context.program);
5856+
let with_token = first_member_tokens.iter().find(|t| t.text_fast(context.program) == "with").unwrap();
5857+
let member_range = SourceRange::new(with_token.start(), node.with.end());
5858+
let force_multi_line = get_use_new_lines_for_nodes_with_preceeding_token("{", &[member_range], context.config.object_expression_prefer_single_line, context);
5859+
gen_surrounded_by_tokens(
5860+
|context| {
5861+
let mut items = PrintItems::new();
5862+
let start_ln = LineNumber::new("objectStart");
5863+
let end_ln = LineNumber::new("objectStart");
5864+
if force_multi_line {
5865+
items.push_signal(Signal::NewLine);
5866+
} else {
5867+
items.push_info(start_ln);
5868+
items.push_condition(conditions::new_line_if_multiple_lines_space_or_new_line_otherwise(start_ln, Some(end_ln)));
5869+
}
5870+
items.push_condition(indent_if_start_of_line_or_start_of_line_indented({
5871+
let mut items = PrintItems::new();
5872+
items.push_sc(sc!("with: "));
5873+
items.extend(gen_node(node.with.into(), context));
5874+
match context.config.object_expression_trailing_commas {
5875+
TrailingCommas::OnlyMultiLine => {
5876+
if force_multi_line {
5877+
items.push_sc(sc!(","));
5878+
} else {
5879+
items.push_condition(conditions::if_true(
5880+
"trailingComma",
5881+
Rc::new(move |context| condition_helpers::is_on_different_line(context, start_ln)),
5882+
",".into(),
5883+
));
5884+
}
5885+
}
5886+
TrailingCommas::Always => {
5887+
items.push_sc(sc!(","));
5888+
}
5889+
TrailingCommas::Never => {}
5890+
}
5891+
items
5892+
}));
5893+
if force_multi_line {
5894+
items.push_signal(Signal::NewLine);
5895+
} else {
5896+
items.push_condition(conditions::if_true(
5897+
"newlineIfMultipleLines",
5898+
Rc::new(move |context| condition_helpers::is_on_different_line(context, start_ln)),
5899+
Signal::NewLine.into(),
5900+
));
5901+
items.push_info(end_ln);
5902+
}
5903+
items
5904+
},
5905+
|_| None,
5906+
GenSurroundedByTokensOptions {
5907+
open_token: sc!("{"),
5908+
close_token: sc!("}"),
5909+
range: Some(node.range()),
5910+
first_member: Some(member_range),
5911+
prefer_single_line_when_empty: false,
5912+
allow_open_token_trailing_comments: true,
5913+
single_line_space_around: false,
5914+
},
5915+
context,
5916+
)
5917+
}
5918+
58495919
fn gen_indexed_access_type<'a>(node: &TsIndexedAccessType<'a>, context: &mut Context<'a>) -> PrintItems {
58505920
let mut items = PrintItems::new();
58515921
items.extend(gen_node(node.obj_type.into(), context));
@@ -7685,13 +7755,13 @@ fn gen_separated_values_with_result<'a>(opts: GenSeparatedValuesParams<'a>, cont
76857755
if node_sorter.is_some() && compute_lines_span {
76867756
panic!("Not implemented scenario. Cannot computed lines span and allow blank lines");
76877757
}
7758+
let sorted_indexes = node_sorter.map(|sorter| get_sorted_indexes(nodes.iter().map(|d| d.as_node()), sorter, context));
76887759

76897760
ir_helpers::gen_separated_values(
76907761
|is_multi_line_or_hanging_ref| {
76917762
let is_multi_line_or_hanging = is_multi_line_or_hanging_ref.create_resolver();
76927763
let mut generated_nodes = Vec::new();
76937764
let nodes_count = nodes.len();
7694-
let sorted_indexes = node_sorter.map(|sorter| get_sorted_indexes(nodes.iter().map(|d| d.as_node()), sorter, context));
76957765

76967766
for (i, value) in nodes.into_iter().enumerate() {
76977767
let node_index = match &sorted_indexes {

‎src/wasm_plugin.rs

+29-27
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,27 @@
11
use dprint_core::configuration::ConfigKeyMap;
22
use dprint_core::configuration::GlobalConfiguration;
3-
use dprint_core::configuration::ResolveConfigurationResult;
43
use dprint_core::generate_plugin_code;
4+
use dprint_core::plugins::CheckConfigUpdatesMessage;
5+
use dprint_core::plugins::ConfigChange;
56
use dprint_core::plugins::FileMatchingInfo;
67
use dprint_core::plugins::FormatResult;
78
use dprint_core::plugins::PluginInfo;
9+
use dprint_core::plugins::PluginResolveConfigurationResult;
10+
use dprint_core::plugins::SyncFormatRequest;
11+
use dprint_core::plugins::SyncHostFormatRequest;
812
use dprint_core::plugins::SyncPluginHandler;
9-
use dprint_core::plugins::SyncPluginInfo;
10-
use std::path::Path;
1113

1214
use super::configuration::resolve_config;
1315
use super::configuration::Configuration;
1416

1517
struct TypeScriptPluginHandler;
1618

1719
impl SyncPluginHandler<Configuration> for TypeScriptPluginHandler {
18-
fn resolve_config(&mut self, config: ConfigKeyMap, global_config: &GlobalConfiguration) -> ResolveConfigurationResult<Configuration> {
19-
resolve_config(config, global_config)
20-
}
21-
22-
fn plugin_info(&mut self) -> SyncPluginInfo {
23-
let version = env!("CARGO_PKG_VERSION").to_string();
24-
SyncPluginInfo {
25-
info: PluginInfo {
26-
name: env!("CARGO_PKG_NAME").to_string(),
27-
version: version.clone(),
28-
config_key: "typescript".to_string(),
29-
help_url: "https://dprint.dev/plugins/typescript".to_string(),
30-
config_schema_url: format!("https://plugins.dprint.dev/dprint/dprint-plugin-typescript/{}/schema.json", version),
31-
update_url: Some("https://plugins.dprint.dev/dprint/dprint-plugin-typescript/latest.json".to_string()),
32-
},
20+
fn resolve_config(&mut self, config: ConfigKeyMap, global_config: &GlobalConfiguration) -> PluginResolveConfigurationResult<Configuration> {
21+
let config = resolve_config(config, global_config);
22+
PluginResolveConfigurationResult {
23+
config: config.config,
24+
diagnostics: config.diagnostics,
3325
file_matching: FileMatchingInfo {
3426
file_extensions: vec![
3527
String::from("ts"),
@@ -46,19 +38,29 @@ impl SyncPluginHandler<Configuration> for TypeScriptPluginHandler {
4638
}
4739
}
4840

41+
fn check_config_updates(&self, _message: CheckConfigUpdatesMessage) -> Result<Vec<ConfigChange>, anyhow::Error> {
42+
Ok(Vec::new())
43+
}
44+
45+
fn plugin_info(&mut self) -> PluginInfo {
46+
let version = env!("CARGO_PKG_VERSION").to_string();
47+
PluginInfo {
48+
name: env!("CARGO_PKG_NAME").to_string(),
49+
version: version.clone(),
50+
config_key: "typescript".to_string(),
51+
help_url: "https://dprint.dev/plugins/typescript".to_string(),
52+
config_schema_url: format!("https://plugins.dprint.dev/dprint/dprint-plugin-typescript/{}/schema.json", version),
53+
update_url: Some("https://plugins.dprint.dev/dprint/dprint-plugin-typescript/latest.json".to_string()),
54+
}
55+
}
56+
4957
fn license_text(&mut self) -> String {
5058
std::str::from_utf8(include_bytes!("../LICENSE")).unwrap().into()
5159
}
5260

53-
fn format(
54-
&mut self,
55-
file_path: &Path,
56-
file_bytes: Vec<u8>,
57-
config: &Configuration,
58-
_format_with_host: impl FnMut(&Path, Vec<u8>, &ConfigKeyMap) -> FormatResult,
59-
) -> FormatResult {
60-
let file_text = String::from_utf8(file_bytes)?;
61-
super::format_text(file_path, None, file_text, config).map(|maybe_text| maybe_text.map(|t| t.into_bytes()))
61+
fn format(&mut self, request: SyncFormatRequest<Configuration>, _format_with_host: impl FnMut(SyncHostFormatRequest) -> FormatResult) -> FormatResult {
62+
let file_text = String::from_utf8(request.file_bytes)?;
63+
super::format_text(request.file_path, None, file_text, request.config).map(|maybe_text| maybe_text.map(|t| t.into_bytes()))
6264
}
6365
}
6466

‎tests/specs/patterns/ArrayPattern/ArrayPattern_All.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const [a, , ,test] = something;
2424

2525
[expect]
2626
[a, , b] = 0;
27-
const [a] = something;
27+
const [a, , ,] = something;
2828
const [a] = something;
2929
const [a, , , test] = something;
3030
const [a, , , test] = something;
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
1+
~~ lineWidth: 75 ~~
12
== should format ==
23
type T = import( "test" );
34
type U = import("test" ).Other;
45
type V = import("test").Other< string >;
56
type X = import("test")<number >;
7+
type Z = import("test", { with: { "resolution-mode": "types" }});
8+
type Z1 = import("testtestingtestingtestingtestingtesting", { with: { "resolution-mode": "types" }});
9+
type Z2 = import("test", {
10+
with: {
11+
"resolution-mode": "types"
12+
}
13+
});
614

715
[expect]
816
type T = import("test");
917
type U = import("test").Other;
1018
type V = import("test").Other<string>;
1119
type X = import("test")<number>;
20+
type Z = import("test", { with: { "resolution-mode": "types" }});
21+
type Z1 = import("testtestingtestingtestingtestingtesting", {
22+
with: { "resolution-mode": "types" },
23+
});
24+
type Z2 = import("test", {
25+
with: {
26+
"resolution-mode": "types",
27+
},
28+
});

0 commit comments

Comments
 (0)
Please sign in to comment.