New place to share code for use in `src-js`, similar to how `crates/oxc_config` works.
Initially, I considered creating an `apps/oxc_cli` and moving `crates/oxc_config` there. However, it felt unnatural deps for `crates/oxc_linter` -> `apps/oxc_cli`, so I decided to keep the Rust code as is for now and share only the JS code.
Since `apps/shared` exports `.ts` files directly, each app is responsible for bundling them via `@oxapps/shared`. Tests still live in `apps/shared`, so separate CI is also added and hooked by each app.
To start, I've only shared the function that reports TS incompatibility errors. This is just for verification purposes and will be fixed in a later PR.
Remove `noUnusedLocals` option from `tsconfig.json` files. It's redundant, as Oxlint `no-unused-vars` covers this for us.
It's an annoyance to have `noUnusedLocals` enabled, as in VS Code TypeScript complains about unused vars, even if they're prefixed with `_`.
Removing this option allows simplifying type tests added in #20066. Only reason these types had to be exported was to stop TS complaining that they were unused.
Replaces #20064
The `dom` lib was implicitly being injected, this means stuff like `Token` and `Comment` were in the global scope, which was incorrect.
cc @overlookmotel
Previously, `oxfmt`'s e2e tests were written in Rust.
However, after migrating our CLI to napi, e2e tests using Vitest were also added.
As a result, there is no longer any reason to maintain tests on the Rust side.
Additionally, while tests using `napi` are possible in Vitest, they are not possible in Rust.
So consolidated everything to Vitest.
Additionally, I added tests that were not included in the previous PR for `embeddedLanguageFormatting: "auto" | "off"`.
## Summary
Adds support for formatting embedded languages (CSS, GraphQL, HTML, Markdown) in JavaScript/TypeScript template literals using Prettier via NAPI bindings.
## Motivation
JavaScript/TypeScript developers often embed CSS, GraphQL queries, HTML, and Markdown in their code using tagged template literals. Without proper formatting support, these embedded languages remain unformatted, leading to inconsistent code style and reduced readability.
This PR enables oxfmt to format these embedded languages using Prettier, providing a seamless formatting experience similar to Prettier's own embedded language support.
## Changes
### Core Functionality
- **Embedded language detection**: Recognizes `css`, `styled`, `gql`, `graphql`, `html`, `md`, and `markdown` template tags
- **Prettier integration**: Uses `@prettier/sync` for synchronous formatting of embedded code
- **NAPI bridge**: Rust-to-JavaScript interop using NAPI ThreadsafeFunction
- **Graceful fallback**: Returns original code if formatting fails or tag is unsupported
### Implementation Details
**Rust side** (`crates/oxc_formatter/`, `apps/oxfmt/src/prettier_plugins/`):
- New `EmbeddedFormatter` trait with callback-based API
- NAPI bindings using `FnArgs` pattern for clean multi-argument calls
- Template formatter enhancement to detect and format tagged templates
- Proper indentation handling: splits Prettier output into lines, uses `hard_line_break()` separators, wraps in `indent()` for context-aware indentation
- Arena allocator pattern to avoid borrow checker conflicts
**JavaScript side** (`apps/oxfmt/src-js/`):
- TypeScript bindings with clean signatures: `formatEmbeddedCode(tagName: string, code: string)`
- Prettier configuration: 80 char width, 2 space indent, semicolons, double quotes
- Tag-to-parser mapping for supported languages
- Error handling with console logging and fallback
**Testing**:
- E2E test suite using Vitest (8 test cases)
- Test fixtures for each supported language
- Snapshot testing with timing normalization for stability
- All tests passing consistently
## Examples
**Before** (unformatted):
```js
const styles = css`.button { color: red; background: blue; }`;
```
**After** (formatted with proper indentation):
```js
const styles = css`
.button {
color: red;
background: blue;
}
`;
```
**Supported tags:**
```js
// CSS
const styles = css`...`;
const component = styled`...`;
// GraphQL
const query = gql`...`;
const schema = graphql`...`;
// HTML
const template = html`...`;
// Markdown
const docs = md`...`;
const readme = markdown`...`;
```
## Testing
```bash
# Run oxfmt tests
just oxfmt
# Watch mode for development
just watch-oxfmt
```
All 8 E2E tests pass:
- ✓ embedded_css
- ✓ embedded_graphql
- ✓ embedded_html
- ✓ embedded_markdown
- ✓ mixed_embedded
- ✓ no_embedded
- ✓ unsupported_tag
- ✓ check_mode
## Related
Related to #13427
## Future Work
Potential enhancements:
- Support for additional embedded languages (SQL, YAML, etc.)
- Custom Prettier configuration via oxfmt config
- Performance optimization for large embedded blocks
- Integration with language servers for inline diagnostics