Documentation
¶
Overview ¶
Package manifest handles the nexus.yml project manifest — the persistent record of a Nexus project's configuration and entities.
This file implements loading, saving, and validating the manifest file. The manifest lives at the root of a generated Nexus project as `nexus.yml`.
Load/Save use gopkg.in/yaml.v3 for serialization. We chose YAML because:
- It's the most human-readable config format
- It supports comments (unlike JSON)
- It aligns with Kubernetes/Docker ecosystem conventions
- Users will hand-edit this file occasionally
Validation catches inconsistencies early — for example, an entity referencing a protocol that isn't enabled, or duplicate entity names.
Package manifest handles the nexus.yml project manifest — the persistent record of a Nexus project's configuration and entities.
The manifest is created during `nexus init` and updated by `nexus add entity`. It stores enough information for subsequent scaffolding commands to know:
- Which protocols, database, auth, and middleware are enabled
- Which entities have been scaffolded (with their fields)
This file defines the core types: Manifest, Entity, and Field.
Design Decisions:
- We use YAML (not JSON or TOML) because it's the most human-readable format for configuration files and aligns with Kubernetes/Docker conventions.
- Entity names are stored in PascalCase to match Go type conventions.
- Field types use a small, well-defined set of abstract types that map cleanly to Go types, SQL column types, protobuf scalar types, and GraphQL scalar types.
- The Manifest embeds enough project metadata to regenerate or extend code without needing the original init wizard answers.
Index ¶
- Constants
- func Exists(dir string) bool
- func Save(m *Manifest, dir string) error
- func SaveTo(m *Manifest, path string) error
- func Validate(m *Manifest) error
- type Entity
- func (e *Entity) EnumFields() []Field
- func (e *Entity) HasEnumFields() bool
- func (e *Entity) HasField(name string) bool
- func (e *Entity) HasSoftDelete() bool
- func (e *Entity) HasStringSliceFields() bool
- func (e *Entity) HasTimestamps() bool
- func (e *Entity) NeedsJSONImport() bool
- func (e *Entity) NeedsTimeImport() bool
- func (e *Entity) OptionalFields() []Field
- func (e *Entity) RequiredFields() []Field
- func (e *Entity) UniqueFields() []Field
- type Field
- type FieldType
- type Manifest
- func (m *Manifest) AddEntity(e Entity) error
- func (m *Manifest) GetEntity(name string) *Entity
- func (m *Manifest) HasAuth() bool
- func (m *Manifest) HasDatabase() bool
- func (m *Manifest) HasEntity(name string) bool
- func (m *Manifest) HasGRPC() bool
- func (m *Manifest) HasGraphQL() bool
- func (m *Manifest) HasMiddleware(name string) bool
- func (m *Manifest) HasProtocol(name string) bool
- func (m *Manifest) HasREST() bool
- func (m *Manifest) HasSSE() bool
- func (m *Manifest) HasWebSocket() bool
- type ValidationError
Constants ¶
const FileName = "nexus.yml"
FileName is the conventional name for the Nexus manifest file.
Variables ¶
This section is empty.
Functions ¶
func Exists ¶
Exists reports whether a nexus.yml file exists in the given directory. If dir is empty, the current working directory is used.
func Save ¶
Save writes the manifest to nexus.yml in the given directory. If dir is empty, the current working directory is used.
The manifest is validated before writing. If validation fails, the file is not written and the validation error is returned.
func Validate ¶
Validate checks the manifest for structural correctness and consistency.
It verifies:
- Required fields (project, module) are non-empty
- Module path is syntactically valid
- Protocols are recognized
- Database and Auth values are recognized
- Entity names are PascalCase and unique
- Field names are snake_case and unique within their entity
- Field types are recognized
- Enum fields have at least one enum value
- No duplicate middleware entries
Types ¶
type Entity ¶
type Entity struct {
// Name is the PascalCase entity name (e.g., "User", "BlogPost").
Name string `yaml:"name"`
// Fields lists the entity's data fields (not including ID or timestamps).
Fields []Field `yaml:"fields"`
// Timestamps controls whether CreatedAt and UpdatedAt fields are included.
// When true, the entity struct includes time.Time fields and the repository
// implementations automatically manage them.
Timestamps bool `yaml:"timestamps"`
// SoftDelete controls whether the entity supports soft deletion.
// When true, a DeletedAt *time.Time field is added and Delete operations
// set this field rather than removing the row. List operations filter
// out soft-deleted entities by default.
SoftDelete bool `yaml:"soft_delete"`
}
Entity represents a single domain entity that has been (or will be) scaffolded across all layers (entity, repository, service, operations, proto, GraphQL).
Entity names are stored in PascalCase (e.g., "User", "BlogPost") to match Go type naming conventions.
func (*Entity) EnumFields ¶
EnumFields returns only the fields that are enum type.
func (*Entity) HasEnumFields ¶
HasEnumFields reports whether any field is an enum type.
func (*Entity) HasSoftDelete ¶
HasSoftDelete reports whether the entity supports soft deletion.
func (*Entity) HasStringSliceFields ¶
HasStringSliceFields reports whether any field is a []string type.
func (*Entity) HasTimestamps ¶
HasTimestamps reports whether the entity includes CreatedAt/UpdatedAt fields.
func (*Entity) NeedsJSONImport ¶
NeedsJSONImport reports whether the entity needs the "encoding/json" import.
func (*Entity) NeedsTimeImport ¶
NeedsTimeImport reports whether the entity needs the "time" import. This is true if timestamps are enabled or any field has type "time".
func (*Entity) OptionalFields ¶
OptionalFields returns only the fields that are NOT required.
func (*Entity) RequiredFields ¶
RequiredFields returns only the fields that are marked as required.
func (*Entity) UniqueFields ¶
UniqueFields returns only the fields that are marked as unique.
type Field ¶
type Field struct {
// Name is the field name in snake_case (e.g., "first_name", "email").
// Templates convert this to PascalCase for Go struct fields and to the
// appropriate casing for JSON tags, SQL columns, and proto fields.
Name string `yaml:"name"`
// Type is the abstract field type. See FieldType constants.
Type FieldType `yaml:"type"`
// Required indicates whether the field must be provided on create.
// Required fields generate non-pointer struct fields and NOT NULL SQL
// constraints. Optional fields generate pointer struct fields.
Required bool `yaml:"required"`
// Unique indicates whether the field must have a unique value across
// all entities. Unique fields generate UNIQUE SQL constraints and
// additional repository methods (e.g., GetByEmail for a unique email field).
Unique bool `yaml:"unique"`
// EnumValues holds the allowed values when Type is "enum".
// Ignored for other field types. Templates generate a typed string
// enum with these values.
EnumValues []string `yaml:"enum_values,omitempty"`
}
Field represents a single data field within an entity. Fields are defined by the user during `nexus add entity` and stored in the manifest.
The combination of Type, Required, and Unique determines how the field is handled in validation, database schema, and API contracts.
func ParseField ¶
ParseField parses a field specification string into a Field struct.
Accepted formats:
"name:type" → Field{Name: "name", Type: "type", Required: false}
"name:type:required" → Field{Name: "name", Type: "type", Required: true}
"name:type:unique" → Field{Name: "name", Type: "type", Unique: true}
"name:type:required:unique" → both required and unique
The order of modifiers (required, unique) does not matter.
func ParseFields ¶
ParseFields parses a space-separated string of field specifications.
Example: "name:string:required email:string:unique:required age:int"
type FieldType ¶
type FieldType string
FieldType represents the abstract type of an entity field. These map to concrete Go types, SQL column types, protobuf types, and GraphQL types.
const ( FieldTypeString FieldType = "string" FieldTypeInt FieldType = "int" FieldTypeFloat FieldType = "float" FieldTypeBool FieldType = "bool" FieldTypeTime FieldType = "time" FieldTypeUUID FieldType = "uuid" FieldTypeText FieldType = "text" // long-form string (TEXT in SQL) FieldTypeEnum FieldType = "enum" FieldTypeJSON FieldType = "json" // stored as JSON blob FieldTypeStrSlice FieldType = "[]string" )
func AllFieldTypes ¶
func AllFieldTypes() []FieldType
AllFieldTypes returns all supported field types.
func (FieldType) GoType ¶
GoType returns the Go type string corresponding to this field type. Used by templates to declare struct fields.
func (FieldType) GraphQLType ¶
GraphQLType returns the GraphQL scalar type for this field type. Used by the GraphQL schema fragment template.
func (FieldType) NeedsImport ¶
NeedsImport returns the Go import path required by this field type, or empty string if no extra import is needed.
type Manifest ¶
type Manifest struct {
// Project is the human-readable project name (e.g., "my-backend").
Project string `yaml:"project"`
// Module is the Go module path (e.g., "github.com/user/my-backend").
Module string `yaml:"module"`
// Version is the project version (e.g., "0.1.0").
Version string `yaml:"version"`
// Protocols lists the enabled protocol adapters (e.g., ["rest", "grpc"]).
Protocols []string `yaml:"protocols"`
// Database is the selected database backend ("sqlite", "postgres", or "none").
Database string `yaml:"database"`
// Auth is the selected authentication strategy ("jwt", "apikey", or "none").
Auth string `yaml:"auth"`
// Middleware lists the enabled middleware (e.g., ["ratelimit", "cors"]).
Middleware []string `yaml:"middleware"`
// Entities lists all scaffolded domain entities with their field definitions.
Entities []Entity `yaml:"entities"`
}
Manifest represents the nexus.yml project configuration file. It is the single source of truth for the project's scaffolding state, recording which features are enabled and which entities have been generated.
The manifest is created by `nexus init` and updated by `nexus add entity`. It allows subsequent commands to understand the project without re-asking the user for configuration details.
func Load ¶
Load reads and parses the nexus.yml manifest from the given directory. If dir is empty, the current working directory is used.
Returns the parsed Manifest and any error encountered during reading, parsing, or validation.
func LoadFrom ¶
LoadFrom reads and parses a manifest from the given file path directly (not a directory). This is useful when you know the exact file path.
func NewManifest ¶
func NewManifest(project, module, version string, protocols []string, database, auth string, middleware []string) *Manifest
NewManifest creates a Manifest from the essential project configuration values. This is used during `nexus init` to create the initial manifest before any entities are added.
func (*Manifest) AddEntity ¶
AddEntity appends an entity to the manifest. Returns an error if an entity with the same name already exists.
func (*Manifest) GetEntity ¶
GetEntity returns the entity with the given name, or nil if not found. The comparison is case-insensitive.
func (*Manifest) HasAuth ¶
HasAuth reports whether authentication (other than "none") is configured.
func (*Manifest) HasDatabase ¶
HasDatabase reports whether a database (other than "none") is configured.
func (*Manifest) HasEntity ¶
HasEntity reports whether the manifest contains an entity with the given name. The comparison is case-insensitive.
func (*Manifest) HasGraphQL ¶
HasGraphQL reports whether GraphQL is in the protocols list.
func (*Manifest) HasMiddleware ¶
HasMiddleware reports whether the manifest has the given middleware enabled.
func (*Manifest) HasProtocol ¶
HasProtocol reports whether the manifest has the given protocol enabled.
func (*Manifest) HasWebSocket ¶
HasWebSocket reports whether WebSocket is in the protocols list.
type ValidationError ¶
type ValidationError struct {
Issues []string
}
ValidationError collects multiple validation issues from the manifest.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error implements the error interface.