Generate type-safe Nickel configurations from any schema source
Amalgam transforms Kubernetes CRDs, OpenAPI schemas, and other type definitions into strongly-typed Nickel configuration language, enabling type-safe infrastructure as code with automatic validation and completion.
Nickel is a powerful configuration language that offers:
- Gradual Typing - Mix static types with dynamic code as needed
- Contracts - Runtime validation with custom predicates
- Merging - Powerful record merging and extension
- Functions - First-class functions for abstraction
- Correctness - Designed to prevent configuration errors
Amalgam bridges the gap between existing schemas (K8s CRDs, OpenAPI) and Nickel's type system, giving you the best of both worlds: auto-generated types from authoritative sources with Nickel's powerful configuration capabilities.
- ๐ฆ Import Kubernetes CRDs - Convert CRDs to strongly-typed Nickel configurations
- ๐ Smart Import Resolution - Automatically resolves cross-package type references with proper imports
- ๐ Package Generation - Creates organized package structures from multiple schemas
- ๐ Generic Architecture - Universal resolver that works with any schema source
- ๐ GitHub Integration - Fetch schemas directly from GitHub repositories
# Clone the repository
git clone https://github.com/seryl/amalgam
cd amalgam
# Build with Cargo
cargo build --release
# Install locally
cargo install --path crates/amalgam-cli# Import from a local file
amalgam import crd --file my-crd.yaml --output my-crd.ncl
# Import from a URL
amalgam import url --url https://raw.githubusercontent.com/example/repo/main/crd.yaml --output output/# Fetch all Crossplane CRDs and generate a Nickel package
amalgam import url \
--url https://github.com/crossplane/crossplane/tree/main/cluster/crds \
--output crossplane-types/This generates a structured Nickel package:
crossplane-types/
โโโ mod.ncl # Main module
โโโ apiextensions.crossplane.io/
โ โโโ mod.ncl # Group module
โ โโโ v1/
โ โ โโโ mod.ncl # Version module
โ โ โโโ composition.ncl # Type definitions
โ โ โโโ compositeresourcedefinition.ncl
โ โโโ v1beta1/
โ โโโ ...
โโโ pkg.crossplane.io/
โโโ ...
Amalgam automatically resolves Kubernetes type references and generates clean Nickel code:
# Module: composition.apiextensions.crossplane.io
let k8s_io_v1 = import "../../k8s_io/v1/objectmeta.ncl" in
{
Composition = {
apiVersion | optional | String,
kind | optional | String,
metadata | optional | k8s_io_v1.ObjectMeta,
spec | optional | {
compositeTypeRef | {
apiVersion | String,
kind | String,
},
# ... more fields
},
},
}The tool intelligently detects and resolves Kubernetes type references:
- Detects:
io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - Generates Import:
let k8s_io_v1 = import "../../k8s_io/v1/objectmeta.ncl" in - Resolves Reference:
k8s_io_v1.ObjectMeta
The resolver system uses a simple, generic pattern-matching approach that works for any schema source:
pub struct TypeResolver {
cache: HashMap<String, Resolution>,
type_registry: HashMap<String, String>,
}Key features:
- Universal Pattern Matching - Works with any schema format (Kubernetes, OpenAPI, Protobuf, etc.)
- Smart Import Detection - Automatically identifies when imports are needed based on namespace patterns
- Type Registry - Maintains a registry of all known types for accurate resolution
- Cache-based Performance - Caches resolutions to avoid repeated lookups
- No Special-casing - Generic implementation that doesn't favor any particular schema source
-
import- Import types from various sourcescrd- Import from a CRD fileurl- Import from URL (GitHub, raw files)open-api- Import from OpenAPI speck8s- Import from Kubernetes cluster (planned)
-
generate- Generate code from IR -
convert- Convert between formats -
vendor- Manage vendored packages
-v, --verbose- Enable verbose output-d, --debug- Enable debug output with detailed tracing
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ amalgam CLI โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Schema Pipeline โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ CRD โ โ OpenAPI โ โ Go โ โ Protobuf โ โ
โ โ Parser โ โ Parser โ โ AST โ โ Parser โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Intermediate Representation (IR) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Unified Type System (Algebraic Types) โ โ
โ โ - Sum Types (Enums/Unions) โ โ
โ โ - Product Types (Structs/Records) โ โ
โ โ - Contracts & Refinement Types โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Code Generation โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Nickel โ โ Go โ โ CUE โ โ JSON โ โ
โ โGenerator โ โGenerator โ โGenerator โ โ Exporter โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
amalgam/
โโโ Cargo.toml # Workspace definition
โโโ flake.nix # Nix development environment
โโโ crates/
โ โโโ amalgam-core/ # Core IR and type system
โ โโโ amalgam-parser/ # Schema parsers (CRD, OpenAPI)
โ โโโ amalgam-codegen/ # Code generators with generic resolver
โ โโโ amalgam-daemon/ # Runtime daemon for watching changes
โ โโโ amalgam-cli/ # Command-line interface
โโโ examples/ # Example configurations
โโโ tests/ # Integration tests
โโโ docs/ # Architecture documentation
Generate type-safe Nickel configurations from your CRDs:
# Import your custom CRDs
amalgam import crd --file my-operator-crd.yaml --output types/
# Use in Nickel configurations
let types = import "types/my-operator.ncl" in
let config = {
apiVersion = "example.io/v1",
kind = "MyResource",
metadata = {
name = "example",
},
spec = types.MyResourceSpec & {
# Type-safe configuration with auto-completion
replicas = 3,
# ...
}
}Type-safe CrossPlane compositions in Nickel with full IDE support:
let crossplane = import "crossplane-types/mod.ncl" in
let composition = crossplane.apiextensions.v1.Composition & {
metadata.name = "my-composition",
spec = {
compositeTypeRef = {
apiVersion = "example.io/v1",
kind = "XDatabase",
},
# Full type checking and validation
}
}# Build all crates
cargo build --workspace
# Run tests
cargo test --workspace
# Run with debug logging
cargo run -- --debug import crd --file test.yamlThe project includes comprehensive test coverage:
- Unit tests for type resolution and parsing
- Integration tests with real CRDs
- Snapshot tests for generated output
- Property-based tests for round-trip conversions
# Run all tests
cargo test
# Run specific test suite
cargo test --package amalgam-parser
# Run with coverage (requires cargo-tarpaulin)
cargo tarpaulin --out Html --output-dir coverage
# Run benchmarks (requires cargo-criterion)
cargo criterion
# Update snapshot tests (requires cargo-insta)
cargo insta review
# Run tests with all features
cargo test --all-features
# Run doctests only
cargo test --doc
# Run a specific test
cargo test test_kubernetes_resolver# Format code
cargo fmt
# Run linter
cargo clippy -- -D warnings
# Check for security vulnerabilities
cargo audit
# Check for outdated dependencies
cargo outdated
# Generate documentation
cargo doc --no-deps --open
# Check licenses
cargo licenseContributions are welcome! Areas of interest:
- Additional schema parsers (Protobuf, GraphQL)
- More code generators (TypeScript, Python)
- Kubernetes cluster integration
- Enhanced type inference
- IDE plugins for generated types
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- โ Enterprise-friendly - Widely accepted in corporate environments
- โ Patent protection - Includes express patent grants
- โ Commercial-ready - Allows building proprietary products and services
- โ Contribution clarity - Clear terms for contributions
- Generates code for Nickel - A powerful configuration language with contracts and gradual typing
- Inspired by CUE and its approach to configuration
- Uses patterns from dhall-kubernetes