Changelog
View SourceAll 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.
[Unreleased]
[0.9.3] - 2026-04-01
Added
spectra_type:update_meta/2: New helper that updates a type's metadata map in one call, reducing the boilerplate of pairedget_meta/set_metacalls.make lint: New lint target usingelp lint --rebar --read-config(also added to CI).
Changed
#sp_user_type_ref{}and#sp_remote_type{}internal records now cachearitydirectly, eliminating repeatedlength/1calls across all serialization and deserialization modules.
[0.9.2] - 2026-03-27
Added
spectra_calendar_codec: Built-in codec forcalendar:datetime()andcalendar:date(). Serialises to/from ISO 8601 strings ("YYYY-MM-DDTHH:MM:SS"and"YYYY-MM-DD"). Opt-in via the application environment, same pattern asspectra_dict_codec.
[0.9.1] - 2026-03-26
Fixed
- String/binary constraints (
min_length,max_length,pattern) are now correctly enforced when the type body is a remote type alias that resolves to a string/binary type (e.g. Elixir'sString.t()). Previously the constraints were silently ignored.
[0.9.0] - 2026-03-24
Added
spectra_dict_codec: Built-in codec for encoding and decodingdict:dict()values. Register it via the app env or-behaviour(spectra_codec)like any other codec. Mostly to show that codecs can be implemented for types with arity > 0.
Changed
- Breaking:
spectra_codeccallbacks now receive an additionalSpType :: spectra:sp_type()argument.encodeanddecodeare now arity 6;schemais now arity 5. Existing codec modules must add this argument to all callback clauses. Usespectra_type:type_args/1onSpTypeto access concrete type-variable bindings at the call site.
[0.8.2] - 2026-03-21
Changed
- README: added reference tables documenting all valid
-spectra()attribute keys for types/records and function specs, including thetitlevssummarydistinction.
[0.8.1] - 2026-03-21
Added
- Exported OpenAPI types:
spectra_openapinow exportsendpoint_spec/0,endpoint_doc/0,response_spec/0,parameter_spec/0,parameter_input_spec/0,http_method/0,http_status_code/0, andopenapi_metadata/0. parameter_input_spec/0: New type for the map passed towith_parameter/3. Distinct from the internalparameter_spec/0(which includesmodule) — the function mergesmodulein automatically.
Changed
- README overhauled: simpler introductory example, cleaner API reference, restructured Custom Codecs section, added
binary_string/stringformat example.
[0.8.0] - 2026-03-19
Added
- Custom codecs: New
spectra_codecbehaviour withencode/4,decode/4, and optionalschema/4callbacks. Register codecs via the application environment ({spectra, [{codecs, #{...}}]}) or by declaring-behaviour(spectra_codec)on the type's own module. - Type parameters: Types can now carry a
type_parametersfield in their-spectra()attribute. The value is passed as the 4th argument to codec callbacks, allowing a single codec module to handle multiple parameterised variants. - Auto-populate
descriptionanddeprecatedfrom type annotations: Parameters, request bodies, and response headers that reference a type with a-spectra()doc annotation now automatically inheritdescriptionanddeprecated. Explicit values on the spec still take precedence. - Plain atom type refs in
spectra_openapi:spectra_openapifunctions now accept plain atoms as type references (e.g.userinstead of{type, user, 0}), matching the behaviour ofspectra.erl.
Changed
- Breaking:
with_request_body/4fourth argument changed from an opts map (#{content_type => ..., description => ...}) to a plaincontent_typebinary. Passdescriptionvia the type's-spectra()annotation instead.
Fixed
type_doc/2now follows type references: The internaltype_doc/2function inspectra_openapipreviously returned an empty description whenever the resolved type was an#sp_user_type_ref{}or#sp_remote_type{}. It now follows the reference to the underlying type to retrieve its description. Local annotations on the alias take precedence — the reference is only followed when the alias itself carries no-spectradoc.
[0.7.0] - 2026-03-04
Added
descriptionanddeprecatedfields for OpenAPI parameters:parameter_spec()now acceptsdescription => binary()anddeprecated => boolean()fields, propagated into the generated OpenAPI output.descriptionfor request body specs:request_body_spec()now accepts adescriptionfield.deprecatedfor response header specs:header_spec()now accepts adeprecated => boolean()field.- Extended
openapi_metadata(): Supports additionalinfofields and a top-levelserverslist for multi-server OpenAPI documents.
Changed
- Breaking:
with_request_body/3,4now takes the schema as the third positional argument. Optional metadata (content_type,description) is passed as a fourthOptsmap. Update calls fromwith_request_body(E, Method, #{schema => S})towith_request_body(E, Method, S).
[0.6.0] - 2026-03-04
Added
-spectraattribute for function specs: You can now annotate-specdeclarations with a-spectra()attribute to attach metadata to functions. Thefunction_doc()type supportssummary,description, anddeprecatedfields (distinct from thetype_doc()fields used for types and records).
Fixed
#sp_union{}typesfield was declared with a default value instead of a type annotation, which could cause subtle runtime issues.
[0.5.1] - 2026-03-02
Added
pre_decoded/pre_encodedoptions fordecode/5andencode/5: pass[pre_decoded]to skip JSON parsing when your input is already a decoded term, or[pre_encoded]to get back ajson:encode_value()term instead ofiodata()fromencode/5.spectra_openapi:endpoints_to_openapi/3: new overload that accepts encode options (e.g.[pre_encoded]) for the generated OpenAPI document.
Changed
__spectra_type_info__/0calls are now cached inpersistent_termalongside abstract-code lookups, reducing repeated reflection overhead.
[0.5.0] - 2026-02-26
Added
- JSON schema documentation: Types can now carry
titleanddescriptionmetadata via thespectraattribute, which is propagated into generated JSON Schema and OpenAPI output __spectra_type_info__/0protocol: Modules can now expose itstype_infoby exporting the__spectra_type_info__/0function. This is an implementation detail in the library. It will be used to pair documentation with types in Elixir, and can later be used for performance and to handle hot code reloading better.
[0.4.0] - 2026-01-27
Changed
- Breaking:
spectra:schema/3now returns schema values directly instead of{ok, Schema}or{error, Reason}tuples.
[0.3.2] - 2026-01-25
Changed
- Improved documentation and clarified OTP 27 requirement
[0.3.0] - 2026-01-20
Changed
- Upgraded JSON Schema from draft-07 to 2020-12 specification with proper
$schemafield support - Upgraded OpenAPI spec generation from 3.0 to 3.1 (which natively uses JSON Schema 2020-12)
- Improved remote type handling in enums and parameterized types
- Simplified error handling implementation in preparation for better error messages
- Enhanced null/optional handling with clearer documentation and dedicated tests for undefined/nil behavior in mandatory vs optional map fields
Internal
- Refactored type utilities into
spectra_util.erlwith renamed functions for consistency - New tests for typed map fields, parameterized remote types, and enum remote types
- Property-based testing for JSON encoding/schema/decoding consistency (
test/prop_json_encode_schema_consistency.erl) - Python validators for JSON Schema 2020-12 and OpenAPI 3.1 standards compliance
- Development tooling improvements including updated
.tool-versionsand enhancedMakefilewith release safeguards - Major code simplification in
spectra_binary_string.erl,spectra_json.erl, andspectra_string.erl - Created
sp_error.erlmodule for consolidated error handling
[0.2.0] - 2025-12-14
Changed
- Breaking: Extra fields in JSON objects are now ignored during deserialization instead of causing a
not_matched_fieldserror. This affects map, struct (elixir) and record deserialization.
Notes
- The old strict validation behavior has been commented out with a TODO to potentially add it back as a configuration option in the future