Skip to content

Commit 984dc07

Browse files
committed
feat(oxfmt): Strip "experimental"SortXxx prefix (#19567)
- `experimentalSortImports` 👉🏻 `sortImports` - `experimentalSortPackageJson` 👉🏻 `sortPackageJson` - `experimentalTailwindcss` 👉🏻 `sortTailwindcss` To avoid breaking changes, the old name is retained as an alias.
1 parent bba146a commit 984dc07

File tree

8 files changed

+571
-564
lines changed

8 files changed

+571
-564
lines changed

apps/oxfmt/src-js/cli/migration/migrate-prettier.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@ export async function runMigratePrettier() {
107107
);
108108
oxfmtrc.printWidth = 80;
109109
}
110-
// `experimentalSortPackageJson` is enabled by default in Oxfmt, but Prettier does not have this.
110+
// `sortPackageJson` is enabled by default in Oxfmt, but Prettier does not have this.
111111
// Only enable if `prettier-plugin-packagejson` is used.
112112
if (hasSortPackageJsonPlugin) {
113-
oxfmtrc.experimentalSortPackageJson = {};
114-
console.error(` - Migrated "prettier-plugin-packagejson" to "experimentalSortPackageJson"`);
113+
oxfmtrc.sortPackageJson = {};
114+
console.error(` - Migrated "prettier-plugin-packagejson" to "sortPackageJson"`);
115115
} else {
116-
oxfmtrc.experimentalSortPackageJson = false;
116+
oxfmtrc.sortPackageJson = false;
117117
}
118118
// `embeddedLanguageFormatting` is not fully supported for JS-in-XXX yet.
119119
if (oxfmtrc.embeddedLanguageFormatting !== "off") {
@@ -184,7 +184,7 @@ const TAILWIND_OPTION_MAPPING: Record<string, string> = {
184184
};
185185

186186
/**
187-
* Migrate prettier-plugin-tailwindcss options to Oxfmt's experimentalTailwindcss format.
187+
* Migrate prettier-plugin-tailwindcss options to Oxfmt's sortTailwindcss format.
188188
*
189189
* Prettier format:
190190
* ```json
@@ -198,7 +198,7 @@ const TAILWIND_OPTION_MAPPING: Record<string, string> = {
198198
* Oxfmt format:
199199
* ```json
200200
* {
201-
* "experimentalTailwindcss": {
201+
* "sortTailwindcss": {
202202
* "config": "./tailwind.config.js",
203203
* "functions": ["clsx", "cn"]
204204
* }
@@ -231,7 +231,7 @@ function migrateTailwindOptions(
231231
}
232232
}
233233

234-
// Only add experimentalTailwindcss if plugin is used or options are present
235-
oxfmtrc.experimentalTailwindcss = tailwindOptions;
236-
console.log("Migrated prettier-plugin-tailwindcss options to experimentalTailwindcss");
234+
// Only add sortTailwindcss if plugin is used or options are present
235+
oxfmtrc.sortTailwindcss = tailwindOptions;
236+
console.log("Migrated prettier-plugin-tailwindcss options to sortTailwindcss");
237237
}

apps/oxfmt/src-js/index.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ export type FormatOptions = Pick<
9191
printWidth?: number;
9292
/** Whether to insert a final newline at the end of the file. (Default: `true`) */
9393
insertFinalNewline?: boolean;
94-
/** Experimental: Sort import statements. Disabled by default. */
94+
/** Sort import statements. Disabled by default. */
95+
sortImports?: SortImportsOptions;
96+
/** @deprecated Use `sortImports` instead. */
9597
experimentalSortImports?: SortImportsOptions;
96-
/** Experimental: Sort `package.json` keys. (Default: `true`) */
98+
/** Sort `package.json` keys. (Default: `true`) */
99+
sortPackageJson?: boolean;
100+
/** @deprecated Use `sortPackageJson` instead. */
97101
experimentalSortPackageJson?: boolean;
98-
/**
99-
* Experimental: Enable Tailwind CSS class sorting in JSX class/className attributes.
100-
* (Default: disabled)
101-
*/
102-
experimentalTailwindcss?: TailwindcssOptions;
102+
/** Enable Tailwind CSS class sorting. (Default: disabled) */
103+
sortTailwindcss?: SortTailwindcssOptions;
104+
/** @deprecated Use `sortTailwindcss` instead. */
105+
experimentalTailwindcss?: SortTailwindcssOptions;
103106
} & Record<string, unknown>; // Also allow additional options for we don't have typed yet.
104107

