biome-to-oxc 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +393 -0
  3. package/dist/advanced-detection-Bekr41wZ.mjs +71 -0
  4. package/dist/advanced-detection-Bekr41wZ.mjs.map +1 -0
  5. package/dist/bin/biome-to-oxc.d.mts +1 -0
  6. package/dist/bin/biome-to-oxc.mjs +93 -0
  7. package/dist/bin/biome-to-oxc.mjs.map +1 -0
  8. package/dist/config-loader-Do081Mw1.mjs +99 -0
  9. package/dist/config-loader-Do081Mw1.mjs.map +1 -0
  10. package/dist/eslint-detector-CiNY3vrg.mjs +69 -0
  11. package/dist/eslint-detector-CiNY3vrg.mjs.map +1 -0
  12. package/dist/formatter-mapper-BMQ4nHqQ.mjs +85 -0
  13. package/dist/formatter-mapper-BMQ4nHqQ.mjs.map +1 -0
  14. package/dist/overrides-transformer-D8lb8ijd.mjs +30 -0
  15. package/dist/overrides-transformer-D8lb8ijd.mjs.map +1 -0
  16. package/dist/oxfmt-overrides-BJtFUPt9.mjs +71 -0
  17. package/dist/oxfmt-overrides-BJtFUPt9.mjs.map +1 -0
  18. package/dist/oxlint-generator-L7ui1BHE.mjs +48 -0
  19. package/dist/oxlint-generator-L7ui1BHE.mjs.map +1 -0
  20. package/dist/package-updater-B-XgYVeR.mjs +69 -0
  21. package/dist/package-updater-B-XgYVeR.mjs.map +1 -0
  22. package/dist/prettier-detector-aLE389_O.mjs +50 -0
  23. package/dist/prettier-detector-aLE389_O.mjs.map +1 -0
  24. package/dist/report-writer-BU-Lyzye.mjs +22 -0
  25. package/dist/report-writer-BU-Lyzye.mjs.map +1 -0
  26. package/dist/reporter-B1SJ0-DK.mjs +26 -0
  27. package/dist/reporter-B1SJ0-DK.mjs.map +1 -0
  28. package/dist/rule-mapper-CvipfcEK.mjs +149 -0
  29. package/dist/rule-mapper-CvipfcEK.mjs.map +1 -0
  30. package/dist/schema-normalizer-CaJrUFMX.mjs +49 -0
  31. package/dist/schema-normalizer-CaJrUFMX.mjs.map +1 -0
  32. package/dist/src/advanced-detection.d.mts +19 -0
  33. package/dist/src/advanced-detection.d.mts.map +1 -0
  34. package/dist/src/advanced-detection.mjs +3 -0
  35. package/dist/src/config-loader.d.mts +9 -0
  36. package/dist/src/config-loader.d.mts.map +1 -0
  37. package/dist/src/config-loader.mjs +3 -0
  38. package/dist/src/eslint-detector.d.mts +9 -0
  39. package/dist/src/eslint-detector.d.mts.map +1 -0
  40. package/dist/src/eslint-detector.mjs +3 -0
  41. package/dist/src/formatter-mapper.d.mts +7 -0
  42. package/dist/src/formatter-mapper.d.mts.map +1 -0
  43. package/dist/src/formatter-mapper.mjs +3 -0
  44. package/dist/src/index.d.mts +7 -0
  45. package/dist/src/index.d.mts.map +1 -0
  46. package/dist/src/index.mjs +157 -0
  47. package/dist/src/index.mjs.map +1 -0
  48. package/dist/src/overrides-transformer.d.mts +7 -0
  49. package/dist/src/overrides-transformer.d.mts.map +1 -0
  50. package/dist/src/overrides-transformer.mjs +3 -0
  51. package/dist/src/oxfmt-overrides.d.mts +7 -0
  52. package/dist/src/oxfmt-overrides.d.mts.map +1 -0
  53. package/dist/src/oxfmt-overrides.mjs +3 -0
  54. package/dist/src/oxlint-generator.d.mts +7 -0
  55. package/dist/src/oxlint-generator.d.mts.map +1 -0
  56. package/dist/src/oxlint-generator.mjs +3 -0
  57. package/dist/src/package-updater.d.mts +7 -0
  58. package/dist/src/package-updater.d.mts.map +1 -0
  59. package/dist/src/package-updater.mjs +3 -0
  60. package/dist/src/prettier-detector.d.mts +8 -0
  61. package/dist/src/prettier-detector.d.mts.map +1 -0
  62. package/dist/src/prettier-detector.mjs +3 -0
  63. package/dist/src/report-writer.d.mts +8 -0
  64. package/dist/src/report-writer.d.mts.map +1 -0
  65. package/dist/src/report-writer.mjs +3 -0
  66. package/dist/src/reporter.d.mts +15 -0
  67. package/dist/src/reporter.d.mts.map +1 -0
  68. package/dist/src/reporter.mjs +3 -0
  69. package/dist/src/rule-mapper.d.mts +13 -0
  70. package/dist/src/rule-mapper.d.mts.map +1 -0
  71. package/dist/src/rule-mapper.mjs +3 -0
  72. package/dist/src/schema-normalizer.d.mts +11 -0
  73. package/dist/src/schema-normalizer.d.mts.map +1 -0
  74. package/dist/src/schema-normalizer.mjs +3 -0
  75. package/dist/src/turbo-updater.d.mts +9 -0
  76. package/dist/src/turbo-updater.d.mts.map +1 -0
  77. package/dist/src/turbo-updater.mjs +3 -0
  78. package/dist/src/types.d.mts +245 -0
  79. package/dist/src/types.d.mts.map +1 -0
  80. package/dist/src/types.mjs +1 -0
  81. package/dist/turbo-updater-3b20rC36.mjs +49 -0
  82. package/dist/turbo-updater-3b20rC36.mjs.map +1 -0
  83. package/dist/types-DCPpFKUB.mjs +1 -0
  84. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dominik Ospritis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,393 @@
