Skip to content

Instantly share code, notes, and snippets.

View moroz's full-sized avatar

Karol Moroz moroz

  • Senior Full Stack Developer at virtualQ GmbH
  • Bay Area, Kaohsiung, TW
  • 09:59 (UTC +08:00)
View GitHub Profile
@moroz
moroz / furigana.tex
Created August 22, 2019 04:12
Furigana in Japanese using XeTeX
\documentclass{article}
\usepackage{fontspec,xeCJK}
\usepackage[overlap,CJK]{ruby}
\renewcommand{\rubysep}{-0.2ex}
\begin{document}
これは\ruby{日本語}{にほんご}の\ruby{文章}{ぶんしょう}。
\end{document}
@moroz
moroz / api_case.ex
Created November 21, 2020 03:28
Test helper for testing Absinthe GraphQL APIs in ExUnit
defmodule MyAppWeb.ApiCase do
use ExUnit.CaseTemplate
using(opts) do
schema = Keyword.get(opts, :schema, MyAppWeb.Api.Schema)
api_path = Keyword.get(opts, :api_path, "/api")
quote do
@__schema__ unquote(schema)
@__api_path__ unquote(api_path)
@moroz
moroz / script.sh
Created November 25, 2020 03:47
Download JDK 8 for Android development without creating Oracle account
#!/bin/sh
DOWNLOAD_URL="https://download.oracle.com/otn-pub/java/jdk/8u271-b09/61ae65e088624f5aaa0b1d2d801acb16/jdk-8u271-linux-x64.tar.gz"
wget -c --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" $DOWNLOAD_URL
@moroz
moroz / format_page.ex
Created November 26, 2020 04:21
Format a pagination struct into neat GraphQL response (scrivener_ecto, absinthe)
defmodule MyAppWeb.Api.Middleware.FormatPage do
@behaviour Absinthe.Middleware
def call(%{value: %Scrivener.Page{} = page} = res, _) do
%{
entries: data,
page_number: page_number,
page_size: page_size,
total_pages: total_pages,
total_entries: total_entries
@moroz
moroz / restrict_access.ex
Last active January 20, 2021 02:49
Transform errors in Absinthe graphql mutations
defmodule MyAppWeb.Api.Middleware.RestrictAccess do
@behaviour Absinthe.Middleware
@moduledoc """
A simple Absinthe middleware to ensure that GraphQL queries or mutations
are always run by authorized users.
"""
def init(default), do: default
@moroz
moroz / cookie_helper.ex
Created February 3, 2021 14:20
Set session with Absinthe mutation
@moroz
moroz / authorize.ex
Created February 4, 2021 01:42
Per-action authorization in Absinthe schema with Bodyguard
defmodule MyAppWeb.Api.Middleware.Authorize do
@behaviour Absinthe.Middleware
@moduledoc """
Absinthe middleware to deny access based on Bodyguard ACLs.
The field name is passed to the policy module as string, as I haven't found
any better way to get the field name from the resolution object.
"""
def call(%{context: %{current_user: user}} = res, module) when is_atom(module) do
@moroz
moroz / application.ex
Created April 3, 2021 05:30
Automatically migrate Ecto database in release
defmodule MyApp.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
@migrator if Mix.env() in [:prod, :staging], do: [MyApp.Migrator], else: []
def start(_type, _args) do
children =
@moroz
moroz / guards.ex
Created April 5, 2021 10:10
Custom Elixir guard for IDs
defmodule MyApp.Guards do
defguard is_id(id) when is_binary(id) or is_integer(id)
end
@moroz
moroz / lazy_preload.ex
Created December 28, 2021 16:07
Lazy preloading Ecto associations
defmodule MyAppWeb.Api.Middleware.LazyPreload do
@moduledoc """
Absinthe middleware to preload Ecto associations only if they have
been requested.
"""
require Absinthe.Schema.Notation
defmacro lazy_preload(assoc_name) do
quote do