Squirrelix reimplements Gleam Squirrel's core
SQL discovery, inference, and codegen behavior with an idiomatic Elixir-native public API.
Upstream Squirrel remains the compatibility reference for query conventions and edge-case tests;
Elixir conventions take precedence for API shape, @spec output, and runtime return values.
Elixir-native direction: generated modules use stdlib typespecs (String.t(), integer(),
map() with required/1, term() for JSON, and so on). Squirrelix does not generate
Gleam records, custom enum ADTs, or opaque tagged error values.
Completed
Query discovery and parsing
- [x] One-query-per-file discovery under
lib/,test/, anddev/. - [x] Leading SQL comments become generated function
@docstrings. - [x] Invalid filename handling with suggested renames where possible.
- [x] One-query-per-file discovery under
Parameter inference
- [x] Equality comparisons, line and block comments, string literals, quoted identifiers, and table-qualified identifiers.
- [x] Generated Elixir argument names deconflicted against
connectionand reserved names.
Postgres inference
- [x] Postgrex prepare metadata for parameters and result types.
- [x] Nullability for table columns, outer joins,
using(...), CTEs, and foreign-key-derived cases. - [x] Structured errors for syntax errors, missing tables, missing columns, invalid enums, and unsupported types.
Type mapping (Elixir-native)
- [x] Scalar Postgres types mapped to Elixir stdlib typespecs.
- [x] Custom Postgres enums mapped to
String.t()(not generated enum modules). - [x] Custom domains mapped to their base type.
- [x] Recursive array support with live Postgrex tests.
- [x] JSON/JSONB mapped to
term()in@specs; composite/point types rejected with hints. - [x] Composite-type policy: reject-with-hints (no nested row modules / opaque
encodings); geometric
pointalso rejected with workarounds. Documented inguides/types.mdand the README FAQ. - [x] Ranges/multiranges and remaining unsupported built-ins rejected with actionable
hints; inventory documented in
guides/types.md.
Code generation
- [x] Per-query row
@typedefinitions and@spec-annotated functions. - [x] Row queries return decoded maps; command queries return
:ok. - [x] Safe overwrite and
mix squirrelix.checkdrift detection. - [x] Runtime decode coverage for nullable values, arrays, JSON, UUIDs, dates/times, and command results.
- [x] Per-query row
Mix tasks and configuration
- [x] Metadata-file mode (
squirr_elix.exsor--metadata). - [x]
--infermode with Postgrex connection options andPG*environment defaults. - [x]
mix squirrelix.genandmix squirrelix.checktask documentation. - [x] Programmatic
Squirrelix.generate/3andSquirrelix.check/3API.
- [x] Metadata-file mode (
Package and docs
- [x] Hex package metadata, Apache-2.0 license, and ExDoc module grouping.
- [x] README mirroring Gleam Squirrel structure (motivation, installation, types, FAQ).
- [x] Guides: getting started, writing queries, types, and configuration.
- [x] ExDoc extras and module docs linking to guides.
Remaining
Parameter inference
- [x] Port remaining upstream cases for repeated parameter names, invalid inferred identifiers, keyword-like names, and ambiguous comparisons.
- [x] Rename inferred
connectionarguments to avoid shadowing the Postgrex connection param.
Postgres inference
- [x] Expand nullability for schema-qualified tables, subqueries in select lists, and expression-derived columns where practical.
- [x] Improve structured errors for connection failures and timeouts.
Type mapping
- [x] Document and finalize behavior for Postgres ranges and remaining unsupported built-ins.
- [x] Revisit composite-type support policy (reject-with-hints; see Completed).
Upstream fixture porting
- [x] Port remaining Birdie snapshots into focused ExUnit cases by behavior rather than copying generated Gleam APIs (join nullability, select-list aliases, multi-helper codegen, long enum names, enum arrays, connection shadowing).
- [x] Document intentional Gleam-only snapshot gaps in
squirr_elix_gleam_parity_test.exs.
Gleam implementation alignment
- [x] Sort generated query functions by source file path (matches Gleam reproducibility).
- [x] Align validation error titles and hints with upstream Squirrel wording (duplicate columns, invalid file/column names, outdated/cannot-overwrite files).
- [x] Keep intentional divergences: Elixir row maps and
@specs,String.t()enums,timestamptzmapped toDateTime.t(), function-name sorting only when file/name differ.
Release
- [x] Harden codegen escaping, EXPLAIN path, overwrite markers, and release docs.
- [x] Publish
0.1.0to Hex and enable HexDocs at https://hexdocs.pm/squirr_elix.
Validation discipline
Each completed slice should run:
mix precommit
(mix precommit runs mix format, mix credo.strict, and mix test.)
Commit only after validation passes.