Current section
Files
Jump to
Current section
Files
src/gleamql@directive.erl
-module(gleamql@directive).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleamql/directive.gleam").
-export([new/1, with_arg/3, skip/1, skip_if/1, include/1, include_if/1, deprecated/1, specified_by/1, to_string/1, name/1, arguments/1]).
-export_type([directive_argument/0, directive/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" GraphQL directive support for fields, fragments, and operations.\n"
"\n"
" This module provides support for GraphQL directives, which are annotations\n"
" that can be applied to fields, fragments, and other GraphQL elements to\n"
" modify their behavior at execution time.\n"
"\n"
" ## Basic Usage\n"
"\n"
" ```gleam\n"
" import gleamql/directive\n"
" import gleamql/field\n"
"\n"
" // Use @skip directive to conditionally exclude a field\n"
" let name_field = \n"
" field.string(\"name\")\n"
" |> field.with_directive(directive.skip(\"skipName\"))\n"
"\n"
" // Use @include directive to conditionally include a field\n"
" let email_field =\n"
" field.string(\"email\")\n"
" |> field.with_directive(directive.include(\"includeEmail\"))\n"
"\n"
" // Multiple directives on one field\n"
" let profile_field =\n"
" field.string(\"profile\")\n"
" |> field.with_directive(directive.include(\"showProfile\"))\n"
" |> field.with_directive(directive.deprecated(Some(\"Use profileV2 instead\")))\n"
" ```\n"
"\n"
" ## Built-in Directives\n"
"\n"
" GraphQL defines several standard directives:\n"
"\n"
" - **@skip(if: Boolean!)** - Skip field if condition is true\n"
" - **@include(if: Boolean!)** - Include field if condition is true\n"
" - **@deprecated(reason: String)** - Mark field as deprecated\n"
" - **@specifiedBy(url: String!)** - Provide scalar specification URL\n"
"\n"
" ## Custom Directives\n"
"\n"
" You can also create custom directives using the `new()` and `with_arg()` functions:\n"
"\n"
" ```gleam\n"
" directive.new(\"customDirective\")\n"
" |> directive.with_arg(\"arg1\", directive.InlineString(\"value\"))\n"
" |> directive.with_arg(\"arg2\", directive.InlineInt(42))\n"
" ```\n"
"\n"
).
-type directive_argument() :: {variable, binary()} |
{inline_string, binary()} |
{inline_int, integer()} |
{inline_float, float()} |
{inline_bool, boolean()} |
inline_null |
{inline_object, list({binary(), directive_argument()})} |
{inline_list, list(directive_argument())}.
-opaque directive() :: {directive,
binary(),
list({binary(), directive_argument()})}.
-file("src/gleamql/directive.gleam", 99).
?DOC(
" Create a new directive with the given name and no arguments.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let custom = directive.new(\"myDirective\")\n"
" // Generates: @myDirective\n"
" ```\n"
).
-spec new(binary()) -> directive().
new(Name) ->
{directive, Name, []}.
-file("src/gleamql/directive.gleam", 116).
?DOC(
" Add an argument to a directive.\n"
"\n"
" Arguments can be inline values or variable references.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" directive.new(\"customDirective\")\n"
" |> directive.with_arg(\"limit\", directive.InlineInt(10))\n"
" |> directive.with_arg(\"filter\", directive.Variable(\"filterVar\"))\n"
" // Generates: @customDirective(limit: 10, filter: $filterVar)\n"
" ```\n"
).
-spec with_arg(directive(), binary(), directive_argument()) -> directive().
with_arg(Dir, Arg_name, Arg_value) ->
{directive, Name, Args} = Dir,
{directive, Name, [{Arg_name, Arg_value} | Args]}.
-file("src/gleamql/directive.gleam", 148).
?DOC(
" Create a @skip directive that conditionally excludes a field.\n"
"\n"
" The @skip directive is one of the standard GraphQL directives. When the\n"
" condition evaluates to true, the field is excluded from the response.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" field.string(\"name\")\n"
" |> field.with_directive(directive.skip(\"shouldSkipName\"))\n"
" // Generates: name @skip(if: $shouldSkipName)\n"
" ```\n"
"\n"
" You must define the corresponding variable in your operation:\n"
"\n"
" ```gleam\n"
" operation.query(\"GetUser\")\n"
" |> operation.variable(\"shouldSkipName\", \"Boolean!\")\n"
" |> operation.field(user_field())\n"
" ```\n"
).
-spec skip(binary()) -> directive().
skip(Variable_name) ->
{directive, <<"skip"/utf8>>, [{<<"if"/utf8>>, {variable, Variable_name}}]}.
-file("src/gleamql/directive.gleam", 164).
?DOC(
" Create a @skip directive with an inline boolean value.\n"
"\n"
" This variant uses an inline boolean instead of a variable reference.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" field.string(\"name\")\n"
" |> field.with_directive(directive.skip_if(True))\n"
" // Generates: name @skip(if: true)\n"
" ```\n"
).
-spec skip_if(boolean()) -> directive().
skip_if(Condition) ->
{directive, <<"skip"/utf8>>, [{<<"if"/utf8>>, {inline_bool, Condition}}]}.
-file("src/gleamql/directive.gleam", 189).
?DOC(
" Create an @include directive that conditionally includes a field.\n"
"\n"
" The @include directive is one of the standard GraphQL directives. When the\n"
" condition evaluates to true, the field is included in the response.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" field.string(\"email\")\n"
" |> field.with_directive(directive.include(\"shouldIncludeEmail\"))\n"
" // Generates: email @include(if: $shouldIncludeEmail)\n"
" ```\n"
"\n"
" You must define the corresponding variable in your operation:\n"
"\n"
" ```gleam\n"
" operation.query(\"GetUser\")\n"
" |> operation.variable(\"shouldIncludeEmail\", \"Boolean!\")\n"
" |> operation.field(user_field())\n"
" ```\n"
).
-spec include(binary()) -> directive().
include(Variable_name) ->
{directive,
<<"include"/utf8>>,
[{<<"if"/utf8>>, {variable, Variable_name}}]}.
-file("src/gleamql/directive.gleam", 205).
?DOC(
" Create an @include directive with an inline boolean value.\n"
"\n"
" This variant uses an inline boolean instead of a variable reference.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" field.string(\"email\")\n"
" |> field.with_directive(directive.include_if(True))\n"
" // Generates: email @include(if: true)\n"
" ```\n"
).
-spec include_if(boolean()) -> directive().
include_if(Condition) ->
{directive, <<"include"/utf8>>, [{<<"if"/utf8>>, {inline_bool, Condition}}]}.
-file("src/gleamql/directive.gleam", 224).
?DOC(
" Create a @deprecated directive to mark a field as deprecated.\n"
"\n"
" The @deprecated directive is typically used in schema definitions, but can\n"
" also be useful for documentation purposes in queries.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" directive.deprecated(Some(\"Use newField instead\"))\n"
" // Generates: @deprecated(reason: \"Use newField instead\")\n"
"\n"
" directive.deprecated(None)\n"
" // Generates: @deprecated\n"
" ```\n"
).
-spec deprecated(gleam@option:option(binary())) -> directive().
deprecated(Reason) ->
case Reason of
{some, R} ->
{directive,
<<"deprecated"/utf8>>,
[{<<"reason"/utf8>>, {inline_string, R}}]};
none ->
{directive, <<"deprecated"/utf8>>, []}
end.
-file("src/gleamql/directive.gleam", 243).
?DOC(
" Create a @specifiedBy directive to reference a scalar specification.\n"
"\n"
" The @specifiedBy directive provides a URL to the specification of a custom scalar.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" directive.specified_by(\"https://tools.ietf.org/html/rfc3339\")\n"
" // Generates: @specifiedBy(url: \"https://tools.ietf.org/html/rfc3339\")\n"
" ```\n"
).
-spec specified_by(binary()) -> directive().
specified_by(Url) ->
{directive,
<<"specifiedBy"/utf8>>,
[{<<"url"/utf8>>, {inline_string, Url}}]}.
-file("src/gleamql/directive.gleam", 317).
?DOC(" Escape special characters in strings for GraphQL.\n").
-spec escape_string(binary()) -> binary().
escape_string(Value) ->
_pipe = Value,
_pipe@1 = gleam@string:replace(_pipe, <<"\\"/utf8>>, <<"\\\\"/utf8>>),
_pipe@2 = gleam@string:replace(_pipe@1, <<"\""/utf8>>, <<"\\\""/utf8>>),
_pipe@3 = gleam@string:replace(_pipe@2, <<"\n"/utf8>>, <<"\\n"/utf8>>),
_pipe@4 = gleam@string:replace(_pipe@3, <<"\r"/utf8>>, <<"\\r"/utf8>>),
gleam@string:replace(_pipe@4, <<"\t"/utf8>>, <<"\\t"/utf8>>).
-file("src/gleamql/directive.gleam", 286).
?DOC(" Convert a DirectiveArgument to its GraphQL string representation.\n").
-spec argument_to_string(directive_argument()) -> binary().
argument_to_string(Arg) ->
case Arg of
{variable, Name} ->
<<"$"/utf8, Name/binary>>;
{inline_string, Value} ->
<<<<"\""/utf8, (escape_string(Value))/binary>>/binary, "\""/utf8>>;
{inline_int, Value@1} ->
erlang:integer_to_binary(Value@1);
{inline_float, Value@2} ->
gleam_stdlib:float_to_string(Value@2);
{inline_bool, true} ->
<<"true"/utf8>>;
{inline_bool, false} ->
<<"false"/utf8>>;
inline_null ->
<<"null"/utf8>>;
{inline_object, Fields} ->
Formatted_fields = begin
_pipe = Fields,
_pipe@1 = gleam@list:map(
_pipe,
fun(Field) ->
{Key, Value@3} = Field,
<<<<Key/binary, ": "/utf8>>/binary,
(argument_to_string(Value@3))/binary>>
end
),
gleam@string:join(_pipe@1, <<", "/utf8>>)
end,
<<<<"{ "/utf8, Formatted_fields/binary>>/binary, " }"/utf8>>;
{inline_list, Items} ->
Formatted_items = begin
_pipe@2 = Items,
_pipe@3 = gleam@list:map(_pipe@2, fun argument_to_string/1),
gleam@string:join(_pipe@3, <<", "/utf8>>)
end,
<<<<"["/utf8, Formatted_items/binary>>/binary, "]"/utf8>>
end.
-file("src/gleamql/directive.gleam", 263).
?DOC(
" Convert a directive to its GraphQL string representation.\n"
"\n"
" This is used internally to generate the GraphQL query string.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" directive.to_string(directive.skip(\"var\"))\n"
" // Returns: \"@skip(if: $var)\"\n"
"\n"
" directive.to_string(directive.include_if(true))\n"
" // Returns: \"@include(if: true)\"\n"
" ```\n"
).
-spec to_string(directive()) -> binary().
to_string(Dir) ->
{directive, Name, Args} = Dir,
Args_string = case Args of
[] ->
<<""/utf8>>;
Args@1 ->
Formatted_args = begin
_pipe = Args@1,
_pipe@1 = lists:reverse(_pipe),
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Arg) ->
{Key, Value} = Arg,
<<<<Key/binary, ": "/utf8>>/binary,
(argument_to_string(Value))/binary>>
end
),
gleam@string:join(_pipe@2, <<", "/utf8>>)
end,
<<<<"("/utf8, Formatted_args/binary>>/binary, ")"/utf8>>
end,
<<<<"@"/utf8, Name/binary>>/binary, Args_string/binary>>.
-file("src/gleamql/directive.gleam", 339).
?DOC(" Get the name of a directive.\n").
-spec name(directive()) -> binary().
name(Dir) ->
erlang:element(2, Dir).
-file("src/gleamql/directive.gleam", 345).
?DOC(" Get the arguments of a directive.\n").
-spec arguments(directive()) -> list({binary(), directive_argument()}).
arguments(Dir) ->
erlang:element(3, Dir).