1
+ # biome-to-oxc
2
+
3
+ 🚀 Migrate from [Biome](https://biomejs.dev) to the [Oxc](https://oxc.rs) ecosystem (oxlint + oxfmt)
4
+
5
+ ## Why Migrate?
6
+
7
+ The Oxc project provides blazing-fast alternatives to existing JavaScript tooling:
8
+
9
+ - **oxlint**: 10x faster than ESLint with 600+ rules and type-aware linting (alpha)
10
+ - **oxfmt**: 30x faster than Prettier, 3x faster than Biome, with Prettier compatibility
11
+
12
+ Both tools are production-ready and actively developed, even in alpha/beta stages.
13
+
14
+ ## Features
15
+
16
+ ### Core Migration
17
+
18
+ ✅ **Automatic Configuration Migration**
19
+
20
+ - Converts `biome.json`/`biome.jsonc` to `.oxlintrc.json` and `.oxfmtrc.jsonc`
21
+ - Maps 80+ Biome linter rules to Oxlint equivalents (native `typescript/` rules)
22
+ - Transforms Biome formatter options to Oxfmt (Prettier-compatible)
23
+ - Normalizes `include`/`includes` field variations automatically
24
+
25
+ ✅ **Preserves Your Setup**
26
+
27
+ - File patterns and ignore patterns
28
+ - Linter configuration overrides
29
+ - **NEW**: Formatter configuration overrides (per-file formatting rules)
30
+ - JavaScript globals and environments
31
+ - Rule severities (error/warn/off)
32
+ - Explicit `printWidth` handling (no silent changes)
33
+
34
+ ### Advanced Features
35
+
36
+ ✅ **Monorepo Support**
37
+
38
+ - Handles `"//"` extends syntax for monorepo roots
39
+ - Automatically detects `.git` or workspace roots
40
+ - Recursive config resolution with proper merging
41
+
42
+ ✅ **Type-Aware Linting** (`--type-aware`)
43
+
44
+ - Detects TypeScript usage
45
+ - Provides `oxlint-tsgolint` installation guidance
46
+ - Suggests type-aware linting commands
47
+
48
+ ✅ **Turborepo Integration** (`--turborepo`)
49
+
50
+ - Detects `turbo.json` configuration
51
+ - Provides task update suggestions
52
+ - Maintains monorepo workflow compatibility
53
+
54
+ ✅ **ESLint Bridge** (`--eslint-bridge`)
55
+
56
+ - Detects existing ESLint configurations
57
+ - Suggests `eslint-plugin-oxlint` integration
58
+ - Provides dual-tool workflow guidance
59
+ - Includes `eslint-plugin-oxfmt` suggestions
60
+
61
+ ✅ **Prettier Migration** (`--prettier`)
62
+
63
+ - Detects Prettier configurations
64
+ - Suggests `oxfmt --migrate=prettier` workflow
65
+ - Helps transition from Prettier to Oxfmt
66
+
67
+ ✅ **Smart Updates**
68
+
69
+ - Optional package.json script updates
70
+ - Automatic config backups
71
+ - Detailed migration reports with JSON export
72
+ - Dry-run mode for safety
73
+ - Integration detection and suggestions
74
+
75
+ ### Cutting-Edge & Experimental Features
76
+
77
+ ✅ **Advanced Formatting Options**
78
+
79
+ - **Object Wrapping**: Controls object literal formatting
80
+ - **Insert Final Newline**: Ensures files end with newline
81
+ - **Embedded Language Formatting**: Auto-formats CSS-in-JS, GraphQL-in-JS
82
+ - **HTML/Prose Options**: Whitespace sensitivity and prose wrapping
83
+
84
+ ✅ **Framework-Specific Support**
85
+
86
+ - **Vue.js**: Automatic detection and `vueIndentScriptAndStyle` configuration
87
+ - **React**: JSX-specific formatting options
88
+ - **Tailwind CSS**: Experimental class sorting and formatting
89
+ - Supports `class`, `className`, `:class` attributes
90
+ - Supports `clsx`, `cn`, `classNames`, `tw` functions
91
+
92
+ ✅ **Experimental Features** (Alpha/Beta)
93
+
94
+ - **Import Sorting**: `experimentalSortImports` with configurable order
95
+ - **Package.json Sorting**: `experimentalSortPackageJson` for consistent deps
96
+ - **Tailwind Integration**: `experimentalTailwindcss` for class optimization
97
+ - **Forward Compatibility**: Passes through unknown options for future features
98
+
99
+ ## Installation
100
+
101
+ ```bash
102
+ # Using npx (no installation required)
103
+ npx biome-to-oxc
104
+
105
+ # Or install globally
106
+ pnpm add -g biome-to-oxc
107
+ ```
108
+
109
+ ## Usage
110
+
111
+ ### Basic Usage
112
+
113
+ ```bash
114
+ # Auto-detect biome.json and migrate
115
+ npx biome-to-oxc
116
+
117
+ # Specify config path
118
+ npx biome-to-oxc --config path/to/biome.json
119
+
120
+ # Dry run to preview changes
121
+ npx biome-to-oxc --dry-run --verbose
122
+ ```
123
+
124
+ ### Options
125
+
126
+ ```
127
+ Options:
128
+ -c, --config <path> Path to biome.json or biome.jsonc
129
+ -o, --output-dir <path> Output directory for generated configs
130
+ --dry-run Show what would be done without making changes
131
+ --no-backup Skip backup of existing config files
132
+ --update-scripts Update package.json scripts to use oxlint/oxfmt
133
+ --type-aware Include type-aware linting guidance and dependencies
134
+ --turborepo Detect and update turbo.json for Turborepo integration
135
+ --eslint-bridge Provide ESLint bridge suggestions for running alongside ESLint
136
+ --prettier Detect Prettier config and provide migration suggestions
137
+ --report <path> Write detailed JSON migration report to specified path
138
+ -v, --verbose Show detailed migration information
139
+ -V, --version Output the version number
140
+ -h, --help Display help for command
141
+ ```
142
+
143
+ ### Examples
144
+
145
+ ```bash
146
+ # Preview migration without changes
147
+ npx biome-to-oxc --dry-run --verbose
148
+
149
+ # Migrate and update package.json scripts
150
+ npx biome-to-oxc --update-scripts
151
+
152
+ # Full migration with all integrations
153
+ npx biome-to-oxc --update-scripts --type-aware --turborepo --eslint-bridge --prettier
154
+
155
+ # Generate detailed JSON report
156
+ npx biome-to-oxc --report migration-report.json
157
+
158
+ # Migrate with custom output directory
159
+ npx biome-to-oxc --output-dir ./config
160
+
161
+ # Migrate without creating backups
162
+ npx biome-to-oxc --no-backup
163
+
164
+ # Monorepo setup with Turborepo
165
+ npx biome-to-oxc --turborepo --update-scripts
166
+
167
+ # TypeScript project with type-aware linting
168
+ npx biome-to-oxc --type-aware --verbose
169
+ ```
170
+
171
+ ## Migration Process
172
+
173
+ 1. **Reads** your `biome.json` or `biome.jsonc`
174
+ 2. **Resolves** extended configurations
175
+ 3. **Generates** two separate configs:
176
+ - `.oxlintrc.json` - Linter configuration
177
+ - `.oxfmtrc.jsonc` - Formatter configuration
178
+ 4. **Maps** Biome rules to Oxlint equivalents
179
+ 5. **Transforms** formatter options to Prettier-compatible format
180
+ 6. **Preserves** overrides and ignore patterns
181
+ 7. **Optionally updates** package.json scripts
182
+
183
+ ## Configuration Mapping
184
+
185
+ ### Linter Categories
186
+
187
+ | Biome Category | Oxlint Category |
188
+ | -------------- | --------------- |
189
+ | correctness | correctness |
190
+ | suspicious | suspicious |
191
+ | style | style |
192
+ | complexity | pedantic |
193
+ | performance | perf |
194
+ | security | restriction |
195
+
196
+ ### Formatter Options
197
+
198
+ | Biome Option | Oxfmt Option | Notes |
199
+ | ---------------- | --------------- | ------------------------------------------------------------- |
200
+ | lineWidth | printWidth | Biome default: 80, Oxfmt default: 100 (always set explicitly) |
201
+ | indentStyle | useTabs | Inverted (tab → true) |
202
+ | indentWidth | tabWidth | Direct mapping |
203
+ | lineEnding | endOfLine | Direct mapping |
204
+ | quoteStyle | singleQuote | Inverted (single → true) |
205
+ | trailingCommas | trailingComma | Direct mapping |
206
+ | semicolons | semi | Inverted (always → true) |
207
+ | arrowParentheses | arrowParens | Direct mapping |
208
+ | bracketSpacing | bracketSpacing | Direct mapping |
209
+ | bracketSameLine | bracketSameLine | Direct mapping |
210
+
211
+ ## After Migration
212
+
213
+ 1. **Review generated configs**
214
+
215
+ ```bash
216
+ cat .oxlintrc.json
217
+ cat .oxfmtrc.jsonc
218
+ ```
219
+
220
+ 2. **Install Oxc tools**
221
+
222
+ ```bash
223
+ pnpm add -D oxlint oxfmt
224
+ # or
225
+ npm install -D oxlint oxfmt
226
+ ```
227
+
228
+ 3. **Run the tools**
229
+
230
+ ```bash
231
+ # Lint your code
232
+ npx oxlint
233
+
234
+ # Format your code
235
+ npx oxfmt
236
+
237
+ # Check formatting without writing
238
+ npx oxfmt --check
239
+ ```
240
+
241
+ 4. **Update your CI/CD**
242
+
243
+ ```yaml
244
+ # Example GitHub Actions
245
+ - name: Lint
246
+ run: pnpm oxlint
247
+
248
+ - name: Check formatting
249
+ run: pnpm oxfmt --check
250
+ ```
251
+
252
+ 5. **Optional: Type-aware linting**
253
+
254
+ ```bash
255
+ # Install type-aware support (use @latest tag)
256
+ pnpm add -D oxlint-tsgolint@latest
257
+
258
+ # Run with type-aware rules
259
+ npx oxlint --type-aware
260
+ ```
261
+
262
+ ## Known Limitations
263
+
264
+ - Not all Biome rules have direct Oxlint equivalents (warnings will be shown)
265
+ - Some advanced Biome features may not be supported
266
+ - Oxfmt is in alpha - test thoroughly before production use
267
+ - Type-aware linting requires `oxlint-tsgolint` package (alpha)
268
+ - CSS and JSON formatter overrides are mapped but may need manual review
269
+ - Prettier plugin support is not available in Oxfmt
270
+
271
+ ## Migration Report
272
+
273
+ After migration, you'll see a comprehensive summary:
274
+
275
+ ```
276
+ ✓ Migration completed successfully!
277
+
278
+ Summary:
279
+ Biome config: /path/to/biome.json
280
+ Oxlint config: /path/to/.oxlintrc.json
281
+ Oxfmt config: /path/to/.oxfmtrc.jsonc
282
+ Rules converted: 42
283
+ Rules skipped: 3
284
+ Linter overrides: 2
285
+ Formatter overrides: 1
286
+
287
+ 🔍 Detected integrations: typescript, turborepo
288
+
289
+ ⚠ Warnings (3):
290
+ Run with --verbose to see all warnings
291
+
292
+ 💡 Suggestions:
293
+ 5 suggestions available. Run with --verbose to see them.
294
+
295
+ 📝 Next steps:
296
+ 1. Review the generated .oxlintrc.json and .oxfmtrc.jsonc files
297
+ 2. Install dependencies: pnpm add -D oxlint oxfmt
298
+ 3. Run oxlint to lint your code
299
+ 4. Run oxfmt to format your code
300
+ 5. Update your CI/CD pipelines to use oxlint and oxfmt
301
+ 6. Consider running with --update-scripts to update package.json
302
+
303
+ 📊 Detailed report saved to: migration-report.json
304
+ ```
305
+
306
+ ### JSON Report Format
307
+
308
+ When using `--report`, a detailed JSON file is generated:
309
+
310
+ ```json
311
+ {
312
+ "success": true,
313
+ "warnings": ["..."],
314
+ "errors": [],
315
+ "suggestions": ["..."],
316
+ "summary": {
317
+ "biomeConfigPath": "/path/to/biome.json",
318
+ "oxlintConfigPath": "/path/to/.oxlintrc.json",
319
+ "oxfmtConfigPath": "/path/to/.oxfmtrc.jsonc",
320
+ "rulesConverted": 42,
321
+ "rulesSkipped": 3,
322
+ "overridesConverted": 2,
323
+ "formatterOverridesConverted": 1
324
+ },
325
+ "detectedIntegrations": {
326
+ "turborepo": true,
327
+ "eslint": false,
328
+ "prettier": false,
329
+ "typescript": true
330
+ }
331
+ }
332
+ ```
333
+
334
+ ## Troubleshooting
335
+
336
+ ### "No Biome configuration file found"
337
+
338
+ Make sure you have a `biome.json` or `biome.jsonc` file in your project root, or specify the path with `--config`.
339
+
340
+ ### "No Oxlint equivalent found for Biome rule"
341
+
342
+ Some Biome rules don't have direct Oxlint equivalents yet. These will be logged as warnings. You can:
343
+
344
+ - Check if the rule is available in a newer version of oxlint
345
+ - Manually add similar rules to `.oxlintrc.json`
346
+ - Open an issue on the Oxc project to request the rule
347
+
348
+ ### TypeScript Errors
349
+
350
+ All TypeScript errors about missing modules are expected until you run `pnpm install`. The tool will work correctly once dependencies are installed.
351
+
352
+ ## Development
353
+
354
+ ```bash
355
+ # Install dependencies
356
+ pnpm install
357
+
358
+ # Build the project
359
+ pnpm build
360
+
361
+ # Run tests
362
+ pnpm test
363
+
364
+ # Lint
365
+ pnpm lint
366
+
367
+ # Format
368
+ pnpm format
369
+ ```
370
+
371
+ ## Contributing
372
+
373
+ Contributions are welcome! Please feel free to submit a Pull Request.
374
+
375
+ ## License
376
+
377
+ MIT
378
+
379
+ ## Acknowledgements
380
+
381
+ This tool is inspired by:
382
+
383
+ - [@oxlint/migrate](https://github.com/oxc-project/oxlint-migrate) - ESLint to Oxlint migration
384
+ - [oxfmt --migrate=prettier](https://oxc.rs/docs/guide/usage/formatter/migrate-from-prettier) - Prettier to Oxfmt migration
385
+
386
+ Special thanks to the [Oxc project](https://github.com/oxc-project/oxc) and [Biome](https://github.com/biomejs/biome) teams for their amazing work!
387
+
388
+ ## Resources
389
+
390
+ - [Oxc Documentation](https://oxc.rs)
391
+ - [Biome Documentation](https://biomejs.dev)
392
+ - [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter)
393
+ - [Oxfmt Configuration](https://oxc.rs/docs/guide/usage/formatter)
@@ -0,0 +1,71 @@
1
+ //#region src/advanced-detection.ts
2
+ function detectProjectFeatures(biomeConfig, reporter) {
3
+ const features = {
4
+ hasVue: false,
5
+ hasReact: false,
6
+ hasTailwind: false,
7
+ hasTypeScript: false,
8
+ hasImportSorting: false,
9
+ hasMonorepo: false,
10
+ hasGraphQL: false,
11
+ hasCSS: false,
12
+ hasHTML: false
13
+ };
14
+ biomeConfig.files?.include?.some((f) => f.endsWith(".html")) || biomeConfig.overrides?.some((o) => o.include?.some((f) => f.endsWith(".html"))) || "html" in biomeConfig && biomeConfig.html;
15
+ const allIncludes = [
16
+ ...biomeConfig.files?.include || [],
17
+ ...biomeConfig.linter?.include || [],
18
+ ...biomeConfig.formatter?.include || []
19
+ ];
20
+ features.hasVue = allIncludes.some((pattern) => pattern.includes(".vue") || pattern.toLowerCase().includes("vue"));
21
+ features.hasReact = allIncludes.some((pattern) => pattern.includes(".jsx") || pattern.includes(".tsx") || pattern.toLowerCase().includes("react")) || !!biomeConfig.javascript?.parser?.jsxEverywhere;
22
+ features.hasTailwind = allIncludes.some((pattern) => pattern.toLowerCase().includes("tailwind") || pattern.includes("tw-") || pattern.includes("tailwind.config"));
23
+ features.hasTypeScript = allIncludes.some((pattern) => pattern.includes(".ts") || pattern.includes(".tsx") || pattern.includes(".mts"));
24
+ if (biomeConfig.linter?.rules && typeof biomeConfig.linter.rules === "object") features.hasImportSorting = Object.keys(biomeConfig.linter.rules).some((key) => key.toLowerCase().includes("import") && (key.toLowerCase().includes("sort") || key.toLowerCase().includes("order")));
25
+ features.hasMonorepo = !!biomeConfig.extends && (Array.isArray(biomeConfig.extends) ? biomeConfig.extends.includes("//") : biomeConfig.extends === "//");
26
+ features.hasGraphQL = allIncludes.some((pattern) => pattern.includes(".graphql") || pattern.includes(".gql") || pattern.toLowerCase().includes("graphql"));
27
+ features.hasCSS = allIncludes.some((pattern) => pattern.includes(".css") || pattern.includes(".scss") || pattern.includes(".sass") || pattern.includes(".less")) || !!biomeConfig.css;
28
+ features.hasHTML = allIncludes.some((pattern) => pattern.includes(".html") || pattern.includes(".htm")) || !!biomeConfig.html;
29
+ const detectedFeatures = Object.entries(features).filter(([_, value]) => value).map(([key]) => key.replace("has", ""));
30
+ if (detectedFeatures.length > 0) reporter.info(`Detected project features: ${detectedFeatures.join(", ")}`);
31
+ return features;
32
+ }
33
+ function generateFeatureSpecificSuggestions(features) {
34
+ const suggestions = [];
35
+ if (features.hasVue) {
36
+ suggestions.push("");
37
+ suggestions.push("Vue.js detected:");
38
+ suggestions.push(" - vueIndentScriptAndStyle option configured");
39
+ suggestions.push(" - Consider using @vue/eslint-config-prettier for Vue-specific formatting");
40
+ }
41
+ if (features.hasTailwind) {
42
+ suggestions.push("");
43
+ suggestions.push("Tailwind CSS detected:");
44
+ suggestions.push(" - experimentalTailwindcss enabled with common class attributes");
45
+ suggestions.push(" - Supports: class, className, :class attributes");
46
+ suggestions.push(" - Supports: clsx, cn, classNames, tw functions");
47
+ }
48
+ if (features.hasImportSorting) {
49
+ suggestions.push("");
50
+ suggestions.push("Import sorting detected:");
51
+ suggestions.push(" - experimentalSortImports enabled");
52
+ suggestions.push(" - Imports will be sorted alphabetically with newlines between groups");
53
+ }
54
+ if (features.hasGraphQL) {
55
+ suggestions.push("");
56
+ suggestions.push("GraphQL detected:");
57
+ suggestions.push(" - Consider using graphql-prettier for GraphQL formatting");
58
+ suggestions.push(" - Oxfmt may support GraphQL in future releases");
59
+ }
60
+ if (features.hasMonorepo) {
61
+ suggestions.push("");
62
+ suggestions.push("Monorepo detected:");
63
+ suggestions.push(" - experimentalSortPackageJson enabled for all package.json files");
64
+ suggestions.push(" - Consider using workspace-specific overrides");
65
+ }
66
+ return suggestions;
67
+ }
68
+
69
+ //#endregion
70
+ export { generateFeatureSpecificSuggestions as n, detectProjectFeatures as t };
71
+ //# sourceMappingURL=advanced-detection-Bekr41wZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced-detection-Bekr41wZ.mjs","names":[],"sources":["../src/advanced-detection.ts"],"sourcesContent":["import type { BiomeConfig, Reporter } from './types.js';\n\nexport type ProjectFeatures = {\n hasVue: boolean;\n hasReact: boolean;\n hasTailwind: boolean;\n hasTypeScript: boolean;\n hasImportSorting: boolean;\n hasMonorepo: boolean;\n hasGraphQL: boolean;\n hasCSS: boolean;\n hasHTML: boolean;\n};\n\nexport function detectProjectFeatures(\n biomeConfig: BiomeConfig,\n reporter: Reporter,\n): ProjectFeatures {\n const features: ProjectFeatures = {\n hasVue: false,\n hasReact: false,\n hasTailwind: false,\n hasTypeScript: false,\n hasImportSorting: false,\n hasMonorepo: false,\n hasGraphQL: false,\n hasCSS: false,\n hasHTML: false,\n };\n\n const hasHtml =\n biomeConfig.files?.include?.some((f) => f.endsWith('.html')) ||\n biomeConfig.overrides?.some((o) => o.include?.some((f) => f.endsWith('.html'))) ||\n ('html' in biomeConfig && !!(biomeConfig as any).html);\n\n const allIncludes = [\n ...(biomeConfig.files?.include || []),\n ...(biomeConfig.linter?.include || []),\n ...(biomeConfig.formatter?.include || []),\n ];\n\n // Vue detection\n features.hasVue = allIncludes.some(\n (pattern) => pattern.includes('.vue') || pattern.toLowerCase().includes('vue'),\n );\n\n // React detection\n features.hasReact =\n allIncludes.some(\n (pattern) =>\n pattern.includes('.jsx') ||\n pattern.includes('.tsx') ||\n pattern.toLowerCase().includes('react'),\n ) || !!biomeConfig.javascript?.parser?.jsxEverywhere;\n\n // Tailwind detection\n features.hasTailwind = allIncludes.some(\n (pattern) =>\n pattern.toLowerCase().includes('tailwind') ||\n pattern.includes('tw-') ||\n pattern.includes('tailwind.config'),\n );\n\n // TypeScript detection\n features.hasTypeScript = allIncludes.some(\n (pattern) => pattern.includes('.ts') || pattern.includes('.tsx') || pattern.includes('.mts'),\n );\n\n // Import sorting detection\n if (biomeConfig.linter?.rules && typeof biomeConfig.linter.rules === 'object') {\n features.hasImportSorting = Object.keys(biomeConfig.linter.rules).some(\n (key) =>\n key.toLowerCase().includes('import') &&\n (key.toLowerCase().includes('sort') || key.toLowerCase().includes('order')),\n );\n }\n\n // Monorepo detection\n features.hasMonorepo =\n !!biomeConfig.extends &&\n (Array.isArray(biomeConfig.extends)\n ? biomeConfig.extends.includes('//')\n : biomeConfig.extends === '//');\n\n // GraphQL detection\n features.hasGraphQL = allIncludes.some(\n (pattern) =>\n pattern.includes('.graphql') ||\n pattern.includes('.gql') ||\n pattern.toLowerCase().includes('graphql'),\n );\n\n // CSS detection\n features.hasCSS =\n allIncludes.some(\n (pattern) =>\n pattern.includes('.css') ||\n pattern.includes('.scss') ||\n pattern.includes('.sass') ||\n pattern.includes('.less'),\n ) || !!biomeConfig.css;\n\n // HTML detection\n features.hasHTML =\n allIncludes.some((pattern) => pattern.includes('.html') || pattern.includes('.htm')) ||\n !!(biomeConfig as any).html;\n\n // Log detected features\n const detectedFeatures = Object.entries(features)\n .filter(([_, value]) => value)\n .map(([key]) => key.replace('has', ''));\n\n if (detectedFeatures.length > 0) {\n reporter.info(`Detected project features: ${detectedFeatures.join(', ')}`);\n }\n\n return features;\n}\n\nexport function generateFeatureSpecificSuggestions(features: ProjectFeatures): string[] {\n const suggestions: string[] = [];\n\n if (features.hasVue) {\n suggestions.push('');\n suggestions.push('Vue.js detected:');\n suggestions.push(' - vueIndentScriptAndStyle option configured');\n suggestions.push(' - Consider using @vue/eslint-config-prettier for Vue-specific formatting');\n }\n\n if (features.hasTailwind) {\n suggestions.push('');\n suggestions.push('Tailwind CSS detected:');\n suggestions.push(' - experimentalTailwindcss enabled with common class attributes');\n suggestions.push(' - Supports: class, className, :class attributes');\n suggestions.push(' - Supports: clsx, cn, classNames, tw functions');\n }\n\n if (features.hasImportSorting) {\n suggestions.push('');\n suggestions.push('Import sorting detected:');\n suggestions.push(' - experimentalSortImports enabled');\n suggestions.push(' - Imports will be sorted alphabetically with newlines between groups');\n }\n\n if (features.hasGraphQL) {\n suggestions.push('');\n suggestions.push('GraphQL detected:');\n suggestions.push(' - Consider using graphql-prettier for GraphQL formatting');\n suggestions.push(' - Oxfmt may support GraphQL in future releases');\n }\n\n if (features.hasMonorepo) {\n suggestions.push('');\n suggestions.push('Monorepo detected:');\n suggestions.push(' - experimentalSortPackageJson enabled for all package.json files');\n suggestions.push(' - Consider using workspace-specific overrides');\n }\n\n return suggestions;\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import "../reporter-B1SJ0-DK.mjs";
3
+ import "../config-loader-Do081Mw1.mjs";
4
+ import { migrate } from "../src/index.mjs";
5
+ import { program } from "commander";
6
+ import pc from "picocolors";
7
+ import { z } from "zod";
8
+
9
+ //#region bin/biome-to-oxc.ts
10
+ const packageJson = {
11
+ name: "biome-to-oxc",
12
+ version: "0.1.0",
13
+ description: "Migrate from Biome to Oxc ecosystem (oxlint + oxfmt)"
14
+ };
15
+ const MigrationOptionsSchema = z.object({
16
+ configPath: z.string().optional(),
17
+ outputDir: z.string().optional(),
18
+ dryRun: z.boolean().default(false),
19
+ noBackup: z.boolean().default(false),
20
+ updateScripts: z.boolean().default(false),
21
+ verbose: z.boolean().default(false),
22
+ typeAware: z.boolean().default(false),
23
+ turborepo: z.boolean().default(false),
24
+ eslintBridge: z.boolean().default(false),
25
+ prettier: z.boolean().default(false),
26
+ report: z.string().optional()
27
+ });
28
+ const handleSignal = (signal, code) => {
29
+ process.exit(code);
30
+ };
31
+ process.on("SIGINT", () => handleSignal("SIGINT", 130));
32
+ process.on("SIGTERM", () => handleSignal("SIGTERM", 143));
33
+ process.on("unhandledRejection", (reason) => {
34
+ console.error(pc.red("\n✖ Unhandled Promise Rejection:"));
35
+ console.error(reason);
36
+ process.exit(1);
37
+ });
38
+ process.on("uncaughtException", (error) => {
39
+ console.error(pc.red("\n✖ Uncaught Exception:"));
40
+ console.error(error);
41
+ process.exit(1);
42
+ });
43
+ async function main() {
44
+ program.name("biome-to-oxc").version(packageJson.version).description(packageJson.description).option("-c, --config <path>", "Path to biome.json or biome.jsonc").option("-o, --output-dir <path>", "Output directory for generated configs").option("--dry-run", "Show what would be done without making changes").option("--no-backup", "Skip backup of existing config files").option("--update-scripts", "Update package.json scripts to use oxlint/oxfmt").option("--type-aware", "Include type-aware linting guidance and dependencies").option("--turborepo", "Detect and update turbo.json for Turborepo integration").option("--eslint-bridge", "Provide ESLint bridge suggestions for running alongside ESLint").option("--prettier", "Detect Prettier config and provide migration suggestions").option("--report <path>", "Write detailed JSON migration report to specified path").option("-v, --verbose", "Show detailed migration information").action(async (rawOptions) => {
45
+ try {
46
+ const opts = {
47
+ ...rawOptions,
48
+ noBackup: !rawOptions.backup
49
+ };
50
+ delete opts.backup;
51
+ const validationResult = MigrationOptionsSchema.safeParse(opts);
52
+ if (!validationResult.success) {
53
+ console.error(pc.red("✖ Invalid options:"));
54
+ validationResult.error.errors.forEach((err) => {
55
+ console.error(` - ${err.path.join(".")}: ${err.message}`);
56
+ });
57
+ process.exit(1);
58
+ }
59
+ const migrationOptions = validationResult.data;
60
+ const report = await migrate(migrationOptions);
61
+ if (report.success) {
62
+ if (report.detectedIntegrations) {
63
+ if (Object.entries(report.detectedIntegrations).filter(([_, detected]) => detected).map(([name]) => name).length > 0) {}
64
+ }
65
+ if (report.warnings.length > 0) {
66
+ if (migrationOptions.verbose) report.warnings.forEach((w) => {});
67
+ }
68
+ if (report.suggestions.length > 0) {
69
+ if (migrationOptions.verbose) report.suggestions.forEach((s) => {});
70
+ }
71
+ if (!migrationOptions.updateScripts) {}
72
+ if (migrationOptions.report) {}
73
+ process.exit(0);
74
+ } else {
75
+ if (report.errors.length > 0) report.errors.forEach((e) => {});
76
+ process.exit(1);
77
+ }
78
+ } catch (error) {
79
+ console.error(pc.red("\n✖ Unexpected error during migration:"));
80
+ console.error(error instanceof Error ? error.stack : error);
81
+ process.exit(1);
82
+ }
83
+ });
84
+ await program.parseAsync();
85
+ }
86
+ main().catch((error) => {
87
+ console.error(pc.red("✖ Fatal error:"), error);
88
+ process.exit(1);
89
+ });
90
+
91
+ //#endregion
92
+ export { };
93
+ //# sourceMappingURL=biome-to-oxc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"biome-to-oxc.mjs","names":[],"sources":["../../bin/biome-to-oxc.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { program } from 'commander';\nimport pc from 'picocolors';\nimport { z } from 'zod';\nimport { migrate } from '../src/index.js';\nimport type { MigrationOptions } from '../src/types.js';\n\nconst packageJson = {\n name: 'biome-to-oxc',\n version: '0.1.0',\n description: 'Migrate from Biome to Oxc ecosystem (oxlint + oxfmt)',\n};\n\n// Zod schema for runtime validation\nconst MigrationOptionsSchema = z.object({\n configPath: z.string().optional(),\n outputDir: z.string().optional(),\n dryRun: z.boolean().default(false),\n noBackup: z.boolean().default(false),\n updateScripts: z.boolean().default(false),\n verbose: z.boolean().default(false),\n typeAware: z.boolean().default(false),\n turborepo: z.boolean().default(false),\n eslintBridge: z.boolean().default(false),\n prettier: z.boolean().default(false),\n report: z.string().optional(),\n});\n\n// Handle interrupt signals\nconst handleSignal = (signal: string, code: number) => {\n \n process.exit(code);\n};\n\nprocess.on('SIGINT', () => handleSignal('SIGINT', 130));\nprocess.on('SIGTERM', () => handleSignal('SIGTERM', 143));\n\nprocess.on('unhandledRejection', (reason) => {\n console.error(pc.red('\\n✖ Unhandled Promise Rejection:'));\n console.error(reason);\n process.exit(1);\n});\n\nprocess.on('uncaughtException', (error) => {\n console.error(pc.red('\\n✖ Uncaught Exception:'));\n console.error(error);\n process.exit(1);\n});\n\nasync function main() {\n program\n .name('biome-to-oxc')\n .version(packageJson.version)\n .description(packageJson.description)\n .option('-c, --config <path>', 'Path to biome.json or biome.jsonc')\n .option('-o, --output-dir <path>', 'Output directory for generated configs')\n .option('--dry-run', 'Show what would be done without making changes')\n .option('--no-backup', 'Skip backup of existing config files')\n .option('--update-scripts', 'Update package.json scripts to use oxlint/oxfmt')\n .option('--type-aware', 'Include type-aware linting guidance and dependencies')\n .option('--turborepo', 'Detect and update turbo.json for Turborepo integration')\n .option('--eslint-bridge', 'Provide ESLint bridge suggestions for running alongside ESLint')\n .option('--prettier', 'Detect Prettier config and provide migration suggestions')\n .option('--report <path>', 'Write detailed JSON migration report to specified path')\n .option('-v, --verbose', 'Show detailed migration information')\n .action(async (rawOptions) => {\n \n\n try {\n // Normalize options (commander transforms --no-backup to backup: false, we need to map it back)\n const opts = {\n ...rawOptions,\n noBackup: !rawOptions.backup, // map from commander's negation\n };\n // Remove the auxiliary backup prop from commander\n delete opts.backup;\n\n const validationResult = MigrationOptionsSchema.safeParse(opts);\n\n if (!validationResult.success) {\n console.error(pc.red('✖ Invalid options:'));\n validationResult.error.errors.forEach((err) => {\n console.error(` - ${err.path.join('.')}: ${err.message}`);\n });\n process.exit(1);\n }\n\n const migrationOptions: MigrationOptions = validationResult.data;\n\n const report = await migrate(migrationOptions);\n\n if (report.success) {\n \n \n \n \n \n \n \n \n \n\n if (report.detectedIntegrations) {\n const integrations = Object.entries(report.detectedIntegrations)\n .filter(([_, detected]) => detected)\n .map(([name]) => name);\n\n if (integrations.length > 0) {\n \n }\n }\n\n if (report.warnings.length > 0) {\n \n if (migrationOptions.verbose) {\n report.warnings.forEach((w) => {});\n } else {\n \n }\n }\n\n if (report.suggestions.length > 0) {\n \n if (migrationOptions.verbose) {\n report.suggestions.forEach((s) => {});\n } else {\n \n }\n }\n\n \n \n \n \n \n \n\n if (!migrationOptions.updateScripts) {\n \n }\n\n if (migrationOptions.report) {\n \n }\n\n process.exit(0);\n } else {\n \n\n if (report.errors.length > 0) {\n \n report.errors.forEach((e) => {});\n }\n\n process.exit(1);\n }\n } catch (error) {\n console.error(pc.red('\\n✖ Unexpected error during migration:'));\n console.error(error instanceof Error ? error.stack : error);\n process.exit(1);\n }\n });\n\n await program.parseAsync();\n}\n\nmain().catch((error) => {\n console.error(pc.red('✖ Fatal error:'), error);\n process.exit(1);\n});\n"],"mappings":"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"}