amalgam 0.1.0

Type-safe configuration generator for Nickel from various schema sources
amalgam-0.1.0 is not a library.
Visit the last successful build: amalgam-0.6.4

πŸ”§ Amalgam

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.

🎯 Why Nickel?

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.

✨ Features

  • πŸ“¦ Import Kubernetes CRDs - Convert CRDs to strongly-typed Nickel configurations
  • πŸ” Smart Import Resolution - Automatically resolves K8s type references with proper imports
  • πŸ“ Package Generation - Creates organized package structures from multiple CRDs
  • πŸ”Œ Extensible Architecture - Plugin-based resolver system for adding new type mappings
  • πŸ™ GitHub Integration - Fetch CRDs directly from GitHub repositories

πŸ“₯ Installation

# 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

πŸš€ Quick Start

Import a Single CRD

# 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/

Import Crossplane CRDs

# 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/
    └── ...

πŸ“ Generated Nickel Output Example

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
    },
  },
}

🎯 Key Features Explained

Import Resolution

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

Extensible Resolver System

Add custom type resolvers using the plugin architecture:

pub trait ReferenceResolver: Send + Sync {
    fn can_resolve(&self, reference: &str) -> bool;
    fn resolve(&self, reference: &str, imports: &[Import], context: &ResolutionContext) -> Option<Resolution>;
    fn name(&self) -> &str;
}

Built-in resolvers:

  • KubernetesResolver - Handles K8s API types
  • LocalTypeResolver - Resolves local type references
  • Easy to add custom resolvers for other type systems

πŸ’» CLI Commands

Main Commands

  • import - Import types from various sources

    • crd - Import from a CRD file
    • url - Import from URL (GitHub, raw files)
    • open-api - Import from OpenAPI spec
    • k8s - Import from Kubernetes cluster (planned)
  • generate - Generate code from IR

  • convert - Convert between formats

  • vendor - Manage vendored packages

Options

  • -v, --verbose - Enable verbose output
  • -d, --debug - Enable debug output with detailed tracing

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        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    β”‚  β”‚   WASM   β”‚   β”‚
β”‚  β”‚Generator β”‚  β”‚Generator β”‚  β”‚Generator β”‚  β”‚  Module  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ Project Structure

amalgam/
β”œβ”€β”€ Cargo.toml                 # Workspace definition
β”œβ”€β”€ crates/
β”‚   β”œβ”€β”€ amalgam-core/          # Core IR and type system
β”‚   β”œβ”€β”€ amalgam-parser/        # Schema parsers (CRD, OpenAPI)
β”‚   β”œβ”€β”€ amalgam-codegen/       # Code generators with resolver system
β”‚   └── amalgam-cli/           # Command-line interface
β”œβ”€β”€ examples/                  # Example configurations
└── tests/                     # Integration tests

πŸ’‘ Use Cases

Kubernetes Configuration Management

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,
    # ...
  }
}

CrossPlane Composition

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
  }
}

πŸ› οΈ Development

Building

# Build all crates
cargo build --workspace

# Run tests
cargo test --workspace

# Run with debug logging
cargo run -- --debug import crd --file test.yaml

Testing

The 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

# Update snapshots
cargo test -- --ignored

🀝 Contributing

Contributions 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

πŸ“œ License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Why Apache 2.0?

  • βœ… 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

πŸ™ Acknowledgments

  • 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