Mode D: Existing Nickel Schema Conversion
This example shows how to convert an existing Nickel schema into a complete provisioning structure with forms, validators, and orchestration scripts.
Use Cases
Mode D is useful when:
- You have existing Nickel schemas from other projects
- You want to migrate configuration systems
- You need to add provisioning automation to existing Nickel configs
- You want to bridge Nickel schemas and TypeDialog forms
Schema Conversion Process
The existing-config.ncl file defines types for a service:
{
Server = { hostname, port, tls_enabled, ... },
Database = { engine, host, port, username, ... },
Authentication = { provider, secret_key, ... },
Monitoring = { enabled, prometheus_url, ... },
Application = { name, version, log_level, ... },
}
Mode D analyzes this schema and:
- Extracts Records: Identifies type definitions (
Server,Database, etc.) - Maps Fields: Converts Nickel types to TypeDialog field types
- Infers Features: Groups related records into domain features
- Generates Artifacts: Creates complete provisioning structure
Running the Example
Convert Nickel Schema to Provisioning
typedialog-provisioning-gen nickel \
--input examples/11-provisioning-generation/mode-d-nickel/existing-config.ncl \
--output /tmp/service-provisioning
Inspect Conversion
# View inferred project spec
cat /tmp/service-provisioning/config.ncl
# View extracted server schema
cat /tmp/service-provisioning/schemas/server.ncl
# View generated form fragment
cat /tmp/service-provisioning/fragments/server-section.toml
# View extracted validators
cat /tmp/service-provisioning/validators/server.ncl
Test Generated Forms
# Test server configuration form
typedialog /tmp/service-provisioning/fragments/server-section.toml --backend cli
# Test database configuration form
typedialog /tmp/service-provisioning/fragments/database-section.toml --backend cli
Schema Extraction Details
Type → Feature Mapping
| Nickel Type | Feature Name | Domain |
|---|---|---|
Server |
server | Infrastructure |
Database |
database | Infrastructure |
Authentication |
authentication | Security |
Monitoring |
monitoring | Observability |
Application |
application | Core |
Field Type Conversion
| Nickel Type | TypeDialog Type | Example |
|---|---|---|
String |
Text | hostname, database_name |
Number |
Number | port (1-65535), timeout |
Bool |
Confirm | tls_enabled, debug |
[String] |
MultiSelect | ["warn", "error"] |
{...} |
RepeatingGroup | Array of records |
String | optional |
Text (optional) | certificate_path |
Example Conversion
Input Nickel:
Server = {
hostname | String,
port | Number,
tls_enabled | Bool | optional,
}
Generated Schema (schemas/server.ncl):
{
Server = {
hostname | String,
port | Number,
tls_enabled | Bool | optional,
},
}
Generated Fragment (fragments/server-section.toml):
[section.server]
description = "Server configuration"
[[section.server.fields]]
name = "hostname"
prompt = "Server hostname"
type = "text"
required = true
[[section.server.fields]]
name = "port"
prompt = "Server port"
type = "number"
required = true
min = 1
max = 65535
[[section.server.fields]]
name = "tls_enabled"
prompt = "Enable TLS?"
type = "confirm"
required = false
Generated Validator (validators/server.ncl):
{
validate_hostname = fun value =>
(std.is_string value) && (std.string.length value > 0),
validate_port = fun value =>
(std.is_number value) && (value >= 1) && (value <= 65535),
validate_tls_enabled = fun value =>
(std.is_bool value),
}
Handling Complex Types
Nested Records
When a record contains another record:
ServiceConfig = {
server | Server, # References Server record
database | Database, # References Database record
}
Generated as separate features with relationships documented.
Optional Fields
Nickel optional modifier:
certificate_path | String | optional,
Generated as optional form field (not required in TypeDialog form).
Array Types
Repeating items:
tags | [String],
Generated as RepeatingGroup field with array validation.
Extending Converted Schema
After conversion, you can:
-
Add New Fields: Modify generated fragments
[[section.server.fields]] name = "max_connections" type = "number" -
Add Validation: Enhance validators
validate_port = fun value => (value >= 1) && (value <= 65535) && (value % 2 == 0) -
Add Defaults: Fill in missing defaults
defaults.server = { port = 8080, tls_enabled = false, } -
Add Constraints: Update constraints.toml
[constraints.server.port] min = 1024 max = 65535
Integration with Existing Services
The converted provisioning can integrate with existing services:
1. Use as Configuration Loader
// Load configuration from generated schema
let config = nickel_eval("provisioning/config.ncl")?;
let parsed: ServiceConfig = serde_json::from_value(config)?;
2. Provide Configuration UI
# Use generated TypeDialog forms for configuration
typedialog provisioning/fragments/database-section.toml \
--backend web --port 3000
3. Add Validation Layer
# Validate user input against Nickel schema
./provisioning/scripts/validate-nickel.sh < user-config.ncl
Migration Path
To migrate an existing configuration system:
-
Define Nickel Schema
# Write or extract your configuration types cat > config.ncl << 'EOF' { MyService = { ... } } EOF -
Convert with Mode D
typedialog-provisioning-gen nickel --input config.ncl --output ./provisioning -
Test Generated Forms
typedialog provisioning/fragments/*.toml --backend cli -
Integrate Validation
# Use validation in your service ./provisioning/scripts/validate-nickel.sh < config.ncl -
Deploy Forms
# Serve configuration UI typedialog-web provisioning/fragments/*.toml
What This Demonstrates
✅ Nickel schema extraction and analysis ✅ Type inference to TypeDialog field mapping ✅ Automatic feature grouping from types ✅ Generator adaptation to schema structure ✅ Validator generation from type constraints ✅ Fragment generation from record fields ✅ Integration with existing Nickel code ✅ Schema versioning and migration
Limitations
Some conversions have limitations:
| Limitation | Workaround |
|---|---|
| Custom Nickel functions | Manual validator enhancement |
| Complex constraints | Update constraints.toml |
| Domain-specific logic | Modify generated fragments |
| Record references | Links documented in fragments |
Next Steps
- Analyze Your Schema: Run Mode D on your Nickel file
- Review Generated Artifacts: Check schemas, forms, validators
- Test Forms: Use TypeDialog CLI to test UX
- Enhance: Add custom fields and validation
- Deploy: Use generated scripts for provisioning
- Iterate: Modify and regenerate as needed
For more control, use Mode B (Config File) examples to define features explicitly.