config

package
v2.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package config is the public API for reading and writing Restish config.

The supported surface is the on-disk restish.json schema structs, path discovery, strict JSONC loading/parsing, whole-file saving, validation, and small helpers that interpret config field values such as operation bases and URL overrides. Comment-preserving mutation helpers, v1 migration internals, and file-lock/atomic-write primitives live under internal packages so they can evolve with the CLI.

Index

Constants

This section is empty.

Variables

View Source
var ErrPermissionCheckUnsupported = errors.New("permission check unsupported on this platform")

ErrPermissionCheckUnsupported reports that Restish cannot verify file permissions on the current platform.

Functions

func ApplyURLOverrides

func ApplyURLOverrides(rawURL string, overrides map[string]string) (string, bool, error)

ApplyURLOverrides rewrites rawURL when it matches a configured URL prefix. The longest matching source prefix wins. Query strings and fragments from the request URL are preserved.

func ConfigFileHasInsecurePermissions

func ConfigFileHasInsecurePermissions(path string) (bool, error)

ConfigFileHasInsecurePermissions reports whether path is readable by group or others. On Windows, existing files return ErrPermissionCheckUnsupported because Unix permission bits are not authoritative and ACL inspection is not implemented.

func DefaultPath

func DefaultPath() string

DefaultPath returns the path to the default config file, honoring the RSH_CONFIG_DIR and XDG environment variable overrides.

func OperationOriginAllowed

func OperationOriginAllowed(serverURL string, patterns []string) bool

OperationOriginAllowed reports whether serverURL's origin is permitted by allowed_operation_origins.

func ReadAPIs

func ReadAPIs(folder string) (map[string]*APIConfig, error)

ReadAPIs returns every API configured in folder, in v2 shape, regardless of whether the user's config is in v2 (restish.json) or v1 (apis.json) format. This is the format-agnostic read path for embedders.

restish.json is preferred when present. apis.json is read only when restish.json does not exist, so a user who has already migrated is served from the v2 file with no v1 conversion. ReadAPIs never modifies either file; the restish CLI's TryMigrate step is responsible for that.

func ReadLegacyAPIs

func ReadLegacyAPIs(folder string) (map[string]*APIConfig, error)

ReadLegacyAPIs reads every API from a v1 apis.json in folder, returning them in v2 shape. The "$schema" key is skipped. Returns an empty map and no error when apis.json does not exist.

This is the read path for embedders that want to read a legacy config without going through the restish CLI's automatic migration. ReadLegacyAPIs never modifies the user's apis.json or restish.json; the restish CLI's own TryMigrate step is responsible for that.

func ResolveOperationBaseURL

func ResolveOperationBaseURL(baseURL, operationBase string) (string, error)

ResolveOperationBaseURL resolves an absolute operation_base path against the API base URL using the same URL-reference semantics as Restish v1.

func Save

func Save(path string, cfg *Config) error

Save serialises cfg as indented JSON and writes it to path, creating the parent directory if necessary. Existing JSONC comments are not preserved.

func Validate

func Validate(cfg *Config) error

Validate checks cross-field config invariants that JSON decoding alone cannot enforce.

func ValidateAPIName

func ValidateAPIName(name string) error

ValidateAPIName enforces a shell- and URL-friendly API short name while allowing non-English letters and numbers.

func ValidateBaseURLForOperationBase

func ValidateBaseURLForOperationBase(raw string) error

ValidateBaseURLForOperationBase ensures operation_base can be resolved at load time instead of failing later when generated commands run.

func ValidateCommandLayout

func ValidateCommandLayout(raw string) error

ValidateCommandLayout enforces supported generated command arrangements.

func ValidateOperationBase

func ValidateOperationBase(raw string) error

ValidateOperationBase enforces the v2 contract that operation_base is an absolute URL path prefix.

func ValidateOperationOriginPattern

func ValidateOperationOriginPattern(raw string) error

ValidateOperationOriginPattern validates an allowed_operation_origins entry. Patterns are origins such as https://api.example.com or conservative single-label wildcards such as https://*.example.com.

func ValidateRetryMaxWait

func ValidateRetryMaxWait(raw string) error

ValidateRetryMaxWait enforces the retry_max_wait duration contract.

func ValidateURLOverrides

func ValidateURLOverrides(overrides map[string]string) error

ValidateURLOverrides enforces the URL prefix rewrite contract.

Types

type APIConfig

