config

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package config loads and validates `craftgo.design.yaml`, the project manifest read by every CLI command.

The manifest lives **inside** the design folder. A repo-relative layout looks like:

myapp/
├── design/
│   ├── craftgo.design.yaml
│   └── api.craftgo
└── internal/...                  (generated)

The directory holding the manifest is the **design root**; its parent is the **project root** that every `output:` path is resolved against. This arrangement keeps each design folder fully self-contained, which is the pre-requisite for a single repo to host multiple craftgo modules (monorepo scenario).

Index

Constants

View Source
const (
	FileCaseKebab = "kebab"
	FileCaseSnake = "snake"
	FileCaseCamel = "camel"
	// DefaultFileCase applies when the manifest leaves fileCase unset.
	DefaultFileCase = FileCaseSnake
)

Supported values for Output.FileCase. They name the case used for generated file and directory names (not URLs or Go identifiers).

View Source
const Filename = "craftgo.design.yaml"

Filename is the canonical project manifest file name. Find walks parent directories looking for it, optionally peeking into a child `design/` directory at each level.

Variables

View Source
var DesignFileExtensions = []string{".craftgo", ".cg"}

DesignFileExtensions are the extensions a craftgo source file may carry. `.craftgo` is canonical; `.cg` is the short alias. Both are accepted everywhere design sources are discovered - `craftgo gen`, `craftgo fmt`, and the language server's project walk and file watcher - and a single project may freely mix the two.

Functions

func IsDesignFile added in v1.3.5

func IsDesignFile(path string) bool

IsDesignFile reports whether path names a craftgo source file, matching its extension against DesignFileExtensions. path may be a full path or a bare file name.

func ResolveModulePath

func ResolveModulePath(projectRoot string) (string, error)

ResolveModulePath walks upward from `projectRoot` looking for a `go.mod`, parses its `module ...` line, and appends the relative path from go.mod's directory to projectRoot. The result is the Go import-path prefix every generated file uses for its imports.

Examples:

go.mod at repo/, module "github.com/foo/bar", projectRoot=repo/
  → "github.com/foo/bar"
go.mod at repo/, module "github.com/foo/bar", projectRoot=repo/services/api
  → "github.com/foo/bar/services/api"

The walk-up handles both the simple single-module project (go.mod at project root) and the monorepo with one shared go.mod at the repo root and project root inside a sub-tree. Errors when no go.mod is found anywhere upward - gen needs the canonical module path to emit imports the Go compiler can resolve.

Types

type Config

type Config struct {
	Output  Output  `yaml:"output"`
	OpenAPI OpenAPI `yaml:"openapi"`

	// Package is the Go import path prefix every generated file uses
	// for its imports - the equivalent of <module>/<relPathFromGoMod>
	// for the project root. Not loaded from YAML: populated at gen
	// time by [ResolveModulePath], which walks up from the project
	// root looking for a go.mod and computes the effective import
	// path. The manifest carries no module field; go.mod's `module`
	// line is the sole source of truth.
	Package string `yaml:"-"`
}

Config is the in-memory shape of `craftgo.design.yaml`. Field tags match the camelCase keys documented in the project README.

func Find

func Find(start string) (*Config, string, string, error)

Find walks upward from `start` until it locates a Filename. At every candidate directory two strategies are tried, in order: the directory itself, then any direct subdirectory containing the manifest - so users can invoke `craftgo gen` from either the design folder or its parent regardless of what the design folder is named (`design`, `contracts`, `apis/v1`, ...). When more than one direct subdir holds a manifest the function bails out with an unambiguous error rather than silently picking one - the caller should pass an explicit folder via FindAt.

On success it returns the loaded *Config, the absolute path of the project root (the parent of the design folder), and the absolute path of the design folder itself. Every `.craftgo` source file lives in the design folder or its descendants.

func FindAt

func FindAt(designFolder, projectRoot string) (*Config, string, string, error)

FindAt loads the manifest at `<designFolder>/craftgo.design.yaml` and returns it alongside the resolved project root. When `projectRoot` is empty the parent of `designFolder` is used; pass an explicit value (typically the current working directory) when the design folder lives outside the project tree - the monorepo case where contracts/ and services/ are siblings.

All paths in the returned tuple are absolute.

func Load

func Load(path string) (*Config, error)

Load parses the manifest at `path`, validates required fields, applies defaults to optional ones, and returns the resulting *Config.

type OAuthFlow added in v1.3.4

type OAuthFlow struct {
	AuthorizationURL string            `yaml:"authorizationUrl,omitempty"`
	TokenURL         string            `yaml:"tokenUrl,omitempty"`
	RefreshURL       string            `yaml:"refreshUrl,omitempty"`
	Scopes           map[string]string `yaml:"scopes,omitempty"`
}