105108
/**
@@ -140,7 +143,7 @@ export type SortImportsOptions = {
140143
* Configuration options for Tailwind CSS class sorting.
141144
* See https://github.com/tailwindlabs/prettier-plugin-tailwindcss#options
142145
*/
143-
export type TailwindcssOptions = {
146+
export type SortTailwindcssOptions = {
144147
/** Path to Tailwind config file (v3). e.g., `"./tailwind.config.js"` */
145148
config?: string;
146149
/** Path to Tailwind stylesheet (v4). e.g., `"./src/app.css"` */
@@ -160,3 +163,6 @@ export type TailwindcssOptions = {
160163
/** Preserve duplicate classes. (Default: `false`) */
161164
preserveDuplicates?: boolean;
162165
};
166+
167+
/** @deprecated Use `SortTailwindcssOptions` instead. */
168+
export type TailwindcssOptions = SortTailwindcssOptions;

apps/oxfmt/src-js/libs/apis.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ async function loadTailwindPlugin(): Promise<typeof import("prettier-plugin-tail
118118
* Load Tailwind CSS plugin lazily when `options._useTailwindPlugin` flag is set.
119119
* The flag is added by Rust side only for relevant parsers.
120120
*
121-
* Option mapping (experimentalTailwindcss.xxx → tailwindXxx) is also done in Rust side.
121+
* Option mapping (sortTailwindcss.xxx → tailwindXxx) is also done in Rust side.
122122
*/
123123
async function setupTailwindPlugin(options: Options): Promise<void> {
124124
if ("_useTailwindPlugin" in options === false) return;

apps/oxfmt/src/core/oxfmtrc.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -201,42 +201,45 @@ pub struct FormatConfig {
201201
#[serde(skip_serializing_if = "Option::is_none")]
202202
pub insert_final_newline: Option<bool>,
203203

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

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

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

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

@@ -393,7 +396,7 @@ impl FormatConfig {
393396

394397
// Below are our own extensions
395398

396-
if let Some(config) = self.experimental_sort_imports {
399+
if let Some(config) = self.sort_imports {
397400
let mut sort_imports = SortImportsOptions::default();
398401

399402
if let Some(v) = config.partition_by_newline {
@@ -511,7 +514,7 @@ impl FormatConfig {
511514
format_options.sort_imports = Some(sort_imports);
512515
}
513516

514-
if let Some(config) = self.experimental_tailwindcss {
517+
if let Some(config) = self.sort_tailwindcss {
515518
format_options.sort_tailwindcss = Some(TailwindcssOptions {
516519
config: config.config,
517520
stylesheet: config.stylesheet,
@@ -525,7 +528,7 @@ impl FormatConfig {
525528
// Currently, there is a no options for TOML formatter
526529
let toml_options = build_toml_options(&format_options);
527530

528-
let sort_package_json = self.experimental_sort_package_json.map_or_else(
531+
let sort_package_json = self.sort_package_json.map_or_else(
529532
|| Some(SortPackageJsonConfig::default().to_sort_options()),
530533
|c| c.to_sort_options(),
531534
);
@@ -1006,7 +1009,7 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
10061009
};
10071010

10081011
// Determine if Tailwind plugin should be used based on config and strategy
1009-
let use_tailwind = obj.contains_key("experimentalTailwindcss")
1012+
let use_tailwind = obj.contains_key("sortTailwindcss")
10101013
&& match strategy {
10111014
FormatFileStrategy::OxcFormatter { .. } => true,
10121015
#[cfg(feature = "napi")]
@@ -1019,9 +1022,7 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
10191022
// Add Tailwind plugin flag and map options
10201023
// See: https://github.com/tailwindlabs/prettier-plugin-tailwindcss#options
10211024
if use_tailwind {
1022-
if let Some(tailwind) =
1023-
obj.get("experimentalTailwindcss").and_then(|v| v.as_object()).cloned()
1024-
{
1025+
if let Some(tailwind) = obj.get("sortTailwindcss").and_then(|v| v.as_object()).cloned() {
10251026
for (src, dst) in [
10261027
("config", "tailwindConfig"),
10271028
("stylesheet", "tailwindStylesheet"),
@@ -1058,8 +1059,8 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
10581059
"arrowParens",
10591060
"quoteProps",
10601061
"jsxSingleQuote",
1061-
"experimentalSortImports",
1062-
"experimentalTailwindcss",
1062+
"sortImports",
1063+
"sortTailwindcss",
10631064
] {
10641065
if let Some(value) = obj.get(key) {
10651066
oxfmt_plugin_options.insert(key.to_string(), value.clone());
@@ -1076,9 +1077,9 @@ pub fn finalize_external_options(config: &mut Value, strategy: &FormatFileStrate
10761077

10771078
// To minimize payload size, remove Prettier unaware options
10781079
for key in [
1079-
"experimentalSortImports",
1080-
"experimentalTailwindcss",
1081-
"experimentalSortPackageJson",
1080+
"sortImports",
1081+
"sortTailwindcss",
1082+
"sortPackageJson",
10821083
"insertFinalNewline",
10831084
"overrides",
10841085
"ignorePatterns",
@@ -1504,7 +1505,7 @@ mod tests_sync_external_options {
15041505
{ "files": ["*.test.js"], "options": { "tabWidth": 4 } }
15051506
],
15061507
"ignorePatterns": ["*.min.js"],
1507-
"experimentalSortImports": { "order": "asc" }
1508+
"sortImports": { "order": "asc" }
15081509
}"#;
15091510
let mut raw_config: Value = serde_json::from_str(json_string).unwrap();
15101511

@@ -1518,7 +1519,7 @@ mod tests_sync_external_options {
15181519
// oxfmt extensions are removed by finalize_external_options
15191520
assert!(!obj.contains_key("overrides"));
15201521
assert!(!obj.contains_key("ignorePatterns"));
1521-
assert!(!obj.contains_key("experimentalSortImports"));
1522+
assert!(!obj.contains_key("sortImports"));
15221523
}
15231524
}
15241525

apps/oxfmt/test/cli/migrate_prettier/migrate_prettier.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ node_modules
116116
}
117117
});
118118

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

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

141-
// Tailwind options should be migrated to experimentalTailwindcss
142-
expect(oxfmtrc.experimentalTailwindcss).toEqual({
141+
// Tailwind options should be migrated to sortTailwindcss
142+
expect(oxfmtrc.sortTailwindcss).toEqual({
143143
config: "./tailwind.config.js",
144144
functions: ["clsx", "cn"],
145145
attributes: ["myClass"],
@@ -155,7 +155,7 @@ node_modules
155155
}
156156
});
157157

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

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

176-
// experimentalTailwindcss should be enabled (empty object)
177-
expect(oxfmtrc.experimentalTailwindcss).toEqual({});
176+
// sortTailwindcss should be enabled (empty object)
177+
expect(oxfmtrc.sortTailwindcss).toEqual({});
178178
} finally {
179179
await fs.rm(tempDir, { recursive: true, force: true });
180180
}
@@ -207,14 +207,14 @@ node_modules
207207
const oxfmtrc = JSON.parse(content);
208208

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

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

220220
try {
@@ -233,13 +233,13 @@ node_modules
233233
const oxfmtrc = JSON.parse(content);
234234

235235
// Prettier does not have package.json sorting by default
236-
expect(oxfmtrc.experimentalSortPackageJson).toBe(false);
236+
expect(oxfmtrc.sortPackageJson).toBe(false);
237237
} finally {
238238
await fs.rm(tempDir, { recursive: true, force: true });
239239
}
240240
});
241241

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

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

260-
expect(oxfmtrc.experimentalSortPackageJson).toBeTruthy();
260+
expect(oxfmtrc.sortPackageJson).toBeTruthy();
261261
} finally {
262262
await fs.rm(tempDir, { recursive: true, force: true });
263263
}

0 commit comments

Comments
 (0)