type APIConfig struct {
	// BaseURL is the base URL for all requests to this API.
	BaseURL string `json:"base_url,omitempty"`
	// SpecURL is the URL of the OpenAPI spec for this API (optional).
	// Mutually exclusive with SpecFiles; SpecFiles takes precedence when both are set.
	SpecURL string `json:"spec_url,omitempty"`
	// AllowCrossOriginSpec permits discovery from Link-header spec URLs on
	// hosts other than base_url. Private, loopback, link-local, and
	// unspecified IP literal targets are still rejected.
	AllowCrossOriginSpec bool `json:"allow_cross_origin_spec,omitempty"`
	// SpecFiles is an ordered list of local file paths or URLs to load the API
	// spec from. Multiple files are deep-merged in order (later entries win on
	// conflict). When set, network spec discovery is skipped entirely.
	SpecFiles []string `json:"spec_files,omitempty"`
	// OperationBase, when set, is an absolute path resolved against base_url for
	// paths generated from OpenAPI operations. Useful when operation paths should
	// escape or replace a sub-path in base_url.
	OperationBase string `json:"operation_base,omitempty"`
	// CommandLayout controls how generated operations are arranged under the
	// API command. Empty or "flat" keeps one flat command namespace; "tags"
	// groups operations under first-tag subcommands.
	CommandLayout string `json:"command_layout,omitempty"`
	// ServerVariables supplies explicit values for OpenAPI server URL variables.
	// Values are used for generated operation path resolution; enum values from
	// remote specs are never expanded eagerly.
	ServerVariables map[string]string `json:"server_variables,omitempty"`
	// URLOverrides rewrites resolved request URL prefixes before execution.
	// It is useful when an OpenAPI document names canonical servers but this
	// profile should route requests to staging, local, or test endpoints.
	URLOverrides map[string]string `json:"url_overrides,omitempty"`
	// AllowedOperationOrigins permits generated commands to use operation- or
	// path-level OpenAPI servers on origins outside base_url.
	AllowedOperationOrigins []string `json:"allowed_operation_origins,omitempty"`
	// Profiles is a map of profile name to profile configuration.
	Profiles map[string]*ProfileConfig `json:"profiles,omitempty"`
	// Pagination holds optional per-API pagination configuration.
	Pagination *PaginationConfig `json:"pagination,omitempty"`
	// RetryMaxWait caps Retry-After/X-Retry-In delays for this API when no
	// command-line or environment override is supplied.
	RetryMaxWait string `json:"retry_max_wait,omitempty"`
	// PreserveHeaderCase sends user/API-supplied header names with their
	// configured casing for broken HTTP/1.x servers that treat names as
	// case-sensitive. It cannot affect HTTP/2, where header names are lowercase
	// by protocol.
	PreserveHeaderCase bool `json:"preserve_header_case,omitempty"`
}

APIConfig holds per-API configuration.

func ConvertLegacyAPI

func ConvertLegacyAPI(name string, raw json.RawMessage) (*APIConfig, []string, error)

ConvertLegacyAPI converts a single v1 (apis.json) APIConfig entry to the current v2 shape. The name argument is used for warning messages only; it does not affect the converted data. Pass the raw JSON value of one entry from an apis.json file, e.g. the bytes associated with one key in the top-level map.

Returned warnings describe migration-time decisions such as dropped invalid operation_base values or migrated PKCS#11 TLS config that now requires the restish-pkcs11 plugin to be installed.

The function does not read or write any files. Callers that want a one-call read of an apis.json folder can use ReadLegacyAPIs.

func ReadLegacyAPI

func ReadLegacyAPI(folder, name string) (*APIConfig, error)

ReadLegacyAPI reads a single named API from a v1 apis.json in folder, returning it in v2 shape. Returns an error when the API is not present.

type AuthConfig

type AuthConfig struct {
	// Type identifies the auth mechanism (e.g. "http-basic", "oauth-client-credentials").
	Type string `json:"type,omitempty"`
	// Params holds handler-specific configuration, e.g. {"username": "alice"}.
	Params map[string]string `json:"params,omitempty"`
}

AuthConfig holds authentication configuration for a profile.

type CacheConfig

type CacheConfig struct {
	// MaxSize is the maximum cache size (e.g. "100MB"). Default: "100MB".
	MaxSize string `json:"max_size,omitempty"`
}

CacheConfig holds cache settings.

type Config

