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
18 changes: 9 additions & 9 deletions apps/oxfmt/src-js/cli/migration/migrate-prettier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ export async function runMigratePrettier() {
);
oxfmtrc.printWidth = 80;
}
// `experimentalSortPackageJson` is enabled by default in Oxfmt, but Prettier does not have this.
// `sortPackageJson` is enabled by default in Oxfmt, but Prettier does not have this.
// Only enable if `prettier-plugin-packagejson` is used.
if (hasSortPackageJsonPlugin) {
oxfmtrc.experimentalSortPackageJson = {};
console.error(` - Migrated "prettier-plugin-packagejson" to "experimentalSortPackageJson"`);
oxfmtrc.sortPackageJson = {};
console.error(` - Migrated "prettier-plugin-packagejson" to "sortPackageJson"`);
} else {
oxfmtrc.experimentalSortPackageJson = false;
oxfmtrc.sortPackageJson = false;
}
// `embeddedLanguageFormatting` is not fully supported for JS-in-XXX yet.
if (oxfmtrc.embeddedLanguageFormatting !== "off") {
Expand Down Expand Up @@ -184,7 +184,7 @@ const TAILWIND_OPTION_MAPPING: Record<string, string> = {
};

/**
* Migrate prettier-plugin-tailwindcss options to Oxfmt's experimentalTailwindcss format.
* Migrate prettier-plugin-tailwindcss options to Oxfmt's sortTailwindcss format.
*
* Prettier format:
* ```json
Expand All @@ -198,7 +198,7 @@ const TAILWIND_OPTION_MAPPING: Record<string, string> = {
* Oxfmt format:
* ```json
* {
* "experimentalTailwindcss": {
* "sortTailwindcss": {
* "config": "./tailwind.config.js",
* "functions": ["clsx", "cn"]
* }
Expand Down Expand Up @@ -231,7 +231,7 @@ function migrateTailwindOptions(
}
}

// Only add experimentalTailwindcss if plugin is used or options are present
oxfmtrc.experimentalTailwindcss = tailwindOptions;
console.log("Migrated prettier-plugin-tailwindcss options to experimentalTailwindcss");
// Only add sortTailwindcss if plugin is used or options are present
oxfmtrc.sortTailwindcss = tailwindOptions;
console.log("Migrated prettier-plugin-tailwindcss options to sortTailwindcss");
}
22 changes: 14 additions & 8 deletions apps/oxfmt/src-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,18 @@ export type FormatOptions = Pick<
printWidth?: number;
/** Whether to insert a final newline at the end of the file. (Default: `true`) */
insertFinalNewline?: boolean;
/** Experimental: Sort import statements. Disabled by default. */
/** Sort import statements. Disabled by default. */
sortImports?: SortImportsOptions;
/** @deprecated Use `sortImports` instead. */
experimentalSortImports?: SortImportsOptions;
/** Experimental: Sort `package.json` keys. (Default: `true`) */
/** Sort `package.json` keys. (Default: `true`) */
sortPackageJson?: boolean;
/** @deprecated Use `sortPackageJson` instead. */
experimentalSortPackageJson?: boolean;
/**
* Experimental: Enable Tailwind CSS class sorting in JSX class/className attributes.
* (Default: disabled)
*/
experimentalTailwindcss?: TailwindcssOptions;
/** Enable Tailwind CSS class sorting. (Default: disabled) */
sortTailwindcss?: SortTailwindcssOptions;
/** @deprecated Use `sortTailwindcss` instead. */
experimentalTailwindcss?: SortTailwindcssOptions;
} & Record<string, unknown>; // Also allow additional options for we don't have typed yet.

