Mode B: Config File Specification
This example shows provisioning generation from a declarative TOML configuration file.
Use Cases
Mode B is ideal when:
- You don't have a Cargo.toml to analyze (e.g., Python, Go services)
- You want complete control over feature definitions
- You're designing configuration before implementation
- You need custom fields not automatically detected
- You're configuring existing services with different tech stacks
Configuration Structure
The project-spec.toml file has three main sections:
1. Project Metadata
[project]
name = "service-name"
description = "What this service does"
type = "Microservice" # WebService, CliTool, Microservice, Library
2. Infrastructure Requirements
[infrastructure]
ssh = true
monitoring = ["prometheus", "grafana"]
cloud_providers = ["aws", "gcp"]
[[infrastructure.databases]]
type = "postgres"
required = true
3. Domain Features
Each feature represents a functional capability:
[features.my_feature]
description = "What this feature does"
enabled = true
[[features.my_feature.fields]]
name = "field_name"
type = "Text" # Text, Number, Password, Confirm, Select, etc.
prompt = "User prompt"
default = "default_value"
help = "Helpful text"
required = true
sensitive = false # Set to true for passwords/secrets
encryption_backend = "age" # For sensitive fields
min = 1 # For numbers/arrays
max = 100
options = ["a", "b"] # For Select/MultiSelect
4. Constraints (Single Source of Truth)
[constraints.feature_name.field_name]
min = 1
max = 100
min_length = 5
max_length = 255
Running the Example
Generate Provisioning Structure
typedialog-provisioning-gen config \
--input examples/11-provisioning-generation/mode-b-config/project-spec.toml \
--output /tmp/microservice-platform
Inspect Generated Files
# View master configuration
cat /tmp/microservice-platform/config.ncl
# View API gateway schema
cat /tmp/microservice-platform/schemas/api_gateway.ncl
# View authentication fragment
cat /tmp/microservice-platform/fragments/authentication-section.toml
# Validate constraints
cat /tmp/microservice-platform/constraints.toml
Test Forms Interactively
# Test API gateway configuration form
typedialog /tmp/microservice-platform/fragments/api_gateway-section.toml --backend cli
# Test authentication configuration form
typedialog /tmp/microservice-platform/fragments/authentication-section.toml --backend cli
Use Generated Scripts
cd /tmp/microservice-platform
# Validate Nickel syntax
./scripts/validate-nickel.sh
# Create Nickel from JSON input
echo '{"api_gateway": {"bind_address": "0.0.0.0:8080"}}' | \
./scripts/json-to-nickel.sh
# Convert back to JSON
./scripts/nickel-to-json.sh < config.ncl
Features Defined in This Example
1. API Gateway
- Purpose: REST API entry point with rate limiting
- Fields:
bind_address- Interface and portrate_limit- Requests per secondtimeout_seconds- Request timeout
Generated Output:
- Schema:
schemas/api_gateway.ncl- Type contract - Validator:
validators/api_gateway.ncl- Validation rules - Defaults:
defaults/api_gateway.ncl- Default values - Fragment:
fragments/api_gateway-section.toml- UI form
2. Event Streaming
- Purpose: Message queue for event-driven architecture
- Fields:
broker_url- Message broker connectionconsumer_group- Kafka consumer group IDmax_concurrent_consumers- Parallelism
3. Authentication
- Purpose: JWT-based access control
- Fields:
jwt_secret- Sensitive signing key (encrypted)jwt_expiry_hours- Token lifetimeallow_refresh_tokens- Refresh mechanism
4. Observability
- Purpose: Logging and distributed tracing
- Fields:
log_level- Trace/Debug/Info/Warn/Errorenable_distributed_tracing- Toggle tracingtrace_sample_rate- Sampling percentage
5. Database Migrations
- Purpose: Schema versioning and evolution
- Fields:
migration_directory- Path to SQL filesauto_migrate_on_startup- Automatic migrations
Field Types Reference
| Type | Use Case | Example |
|---|---|---|
| Text | Free-form string | domain.example.com |
| Number | Integer or float | 8080, 0.5 |
| Password | Sensitive text | secret key (encrypted) |
| Confirm | Yes/No toggle | Enable feature? |
| Select | Single choice | Log level: debug, info, warn |
| MultiSelect | Multiple choices | Monitoring: prometheus, grafana |
| Editor | Multi-line code | SQL migration script |
| Date | Calendar picker | Deployment date |
| RepeatingGroup | Array of items | Multiple database servers |
Sensitive Fields
Mark fields as sensitive for encryption:
[[features.authentication.fields]]
name = "jwt_secret"
type = "Password"
sensitive = true
encryption_backend = "age" # Default: age
Supported backends:
age- Modern encryption (recommended)sops- Mozilla SOPSsecretumvault- SecretumVault integrationaws-kms- AWS Key Management Servicegcp-kms- Google Cloud KMSazure-kms- Azure Key Vault
Constraints System
Constraints provide a single source of truth for validation bounds:
[constraints.api_gateway.bind_address]
min_length = 3
max_length = 50
[constraints.api_gateway.rate_limit]
min = 1
max = 10000
These constraints are:
- Used in TypeDialog forms (enforced client-side)
- Referenced in validators (Nickel validation)
- Available in fragments (UI constraints)
- Documented in generated schema
Extending This Example
Add a New Feature
-
Add to
project-spec.toml:[features.caching] description = "Redis caching layer" [[features.caching.fields]] name = "redis_url" type = "Text" prompt = "Redis connection string" -
Regenerate:
typedialog-provisioning-gen config --input project-spec.toml --output ./output -
Generated files appear:
schemas/caching.nclvalidators/caching.ncldefaults/caching.nclfragments/caching-section.toml
Customize a Field
- Modify the field definition
- Update constraints if needed
- Regenerate
The regeneration merges with existing configuration, making it safe to iterate.
What This Demonstrates
✅ Complete feature definition without code ✅ Type safety through Nickel contracts ✅ Constraint interpolation (single source of truth) ✅ Multi-language field options (Select, MultiSelect) ✅ Sensitive data encryption configuration ✅ Infrastructure requirements specification ✅ Full 7-layer validation stack generation
Next Steps
- Copy and Customize: Use this as a template for your service
- Add Your Features: Define the capabilities your service provides
- Generate: Run provisioning-gen to create artifacts
- Test: Use TypeDialog forms to validate configuration
- Deploy: Use generated scripts for orchestration
- Iterate: Modify spec and regenerate as needed
Integration with Application
Once generated, import Nickel schemas in your app:
# config.ncl
let infrastructure = import "schemas/database.ncl"
let auth = import "schemas/authentication.ncl"
{
database = {
%host% = "localhost",
port = 5432,
} | infrastructure.Database,
authentication = auth.Authentication,
}
Or deserialize from JSON:
# Load configuration from TypeDialog form output
./scripts/json-to-nickel.sh < form-output.json > config.ncl
# Validate against schema
nickel eval config.ncl
# Export to application
./scripts/nickel-to-json.sh < config.ncl > config.json