type Config struct {
	// APIs is a map of short API name to per-API configuration.
	APIs map[string]*APIConfig `json:"apis,omitempty"`

	// AuthProfiles holds named auth configurations that API profiles can
	// reference with auth_ref.
	AuthProfiles map[string]*AuthConfig `json:"auth_profiles,omitempty"`

	// Cache holds global cache settings.
	Cache CacheConfig `json:"cache,omitempty"`

	// Theme customizes syntax highlighting for readable terminal output.
	// Keys are Chroma token names or Restish theme aliases; values are Chroma
	// style descriptors such as "#afd787" or "bold #ff5f87".
	Theme map[string]string `json:"theme,omitempty"`

	// ThemeSource records the source URL last used by `config theme set`.
	ThemeSource string `json:"theme_source,omitempty"`

	// Plugins holds per-plugin configuration keyed by plugin name (without the
	// "restish-" prefix). Each value is stored as raw JSON so that restish
	// itself does not need to know the shape of each plugin's config.
	// Plugins can read their config via the "config-read" message.
	//
	// Example restish.json entry:
	//   "plugins": {
	//     "bulk": { "concurrency": 4, "retry": true }
	//   }
	Plugins map[string]json.RawMessage `json:"plugins,omitempty"`

	// Migration describes a one-time v1 -> v2 config migration that happened
	// while loading this config. It is not persisted back into restish.json.
	// Embedders using config.Load will not see this populated; only the restish
	// CLI's explicit migration step sets it.
	Migration *MigrationInfo `json:"-"`
}

Config is the top-level configuration for Restish, loaded from restish.json.

func Load

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

Load reads and parses the JSONC config file at path. If the file does not exist, an empty default Config is returned without error. A missing config file is normal for first-time users; Load does not perform a v1->v2 migration. The restish CLI runs its own legacy migration step before calling Load. Use LoadExplicit when a missing file should be an error.

func LoadExplicit

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

LoadExplicit reads a user-selected config file. Unlike Load, a missing file is an error because explicit config selection must not silently fall back to an empty or platform-default config.

func LoadExplicitOrEmpty

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

LoadExplicitOrEmpty reads a user-selected config file, returning an empty config when the selected file does not exist. Use this only for commands that are about to write the selected config path.

func ParseConfigBytes

func ParseConfigBytes(path string, data []byte) (*Config, error)

ParseConfigBytes parses a config payload from in-memory bytes using the same JSONC stripping, strict-field checks, and validation as Load.

func (*Config) PluginConfig

func (c *Config) PluginConfig(name string, v any) error

PluginConfig unmarshals the configuration stored under plugins[name] into v. Returns nil without modifying v when no config exists for that plugin. name should be the plugin's short name (without the "restish-" prefix).

type ConfigDiagnostics

type ConfigDiagnostics struct {
	UnknownFields []UnknownFieldDiagnostic
}

ConfigDiagnostics describes non-executing config diagnostics. It is intended for recovery commands such as doctor; normal execution still uses strict parsing and validation.

func DiagnoseConfig

func DiagnoseConfig(path string) (*ConfigDiagnostics, error)

DiagnoseConfig inspects a config file without accepting unknown fields for execution. It returns syntax errors, but otherwise reports schema diagnostics that recovery commands can display alongside strict parser failures.

type CredentialConfig

type CredentialConfig struct {
	// Auth holds inline authentication configuration for this credential.
	Auth *AuthConfig `json:"auth,omitempty"`
	// AuthRef names a top-level auth_profiles entry to use for this credential.
	AuthRef string `json:"auth_ref,omitempty"`
	// Satisfies lists requirement values, such as OAuth scopes or non-OAuth
	// roles, that this credential is intended to satisfy.
	Satisfies []string `json:"satisfies,omitempty"`
}

CredentialConfig binds a local auth configuration to a generated operation credential requirement.

type MigrationInfo

type MigrationInfo struct {
	SourcePath string
	BackupPath string
	Warnings   []string
}

MigrationInfo describes a one-time v1 -> v2 config migration performed by the restish CLI when an old apis.json is detected.

type PaginationConfig

type PaginationConfig struct {
	// ItemsPath is a filter expression that extracts the items array from the
	// response body (e.g. "data" for JSON:API, "results" for some REST APIs).
	// When empty, the body itself is used (if it is an array).
	ItemsPath string `json:"items_path,omitempty"`
	// NextPath is a filter expression that extracts the next-page URL from the
	// response body (alternative to Link header rel="next").
	NextPath string `json:"next_path,omitempty"`
	// PageParam is the URL query parameter that increments between pages when
	// an API has no next links or next_path metadata.
	PageParam string `json:"page_param,omitempty"`
}