/**
Expand Down Expand Up @@ -140,7 +143,7 @@ export type SortImportsOptions = {
* Configuration options for Tailwind CSS class sorting.
* See https://github.com/tailwindlabs/prettier-plugin-tailwindcss#options
*/
export type TailwindcssOptions = {
export type SortTailwindcssOptions = {
/** Path to Tailwind config file (v3). e.g., `"./tailwind.config.js"` */
config?: string;
/** Path to Tailwind stylesheet (v4). e.g., `"./src/app.css"` */
Expand All @@ -160,3 +163,6 @@ export type TailwindcssOptions = {
/** Preserve duplicate classes. (Default: `false`) */
preserveDuplicates?: boolean;
};

/** @deprecated Use `SortTailwindcssOptions` instead. */
export type TailwindcssOptions = SortTailwindcssOptions;
2 changes: 1 addition & 1 deletion apps/oxfmt/src-js/libs/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async function loadTailwindPlugin(): Promise<typeof import("prettier-plugin-tail
* Load Tailwind CSS plugin lazily when `options._useTailwindPlugin` flag is set.
* The flag is added by Rust side only for relevant parsers.
*
* Option mapping (experimentalTailwindcss.xxx → tailwindXxx) is also done in Rust side.
* Option mapping (sortTailwindcss.xxx → tailwindXxx) is also done in Rust side.
*/
async function setupTailwindPlugin(options: Options): Promise<void> {
if ("_useTailwindPlugin" in options === false) return;
Expand Down
43 changes: 22 additions & 21 deletions apps/oxfmt/src/core/oxfmtrc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,42 +201,45 @@ pub struct FormatConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_final_newline: Option<bool>,

/// Experimental: Sort import statements.
/// Sort import statements.
///
/// Using the similar algorithm as [eslint-plugin-perfectionist/sort-imports](https://perfectionist.dev/rules/sort-imports).
/// For details, see each field's documentation.
///
/// - Default: Disabled
#[serde(skip_serializing_if = "Option::is_none")]
pub experimental_sort_imports: Option<SortImportsConfig>,
#[serde(alias = "experimentalSortImports")]
pub sort_imports: Option<SortImportsConfig>,

/// Experimental: Sort `package.json` keys.
/// Sort `package.json` keys.
///
/// The algorithm is NOT compatible with [prettier-plugin-sort-packagejson](https://github.com/matzkoh/prettier-plugin-packagejson).
/// But we believe it is clearer and easier to navigate.
/// For details, see each field's documentation.
///
/// - Default: `true`
#[serde(skip_serializing_if = "Option::is_none")]
pub experimental_sort_package_json: Option<SortPackageJsonUserConfig>,
#[serde(alias = "experimentalSortPackageJson")]
pub sort_package_json: Option<SortPackageJsonUserConfig>,

/// Experimental: Sort Tailwind CSS classes.
/// Sort Tailwind CSS classes.
///
/// Using the same algorithm as [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss).
/// Option names omit the `tailwind` prefix used in the original plugin (e.g., `config` instead of `tailwindConfig`).
/// For details, see each field's documentation.
///
/// - Default: Disabled
#[serde(skip_serializing_if = "Option::is_none")]
pub experimental_tailwindcss: Option<TailwindcssConfig>,
#[serde(alias = "experimentalTailwindcss")]
pub sort_tailwindcss: Option<TailwindcssConfig>,
}

impl FormatConfig {
/// Resolve relative tailwind paths (`config`, `stylesheet`) to absolute paths.
/// Otherwise, the plugin tries to resolve the Prettier's configuration file, not Oxfmt's.
/// <https://github.com/tailwindlabs/prettier-plugin-tailwindcss/blob/125a8bc77639529a5a0c7e4e8a02174d7ed2d70b/src/config.ts#L50-L54>
pub fn resolve_tailwind_paths(&mut self, base_dir: &Path) {
let Some(ref mut tw) = self.experimental_tailwindcss else {
let Some(ref mut tw) = self.sort_tailwindcss else {
return;
};

Expand Down Expand Up @@ -393,7 +396,7 @@ impl FormatConfig {

// Below are our own extensions

if let Some(config) = self.experimental_sort_imports {
if let Some(config) = self.sort_imports {
let mut sort_imports = SortImportsOptions::default();

if let Some(v) = config.partition_by_newline {
Expand Down Expand Up @@ -511,7 +514,7 @@ impl FormatConfig {
format_options.sort_imports = Some(sort_imports);
}

if let Some(config) = self.experimental_tailwindcss {
if let Some(config) = self.sort_tailwindcss {
format_options.sort_tailwindcss = Some(TailwindcssOptions {
config: config.config,
stylesheet: config.stylesheet,
Expand All @@ -525,7 +528,7 @@ impl FormatConfig {
// Currently, there is a no options for TOML formatter
let toml_options = build_toml_options(&format_options);

let sort_package_json = self.experimental_sort_package_json.map_or_else(
let sort_package_json = self.sort_package_json.map_or_else(
|| Some(SortPackageJsonConfig::default().to_sort_options()),
|c| c.to_sort_options(),
);
Expand Down Expand Up @@ -1006,7 +1009,7 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
};

// Determine if Tailwind plugin should be used based on config and strategy
let use_tailwind = obj.contains_key("experimentalTailwindcss")
let use_tailwind = obj.contains_key("sortTailwindcss")
&& match strategy {
FormatFileStrategy::OxcFormatter { .. } => true,
#[cfg(feature = "napi")]
Expand All @@ -1019,9 +1022,7 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
// Add Tailwind plugin flag and map options
// See: https://github.com/tailwindlabs/prettier-plugin-tailwindcss#options
if use_tailwind {
if let Some(tailwind) =
obj.get("experimentalTailwindcss").and_then(|v| v.as_object()).cloned()
{
if let Some(tailwind) = obj.get("sortTailwindcss").and_then(|v| v.as_object()).cloned() {
for (src, dst) in [
("config", "tailwindConfig"),
("stylesheet", "tailwindStylesheet"),
Expand Down Expand Up @@ -1058,8 +1059,8 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
"arrowParens",
"quoteProps",
"jsxSingleQuote",
"experimentalSortImports",
"experimentalTailwindcss",
"sortImports",
"sortTailwindcss",
] {
if let Some(value) = obj.get(key) {
oxfmt_plugin_options.insert(key.to_string(), value.clone());
Expand All @@ -1076,9 +1077,9 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate

// To minimize payload size, remove Prettier unaware options
for key in [
"experimentalSortImports",
"experimentalTailwindcss",
"experimentalSortPackageJson",
"sortImports",
"sortTailwindcss",
"sortPackageJson",
"insertFinalNewline",
"overrides",
"ignorePatterns",
Expand Down Expand Up @@ -1504,7 +1505,7 @@ mod tests_sync_external_options {
{ "files": ["*.test.js"], "options": { "tabWidth": 4 } }
],
"ignorePatterns": ["*.min.js"],
"experimentalSortImports": { "order": "asc" }
"sortImports": { "order": "asc" }
}"#;
let mut raw_config: Value = serde_json::from_str(json_string).unwrap();

Expand All @@ -1518,7 +1519,7 @@ mod tests_sync_external_options {
// oxfmt extensions are removed by finalize_external_options
assert!(!obj.contains_key("overrides"));
assert!(!obj.contains_key("ignorePatterns"));
assert!(!obj.contains_key("experimentalSortImports"));
assert!(!obj.contains_key("sortImports"));
}
}

Expand Down
24 changes: 12 additions & 12 deletions apps/oxfmt/test/cli/migrate_prettier/migrate_prettier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ node_modules
}
});

it("should migrate prettier-plugin-tailwindcss options to experimentalTailwindcss", async () => {
it("should migrate prettier-plugin-tailwindcss options to sortTailwindcss", async () => {
const tempDir = await fs.mkdtemp(join(tmpdir(), "oxfmt-migrate-test"));

try {
Expand All @@ -138,8 +138,8 @@ node_modules
const content = await fs.readFile(join(tempDir, ".oxfmtrc.json"), "utf8");
const oxfmtrc = JSON.parse(content);

// Tailwind options should be migrated to experimentalTailwindcss
expect(oxfmtrc.experimentalTailwindcss).toEqual({
// Tailwind options should be migrated to sortTailwindcss
expect(oxfmtrc.sortTailwindcss).toEqual({
config: "./tailwind.config.js",
functions: ["clsx", "cn"],
attributes: ["myClass"],
Expand All @@ -155,7 +155,7 @@ node_modules
}
});

it("should enable experimentalTailwindcss when plugin is listed without options", async () => {
it("should enable sortTailwindcss when plugin is listed without options", async () => {
const tempDir = await fs.mkdtemp(join(tmpdir(), "oxfmt-migrate-test"));

try {
Expand All @@ -173,8 +173,8 @@ node_modules
const content = await fs.readFile(join(tempDir, ".oxfmtrc.json"), "utf8");
const oxfmtrc = JSON.parse(content);

// experimentalTailwindcss should be enabled (empty object)
expect(oxfmtrc.experimentalTailwindcss).toEqual({});
// sortTailwindcss should be enabled (empty object)
expect(oxfmtrc.sortTailwindcss).toEqual({});
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
Expand Down Expand Up @@ -207,14 +207,14 @@ node_modules
const oxfmtrc = JSON.parse(content);

// Non-regex values should still be migrated
expect(oxfmtrc.experimentalTailwindcss.functions).toEqual(["clsx", "/^tw-/"]);
expect(oxfmtrc.experimentalTailwindcss.attributes).toEqual(["className", "/^data-tw-/"]);
expect(oxfmtrc.sortTailwindcss.functions).toEqual(["clsx", "/^tw-/"]);
expect(oxfmtrc.sortTailwindcss.attributes).toEqual(["className", "/^data-tw-/"]);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});

it("should disable experimentalSortPackageJson by default", async () => {
it("should disable sortPackageJson by default", async () => {
const tempDir = await fs.mkdtemp(join(tmpdir(), "oxfmt-migrate-test"));

try {
Expand All @@ -233,13 +233,13 @@ node_modules
const oxfmtrc = JSON.parse(content);

// Prettier does not have package.json sorting by default
expect(oxfmtrc.experimentalSortPackageJson).toBe(false);
expect(oxfmtrc.sortPackageJson).toBe(false);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});

it("should enable experimentalSortPackageJson when prettier-plugin-packagejson is used", async () => {
it("should enable sortPackageJson when prettier-plugin-packagejson is used", async () => {
const tempDir = await fs.mkdtemp(join(tmpdir(), "oxfmt-migrate-test"));

try {
Expand All @@ -257,7 +257,7 @@ node_modules
const content = await fs.readFile(join(tempDir, ".oxfmtrc.json"), "utf8");
const oxfmtrc = JSON.parse(content);

expect(oxfmtrc.experimentalSortPackageJson).toBeTruthy();
expect(oxfmtrc.sortPackageJson).toBeTruthy();
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
Expand Down
Loading
Loading