OAuthFlow mirrors the OpenAPI `oauthFlow` object for one grant type.

type OAuthFlows added in v1.3.4

type OAuthFlows struct {
	Implicit          *OAuthFlow `yaml:"implicit,omitempty"`
	Password          *OAuthFlow `yaml:"password,omitempty"`
	ClientCredentials *OAuthFlow `yaml:"clientCredentials,omitempty"`
	AuthorizationCode *OAuthFlow `yaml:"authorizationCode,omitempty"`
}

OAuthFlows mirrors the OpenAPI `oauthFlows` object: the four standard grant flows, each optional but at least one required for a valid oauth2 scheme.

func (*OAuthFlows) HasFlow added in v1.3.4

func (f *OAuthFlows) HasFlow() bool

HasFlow reports whether at least one OAuth2 flow is configured.

type OpenAPI

type OpenAPI struct {
	Title           string                    `yaml:"title"`
	Version         string                    `yaml:"version"`
	Description     string                    `yaml:"description"`
	BasePath        string                    `yaml:"basePath"`
	SecuritySchemes map[string]SecurityScheme `yaml:"securitySchemes"`
}

OpenAPI carries metadata that surfaces in the generated specification's info / servers blocks. BasePath is also used by the runtime to compute the final route string for each method. SecuritySchemes is a name → scheme map that powers the `@security(name)` cross-check: any DSL reference must resolve to a key here when the map is non-empty.

type Output

type Output struct {
	Types      string `yaml:"types"`
	Transport  string `yaml:"transport"`
	Routes     string `yaml:"routes"`
	Service    string `yaml:"service"`
	Main       string `yaml:"main"`
	Svccontext string `yaml:"svccontext"`
	OpenAPI    string `yaml:"openapi"`
	// Middleware is the scaffold-once output dir for middleware
	// implementation files. The corresponding type declarations live
	// next to svccontext.go (see GenerateProjectMiddlewares).
	Middleware string `yaml:"middleware"`
	// Config is the scaffold-once directory holding the runtime
	// configuration package (config.go + config.yaml +
	// example.config.yaml). main.go reads from `<Config>/config.yaml`
	// at boot. Defaults to `./config`.
	Config string `yaml:"config"`
	// FileCase selects the naming convention for GENERATED file and
	// directory names derived from DSL identifiers - the per-method
	// handler/service files and the per-service directory. `snake`
	// (default) yields `create_user.go` / `user_service/`, `kebab`
	// yields `create-user.go` / `user-service/`, `camel` yields
	// `createUser.go` / `userService/`. It affects on-disk names only:
	// URL routes stay kebab-case, and Go package names / identifiers
	// are unchanged.
	FileCase string `yaml:"fileCase"`
}

Output groups every generated-artefact destination. Directory paths (Types, Transport, Routes, Service) are appended with `/<service>` per service at codegen time. File paths (Main, Svccontext, OpenAPI) point at the exact file that will be written. All paths are relative to the **project root** (the parent of the design folder).

func (Output) RuntimeDisabled added in v1.7.0

func (o Output) RuntimeDisabled() bool

RuntimeDisabled reports whether the project opted out of the generated runtime layer (main.go, config, svccontext) with `output.main: "-"`.

type SecurityScheme

type SecurityScheme struct {
	// Type is the OpenAPI 3.1 scheme type: "http", "apiKey", "oauth2",
	// "openIdConnect", or "mutualTLS". Required.
	Type string `yaml:"type"`
	// Scheme is the HTTP authentication scheme name (`bearer`, `basic`).
	// Used only when Type == "http".
	Scheme string `yaml:"scheme,omitempty"`
	// BearerFormat hints at the bearer token shape (e.g. "JWT").
	BearerFormat string `yaml:"bearerFormat,omitempty"`
	// In is the apiKey location: "header", "query", or "cookie".
	In string `yaml:"in,omitempty"`
	// Name is the apiKey header / query / cookie name.
	Name string `yaml:"name,omitempty"`
	// OpenIDConnectURL is the discovery URL for openIdConnect.
	OpenIDConnectURL string `yaml:"openIdConnectUrl,omitempty"`
	// Flows configures the OAuth2 flows. Required (with at least one flow)
	// when Type == "oauth2" - the OpenAPI spec mandates a `flows` object, and
	// omitting it produces an invalid document that downstream client
	// generators (e.g. @hey-api/openapi-ts) reject.
	Flows *OAuthFlows `yaml:"flows,omitempty"`
}

SecurityScheme is the project-side projection of an OpenAPI 3.1 security scheme object. Only the fields the codegen needs to validate references and emit OpenAPI components are modelled.

Jump to

Keyboard shortcuts

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