Skip to content

Commit

Permalink
[MOTOR-1353]: [Bburago] Support for auth0 (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
enerdgumen authored May 16, 2022
1 parent 15fd2b1 commit 2d6f3f9
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 3 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Next]

## [1.2.0] - 2022-05-16

### Added

- New `BridgeEx.Extensions.ExternalResources` module useful to embed external resources with less boilerplate

### Fixed

- Typespec of `BridgeEx.Graphql.Client.call` function is now compatible with `encode_variables: true` option

## [1.1.0] - 2022-03-07

### Added
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ Refer to [the documentation](https://hexdocs.pm/bridge_ex/BridgeEx.Graphql.html)

If you need more control on your requests you can use [`BridgeEx.Graphql.Client.call`](https://hexdocs.pm/bridge_ex/BridgeEx.Graphql.Client.html#call/7) directly.

The library supports preloading queries from external files via the `BridgeEx.Extensions.ExternalResources` optional macro:

```elixir
defmodule MyApp.SomeServiceBridge do
use BridgeEx.Graphql, endpoint: "http://some_service.example.com"
use BridgeEx.Extensions.ExternalResources, resources: [my_query: "my_query.graphql"]

def my_query(%{} = variables), do: call(my_query(), variables)
end
```

#### Call options

When `call`ing you can provide the following options, some of which override the ones provided when `use`ing the bridge:
Expand Down Expand Up @@ -186,7 +197,7 @@ The package can be installed by adding `bridge_ex` to your list of dependencies
```elixir
def deps do
[
{:bridge_ex, "~> 1.1.0"}
{:bridge_ex, "~> 1.2.0"}
# only if you want auth0 too
# {:prima_auth0_ex, "~> 0.3.0"}
]
Expand Down
64 changes: 64 additions & 0 deletions lib/extensions/external_resources.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
defmodule BridgeEx.Extensions.ExternalResources do
@moduledoc """
Preload a set of resources marking them as "external" and provide the related getter functions.
## Options
* `resources` (required): enumerable of resource names (atoms) and their paths (strings).
Each path is assumed to be relative to the module directory.
## Examples
```elixir
defmodule MyBridge do
use BridgeEx.Extensions.ExternalResources,
resources: [
my_query: "queries/query.graphql",
my_mutation: "mutations/mutation.graphql"
]
# it generates the following code:
@external_resource "\#{__DIR__}/queries/query.graphql"
@external_resource "\#{__DIR__}/mutations/mutation.graphql"
@spec my_query() :: String.t()
def my_query, do: Map.fetch!(external_resources(), :my_query)
@spec my_mutation() :: String.t()
def my_mutation, do: Map.fetch!(external_resources(), :my_mutation)
defp external_resources do
%{
my_query: "contents of query.graphql",
my_mutation: "contents of mutation.graphql"
}
end
end
```
"""

defmacro __using__(resources: resources) do
dir = Path.dirname(__CALLER__.file)
resources = for {name, path} <- resources, do: {name, Path.join(dir, path)}
contents = for {name, path} <- resources, into: %{}, do: {name, File.read!(path)}

getters =
for {name, _path} <- resources do
quote do
@spec unquote(name)() :: String.t()
def unquote(name)(), do: Map.fetch!(external_resources(), unquote(name))
end
end

external_resource_attributes =
for {_name, path} <- resources do
quote do: @external_resource(unquote(path))
end

quote generated: true do
unquote_splicing(external_resource_attributes)
unquote_splicing(getters)
defp external_resources, do: unquote(Macro.escape(contents))
end
end
end
2 changes: 1 addition & 1 deletion lib/graphql/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule BridgeEx.Graphql.Client do
@spec call(
url :: String.t(),
query :: String.t(),
variables :: map(),
variables :: map() | String.t(),
http_options :: Keyword.t(),
http_headers :: map(),
retry_options :: Keyword.t(),
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule BridgeEx.MixProject do
use Mix.Project

@source_url "https://github.com/primait/bridge_ex"
@version "1.1.0"
@version "1.2.0"

def project do
[
Expand Down
46 changes: 46 additions & 0 deletions test/extensions/external_resources_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
defmodule BridgeEx.Extensions.ExternalResourcesTest do
use ExUnit.Case

defmodule Example do
use BridgeEx.Extensions.ExternalResources,
resources: [
question: "resources/question.txt",
answer: "resources/answer.txt"
]
end

test "it generates getter functions" do
assert "How many roads must a man walk down?" == Example.question()
assert "42" == Example.answer()
end

test "it marks files as external resources" do
paths =
for {:external_resource, [path]} <- Example.__info__(:attributes),
into: MapSet.new(),
do: Path.relative_to(path, __DIR__)

assert MapSet.new(["resources/question.txt", "resources/answer.txt"]) == paths
end

test "it fails to compile if no resources are given" do
quoted =
quote do
use BridgeEx.Extensions.ExternalResources
end

assert_raise FunctionClauseError, fn -> Code.eval_quoted(quoted) end
end

test "it fails to compile if a file is missing" do
quoted =
quote do
use BridgeEx.Extensions.ExternalResources,
resources: [
missing: "missing.txt"
]
end

assert_raise File.Error, fn -> Code.eval_quoted(quoted) end
end
end
1 change: 1 addition & 0 deletions test/extensions/resources/answer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
1 change: 1 addition & 0 deletions test/extensions/resources/question.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
How many roads must a man walk down?

0 comments on commit 2d6f3f9

Please sign in to comment.