# `Spark.Dsl`
[🔗](https://github.com/ash-project/spark/blob/v2.7.0/lib/spark/dsl.ex#L5)

The primary entry point for defining a DSL.

To define a DSL, add `use Spark.Dsl, ...options`. The options supported with `use Spark.Dsl` are:

* `:single_extension_kinds` (list of `t:atom/0`) - The extension kinds that are allowed to have a single value. For example: `[:data_layer]` The default value is `[]`.

* `:many_extension_kinds` (list of `t:atom/0`) - The extension kinds that can have multiple values. e.g `[notifiers: [Notifier1, Notifier2]]` The default value is `[]`.

* `:untyped_extensions?` (`t:boolean/0`) - Whether or not to support an `extensions` key which contains untyped extensions The default value is `true`.

* `:extension_kind_types` (`t:keyword/0`) - A keyword list of extension kinds and their types, e.g `[authorizers: {:list, {:behaviour, Ash.Authorizer}}]` The default value is `[]`.

* `:extension_kind_docs` (`t:keyword/0`) - A keyword list of extension kinds and a short documentation snippet to be used when autocompleting that option The default value is `[]`.

* `:default_extensions` (`t:keyword/0`) - The extensions that are included by default. e.g `[data_layer: Default, notifiers: [Notifier1]]`
  Default values for single extension kinds are overwritten if specified by the implementor, while many extension
  kinds are appended to if specified by the implementor. The default value is `[]`.

* `:opt_schema` (`t:keyword/0`) - A schema for additional options to accept when calling `use YourSpark` The default value is `[]`.

* `:opts_to_document` - A list of `t:atom/0` or `:all`. Spark automatically detects options and documents them in `@moduledoc`.
  You can instruct Spark to use only a subset of options, e.g. `opts_to_document: [:fragments]`. The default value is `:all`.

See the callbacks defined in this module to augment the behavior/compilation of the module getting a Dsl.

## Schemas/Data Types

For more information, see `Spark.Options`.

# `entity`

```elixir
@type entity() :: %Spark.Dsl.Entity{
  args: term(),
  auto_set_fields: term(),
  deprecations: term(),
  describe: term(),
  docs: term(),
  entities: term(),
  examples: term(),
  hide: term(),
  identifier: term(),
  imports: term(),
  links: term(),
  modules: term(),
  name: term(),
  no_depend_modules: term(),
  recursive_as: term(),
  schema: term(),
  singleton_entity_keys: term(),
  snippet: term(),
  target: term(),
  transform: term()
}
```

# `opts`

```elixir
@type opts() :: keyword()
```

# `section`

```elixir
@type section() :: %Spark.Dsl.Section{
  after_define: term(),
  auto_set_fields: term(),
  deprecations: term(),
  describe: term(),
  docs: term(),
  entities: term(),
  examples: term(),
  imports: term(),
  links: term(),
  modules: term(),
  name: term(),
  no_depend_modules: term(),
  patchable?: term(),
  schema: term(),
  sections: term(),
  singleton_entity_keys: term(),
  snippet: term(),
  top_level?: term()
}
```

# `t`

```elixir
@type t() :: map()
```

# `explain`

```elixir
@callback explain(t(), opts()) :: String.t() | nil
```

Validate/add options. Those options will be passed to `handle_opts` and `handle_before_compile`

# `handle_before_compile`

```elixir
@callback handle_before_compile(keyword()) :: Macro.t()
```

Handle options in the context of the module, after all extensions have been processed. Must return a `quote` block.

# `handle_opts`

```elixir
@callback handle_opts(keyword()) :: Macro.t()
```

Handle options in the context of the module. Must return a `quote` block.

If you want to persist anything in the DSL persistence layer,
use `@persist {:key, value}`. It can be called multiple times to
persist multiple times.

# `init`

```elixir
@callback init(opts()) :: {:ok, opts()} | {:error, String.t() | term()}
```

Validate/add options. Those options will be passed to `handle_opts` and `handle_before_compile`

# `verify`

```elixir
@callback verify(
  module(),
  keyword()
) :: term()
```

A callback that is called in the `after_verify` hook. Only runs on versions of Elixir >= 1.14.0

# `handle_fragments`

# `is?`

---

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