Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/oxc_formatter/examples/sort_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fn main() -> Result<(), String> {
sort_side_effects,
ignore_case,
newlines_between,
internal_pattern: None,
groups: None,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ pub fn compute_import_metadata<'a>(

let source = extract_source_path(source);
let is_style_import = is_style(source);
let path_kind = to_path_kind(source, options);

// Create group matcher from import characteristics
let matcher = ImportGroupMatcher {
is_side_effect: *is_side_effect,
is_type_import: *is_type_import,
is_style_import,
path_kind: to_path_kind(source),
path_kind,
is_subpath: is_subpath(source),
has_default_specifier: *has_default_specifier,
has_namespace_specifier: *has_namespace_specifier,
Expand Down Expand Up @@ -346,7 +347,7 @@ enum ImportPathKind {
}

/// Determine the path kind for an import source.
fn to_path_kind(source: &str) -> ImportPathKind {
fn to_path_kind(source: &str, options: &options::SortImports) -> ImportPathKind {
if is_builtin(source) {
return ImportPathKind::Builtin;
}
Expand All @@ -364,8 +365,11 @@ fn to_path_kind(source: &str) -> ImportPathKind {
return ImportPathKind::Sibling;
}

// TODO: This can be changed via `options.internalPattern`
if source.starts_with("~/") || source.starts_with("@/") {
// Check if source matches any internal pattern
if match &options.internal_pattern {
Some(patterns) => patterns.iter().any(|p| source.starts_with(p.as_str())),
None => ["~/", "@/"].iter().any(|p| source.starts_with(*p)),
} {
return ImportPathKind::Internal;
}

Expand Down
4 changes: 4 additions & 0 deletions crates/oxc_formatter/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,9 @@ pub struct SortImports {
///
/// NOTE: Cannot be used together with `partition_by_newline: true`.
pub newlines_between: bool,
/// Prefixes for internal imports.
/// If `None`, uses the default internal patterns.
pub internal_pattern: Option<Vec<String>>,
/// Groups configuration for organizing imports.
/// Each inner `Vec` represents a group, and multiple group names in the same `Vec` are treated as one.
/// If `None`, uses the default groups.
Expand All @@ -1019,6 +1022,7 @@ impl Default for SortImports {
order: SortOrder::default(),
ignore_case: true,
newlines_between: true,
internal_pattern: None,
groups: None,
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/oxc_formatter/src/service/oxfmtrc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ pub struct SortImportsConfig {
pub ignore_case: bool,
#[serde(default = "default_true")]
pub newlines_between: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub internal_pattern: Option<Vec<String>>,
/// Custom groups configuration for organizing imports.
/// Each array element represents a group, and multiple group names in the same array are treated as one.
/// Accepts both `string` and `string[]` as group elements.
Expand Down Expand Up @@ -378,6 +380,7 @@ impl Oxfmtrc {
}),
ignore_case: sort_imports_config.ignore_case,
newlines_between: sort_imports_config.newlines_between,
internal_pattern: sort_imports_config.internal_pattern,
groups: sort_imports_config.groups,
});
}
Expand Down
29 changes: 29 additions & 0 deletions crates/oxc_formatter/tests/ir_transform/sort_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,35 @@ import { z } from "z";

// ---

#[test]
fn should_support_internal_pattern_option() {
assert_format(
r##"
import type { T } from "a";
import { a } from "a";
import type { S } from "#b";
import c from "#c";
import { b1, b2 } from "#b";
import { d } from "../d";
"##,
r##"{ "experimentalSortImports": { "internalPattern": ["#"] } }"##,
r##"
import type { T } from "a";

import { a } from "a";

import type { S } from "#b";

import { b1, b2 } from "#b";
import c from "#c";

import { d } from "../d";
"##,
);
}

// ---

#[test]
fn should_groups_and_sorts_by_type_and_source() {
assert_format(
Expand Down
9 changes: 9 additions & 0 deletions crates/oxc_formatter/tests/snapshots/schema_json.snap
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ expression: json
"default": true,
"type": "boolean"
},
"internalPattern": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
}
},
"newlinesBetween": {
"default": true,
"type": "boolean"
Expand Down
2 changes: 2 additions & 0 deletions napi/playground/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ export interface OxcSortImportsOptions {
ignoreCase?: boolean
/** Add newlines between import groups (default: true) */
newlinesBetween?: boolean
/** Pattern prefixes for internal imports */
internalPattern?: Array<string>
/** Custom groups of imports */
groups?: Array<Array<string>>
}
Expand Down
1 change: 1 addition & 0 deletions napi/playground/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ impl Oxc {
order,
ignore_case: sort_imports_config.ignore_case.unwrap_or(true),
newlines_between: sort_imports_config.newlines_between.unwrap_or(true),
internal_pattern: sort_imports_config.internal_pattern.clone(),
groups: sort_imports_config.groups.clone(),
});
}
Expand Down
2 changes: 2 additions & 0 deletions napi/playground/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ pub struct OxcSortImportsOptions {
pub ignore_case: Option<bool>,
/// Add newlines between import groups (default: true)
pub newlines_between: Option<bool>,
/// Pattern prefixes for internal imports
pub internal_pattern: Option<Vec<String>>,
/// Custom groups of imports
pub groups: Option<Vec<Vec<String>>>,
}
9 changes: 9 additions & 0 deletions npm/oxfmt/configuration_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@
"default": true,
"type": "boolean"
},
"internalPattern": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
}
},
"newlinesBetween": {
"default": true,
"type": "boolean"
Expand Down
Loading