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

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

[0.1.0] - 2026-11-07

First public release.

Added

  • Exports from any Enumerable or {Repo, queryable} Ecto source:
  • Plug/Phoenix downloads (BeamExport.Plug, requires :plug):
    • send_staged_export/4 writes the export to a private (0700) temporary directory, releases the database connection, then serves the file with send_file. Temporary files are removed when the request process exits.
    • send_chunked_export/4 streams with chunked transfer encoding and stops reading the source when the client disconnects.
  • CSV encoding: RFC 4180 quoting, custom separators, "\r\n" or "\n" line terminators. Exact floats (Float.to_string/1), decimals in plain notation, ISO 8601 dates and times, tuple rows (Ecto select: {...}), and map/struct records read by :headers.
  • Formula injection protection, enabled by default (sanitize_formulas: true), following the OWASP recommendation.
  • Ecto integration: cursor streaming with :max_rows batches; eager rejection of preloads (BeamExport.PreloadError); reuses the caller's transaction when there is one; uses Repo.transact/2 on Ecto 3.13+ and Repo.transaction/2 before.
  • Errors: BeamExport.MappingError, BeamExport.EncodeError, BeamExport.TimeoutError, BeamExport.ExportError, BeamExport.PreloadError. Record contents are redacted by default (:include_record_in_errors opts in).
  • Option validation: unknown options and invalid values raise ArgumentError.
  • Telemetry: [:beam_export, :export, :start | :chunk | :stop | :exception] events from to_file/3 and to_iodata/2. Exception metadata is always redacted.

Behaviour notes

These describe guarantees that a pre-release audit found missing in earlier development snapshots:

  • An export that does not complete is never reported as successful. This covers stalled consumers (:consumer_timeout), unresponsive databases (:batch_timeout), failed commits, crashed workers, and write errors reported only when a file is closed (for example a full disk).
  • A failed export never deletes a file it did not create or truncate, and never deletes non-regular files.
  • meta.rows counts the header row.