469 lines
11 KiB
Markdown
469 lines
11 KiB
Markdown
|
|
# Nickel Schema to TOML Form Generation Examples
|
||
|
|
|
||
|
|
This directory contains complete, runnable examples of the TypeDialog Nickel integration workflow:
|
||
|
|
|
||
|
|
```
|
||
|
|
Nickel Schema → TOML Form → User Input → JSON Results → Nickel Output
|
||
|
|
```
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
### Example 1: Simple Schema (Learning)
|
||
|
|
|
||
|
|
Generate a TOML form from a basic Nickel schema:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Generate form
|
||
|
|
just nickel::nickel-to-form schemas/simple.ncl generated/simple/
|
||
|
|
|
||
|
|
# Execute form interactively
|
||
|
|
typedialog form generated/simple/form.toml -o results/simple_results.json
|
||
|
|
|
||
|
|
# View results
|
||
|
|
cat results/simple_results.json | jq .
|
||
|
|
```
|
||
|
|
|
||
|
|
**What it demonstrates**:
|
||
|
|
- Basic type mapping (String, Number, Bool)
|
||
|
|
- Doc comment extraction
|
||
|
|
- Default value handling
|
||
|
|
- Simple form generation
|
||
|
|
|
||
|
|
### Example 2: Complex Schema (Fragmentation)
|
||
|
|
|
||
|
|
Generate fragmented forms from a schema with multiple sections:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Generate with automatic fragmentation
|
||
|
|
just nickel::nickel-to-form schemas/complex.ncl generated/complex/
|
||
|
|
|
||
|
|
# List generated files
|
||
|
|
ls -la generated/complex/
|
||
|
|
ls -la generated/complex/fragments/
|
||
|
|
|
||
|
|
# Execute main form
|
||
|
|
typedialog form generated/complex/main_form.toml -o results/complex_results.json
|
||
|
|
```
|
||
|
|
|
||
|
|
**What it demonstrates**:
|
||
|
|
- Fragment markers (`# @fragment: name`)
|
||
|
|
- Multi-file form composition
|
||
|
|
- Fragment includes in main form
|
||
|
|
- Large schema organization
|
||
|
|
|
||
|
|
**Generated structure**:
|
||
|
|
```
|
||
|
|
generated/complex/
|
||
|
|
├── main_form.toml # Form with includes
|
||
|
|
└── fragments/
|
||
|
|
├── app_config.toml
|
||
|
|
├── server_config.toml
|
||
|
|
├── database_config.toml
|
||
|
|
└── cache_config.toml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Example 3: Conditional Fields (Smart Visibility)
|
||
|
|
|
||
|
|
Generate conditionals automatically from optional fields:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Generate with conditionals
|
||
|
|
just nickel::nickel-to-form schemas/conditional.ncl generated/conditional/
|
||
|
|
|
||
|
|
# View generated conditionals
|
||
|
|
grep -A 2 'when =' generated/conditional/form.toml
|
||
|
|
|
||
|
|
# Execute form - notice conditional visibility
|
||
|
|
typedialog form generated/conditional/form.toml
|
||
|
|
```
|
||
|
|
|
||
|
|
**What it demonstrates**:
|
||
|
|
- Optional field handling
|
||
|
|
- Automatic conditional generation from contracts
|
||
|
|
- Boolean dependency detection
|
||
|
|
- Dynamic form visibility
|
||
|
|
|
||
|
|
**Example generated conditionals**:
|
||
|
|
```toml
|
||
|
|
[[fields]]
|
||
|
|
name = "tls_cert_path"
|
||
|
|
when = "tls_enabled == true" # Auto-generated!
|
||
|
|
|
||
|
|
[[fields]]
|
||
|
|
name = "database_url"
|
||
|
|
when = "database_enabled == true" # Auto-generated!
|
||
|
|
```
|
||
|
|
|
||
|
|
### Example 4: i18n Extraction (Multi-Language)
|
||
|
|
|
||
|
|
Generate Fluent translation files from schema:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Extract i18n only
|
||
|
|
just nickel::nickel-i18n schemas/i18n.ncl generated/i18n/
|
||
|
|
|
||
|
|
# View generated translations
|
||
|
|
ls -la generated/i18n/locales/
|
||
|
|
cat generated/i18n/locales/en/forms.ftl
|
||
|
|
cat generated/i18n/locales/es/forms.ftl
|
||
|
|
|
||
|
|
# Execute with Spanish locale
|
||
|
|
LOCALE=es typedialog form generated/i18n/form.toml
|
||
|
|
```
|
||
|
|
|
||
|
|
**What it demonstrates**:
|
||
|
|
- Multi-language doc comment parsing
|
||
|
|
- Fluent (.ftl) file generation
|
||
|
|
- Locale-specific form generation
|
||
|
|
- Translation key mapping
|
||
|
|
|
||
|
|
**Generated translations**:
|
||
|
|
```fluent
|
||
|
|
# en/forms.ftl
|
||
|
|
app-name-prompt = Application name
|
||
|
|
app-name-help = Enter the application display name
|
||
|
|
|
||
|
|
# es/forms.ftl
|
||
|
|
app-name-prompt = Nombre de la aplicación
|
||
|
|
app-name-help = Ingrese el nombre de la aplicación
|
||
|
|
```
|
||
|
|
|
||
|
|
### Example 5: Full Workflow (Schema → Results → Nickel)
|
||
|
|
|
||
|
|
Complete workflow: generate form, execute with results, render Nickel output:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Full workflow: schema → form → results → Nickel
|
||
|
|
just nickel::nickel-workflow \
|
||
|
|
schemas/simple.ncl \
|
||
|
|
templates/config.ncl.j2 \
|
||
|
|
generated/output_config.ncl
|
||
|
|
|
||
|
|
# Validate generated Nickel
|
||
|
|
nickel typecheck generated/output_config.ncl
|
||
|
|
|
||
|
|
# View generated configuration
|
||
|
|
cat generated/output_config.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
**What it demonstrates**:
|
||
|
|
- End-to-end workflow automation
|
||
|
|
- Form execution with user input
|
||
|
|
- Template rendering with results
|
||
|
|
- Nickel validation
|
||
|
|
- Configuration generation
|
||
|
|
|
||
|
|
## Directory Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
examples/07-nickel-generation/
|
||
|
|
├── README.md # This file
|
||
|
|
├── schemas/ # Nickel schema files
|
||
|
|
│ ├── simple.ncl # Basic types only
|
||
|
|
│ ├── complex.ncl # With fragment markers
|
||
|
|
│ ├── conditional.ncl # With optional fields + boolean deps
|
||
|
|
│ └── i18n.ncl # With English/Spanish docs
|
||
|
|
├── templates/ # Jinja2 templates for rendering
|
||
|
|
│ ├── config.ncl.j2 # Basic config template
|
||
|
|
│ ├── service_spec.ncl.j2 # Kubernetes service template
|
||
|
|
│ └── deployment.ncl.j2 # Kubernetes deployment template
|
||
|
|
├── generated/ # Example outputs (reference)
|
||
|
|
│ ├── simple/
|
||
|
|
│ │ └── form.toml
|
||
|
|
│ ├── complex/
|
||
|
|
│ │ ├── main_form.toml
|
||
|
|
│ │ └── fragments/
|
||
|
|
│ ├── conditional/
|
||
|
|
│ │ └── form.toml
|
||
|
|
│ └── i18n/
|
||
|
|
│ ├── form.toml
|
||
|
|
│ └── locales/
|
||
|
|
└── results/ # Example results (reference)
|
||
|
|
└── simple_results.json
|
||
|
|
```
|
||
|
|
|
||
|
|
## Schema Features Explained
|
||
|
|
|
||
|
|
### Fragment Markers
|
||
|
|
|
||
|
|
Mark sections for automatic splitting:
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
# @fragment: database_config
|
||
|
|
database = { ... }
|
||
|
|
```
|
||
|
|
|
||
|
|
Generates separate file: `fragments/database_config.toml`
|
||
|
|
|
||
|
|
**When to use**:
|
||
|
|
- Schemas with 20+ fields
|
||
|
|
- Logical section boundaries
|
||
|
|
- Independent configuration areas
|
||
|
|
|
||
|
|
### Optional Fields with Dependencies
|
||
|
|
|
||
|
|
Automatically generate conditionals:
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
tls_enabled | doc "Enable TLS" : Bool,
|
||
|
|
|
||
|
|
tls_cert | optional
|
||
|
|
| doc "Certificate path"
|
||
|
|
: String,
|
||
|
|
```
|
||
|
|
|
||
|
|
Generates:
|
||
|
|
```toml
|
||
|
|
[[fields]]
|
||
|
|
name = "tls_cert"
|
||
|
|
when = "tls_enabled == true"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Pattern**: `<feature>_enabled` → dependent fields
|
||
|
|
|
||
|
|
### Multi-Language Docs
|
||
|
|
|
||
|
|
Support multiple languages in doc comments:
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
field_name
|
||
|
|
| doc "English text"
|
||
|
|
| doc.es "Texto en español"
|
||
|
|
: String
|
||
|
|
```
|
||
|
|
|
||
|
|
Generates `.ftl` files for each locale with translations
|
||
|
|
|
||
|
|
## Templates
|
||
|
|
|
||
|
|
### config.ncl.j2
|
||
|
|
|
||
|
|
Basic application configuration template:
|
||
|
|
- Renders app metadata
|
||
|
|
- Server configuration
|
||
|
|
- Database connection (optional)
|
||
|
|
- Cache settings (conditional)
|
||
|
|
|
||
|
|
**Usage**:
|
||
|
|
```bash
|
||
|
|
just nickel::nickel-workflow \
|
||
|
|
schemas/simple.ncl \
|
||
|
|
templates/config.ncl.j2 \
|
||
|
|
config.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
### service_spec.ncl.j2
|
||
|
|
|
||
|
|
Kubernetes service specification:
|
||
|
|
- Service metadata
|
||
|
|
- Port configuration
|
||
|
|
- Selector rules
|
||
|
|
- Service type (ClusterIP, NodePort, LoadBalancer)
|
||
|
|
|
||
|
|
**Usage**:
|
||
|
|
```bash
|
||
|
|
typedialog form <form> -o results.json
|
||
|
|
typedialog nickel-template templates/service_spec.ncl.j2 results.json -o service.ncl
|
||
|
|
nickel export service.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
### deployment.ncl.j2
|
||
|
|
|
||
|
|
Kubernetes deployment configuration:
|
||
|
|
- Deployment metadata
|
||
|
|
- Pod replica count
|
||
|
|
- Container specification
|
||
|
|
- Resource limits and requests
|
||
|
|
- Health checks (liveness, readiness probes)
|
||
|
|
- Environment variables
|
||
|
|
|
||
|
|
**Usage**:
|
||
|
|
```bash
|
||
|
|
just nickel::nickel-workflow \
|
||
|
|
<schema> \
|
||
|
|
templates/deployment.ncl.j2 \
|
||
|
|
deployment.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
## Common Workflows
|
||
|
|
|
||
|
|
### Preview Form Before Generation
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Preview without writing files
|
||
|
|
just nickel::nickel-preview schemas/complex.ncl
|
||
|
|
|
||
|
|
# Then generate with full options
|
||
|
|
just nickel::nickel-to-form schemas/complex.ncl generated/complex/
|
||
|
|
```
|
||
|
|
|
||
|
|
### Extract i18n Only
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Generate only translation files
|
||
|
|
just nickel::nickel-i18n schemas/i18n.ncl translations/
|
||
|
|
|
||
|
|
# Review translations
|
||
|
|
cat translations/locales/en/forms.ftl
|
||
|
|
cat translations/locales/es/forms.ftl
|
||
|
|
```
|
||
|
|
|
||
|
|
### Render Template with Sample Data
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Use example results to render template
|
||
|
|
typedialog nickel-template templates/config.ncl.j2 \
|
||
|
|
results/simple_results.json \
|
||
|
|
-o sample_output.ncl
|
||
|
|
|
||
|
|
# Review output
|
||
|
|
cat sample_output.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
### Full Interactive Workflow
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Generate form
|
||
|
|
just nickel::nickel-to-form schemas/simple.ncl /tmp/form_gen/
|
||
|
|
|
||
|
|
# 2. Execute form interactively
|
||
|
|
typedialog form /tmp/form_gen/form.toml -o /tmp/results.json
|
||
|
|
|
||
|
|
# 3. Review results
|
||
|
|
cat /tmp/results.json | jq .
|
||
|
|
|
||
|
|
# 4. Render template
|
||
|
|
typedialog nickel-template templates/config.ncl.j2 \
|
||
|
|
/tmp/results.json \
|
||
|
|
-o /tmp/generated_config.ncl
|
||
|
|
|
||
|
|
# 5. Validate Nickel
|
||
|
|
nickel typecheck /tmp/generated_config.ncl
|
||
|
|
|
||
|
|
# 6. Export to JSON
|
||
|
|
nickel export /tmp/generated_config.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Examples
|
||
|
|
|
||
|
|
### Run All Examples
|
||
|
|
|
||
|
|
```bash
|
||
|
|
#!/bin/bash
|
||
|
|
|
||
|
|
EXAMPLES_DIR="examples/07-nickel-generation"
|
||
|
|
|
||
|
|
# Test 1: Simple
|
||
|
|
echo "Testing simple schema..."
|
||
|
|
just nickel::nickel-to-form "$EXAMPLES_DIR/schemas/simple.ncl" /tmp/test_simple
|
||
|
|
[ -f /tmp/test_simple/form.toml ] && echo "✓ Simple form generated"
|
||
|
|
|
||
|
|
# Test 2: Complex
|
||
|
|
echo "Testing complex schema..."
|
||
|
|
just nickel::nickel-to-form "$EXAMPLES_DIR/schemas/complex.ncl" /tmp/test_complex
|
||
|
|
[ -f /tmp/test_complex/main_form.toml ] && echo "✓ Complex form generated"
|
||
|
|
[ -d /tmp/test_complex/fragments ] && echo "✓ Fragments created"
|
||
|
|
|
||
|
|
# Test 3: Conditional
|
||
|
|
echo "Testing conditional schema..."
|
||
|
|
just nickel::nickel-to-form "$EXAMPLES_DIR/schemas/conditional.ncl" /tmp/test_conditional
|
||
|
|
grep -q "when =" /tmp/test_conditional/form.toml && echo "✓ Conditionals generated"
|
||
|
|
|
||
|
|
# Test 4: i18n
|
||
|
|
echo "Testing i18n schema..."
|
||
|
|
just nickel::nickel-i18n "$EXAMPLES_DIR/schemas/i18n.ncl" /tmp/test_i18n
|
||
|
|
[ -f /tmp/test_i18n/locales/en/forms.ftl ] && echo "✓ English translations generated"
|
||
|
|
[ -f /tmp/test_i18n/locales/es/forms.ftl ] && echo "✓ Spanish translations generated"
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "All tests passed!"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Extending Examples
|
||
|
|
|
||
|
|
### Adding New Schemas
|
||
|
|
|
||
|
|
1. Create `schemas/my_schema.ncl` with Nickel configuration
|
||
|
|
2. Add fragment markers (`# @fragment: name`) for sections
|
||
|
|
3. Use optional fields for conditionals
|
||
|
|
4. Use multi-language docs for i18n
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
{
|
||
|
|
# @fragment: my_section
|
||
|
|
my_field | doc "English" | doc.es "Español" : String,
|
||
|
|
|
||
|
|
feature_enabled | doc "Enable feature" : Bool = false,
|
||
|
|
|
||
|
|
feature_config | optional
|
||
|
|
| doc "Feature configuration"
|
||
|
|
: String,
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Adding New Templates
|
||
|
|
|
||
|
|
1. Create `templates/my_template.ncl.j2`
|
||
|
|
2. Use Jinja2 syntax for conditionals and loops
|
||
|
|
3. Reference form result variables
|
||
|
|
4. Test with sample data
|
||
|
|
|
||
|
|
```jinja2
|
||
|
|
{
|
||
|
|
config = {
|
||
|
|
{% for item in items %}
|
||
|
|
{{ item.name }} : String = "{{ item.value }}",
|
||
|
|
{% endfor %}
|
||
|
|
},
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Form Generation Fails
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Verify schema syntax
|
||
|
|
nickel typecheck schemas/simple.ncl
|
||
|
|
|
||
|
|
# Check for schema-specific issues
|
||
|
|
nickel query schemas/simple.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
### Fragment Includes Not Found
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Verify fragments directory exists
|
||
|
|
ls -la generated/complex/fragments/
|
||
|
|
|
||
|
|
# Check include paths in main form
|
||
|
|
grep includes generated/complex/main_form.toml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Conditionals Not Generated
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Verify optional fields exist
|
||
|
|
grep -A 2 "optional" schemas/conditional.ncl
|
||
|
|
|
||
|
|
# Check for boolean enable flags
|
||
|
|
grep "_enabled" schemas/conditional.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
### i18n Not Working
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Verify locale directories created
|
||
|
|
find generated/i18n/locales/ -name "*.ftl"
|
||
|
|
|
||
|
|
# Check .ftl file format
|
||
|
|
cat generated/i18n/locales/en/forms.ftl | head
|
||
|
|
```
|
||
|
|
|
||
|
|
## See Also
|
||
|
|
|
||
|
|
- `.claude/guidelines/typedialog.md` - Complete TypeDialog guide
|
||
|
|
- `templates/nickel/README.md` - Template library documentation
|
||
|
|
- `just nickel::help` - All available recipes
|
||
|
|
- `/nickel-gen` - Interactive slash command
|