PaginationConfig holds per-API pagination settings.

type ParseError

type ParseError struct {
	Path   string
	Err    error
	Line   int
	Column int
}

ParseError is returned when the config file contains invalid JSON or an unrecognized field. It includes line:column position when available.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

type Paths

type Paths struct {
	// contains filtered or unexported fields
}

Paths provides centralized directory and path management for Restish, using developer-friendly XDG-style defaults on Unix-like systems and standard user directories on Windows after Restish-specific environment variable overrides.

func NewPaths

func NewPaths() *Paths

NewPaths creates a new Paths instance that computes directories based on the current environment and OS.

func NewPathsWithConfigFile

func NewPathsWithConfigFile(path string) *Paths

NewPathsWithConfigFile creates Paths for an explicit config file. Sidecar state stored in the config directory, such as token caches and external-tool approvals, follows the selected config file.

func (*Paths) Cache

func (p *Paths) Cache() string

Cache returns the cache directory path for HTTP responses and other transient data.

func (*Paths) CacheError

func (p *Paths) CacheError() error

CacheError returns why the cache directory used a fallback, if any.

func (*Paths) Config

func (p *Paths) Config() string

Config returns the config directory path, typically containing restish.json, profiles, and auth configuration.

func (*Paths) ConfigError

func (p *Paths) ConfigError() error

ConfigError returns why the config directory could not be determined, if any.

func (*Paths) ConfigFile

func (p *Paths) ConfigFile() string

ConfigFile returns the path to the main restish.json config file.

func (*Paths) PluginManifestCache

func (p *Paths) PluginManifestCache() string

PluginManifestCache returns the directory for cached plugin manifests.

func (*Paths) SpecCache

func (p *Paths) SpecCache() string

SpecCache returns the subdirectory for cached API spec files.

func (*Paths) TokenCache

func (p *Paths) TokenCache() string

TokenCache returns the path to the token cache file.

type ProfileConfig

type ProfileConfig struct {
	// BaseURL overrides the API-level base_url when this profile is active.
	BaseURL string `json:"base_url,omitempty"`
	// OperationBase overrides API-level operation_base when this profile is active.
	OperationBase string `json:"operation_base,omitempty"`
	// Headers is a list of persistent "Name: Value" headers sent with every request.
	Headers []string `json:"headers,omitempty"`
	// Query is a list of persistent "key=value" query params sent with every request.
	Query []string `json:"query,omitempty"`
	// CACertPath is an optional PEM CA bundle for this profile.
	CACertPath string `json:"ca_cert,omitempty"`
	// ClientCertPath is the PEM client certificate path for this profile.
	ClientCertPath string `json:"client_cert,omitempty"`
	// ClientKeyPath is the PEM client private key path for this profile.
	ClientKeyPath string `json:"client_key,omitempty"`
	// TLSSigner selects a tls-signer plugin for mTLS client certificate signing.
	TLSSigner string `json:"tls_signer,omitempty"`
	// TLSSignerParams passes plugin-specific configuration to the tls-signer.
	TLSSignerParams map[string]string `json:"tls_signer_params,omitempty"`
	// ServerVariables overrides API-level OpenAPI server URL variables for this
	// profile when generating operation paths.
	ServerVariables map[string]string `json:"server_variables,omitempty"`
	// URLOverrides overrides or extends API-level URL prefix rewrites for this
	// profile.
	URLOverrides map[string]string `json:"url_overrides,omitempty"`
	// Auth holds authentication configuration for this profile.
	Auth *AuthConfig `json:"auth,omitempty"`
	// AuthRef names a top-level auth_profiles entry to use for this profile.
	AuthRef string `json:"auth_ref,omitempty"`
	// Credentials maps operation credential requirement IDs to auth
	// configurations that satisfy them.
	Credentials map[string]*CredentialConfig `json:"credentials,omitempty"`
}

ProfileConfig holds per-profile overrides for an API.

type UnknownFieldDiagnostic

type UnknownFieldDiagnostic struct {
	Path       string
	Field      string
	Line       int
	Column     int
	Suggestion string
	Hint       string
}

UnknownFieldDiagnostic reports a config field that is not part of the v2 schema. Path is a dotted config path such as "apis.example.base".

Jump to

Keyboard shortcuts

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