# `OXC.Lint`
[🔗](https://github.com/elixir-volt/oxc_ex/blob/v0.19.0/lib/oxc/lint.ex#L1)

Lint JavaScript/TypeScript source with oxlint's built-in rules
and optional custom Elixir rules.

Combines native Rust performance for 650+ standard rules with
the ability to write project-specific rules in Elixir using
the same AST that `OXC.parse/2` returns.

## Examples

    {:ok, diags} = OXC.Lint.run("debugger;", "test.js",
      rules: %{"no-debugger" => :deny})

    {:ok, []} = OXC.Lint.run("export const x = 1;\n", "test.ts")

# `diagnostic`

```elixir
@type diagnostic() :: OXC.Diagnostic.t()
```

# `global_access`

```elixir
@type global_access() :: :readonly | :writable | :off
```

# `option`

```elixir
@type option() ::
  {:rules, %{required(String.t()) =&gt; severity()}}
  | {:plugins, [plugin()]}
  | {:env, [String.t()]}
  | {:globals, %{required(String.t()) =&gt; global_access()}}
  | {:fix, boolean()}
  | {:custom_rules, [{module(), severity()}]}
  | {:settings, map()}
```

# `plugin`

```elixir
@type plugin() :: String.t()
```

An oxlint plugin name, such as `"react"` or `"jsx-a11y"`.

# `severity`

```elixir
@type severity() :: :allow | :warn | :deny
```

Rule severity in lint options. Findings report `:error` for `:deny` and `:warning` for `:warn`.

# `run`

```elixir
@spec run([String.t()], [OXC.Lint.TypeAware.option()]) ::
  {:ok, [diagnostic()]} | {:error, [diagnostic()]}
```

Lint source code with oxlint's built-in rules and optional custom rules.

Pass a list of files with `type_aware: true` to run TypeScript type-aware
rules through `tsgolint` headless mode:

    OXC.Lint.run(["lib/app.ts"],
      type_aware: true,
      tsgolint: "tsgolint",
      rules: %{"typescript/no-floating-promises" => :deny})

Categories select type-aware rules too, from the enabled `:plugins`, so
`rules: %{"correctness" => :deny}` runs `typescript/no-floating-promises`.

## Options

  * `:rules` — map of rule names to severity (`:deny`, `:warn`, `:allow`).
    Rule names follow oxlint conventions: `"eqeqeq"`, `"react/no-danger"`,
    `"typescript/no-explicit-any"`, etc. Categories such as `"correctness"`
    and `"all"` select every rule in them. `"all"` applies first, then
    categories, then single rules, so a single rule overrides its category.

  * `:plugins` — oxlint plugin names to enable, such as `["react", "jsx-a11y"]`,
    accepting the same names and aliases as an oxlint config file.
    Default: oxlint's default plugins. Unknown names are errors.

  * `:fix` — compute fix suggestions. Default: `false`

  * `:env` — list of enabled Oxlint environment names, for example
    `["browser", "node", "mocha"]`.

  * `:globals` — map of global names to `:readonly`, `:writable`, or `:off`,
    for example `%{"jQuery" => :readonly}`.

  * `:custom_rules` — list of `{module, severity}` tuples for Elixir rules.
    Each module must implement the `OXC.Lint.Rule` behaviour.

  * `:settings` — arbitrary map passed to custom rule context.

## Examples

    # Built-in rules only
    {:ok, diags} = OXC.Lint.run("debugger;", "test.js",
      rules: %{"no-debugger" => :deny})

    # With specific plugins and rules
    {:ok, diags} = OXC.Lint.run(source, "app.tsx",
      plugins: ["react", "typescript"],
      rules: %{"no-console" => :warn, "react/no-danger" => :deny}
    )

    # With custom Elixir rules
    {:ok, diags} = OXC.Lint.run(source, "app.ts",
      custom_rules: [{MyApp.NoConsoleLog, :warn}]
    )

# `run`

```elixir
@spec run(iodata(), String.t(), [option()]) ::
  {:ok, [diagnostic()]} | {:error, [diagnostic()]}
```

# `run!`

```elixir
@spec run!(iodata(), String.t(), [option()]) :: [diagnostic()]
```

Like `run/3` but raises on errors.

# `type_aware_rules`

```elixir
@spec type_aware_rules(keyword()) ::
  {:ok, %{required(String.t()) =&gt; severity() | {severity(), term()}}}
  | {:error, [diagnostic()]}
```

Resolve the type-aware rules that `run/2` submits to tsgolint for these options.

`all` and category filters in `:rules` select type-aware rules from the enabled
`:plugins` through oxlint's rule registry. Rules named `typescript/*` keep their
options and override their categories. Other rules are syntax rules and are left out.

    {:ok, %{"typescript/no-floating-promises" => :deny}} =
      OXC.Lint.type_aware_rules(rules: %{"typescript/no-floating-promises" => :deny})

---

*Consult [api-reference.md](api-reference.md) for complete listing*
