schemagen¶
Package schemagen provides JSON Schema generation from action metadata.
This package generates JSON Schema, OpenAPI specifications, and TypeScript definitions from mooncake's action registry and Go struct definitions.
The generator uses multiple sources: 1. Action metadata from actions.List() (platforms, capabilities) 2. Go struct tags from config structs (types, descriptions) 3. Custom schema hints for complex validations
Usage:
Index¶
- Variables
- type Definition
- type Generator
- func NewGenerator(opts GeneratorOptions) *Generator
- func (g Generator) Generate() (Schema, error)
- func (g Generator) GenerateOpenAPI() (OpenAPISpec, error)
- func (g *Generator) GenerateTypeScript() (string, error)
- type GeneratorOptions
- type NotConstraint
- type OneOfConstraint
- type OpenAPIComponents
- type OpenAPIContact
- type OpenAPIExample
- type OpenAPIInfo
- type OpenAPILicense
- type OpenAPIMediaType
- type OpenAPIOperation
- type OpenAPIPath
- type OpenAPIRequestBody
- type OpenAPIResponse
- type OpenAPISchema
- type OpenAPIServer
- type OpenAPISpec
- type Property
- type RequiredConstraint
- type Schema
- func (s Schema) ConvertToOpenAPI() OpenAPISpec
- func (s *Schema) GenerateTypeScript() string
- func (s *Schema) MarshalJSON() ([]byte, error)
- func (s *Schema) MarshalPrettyJSON() ([]byte, error)
- type SchemaRef
- type TypeScriptGenerator
- type Writer
- func NewWriter(format string) *Writer
- func (w Writer) Write(schema Schema, out io.Writer) error
- func (w Writer) WriteOpenAPI(spec OpenAPISpec, out io.Writer) error
- func (w *Writer) WriteTypeScript(tsContent string, out io.Writer) error
Variables¶
EnhancedDescriptions adds detailed descriptions to properties.
var EnhancedDescriptions = map[string]map[string]string{
"os.service": {
"name": "Service name (systemd: nginx, launchd: com.example.app)",
"state": "Desired service state",
"enabled": "Enable service to start on boot (systemd: enable/disable, launchd: bootstrap/bootout)",
"daemon_reload": "Run 'systemctl daemon-reload' after unit file changes (systemd only)",
},
"file.write": {
"path": "File, directory, or symlink path (required)",
"state": "Desired file state (file/present: file exists, absent: removed, directory: dir exists, link: symlink, hardlink: hard link, touch: update timestamp, perms: change permissions only)",
"mode": "File permissions (e.g., '0644', '0755')",
"owner": "File owner (username or UID)",
"group": "File group (groupname or GID)",
},
"shell": {
"cmd": "Shell command to execute (required)",
"interpreter": "Shell interpreter binary (any executable on PATH). Default: bash on Unix, powershell on Windows. On Windows, 'cmd' dispatches with /c, others with -Command.",
"stdin": "Input to provide to the command via stdin",
"capture": "Capture command output (default: true). When false, output is only streamed",
"run_as_admin": "Windows only — assert the mooncake process is elevated; fail the step if it isn't. Does not attempt UAC. Ignored on Unix.",
"error_action": "Windows + PowerShell only — sets $ErrorActionPreference (Stop, Continue, SilentlyContinue, ...). Default: Stop. Ignored elsewhere.",
},
"pkg": {
"name": "Package name (single package)",
"names": "Multiple packages to install/remove",
"state": "Package state (present: installed, absent: removed, latest: install or upgrade)",
"manager": "Package manager (auto-detected if empty: apt, dnf, yum, pacman, zypper, apk, brew, port, choco, scoop)",
"update_cache": "Update package cache before operation (e.g., apt-get update)",
},
}
FieldOverrides hand-tunes specific (action, field) pairs whose JSON Schema type isn't directly derivable from the Go struct (e.g. union types supported by custom UnmarshalYAML).
Applied after the reflection-based property extraction.
var FieldOverrides = map[string]func(prop *Property){
"package.names": func(prop *Property) {
prop.Type = ""
prop.Items = nil
prop.OneOf = []*Property{
{Type: "array", Items: &Property{Type: "string"}},
{Type: "string"},
}
},
"os.sysctl.value": func(prop *Property) {
prop.Type = ""
prop.OneOf = []*Property{
{Type: "string"},
{Type: "integer"},
{Type: "boolean"},
}
},
}
KnownEnums maps action.field paths to their enum values. Keys use spec-21 dot-namespaced action names.
var KnownEnums = map[string][]string{
"os.service.state": {"started", "stopped", "restarted", "reloaded"},
"file.write.state": {"file", "present", "absent", "directory", "link", "hardlink", "touch", "perms"},
"pkg.state": {"present", "absent", "latest"},
"os.cron.state": {"present", "absent"},
"os.sysctl.state": {"present", "absent"},
"os.systemd.scope": {"system", "user"},
}
KnownPatterns maps field names to regex patterns for validation.
var KnownPatterns = map[string]string{
"timeout": `^[0-9]+(ns|us|µs|ms|s|m|h)$`,
"delay": `^[0-9]+(ns|us|µs|ms|s|m|h)$`,
"mode": `^[0-7]{3,4}$`,
}
KnownRanges maps field names to min/max constraints.
type Definition¶
Definition represents a schema definition (typically for an action).
type Definition struct {
Type string `json:"type" yaml:"type"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Properties map[string]*Property `json:"properties,omitempty" yaml:"properties,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
OneOf []*OneOfConstraint `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
AnyOf []*SchemaRef `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
AllOf []*SchemaRef `json:"allOf,omitempty" yaml:"allOf,omitempty"`
// additionalProperties controls whether unknown properties are allowed
AdditionalProperties *bool `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
// Custom extensions for mooncake
XPlatforms []string `json:"x-platforms,omitempty" yaml:"x-platforms,omitempty"`
XRequiresSudo bool `json:"x-requires-sudo,omitempty" yaml:"x-requires-sudo,omitempty"`
XImplementsCheck bool `json:"x-implements-check,omitempty" yaml:"x-implements-check,omitempty"`
XImplementsDiff bool `json:"x-implements-diff,omitempty" yaml:"x-implements-diff,omitempty"`
XImplementsCost bool `json:"x-implements-cost,omitempty" yaml:"x-implements-cost,omitempty"`
XImplementsReverse bool `json:"x-implements-reverse,omitempty" yaml:"x-implements-reverse,omitempty"`
XImplementsPermissions bool `json:"x-implements-permissions,omitempty" yaml:"x-implements-permissions,omitempty"`
XCategory string `json:"x-category,omitempty" yaml:"x-category,omitempty"`
XSupportsDryRun bool `json:"x-supports-dry-run,omitempty" yaml:"x-supports-dry-run,omitempty"`
XSupportsBecome bool `json:"x-supports-become,omitempty" yaml:"x-supports-become,omitempty"`
XVersion string `json:"x-version,omitempty" yaml:"x-version,omitempty"`
XEmitsEvents []string `json:"x-emits-events,omitempty" yaml:"x-emits-events,omitempty"`
}
type Generator¶
Generator generates JSON Schema from action metadata and struct definitions.
func NewGenerator¶
NewGenerator creates a new schema generator with options.
func (*Generator) Generate¶
Generate creates a complete JSON Schema from the action registry.
func (*Generator) GenerateOpenAPI¶
GenerateOpenAPI generates an OpenAPI 3.0 specification.
func (*Generator) GenerateTypeScript¶
GenerateTypeScript generates TypeScript definitions.
type GeneratorOptions¶
GeneratorOptions configures schema generation behavior.
type GeneratorOptions struct {
// IncludeExamples adds example values to properties
IncludeExamples bool
// IncludeExtensions adds custom x- extensions
IncludeExtensions bool
// StrictValidation generates stricter validation rules
StrictValidation bool
// OutputFormat specifies the output format (json, yaml, openapi, typescript)
OutputFormat string
}
type NotConstraint¶
NotConstraint represents a "not" constraint with anyOf clauses.
type NotConstraint struct {
AnyOf []*RequiredConstraint `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
}
type OneOfConstraint¶
OneOfConstraint represents a oneOf constraint with required and not clauses. It can also represent complete schema alternatives (for root-level oneOf).
type OneOfConstraint struct {
// For mutual exclusion constraints at step level
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
Properties map[string]*Property `json:"properties,omitempty" yaml:"properties,omitempty"`
Not *NotConstraint `json:"not,omitempty" yaml:"not,omitempty"`
// For root-level oneOf alternatives (complete schemas)
Type string `json:"type,omitempty" yaml:"type,omitempty"`
Items *SchemaRef `json:"items,omitempty" yaml:"items,omitempty"`
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
type OpenAPIComponents¶
OpenAPIComponents contains reusable components.
type OpenAPIComponents struct {
Schemas map[string]*OpenAPISchema `json:"schemas,omitempty" yaml:"schemas,omitempty"`
}
type OpenAPIContact¶
OpenAPIContact contains contact information.
type OpenAPIContact struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Email string `json:"email,omitempty" yaml:"email,omitempty"`
}
type OpenAPIExample¶
OpenAPIExample represents an example.
type OpenAPIExample struct {
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Value interface{} `json:"value,omitempty" yaml:"value,omitempty"`
}
type OpenAPIInfo¶
OpenAPIInfo contains API metadata.
type OpenAPIInfo struct {
Title string `json:"title" yaml:"title"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Version string `json:"version" yaml:"version"`
Contact *OpenAPIContact `json:"contact,omitempty" yaml:"contact,omitempty"`
License *OpenAPILicense `json:"license,omitempty" yaml:"license,omitempty"`
}
type OpenAPILicense¶
OpenAPILicense contains license information.
type OpenAPILicense struct {
Name string `json:"name" yaml:"name"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
}
type OpenAPIMediaType¶
OpenAPIMediaType describes a media type.
type OpenAPIMediaType struct {
Schema *OpenAPISchema `json:"schema,omitempty" yaml:"schema,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Examples map[string]OpenAPIExample `json:"examples,omitempty" yaml:"examples,omitempty"`
}
type OpenAPIOperation¶
OpenAPIOperation describes a single API operation.
type OpenAPIOperation struct {
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
RequestBody *OpenAPIRequestBody `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
Responses map[string]OpenAPIResponse `json:"responses" yaml:"responses"`
}
type OpenAPIPath¶
OpenAPIPath represents API path operations.
type OpenAPIPath struct {
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Get *OpenAPIOperation `json:"get,omitempty" yaml:"get,omitempty"`
Post *OpenAPIOperation `json:"post,omitempty" yaml:"post,omitempty"`
}
type OpenAPIRequestBody¶
OpenAPIRequestBody describes a request body.
type OpenAPIRequestBody struct {
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
Content map[string]OpenAPIMediaType `json:"content" yaml:"content"`
}
type OpenAPIResponse¶
OpenAPIResponse describes a response.
type OpenAPIResponse struct {
Description string `json:"description" yaml:"description"`
Content map[string]OpenAPIMediaType `json:"content,omitempty" yaml:"content,omitempty"`
}
type OpenAPISchema¶
OpenAPISchema represents a schema (simplified from JSON Schema). OpenAPI 3.0 uses a subset of JSON Schema with some modifications.
type OpenAPISchema struct {
Type string `json:"type,omitempty" yaml:"type,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
Properties map[string]*OpenAPISchema `json:"properties,omitempty" yaml:"properties,omitempty"`
Items *OpenAPISchema `json:"items,omitempty" yaml:"items,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
// OneOf, AnyOf, AllOf support
OneOf []*OpenAPISchema `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
AnyOf []*OpenAPISchema `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
AllOf []*OpenAPISchema `json:"allOf,omitempty" yaml:"allOf,omitempty"`
Not *OpenAPISchema `json:"not,omitempty" yaml:"not,omitempty"`
// Validation
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
MinLength *int `json:"minLength,omitempty" yaml:"minLength,omitempty"`
MaxLength *int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
Format string `json:"format,omitempty" yaml:"format,omitempty"`
AdditionalProperties *bool `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
// Custom extensions (x- prefixed fields are allowed in OpenAPI)
XPlatforms []string `json:"x-platforms,omitempty" yaml:"x-platforms,omitempty"`
XRequiresSudo bool `json:"x-requires-sudo,omitempty" yaml:"x-requires-sudo,omitempty"`
XImplementsCheck bool `json:"x-implements-check,omitempty" yaml:"x-implements-check,omitempty"`
XImplementsDiff bool `json:"x-implements-diff,omitempty" yaml:"x-implements-diff,omitempty"`
XImplementsCost bool `json:"x-implements-cost,omitempty" yaml:"x-implements-cost,omitempty"`
XImplementsReverse bool `json:"x-implements-reverse,omitempty" yaml:"x-implements-reverse,omitempty"`
XImplementsPermissions bool `json:"x-implements-permissions,omitempty" yaml:"x-implements-permissions,omitempty"`
XCategory string `json:"x-category,omitempty" yaml:"x-category,omitempty"`
XSupportsDryRun bool `json:"x-supports-dry-run,omitempty" yaml:"x-supports-dry-run,omitempty"`
XSupportsBecome bool `json:"x-supports-become,omitempty" yaml:"x-supports-become,omitempty"`
XVersion string `json:"x-version,omitempty" yaml:"x-version,omitempty"`
XEmitsEvents []string `json:"x-emits-events,omitempty" yaml:"x-emits-events,omitempty"`
}
type OpenAPIServer¶
OpenAPIServer describes a server.
type OpenAPIServer struct {
URL string `json:"url" yaml:"url"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
type OpenAPISpec¶
OpenAPISpec represents an OpenAPI 3.0 specification document.
type OpenAPISpec struct {
OpenAPI string `json:"openapi" yaml:"openapi"`
Info OpenAPIInfo `json:"info" yaml:"info"`
Servers []OpenAPIServer `json:"servers,omitempty" yaml:"servers,omitempty"`
Paths map[string]OpenAPIPath `json:"paths,omitempty" yaml:"paths,omitempty"`
Components OpenAPIComponents `json:"components" yaml:"components"`
}
type Property¶
Property represents a schema property (field in an action struct).
type Property struct {
Type string `json:"type,omitempty" yaml:"type,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Items *Property `json:"items,omitempty" yaml:"items,omitempty"`
Properties map[string]*Property `json:"properties,omitempty" yaml:"properties,omitempty"`
OneOf []*Property `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
// Validation
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
MinLength *int `json:"minLength,omitempty" yaml:"minLength,omitempty"`
MaxLength *int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
Format string `json:"format,omitempty" yaml:"format,omitempty"`
// Additional metadata
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
AdditionalProps *bool `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
}
type RequiredConstraint¶
RequiredConstraint represents a simple required constraint.
type Schema¶
Schema represents a complete JSON Schema document.
type Schema struct {
SchemaURI string `json:"$schema" yaml:"$schema"`
ID string `json:"$id,omitempty" yaml:"$id,omitempty"`
Title string `json:"title" yaml:"title"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Type string `json:"type,omitempty" yaml:"type,omitempty"`
Items *SchemaRef `json:"items,omitempty" yaml:"items,omitempty"`
OneOf []*OneOfConstraint `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
Definitions map[string]*Definition `json:"definitions,omitempty" yaml:"definitions,omitempty"`
}
func (*Schema) ConvertToOpenAPI¶
ConvertToOpenAPI converts a JSON Schema to OpenAPI 3.0 format.
func (*Schema) GenerateTypeScript¶
GenerateTypeScript generates TypeScript definitions from a schema.
func (*Schema) MarshalJSON¶
MarshalJSON converts the schema to JSON.
func (*Schema) MarshalPrettyJSON¶
MarshalPrettyJSON converts the schema to pretty-printed JSON.
type SchemaRef¶
SchemaRef represents a reference to another schema definition. Also used inside anyOf/allOf branches as a lightweight "shape with just a required clause" fragment when neither $ref nor type fits — e.g. runConfig's anyOf: [{required: [steps]}, {required: [tasks]}].
type SchemaRef struct {
Ref string `json:"$ref,omitempty"`
Type string `json:"type,omitempty"`
Description string `json:"description,omitempty"`
Required []string `json:"required,omitempty"`
}
type TypeScriptGenerator¶
TypeScriptGenerator generates TypeScript definitions from schema.
type Writer¶
Writer handles writing schemas in different formats.
func NewWriter¶
NewWriter creates a new writer for the specified format.
func (*Writer) Write¶
Write writes the schema to the given writer.
func (*Writer) WriteOpenAPI¶
WriteOpenAPI writes an OpenAPI spec to the given writer.
func (*Writer) WriteTypeScript¶
WriteTypeScript writes TypeScript definitions to the given writer.
Generated by gomarkdoc