manifest

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

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

View Source
const FileName = "nexus.yml"

FileName is the conventional name for the Nexus manifest file.

Variables

This section is empty.

Functions

func Exists

func Exists(dir string) bool

Exists reports whether a nexus.yml file exists in the given directory. If dir is empty, the current working directory is used.

func Save

func Save(m *Manifest, dir string) error

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 SaveTo

func SaveTo(m *Manifest, path string) error

SaveTo writes the manifest to the exact file path specified.

func Validate

func Validate(m *Manifest) error

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

func (e *Entity) EnumFields() []Field

EnumFields returns only the fields that are enum type.

func (*Entity) HasEnumFields

func (e *Entity) HasEnumFields() bool

HasEnumFields reports whether any field is an enum type.

func (*Entity) HasField

func (e *Entity) HasField(name string) bool

HasField reports whether the entity has a field with the given name.

func (*Entity) HasSoftDelete

func (e *Entity) HasSoftDelete() bool

HasSoftDelete reports whether the entity supports soft deletion.

func (*Entity) HasStringSliceFields

func (e *Entity) HasStringSliceFields() bool

HasStringSliceFields reports whether any field is a []string type.

func (*Entity) HasTimestamps

func (e *Entity) HasTimestamps() bool

HasTimestamps reports whether the entity includes CreatedAt/UpdatedAt fields.

func (*Entity) NeedsJSONImport

func (e *Entity) NeedsJSONImport() bool

NeedsJSONImport reports whether the entity needs the "encoding/json" import.

func (*Entity) NeedsTimeImport

func (e *Entity) NeedsTimeImport() bool

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

func (e *Entity) OptionalFields() []Field

OptionalFields returns only the fields that are NOT required.

func (*Entity) RequiredFields

func (e *Entity) RequiredFields() []Field

RequiredFields returns only the fields that are marked as required.

func (*Entity) UniqueFields

func (e *Entity) UniqueFields() []Field

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

func ParseField(spec string) (Field, error)

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

func ParseFields(spec string) ([]Field, error)

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

func (ft FieldType) GoType() string

GoType returns the Go type string corresponding to this field type. Used by templates to declare struct fields.

func (FieldType) GraphQLType

func (ft FieldType) GraphQLType() string

GraphQLType returns the GraphQL scalar type for this field type. Used by the GraphQL schema fragment template.

func (FieldType) IsValid

func (ft FieldType) IsValid() bool

IsValid reports whether the field type is a recognized type.

func (FieldType) NeedsImport

func (ft FieldType) NeedsImport() string

NeedsImport returns the Go import path required by this field type, or empty string if no extra import is needed.

func (FieldType) ProtoType

func (ft FieldType) ProtoType() string

ProtoType returns the Protocol Buffers scalar type for this field type. Used by the .proto template to generate message definitions.

func (FieldType) SQLType

func (ft FieldType) SQLType() string

SQLType returns the SQL column type for this field type. Used by repository templates to generate CREATE TABLE statements.

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

func Load(dir string) (*Manifest, error)

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

func LoadFrom(path string) (*Manifest, error)

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

func (m *Manifest) AddEntity(e Entity) error

AddEntity appends an entity to the manifest. Returns an error if an entity with the same name already exists.

func (*Manifest) GetEntity

func (m *Manifest) GetEntity(name string) *Entity

GetEntity returns the entity with the given name, or nil if not found. The comparison is case-insensitive.

func (*Manifest) HasAuth

func (m *Manifest) HasAuth() bool

HasAuth reports whether authentication (other than "none") is configured.

func (*Manifest) HasDatabase

func (m *Manifest) HasDatabase() bool

HasDatabase reports whether a database (other than "none") is configured.

func (*Manifest) HasEntity

func (m *Manifest) HasEntity(name string) bool

HasEntity reports whether the manifest contains an entity with the given name. The comparison is case-insensitive.

func (*Manifest) HasGRPC

func (m *Manifest) HasGRPC() bool

HasGRPC reports whether gRPC is in the protocols list.

func (*Manifest) HasGraphQL

func (m *Manifest) HasGraphQL() bool

HasGraphQL reports whether GraphQL is in the protocols list.

func (*Manifest) HasMiddleware

func (m *Manifest) HasMiddleware(name string) bool

HasMiddleware reports whether the manifest has the given middleware enabled.

func (*Manifest) HasProtocol

func (m *Manifest) HasProtocol(name string) bool

HasProtocol reports whether the manifest has the given protocol enabled.

func (*Manifest) HasREST

func (m *Manifest) HasREST() bool

HasREST reports whether REST is in the protocols list.

func (*Manifest) HasSSE

func (m *Manifest) HasSSE() bool

HasSSE reports whether SSE is in the protocols list.

func (*Manifest) HasWebSocket

func (m *Manifest) HasWebSocket() bool

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL