CCXT.Spec (ccxt_client v0.6.1)

Copy Markdown View Source

Compile-time JSON spec loader for exchange specifications.

Reads exchange specs from priv/specs/json/output/ and decodes them for use by the generator macro (CCXT.Exchange). Specs are loaded at compile time inside the generator — this module provides the loading functions but does not store specs as module attributes.

Usage

# In generator macro (compile time):
spec = CCXT.Spec.load!("bybit")

# List available exchanges:
CCXT.Spec.exchanges()
#=> ["aftermath", "alpaca", "apex", ...]

Schema Version

load!/1 and load_manifest!/0 enforce schema_version major 3 (ccxt_extract Schema 3.0.0+). Per-exchange specs must also carry a non-empty top-level _provenance map (RFC 6901 pointer keys → "raw" / "derived" / "override"); the manifest does not.

A mismatch raises with a specific message naming the spec and the offending field, so a stale priv/specs/json/output/ surfaces as a clear compile-time failure instead of a downstream MatchError.

Dead Weight Stripping

load!/1 removes extraction-only data (structure.interface_signatures and structure.methods) that is only useful for static analysis, not runtime code generation. This reduces memory for Macro.escape/1.

Summary

Functions

Returns the list of available exchange IDs from the manifest.

Loads and decodes an exchange spec by ID.

Loads and decodes the manifest file.

Returns the absolute path to the manifest file.

Returns the absolute path to a spec file for the given exchange ID.

Validates a decoded manifest map against the Schema 3.0.0+ contract.

Validates a decoded per-exchange spec map against the Schema 3.0.0+ contract: schema_version must be a string whose numeric major equals 3, and _provenance must be a non-empty top-level map. On mismatch, raises with a message naming the exchange and the offending field.

Functions

exchanges()

@spec exchanges() :: [String.t()]

Returns the list of available exchange IDs from the manifest.

Examples

CCXT.Spec.exchanges()
#=> ["aftermath", "alpaca", "apex", "arkham", ...]

load!(exchange_id)

@spec load!(String.t()) :: map()

Loads and decodes an exchange spec by ID.

Reads the JSON file, decodes it, and strips extraction-only data from structure. Returns a map with string keys.

Raises File.Error if the spec file doesn't exist, or Jason.DecodeError on invalid JSON.

Examples

spec = CCXT.Spec.load!("bybit")
spec["exchange"]["id"]
#=> "bybit"

load_manifest!()

@spec load_manifest!() :: map()

Loads and decodes the manifest file.

Returns the decoded _manifest.json containing exchange list, CCXT version, and extraction metadata.

Examples

manifest = CCXT.Spec.load_manifest!()
manifest["ccxt_version"]
#=> "4.5.46"

manifest["exchange_count"]
#=> 23

manifest_path()

@spec manifest_path() :: String.t()

Returns the absolute path to the manifest file.

Examples

CCXT.Spec.manifest_path()
#=> "/path/to/priv/specs/json/output/_manifest.json"

spec_path(exchange_id)

@spec spec_path(String.t()) :: String.t()

Returns the absolute path to a spec file for the given exchange ID.

Examples

CCXT.Spec.spec_path("bybit")
#=> "/path/to/priv/specs/json/output/bybit.json"

validate_manifest_schema!(manifest)

@spec validate_manifest_schema!(map()) :: map()

Validates a decoded manifest map against the Schema 3.0.0+ contract.

Only the schema_version major is enforced — manifests have no _provenance by design (different document type from per-exchange specs). Raises on mismatch; returns the manifest unchanged on success. Exposed for test coverage of the guard branches.

validate_schema!(spec, exchange_id)

@spec validate_schema!(map(), String.t()) :: map()

Validates a decoded per-exchange spec map against the Schema 3.0.0+ contract: schema_version must be a string whose numeric major equals 3, and _provenance must be a non-empty top-level map. On mismatch, raises with a message naming the exchange and the offending field.

Returns the spec unchanged on success. Called internally from load!/1; exposed publicly so test suites can exercise every branch against in-memory maps without writing fixture files into the live spec directory.