All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.3.1 - 2026-08-14

Tracks the June–July 2026 Dropbox API spec updates that touch routes Magpie already wraps.

Added

  • Magpie.Files.ListFolder.list_folder/3 and stream/3 now take an optional opts map merged into the request body, so callers can use the remaining /files/list_folder arguments — including the new include_restorable_info flag (each returned deleted entry then says whether it can be restored via is_restorable)
  • Magpie.Files.ListFolder.list_revisions/4 gained the same optional opts map ("mode", "before_rev", "include_restorable_info")

Changed

  • Magpie.Files.get_thumbnail_v2/3 docs no longer list "quality" as an option — Dropbox pulled the field from the public API surface in the July 2026 spec update

0.3.0 - 2026-08-10

Phoenix uploads. LiveView already owns the upload experience, so Magpie does not ship a component — it fills the two gaps a Dropbox backend creates: getting the bytes there without spooling them to disk, and skipping the server altogether.

Added

  • Magpie.LiveView.UploadWriter — a Phoenix.LiveView.UploadWriter that streams a LiveView upload straight into a Dropbox upload session, so the bytes never land on the server's disk. Chunks are buffered to :chunk_size (default 8 MiB, Dropbox wants multiples of 4 MiB) and the tail rides along with the finish call. Magpie does not depend on :phoenix_live_view — the behaviour is a plain set of callbacks
  • Magpie.LiveView.presign_upload/4 — a LiveView :external uploader that mints a one-time link with Magpie.Files.get_temporary_upload_link/3 so the browser posts the file straight to Dropbox, bypassing the server. Entries above Dropbox's 150 MB single-request limit are rejected at presign time instead of being handed a link that cannot work. The client-side half ships as priv/static/magpie_uploader.js

0.2.1 - 2026-08-05

Added

  • Magpie.Auth.TokenServer no longer requires a refresh token at startup. A server started without one sits in an unconfigured state — calls return a pattern-matchable {:error, %Magpie.Error{summary: "no_refresh_token"}} without touching the network — and the new set_refresh_token/3 configures it (or replaces the token, for re-authorization) at any time, discarding any cached access token unless a valid access_token/expires_at pair is seeded. Fresh installs whose token arrives through the OAuth callback now work from a plain static supervision tree
  • Magpie.Auth.authorize_url/2 accepts extra_params: (keyword list or map) for additional Dropbox authorization params such as force_reapprove, locale, require_role and disable_signup. Params the function already sets cannot be overridden — collisions raise ArgumentError

0.2.0 - 2026-08-05

OAuth 2 support. Dropbox access tokens expire after ~4 hours, so a static token is not enough for anything that runs unattended — Magpie now handles the whole flow and keeps tokens fresh on its own.

Added

  • Magpie.Auth — OAuth 2 flow helpers: authorize_url/2 (offline access by default), pkce_pair/0 and pkce_challenge/1 for public apps, exchange_code/3 and refresh/3
  • Magpie.Auth.Token — token struct with an absolute expires_at computed from Dropbox's expires_in
  • Magpie.Auth.TokenProvider — behaviour that decouples the client from where tokens live, with two implementations: Magpie.Auth.StaticToken and Magpie.Auth.TokenServer
  • Magpie.Auth.TokenServer — supervised token holder that refreshes proactively (configurable :refresh_margin, default 300s), serializes concurrent refreshes into a single request, survives failed refreshes and can persist tokens through an :on_refresh callback
  • Magpie.Client.new/1 accepts a refresh token (refresh_token:/app_key: + app_secret: or pkce: true, starting a linked TokenServer) or an explicit token_provider: {module, arg}
  • Transparent recovery from expired tokens: requests rejected with HTTP 401 expired_access_token are refreshed and replayed once. Streamed upload bodies cannot be replayed and are not retried — the proactive refresh covers them
  • OAuth guide on HexDocs: getting a refresh token from the App Console, the web redirect flow, PKCE, supervision, persistence and custom providers

Changed

  • Magpie.Client gained a token_provider field; access_token is kept and Magpie.Client.new("ACCESS_TOKEN") behaves exactly as before
  • Magpie.Error.new/2 uses the OAuth error field (e.g. "invalid_grant") as the error summary when there is no error_summary

0.1.0 - 2026-08-01

First release of Magpie 🐦 — a modern, actively maintained Elixir client for the Dropbox API v2, born as a rewrite of the unmaintained elixir_dropbox package (see the Origin section of the README).

Added

Changed

  • HTTP client migrated from HTTPoison/Poison to Req/Jason
  • Every call now returns {:ok, result} or {:error, %Magpie.Error{}}
  • Deprecated Dropbox endpoints migrated to their current versions: move_v2, search_v2 (+ search/continue_v2), copy_batch_v2 (+ check_v2), upload_session/finish_batch_v2 and create_shared_link_with_settings
  • Default endpoint URLs are built in — consumer configuration is optional

Fixed

Deprecated

  • The legacy /paper/docs/* wrappers (Magpie.Paper.*) remain for compatibility, but the whole Paper API is deprecated by Dropbox — prefer Magpie.Files.Paper